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

Commit

Permalink
Ops id trait (#1758)
Browse files Browse the repository at this point in the history
### 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.
  • Loading branch information
ChihChengLiang authored Feb 6, 2024
1 parent 81e715a commit be9fed5
Show file tree
Hide file tree
Showing 18 changed files with 107 additions and 59 deletions.
60 changes: 56 additions & 4 deletions eth-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ pub use keccak::{keccak256, Keccak};

pub use bytecode::Bytecode;
pub use error::Error;
use halo2_proofs::halo2curves::{
bn256::{Fq, Fr},
ff::{Field as Halo2Field, FromUniformBytes, PrimeField},
use halo2_proofs::{
halo2curves::{
bn256::{Fq, Fr},
ff::{Field as Halo2Field, FromUniformBytes, PrimeField},
},
plonk::Expression,
};

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

/// trait to retrieve general operation itentity element
pub trait OpsIdentity {
/// output type
type Output;
/// additive identity
fn zero() -> Self::Output;
/// multiplicative identity
fn one() -> Self::Output;
}

impl<F: Field> OpsIdentity for Expression<F> {
type Output = Expression<F>;
fn zero() -> Self::Output {
Expression::Constant(F::ZERO)
}

fn one() -> Self::Output {
Expression::Constant(F::ONE)
}
}

// Impl OpsIdentity for Fr
impl OpsIdentity for Fr {
type Output = Fr;

fn zero() -> Self::Output {
Fr::zero()
}

fn one() -> Self::Output {
Fr::one()
}
}

// Impl OpsIdentity for Fq
impl OpsIdentity for Fq {
type Output = Fq;

fn zero() -> Self::Output {
Fq::zero()
}

fn one() -> Self::Output {
Fq::one()
}
}

/// Trait used to reduce verbosity with the declaration of the [`PrimeField`]
/// trait and its repr.
pub trait Field: Halo2Field + PrimeField<Repr = [u8; 32]> + FromUniformBytes<64> + Ord {
pub trait Field:
Halo2Field + PrimeField<Repr = [u8; 32]> + FromUniformBytes<64> + Ord + OpsIdentity<Output = Self>
{
/// Gets the lower 128 bits of this field element when expressed
/// canonically.
fn get_lower_128(&self) -> u128 {
Expand Down
2 changes: 1 addition & 1 deletion zkevm-circuits/src/evm_circuit/execution/begin_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
},
};
use bus_mapping::state_db::CodeDB;
use eth_types::{evm_types::PRECOMPILE_COUNT, keccak256, Field, ToWord, U256};
use eth_types::{evm_types::PRECOMPILE_COUNT, keccak256, Field, OpsIdentity, ToWord, U256};
use halo2_proofs::{
circuit::Value,
plonk::{Error, Expression},
Expand Down
4 changes: 3 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/callop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ use bus_mapping::{
evm::OpcodeId,
precompile::{is_precompiled, PrecompileCalls},
};
use eth_types::{evm_types::GAS_STIPEND_CALL_WITH_VALUE, Field, ToAddress, ToScalar, U256};
use eth_types::{
evm_types::GAS_STIPEND_CALL_WITH_VALUE, Field, OpsIdentity, ToAddress, ToScalar, U256,
};
use halo2_proofs::{circuit::Value, plonk::Error};
use std::cmp::min;

Expand Down
2 changes: 1 addition & 1 deletion zkevm-circuits/src/evm_circuit/execution/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use bus_mapping::{
};
use eth_types::{
evm_types::{GasCost, INIT_CODE_WORD_GAS},
Field, ToBigEndian, ToScalar, ToWord, U256,
Field, OpsIdentity, ToBigEndian, ToScalar, ToWord, U256,
};
use ethers_core::utils::keccak256;
use gadgets::util::{and, select};
Expand Down
2 changes: 1 addition & 1 deletion zkevm-circuits/src/evm_circuit/execution/end_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
table::{CallContextFieldTag, TxContextFieldTag},
util::{word::Word, Expr},
};
use eth_types::Field;
use eth_types::{Field, OpsIdentity};
use gadgets::util::select;
use halo2_proofs::{circuit::Value, plonk::Error};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
witness::{Block, Call, ExecStep, Transaction},
};
use bus_mapping::evm::OpcodeId;
use eth_types::{Field, U256};
use eth_types::{Field, OpsIdentity, U256};
use halo2_proofs::{circuit::Value, plonk::Error};

#[derive(Clone, Debug)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
Expr,
},
};
use eth_types::{evm_types::OpcodeId, Field, ToAddress, U256};
use eth_types::{evm_types::OpcodeId, Field, OpsIdentity, ToAddress, U256};
use halo2_proofs::{circuit::Value, plonk::Error};

#[derive(Clone, Debug)]
Expand Down
2 changes: 1 addition & 1 deletion zkevm-circuits/src/evm_circuit/execution/stop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
},
};
use bus_mapping::evm::OpcodeId;
use eth_types::Field;
use eth_types::{Field, OpsIdentity};
use halo2_proofs::{circuit::Value, plonk::Error};

