Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit 4f168b2

Browse files
committed
unify word interface for zero/one
1 parent 81e715a commit 4f168b2

21 files changed

+286
-163
lines changed

eth-types/src/lib.rs

+52-4
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ pub use keccak::{keccak256, Keccak};
2424

2525
pub use bytecode::Bytecode;
2626
pub use error::Error;
27-
use halo2_proofs::halo2curves::{
28-
bn256::{Fq, Fr},
29-
ff::{Field as Halo2Field, FromUniformBytes, PrimeField},
27+
use halo2_proofs::{
28+
halo2curves::{
29+
bn256::{Fq, Fr},
30+
ff::{Field as Halo2Field, FromUniformBytes, PrimeField},
31+
},
32+
plonk::Expression,
3033
};
3134

3235
use crate::evm_types::{memory::Memory, stack::Stack, storage::Storage, OpcodeId};
@@ -42,9 +45,32 @@ pub use ethers_core::{
4245
use serde::{de, Deserialize, Serialize};
4346
use std::{collections::HashMap, fmt, str::FromStr};
4447

48+
/// trait to retrieve general operation itentity element
49+
pub trait OpsIdentity {
50+
/// output type
51+
type Output;
52+
/// additive identity
53+
fn zero<T>() -> Self::Output;
54+
/// multiplicative identity
55+
fn one<T>() -> Self::Output;
56+
}
57+
58+
impl<F: Field> OpsIdentity for Expression<F> {
59+
type Output = Expression<F>;
60+
fn zero<T>() -> Self::Output {
61+
Expression::Constant(F::ZERO)
62+
}
63+
64+
fn one<T>() -> Self::Output {
65+
Expression::Constant(F::ONE)
66+
}
67+
}
68+
4569
/// Trait used to reduce verbosity with the declaration of the [`PrimeField`]
4670
/// trait and its repr.
47-
pub trait Field: Halo2Field + PrimeField<Repr = [u8; 32]> + FromUniformBytes<64> + Ord {
71+
pub trait Field:
72+
Halo2Field + PrimeField<Repr = [u8; 32]> + FromUniformBytes<64> + Ord + OpsIdentity
73+
{
4874
/// Gets the lower 128 bits of this field element when expressed
4975
/// canonically.
5076
fn get_lower_128(&self) -> u128 {
@@ -65,12 +91,34 @@ pub trait Field: Halo2Field + PrimeField<Repr = [u8; 32]> + FromUniformBytes<64>
6591
}
6692
}
6793

94+
impl OpsIdentity for Fr {
95+
type Output = Fr;
96+
97+
fn zero<T>() -> Self::Output {
98+
Fr::zero()
99+
}
100+
101+
fn one<T>() -> Self::Output {
102+
Fr::one()
103+
}
104+
}
68105
// Impl custom `Field` trait for BN256 Fr to be used and consistent with the
69106
// rest of the workspace.
70107
impl Field for Fr {}
71108

72109
// Impl custom `Field` trait for BN256 Frq to be used and consistent with the
73110
// rest of the workspace.
111+
impl OpsIdentity for Fq {
112+
type Output = Fq;
113+
114+
fn zero<T>() -> Self::Output {
115+
Fq::zero()
116+
}
117+
118+
fn one<T>() -> Self::Output {
119+
Fq::one()
120+
}
121+
}
74122
impl Field for Fq {}
75123

76124
/// Trait used to define types that can be converted to a 256 bit scalar value.

gadgets/src/util.rs

-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@ impl<F: Field> Expr<F> for &Expression<F> {
264264
(*self).clone()
265265
}
266266
}
267-
268267
/// Given a bytes-representation of an expression, it computes and returns the
269268
/// single expression.
270269
pub fn expr_from_bytes<F: Field, E: Expr<F>>(bytes: &[E]) -> Expression<F> {

light-client-poc/src/circuit/state_update.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::equal_words::EqualWordsConfig;
2-
use eth_types::Field;
2+
use eth_types::{Field, OpsIdentity};
33
use eyre::Result;
44
use gadgets::{
55
is_zero::{IsZeroChip, IsZeroConfig, IsZeroInstruction},
@@ -68,7 +68,10 @@ pub struct StateUpdateCircuitConfig<F: Field> {
6868

6969
/// MPT Circuit for proving the storage modification is valid.
7070
#[derive(Default)]
71-
pub struct StateUpdateCircuit<F: Field> {
71+
pub struct StateUpdateCircuit<F: Field + OpsIdentity<Output = F>>
72+
where
73+
<F as OpsIdentity>::Output: Field,
74+
{
7275
pub transforms: Transforms,
7376
#[cfg(not(feature = "disable-keccak"))]
7477
pub keccak_circuit: KeccakCircuit<F>,
@@ -78,7 +81,10 @@ pub struct StateUpdateCircuit<F: Field> {
7881
pub max_proof_count: usize,
7982
}
8083

81-
impl<F: Field> Circuit<F> for StateUpdateCircuit<F> {
84+
impl<F: Field + OpsIdentity<Output = F>> Circuit<F> for StateUpdateCircuit<F>
85+
where
86+
<F as OpsIdentity>::Output: Field,
87+
{
8288
type Config = (StateUpdateCircuitConfig<F>, Challenges);
8389
type FloorPlanner = SimpleFloorPlanner;
8490
type Params = MPTCircuitParams;

zkevm-circuits/src/evm_circuit/execution/begin_tx.rs

+29-17
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,12 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
221221
cb.account_write(
222222
call_callee_address.to_word(),
223223
AccountFieldTag::Nonce,
224-
Word::one(),
225-
Word::zero(),
224+
Word::one::<Expression<F>>(),
225+
Word::zero::<Expression<F>>(),
226226
Some(&mut reversion_info),
227227
);
228228
for (field_tag, value) in [
229-
(CallContextFieldTag::Depth, Word::one()),
229+
(CallContextFieldTag::Depth, Word::one::<Expression<F>>()),
230230
(
231231
CallContextFieldTag::CallerAddress,
232232
tx.caller_address.to_word(),
@@ -235,24 +235,30 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
235235
CallContextFieldTag::CalleeAddress,
236236
call_callee_address.to_word(),
237237
),
238-
(CallContextFieldTag::CallDataOffset, Word::zero()),
238+
(
239+
CallContextFieldTag::CallDataOffset,
240+
Word::zero::<Expression<F>>(),
241+
),
239242
(
240243
CallContextFieldTag::CallDataLength,
241244
Word::from_lo_unchecked(tx.call_data_length.expr()),
242245
),
243246
(CallContextFieldTag::Value, tx.value.to_word()),
244-
(CallContextFieldTag::IsStatic, Word::zero()),
245-
(CallContextFieldTag::LastCalleeId, Word::zero()),
247+
(CallContextFieldTag::IsStatic, Word::zero::<Expression<F>>()),
248+
(
249+
CallContextFieldTag::LastCalleeId,
250+
Word::zero::<Expression<F>>(),
251+
),
246252
(
247253
CallContextFieldTag::LastCalleeReturnDataOffset,
248-
Word::zero(),
254+
Word::zero::<Expression<F>>(),
249255
),
250256
(
251257
CallContextFieldTag::LastCalleeReturnDataLength,
252-
Word::zero(),
258+
Word::zero::<Expression<F>>(),
253259
),
254-
(CallContextFieldTag::IsRoot, Word::one()),
255-
(CallContextFieldTag::IsCreate, Word::one()),
260+
(CallContextFieldTag::IsRoot, Word::one::<Expression<F>>()),
261+
(CallContextFieldTag::IsCreate, Word::one::<Expression<F>>()),
256262
(
257263
CallContextFieldTag::CodeHash,
258264
cb.curr.state.code_hash.to_word(),
@@ -349,7 +355,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
349355
|cb| {
350356
// Setup first call's context.
351357
for (field_tag, value) in [
352-
(CallContextFieldTag::Depth, Word::one()),
358+
(CallContextFieldTag::Depth, Word::one::<Expression<F>>()),
353359
(
354360
CallContextFieldTag::CallerAddress,
355361
tx.caller_address.to_word(),
@@ -358,23 +364,29 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
358364
CallContextFieldTag::CalleeAddress,
359365
tx.callee_address.to_word(),
360366
),
361-
(CallContextFieldTag::CallDataOffset, Word::zero()),
367+
(
368+
CallContextFieldTag::CallDataOffset,
369+
Word::zero::<Expression<F>>(),
370+
),
362371
(
363372
CallContextFieldTag::CallDataLength,
364373
Word::from_lo_unchecked(tx.call_data_length.expr()),
365374
),
366375
(CallContextFieldTag::Value, tx.value.to_word()),
367-
(CallContextFieldTag::IsStatic, Word::zero()),
368-
(CallContextFieldTag::LastCalleeId, Word::zero()),
376+
(CallContextFieldTag::IsStatic, Word::zero::<Expression<F>>()),
377+
(
378+
CallContextFieldTag::LastCalleeId,
379+
Word::zero::<Expression<F>>(),
380+
),
369381
(
370382
CallContextFieldTag::LastCalleeReturnDataOffset,
371-
Word::zero(),
383+
Word::zero::<Expression<F>>(),
372384
),
373385
(
374386
CallContextFieldTag::LastCalleeReturnDataLength,
375-
Word::zero(),
387+
Word::zero::<Expression<F>>(),
376388
),
377-
(CallContextFieldTag::IsRoot, Word::one()),
389+
(CallContextFieldTag::IsRoot, Word::one::<Expression<F>>()),
378390
(
379391
CallContextFieldTag::IsCreate,
380392
Word::from_lo_unchecked(tx.is_create.expr()),

zkevm-circuits/src/evm_circuit/execution/callop.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ use bus_mapping::{
3232
precompile::{is_precompiled, PrecompileCalls},
3333
};
3434
use eth_types::{evm_types::GAS_STIPEND_CALL_WITH_VALUE, Field, ToAddress, ToScalar, U256};
35-
use halo2_proofs::{circuit::Value, plonk::Error};
35+
use halo2_proofs::{
36+
circuit::Value,
37+
plonk::{Error, Expression},
38+
};
3639
use std::cmp::min;
3740

3841
/// Gadget for call related opcodes. It supports `OpcodeId::CALL`,
@@ -540,7 +543,7 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
540543
CallContextFieldTag::LastCalleeReturnDataOffset,
541544
CallContextFieldTag::LastCalleeReturnDataLength,
542545
] {
543-
cb.call_context_lookup_write(None, field_tag, Word::zero());
546+
cb.call_context_lookup_write(None, field_tag, Word::zero::<Expression<F>>());
544547
}
545548

546549
// For CALL opcode, it has an extra stack pop `value` (+1) and if the value is
@@ -588,7 +591,7 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
588591
CallContextFieldTag::LastCalleeReturnDataOffset,
589592
CallContextFieldTag::LastCalleeReturnDataLength,
590593
] {
591-
cb.call_context_lookup_write(None, field_tag, Word::zero());
594+
cb.call_context_lookup_write(None, field_tag, Word::zero::<Expression<F>>());
592595
}
593596

594597
cb.require_step_state_transition(StepStateTransition {
@@ -689,17 +692,20 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
689692
CallContextFieldTag::IsStatic,
690693
Word::from_lo_unchecked(or::expr([is_static.expr(), is_staticcall.expr()])),
691694
),
692-
(CallContextFieldTag::LastCalleeId, Word::zero()),
695+
(
696+
CallContextFieldTag::LastCalleeId,
697+
Word::zero::<Expression<F>>(),
698+
),
693699
(
694700
CallContextFieldTag::LastCalleeReturnDataOffset,
695-
Word::zero(),
701+
Word::zero::<Expression<F>>(),
696702
),
697703
(
698704
CallContextFieldTag::LastCalleeReturnDataLength,
699-
Word::zero(),
705+
Word::zero::<Expression<F>>(),
700706
),
701-
(CallContextFieldTag::IsRoot, Word::zero()),
702-
(CallContextFieldTag::IsCreate, Word::zero()),
707+
(CallContextFieldTag::IsRoot, Word::zero::<Expression<F>>()),
708+
(CallContextFieldTag::IsCreate, Word::zero::<Expression<F>>()),
703709
(
704710
CallContextFieldTag::CodeHash,
705711
call_gadget.callee_code_hash.to_word(),

zkevm-circuits/src/evm_circuit/execution/create.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
296296
CallContextFieldTag::LastCalleeReturnDataOffset,
297297
CallContextFieldTag::LastCalleeReturnDataLength,
298298
] {
299-
cb.call_context_lookup_write(None, field_tag, Word::zero());
299+
cb.call_context_lookup_write(None, field_tag, Word::zero::<Expression<F>>());
300300
}
301301

302302
cb.require_step_state_transition(StepStateTransition {
@@ -342,8 +342,8 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
342342
cb.account_write(
343343
contract_addr.to_word(),
344344
AccountFieldTag::Nonce,
345-
Word::one(),
346-
Word::zero(),
345+
Word::one::<Expression<F>>(),
346+
Word::zero::<Expression<F>>(),
347347
Some(&mut callee_reversion_info),
348348
);
349349

@@ -420,7 +420,11 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
420420
CallContextFieldTag::LastCalleeReturnDataOffset,
421421
CallContextFieldTag::LastCalleeReturnDataLength,
422422
] {
423-
cb.call_context_lookup_write(None, field_tag, Word::zero());
423+
cb.call_context_lookup_write(
424+
None,
425+
field_tag,
426+
Word::zero::<Expression<F>>(),
427+
);
424428
}
425429
cb.require_step_state_transition(StepStateTransition {
426430
rw_counter: Delta(cb.rw_counter_offset()),
@@ -463,7 +467,7 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
463467
CallContextFieldTag::LastCalleeReturnDataOffset,
464468
CallContextFieldTag::LastCalleeReturnDataLength,
465469
] {
466-
cb.call_context_lookup_write(None, field_tag, Word::zero());
470+
cb.call_context_lookup_write(None, field_tag, Word::zero::<Expression<F>>());
467471
}
468472

469473
cb.require_step_state_transition(StepStateTransition {

zkevm-circuits/src/evm_circuit/execution/end_block.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ use crate::{
1616
};
1717
use eth_types::Field;
1818
use gadgets::util::select;
19-
use halo2_proofs::{circuit::Value, plonk::Error};
19+
use halo2_proofs::{
20+
circuit::Value,
21+
plonk::{Error, Expression},
22+
};
2023

2124
#[derive(Clone, Debug)]
2225
pub(crate) struct EndBlockGadget<F> {
@@ -74,7 +77,7 @@ impl<F: Field> ExecutionGadget<F> for EndBlockGadget<F> {
7477
total_txs.expr() + 1.expr(),
7578
TxContextFieldTag::CallerAddress,
7679
None,
77-
Word::zero(),
80+
Word::zero::<Expression<F>>(),
7881
);
7982
// Since every tx lookup done in the EVM circuit must succeed
8083
// and uses a unique tx_id, we know that at

zkevm-circuits/src/evm_circuit/execution/error_precompile_failed.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ use crate::{
1818
};
1919
use bus_mapping::evm::OpcodeId;
2020
use eth_types::{Field, U256};
21-
use halo2_proofs::{circuit::Value, plonk::Error};
21+
use halo2_proofs::{
22+
circuit::Value,
23+
plonk::{Error, Expression},
24+
};
2225

2326
#[derive(Clone, Debug)]
2427
pub(crate) struct ErrorPrecompileFailedGadget<F> {
@@ -87,7 +90,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorPrecompileFailedGadget<F> {
8790
cb.stack_pop(cd_length.to_word());
8891
cb.stack_pop(rd_offset.to_word());
8992
cb.stack_pop(rd_length.to_word());
90-
cb.stack_push(Word::zero());
93+
cb.stack_push(Word::zero::<Expression<F>>());
9194

9295
for (field_tag, value) in [
9396
(CallContextFieldTag::LastCalleeId, callee_call_id.expr()),

zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ use crate::{
1717
},
1818
};
1919
use eth_types::{evm_types::OpcodeId, Field, ToAddress, U256};
20-
use halo2_proofs::{circuit::Value, plonk::Error};
20+
use halo2_proofs::{
21+
circuit::Value,
22+
plonk::{Error, Expression},
23+
};
2124

2225
#[derive(Clone, Debug)]
2326
pub(crate) struct ErrorWriteProtectionGadget<F> {
@@ -73,7 +76,11 @@ impl<F: Field> ExecutionGadget<F> for ErrorWriteProtectionGadget<F> {
7376
});
7477

7578
// current call context is readonly
76-
cb.call_context_lookup_read(None, CallContextFieldTag::IsStatic, Word::one());
79+
cb.call_context_lookup_read(
80+
None,
81+
CallContextFieldTag::IsStatic,
82+
Word::one::<Expression<F>>(),
83+
);
7784

7885
// constrain not root call as at least one previous staticcall preset.
7986
cb.require_zero(

0 commit comments

Comments
 (0)