diff --git a/evm/src/cpu/kernel/asm/moddiv.asm b/evm/src/cpu/kernel/asm/moddiv.asm index 630dcc54..2b76d054 100644 --- a/evm/src/cpu/kernel/asm/moddiv.asm +++ b/evm/src/cpu/kernel/asm/moddiv.asm @@ -25,7 +25,7 @@ %mulmodn %endmacro -// Computes the inverse modulo N by providing it non-deterministically. +// Non-deterministically provide the inverse modulo N. %macro inverse // stack: x PROVER_INPUT(ff::bn254_base::inverse) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index c9d52cff..b5f44103 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -4,6 +4,7 @@ use anyhow::{anyhow, bail}; use ethereum_types::{BigEndianHash, U256, U512}; use keccak_hash::keccak; +use crate::cpu::kernel::assembler::Kernel; use crate::cpu::kernel::prover_input::ProverInputFn; /// Halt interpreter execution whenever a jump to this offset is done. @@ -53,7 +54,7 @@ impl EvmMemory { } } -pub(crate) struct Interpreter<'a> { +pub struct Interpreter<'a> { code: &'a [u8], jumpdests: Vec, offset: usize, @@ -63,7 +64,20 @@ pub(crate) struct Interpreter<'a> { running: bool, } -pub(crate) fn run<'a>( +pub fn run_with_kernel( + kernel: &Kernel, + initial_offset: usize, + initial_stack: Vec, +) -> anyhow::Result { + run( + &kernel.code, + initial_offset, + initial_stack, + &kernel.prover_inputs, + ) +} + +pub fn run<'a>( code: &'a [u8], initial_offset: usize, initial_stack: Vec, diff --git a/evm/src/cpu/kernel/mod.rs b/evm/src/cpu/kernel/mod.rs index a79e17e9..67a22fc1 100644 --- a/evm/src/cpu/kernel/mod.rs +++ b/evm/src/cpu/kernel/mod.rs @@ -1,14 +1,13 @@ pub mod aggregator; pub mod assembler; mod ast; +pub mod interpreter; pub(crate) mod keccak_util; mod opcodes; mod parser; mod prover_input; mod stack_manipulation; -#[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 c9cb8821..5f3ecd42 100644 --- a/evm/src/cpu/kernel/prover_input.rs +++ b/evm/src/cpu/kernel/prover_input.rs @@ -8,7 +8,7 @@ use crate::cpu::kernel::prover_input::Field::{ use crate::cpu::kernel::prover_input::FieldOp::{Inverse, Sqrt}; #[derive(PartialEq, Eq, Debug, Clone)] -pub(crate) struct ProverInputFn(Vec); +pub struct ProverInputFn(Vec); impl From> for ProverInputFn { fn from(v: Vec) -> Self { diff --git a/evm/src/cpu/kernel/tests/curve_ops.rs b/evm/src/cpu/kernel/tests/curve_ops.rs index 72e4169b..44609f21 100644 --- a/evm/src/cpu/kernel/tests/curve_ops.rs +++ b/evm/src/cpu/kernel/tests/curve_ops.rs @@ -4,7 +4,7 @@ mod bn { use ethereum_types::U256; use crate::cpu::kernel::aggregator::combined_kernel; - use crate::cpu::kernel::interpreter::run; + use crate::cpu::kernel::interpreter::run_with_kernel; use crate::cpu::kernel::tests::u256ify; #[test] @@ -43,82 +43,76 @@ mod bn { // Standard addition #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point1.1, point1.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point2.1, point2.0])?); // Standard addition #2 let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, point0.1, point0.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point2.1, point2.0])?); // Standard doubling #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point0.1, point0.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point3.1, point3.0])?); // Standard doubling #2 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0])?; - let stack = run( - &kernel.code, - ec_double, - initial_stack, - &kernel.prover_inputs, - )? - .stack; + let stack = run_with_kernel(&kernel, ec_double, initial_stack)?.stack; assert_eq!(stack, u256ify([point3.1, point3.0])?); // Standard doubling #3 let initial_stack = u256ify(["0xdeadbeef", "0x2", point0.1, point0.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([point3.1, point3.0])?); // Addition with identity #1 let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, point1.1, point1.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point1.1, point1.0])?); // Addition with identity #2 let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, identity.1, identity.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point1.1, point1.0])?); // Addition with identity #3 let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, identity.1, identity.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([identity.1, identity.0])?); // Addition with invalid point(s) #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, invalid.1, invalid.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Addition with invalid point(s) #2 let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, point0.1, point0.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Addition with invalid point(s) #3 let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, identity.1, identity.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Addition with invalid point(s) #4 let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, invalid.1, invalid.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Scalar multiplication #1 let initial_stack = u256ify(["0xdeadbeef", s, point0.1, point0.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([point4.1, point4.0])?); // Scalar multiplication #2 let initial_stack = u256ify(["0xdeadbeef", "0x0", point0.1, point0.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([identity.1, identity.0])?); // Scalar multiplication #3 let initial_stack = u256ify(["0xdeadbeef", "0x1", point0.1, point0.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([point0.1, point0.0])?); // Scalar multiplication #4 let initial_stack = u256ify(["0xdeadbeef", s, identity.1, identity.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([identity.1, identity.0])?); // Scalar multiplication #5 let initial_stack = u256ify(["0xdeadbeef", s, invalid.1, invalid.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Multiple calls @@ -132,7 +126,7 @@ mod bn { point0.1, point0.0, ])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point4.1, point4.0])?); Ok(()) @@ -144,7 +138,7 @@ mod secp { use anyhow::Result; use crate::cpu::kernel::aggregator::combined_kernel; - use crate::cpu::kernel::interpreter::run; + use crate::cpu::kernel::interpreter::{run, run_with_kernel}; use crate::cpu::kernel::tests::u256ify; #[test] @@ -182,7 +176,7 @@ mod secp { // Standard addition #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point1.1, point1.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point2.1, point2.0])?); // Standard addition #2 let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, point0.1, point0.0])?; @@ -191,52 +185,46 @@ mod secp { // Standard doubling #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point0.1, point0.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point3.1, point3.0])?); // Standard doubling #2 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0])?; - let stack = run( - &kernel.code, - ec_double, - initial_stack, - &kernel.prover_inputs, - )? - .stack; + let stack = run_with_kernel(&kernel, ec_double, initial_stack)?.stack; assert_eq!(stack, u256ify([point3.1, point3.0])?); // Standard doubling #3 let initial_stack = u256ify(["0xdeadbeef", "0x2", point0.1, point0.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([point3.1, point3.0])?); // Addition with identity #1 let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, point1.1, point1.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point1.1, point1.0])?); // Addition with identity #2 let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, identity.1, identity.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point1.1, point1.0])?); // Addition with identity #3 let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, identity.1, identity.0])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([identity.1, identity.0])?); // Scalar multiplication #1 let initial_stack = u256ify(["0xdeadbeef", s, point0.1, point0.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([point4.1, point4.0])?); // Scalar multiplication #2 let initial_stack = u256ify(["0xdeadbeef", "0x0", point0.1, point0.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([identity.1, identity.0])?); // Scalar multiplication #3 let initial_stack = u256ify(["0xdeadbeef", "0x1", point0.1, point0.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([point0.1, point0.0])?); // Scalar multiplication #4 let initial_stack = u256ify(["0xdeadbeef", s, identity.1, identity.0])?; - let stack = run(&kernel.code, ec_mul, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_mul, initial_stack)?.stack; assert_eq!(stack, u256ify([identity.1, identity.0])?); // Multiple calls @@ -250,7 +238,7 @@ mod secp { point0.1, point0.0, ])?; - let stack = run(&kernel.code, ec_add, initial_stack, &kernel.prover_inputs)?.stack; + let stack = run_with_kernel(&kernel, ec_add, initial_stack)?.stack; assert_eq!(stack, u256ify([point4.1, point4.0])?); Ok(())