diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 114a3d83..81be7f96 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -90,5 +90,6 @@ mod tests { // Make sure we can parse and assemble the entire kernel. let kernel = combined_kernel(); debug!("Total kernel size: {} bytes", kernel.code.len()); + dbg!("Total kernel size: {} bytes", kernel.code.len()); } } diff --git a/evm/src/cpu/kernel/asm/moddiv.asm b/evm/src/cpu/kernel/asm/moddiv.asm index 2b76d054..780473b9 100644 --- a/evm/src/cpu/kernel/asm/moddiv.asm +++ b/evm/src/cpu/kernel/asm/moddiv.asm @@ -30,16 +30,10 @@ // stack: x PROVER_INPUT(ff::bn254_base::inverse) // stack: x^-1, x - %stack (inv, x) -> (inv, x, @BN_BASE, inv, x) - // stack: x^-1, x, N, x^-1, x + %stack (inv, x) -> (inv, x, @BN_BASE, inv) + // stack: x^-1, x, N, x^-1 MULMOD - // stack: x^-1 * x, x^-1, x - PUSH 1 - // stack: 1, x^-1 * x, x^-1, x - %assert_eq - // stack: x^-1, x - SWAP1 - // stack: x, x^-1 - POP + // stack: x^-1 * x, x^-1 + %assert_eq_const(1) // stack: x^-1 %endmacro diff --git a/evm/src/cpu/kernel/asm/secp256k1/inverse_scalar.asm b/evm/src/cpu/kernel/asm/secp256k1/inverse_scalar.asm index 7b859b4f..6e1563e2 100644 --- a/evm/src/cpu/kernel/asm/secp256k1/inverse_scalar.asm +++ b/evm/src/cpu/kernel/asm/secp256k1/inverse_scalar.asm @@ -22,16 +22,10 @@ // stack: x PROVER_INPUT(ff::secp256k1_scalar::inverse) // stack: x^-1, x - %stack (inv, x) -> (inv, x, @SECP_SCALAR, inv, x) - // stack: x^-1, x, N, x^-1, x + %stack (inv, x) -> (inv, x, @SECP_SCALAR, inv) + // stack: x^-1, x, N, x^-1 MULMOD - // stack: x^-1 * x, x^-1, x - PUSH 1 - // stack: 1, x^-1 * x, x^-1, x - %assert_eq - // stack: x^-1, x - SWAP1 - // stack: x, x^-1 - POP + // stack: x^-1 * x, x^-1 + %assert_eq_const(1) // stack: x^-1 %endmacro diff --git a/evm/src/cpu/kernel/asm/secp256k1/lift_x.asm b/evm/src/cpu/kernel/asm/secp256k1/lift_x.asm index 4bef700e..dc765518 100644 --- a/evm/src/cpu/kernel/asm/secp256k1/lift_x.asm +++ b/evm/src/cpu/kernel/asm/secp256k1/lift_x.asm @@ -10,7 +10,7 @@ // stack: x^3+7, x, parity DUP1 // stack: x^3+7, x^3+7, parity - %sqrt_secp_base + %sqrt_secp_base_unsafe // stack: y, x^3+7, x, parity SWAP1 // stack: x^3+7, y, parity @@ -61,7 +61,8 @@ %endmacro // Non-deterministically provide the square root modulo N. -%macro sqrt_secp_base +// Note: The square root is not checked and the macro doesn't not panic if `x` is not a square. +%macro sqrt_secp_base_unsafe // stack: x PROVER_INPUT(ff::secp256k1_base::sqrt) // stack: √x, x diff --git a/evm/src/cpu/kernel/asm/secp256k1/moddiv.asm b/evm/src/cpu/kernel/asm/secp256k1/moddiv.asm index fd077b11..d878dc14 100644 --- a/evm/src/cpu/kernel/asm/secp256k1/moddiv.asm +++ b/evm/src/cpu/kernel/asm/secp256k1/moddiv.asm @@ -30,16 +30,10 @@ // stack: x PROVER_INPUT(ff::secp256k1_base::inverse) // stack: x^-1, x - %stack (inv, x) -> (inv, x, @SECP_BASE, inv, x) - // stack: x^-1, x, N, x^-1, x + %stack (inv, x) -> (inv, x, @SECP_BASE, inv) + // stack: x^-1, x, N, x^-1 MULMOD - // stack: x^-1 * x, x^-1, x - PUSH 1 - // stack: 1, x^-1 * x, x^-1, x - %assert_eq - // stack: x^-1, x - SWAP1 - // stack: x, x^-1 - POP + // stack: x^-1 * x, x^-1 + %assert_eq_const(1) // stack: x^-1 %endmacro diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 0634b864..61272c24 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -336,7 +336,7 @@ impl<'a> Interpreter<'a> { .prover_inputs_map .get(&(self.offset - 1)) .ok_or_else(|| anyhow!("Offset not in prover inputs."))?; - let output = prover_input_fn.run(self.stack.clone()); + let output = prover_input_fn.run(&self.stack); self.stack.push(output); self.prover_inputs.push(output); Ok(()) diff --git a/evm/src/cpu/kernel/mod.rs b/evm/src/cpu/kernel/mod.rs index d146884a..5b9b1b4a 100644 --- a/evm/src/cpu/kernel/mod.rs +++ b/evm/src/cpu/kernel/mod.rs @@ -1,14 +1,15 @@ pub mod aggregator; pub mod assembler; mod ast; -pub mod interpreter; pub(crate) mod keccak_util; mod opcodes; mod parser; -mod prover_input; +pub mod prover_input; mod stack_manipulation; mod txn_fields; +#[cfg(test)] +mod interpreter; #[cfg(test)] mod tests; diff --git a/evm/src/cpu/kernel/prover_input.rs b/evm/src/cpu/kernel/prover_input.rs index b27eb561..38e1914e 100644 --- a/evm/src/cpu/kernel/prover_input.rs +++ b/evm/src/cpu/kernel/prover_input.rs @@ -20,7 +20,7 @@ impl From> for ProverInputFn { impl ProverInputFn { /// Run the function on the stack. - pub(crate) fn run(&self, stack: Vec) -> U256 { + pub fn run(&self, stack: &[U256]) -> U256 { match self.0[0].as_str() { "ff" => self.run_ff(stack), "mpt" => todo!(), @@ -29,10 +29,10 @@ impl ProverInputFn { } // Finite field operations. - fn run_ff(&self, mut stack: Vec) -> U256 { + fn run_ff(&self, stack: &[U256]) -> U256 { let field = Field::from_str(self.0[1].as_str()).unwrap(); let op = FieldOp::from_str(self.0[2].as_str()).unwrap(); - let x = stack.pop().expect("Empty stack"); + let x = *stack.last().expect("Empty stack"); field.op(op, x) } @@ -130,7 +130,7 @@ fn modexp(x: U256, e: U256, n: U256) -> U256 { let mut product = U256::one(); for j in 0..256 { - if !(e >> j & U256::one()).is_zero() { + if e.bit(j) { product = U256::try_from(product.full_mul(current) % n).unwrap(); } current = U256::try_from(current.full_mul(current) % n).unwrap();