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

Commit

Permalink
unify word interface for zero/one
Browse files Browse the repository at this point in the history
  • Loading branch information
hero78119 committed Feb 5, 2024
1 parent 81e715a commit 0b4ac52
Show file tree
Hide file tree
Showing 21 changed files with 288 additions and 163 deletions.
58 changes: 54 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,32 @@ 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<T>() -> Self::Output;
/// multiplicative identity
fn one<T>() -> Self::Output;
}

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

fn one<T>() -> Self::Output {
Expression::Constant(F::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
{
/// Gets the lower 128 bits of this field element when expressed
/// canonically.
fn get_lower_128(&self) -> u128 {
Expand All @@ -65,10 +91,34 @@ pub trait Field: Halo2Field + PrimeField<Repr = [u8; 32]> + FromUniformBytes<64>
}
}

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

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

fn one<T>() -> Self::Output {
Fr::one()
}
}
// Impl custom `Field` trait for BN256 Fr to be used and consistent with the
// rest of the workspace.
impl Field for Fr {}

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

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

fn one<T>() -> Self::Output {
Fq::one()
}
}
// Impl custom `Field` trait for BN256 Frq to be used and consistent with the
// rest of the workspace.
impl Field for Fq {}
Expand Down
1 change: 0 additions & 1 deletion gadgets/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ impl<F: Field> Expr<F> for &Expression<F> {
(*self).clone()
}
}

