From 257420dced48a57fdb77e686ec26c0ec3c62eb43 Mon Sep 17 00:00:00 2001 From: z2trillion Date: Fri, 10 Jun 2022 12:51:27 -0400 Subject: [PATCH 1/5] Add NotGadget --- zkevm-circuits/src/evm_circuit/execution.rs | 5 + .../src/evm_circuit/execution/not.rs | 138 ++++++++++++++++++ zkevm-circuits/src/evm_circuit/witness.rs | 1 + 3 files changed, 144 insertions(+) create mode 100644 zkevm-circuits/src/evm_circuit/execution/not.rs diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index b927b4d817..dc168048a2 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -58,6 +58,7 @@ mod memory_copy; mod msize; mod mul_div_mod; mod mulmod; +mod not; mod origin; mod pc; mod pop; @@ -107,6 +108,7 @@ use memory_copy::CopyToMemoryGadget; use msize::MsizeGadget; use mul_div_mod::MulDivModGadget; use mulmod::MulModGadget; +use not::NotGadget; use origin::OriginGadget; use pc::PcGadget; use pop::PopGadget; @@ -185,6 +187,7 @@ pub(crate) struct ExecutionConfig { msize_gadget: MsizeGadget, mul_div_mod_gadget: MulDivModGadget, mulmod_gadget: MulModGadget, + not_gadget: NotGadget, origin_gadget: OriginGadget, pc_gadget: PcGadget, pop_gadget: PopGadget, @@ -379,6 +382,7 @@ impl ExecutionConfig { msize_gadget: configure_gadget!(), mul_div_mod_gadget: configure_gadget!(), mulmod_gadget: configure_gadget!(), + not_gadget: configure_gadget!(), origin_gadget: configure_gadget!(), pc_gadget: configure_gadget!(), pop_gadget: configure_gadget!(), @@ -818,6 +822,7 @@ impl ExecutionConfig { ExecutionState::MSIZE => assign_exec_step!(self.msize_gadget), ExecutionState::MUL_DIV_MOD => assign_exec_step!(self.mul_div_mod_gadget), ExecutionState::MULMOD => assign_exec_step!(self.mulmod_gadget), + ExecutionState::NOT => assign_exec_step!(self.not_gadget), ExecutionState::ORIGIN => assign_exec_step!(self.origin_gadget), ExecutionState::PC => assign_exec_step!(self.pc_gadget), ExecutionState::POP => assign_exec_step!(self.pop_gadget), diff --git a/zkevm-circuits/src/evm_circuit/execution/not.rs b/zkevm-circuits/src/evm_circuit/execution/not.rs new file mode 100644 index 0000000000..629196e566 --- /dev/null +++ b/zkevm-circuits/src/evm_circuit/execution/not.rs @@ -0,0 +1,138 @@ +use crate::{ + evm_circuit::{ + execution::ExecutionGadget, + step::ExecutionState, + table::{FixedTableTag, Lookup}, + util::{ + common_gadget::SameContextGadget, + constraint_builder::{ConstraintBuilder, StepStateTransition, Transition::Delta}, + CachedRegion, Word, + }, + witness::{Block, Call, ExecStep, Transaction}, + }, + util::Expr, +}; +use eth_types::evm_types::OpcodeId; +use eth_types::Field; +use eth_types::ToLittleEndian; +use halo2_proofs::plonk::Error; + +#[derive(Clone, Debug)] +pub(crate) struct NotGadget { + same_context: SameContextGadget, + input: Word, + output: Word, +} + +impl ExecutionGadget for NotGadget { + const NAME: &'static str = "NOT"; + + const EXECUTION_STATE: ExecutionState = ExecutionState::NOT; + + fn configure(cb: &mut ConstraintBuilder) -> Self { + let opcode = cb.query_cell(); + + let input = cb.query_word(); + let output = cb.query_word(); + + cb.stack_pop(input.expr()); + cb.stack_push(output.expr()); + + for idx in 0..32 { + cb.add_lookup( + "Bitwise lookup", + Lookup::Fixed { + tag: FixedTableTag::BitwiseXor.expr(), + values: [ + input.cells[idx].expr(), + output.cells[idx].expr(), + 255.expr(), + ], + }, + ); + } + + // State transition + let step_state_transition = StepStateTransition { + rw_counter: Delta(2.expr()), + program_counter: Delta(1.expr()), + stack_pointer: Delta(0.expr()), + gas_left: Delta(-OpcodeId::NOT.constant_gas_cost().expr()), + ..Default::default() + }; + let same_context = SameContextGadget::construct(cb, opcode, step_state_transition); + + Self { + same_context, + input, + output, + } + } + + fn assign_exec_step( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + block: &Block, + _: &Transaction, + _: &Call, + step: &ExecStep, + ) -> Result<(), Error> { + self.same_context.assign_exec_step(region, offset, step)?; + + let [input, output] = + [step.rw_indices[0], step.rw_indices[1]].map(|idx| block.rws[idx].stack_value()); + self.input + .assign(region, offset, Some(input.to_le_bytes()))?; + self.output + .assign(region, offset, Some(output.to_le_bytes()))?; + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use crate::{ + evm_circuit::test::rand_word, + test_util::{get_fixed_table, run_test_circuits, BytecodeTestConfig, FixedTableConfig}, + }; + use eth_types::{bytecode, Word}; + use mock::TestContext; + + fn test_ok(a: Word) { + let bytecode = bytecode! { + PUSH32(a) + NOT + STOP + }; + let test_config = BytecodeTestConfig { + evm_circuit_lookup_tags: get_fixed_table(FixedTableConfig::Complete), + ..Default::default() + }; + + assert_eq!( + run_test_circuits( + TestContext::<1, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + Some(test_config) + ), + Ok(()) + ); + } + + #[test] + fn not_gadget_simple() { + test_ok(0.into()); + test_ok(1.into()); + test_ok(255.into()); + test_ok(256.into()); + test_ok(Word::MAX); + } + + #[test] + fn not_gadget_rand() { + let a = rand_word(); + dbg!(a); + test_ok(a); + } +} diff --git a/zkevm-circuits/src/evm_circuit/witness.rs b/zkevm-circuits/src/evm_circuit/witness.rs index 083a68fe05..3896340559 100644 --- a/zkevm-circuits/src/evm_circuit/witness.rs +++ b/zkevm-circuits/src/evm_circuit/witness.rs @@ -1207,6 +1207,7 @@ impl From<&circuit_input_builder::ExecStep> for ExecutionState { OpcodeId::AND => ExecutionState::BITWISE, OpcodeId::XOR => ExecutionState::BITWISE, OpcodeId::OR => ExecutionState::BITWISE, + OpcodeId::NOT => ExecutionState::NOT, OpcodeId::POP => ExecutionState::POP, OpcodeId::PUSH32 => ExecutionState::PUSH, OpcodeId::BYTE => ExecutionState::BYTE, From 261109e282bcb2ee6ef729c92419a7f2276fe110 Mon Sep 17 00:00:00 2001 From: z2trillion Date: Fri, 10 Jun 2022 13:27:04 -0400 Subject: [PATCH 2/5] Update lookup name --- zkevm-circuits/src/evm_circuit/execution/not.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/not.rs b/zkevm-circuits/src/evm_circuit/execution/not.rs index 629196e566..79e02d10e8 100644 --- a/zkevm-circuits/src/evm_circuit/execution/not.rs +++ b/zkevm-circuits/src/evm_circuit/execution/not.rs @@ -13,8 +13,7 @@ use crate::{ util::Expr, }; use eth_types::evm_types::OpcodeId; -use eth_types::Field; -use eth_types::ToLittleEndian; +use eth_types::{Field, ToLittleEndian}; use halo2_proofs::plonk::Error; #[derive(Clone, Debug)] @@ -40,7 +39,7 @@ impl ExecutionGadget for NotGadget { for idx in 0..32 { cb.add_lookup( - "Bitwise lookup", + "input XOR output is all 1's", Lookup::Fixed { tag: FixedTableTag::BitwiseXor.expr(), values: [ From 72e259836fd39a71b528606d7ab195f4ee787ce7 Mon Sep 17 00:00:00 2001 From: z2trillion Date: Tue, 14 Jun 2022 17:54:38 -0400 Subject: [PATCH 3/5] Update zkevm-circuits/src/evm_circuit/execution/not.rs Co-authored-by: Rohit Narurkar --- zkevm-circuits/src/evm_circuit/execution/not.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/not.rs b/zkevm-circuits/src/evm_circuit/execution/not.rs index 79e02d10e8..ac4f4f33e2 100644 --- a/zkevm-circuits/src/evm_circuit/execution/not.rs +++ b/zkevm-circuits/src/evm_circuit/execution/not.rs @@ -37,16 +37,12 @@ impl ExecutionGadget for NotGadget { cb.stack_pop(input.expr()); cb.stack_push(output.expr()); - for idx in 0..32 { + for (i, o) in input.cells.iter().zip(output.cells.iter()) { cb.add_lookup( "input XOR output is all 1's", Lookup::Fixed { tag: FixedTableTag::BitwiseXor.expr(), - values: [ - input.cells[idx].expr(), - output.cells[idx].expr(), - 255.expr(), - ], + values: [i.expr(), o.expr(), 255.expr()], }, ); } From cc997d5ce4e2e82c0c63499f8cefac1b09b7b06b Mon Sep 17 00:00:00 2001 From: z2trillion Date: Wed, 15 Jun 2022 13:03:37 -0400 Subject: [PATCH 4/5] Update zkevm-circuits/src/evm_circuit/execution/not.rs Co-authored-by: adria0.eth <5526331+adria0@users.noreply.github.com> --- zkevm-circuits/src/evm_circuit/execution/not.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/zkevm-circuits/src/evm_circuit/execution/not.rs b/zkevm-circuits/src/evm_circuit/execution/not.rs index ac4f4f33e2..ebf9bf5b3f 100644 --- a/zkevm-circuits/src/evm_circuit/execution/not.rs +++ b/zkevm-circuits/src/evm_circuit/execution/not.rs @@ -127,6 +127,7 @@ mod test { #[test] fn not_gadget_rand() { let a = rand_word(); + // the debug statement is useful for random tests so in case it fails, the failing example shows up in the logs. dbg!(a); test_ok(a); } From bbbeea20b30dfb52703ae4f207d009a5e71b721d Mon Sep 17 00:00:00 2001 From: z2trillion Date: Wed, 15 Jun 2022 13:18:53 -0400 Subject: [PATCH 5/5] fmt --- zkevm-circuits/src/evm_circuit/execution/not.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/not.rs b/zkevm-circuits/src/evm_circuit/execution/not.rs index ebf9bf5b3f..b0b245ab2e 100644 --- a/zkevm-circuits/src/evm_circuit/execution/not.rs +++ b/zkevm-circuits/src/evm_circuit/execution/not.rs @@ -127,7 +127,8 @@ mod test { #[test] fn not_gadget_rand() { let a = rand_word(); - // the debug statement is useful for random tests so in case it fails, the failing example shows up in the logs. + // the debug statement is useful for random tests so in case it fails, the + // failing example shows up in the logs. dbg!(a); test_ok(a); }