This commit is contained in:
wborgeaud 2022-07-23 12:52:45 +02:00
parent cafae8b818
commit 9dacbe0ff6
5 changed files with 19 additions and 21 deletions

View File

@ -29,6 +29,7 @@ pub struct Kernel {
pub(crate) global_labels: HashMap<String, usize>, pub(crate) global_labels: HashMap<String, usize>,
/// Map from `PROVER_INPUT` offsets to their corresponding `ProverInputFn`.
pub(crate) prover_inputs: HashMap<usize, ProverInputFn>, pub(crate) prover_inputs: HashMap<usize, ProverInputFn>,
} }

View File

@ -29,7 +29,7 @@ local_label = { identifier ~ ":" }
bytes_item = { ^"BYTES " ~ literal ~ ("," ~ literal)* } bytes_item = { ^"BYTES " ~ literal ~ ("," ~ literal)* }
push_instruction = { ^"PUSH " ~ push_target } push_instruction = { ^"PUSH " ~ push_target }
push_target = { literal | identifier | variable | constant } push_target = { literal | identifier | variable | constant }
prover_input_instruction = { ^"PROVER_INPUT" ~ "(" ~ prover_input_fn ~ ")" } // TODO: Could also support extra arguments. prover_input_instruction = { ^"PROVER_INPUT" ~ "(" ~ prover_input_fn ~ ")" }
prover_input_fn = { identifier ~ ("::" ~ identifier)*} prover_input_fn = { identifier ~ ("::" ~ identifier)*}
nullary_instruction = { identifier } nullary_instruction = { identifier }

View File

