From 9ec9774410c8fec0267d6c0ab72676c85f3d8137 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 14 Mar 2023 17:29:38 -0700 Subject: [PATCH] run_ops --- evm/src/bls381_arithmetic.rs | 60 +++++++++++----------- evm/src/cpu/kernel/interpreter.rs | 85 +++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 30 deletions(-) diff --git a/evm/src/bls381_arithmetic.rs b/evm/src/bls381_arithmetic.rs index bf886e1c..4a9daedd 100644 --- a/evm/src/bls381_arithmetic.rs +++ b/evm/src/bls381_arithmetic.rs @@ -31,77 +31,77 @@ pub const BLS_BASE: U512 = U512([ ]); #[derive(Debug, Copy, Clone, PartialEq)] -pub struct Fp { +pub struct Fp381 { pub val: U512, } -impl Fp { - pub fn new(val: usize) -> Fp { - Fp { +impl Fp381 { + pub fn new(val: usize) -> Fp381 { + Fp381 { val: U512::from(val), } } } -// impl Distribution for Standard { -// fn sample(&self, rng: &mut R) -> Fp { +// impl Distribution for Standard { +// fn sample(&self, rng: &mut R) -> Fp381 { // let xs = rng.gen::<[u64; 8]>(); -// Fp { +// Fp381 { // val: U512(xs) % BLS_BASE, // } // } // } -impl Add for Fp { +impl Add for Fp381 { type Output = Self; fn add(self, other: Self) -> Self { - Fp { + Fp381 { val: (self.val + other.val) % BLS_BASE, } } } -impl Neg for Fp { +impl Neg for Fp381 { type Output = Self; fn neg(self) -> Self::Output { - Fp { + Fp381 { val: (BLS_BASE - self.val) % BLS_BASE, } } } -impl Sub for Fp { +impl Sub for Fp381 { type Output = Self; fn sub(self, other: Self) -> Self { - Fp { + Fp381 { val: (BLS_BASE + self.val - other.val) % BLS_BASE, } } } -impl Fp { - fn lsh_128(self) -> Fp { +impl Fp381 { + fn lsh_128(self) -> Fp381 { let b128: U512 = U512([0, 0, 1, 0, 0, 0, 0, 0]); // since BLS_BASE < 2^384, multiplying by 2^128 doesn't overflow the U512 - Fp { + Fp381 { val: self.val.saturating_mul(b128) % BLS_BASE, } } - fn lsh_256(self) -> Fp { + fn lsh_256(self) -> Fp381 { self.lsh_128().lsh_128() } - fn lsh_512(self) -> Fp { + fn lsh_512(self) -> Fp381 { self.lsh_256().lsh_256() } } #[allow(clippy::suspicious_arithmetic_impl)] -impl Mul for Fp { +impl Mul for Fp381 { type Output = Self; fn mul(self, other: Self) -> Self { @@ -110,16 +110,16 @@ impl Mul for Fp { let (x1, x0) = self.val.div_mod(b256); let (y1, y0) = other.val.div_mod(b256); - let z00 = Fp { + let z00 = Fp381 { val: x0.saturating_mul(y0) % BLS_BASE, }; - let z01 = Fp { + let z01 = Fp381 { val: x0.saturating_mul(y1), }; - let z10 = Fp { + let z10 = Fp381 { val: x1.saturating_mul(y0), }; - let z11 = Fp { + let z11 = Fp381 { val: x1.saturating_mul(y1), }; @@ -127,16 +127,16 @@ impl Mul for Fp { } } -impl FieldExt for Fp { - const ZERO: Self = Fp { val: U512::zero() }; - const UNIT: Self = Fp { val: U512::one() }; - fn inv(self) -> Fp { +impl FieldExt for Fp381 { + const ZERO: Self = Fp381 { val: U512::zero() }; + const UNIT: Self = Fp381 { val: U512::one() }; + fn inv(self) -> Fp381 { exp_fp(self, BLS_BASE - 2) } } #[allow(clippy::suspicious_arithmetic_impl)] -impl Div for Fp { +impl Div for Fp381 { type Output = Self; fn div(self, rhs: Self) -> Self::Output { @@ -144,9 +144,9 @@ impl Div for Fp { } } -fn exp_fp(x: Fp, e: U512) -> Fp { +fn exp_fp(x: Fp381, e: U512) -> Fp381 { let mut current = x; - let mut product = Fp { val: U512::one() }; + let mut product = Fp381 { val: U512::one() }; for j in 0..512 { if e.bit(j) { diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 52876c97..42e67424 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -8,6 +8,7 @@ use ethereum_types::{U256, U512}; use keccak_hash::keccak; use plonky2::field::goldilocks_field::GoldilocksField; +use crate::bls381_arithmetic::{Fp381, BLS_BASE}; use crate::bn254_arithmetic::BN_BASE; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; @@ -438,6 +439,90 @@ impl<'a> Interpreter<'a> { self.push((x + (BN_BASE - y)) % BN_BASE); } + #[allow(dead_code)] + fn run_addfp381_lo(&mut self) { + let x1 = self.pop(); + let x0 = self.pop(); + let y1 = self.pop(); + let y0 = self.pop(); + + let x = U512::from(x0) + (U512::from(x1) << 256); + let y = U512::from(y0) + (U512::from(y1) << 256); + let z = (x + y) % BLS_BASE; + + self.push(U256(z.0[0..4].try_into().unwrap())); + } + + #[allow(dead_code)] + fn run_addfp381_hi(&mut self) { + let x1 = self.pop(); + let x0 = self.pop(); + let y1 = self.pop(); + let y0 = self.pop(); + + let x = U512::from(x0) + (U512::from(x1) << 256); + let y = U512::from(y0) + (U512::from(y1) << 256); + let z = (x + y) % BLS_BASE; + + self.push(U256(z.0[4..].try_into().unwrap())); + } + + #[allow(dead_code)] + fn run_mulfp254_lo(&mut self) { + let x1 = self.pop(); + let x0 = self.pop(); + let y1 = self.pop(); + let y0 = self.pop(); + + let x = U512::from(x0) + (U512::from(x1) << 256); + let y = U512::from(y0) + (U512::from(y1) << 256); + let z = (Fp381 {val: x} * Fp381 {val: y}).val; + + self.push(U256(z.0[0..4].try_into().unwrap())); + } + + #[allow(dead_code)] + fn run_mulfp254_hi(&mut self) { + let x1 = self.pop(); + let x0 = self.pop(); + let y1 = self.pop(); + let y0 = self.pop(); + + let x = U512::from(x0) + (U512::from(x1) << 256); + let y = U512::from(y0) + (U512::from(y1) << 256); + let z = (Fp381 {val: x} * Fp381 {val: y}).val; + + self.push(U256(z.0[4..].try_into().unwrap())); + } + + #[allow(dead_code)] + fn run_subfp381_lo(&mut self) { + let x1 = self.pop(); + let x0 = self.pop(); + let y1 = self.pop(); + let y0 = self.pop(); + + let x = U512::from(x0) + (U512::from(x1) << 256); + let y = U512::from(y0) + (U512::from(y1) << 256); + let z = (BLS_BASE + x - y) % BLS_BASE; + + self.push(U256(z.0[0..4].try_into().unwrap())); + } + + #[allow(dead_code)] + fn run_subfp381_hi(&mut self) { + let x1 = self.pop(); + let x0 = self.pop(); + let y1 = self.pop(); + let y0 = self.pop(); + + let x = U512::from(x0) + (U512::from(x1) << 256); + let y = U512::from(y0) + (U512::from(y1) << 256); + let z = (BLS_BASE + x - y) % BLS_BASE; + + self.push(U256(z.0[4..].try_into().unwrap())); + } + fn run_div(&mut self) { let x = self.pop(); let y = self.pop();