plonky2/evm/src/generation/prover_input.rs

220 lines
6.5 KiB
Rust
Raw Normal View History

2022-07-23 11:47:10 +02:00
use std::str::FromStr;
use anyhow::{bail, Error};
2022-10-21 18:00:41 +02:00
use ethereum_types::{BigEndianHash, H256, U256};
use plonky2::field::types::Field;
2022-07-23 11:47:10 +02:00
2023-01-17 23:58:36 +07:00
// use crate::bn254_arithmetic::{fp12_to_array, inv_fp12, vec_to_fp12};
use crate::generation::prover_input::EvmField::{
2022-07-23 11:47:10 +02:00
Bn254Base, Bn254Scalar, Secp256k1Base, Secp256k1Scalar,
};
use crate::generation::prover_input::FieldOp::{Inverse, Sqrt};
use crate::generation::state::GenerationState;
2022-12-20 00:22:59 -08:00
use crate::witness::util::{stack_peek, stack_peeks};
2022-07-23 11:47:10 +02:00
2022-07-23 12:52:45 +02:00
/// Prover input function represented as a scoped function name.
/// Example: `PROVER_INPUT(ff::bn254_base::inverse)` is represented as `ProverInputFn([ff, bn254_base, inverse])`.
2022-07-23 11:16:45 +02:00
#[derive(PartialEq, Eq, Debug, Clone)]
2022-07-23 12:36:03 +02:00
pub struct ProverInputFn(Vec<String>);
2022-07-23 11:16:45 +02:00
impl From<Vec<String>> for ProverInputFn {
fn from(v: Vec<String>) -> Self {
Self(v)
}
}
2022-07-23 11:47:10 +02:00
impl<F: Field> GenerationState<F> {
2022-12-01 11:15:51 -08:00
pub(crate) fn prover_input(&mut self, input_fn: &ProverInputFn) -> U256 {
match input_fn.0[0].as_str() {
2022-09-29 23:09:32 -07:00
"end_of_txns" => self.run_end_of_txns(),
2022-12-01 11:15:51 -08:00
"ff" => self.run_ff(input_fn),
2022-12-20 00:22:59 -08:00
"ffe" => self.run_ffe(input_fn),
2022-09-22 20:09:48 -07:00
"mpt" => self.run_mpt(),
2022-09-29 23:09:32 -07:00
"rlp" => self.run_rlp(),
2022-12-01 11:15:51 -08:00
"account_code" => self.run_account_code(input_fn),
2022-07-23 11:47:10 +02:00
_ => panic!("Unrecognized prover input function."),
}
}
2022-09-29 23:09:32 -07:00
fn run_end_of_txns(&mut self) -> U256 {
let end = self.next_txn_index == self.inputs.signed_txns.len();
if end {
U256::one()
} else {
self.next_txn_index += 1;
U256::zero()
}
}
/// Finite field operations.
2022-12-01 11:15:51 -08:00
fn run_ff(&self, input_fn: &ProverInputFn) -> U256 {
let field = EvmField::from_str(input_fn.0[1].as_str()).unwrap();
let op = FieldOp::from_str(input_fn.0[2].as_str()).unwrap();
2022-12-01 11:15:51 -08:00
let x = stack_peek(self, 0).expect("Empty stack");
2022-07-23 11:47:10 +02:00
field.op(op, x)
}
2022-07-23 12:52:45 +02:00
2022-12-20 00:22:59 -08:00
/// Finite field extension operations.
fn run_ffe(&self, input_fn: &ProverInputFn) -> U256 {
let field = EvmField::from_str(input_fn.0[1].as_str()).unwrap();
2023-01-13 08:47:15 +04:00
let component = input_fn.0[2].as_str();
2022-12-20 00:22:59 -08:00
let xs = stack_peeks(self).expect("Empty stack");
2023-01-13 08:47:15 +04:00
// TODO: This sucks... come back later
let n = match component {
2023-01-17 15:57:46 +07:00
"component_0" => 0,
"component_1" => 1,
"component_2" => 2,
"component_3" => 3,
"component_4" => 4,
"component_5" => 5,
"component_6" => 6,
"component_7" => 7,
"component_8" => 8,
"component_9" => 9,
"component_10" => 10,
"component_11" => 11,
2023-01-13 09:06:51 +04:00
_ => panic!("out of bounds"),
2023-01-13 08:47:15 +04:00
};
2023-01-17 23:58:36 +07:00
// field.inverse_fp12(n, xs)
todo!()
2022-12-20 00:22:59 -08:00
}
/// MPT data.
2022-09-22 20:09:48 -07:00
fn run_mpt(&mut self) -> U256 {
self.mpt_prover_inputs
.pop()
.unwrap_or_else(|| panic!("Out of MPT data"))
2022-07-23 12:52:45 +02:00
}
2022-09-29 23:09:32 -07:00
/// RLP data.
fn run_rlp(&mut self) -> U256 {
self.rlp_prover_inputs
.pop()
.unwrap_or_else(|| panic!("Out of RLP data"))
}
2022-10-21 18:00:41 +02:00
2022-10-27 14:57:17 +02:00
/// Account code.
2022-12-01 11:15:51 -08:00
fn run_account_code(&mut self, input_fn: &ProverInputFn) -> U256 {
2022-10-21 18:00:41 +02:00
match input_fn.0[1].as_str() {
"length" => {
2022-10-27 14:57:17 +02:00
// Return length of code.
// stack: codehash, ...
2022-12-01 11:15:51 -08:00
let codehash = stack_peek(self, 0).expect("Empty stack");
self.inputs.contract_code[&H256::from_uint(&codehash)]
2022-10-21 18:00:41 +02:00
.len()
.into()
}
"get" => {
2022-10-27 14:57:17 +02:00
// Return `code[i]`.
// stack: i, code_length, codehash, ...
2022-12-01 11:15:51 -08:00
let i = stack_peek(self, 0).expect("Unexpected stack").as_usize();
let codehash = stack_peek(self, 2).expect("Unexpected stack");
2022-10-21 18:00:41 +02:00
self.inputs.contract_code[&H256::from_uint(&codehash)][i].into()
}
2022-10-27 14:57:17 +02:00
_ => panic!("Invalid prover input function."),
2022-10-21 18:00:41 +02:00
}
}
2022-07-23 11:47:10 +02:00
}
enum EvmField {
2022-07-23 11:47:10 +02:00
Bn254Base,
Bn254Scalar,
Secp256k1Base,
Secp256k1Scalar,
}
enum FieldOp {
Inverse,
Sqrt,
}
impl FromStr for EvmField {
type Err = Error;
2022-07-23 11:47:10 +02:00
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"bn254_base" => Bn254Base,
"bn254_scalar" => Bn254Scalar,
"secp256k1_base" => Secp256k1Base,
"secp256k1_scalar" => Secp256k1Scalar,
_ => bail!("Unrecognized field."),
2022-07-23 11:47:10 +02:00
})
}
}
impl FromStr for FieldOp {
type Err = Error;
2022-07-23 11:47:10 +02:00
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"inverse" => Inverse,
"sqrt" => Sqrt,
_ => bail!("Unrecognized field operation."),
2022-07-23 11:47:10 +02:00
})
}
}
impl EvmField {
2022-07-23 11:47:10 +02:00
fn order(&self) -> U256 {
match self {
EvmField::Bn254Base => {
2022-07-23 11:47:10 +02:00
U256::from_str("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
.unwrap()
}
EvmField::Bn254Scalar => todo!(),
EvmField::Secp256k1Base => {
2022-07-27 16:49:26 +02:00
U256::from_str("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f")
.unwrap()
}
EvmField::Secp256k1Scalar => {
2022-07-27 16:49:26 +02:00
U256::from_str("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
.unwrap()
}
2022-07-23 11:47:10 +02:00
}
}
fn op(&self, op: FieldOp, x: U256) -> U256 {
match op {
FieldOp::Inverse => self.inverse(x),
2022-07-27 17:06:16 +02:00
FieldOp::Sqrt => self.sqrt(x),
2022-07-23 11:47:10 +02:00
}
}
fn inverse(&self, x: U256) -> U256 {
let n = self.order();
assert!(x < n);
modexp(x, n - 2, n)
}
2022-07-27 17:06:16 +02:00
fn sqrt(&self, x: U256) -> U256 {
let n = self.order();
assert!(x < n);
let (q, r) = (n + 1).div_mod(4.into());
assert!(
r.is_zero(),
"Only naive sqrt implementation for now. If needed implement Tonelli-Shanks."
);
modexp(x, q, n)
}
2022-12-20 00:22:59 -08:00
2023-01-17 23:58:36 +07:00
// fn inverse_fp12(&self, n: usize, xs: Vec<U256>) -> U256 {
// let offset = 12 - n;
// let vec: Vec<U256> = xs[offset..].to_vec();
// let f = fp12_to_array(inv_fp12(vec_to_fp12(vec)));
// f[n]
// }
2022-07-23 11:47:10 +02:00
}
fn modexp(x: U256, e: U256, n: U256) -> U256 {
let mut current = x;
let mut product = U256::one();
for j in 0..256 {
2022-07-28 10:35:53 +02:00
if e.bit(j) {
2022-07-23 11:47:10 +02:00
product = U256::try_from(product.full_mul(current) % n).unwrap();
}
current = U256::try_from(current.full_mul(current) % n).unwrap();
}
product
}