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

Commit be9fed5

Browse files
Ops id trait (#1758)
### Description to address discussion in PR #1748 ### Rationale implement OpsIdentity for word<T> so that we no longer need to type hint `::<Expression<F>>` or `::<F>` every time.
1 parent 81e715a commit be9fed5

18 files changed

+107
-59
lines changed

eth-types/src/lib.rs

+56-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,58 @@ 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() -> Self::Output;
54+
/// multiplicative identity
55+
fn one() -> Self::Output;
56+
}
57+
58+
impl<F: Field> OpsIdentity for Expression<F> {
59+
type Output = Expression<F>;
60+
fn zero() -> Self::Output {
61+
Expression::Constant(F::ZERO)
62+
}
63+
64+
fn one() -> Self::Output {
65+
Expression::Constant(F::ONE)
66+
}
67+
}
68+
69+
// Impl OpsIdentity for Fr
70+
impl OpsIdentity for Fr {
71+
type Output = Fr;
72+
73+
fn zero() -> Self::Output {
74+
Fr::zero()
75+
}
76+
77+
fn one() -> Self::Output {
78+
Fr::one()
79+
}
80+
}
81+
82+
// Impl OpsIdentity for Fq
83+
impl OpsIdentity for Fq {
84+
type Output = Fq;
85+
86+
fn zero() -> Self::Output {
87+
Fq::zero()
88+
}
89+
90+
fn one() -> Self::Output {
91+
Fq::one()
92+
}
93+
}
94+
4595
/// Trait used to reduce verbosity with the declaration of the [`PrimeField`]
4696
/// trait and its repr.
47-
pub trait Field: Halo2Field + PrimeField<Repr = [u8; 32]> + FromUniformBytes<64> + Ord {
97+
pub trait Field:
98+
Halo2Field + PrimeField<Repr = [u8; 32]> + FromUniformBytes<64> + Ord + OpsIdentity<Output = Self>
99+
{
48100
/// Gets the lower 128 bits of this field element when expressed
49101
/// canonically.
50102
fn get_lower_128(&self) -> u128 {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::{
2727
},
2828
};
2929
use bus_mapping::state_db::CodeDB;
30-
use eth_types::{evm_types::PRECOMPILE_COUNT, keccak256, Field, ToWord, U256};
30+
use eth_types::{evm_types::PRECOMPILE_COUNT, keccak256, Field, OpsIdentity, ToWord, U256};
3131
use halo2_proofs::{
3232
circuit::Value,
3333
plonk::{Error, Expression},

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ use bus_mapping::{
3131
evm::OpcodeId,
3232
precompile::{is_precompiled, PrecompileCalls},
3333
};
34-
use eth_types::{evm_types::GAS_STIPEND_CALL_WITH_VALUE, Field, ToAddress, ToScalar, U256};
34+
use eth_types::{
35+
evm_types::GAS_STIPEND_CALL_WITH_VALUE, Field, OpsIdentity, ToAddress, ToScalar, U256,
36+
};
3537
use halo2_proofs::{circuit::Value, plonk::Error};
3638
use std::cmp::min;
3739

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use bus_mapping::{
3434
};
3535
use eth_types::{
3636
evm_types::{GasCost, INIT_CODE_WORD_GAS},
37-
Field, ToBigEndian, ToScalar, ToWord, U256,
37+
Field, OpsIdentity, ToBigEndian, ToScalar, ToWord, U256,
3838
};
3939
use ethers_core::utils::keccak256;
4040
use gadgets::util::{and, select};

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
table::{CallContextFieldTag, TxContextFieldTag},
1515
util::{word::Word, Expr},
1616
};
17-
use eth_types::Field;
17+
use eth_types::{Field, OpsIdentity};
1818
use gadgets::util::select;
1919
use halo2_proofs::{circuit::Value, plonk::Error};
2020

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
witness::{Block, Call, ExecStep, Transaction},
1818
};
1919
use bus_mapping::evm::OpcodeId;
20-
use eth_types::{Field, U256};
20+
use eth_types::{Field, OpsIdentity, U256};
2121
use halo2_proofs::{circuit::Value, plonk::Error};
2222

2323
#[derive(Clone, Debug)]

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
Expr,
1717
},
1818
};
19-
use eth_types::{evm_types::OpcodeId, Field, ToAddress, U256};
19+
use eth_types::{evm_types::OpcodeId, Field, OpsIdentity, ToAddress, U256};
2020
use halo2_proofs::{circuit::Value, plonk::Error};
2121