@ -7,6 +7,8 @@ use crate::cpu::kernel::prover_input::Field::{
}; };
use crate::cpu::kernel::prover_input::FieldOp::{Inverse, Sqrt}; use crate::cpu::kernel::prover_input::FieldOp::{Inverse, Sqrt};
/// Prover input function represented as a scoped function name.
/// Example: `PROVER_INPUT(ff::bn254_base::inverse)` is represented as `ProverInputFn([ff, bn254_base, inverse])`.
#[derive(PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
pub struct ProverInputFn(Vec<String>); pub struct ProverInputFn(Vec<String>);
@ -17,20 +19,27 @@ impl From<Vec<String>> for ProverInputFn {
} }
impl ProverInputFn { impl ProverInputFn {
/// Run the function on the stack.
pub(crate) fn run(&self, stack: Vec<U256>) -> U256 { pub(crate) fn run(&self, stack: Vec<U256>) -> U256 {
match self.0[0].as_str() { match self.0[0].as_str() {
"ff" => self.run_ff(stack), "ff" => self.run_ff(stack),
"storage" => todo!(), "mpt" => todo!(),
_ => panic!("Unrecognized prover input function."), _ => panic!("Unrecognized prover input function."),
} }
} }
// Finite field operations.
fn run_ff(&self, mut stack: Vec<U256>) -> U256 { fn run_ff(&self, mut stack: Vec<U256>) -> U256 {
let field = Field::from_str(self.0[1].as_str()).unwrap(); let field = Field::from_str(self.0[1].as_str()).unwrap();
let op = FieldOp::from_str(self.0[2].as_str()).unwrap(); let op = FieldOp::from_str(self.0[2].as_str()).unwrap();
let x = stack.pop().expect("Empty stack"); let x = stack.pop().expect("Empty stack");
field.op(op, x) field.op(op, x)
} }
// MPT operations.
fn run_mpt(&self, mut stack: Vec<U256>) -> U256 {
todo!()
}
} }
enum Field { enum Field {

View File

@ -5,7 +5,7 @@ use ethereum_types::U256;
use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::aggregator::combined_kernel;
use crate::cpu::kernel::assembler::Kernel; use crate::cpu::kernel::assembler::Kernel;
use crate::cpu::kernel::interpreter::run; use crate::cpu::kernel::interpreter::run_with_kernel;
use crate::cpu::kernel::tests::u256ify; use crate::cpu::kernel::tests::u256ify;
fn test_valid_ecrecover( fn test_valid_ecrecover(
@ -18,13 +18,7 @@ fn test_valid_ecrecover(
) -> Result<()> { ) -> Result<()> {
let ecrecover = kernel.global_labels["ecrecover"]; let ecrecover = kernel.global_labels["ecrecover"];
let initial_stack = u256ify(["0xdeadbeef", s, r, v, hash])?; let initial_stack = u256ify(["0xdeadbeef", s, r, v, hash])?;
let stack = run( let stack = run_with_kernel(kernel, ecrecover, initial_stack)?.stack;
&kernel.code,
ecrecover,
initial_stack,
&kernel.prover_inputs,
)?
.stack;
assert_eq!(stack[0], U256::from_str(expected).unwrap()); assert_eq!(stack[0], U256::from_str(expected).unwrap());
Ok(()) Ok(())
@ -33,13 +27,7 @@ fn test_valid_ecrecover(
fn test_invalid_ecrecover(hash: &str, v: &str, r: &str, s: &str, kernel: &Kernel) -> Result<()> { fn test_invalid_ecrecover(hash: &str, v: &str, r: &str, s: &str, kernel: &Kernel) -> Result<()> {
let ecrecover = kernel.global_labels["ecrecover"]; let ecrecover = kernel.global_labels["ecrecover"];
let initial_stack = u256ify(["0xdeadbeef", s, r, v, hash])?; let initial_stack = u256ify(["0xdeadbeef", s, r, v, hash])?;
let stack = run( let stack = run_with_kernel(kernel, ecrecover, initial_stack)?.stack;
&kernel.code,
ecrecover,
initial_stack,
&kernel.prover_inputs,
)?
.stack;
assert_eq!(stack, vec![U256::MAX]); assert_eq!(stack, vec![U256::MAX]);
Ok(()) Ok(())

View File

@ -5,7 +5,7 @@ use ethereum_types::U256;
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::aggregator::combined_kernel;
use crate::cpu::kernel::interpreter::run; use crate::cpu::kernel::interpreter::{run, run_with_kernel};
#[test] #[test]
fn test_exp() -> Result<()> { fn test_exp() -> Result<()> {
@ -18,7 +18,7 @@ fn test_exp() -> Result<()> {
// Random input // Random input
let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, a]; let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, a];
let stack_with_kernel = run(&kernel.code, exp, initial_stack, &kernel.prover_inputs)?.stack; let stack_with_kernel = run_with_kernel(&kernel, exp, initial_stack)?.stack;
let initial_stack = vec![b, a]; let initial_stack = vec![b, a];
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)?.stack; let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)?.stack;
@ -26,7 +26,7 @@ fn test_exp() -> Result<()> {
// 0 base // 0 base
let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, U256::zero()]; let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, U256::zero()];
let stack_with_kernel = run(&kernel.code, exp, initial_stack, &kernel.prover_inputs)?.stack; let stack_with_kernel = run_with_kernel(&kernel, exp, initial_stack)?.stack;
let initial_stack = vec![b, U256::zero()]; let initial_stack = vec![b, U256::zero()];
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)?.stack; let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)?.stack;
@ -34,7 +34,7 @@ fn test_exp() -> Result<()> {
// 0 exponent // 0 exponent
let initial_stack = vec![U256::from_str("0xdeadbeef")?, U256::zero(), a]; let initial_stack = vec![U256::from_str("0xdeadbeef")?, U256::zero(), a];
let stack_with_kernel = run(&kernel.code, exp, initial_stack, &kernel.prover_inputs)?.stack; let stack_with_kernel = run_with_kernel(&kernel, exp, initial_stack)?.stack;
let initial_stack = vec![U256::zero(), a]; let initial_stack = vec![U256::zero(), a];
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)?.stack; let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)?.stack;