#[derive(Clone, Debug)]
Expand Down
4 changes: 3 additions & 1 deletion zkevm-circuits/src/evm_circuit/util/common_gadget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ use crate::{
witness::{Block, Call, ExecStep},
};
use bus_mapping::state_db::CodeDB;
use eth_types::{evm_types::GasCost, Field, ToAddress, ToLittleEndian, ToScalar, ToWord, U256};
use eth_types::{
evm_types::GasCost, Field, OpsIdentity, ToAddress, ToLittleEndian, ToScalar, ToWord, U256,
};
use gadgets::util::{select, sum};
use halo2_proofs::{
circuit::Value,
Expand Down
2 changes: 1 addition & 1 deletion zkevm-circuits/src/evm_circuit/util/constraint_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
use bus_mapping::{
circuit_input_builder::FeatureConfig, operation::Target, state_db::EMPTY_CODE_HASH_LE,
};
use eth_types::Field;
use eth_types::{Field, OpsIdentity};
use gadgets::util::{not, sum};
use halo2_proofs::{
circuit::Value,
Expand Down
24 changes: 12 additions & 12 deletions zkevm-circuits/src/mpt_circuit/account_leaf.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use eth_types::{Field, U256};
use eth_types::{Field, OpsIdentity, U256};
use gadgets::util::{pow, Scalar};
use halo2_proofs::{
circuit::Value,
Expand Down Expand Up @@ -554,10 +554,10 @@ impl<F: Field> AccountLeafConfig<F> {

// Key
let mut key_rlc = vec![0.scalar(); 2];
let mut nonce = vec![Word::zero_f(); 2];
let mut balance = vec![Word::zero_f(); 2];
let mut storage = vec![Word::zero_f(); 2];
let mut codehash = vec![Word::zero_f(); 2];
let mut nonce = vec![Word::zero(); 2];
let mut balance = vec![Word::zero(); 2];
let mut storage = vec![Word::zero(); 2];
let mut codehash = vec![Word::zero(); 2];
let mut key_data = vec![KeyDataWitness::default(); 2];
let mut parent_data = vec![ParentDataWitness::default(); 2];
for is_s in [true, false] {
Expand Down Expand Up @@ -727,11 +727,11 @@ impl<F: Field> AccountLeafConfig<F> {
} else if is_codehash_mod {
(MPTProofType::CodeHashChanged, codehash)
} else if is_account_delete_mod {
(MPTProofType::AccountDestructed, vec![Word::zero_f(); 2])
(MPTProofType::AccountDestructed, vec![Word::zero(); 2])
} else if is_non_existing_proof {
(MPTProofType::AccountDoesNotExist, vec![Word::zero_f(); 2])
(MPTProofType::AccountDoesNotExist, vec![Word::zero(); 2])
} else {
(MPTProofType::Disabled, vec![Word::zero_f(); 2])
(MPTProofType::Disabled, vec![Word::zero(); 2])
};

if account.is_mod_extension[0] || account.is_mod_extension[1] {
Expand All @@ -746,10 +746,10 @@ impl<F: Field> AccountLeafConfig<F> {
let mut new_value = value[false.idx()];
let mut old_value = value[true.idx()];
if parent_data[false.idx()].is_placeholder {
new_value = word::Word::zero_f();
new_value = word::Word::zero();
} else if is_non_existing_proof {
new_value = word::Word::zero_f();
old_value = word::Word::zero_f();
new_value = word::Word::zero();
old_value = word::Word::zero();
}
mpt_config.mpt_table.assign_cached(
region,
Expand All @@ -758,7 +758,7 @@ impl<F: Field> AccountLeafConfig<F> {
address: Value::known(from_bytes::value(
&account.address.iter().cloned().rev().collect::<Vec<_>>(),
)),
storage_key: word::Word::zero_f().into_value(),
storage_key: word::Word::zero().into_value(),
proof_type: Value::known(proof_type.scalar()),
new_root: main_data.new_root.into_value(),
old_root: main_data.old_root.into_value(),
Expand Down
4 changes: 2 additions & 2 deletions zkevm-circuits/src/mpt_circuit/branch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use eth_types::Field;
use eth_types::{Field, OpsIdentity};
use gadgets::util::Scalar;
use halo2_proofs::plonk::{Error, Expression, VirtualCells};

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

// Set the branch we'll take
let mut mod_node_hash_word = [word::Word::zero_f(); 2];
let mut mod_node_hash_word = [word::Word::zero(); 2];
let mut mod_node_hash_rlc = [0.scalar(); 2];
for is_s in [true, false] {
(
Expand Down
2 changes: 1 addition & 1 deletion zkevm-circuits/src/mpt_circuit/extension.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use eth_types::Field;
use eth_types::{Field, OpsIdentity};
use gadgets::util::{pow, Scalar};
use halo2_proofs::plonk::{Error, Expression, VirtualCells};

Expand Down
4 changes: 2 additions & 2 deletions zkevm-circuits/src/mpt_circuit/extension_branch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use eth_types::Field;
use eth_types::{Field, OpsIdentity};
use gadgets::util::Scalar;
use halo2_proofs::plonk::{Error, Expression, VirtualCells};

Expand Down Expand Up @@ -291,7 +291,7 @@ impl<F: Field> ExtensionBranchConfig<F> {
mod_node_hash_rlc[is_s.idx()],
false,
false,
Word::zero_f(),
Word::zero(),
)?;
} else {
KeyData::witness_store(
Expand Down
2 changes: 1 addition & 1 deletion zkevm-circuits/src/mpt_circuit/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
Challenges, Expr,
},
};
use eth_types::{Field, Word as U256};
use eth_types::{Field, OpsIdentity, Word as U256};
use gadgets::util::{not, or, pow, xor, Scalar};
use halo2_proofs::{
circuit::Value,
Expand Down
4 changes: 2 additions & 2 deletions zkevm-circuits/src/mpt_circuit/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
},
util::word::Word,
};
use eth_types::Field;
use eth_types::{Field, OpsIdentity};
use gadgets::util::Scalar;
use halo2_proofs::plonk::{Error, VirtualCells};

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

let mut root = vec![Word::zero_f(); 2];
let mut root = vec![Word::zero(); 2];
for is_s in [true, false] {
root[is_s.idx()] = rlp_values[is_s.idx()].word();
}
Expand Down
12 changes: 6 additions & 6 deletions zkevm-circuits/src/mpt_circuit/storage_leaf.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use eth_types::{Field, U256};
use eth_types::{Field, OpsIdentity, U256};
use gadgets::util::Scalar;
use halo2_proofs::{
circuit::Value,
Expand Down Expand Up @@ -191,7 +191,7 @@ impl<F: Field> StorageLeafConfig<F> {

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

// Make sure the RLP encoding is correct.
Expand Down Expand Up @@ -436,7 +436,7 @@ impl<F: Field> StorageLeafConfig<F> {
let mut key_data = vec![KeyDataWitness::default(); 2];
let mut parent_data = vec![ParentDataWitness::default(); 2];
let mut key_rlc = vec![0.scalar(); 2];
let mut value_word = vec![Word::zero_f(); 2];
let mut value_word = vec![Word::zero(); 2];
for is_s in [true, false] {
self.is_mod_extension[is_s.idx()].assign(
region,
Expand Down Expand Up @@ -596,10 +596,10 @@ impl<F: Field> StorageLeafConfig<F> {
let mut new_value = value_word[false.idx()];
let mut old_value = value_word[true.idx()];
if parent_data[false.idx()].is_placeholder {
new_value = word::Word::zero_f();
new_value = word::Word::zero();
} else if is_non_existing_proof {
new_value = word::Word::zero_f();
old_value = word::Word::zero_f();
new_value = word::Word::zero();
old_value = word::Word::zero();
}
mpt_config.mpt_table.assign_cached(
region,
Expand Down
32 changes: 12 additions & 20 deletions zkevm-circuits/src/util/word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// limb is 256/4 = 64 bits

use bus_mapping::state_db::CodeDB;
use eth_types::{Field, ToLittleEndian, H160, H256};
use eth_types::{Field, OpsIdentity, ToLittleEndian, H160, H256};
use gadgets::util::{not, or, Expr};
use halo2_proofs::{
circuit::{AssignedCell, Region, Value},
Expand Down Expand Up @@ -267,6 +267,17 @@ impl<F: Field> From<eth_types::Word> for Word<F> {
}
}

impl<T: Clone + OpsIdentity<Output = T>> OpsIdentity for Word<T> {
/// output type
type Output = Word<T>;
fn zero() -> Self::Output {
Word::new([T::zero(), T::zero()])
}
fn one() -> Self::Output {
Word::new([T::one(), T::zero()])
}
}

impl<F: Field> From<H256> for Word<F> {
/// Construct the word from H256
fn from(h: H256) -> Self {
Expand Down Expand Up @@ -354,16 +365,6 @@ impl<F: Field, T: Expr<F> + Clone> WordExpr<F> for Word<T> {
}

impl<F: Field> Word<F> {
/// zero word
pub fn zero_f() -> Self {
Self::new([F::ZERO, F::ZERO])
}

/// one word
pub fn one_f() -> Self {
Self::new([F::ONE, F::ZERO])
}

/// Convert address (h160) to single field element.
/// This method is Address specific
pub fn compress_f(&self) -> F {
Expand All @@ -376,15 +377,6 @@ impl<F: Field> Word<Expression<F>> {
pub fn from_lo_unchecked(lo: Expression<F>) -> Self {
Self::new([lo, 0.expr()])
}
/// zero word
pub fn zero() -> Self {
Self::new([0.expr(), 0.expr()])
}

/// one word
pub fn one() -> Self {
Self::new([1.expr(), 0.expr()])
}

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

0 comments on commit be9fed5

Please sign in to comment.