/// Given a bytes-representation of an expression, it computes and returns the
/// single expression.
pub fn expr_from_bytes<F: Field, E: Expr<F>>(bytes: &[E]) -> Expression<F> {
Expand Down
12 changes: 9 additions & 3 deletions light-client-poc/src/circuit/state_update.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::equal_words::EqualWordsConfig;
use eth_types::Field;
use eth_types::{Field, OpsIdentity};
use eyre::Result;
use gadgets::{
is_zero::{IsZeroChip, IsZeroConfig, IsZeroInstruction},
Expand Down Expand Up @@ -68,7 +68,10 @@ pub struct StateUpdateCircuitConfig<F: Field> {

/// MPT Circuit for proving the storage modification is valid.
#[derive(Default)]
pub struct StateUpdateCircuit<F: Field> {
pub struct StateUpdateCircuit<F: Field + OpsIdentity<Output = F>>
where
<F as OpsIdentity>::Output: Field,
{
pub transforms: Transforms,
#[cfg(not(feature = "disable-keccak"))]
pub keccak_circuit: KeccakCircuit<F>,
Expand All @@ -78,7 +81,10 @@ pub struct StateUpdateCircuit<F: Field> {
pub max_proof_count: usize,
}

impl<F: Field> Circuit<F> for StateUpdateCircuit<F> {
impl<F: Field + OpsIdentity<Output = F>> Circuit<F> for StateUpdateCircuit<F>
where
<F as OpsIdentity>::Output: Field,
{
type Config = (StateUpdateCircuitConfig<F>, Challenges);
type FloorPlanner = SimpleFloorPlanner;
type Params = MPTCircuitParams;
Expand Down
46 changes: 29 additions & 17 deletions zkevm-circuits/src/evm_circuit/execution/begin_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,12 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
cb.account_write(
call_callee_address.to_word(),
AccountFieldTag::Nonce,
Word::one(),
Word::zero(),
Word::one::<Expression<F>>(),
Word::zero::<Expression<F>>(),
Some(&mut reversion_info),
);
for (field_tag, value) in [
(CallContextFieldTag::Depth, Word::one()),
(CallContextFieldTag::Depth, Word::one::<Expression<F>>()),
(
CallContextFieldTag::CallerAddress,
tx.caller_address.to_word(),
Expand All @@ -235,24 +235,30 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
CallContextFieldTag::CalleeAddress,
call_callee_address.to_word(),
),
(CallContextFieldTag::CallDataOffset, Word::zero()),
(
CallContextFieldTag::CallDataOffset,
Word::zero::<Expression<F>>(),
),
(
CallContextFieldTag::CallDataLength,
Word::from_lo_unchecked(tx.call_data_length.expr()),
),
(CallContextFieldTag::Value, tx.value.to_word()),
(CallContextFieldTag::IsStatic, Word::zero()),
(CallContextFieldTag::LastCalleeId, Word::zero()),
(CallContextFieldTag::IsStatic, Word::zero::<Expression<F>>()),
(
CallContextFieldTag::LastCalleeId,
Word::zero::<Expression<F>>(),
),
(
CallContextFieldTag::LastCalleeReturnDataOffset,
Word::zero(),
Word::zero::<Expression<F>>(),
),
(
CallContextFieldTag::LastCalleeReturnDataLength,
Word::zero(),
Word::zero::<Expression<F>>(),
),
(CallContextFieldTag::IsRoot, Word::one()),
(CallContextFieldTag::IsCreate, Word::one()),
(CallContextFieldTag::IsRoot, Word::one::<Expression<F>>()),
(CallContextFieldTag::IsCreate, Word::one::<Expression<F>>()),
(
CallContextFieldTag::CodeHash,
cb.curr.state.code_hash.to_word(),
Expand Down Expand Up @@ -349,7 +355,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
|cb| {
// Setup first call's context.
for (field_tag, value) in [
(CallContextFieldTag::Depth, Word::one()),
(CallContextFieldTag::Depth, Word::one::<Expression<F>>()),
(
CallContextFieldTag::CallerAddress,
tx.caller_address.to_word(),
Expand All @@ -358,23 +364,29 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
CallContextFieldTag::CalleeAddress,
tx.callee_address.to_word(),
),
(CallContextFieldTag::CallDataOffset, Word::zero()),
(
CallContextFieldTag::CallDataOffset,
Word::zero::<Expression<F>>(),
),
(
CallContextFieldTag::CallDataLength,
Word::from_lo_unchecked(tx.call_data_length.expr()),
),
(CallContextFieldTag::Value, tx.value.to_word()),
(CallContextFieldTag::IsStatic, Word::zero()),
(CallContextFieldTag::LastCalleeId, Word::zero()),
(CallContextFieldTag::IsStatic, Word::zero::<Expression<F>>()),
(
CallContextFieldTag::LastCalleeId,
Word::zero::<Expression<F>>(),
),
(
CallContextFieldTag::LastCalleeReturnDataOffset,
Word::zero(),
Word::zero::<Expression<F>>(),
),
(
CallContextFieldTag::LastCalleeReturnDataLength,
Word::zero(),
Word::zero::<Expression<F>>(),
),
(CallContextFieldTag::IsRoot, Word::one()),
(CallContextFieldTag::IsRoot, Word::one::<Expression<F>>()),
(
CallContextFieldTag::IsCreate,
Word::from_lo_unchecked(tx.is_create.expr()),
Expand Down
22 changes: 14 additions & 8 deletions zkevm-circuits/src/evm_circuit/execution/callop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ use bus_mapping::{
precompile::{is_precompiled, PrecompileCalls},
};
use eth_types::{evm_types::GAS_STIPEND_CALL_WITH_VALUE, Field, ToAddress, ToScalar, U256};
use halo2_proofs::{circuit::Value, plonk::Error};
use halo2_proofs::{
circuit::Value,
plonk::{Error, Expression},
};
use std::cmp::min;

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

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

cb.require_step_state_transition(StepStateTransition {
Expand Down Expand Up @@ -689,17 +692,20 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
CallContextFieldTag::IsStatic,
Word::from_lo_unchecked(or::expr([is_static.expr(), is_staticcall.expr()])),
),
(CallContextFieldTag::LastCalleeId, Word::zero()),
(
CallContextFieldTag::LastCalleeId,
Word::zero::<Expression<F>>(),
),
(
CallContextFieldTag::LastCalleeReturnDataOffset,
Word::zero(),
Word::zero::<Expression<F>>(),
),
(
CallContextFieldTag::LastCalleeReturnDataLength,
Word::zero(),
Word::zero::<Expression<F>>(),
),
(CallContextFieldTag::IsRoot, Word::zero()),
(CallContextFieldTag::IsCreate, Word::zero()),
(CallContextFieldTag::IsRoot, Word::zero::<Expression<F>>()),
(CallContextFieldTag::IsCreate, Word::zero::<Expression<F>>()),
(
CallContextFieldTag::CodeHash,
call_gadget.callee_code_hash.to_word(),
Expand Down
14 changes: 9 additions & 5 deletions zkevm-circuits/src/evm_circuit/execution/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
CallContextFieldTag::LastCalleeReturnDataOffset,
CallContextFieldTag::LastCalleeReturnDataLength,
] {
cb.call_context_lookup_write(None, field_tag, Word::zero());
cb.call_context_lookup_write(None, field_tag, Word::zero::<Expression<F>>());
}

cb.require_step_state_transition(StepStateTransition {
Expand Down Expand Up @@ -342,8 +342,8 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
cb.account_write(
contract_addr.to_word(),
AccountFieldTag::Nonce,
Word::one(),
Word::zero(),
Word::one::<Expression<F>>(),
Word::zero::<Expression<F>>(),
Some(&mut callee_reversion_info),
);

Expand Down Expand Up @@ -420,7 +420,11 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
CallContextFieldTag::LastCalleeReturnDataOffset,
CallContextFieldTag::LastCalleeReturnDataLength,
] {
cb.call_context_lookup_write(None, field_tag, Word::zero());
cb.call_context_lookup_write(
None,
field_tag,
Word::zero::<Expression<F>>(),
);
}
cb.require_step_state_transition(StepStateTransition {
rw_counter: Delta(cb.rw_counter_offset()),
Expand Down Expand Up @@ -463,7 +467,7 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
CallContextFieldTag::LastCalleeReturnDataOffset,
CallContextFieldTag::LastCalleeReturnDataLength,
] {
cb.call_context_lookup_write(None, field_tag, Word::zero());
cb.call_context_lookup_write(None, field_tag, Word::zero::<Expression<F>>());
}

cb.require_step_state_transition(StepStateTransition {
Expand Down
7 changes: 5 additions & 2 deletions zkevm-circuits/src/evm_circuit/execution/end_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use crate::{
};
use eth_types::Field;
use gadgets::util::select;
use halo2_proofs::{circuit::Value, plonk::Error};
use halo2_proofs::{
circuit::Value,
plonk::{Error, Expression},
};

#[derive(Clone, Debug)]
pub(crate) struct EndBlockGadget<F> {
Expand Down Expand Up @@ -74,7 +77,7 @@ impl<F: Field> ExecutionGadget<F> for EndBlockGadget<F> {
total_txs.expr() + 1.expr(),
TxContextFieldTag::CallerAddress,
None,
Word::zero(),
Word::zero::<Expression<F>>(),
);
// Since every tx lookup done in the EVM circuit must succeed
// and uses a unique tx_id, we know that at
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use crate::{
};
use bus_mapping::evm::OpcodeId;
use eth_types::{Field, U256};
use halo2_proofs::{circuit::Value, plonk::Error};
use halo2_proofs::{
circuit::Value,
plonk::{Error, Expression},
};

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

for (field_tag, value) in [
(CallContextFieldTag::LastCalleeId, callee_call_id.expr()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use crate::{
},
};
use eth_types::{evm_types::OpcodeId, Field, ToAddress, U256};
use halo2_proofs::{circuit::Value, plonk::Error};
use halo2_proofs::{
circuit::Value,
plonk::{Error, Expression},
};

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

// current call context is readonly
cb.call_context_lookup_read(None, CallContextFieldTag::IsStatic, Word::one());
cb.call_context_lookup_read(
None,
CallContextFieldTag::IsStatic,
Word::one::<Expression<F>>(),
);

// constrain not root call as at least one previous staticcall preset.
cb.require_zero(
Expand Down
Loading

0 comments on commit 0b4ac52

Please sign in to comment.