2222
#[derive(Clone, Debug)]

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{
2121
},
2222
};
2323
use bus_mapping::evm::OpcodeId;
24-
use eth_types::Field;
24+
use eth_types::{Field, OpsIdentity};
2525
use halo2_proofs::{circuit::Value, plonk::Error};
2626

2727
#[derive(Clone, Debug)]

zkevm-circuits/src/evm_circuit/util/common_gadget.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ use crate::{
2828
witness::{Block, Call, ExecStep},
2929
};
3030
use bus_mapping::state_db::CodeDB;
31-
use eth_types::{evm_types::GasCost, Field, ToAddress, ToLittleEndian, ToScalar, ToWord, U256};
31+
use eth_types::{
32+
evm_types::GasCost, Field, OpsIdentity, ToAddress, ToLittleEndian, ToScalar, ToWord, U256,
33+
};
3234
use gadgets::util::{select, sum};
3335
use halo2_proofs::{
3436
circuit::Value,

zkevm-circuits/src/evm_circuit/util/constraint_builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::{
1818
use bus_mapping::{
1919
circuit_input_builder::FeatureConfig, operation::Target, state_db::EMPTY_CODE_HASH_LE,
2020
};
21-
use eth_types::Field;
21+
use eth_types::{Field, OpsIdentity};
2222
use gadgets::util::{not, sum};
2323
use halo2_proofs::{
2424
circuit::Value,

zkevm-circuits/src/mpt_circuit/account_leaf.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use eth_types::{Field, U256};
1+
use eth_types::{Field, OpsIdentity, U256};
22
use gadgets::util::{pow, Scalar};
33
use halo2_proofs::{
44
circuit::Value,
@@ -554,10 +554,10 @@ impl<F: Field> AccountLeafConfig<F> {
554554

555555
// Key
556556
let mut key_rlc = vec![0.scalar(); 2];
557-
let mut nonce = vec![Word::zero_f(); 2];
558-
let mut balance = vec![Word::zero_f(); 2];
559-
let mut storage = vec![Word::zero_f(); 2];
560-
let mut codehash = vec![Word::zero_f(); 2];
557+
let mut nonce = vec![Word::zero(); 2];
558+
let mut balance = vec![Word::zero(); 2];
559+
let mut storage = vec![Word::zero(); 2];
560+
let mut codehash = vec![Word::zero(); 2];
561561
let mut key_data = vec![KeyDataWitness::default(); 2];
562562
let mut parent_data = vec![ParentDataWitness::default(); 2];
563563
for is_s in [true, false] {
@@ -727,11 +727,11 @@ impl<F: Field> AccountLeafConfig<F> {
727727
} else if is_codehash_mod {
728728
(MPTProofType::CodeHashChanged, codehash)
729729
} else if is_account_delete_mod {
730-
(MPTProofType::AccountDestructed, vec![Word::zero_f(); 2])
730+
(MPTProofType::AccountDestructed, vec![Word::zero(); 2])
731731
} else if is_non_existing_proof {
732-
(MPTProofType::AccountDoesNotExist, vec![Word::zero_f(); 2])
732+
(MPTProofType::AccountDoesNotExist, vec![Word::zero(); 2])
733733
} else {
734-
(MPTProofType::Disabled, vec![Word::zero_f(); 2])
734+
(MPTProofType::Disabled, vec![Word::zero(); 2])
735735
};
736736

737737
if account.is_mod_extension[0] || account.is_mod_extension[1] {
@@ -746,10 +746,10 @@ impl<F: Field> AccountLeafConfig<F> {
746746
let mut new_value = value[false.idx()];
747747
let mut old_value = value[true.idx()];
748748
if parent_data[false.idx()].is_placeholder {
749-
new_value = word::Word::zero_f();
749+
new_value = word::Word::zero();
750750
} else if is_non_existing_proof {
751-
new_value = word::Word::zero_f();
752-
old_value = word::Word::zero_f();
751+
new_value = word::Word::zero();
752+
old_value = word::Word::zero();
753753
}
754754
mpt_config.mpt_table.assign_cached(
755755
region,
@@ -758,7 +758,7 @@ impl<F: Field> AccountLeafConfig<F> {
758758
address: Value::known(from_bytes::value(
759759
&account.address.iter().cloned().rev().collect::<Vec<_>>(),
760760
)),
761-
storage_key: word::Word::zero_f().into_value(),
761+
storage_key: word::Word::zero().into_value(),
762762
proof_type: Value::known(proof_type.scalar()),
763763
new_root: main_data.new_root.into_value(),
764764
old_root: main_data.old_root.into_value(),

zkevm-circuits/src/mpt_circuit/branch.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use eth_types::Field;
1+
use eth_types::{Field, OpsIdentity};
22
use gadgets::util::Scalar;
33
use halo2_proofs::plonk::{Error, Expression, VirtualCells};
44

@@ -351,7 +351,7 @@ impl<F: Field> BranchGadget<F> {
351351
let key_mult_post_branch = *key_mult * mult;
352352

353353
// Set the branch we'll take
354-
let mut mod_node_hash_word = [word::Word::zero_f(); 2];
354+
let mut mod_node_hash_word = [word::Word::zero(); 2];
355355
let mut mod_node_hash_rlc = [0.scalar(); 2];
356356
for is_s in [true, false] {
357357
(

zkevm-circuits/src/mpt_circuit/extension.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use eth_types::Field;
1+
use eth_types::{Field, OpsIdentity};
22
use gadgets::util::{pow, Scalar};
33
use halo2_proofs::plonk::{Error, Expression, VirtualCells};
44

zkevm-circuits/src/mpt_circuit/extension_branch.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use eth_types::Field;
1+
use eth_types::{Field, OpsIdentity};
22
use gadgets::util::Scalar;
33
use halo2_proofs::plonk::{Error, Expression, VirtualCells};
44

@@ -291,7 +291,7 @@ impl<F: Field> ExtensionBranchConfig<F> {
291291
mod_node_hash_rlc[is_s.idx()],
292292
false,
293293
false,
294-
Word::zero_f(),
294+
Word::zero(),
295295
)?;
296296
} else {
297297
KeyData::witness_store(

zkevm-circuits/src/mpt_circuit/helpers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::{
2727
Challenges, Expr,
2828
},
2929
};
30-
use eth_types::{Field, Word as U256};
30+
use eth_types::{Field, OpsIdentity, Word as U256};
3131
use gadgets::util::{not, or, pow, xor, Scalar};
3232
use halo2_proofs::{
3333
circuit::Value,

zkevm-circuits/src/mpt_circuit/start.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
},
1616
util::word::Word,
1717
};
18-
use eth_types::Field;
18+
use eth_types::{Field, OpsIdentity};
1919
use gadgets::util::Scalar;
2020
use halo2_proofs::plonk::{Error, VirtualCells};
2121

@@ -96,7 +96,7 @@ impl<F: Field> StartConfig<F> {
9696
self.proof_type
9797
.assign(region, offset, start.proof_type.scalar())?;
9898

99-
let mut root = vec![Word::zero_f(); 2];
99+
let mut root = vec![Word::zero(); 2];
100100
for is_s in [true, false] {
101101
root[is_s.idx()] = rlp_values[is_s.idx()].word();
102102
}

zkevm-circuits/src/mpt_circuit/storage_leaf.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use eth_types::{Field, U256};
1+
use eth_types::{Field, OpsIdentity, U256};
22
use gadgets::util::Scalar;
33
use halo2_proofs::{
44
circuit::Value,
@@ -191,7 +191,7 @@ impl<F: Field> StorageLeafConfig<F> {
191191

192192
// Placeholder leaves default to value `0`.
193193
ifx! {is_placeholder_leaf => {
194-
require!(value_word[is_s.idx()] => Word::zero());
194+
require!(value_word[is_s.idx()] => Word::<Expression<F>>::zero());
195195
}}
196196

197197
// Make sure the RLP encoding is correct.
@@ -436,7 +436,7 @@ impl<F: Field> StorageLeafConfig<F> {
436436
let mut key_data = vec![KeyDataWitness::default(); 2];
437437
let mut parent_data = vec![ParentDataWitness::default(); 2];
438438
let mut key_rlc = vec![0.scalar(); 2];
439-
let mut value_word = vec![Word::zero_f(); 2];
439+
let mut value_word = vec![Word::zero(); 2];
440440
for is_s in [true, false] {
441441
self.is_mod_extension[is_s.idx()].assign(
442442
region,
@@ -596,10 +596,10 @@ impl<F: Field> StorageLeafConfig<F> {
596596
let mut new_value = value_word[false.idx()];
597597
let mut old_value = value_word[true.idx()];
598598
if parent_data[false.idx()].is_placeholder {
599-
new_value = word::Word::zero_f();
599+
new_value = word::Word::zero();
600600
} else if is_non_existing_proof {
601-
new_value = word::Word::zero_f();
602-
old_value = word::Word::zero_f();
601+
new_value = word::Word::zero();
602+
old_value = word::Word::zero();
603603
}
604604
mpt_config.mpt_table.assign_cached(
605605
region,

zkevm-circuits/src/util/word.rs

+12-20
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// limb is 256/4 = 64 bits
55

66
use bus_mapping::state_db::CodeDB;
7-
use eth_types::{Field, ToLittleEndian, H160, H256};
7+
use eth_types::{Field, OpsIdentity, ToLittleEndian, H160, H256};
88
use gadgets::util::{not, or, Expr};
99
use halo2_proofs::{
1010
circuit::{AssignedCell, Region, Value},
@@ -267,6 +267,17 @@ impl<F: Field> From<eth_types::Word> for Word<F> {
267267
}
268268
}
269269

270+
impl<T: Clone + OpsIdentity<Output = T>> OpsIdentity for Word<T> {
271+
/// output type
272+
type Output = Word<T>;
273+
fn zero() -> Self::Output {
274+
Word::new([T::zero(), T::zero()])
275+
}
276+
fn one() -> Self::Output {
277+
Word::new([T::one(), T::zero()])
278+
}
279+
}
280+
270281
impl<F: Field> From<H256> for Word<F> {
271282
/// Construct the word from H256
272283
fn from(h: H256) -> Self {
@@ -354,16 +365,6 @@ impl<F: Field, T: Expr<F> + Clone> WordExpr<F> for Word<T> {
354365
}
355366

356367
impl<F: Field> Word<F> {
357-
/// zero word
358-
pub fn zero_f() -> Self {
359-
Self::new([F::ZERO, F::ZERO])
360-
}
361-
362-
/// one word
363-
pub fn one_f() -> Self {
364-
Self::new([F::ONE, F::ZERO])
365-
}
366-
367368
/// Convert address (h160) to single field element.
368369
/// This method is Address specific
369370
pub fn compress_f(&self) -> F {
@@ -376,15 +377,6 @@ impl<F: Field> Word<Expression<F>> {
376377
pub fn from_lo_unchecked(lo: Expression<F>) -> Self {
377378
Self::new([lo, 0.expr()])
378379
}
379-
/// zero word
380-
pub fn zero() -> Self {
381-
Self::new([0.expr(), 0.expr()])
382-
}
383-
384-
/// one word
385-
pub fn one() -> Self {
386-
Self::new([1.expr(), 0.expr()])
387-
}
388380

389381
/// select based on selector. Here assume selector is 1/0 therefore no overflow check
390382
pub fn select<T: Expr<F> + Clone>(

0 commit comments

Comments
 (0)