From cd5edab478bedc742300decb0f7e15717077610b Mon Sep 17 00:00:00 2001 From: Chih Cheng Liang Date: Thu, 15 Feb 2024 19:03:28 +0800 Subject: [PATCH] Streamline the math gadget API (#1765) ### Description We improve the readability by sweeping gadget constructors under the constraint builder. ### Issue Link Quick search and replace ### Type of change Refactor (no updates to logic) ### Contents - changed `XGadget::construct(cb, ...)` to `cb.x(...)` - some IsZero checks are replaced with IsEqual checks. ### Rationale We keep consumption of the following gadgets unchanged because they are not used frequently enough. - abs_word - add_word - binary_number - byte_size - cmp_words - comparison - modulo - mul_add_words - mul_add_words512 - mul_word_u64 --- .../src/evm_circuit/execution/addmod.rs | 2 +- .../src/evm_circuit/execution/balance.rs | 2 +- .../src/evm_circuit/execution/begin_tx.rs | 7 +- .../src/evm_circuit/execution/byte.rs | 2 +- .../src/evm_circuit/execution/callop.rs | 58 ++++++++--------- .../src/evm_circuit/execution/comparator.rs | 4 +- .../src/evm_circuit/execution/create.rs | 20 +++--- .../src/evm_circuit/execution/end_block.rs | 11 ++-- .../src/evm_circuit/execution/end_tx.rs | 4 +- .../evm_circuit/execution/error_code_store.rs | 3 +- .../execution/error_invalid_creation_code.rs | 2 +- .../execution/error_invalid_jump.rs | 6 +- .../execution/error_oog_account_access.rs | 3 +- .../evm_circuit/execution/error_oog_call.rs | 2 +- .../execution/error_oog_constant.rs | 3 +- .../evm_circuit/execution/error_oog_create.rs | 5 +- .../evm_circuit/execution/error_oog_log.rs | 4 +- .../execution/error_oog_precompile.rs | 3 +- .../execution/error_oog_static_memory.rs | 2 +- .../execution/error_return_data_oo_bound.rs | 7 +- .../execution/error_write_protection.rs | 11 ++-- .../src/evm_circuit/execution/exp.rs | 6 +- .../src/evm_circuit/execution/extcodecopy.rs | 2 +- .../src/evm_circuit/execution/extcodesize.rs | 2 +- .../src/evm_circuit/execution/invalid_tx.rs | 5 +- .../src/evm_circuit/execution/is_zero.rs | 2 +- .../src/evm_circuit/execution/jumpi.rs | 2 +- .../src/evm_circuit/execution/memory.rs | 4 +- .../src/evm_circuit/execution/mul_div_mod.rs | 4 +- .../src/evm_circuit/execution/mulmod.rs | 4 +- .../src/evm_circuit/execution/push.rs | 12 ++-- .../evm_circuit/execution/return_revert.rs | 5 +- .../src/evm_circuit/execution/sar.rs | 20 +++--- .../src/evm_circuit/execution/sdiv_smod.rs | 8 +-- .../src/evm_circuit/execution/shl_shr.rs | 9 ++- .../execution/signed_comparator.rs | 8 +-- .../src/evm_circuit/execution/signextend.rs | 5 +- .../src/evm_circuit/execution/sstore.rs | 16 ++--- .../src/evm_circuit/util/common_gadget.rs | 25 ++++--- .../evm_circuit/util/constraint_builder.rs | 65 +++++++++++++++++-- .../evm_circuit/util/math_gadget/abs_word.rs | 2 +- .../util/math_gadget/comparison.rs | 4 +- .../evm_circuit/util/math_gadget/is_equal.rs | 2 +- .../util/math_gadget/is_equal_word.rs | 14 ++-- .../evm_circuit/util/math_gadget/lt_word.rs | 2 +- .../evm_circuit/util/math_gadget/min_max.rs | 2 +- .../evm_circuit/util/math_gadget/modulo.rs | 8 +-- .../src/evm_circuit/util/math_gadget/rlp.rs | 2 +- .../src/evm_circuit/util/memory_gadget.rs | 13 ++-- zkevm-circuits/src/evm_circuit/util/tx.rs | 5 +- 50 files changed, 230 insertions(+), 189 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/addmod.rs b/zkevm-circuits/src/evm_circuit/execution/addmod.rs index c8def073eb..9bd928a7ce 100644 --- a/zkevm-circuits/src/evm_circuit/execution/addmod.rs +++ b/zkevm-circuits/src/evm_circuit/execution/addmod.rs @@ -69,7 +69,7 @@ impl ExecutionGadget for AddModGadget { let a_reduced = cb.query_word32(); let d = cb.query_word32(); - let n_is_zero = IsZeroWordGadget::construct(cb, &n); + let n_is_zero = cb.is_zero_word(&n); // 1. check k * N + a_reduced == a without overflow let muladd_k_n_areduced = diff --git a/zkevm-circuits/src/evm_circuit/execution/balance.rs b/zkevm-circuits/src/evm_circuit/execution/balance.rs index ccc4809cc8..ef3f6dfeea 100644 --- a/zkevm-circuits/src/evm_circuit/execution/balance.rs +++ b/zkevm-circuits/src/evm_circuit/execution/balance.rs @@ -60,7 +60,7 @@ impl ExecutionGadget for BalanceGadget { AccountFieldTag::CodeHash, code_hash.to_word(), ); - let not_exists = IsZeroWordGadget::construct(cb, &code_hash); + let not_exists = cb.is_zero_word(&code_hash); let exists = not::expr(not_exists.expr()); let balance = cb.query_word32(); cb.condition(exists.expr(), |cb| { diff --git a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs index fc4e2f321b..80de4c1973 100644 --- a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs @@ -81,7 +81,7 @@ impl ExecutionGadget for BeginTxGadget { let gas_left = tx.gas.expr() - tx.intrinsic_gas(); let sufficient_gas_left = RangeCheckGadget::construct(cb, gas_left.clone()); - let tx_caller_address_is_zero = IsZeroWordGadget::construct(cb, &tx.caller_address); + let tx_caller_address_is_zero = cb.is_zero_word(&tx.caller_address); cb.require_equal( "CallerAddress != 0 (not a padding tx)", tx_caller_address_is_zero.expr(), @@ -155,9 +155,8 @@ impl ExecutionGadget for BeginTxGadget { // Read code_hash of callee let code_hash = cb.query_word_unchecked(); - let is_empty_code_hash = - IsEqualWordGadget::construct(cb, &code_hash.to_word(), &cb.empty_code_hash()); - let callee_not_exists = IsZeroWordGadget::construct(cb, &code_hash); + let is_empty_code_hash = cb.is_eq_word(&code_hash.to_word(), &cb.empty_code_hash()); + let callee_not_exists = cb.is_zero_word(&code_hash); // no_callee_code is true when the account exists and has empty // code hash, or when the account doesn't exist (which we encode with // code_hash = 0). diff --git a/zkevm-circuits/src/evm_circuit/execution/byte.rs b/zkevm-circuits/src/evm_circuit/execution/byte.rs index dd3b89ac68..fb06fb0579 100644 --- a/zkevm-circuits/src/evm_circuit/execution/byte.rs +++ b/zkevm-circuits/src/evm_circuit/execution/byte.rs @@ -53,7 +53,7 @@ impl ExecutionGadget for ByteGadget { let is_byte_selected = array_init(|idx| { // Check if this byte is selected looking only at the LSB of the // index word - IsEqualGadget::construct(cb, index.limbs[0].expr(), (31 - idx).expr()) + cb.is_eq(index.limbs[0].expr(), (31 - idx).expr()) }); // Sum all possible selected bytes diff --git a/zkevm-circuits/src/evm_circuit/execution/callop.rs b/zkevm-circuits/src/evm_circuit/execution/callop.rs index 4af82c36bb..66716640c1 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callop.rs @@ -11,7 +11,8 @@ use crate::{ Transition::{Delta, To}, }, math_gadget::{ - ConstantDivisionGadget, IsZeroGadget, LtGadget, LtWordGadget, MinMaxGadget, + ConstantDivisionGadget, IsEqualGadget, IsZeroGadget, LtGadget, LtWordGadget, + MinMaxGadget, }, memory_gadget::{CommonMemoryAddressGadget, MemoryAddressGadget}, not, or, @@ -44,10 +45,10 @@ use std::cmp::min; pub(crate) struct CallOpGadget { opcode: Cell, - is_call: IsZeroGadget, - is_callcode: IsZeroGadget, - is_delegatecall: IsZeroGadget, - is_staticcall: IsZeroGadget, + is_call: IsEqualGadget, + is_callcode: IsEqualGadget, + is_delegatecall: IsEqualGadget, + is_staticcall: IsEqualGadget, tx_id: Cell, reversion_info: ReversionInfo, current_callee_address: WordLoHiCell, @@ -94,12 +95,10 @@ impl ExecutionGadget for CallOpGadget { fn configure(cb: &mut EVMConstraintBuilder) -> Self { let opcode = cb.query_cell(); cb.opcode_lookup(opcode.expr(), 1.expr()); - let is_call = IsZeroGadget::construct(cb, opcode.expr() - OpcodeId::CALL.expr()); - let is_callcode = IsZeroGadget::construct(cb, opcode.expr() - OpcodeId::CALLCODE.expr()); - let is_delegatecall = - IsZeroGadget::construct(cb, opcode.expr() - OpcodeId::DELEGATECALL.expr()); - let is_staticcall = - IsZeroGadget::construct(cb, opcode.expr() - OpcodeId::STATICCALL.expr()); + let is_call = cb.is_eq(opcode.expr(), OpcodeId::CALL.expr()); + let is_callcode = cb.is_eq(opcode.expr(), OpcodeId::CALLCODE.expr()); + let is_delegatecall = cb.is_eq(opcode.expr(), OpcodeId::DELEGATECALL.expr()); + let is_staticcall = cb.is_eq(opcode.expr(), OpcodeId::STATICCALL.expr()); // Use rw_counter of the step which triggers next call as its call_id. let callee_call_id = cb.curr.state.rw_counter.clone(); @@ -196,9 +195,9 @@ impl ExecutionGadget for CallOpGadget { // rwc_delta = 8 + is_delegatecall * 2 + call_gadget.rw_delta() + // callee_reversion_info.rw_delta() let is_insufficient_balance = - LtWordGadget::construct(cb, &caller_balance.to_word(), &call_gadget.value.to_word()); + cb.is_lt_word(&caller_balance.to_word(), &call_gadget.value.to_word()); // depth < 1025 - let is_depth_ok = LtGadget::construct(cb, depth.expr(), 1025.expr()); + let is_depth_ok = cb.is_lt(depth.expr(), 1025.expr()); let is_precheck_ok = and::expr([ is_depth_ok.expr(), @@ -215,18 +214,15 @@ impl ExecutionGadget for CallOpGadget { // whether the call is to a precompiled contract. // precompile contracts are stored from address 0x01 to 0x09. - let is_code_address_zero = IsZeroGadget::construct(cb, call_gadget.callee_address.expr()); - let is_precompile_lt = - LtGadget::construct(cb, call_gadget.callee_address.expr(), 0x0A.expr()); + let is_code_address_zero = cb.is_zero(call_gadget.callee_address.expr()); + let is_precompile_lt = cb.is_lt(call_gadget.callee_address.expr(), 0x0A.expr()); let is_precompile = and::expr([ not::expr(is_code_address_zero.expr()), is_precompile_lt.expr(), ]); let precompile_return_length = cb.query_cell(); - let precompile_return_length_zero = - IsZeroGadget::construct(cb, precompile_return_length.expr()); - let precompile_return_data_copy_size = MinMaxGadget::construct( - cb, + let precompile_return_length_zero = cb.is_zero(precompile_return_length.expr()); + let precompile_return_data_copy_size = cb.min_max( precompile_return_length.expr(), call_gadget.rd_address.length(), ); @@ -275,10 +271,10 @@ impl ExecutionGadget for CallOpGadget { let gas_cost = call_gadget.gas_cost_expr(is_warm_prev.expr(), is_call.expr()); // Apply EIP 150 let gas_available = cb.curr.state.gas_left.expr() - gas_cost.clone(); - let one_64th_gas = ConstantDivisionGadget::construct(cb, gas_available.clone(), 64); + let one_64th_gas = cb.div_by_const(gas_available.clone(), 64); let all_but_one_64th_gas = gas_available - one_64th_gas.quotient(); let capped_callee_gas_left = - MinMaxGadget::construct(cb, call_gadget.gas_expr(), all_but_one_64th_gas.clone()); + cb.min_max(call_gadget.gas_expr(), all_but_one_64th_gas.clone()); let callee_gas_left = select::expr( call_gadget.gas_is_u64.expr(), capped_callee_gas_left.min(), @@ -480,10 +476,10 @@ impl ExecutionGadget for CallOpGadget { let callee_gas_left = callee_gas_left.expr() + call_gadget.has_value.clone() * GAS_STIPEND_CALL_WITH_VALUE.expr(); - let precompile_output_word_size_div: ConstantDivisionGadget = - ConstantDivisionGadget::construct(cb, precompile_output_rws.expr(), 32); + let precompile_output_word_size_div = + cb.div_by_const(precompile_output_rws.expr(), 32); let precompile_output_word_size_div_remainder_zero = - IsZeroGadget::construct(cb, precompile_output_word_size_div.remainder()); + cb.is_zero(precompile_output_word_size_div.remainder()); let precompile_output_word_size = precompile_output_word_size_div.quotient() + 1.expr() - precompile_output_word_size_div_remainder_zero.expr(); @@ -891,22 +887,26 @@ impl ExecutionGadget for CallOpGadget { self.is_call.assign( region, offset, - F::from(opcode.as_u64()) - F::from(OpcodeId::CALL.as_u64()), + F::from(opcode.as_u64()), + F::from(OpcodeId::CALL.as_u64()), )?; self.is_callcode.assign( region, offset, - F::from(opcode.as_u64()) - F::from(OpcodeId::CALLCODE.as_u64()), + F::from(opcode.as_u64()), + F::from(OpcodeId::CALLCODE.as_u64()), )?; self.is_delegatecall.assign( region, offset, - F::from(opcode.as_u64()) - F::from(OpcodeId::DELEGATECALL.as_u64()), + F::from(opcode.as_u64()), + F::from(OpcodeId::DELEGATECALL.as_u64()), )?; self.is_staticcall.assign( region, offset, - F::from(opcode.as_u64()) - F::from(OpcodeId::STATICCALL.as_u64()), + F::from(opcode.as_u64()), + F::from(OpcodeId::STATICCALL.as_u64()), )?; self.tx_id .assign(region, offset, Value::known(F::from(tx_id.low_u64())))?; diff --git a/zkevm-circuits/src/evm_circuit/execution/comparator.rs b/zkevm-circuits/src/evm_circuit/execution/comparator.rs index 5dcfbca0b8..a0f81f8109 100644 --- a/zkevm-circuits/src/evm_circuit/execution/comparator.rs +++ b/zkevm-circuits/src/evm_circuit/execution/comparator.rs @@ -41,10 +41,10 @@ impl ExecutionGadget for ComparatorGadget { let b = cb.query_word_unchecked(); // Check if opcode is EQ - let is_eq = IsEqualGadget::construct(cb, opcode.expr(), OpcodeId::EQ.expr()); + let is_eq = cb.is_eq(opcode.expr(), OpcodeId::EQ.expr()); // Check if opcode is GT. For GT we swap the stack inputs so that we // actually do greater than instead of smaller than. - let is_gt = IsEqualGadget::construct(cb, opcode.expr(), OpcodeId::GT.expr()); + let is_gt = cb.is_eq(opcode.expr(), OpcodeId::GT.expr()); let word_comparison = CmpWordsGadget::construct(cb, a.clone(), b.clone()); diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index 61b842308d..9b560a16ce 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -13,7 +13,7 @@ use crate::{ Transition::{Delta, To}, }, math_gadget::{ - ConstantDivisionGadget, ContractCreateGadget, IsZeroGadget, IsZeroWordGadget, + ConstantDivisionGadget, ContractCreateGadget, IsEqualGadget, IsZeroWordGadget, LtGadget, LtWordGadget, }, memory_gadget::{ @@ -53,7 +53,7 @@ pub(crate) struct CreateGadget, depth: Cell, - is_create2: IsZeroGadget, + is_create2: IsEqualGadget, is_success: Cell, was_warm: Cell, value: Word32Cell, @@ -95,7 +95,7 @@ impl ExecutionGadget< opcode.expr(), vec![OpcodeId::CREATE2.expr(), OpcodeId::CREATE.expr()], ); - let is_create2 = IsZeroGadget::construct(cb, opcode.expr() - OpcodeId::CREATE2.expr()); + let is_create2 = cb.is_eq(opcode.expr(), OpcodeId::CREATE2.expr()); // Use rw_counter of the step which triggers next call as its call_id. let callee_call_id = cb.curr.state.rw_counter.clone(); @@ -143,10 +143,9 @@ impl ExecutionGadget< ); // Pre-check: call depth, user's nonce and user's balance - let is_depth_in_range = LtGadget::construct(cb, depth.expr(), 1025.expr()); - let is_insufficient_balance = - LtWordGadget::construct(cb, &caller_balance.to_word(), &value.to_word()); - let is_nonce_in_range = LtGadget::construct(cb, caller_nonce.expr(), u64::MAX.expr()); + let is_depth_in_range = cb.is_lt(depth.expr(), 1025.expr()); + let is_insufficient_balance = cb.is_lt_word(&caller_balance.to_word(), &value.to_word()); + let is_nonce_in_range = cb.is_lt(caller_nonce.expr(), u64::MAX.expr()); let is_precheck_ok = and::expr([ is_depth_in_range.expr(), not::expr(is_insufficient_balance.expr()), @@ -169,7 +168,7 @@ impl ExecutionGadget< ); let gas_cost = GasCost::CREATE.expr() + memory_expansion.gas_cost() + keccak_gas_cost; let gas_remaining = cb.curr.state.gas_left.expr() - gas_cost.clone(); - let gas_left = ConstantDivisionGadget::construct(cb, gas_remaining.clone(), 64); + let gas_left = cb.div_by_const(gas_remaining.clone(), 64); let callee_gas_left = gas_remaining - gas_left.quotient(); let was_warm = cb.query_bool(); @@ -209,7 +208,7 @@ impl ExecutionGadget< // empty_code_hash_word))` to represent `(callee_nonce == 0 && (prev_code_hash_word // == 0 or prev_code_hash_word == empty_code_hash_word))` let prev_code_hash_word = prev_code_hash.to_word(); - let prev_code_hash_is_zero = IsZeroWordGadget::construct(cb, &prev_code_hash_word); + let prev_code_hash_is_zero = cb.is_zero_word(&prev_code_hash_word); cb.condition(not::expr(prev_code_hash_is_zero.expr()), |cb| { cb.account_read( contract_addr.to_word(), @@ -525,7 +524,8 @@ impl ExecutionGadget< self.is_create2.assign( region, offset, - F::from(opcode.as_u64()) - F::from(OpcodeId::CREATE2.as_u64()), + F::from(opcode.as_u64()), + F::from(OpcodeId::CREATE2.as_u64()), )?; self.tx_id diff --git a/zkevm-circuits/src/evm_circuit/execution/end_block.rs b/zkevm-circuits/src/evm_circuit/execution/end_block.rs index 51e35e2d5e..63c5e530e1 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_block.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_block.rs @@ -6,7 +6,7 @@ use crate::{ constraint_builder::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition::Same, }, - math_gadget::{IsEqualGadget, IsZeroGadget}, + math_gadget::IsEqualGadget, not, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, @@ -22,7 +22,7 @@ use halo2_proofs::{circuit::Value, plonk::Error}; pub(crate) struct EndBlockGadget { total_txs: Cell, total_txs_is_max_txs: IsEqualGadget, - is_empty_block: IsZeroGadget, + is_empty_block: IsEqualGadget, max_rws: Cell, max_txs: Cell, } @@ -36,10 +36,9 @@ impl ExecutionGadget for EndBlockGadget { let max_txs = cb.query_copy_cell(); let max_rws = cb.query_copy_cell(); let total_txs = cb.query_cell(); - let total_txs_is_max_txs = IsEqualGadget::construct(cb, total_txs.expr(), max_txs.expr()); + let total_txs_is_max_txs = cb.is_eq(total_txs.expr(), max_txs.expr()); // Note that rw_counter starts at 1 - let is_empty_block = - IsZeroGadget::construct(cb, cb.curr.state.rw_counter.clone().expr() - 1.expr()); + let is_empty_block = cb.is_eq(cb.curr.state.rw_counter.clone().expr(), 1.expr()); let total_rws_before_padding = cb.curr.state.rw_counter.clone().expr() - 1.expr() + select::expr( @@ -126,7 +125,7 @@ impl ExecutionGadget for EndBlockGadget { step: &ExecStep, ) -> Result<(), Error> { self.is_empty_block - .assign(region, offset, F::from(u64::from(step.rwc) - 1))?; + .assign(region, offset, F::from(u64::from(step.rwc)), F::ONE)?; let max_rws = F::from(block.circuits_params.max_rws as u64); let max_rws_assigned = self.max_rws.assign(region, offset, Value::known(max_rws))?; diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index e8bfc5b779..8c68776fdc 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -67,7 +67,7 @@ impl ExecutionGadget for EndTxGadget { ); let refund = cb.query_cell(); cb.tx_refund_read(tx_id.expr(), WordLoHi::from_lo_unchecked(refund.expr())); - let effective_refund = MinMaxGadget::construct(cb, max_refund.quotient(), refund.expr()); + let effective_refund = cb.min_max(max_refund.quotient(), refund.expr()); // Add effective_refund * tx_gas_price back to caller's balance let mul_gas_price_by_refund = MulWordByU64Gadget::construct( @@ -85,7 +85,7 @@ impl ExecutionGadget for EndTxGadget { // Add gas_used * effective_tip to coinbase's balance let coinbase = cb.query_word_unchecked(); let coinbase_code_hash = cb.query_word_unchecked(); - let coinbase_code_hash_is_zero = IsZeroWordGadget::construct(cb, &coinbase_code_hash); + let coinbase_code_hash_is_zero = cb.is_zero_word(&coinbase_code_hash); cb.account_read( coinbase.to_word(), AccountFieldTag::CodeHash, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs b/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs index 3440bd9f44..2506639307 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs @@ -72,8 +72,7 @@ impl ExecutionGadget for ErrorCodeStoreGadget { ); // constrain code size > MAXCODESIZE - let max_code_size_exceed = - LtGadget::construct(cb, MAXCODESIZE.expr(), memory_address.length()); + let max_code_size_exceed = cb.is_lt(MAXCODESIZE.expr(), memory_address.length()); // check must be one of CodeStoreOutOfGas or MaxCodeSizeExceeded cb.require_in_set( diff --git a/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs b/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs index e076a831bc..6b7482046a 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs @@ -46,7 +46,7 @@ impl ExecutionGadget for ErrorInvalidCreationCodeGadget { cb.memory_lookup(0.expr(), memory_address.offset(), first_byte.expr(), None); let is_first_byte_invalid = - IsEqualGadget::construct(cb, first_byte.expr(), INVALID_INIT_CODE_FIRST_BYTE.expr()); + cb.is_eq(first_byte.expr(), INVALID_INIT_CODE_FIRST_BYTE.expr()); cb.require_true( "is_first_byte_invalid is true", is_first_byte_invalid.expr(), diff --git a/zkevm-circuits/src/evm_circuit/execution/error_invalid_jump.rs b/zkevm-circuits/src/evm_circuit/execution/error_invalid_jump.rs index e5b40f5f71..6fab8e624b 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_invalid_jump.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_invalid_jump.rs @@ -54,14 +54,14 @@ impl ExecutionGadget for ErrorInvalidJumpGadget { vec![OpcodeId::JUMP.expr(), OpcodeId::JUMPI.expr()], ); - let is_jumpi = IsEqualGadget::construct(cb, opcode.expr(), OpcodeId::JUMPI.expr()); + let is_jumpi = cb.is_eq(opcode.expr(), OpcodeId::JUMPI.expr()); // initialize is_jump_dest - let is_jump_dest = IsEqualGadget::construct(cb, value.expr(), OpcodeId::JUMPDEST.expr()); + let is_jump_dest = cb.is_eq(value.expr(), OpcodeId::JUMPDEST.expr()); // first default this condition, if use will re-construct with real condition // value - let is_condition_zero = IsZeroWordGadget::construct(cb, &condition); + let is_condition_zero = cb.is_zero_word(&condition); // Pop the value from the stack cb.stack_pop(dest.original_word().to_word()); diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_account_access.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_account_access.rs index 9e36738ef2..7878b67252 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_account_access.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_account_access.rs @@ -62,8 +62,7 @@ impl ExecutionGadget for ErrorOOGAccountAccessGadget { GasCost::COLD_ACCOUNT_ACCESS.expr(), ); - let insufficient_gas_cost = - LtGadget::construct(cb, cb.curr.state.gas_left.expr(), gas_cost); + let insufficient_gas_cost = cb.is_lt(cb.curr.state.gas_left.expr(), gas_cost); cb.require_equal( "Gas left is less than gas cost", diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_call.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_call.rs index 38aeae1db7..53b61484aa 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_call.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_call.rs @@ -79,7 +79,7 @@ impl ExecutionGadget for ErrorOOGCallGadget { let gas_cost = call_gadget.gas_cost_expr(is_warm.expr(), is_call.expr()); // Check if the amount of gas available is less than the amount of gas required - let insufficient_gas = LtGadget::construct(cb, cb.curr.state.gas_left.expr(), gas_cost); + let insufficient_gas = cb.is_lt(cb.curr.state.gas_left.expr(), gas_cost); cb.require_equal( "Either Memory address is overflow or gas left is less than cost", diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_constant.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_constant.rs index acaec49d6d..c0061b31c5 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_constant.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_constant.rs @@ -38,8 +38,7 @@ impl ExecutionGadget for ErrorOOGConstantGadget { cb.constant_gas_lookup(opcode.expr(), gas_required.expr()); // Check if the amount of gas available is less than the amount of gas // required - let insufficient_gas = - LtGadget::construct(cb, cb.curr.state.gas_left.expr(), gas_required.expr()); + let insufficient_gas = cb.is_lt(cb.curr.state.gas_left.expr(), gas_required.expr()); cb.require_equal( "constant gas left is less than gas required ", insufficient_gas.expr(), diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs index b22619ae01..99756d1d23 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs @@ -68,8 +68,7 @@ impl ExecutionGadget for ErrorOOGCreateGadget { cb.stack_pop(memory_address.length_word()); cb.condition(is_create2.expr().0, |cb| cb.stack_pop(salt.to_word())); - let init_code_size_overflow = - LtGadget::construct(cb, MAX_INIT_CODE_SIZE.expr(), memory_address.length()); + let init_code_size_overflow = cb.is_lt(MAX_INIT_CODE_SIZE.expr(), memory_address.length()); let minimum_word_size = MemoryWordSizeGadget::construct(cb, memory_address.length()); let memory_expansion = MemoryExpansionGadget::construct(cb, [memory_address.address()]); @@ -81,7 +80,7 @@ impl ExecutionGadget for ErrorOOGCreateGadget { CREATE_GAS_PER_CODE_WORD.expr(), ); let gas_cost = GasCost::CREATE.expr() + memory_expansion.gas_cost() + code_store_gas_cost; - let insufficient_gas = LtGadget::construct(cb, cb.curr.state.gas_left.expr(), gas_cost); + let insufficient_gas = cb.is_lt(cb.curr.state.gas_left.expr(), gas_cost); cb.require_equal( "Memory address is overflow, init code size is overflow, or gas left is less than cost", diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs index 4dbb9f4a24..bf129c5088 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs @@ -55,7 +55,7 @@ impl ExecutionGadget for ErrorOOGLogGadget { cb.require_zero("is_static_call is false in LOGN", is_static_call.expr()); let topic_count = opcode.expr() - OpcodeId::LOG0.as_u8().expr(); - let is_opcode_logn = LtGadget::construct(cb, topic_count.clone(), 5.expr()); + let is_opcode_logn = cb.is_lt(topic_count.clone(), 5.expr()); cb.require_equal( "topic count in [0..5) which means opcode is Log0...Log4 ", is_opcode_logn.expr(), @@ -73,7 +73,7 @@ impl ExecutionGadget for ErrorOOGLogGadget { // Check if the amount of gas available is less than the amount of gas // required - let insufficient_gas = LtGadget::construct(cb, cb.curr.state.gas_left.expr(), gas_cost); + let insufficient_gas = cb.is_lt(cb.curr.state.gas_left.expr(), gas_cost); cb.require_equal( "Memory address is overflow or gas left is less than cost", or::expr([memory_address.overflow(), insufficient_gas.expr()]), diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_precompile.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_precompile.rs index 72ebf106e9..4dd3df7ca8 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_precompile.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_precompile.rs @@ -114,8 +114,7 @@ impl ExecutionGadget for ErrorOOGPrecompileGadget { ); // gas_left < required_gas - let insufficient_gas = - LtGadget::construct(cb, cb.curr.state.gas_left.expr(), required_gas.expr()); + let insufficient_gas = cb.is_lt(cb.curr.state.gas_left.expr(), required_gas.expr()); cb.require_equal("gas_left < required_gas", insufficient_gas.expr(), 1.expr()); let restore_context = RestoreContextGadget::construct2( diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_static_memory.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_static_memory.rs index 588d8c4cc4..948062ce7d 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_static_memory.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_static_memory.rs @@ -55,7 +55,7 @@ impl ExecutionGadget for ErrorOOGStaticMemoryGadget { ); // Check if this is an MSTORE8 - let is_mstore8 = IsEqualGadget::construct(cb, opcode.expr(), OpcodeId::MSTORE8.expr()); + let is_mstore8 = cb.is_eq(opcode.expr(), OpcodeId::MSTORE8.expr()); // pop memory_offset from stack let memory_address = MemoryExpandedAddressGadget::construct_self(cb); diff --git a/zkevm-circuits/src/evm_circuit/execution/error_return_data_oo_bound.rs b/zkevm-circuits/src/evm_circuit/execution/error_return_data_oo_bound.rs index a20954ef5f..52a9839239 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_return_data_oo_bound.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_return_data_oo_bound.rs @@ -69,18 +69,17 @@ impl ExecutionGadget for ErrorReturnDataOutOfBoundGadget { // Check if `data_offset` is Uint64 overflow. let data_offset_larger_u64 = sum::expr(&data_offset.limbs[N_BYTES_U64..]); - let is_data_offset_within_u64 = IsZeroGadget::construct(cb, data_offset_larger_u64); + let is_data_offset_within_u64 = cb.is_zero(data_offset_larger_u64); // Check if `remainder_end` is Uint64 overflow. let sum = AddWordsGadget::construct(cb, [data_offset, size], remainder_end.clone()); let is_end_u256_overflow = sum.carry().as_ref().unwrap(); let remainder_end_larger_u64 = sum::expr(&remainder_end.limbs[N_BYTES_U64..]); - let is_remainder_end_within_u64 = IsZeroGadget::construct(cb, remainder_end_larger_u64); + let is_remainder_end_within_u64 = cb.is_zero(remainder_end_larger_u64); // check if `remainder_end` exceeds return data length. - let is_remainder_end_exceed_len = LtGadget::construct( - cb, + let is_remainder_end_exceed_len = cb.is_lt( return_data_length.expr(), from_bytes::expr(&remainder_end.limbs[..N_BYTES_U64]), ); diff --git a/zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs b/zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs index 9e148bc6d3..531bdc9813 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs @@ -5,7 +5,7 @@ use crate::{ util::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, - math_gadget::{IsZeroGadget, IsZeroWordGadget}, + math_gadget::{IsEqualGadget, IsZeroWordGadget}, AccountAddress, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, @@ -22,7 +22,7 @@ use halo2_proofs::{circuit::Value, plonk::Error}; #[derive(Clone, Debug)] pub(crate) struct ErrorWriteProtectionGadget { opcode: Cell, - is_call: IsZeroGadget, + is_call: IsEqualGadget, gas: WordLoHiCell, code_address: AccountAddress, value: WordLoHiCell, @@ -37,11 +37,11 @@ impl ExecutionGadget for ErrorWriteProtectionGadget { fn configure(cb: &mut EVMConstraintBuilder) -> Self { let opcode = cb.query_cell(); - let is_call = IsZeroGadget::construct(cb, opcode.expr() - OpcodeId::CALL.expr()); + let is_call = cb.is_eq(opcode.expr(), OpcodeId::CALL.expr()); let gas_word = cb.query_word_unchecked(); let code_address = cb.query_account_address(); let value = cb.query_word_unchecked(); - let is_value_zero = IsZeroWordGadget::construct(cb, &value); + let is_value_zero = cb.is_zero_word(&value); // require_in_set method will spilit into more low degree expressions if exceed // max_degree. otherwise need to do fixed lookup for these opcodes @@ -122,7 +122,8 @@ impl ExecutionGadget for ErrorWriteProtectionGadget { self.is_call.assign( region, offset, - F::from(opcode.as_u64()) - F::from(OpcodeId::CALL.as_u64()), + F::from(opcode.as_u64()), + F::from(OpcodeId::CALL.as_u64()), )?; self.is_value_zero .assign(region, offset, WordLoHi::from(value))?; diff --git a/zkevm-circuits/src/evm_circuit/execution/exp.rs b/zkevm-circuits/src/evm_circuit/execution/exp.rs index 0945e2819e..24de01a70e 100644 --- a/zkevm-circuits/src/evm_circuit/execution/exp.rs +++ b/zkevm-circuits/src/evm_circuit/execution/exp.rs @@ -78,11 +78,11 @@ impl ExecutionGadget for ExponentiationGadget { // We simplify constraints depending on whether or not the exponent is 0 or 1. // In order to do this, we build some utility expressions. - let exponent_lo_is_zero = IsZeroGadget::construct(cb, exponent_lo.clone()); - let exponent_hi_is_zero = IsZeroGadget::construct(cb, exponent_hi.clone()); + let exponent_lo_is_zero = cb.is_zero(exponent_lo.clone()); + let exponent_hi_is_zero = cb.is_zero(exponent_hi.clone()); let exponent_is_zero_expr = and::expr([exponent_lo_is_zero.expr(), exponent_hi_is_zero.expr()]); - let exponent_lo_is_one = IsEqualGadget::construct(cb, exponent_lo.clone(), 1.expr()); + let exponent_lo_is_one = cb.is_eq(exponent_lo.clone(), 1.expr()); let exponent_is_one_expr = and::expr([exponent_lo_is_one.expr(), exponent_hi_is_zero.expr()]); diff --git a/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs b/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs index f7e8ba4793..bb05e5237d 100644 --- a/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs @@ -91,7 +91,7 @@ impl ExecutionGadget for ExtcodecopyGadget { AccountFieldTag::CodeHash, code_hash.to_word(), ); - let not_exists = IsZeroWordGadget::construct(cb, &code_hash.to_word()); + let not_exists = cb.is_zero_word(&code_hash.to_word()); let exists = not::expr(not_exists.expr()); cb.condition(exists.expr(), |cb| { cb.bytecode_length(code_hash.to_word(), code_size.expr()); diff --git a/zkevm-circuits/src/evm_circuit/execution/extcodesize.rs b/zkevm-circuits/src/evm_circuit/execution/extcodesize.rs index 631f75cf85..908b1e2b7b 100644 --- a/zkevm-circuits/src/evm_circuit/execution/extcodesize.rs +++ b/zkevm-circuits/src/evm_circuit/execution/extcodesize.rs @@ -69,7 +69,7 @@ impl ExecutionGadget for ExtcodesizeGadget { AccountFieldTag::CodeHash, code_hash.to_word(), ); - let not_exists = IsZeroWordGadget::construct(cb, &code_hash); + let not_exists = cb.is_zero_word(&code_hash); let exists = not::expr(not_exists.expr()); let code_size = cb.query_u64(); diff --git a/zkevm-circuits/src/evm_circuit/execution/invalid_tx.rs b/zkevm-circuits/src/evm_circuit/execution/invalid_tx.rs index a87dc847e6..1100175592 100644 --- a/zkevm-circuits/src/evm_circuit/execution/invalid_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/invalid_tx.rs @@ -47,7 +47,7 @@ impl ExecutionGadget for InvalidTxGadget { AccountFieldTag::Nonce, WordLoHi::from_lo_unchecked(account_nonce.expr()), ); - let is_nonce_match = IsEqualGadget::construct(cb, account_nonce.expr(), tx.nonce.expr()); + let is_nonce_match = cb.is_eq(account_nonce.expr(), tx.nonce.expr()); // Check if the gas limit is larger or equal to the intrinsic gas cost let insufficient_gas_limit = @@ -60,8 +60,7 @@ impl ExecutionGadget for InvalidTxGadget { AccountFieldTag::Balance, balance.to_word(), ); - let insufficient_balance = - LtWordGadget::construct(cb, &balance.to_word(), &tx.total_cost().to_word()); + let insufficient_balance = cb.is_lt_word(&balance.to_word(), &tx.total_cost().to_word()); // At least one of the invalid conditions needs to be true let invalid_tx = or::expr([ diff --git a/zkevm-circuits/src/evm_circuit/execution/is_zero.rs b/zkevm-circuits/src/evm_circuit/execution/is_zero.rs index 1c9b189808..c2f52e4100 100644 --- a/zkevm-circuits/src/evm_circuit/execution/is_zero.rs +++ b/zkevm-circuits/src/evm_circuit/execution/is_zero.rs @@ -34,7 +34,7 @@ impl ExecutionGadget for IsZeroGadget { let opcode = cb.query_cell(); let value = cb.query_word_unchecked(); - let is_zero_word = math_gadget::IsZeroWordGadget::construct(cb, &value); + let is_zero_word = cb.is_zero_word(&value); cb.stack_pop(value.to_word()); cb.stack_push(WordLoHi::from_lo_unchecked(is_zero_word.expr())); diff --git a/zkevm-circuits/src/evm_circuit/execution/jumpi.rs b/zkevm-circuits/src/evm_circuit/execution/jumpi.rs index 67e7b343c7..40b9878ea0 100644 --- a/zkevm-circuits/src/evm_circuit/execution/jumpi.rs +++ b/zkevm-circuits/src/evm_circuit/execution/jumpi.rs @@ -44,7 +44,7 @@ impl ExecutionGadget for JumpiGadget { cb.stack_pop(condition.to_word()); // Determine if the jump condition is met - let is_condition_zero = IsZeroWordGadget::construct(cb, &condition); + let is_condition_zero = cb.is_zero_word(&condition); let should_jump = 1.expr() - is_condition_zero.expr(); // Lookup opcode at destination when should_jump diff --git a/zkevm-circuits/src/evm_circuit/execution/memory.rs b/zkevm-circuits/src/evm_circuit/execution/memory.rs index 3aa47184ff..2956730d7f 100644 --- a/zkevm-circuits/src/evm_circuit/execution/memory.rs +++ b/zkevm-circuits/src/evm_circuit/execution/memory.rs @@ -46,9 +46,9 @@ impl ExecutionGadget for MemoryGadget { let value = cb.query_word32(); // Check if this is an MLOAD - let is_mload = IsEqualGadget::construct(cb, opcode.expr(), OpcodeId::MLOAD.expr()); + let is_mload = cb.is_eq(opcode.expr(), OpcodeId::MLOAD.expr()); // Check if this is an MSTORE8 - let is_mstore8 = IsEqualGadget::construct(cb, opcode.expr(), OpcodeId::MSTORE8.expr()); + let is_mstore8 = cb.is_eq(opcode.expr(), OpcodeId::MSTORE8.expr()); // This is an MSTORE/MSTORE8 let is_store = not::expr(is_mload.expr()); // This is an MSTORE/MLOAD diff --git a/zkevm-circuits/src/evm_circuit/execution/mul_div_mod.rs b/zkevm-circuits/src/evm_circuit/execution/mul_div_mod.rs index 84290e6bf3..19bf5f2735 100644 --- a/zkevm-circuits/src/evm_circuit/execution/mul_div_mod.rs +++ b/zkevm-circuits/src/evm_circuit/execution/mul_div_mod.rs @@ -63,8 +63,8 @@ impl ExecutionGadget for MulDivModGadget { let d = cb.query_word32(); let mul_add_words = MulAddWordsGadget::construct(cb, [&a, &b, &c, &d]); - let divisor_is_zero = IsZeroWordGadget::construct(cb, &b); - let lt_word = LtWordGadget::construct(cb, &c.to_word(), &b.to_word()); + let divisor_is_zero = cb.is_zero_word(&b); + let lt_word = cb.is_lt_word(&c.to_word(), &b.to_word()); // Pop a and b from the stack, push result on the stack // The first pop is multiplier for MUL and dividend for DIV/MOD diff --git a/zkevm-circuits/src/evm_circuit/execution/mulmod.rs b/zkevm-circuits/src/evm_circuit/execution/mulmod.rs index 6b6f7299d2..d2d021c6f7 100644 --- a/zkevm-circuits/src/evm_circuit/execution/mulmod.rs +++ b/zkevm-circuits/src/evm_circuit/execution/mulmod.rs @@ -70,8 +70,8 @@ impl ExecutionGadget for MulModGadget { let mul512_right = MulAddWords512Gadget::construct(cb, [&k, &n, &d, &e], Some(&r)); // (r < n ) or n == 0 - let n_is_zero = IsZeroWordGadget::construct(cb, &n); - let lt = LtWordGadget::construct(cb, &r.to_word(), &n.to_word()); + let n_is_zero = cb.is_zero_word(&n); + let lt = cb.is_lt_word(&r.to_word(), &n.to_word()); cb.add_constraint( " (1 - (r < n) - (n==0)) ", 1.expr() - lt.expr() - n_is_zero.expr(), diff --git a/zkevm-circuits/src/evm_circuit/execution/push.rs b/zkevm-circuits/src/evm_circuit/execution/push.rs index 2948da9272..d6e95b6552 100644 --- a/zkevm-circuits/src/evm_circuit/execution/push.rs +++ b/zkevm-circuits/src/evm_circuit/execution/push.rs @@ -10,7 +10,7 @@ use crate::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition::Delta, }, - math_gadget::{IsZeroGadget, LtGadget}, + math_gadget::{IsEqualGadget, LtGadget}, not, or, select, sum, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, @@ -27,7 +27,7 @@ use halo2_proofs::{circuit::Value, plonk::Error}; #[derive(Clone, Debug)] pub(crate) struct PushGadget { same_context: SameContextGadget, - is_push0: IsZeroGadget, + is_push0: IsEqualGadget, value: Word32Cell, is_pushed: [Cell; 32], is_padding: [Cell; 32], @@ -42,7 +42,7 @@ impl ExecutionGadget for PushGadget { fn configure(cb: &mut EVMConstraintBuilder) -> Self { let opcode = cb.query_cell(); - let is_push0 = IsZeroGadget::construct(cb, opcode.expr() - OpcodeId::PUSH0.expr()); + let is_push0 = cb.is_eq(opcode.expr(), OpcodeId::PUSH0.expr()); let value = cb.query_word32(); cb.stack_push(value.to_word()); @@ -56,8 +56,7 @@ impl ExecutionGadget for PushGadget { cb.bytecode_length(cb.curr.state.code_hash.to_word(), code_length.expr()); let num_bytes_needed = opcode.expr() - OpcodeId::PUSH0.expr(); - let is_out_of_bound = - LtGadget::construct(cb, code_length_left.expr(), num_bytes_needed.expr()); + let is_out_of_bound = cb.is_lt(code_length_left.expr(), num_bytes_needed.expr()); let num_bytes_padding = select::expr( is_out_of_bound.expr(), num_bytes_needed.expr() - code_length_left.expr(), @@ -170,7 +169,8 @@ impl ExecutionGadget for PushGadget { self.is_push0.assign( region, offset, - F::from(opcode.as_u64() - OpcodeId::PUSH0.as_u64()), + F::from(opcode.as_u64()), + OpcodeId::PUSH0.as_u64().into(), )?; let bytecode = block diff --git a/zkevm-circuits/src/evm_circuit/execution/return_revert.rs b/zkevm-circuits/src/evm_circuit/execution/return_revert.rs index d0b7bd1dcb..02a1a5854a 100644 --- a/zkevm-circuits/src/evm_circuit/execution/return_revert.rs +++ b/zkevm-circuits/src/evm_circuit/execution/return_revert.rs @@ -92,7 +92,7 @@ impl ExecutionGadget for ReturnRevertGadget { // These are globally defined because they are used across multiple cases. let copy_rw_increase = cb.query_cell(); - let copy_rw_increase_is_zero = IsZeroGadget::construct(cb, copy_rw_increase.expr()); + let copy_rw_increase_is_zero = cb.is_zero(copy_rw_increase.expr()); let memory_expansion = MemoryExpansionGadget::construct(cb, [range.address()]); @@ -218,8 +218,7 @@ impl ExecutionGadget for ReturnRevertGadget { CallContextFieldTag::ReturnDataLength, ] .map(|field_tag| cb.call_context(None, field_tag)); - let copy_length = - MinMaxGadget::construct(cb, return_data_length.expr(), range.length()); + let copy_length = cb.min_max(return_data_length.expr(), range.length()); cb.require_equal( "increase rw counter twice for each memory to memory byte copied", copy_length.min() + copy_length.min(), diff --git a/zkevm-circuits/src/evm_circuit/execution/sar.rs b/zkevm-circuits/src/evm_circuit/execution/sar.rs index 9cfb4ac939..fd09750a16 100644 --- a/zkevm-circuits/src/evm_circuit/execution/sar.rs +++ b/zkevm-circuits/src/evm_circuit/execution/sar.rs @@ -99,8 +99,8 @@ impl ExecutionGadget for SarGadget { let p_lo = cb.query_cell(); let p_hi = cb.query_cell(); let p_top = cb.query_cell(); - let is_neg = LtGadget::construct(cb, 127.expr(), a.limbs[31].expr()); - let shf_lt256 = IsZeroGadget::construct(cb, sum::expr(&shift.limbs[1..32])); + let is_neg = cb.is_lt(127.expr(), a.limbs[31].expr()); + let shf_lt256 = cb.is_zero(sum::expr(&shift.limbs[1..32])); for idx in 0..4 { cb.require_equal( @@ -112,23 +112,23 @@ impl ExecutionGadget for SarGadget { // Constrain `a64s_lo[idx] < p_lo`. let a64s_lo_lt_p_lo = array_init(|idx| { - let lt = LtGadget::construct(cb, a64s_lo[idx].expr(), p_lo.expr()); + let lt = cb.is_lt(a64s_lo[idx].expr(), p_lo.expr()); cb.require_zero("a64s_lo[idx] < p_lo", 1.expr() - lt.expr()); lt }); // Constrain `a64s_hi[idx] < p_hi`. let a64s_hi_lt_p_hi = array_init(|idx| { - let lt = LtGadget::construct(cb, a64s_hi[idx].expr(), p_hi.expr()); + let lt = cb.is_lt(a64s_hi[idx].expr(), p_hi.expr()); cb.require_zero("a64s_hi[idx] < p_hi", 1.expr() - lt.expr()); lt }); // Merge contraints - let shf_lo_div64_eq0 = IsZeroGadget::construct(cb, shf_div64.expr()); - let shf_lo_div64_eq1 = IsEqualGadget::construct(cb, shf_div64.expr(), 1.expr()); - let shf_lo_div64_eq2 = IsEqualGadget::construct(cb, shf_div64.expr(), 2.expr()); - let shf_lo_div64_eq3 = IsEqualGadget::construct(cb, shf_div64.expr(), 3.expr()); + let shf_lo_div64_eq0 = cb.is_zero(shf_div64.expr()); + let shf_lo_div64_eq1 = cb.is_eq(shf_div64.expr(), 1.expr()); + let shf_lo_div64_eq2 = cb.is_eq(shf_div64.expr(), 2.expr()); + let shf_lo_div64_eq3 = cb.is_eq(shf_div64.expr(), 3.expr()); let shf_div64_eq0 = shf_lt256.expr() * shf_lo_div64_eq0.expr(); let shf_div64_eq1 = shf_lt256.expr() * shf_lo_div64_eq1.expr(); let shf_div64_eq2 = shf_lt256.expr() * shf_lo_div64_eq2.expr(); @@ -179,9 +179,9 @@ impl ExecutionGadget for SarGadget { ); // Shift constraint - let shf_div64_lt_4 = LtGadget::construct(cb, shf_div64.expr(), 4.expr()); + let shf_div64_lt_4 = cb.is_lt(shf_div64.expr(), 4.expr()); cb.require_equal("shf_div64 < 4", shf_div64_lt_4.expr(), 1.expr()); - let shf_mod64_lt_64 = LtGadget::construct(cb, shf_mod64.expr(), 64.expr()); + let shf_mod64_lt_64 = cb.is_lt(shf_mod64.expr(), 64.expr()); cb.require_equal("shf_mod64 < 64", shf_mod64_lt_64.expr(), 1.expr()); cb.require_equal( "shift[0] == shf_mod64 + shf_div64 * 64", diff --git a/zkevm-circuits/src/evm_circuit/execution/sdiv_smod.rs b/zkevm-circuits/src/evm_circuit/execution/sdiv_smod.rs index 85a271661d..b6779c420f 100644 --- a/zkevm-circuits/src/evm_circuit/execution/sdiv_smod.rs +++ b/zkevm-circuits/src/evm_circuit/execution/sdiv_smod.rs @@ -52,9 +52,9 @@ impl ExecutionGadget for SignedDivModGadget { let divisor_abs = AbsWordGadget::construct(cb); let remainder_abs = AbsWordGadget::construct(cb); let dividend_abs = AbsWordGadget::construct(cb); - let quotient_is_zero = IsZeroWordGadget::construct(cb, quotient_abs.x()); - let divisor_is_zero = IsZeroWordGadget::construct(cb, divisor_abs.x()); - let remainder_is_zero = IsZeroWordGadget::construct(cb, remainder_abs.x()); + let quotient_is_zero = cb.is_zero_word(quotient_abs.x()); + let divisor_is_zero = cb.is_zero_word(divisor_abs.x()); + let remainder_is_zero = cb.is_zero_word(remainder_abs.x()); cb.stack_pop(dividend_abs.x().to_word()); cb.stack_pop(divisor_abs.x().to_word()); @@ -109,7 +109,7 @@ impl ExecutionGadget for SignedDivModGadget { // `sign(dividend) == sign(divisor) ^ sign(quotient)` cannot be applied // for this case. let dividend_is_signed_overflow = - LtGadget::construct(cb, 127.expr(), dividend_abs.x_abs().limbs[31].expr()); + cb.is_lt(127.expr(), dividend_abs.x_abs().limbs[31].expr()); // Constrain sign(dividend) == sign(divisor) ^ sign(quotient) when both // quotient and divisor are non-zero and dividend is not signed overflow. diff --git a/zkevm-circuits/src/evm_circuit/execution/shl_shr.rs b/zkevm-circuits/src/evm_circuit/execution/shl_shr.rs index 92c614d861..ef822f0074 100644 --- a/zkevm-circuits/src/evm_circuit/execution/shl_shr.rs +++ b/zkevm-circuits/src/evm_circuit/execution/shl_shr.rs @@ -69,11 +69,10 @@ impl ExecutionGadget for ShlShrGadget { let mul_add_words = MulAddWordsGadget::construct(cb, ["ient, &divisor, &remainder, ÷nd]); - let shf_lt256 = IsZeroGadget::construct(cb, sum::expr(&shift.limbs[1..32])); - let divisor_is_zero = IsZeroWordGadget::construct(cb, &divisor); - let remainder_is_zero = IsZeroWordGadget::construct(cb, &remainder); - let remainder_lt_divisor = - LtWordGadget::construct(cb, &remainder.to_word(), &divisor.to_word()); + let shf_lt256 = cb.is_zero(sum::expr(&shift.limbs[1..32])); + let divisor_is_zero = cb.is_zero_word(&divisor); + let remainder_is_zero = cb.is_zero_word(&remainder); + let remainder_lt_divisor = cb.is_lt_word(&remainder.to_word(), &divisor.to_word()); // Constrain stack pops and pushes as: // - for SHL, two pops are shift and quotient, and push is dividend. diff --git a/zkevm-circuits/src/evm_circuit/execution/signed_comparator.rs b/zkevm-circuits/src/evm_circuit/execution/signed_comparator.rs index c6ebfcfe35..2211fa90d5 100644 --- a/zkevm-circuits/src/evm_circuit/execution/signed_comparator.rs +++ b/zkevm-circuits/src/evm_circuit/execution/signed_comparator.rs @@ -51,7 +51,7 @@ impl ExecutionGadget for SignedComparatorGadget { // The Signed Comparator gadget is used for both opcodes SLT and SGT. // Depending on whether the opcode is SLT or SGT, we // swap the order in which the inputs are placed on the stack. - let is_sgt = IsEqualGadget::construct(cb, opcode.expr(), OpcodeId::SGT.expr()); + let is_sgt = cb.is_eq(opcode.expr(), OpcodeId::SGT.expr()); // Both a and b are to be treated as two's complement signed 256-bit // (32 cells) integers. This means, the first bit denotes the sign @@ -59,8 +59,8 @@ impl ExecutionGadget for SignedComparatorGadget { // number is negative if the most significant cell >= 128 // (0b10000000). a and b being in the little-endian notation, the // most-significant byte is the last byte. - let sign_check_a = LtGadget::construct(cb, a.limbs[31].expr(), 128.expr()); - let sign_check_b = LtGadget::construct(cb, b.limbs[31].expr(), 128.expr()); + let sign_check_a = cb.is_lt(a.limbs[31].expr(), 128.expr()); + let sign_check_b = cb.is_lt(b.limbs[31].expr(), 128.expr()); // sign_check_a_lt expression implies a is positive since its MSB < 2**7 // sign_check_b_lt expression implies b is positive since its MSB < 2**7 @@ -77,7 +77,7 @@ impl ExecutionGadget for SignedComparatorGadget { // b_hi) && (a_lo < b_lo))) let (a_lo, a_hi) = a.to_word().to_lo_hi(); let (b_lo, b_hi) = b.to_word().to_lo_hi(); - let lt_lo = LtGadget::construct(cb, a_lo, b_lo); + let lt_lo = cb.is_lt(a_lo, b_lo); let comparison_hi = ComparisonGadget::construct(cb, a_hi, b_hi); let a_lt_b_lo = lt_lo.expr(); let (a_lt_b_hi, a_eq_b_hi) = comparison_hi.expr(); diff --git a/zkevm-circuits/src/evm_circuit/execution/signextend.rs b/zkevm-circuits/src/evm_circuit/execution/signextend.rs index fbf48b3d2c..093688bea0 100644 --- a/zkevm-circuits/src/evm_circuit/execution/signextend.rs +++ b/zkevm-circuits/src/evm_circuit/execution/signextend.rs @@ -52,12 +52,11 @@ impl ExecutionGadget for SignextendGadget { // need to do any changes. So just sum all the non-LSB byte // values here and then check if it's non-zero so we can use // that as an additional condition to enable the selector. - let is_msb_sum_zero = IsZeroGadget::construct(cb, sum::expr(&index.limbs[1..32])); + let is_msb_sum_zero = cb.is_zero(sum::expr(&index.limbs[1..32])); // Check if this byte is selected looking only at the LSB of the index // word - let is_byte_selected = - array_init(|idx| IsEqualGadget::construct(cb, index.limbs[0].expr(), idx.expr())); + let is_byte_selected = array_init(|idx| cb.is_eq(index.limbs[0].expr(), idx.expr())); // We need to find the byte we have to get the sign from so we can // extend correctly. We go byte by byte and check if `idx == diff --git a/zkevm-circuits/src/evm_circuit/execution/sstore.rs b/zkevm-circuits/src/evm_circuit/execution/sstore.rs index 244e1595c0..ebcb7b52db 100644 --- a/zkevm-circuits/src/evm_circuit/execution/sstore.rs +++ b/zkevm-circuits/src/evm_circuit/execution/sstore.rs @@ -248,16 +248,14 @@ impl SstoreTxRefundGadget { value_prev: T, original_value: T, ) -> Self { - let value_prev_is_zero_gadget = IsZeroWordGadget::construct(cb, &value_prev.to_word()); - let value_is_zero_gadget = IsZeroWordGadget::construct(cb, &value.to_word()); - let original_is_zero_gadget = IsZeroWordGadget::construct(cb, &original_value.to_word()); - - let original_eq_value_gadget = - IsEqualWordGadget::construct(cb, &original_value.to_word(), &value.to_word()); - let prev_eq_value_gadget = - IsEqualWordGadget::construct(cb, &value_prev.to_word(), &value.to_word()); + let value_prev_is_zero_gadget = cb.is_zero_word(&value_prev.to_word()); + let value_is_zero_gadget = cb.is_zero_word(&value.to_word()); + let original_is_zero_gadget = cb.is_zero_word(&original_value.to_word()); + + let original_eq_value_gadget = cb.is_eq_word(&original_value.to_word(), &value.to_word()); + let prev_eq_value_gadget = cb.is_eq_word(&value_prev.to_word(), &value.to_word()); let original_eq_prev_gadget = - IsEqualWordGadget::construct(cb, &original_value.to_word(), &value_prev.to_word()); + cb.is_eq_word(&original_value.to_word(), &value_prev.to_word()); let value_prev_is_zero = value_prev_is_zero_gadget.expr(); let value_is_zero = value_is_zero_gadget.expr(); diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 420051b90c..0c323be986 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -385,7 +385,7 @@ impl TransferToGadget { mut reversion_info: Option<&mut ReversionInfo>, account_write: bool, ) -> Self { - let value_is_zero = IsZeroWordGadget::construct(cb, &value); + let value_is_zero = cb.is_zero_word(&value); if account_write { Self::create_account( cb, @@ -497,7 +497,7 @@ impl TransferWithGasFeeGadget { ) -> Self { let sender_sub_fee = UpdateBalanceGadget::construct(cb, sender_address.to_word(), vec![gas_fee], None); - let value_is_zero = IsZeroWordGadget::construct(cb, &value); + let value_is_zero = cb.is_zero_word(&value); // If receiver doesn't exist, create it TransferToGadget::create_account( cb, @@ -618,7 +618,7 @@ impl TransferGadget { value: Word32Cell, reversion_info: &mut ReversionInfo, ) -> Self { - let value_is_zero = IsZeroWordGadget::construct(cb, &value); + let value_is_zero = cb.is_zero_word(&value); // If receiver doesn't exist, create it TransferToGadget::create_account( cb, @@ -773,12 +773,12 @@ impl, const IS_SUCCESS_CAL }); // Recomposition of random linear combination to integer - let gas_is_u64 = IsZeroGadget::construct(cb, sum::expr(&gas_word.limbs[N_BYTES_GAS..])); + let gas_is_u64 = cb.is_zero(sum::expr(&gas_word.limbs[N_BYTES_GAS..])); let memory_expansion = MemoryExpansionGadget::construct(cb, [cd_address.address(), rd_address.address()]); // construct common gadget - let value_is_zero = IsZeroWordGadget::construct(cb, &value); + let value_is_zero = cb.is_zero_word(&value); let has_value = select::expr( is_delegatecall.expr() + is_staticcall.expr(), 0.expr(), @@ -791,9 +791,8 @@ impl, const IS_SUCCESS_CAL AccountFieldTag::CodeHash, callee_code_hash.to_word(), ); - let is_empty_code_hash = - IsEqualWordGadget::construct(cb, &callee_code_hash, &cb.empty_code_hash()); - let callee_not_exists = IsZeroWordGadget::construct(cb, &callee_code_hash); + let is_empty_code_hash = cb.is_eq_word(&callee_code_hash, &cb.empty_code_hash()); + let callee_not_exists = cb.is_zero_word(&callee_code_hash); Self { is_success, @@ -973,9 +972,9 @@ impl + Clone> SstoreGasGadget { value_prev: T, original_value: T, ) -> Self { - let value_eq_prev = IsEqualWordGadget::construct(cb, &value, &value_prev); - let original_eq_prev = IsEqualWordGadget::construct(cb, &original_value, &value_prev); - let original_is_zero = IsZeroWordGadget::construct(cb, &original_value); + let value_eq_prev = cb.is_eq_word(&value, &value_prev); + let original_eq_prev = cb.is_eq_word(&original_value, &value_prev); + let original_is_zero = cb.is_zero_word(&original_value); let warm_case_gas = select::expr( value_eq_prev.expr(), GasCost::WARM_ACCESS.expr(), @@ -1193,7 +1192,7 @@ impl WordByteCapGadget { pub(crate) fn construct(cb: &mut EVMConstraintBuilder, cap: Expression) -> Self { let word = WordByteRangeGadget::construct(cb); let value = select::expr(word.overflow(), cap.expr(), word.valid_value()); - let lt_cap = LtGadget::construct(cb, value, cap); + let lt_cap = cb.is_lt(value, cap); Self { word, lt_cap } } @@ -1255,7 +1254,7 @@ impl WordByteRangeGadget { debug_assert!(VALID_BYTES < 32); let original = cb.query_word32(); - let not_overflow = IsZeroGadget::construct(cb, sum::expr(&original.limbs[VALID_BYTES..])); + let not_overflow = cb.is_zero(sum::expr(&original.limbs[VALID_BYTES..])); Self { original, diff --git a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs index a38026c1ab..8d58c5b18e 100644 --- a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs +++ b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs @@ -1,3 +1,10 @@ +use super::{ + math_gadget::{ + ConstantDivisionGadget, IsEqualGadget, IsEqualWordGadget, IsZeroGadget, IsZeroWordGadget, + LtGadget, LtWordGadget, MinMaxGadget, + }, + rlc, AccountAddress, CachedRegion, CellType, MemoryAddress, StoredExpression, U64Cell, +}; use crate::{ evm_circuit::{ param::STACK_CAPACITY, @@ -29,10 +36,6 @@ use halo2_proofs::{ }, }; -use super::{ - rlc, AccountAddress, CachedRegion, CellType, MemoryAddress, StoredExpression, U64Cell, -}; - // Max degree allowed in all expressions passing through the ConstraintBuilder. // It aims to cap `extended_k` to 2, which allows constraint degree to 2^2+1, // but each ExecutionGadget has implicit selector degree 3, so here it only @@ -581,6 +584,60 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> { constrain!(log_id); } + // Math gadgets + + pub(crate) fn is_zero(&mut self, value: Expression) -> IsZeroGadget { + IsZeroGadget::construct(self, value) + } + + pub(crate) fn is_zero_word>(&mut self, value: &T) -> IsZeroWordGadget { + IsZeroWordGadget::construct(self, value) + } + + pub(crate) fn is_eq(&mut self, lhs: Expression, rhs: Expression) -> IsEqualGadget { + IsEqualGadget::construct(self, lhs, rhs) + } + + pub(crate) fn is_eq_word, T2: WordExpr>( + &mut self, + lhs: &T1, + rhs: &T2, + ) -> IsEqualWordGadget { + IsEqualWordGadget::construct(self, lhs, rhs) + } + + pub(crate) fn is_lt( + &mut self, + lhs: Expression, + rhs: Expression, + ) -> LtGadget { + LtGadget::construct(self, lhs, rhs) + } + + pub(crate) fn is_lt_word + Clone>( + &mut self, + lhs: &WordLoHi, + rhs: &WordLoHi, + ) -> LtWordGadget { + LtWordGadget::construct(self, lhs, rhs) + } + + pub(crate) fn min_max( + &mut self, + lhs: Expression, + rhs: Expression, + ) -> MinMaxGadget { + MinMaxGadget::construct(self, lhs, rhs) + } + + pub(crate) fn div_by_const( + &mut self, + numerator: Expression, + denominator: u64, + ) -> ConstantDivisionGadget { + ConstantDivisionGadget::construct(self, numerator, denominator) + } + // Fixed pub(crate) fn range_lookup(&mut self, value: Expression, range: u64) { diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/abs_word.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/abs_word.rs index 119e7d77a2..7778c33950 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/abs_word.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/abs_word.rs @@ -38,7 +38,7 @@ impl AbsWordGadget { let sum = cb.query_word32(); let (x_lo, x_hi) = x.to_word().to_lo_hi(); let (x_abs_lo, x_abs_hi) = x_abs.to_word().to_lo_hi(); - let is_neg = LtGadget::construct(cb, 127.expr(), x.limbs[31].expr()); + let is_neg = cb.is_lt(127.expr(), x.limbs[31].expr()); cb.add_constraint( "x_abs_lo == x_lo when x >= 0", diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/comparison.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/comparison.rs index 5568ec54c4..af4d244f1d 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/comparison.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/comparison.rs @@ -21,8 +21,8 @@ impl ComparisonGadget { lhs: Expression, rhs: Expression, ) -> Self { - let lt = LtGadget::::construct(cb, lhs, rhs); - let eq = IsZeroGadget::::construct(cb, sum::expr(<.diff_bytes())); + let lt = cb.is_lt(lhs, rhs); + let eq = cb.is_zero(sum::expr(<.diff_bytes())); Self { lt, eq } } diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/is_equal.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/is_equal.rs index f0ddb64048..69c8c092b8 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/is_equal.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/is_equal.rs @@ -16,7 +16,7 @@ impl IsEqualGadget { lhs: Expression, rhs: Expression, ) -> Self { - let is_zero = IsZeroGadget::construct(cb, lhs - rhs); + let is_zero = cb.is_zero(lhs - rhs); Self { is_zero } } diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/is_equal_word.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/is_equal_word.rs index 75ebc05f85..b7bb201251 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/is_equal_word.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/is_equal_word.rs @@ -14,13 +14,13 @@ use crate::{ util::word::{WordExpr, WordLoHi}, }; -use super::IsZeroGadget; +use super::IsEqualGadget; /// Returns `1` when `lhs == rhs`, and returns `0` otherwise. #[derive(Clone, Debug)] pub struct IsEqualWordGadget { - is_zero_lo: IsZeroGadget, - is_zero_hi: IsZeroGadget, + is_zero_lo: IsEqualGadget, + is_zero_hi: IsEqualGadget, _marker: PhantomData<(T1, T2)>, } @@ -28,8 +28,8 @@ impl, T2: WordExpr> IsEqualWordGadget { pub(crate) fn construct(cb: &mut EVMConstraintBuilder, lhs: &T1, rhs: &T2) -> Self { let (lhs_lo, lhs_hi) = lhs.to_word().to_lo_hi(); let (rhs_lo, rhs_hi) = rhs.to_word().to_lo_hi(); - let is_zero_lo = IsZeroGadget::construct(cb, lhs_lo - rhs_lo); - let is_zero_hi = IsZeroGadget::construct(cb, lhs_hi - rhs_hi); + let is_zero_lo = cb.is_eq(lhs_lo, rhs_lo); + let is_zero_hi = cb.is_eq(lhs_hi, rhs_hi); Self { is_zero_lo, @@ -51,8 +51,8 @@ impl, T2: WordExpr> IsEqualWordGadget { ) -> Result { let (lhs_lo, lhs_hi) = lhs.to_lo_hi(); let (rhs_lo, rhs_hi) = rhs.to_lo_hi(); - self.is_zero_lo.assign(region, offset, lhs_lo - rhs_lo)?; - self.is_zero_hi.assign(region, offset, lhs_hi - rhs_hi)?; + self.is_zero_lo.assign(region, offset, lhs_lo, rhs_lo)?; + self.is_zero_hi.assign(region, offset, lhs_hi, rhs_hi)?; Ok(F::from(2)) } diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/lt_word.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/lt_word.rs index c27825aa4a..b5499f2e1b 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/lt_word.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/lt_word.rs @@ -24,7 +24,7 @@ impl LtWordGadget { let (lhs_lo, lhs_hi) = lhs.to_lo_hi(); let (rhs_lo, rhs_hi) = rhs.to_lo_hi(); let comparison_hi = ComparisonGadget::construct(cb, lhs_hi.expr(), rhs_hi.expr()); - let lt_lo = LtGadget::construct(cb, lhs_lo.expr(), rhs_lo.expr()); + let lt_lo = cb.is_lt(lhs_lo.expr(), rhs_lo.expr()); Self { comparison_hi, lt_lo, diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/min_max.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/min_max.rs index ee6b101ab8..f5201d40e1 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/min_max.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/min_max.rs @@ -19,7 +19,7 @@ impl MinMaxGadget { lhs: Expression, rhs: Expression, ) -> Self { - let lt = LtGadget::construct(cb, lhs.clone(), rhs.clone()); + let lt = cb.is_lt(lhs.clone(), rhs.clone()); let max = select::expr(lt.expr(), rhs.clone(), lhs.clone()); let min = select::expr(lt.expr(), lhs, rhs); diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs index 3409c4861d..28779640cf 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs @@ -36,11 +36,11 @@ impl ModGadget { let (a, n, r) = (words[0], words[1], words[2]); let k = cb.query_word32(); let a_or_zero = cb.query_word32(); - let n_is_zero = IsZeroWordGadget::construct(cb, n); - let a_or_is_zero = IsZeroWordGadget::construct(cb, &a_or_zero); + let n_is_zero = cb.is_zero_word(n); + let a_or_is_zero = cb.is_zero_word(&a_or_zero); let mul_add_words = MulAddWordsGadget::construct(cb, [&k, n, r, &a_or_zero]); - let eq = IsEqualWordGadget::construct(cb, a, &a_or_zero); - let lt = LtWordGadget::construct(cb, &r.to_word(), &n.to_word()); + let eq = cb.is_eq_word(a, &a_or_zero); + let lt = cb.is_lt_word(&r.to_word(), &n.to_word()); // Constrain the aux variable a_or_zero to be =a or =0 if n==0: // (a == a_or_zero) ^ (n == 0 & a_or_zero == 0) cb.add_constraint( diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/rlp.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/rlp.rs index 6883049b48..352a832c32 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/rlp.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/rlp.rs @@ -48,7 +48,7 @@ impl RlpU64Gadget { .zip(&is_most_significant_byte) .map(|(byte, indicator)| byte.expr() * indicator.expr()), ); - let most_significant_byte_is_zero = IsZeroGadget::construct(cb, most_significant_byte); + let most_significant_byte_is_zero = cb.is_zero(most_significant_byte); let is_lt_128 = cb.query_bool(); let value = expr_from_bytes(&value_rlc.cells); diff --git a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs index eef9446fe3..3d13fb37a6 100644 --- a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs @@ -85,7 +85,7 @@ impl MemoryAddressGadget { memory_offset: WordLoHiCell, memory_length: MemoryAddress, ) -> Self { - let memory_length_is_zero = IsZeroGadget::construct(cb, memory_length.sum_expr()); + let memory_length_is_zero = cb.is_zero(memory_length.sum_expr()); let memory_offset_bytes = cb.query_memory_address(); let has_length = 1.expr() - memory_length_is_zero.expr(); @@ -196,16 +196,15 @@ impl CommonMemoryAddressGadget for MemoryExpandedAddressGadget { let length = cb.query_word32(); let sum = cb.query_word32(); - let sum_lt_cap = LtGadget::construct( - cb, + let sum_lt_cap = cb.is_lt( from_bytes::expr(&sum.limbs[..N_BYTES_U64]), (MAX_EXPANDED_MEMORY_ADDRESS + 1).expr(), ); let sum_overflow_hi = sum::expr(&sum.limbs[N_BYTES_U64..]); - let sum_within_u64 = IsZeroGadget::construct(cb, sum_overflow_hi); + let sum_within_u64 = cb.is_zero(sum_overflow_hi); - let length_is_zero = IsZeroGadget::construct(cb, sum::expr(&length.limbs)); + let length_is_zero = cb.is_zero(sum::expr(&length.limbs)); let offset_length_sum = AddWordsGadget::construct(cb, [offset, length], sum); Self { @@ -340,7 +339,7 @@ pub(crate) struct MemoryWordSizeGadget { impl MemoryWordSizeGadget { pub(crate) fn construct(cb: &mut EVMConstraintBuilder, address: Expression) -> Self { - let memory_word_size = ConstantDivisionGadget::construct(cb, address + 31.expr(), 32); + let memory_word_size = cb.div_by_const(address + 31.expr(), 32); Self { memory_word_size } } @@ -613,7 +612,7 @@ impl let is_empty = not::expr(&selectors[0]); let cap = select::expr(is_empty.expr(), 0.expr(), MAX_BYTES.expr()); let signed_len = addr_end - addr_start; - let min_gadget = MinMaxGadget::construct(cb, cap, signed_len); + let min_gadget = cb.min_max(cap, signed_len); // If we claim that the buffer is empty, we prove that the end is at or before the start. // buffer_len = max(0, signed_len) = 0 diff --git a/zkevm-circuits/src/evm_circuit/util/tx.rs b/zkevm-circuits/src/evm_circuit/util/tx.rs index 0ac5cc4a01..d99b029ffd 100644 --- a/zkevm-circuits/src/evm_circuit/util/tx.rs +++ b/zkevm-circuits/src/evm_circuit/util/tx.rs @@ -81,7 +81,7 @@ impl EndTxHelperGadget { gas_used: Expression, num_rw: Expression, ) -> Self { - let is_first_tx = IsEqualGadget::construct(cb, tx_id.expr(), 1.expr()); + let is_first_tx = cb.is_eq(tx_id.expr(), 1.expr()); // Constrain tx receipt fields cb.tx_receipt_lookup( @@ -240,8 +240,7 @@ impl TxDataGadget { // Calculate transaction gas fee let mul_gas_fee_by_gas = MulWordByU64Gadget::construct(cb, gas_price.clone(), gas.expr()); - let call_data_word_length = - ConstantDivisionGadget::construct(cb, call_data_length.expr() + 31.expr(), 32); + let call_data_word_length = cb.div_by_const(call_data_length.expr() + 31.expr(), 32); let (cost_sum, gas_mul_gas_price_plus_value) = if calculate_total_cost { let cost_sum = cb.query_word32();