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

Commit

Permalink
simplify pair_select
Browse files Browse the repository at this point in the history
  • Loading branch information
ChihChengLiang committed Feb 13, 2024
1 parent 3151efd commit 96b2486
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 238 deletions.
22 changes: 4 additions & 18 deletions zkevm-circuits/src/evm_circuit/execution/add_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
util::{
common_gadget::SameContextGadget,
constraint_builder::{EVMConstraintBuilder, StepStateTransition, Transition::Delta},
math_gadget::{AddWordsGadget, PairSelectGadget},
math_gadget::AddWordsGadget,
CachedRegion,
},
witness::{Block, Call, ExecStep, Transaction},
Expand All @@ -27,7 +27,6 @@ use halo2_proofs::plonk::Error;
pub(crate) struct AddSubGadget<F> {
same_context: SameContextGadget<F>,
add_words: AddWordsGadget<F, 2, false>,
is_sub: PairSelectGadget<F>,
}

impl<F: Field> ExecutionGadget<F> for AddSubGadget<F> {
Expand All @@ -44,19 +43,14 @@ impl<F: Field> ExecutionGadget<F> for AddSubGadget<F> {
let add_words = AddWordsGadget::construct(cb, [a.clone(), b.clone()], c.clone());

// Swap a and c if opcode is SUB
let is_sub = PairSelectGadget::construct(
cb,
opcode.expr(),
OpcodeId::SUB.expr(),
OpcodeId::ADD.expr(),
);
let is_sub = cb.pair_select(opcode.expr(), OpcodeId::SUB.expr(), OpcodeId::ADD.expr());

// ADD: Pop a and b from the stack, push c on the stack
// SUB: Pop c and b from the stack, push a on the stack

cb.stack_pop(WordLoHi::select(is_sub.expr().0, c.to_word(), a.to_word()));
cb.stack_pop(WordLoHi::select(is_sub.clone(), c.to_word(), a.to_word()));
cb.stack_pop(b.to_word());
cb.stack_push(WordLoHi::select(is_sub.expr().0, a.to_word(), c.to_word()));
cb.stack_push(WordLoHi::select(is_sub, a.to_word(), c.to_word()));

// State transition
let step_state_transition = StepStateTransition {
Expand All @@ -71,7 +65,6 @@ impl<F: Field> ExecutionGadget<F> for AddSubGadget<F> {
Self {
same_context,
add_words,
is_sub,
}
}

Expand All @@ -94,13 +87,6 @@ impl<F: Field> ExecutionGadget<F> for AddSubGadget<F> {
};
let [a, b, c] = indices.map(|index| block.get_rws(step, index).stack_value());
self.add_words.assign(region, offset, [a, b], c)?;
self.is_sub.assign(
region,
offset,
F::from(opcode.as_u64()),
F::from(OpcodeId::SUB.as_u64()),
F::from(OpcodeId::ADD.as_u64()),
)?;

Ok(())
}
Expand Down
20 changes: 5 additions & 15 deletions zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
util::{
common_gadget::CommonErrorGadget,
constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder},
math_gadget::{LtGadget, PairSelectGadget},
math_gadget::LtGadget,
memory_gadget::{
CommonMemoryAddressGadget, MemoryExpandedAddressGadget, MemoryExpansionGadget,
MemoryWordSizeGadget,
Expand All @@ -30,7 +30,6 @@ pub(crate) struct ErrorOOGCreateGadget<F> {
opcode: Cell<F>,
value: Word32Cell<F>,
salt: Word32Cell<F>,
is_create2: PairSelectGadget<F>,
minimum_word_size: MemoryWordSizeGadget<F>,
memory_address: MemoryExpandedAddressGadget<F>,
memory_expansion: MemoryExpansionGadget<F, 1, N_BYTES_MEMORY_WORD_SIZE>,
Expand All @@ -51,8 +50,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCreateGadget<F> {
fn configure(cb: &mut EVMConstraintBuilder<F>) -> Self {
let opcode = cb.query_cell();

let is_create2 = PairSelectGadget::construct(
cb,
let is_create2 = cb.pair_select(
opcode.expr(),
OpcodeId::CREATE2.expr(),
OpcodeId::CREATE.expr(),
Expand All @@ -66,7 +64,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCreateGadget<F> {
cb.stack_pop(value.to_word());
cb.stack_pop(memory_address.offset_word());
cb.stack_pop(memory_address.length_word());
cb.condition(is_create2.expr().0, |cb| cb.stack_pop(salt.to_word()));
cb.condition(is_create2.clone(), |cb| cb.stack_pop(salt.to_word()));

let init_code_size_overflow =
LtGadget::construct(cb, MAX_INIT_CODE_SIZE.expr(), memory_address.length());
Expand All @@ -76,7 +74,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCreateGadget<F> {

let code_store_gas_cost = minimum_word_size.expr()
* select::expr(
is_create2.expr().0,
is_create2.clone(),
CREATE2_GAS_PER_CODE_WORD.expr(),
CREATE_GAS_PER_CODE_WORD.expr(),
);
Expand All @@ -96,14 +94,13 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCreateGadget<F> {
let common_error_gadget = CommonErrorGadget::construct(
cb,
opcode.expr(),
select::expr(is_create2.expr().0, 4.expr(), 3.expr()),
select::expr(is_create2, 4.expr(), 3.expr()),
);

Self {
opcode,
value,
salt,
is_create2,
minimum_word_size,
memory_address,
memory_expansion,
Expand Down Expand Up @@ -132,13 +129,6 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCreateGadget<F> {
let is_create2 = opcode == OpcodeId::CREATE2;
self.opcode
.assign(region, offset, Value::known(F::from(opcode.as_u64())))?;
self.is_create2.assign(
region,
offset,
F::from(opcode.as_u64()),
F::from(OpcodeId::CREATE2.as_u64()),
F::from(OpcodeId::CREATE.as_u64()),
)?;

let [value, memory_offset, memory_length] =
[0, 1, 2].map(|i| block.get_rws(step, i).stack_value());
Expand Down
22 changes: 6 additions & 16 deletions zkevm-circuits/src/evm_circuit/execution/error_oog_sload_sstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
CommonErrorGadget, SloadGasGadget, SstoreGasGadget,
},
constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder},
math_gadget::{LtGadget, PairSelectGadget},
math_gadget::LtGadget,
or, select, CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
Expand Down Expand Up @@ -40,7 +40,6 @@ pub(crate) struct ErrorOOGSloadSstoreGadget<F> {
value_prev: WordLoHiCell<F>,
original_value: WordLoHiCell<F>,
is_warm: Cell<F>,
is_sstore: PairSelectGadget<F>,
sstore_gas_cost: SstoreGasGadget<F, WordLoHiCell<F>>,
insufficient_gas_cost: LtGadget<F, N_BYTES_GAS>,
// Constrain for SSTORE reentrancy sentry.
Expand All @@ -56,8 +55,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGSloadSstoreGadget<F> {
fn configure(cb: &mut EVMConstraintBuilder<F>) -> Self {
let opcode = cb.query_cell();

let is_sstore = PairSelectGadget::construct(
cb,
let is_sstore = cb.pair_select(
opcode.expr(),
OpcodeId::SSTORE.expr(),
OpcodeId::SLOAD.expr(),
Expand All @@ -68,7 +66,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGSloadSstoreGadget<F> {
let callee_address = cb.call_context_read_as_word(None, CallContextFieldTag::CalleeAddress);

// Constrain `is_static` must be false for SSTORE.
cb.require_zero("is_static == false", is_static.expr() * is_sstore.expr().0);
cb.require_zero("is_static == false", is_static.expr() * is_sstore.clone());

let key = cb.query_word_unchecked();
let value = cb.query_word_unchecked();
Expand All @@ -85,7 +83,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGSloadSstoreGadget<F> {
);

let sload_gas_cost = SloadGasGadget::construct(cb, is_warm.expr());
let sstore_gas_cost = cb.condition(is_sstore.expr().0, |cb| {
let sstore_gas_cost = cb.condition(is_sstore.clone(), |cb| {
cb.stack_pop(value.to_word());

cb.account_storage_read(
Expand All @@ -109,7 +107,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGSloadSstoreGadget<F> {
cb,
cb.curr.state.gas_left.expr(),
select::expr(
is_sstore.expr().0,
is_sstore.clone(),
sstore_gas_cost.expr(),
sload_gas_cost.expr(),
),
Expand All @@ -124,7 +122,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGSloadSstoreGadget<F> {
"Gas left is less than gas cost or gas sentry (only for SSTORE)",
or::expr([
insufficient_gas_cost.expr(),
and::expr([is_sstore.expr().0, insufficient_gas_sentry.expr()]),
and::expr([is_sstore, insufficient_gas_sentry.expr()]),
]),
1.expr(),
);
Expand All @@ -142,7 +140,6 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGSloadSstoreGadget<F> {
value_prev,
original_value,
is_warm,
is_sstore,
sstore_gas_cost,
insufficient_gas_cost,
insufficient_gas_sentry,
Expand Down Expand Up @@ -199,13 +196,6 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGSloadSstoreGadget<F> {
self.is_warm
.assign(region, offset, Value::known(F::from(is_warm as u64)))?;

self.is_sstore.assign(
region,
offset,
F::from(opcode.as_u64()),
F::from(OpcodeId::SSTORE.as_u64()),
F::from(OpcodeId::SLOAD.as_u64()),
)?;
self.sstore_gas_cost
.assign(region, offset, value, value_prev, original_value, is_warm)?;
self.insufficient_gas_cost.assign_value(
Expand Down
25 changes: 25 additions & 0 deletions zkevm-circuits/src/evm_circuit/util/constraint_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,31 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> {
constrain!(log_id);
}

// Math gadgets

/// - `is_a` is `1` when `value == a`, else `0`
/// - `value` is required to be either `a` or `b`.
/// The benefit of this gadget over `IsEqualGadget` is that the expression returned is a single
/// value which will make future expressions depending on this result more efficient.
pub(crate) fn pair_select(
&mut self,
value: Expression<F>,
a: Expression<F>,
b: Expression<F>,
) -> Expression<F> {
let is_a = self.query_bool();
let is_a = is_a.expr();
// Force `is_a` to be `0` when `value != a`
self.add_constraint("is_a ⋅ (value - a)", is_a.clone() * (value.clone() - a));
// Force `1 - is_a` to be `0` when `value != b`
self.add_constraint(
"(1 - is_a) ⋅ (value - b)",
(1.expr() - is_a.clone()) * (value - b),
);

is_a
}

// Fixed

pub(crate) fn range_lookup(&mut self, value: Expression<F>, range: u64) {
Expand Down
2 changes: 0 additions & 2 deletions zkevm-circuits/src/evm_circuit/util/math_gadget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ mod modulo;
mod mul_add_words;
mod mul_add_words512;
mod mul_word_u64;
mod pair_select;
mod range_check;
mod rlp;
#[cfg(test)]
Expand All @@ -44,7 +43,6 @@ pub(crate) use modulo::ModGadget;
pub(crate) use mul_add_words::MulAddWordsGadget;
pub(crate) use mul_add_words512::MulAddWords512Gadget;
pub(crate) use mul_word_u64::MulWordByU64Gadget;
pub(crate) use pair_select::PairSelectGadget;
pub(crate) use range_check::RangeCheckGadget;
pub(crate) use rlp::ContractCreateGadget;

Expand Down
Loading

0 comments on commit 96b2486

Please sign in to comment.