This commit is contained in:
Dmitry Vagner 2023-03-21 21:10:01 -07:00
parent 1437affcfd
commit 9ea0ebd78f
3 changed files with 125 additions and 3 deletions

View File

@ -0,0 +1,41 @@
%macro add_fp381
// stack: x0, x1, y0, y1
PROVER_INPUT(sf::bls381_base::add_hi)
// stack: z1, x0, x1, y0, y1
SWAP4
// stack: y1, x0, x1, y0, z1
PROVER_INPUT(sf::bls381_base::add_lo)
// stack: z0, y1, x0, x1, y0, z1
SWAP4
// stack: y0, y1, x0, x1, z0, z1
%pop4
// stack: z0, z1
%endmacro
%macro mul_fp381
// stack: x0, x1, y0, y1
PROVER_INPUT(sf::bls381_base::mul_hi)
// stack: z1, x0, x1, y0, y1
SWAP4
// stack: y1, x0, x1, y0, z1
PROVER_INPUT(sf::bls381_base::mul_lo)
// stack: z0, y1, x0, x1, y0, z1
SWAP4
// stack: y0, y1, x0, x1, z0, z1
%pop4
// stack: z0, z1
%endmacro
%macro sub_fp381
// stack: x0, x1, y0, y1
PROVER_INPUT(sf::bls381_base::sub_hi)
// stack: z1, x0, x1, y0, y1
SWAP4
// stack: y1, x0, x1, y0, z1
PROVER_INPUT(sf::bls381_base::sub_lo)
// stack: z0, y1, x0, x1, y0, z1
SWAP4
// stack: y0, y1, x0, x1, z0, z1
%pop4
// stack: z0, z1
%endmacro

View File

@ -137,6 +137,14 @@ impl BLS381 {
val: U512::from(val),
}
}
pub fn lo(self) -> U256 {
U256(self.val.0[..4].try_into().unwrap())
}
pub fn hi(self) -> U256 {
U256(self.val.0[4..].try_into().unwrap())
}
}
impl Distribution<BLS381> for Standard {

View File

@ -2,12 +2,12 @@ use std::mem::transmute;
use std::str::FromStr;
use anyhow::{bail, Error};
use ethereum_types::{BigEndianHash, H256, U256};
use ethereum_types::{BigEndianHash, H256, U256, U512};
use plonky2::field::types::Field;
use crate::extension_tower::{FieldExt, Fp12, BN254};
use crate::extension_tower::{FieldExt, Fp12, BLS381, BN254};
use crate::generation::prover_input::EvmField::{
Bn254Base, Bn254Scalar, Secp256k1Base, Secp256k1Scalar,
Bls381Base, Bls381Scalar, Bn254Base, Bn254Scalar, Secp256k1Base, Secp256k1Scalar,
};
use crate::generation::prover_input::FieldOp::{Inverse, Sqrt};
use crate::generation::state::GenerationState;
@ -30,6 +30,7 @@ impl<F: Field> GenerationState<F> {
match input_fn.0[0].as_str() {
"end_of_txns" => self.run_end_of_txns(),
"ff" => self.run_ff(input_fn),
"sf" => self.run_sf(input_fn),
"ffe" => self.run_ffe(input_fn),
"mpt" => self.run_mpt(),
"rlp" => self.run_rlp(),
@ -56,6 +57,24 @@ impl<F: Field> GenerationState<F> {
field.op(op, x)
}
/// Special finite field operations.
fn run_sf(&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();
let ptr = stack_peek(self, 11 - n).expect("Empty stack").as_usize();
let xs: [U256; 4] = match field {
Bn254Base => {
let mut xs: [U256; 4] = [U256::zero(); 4];
for i in 0..4 {
xs[i] = kernel_peek(self, BnPairing, ptr + i);
}
xs
}
_ => todo!(),
};
field.op(op, xs)
}
/// Finite field extension operations.
fn run_ffe(&self, input_fn: &ProverInputFn) -> U256 {
let field = EvmField::from_str(input_fn.0[1].as_str()).unwrap();
@ -126,6 +145,8 @@ impl<F: Field> GenerationState<F> {
}
enum EvmField {
Bls381Base,
Bls381Scalar,
Bn254Base,
Bn254Scalar,
Secp256k1Base,
@ -142,6 +163,8 @@ impl FromStr for EvmField {
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"bls381_base" => Bls381Base,
"bls381_scalar" => Bls381Scalar,
"bn254_base" => Bn254Base,
"bn254_scalar" => Bn254Scalar,
"secp256k1_base" => Secp256k1Base,
@ -166,6 +189,8 @@ impl FromStr for FieldOp {
impl EvmField {
fn order(&self) -> U256 {
match self {
EvmField::Bls381Base => todo!(),
EvmField::Bls381Scalar => todo!(),
EvmField::Bn254Base => {
U256::from_str("0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
.unwrap()
@ -206,6 +231,54 @@ impl EvmField {
modexp(x, q, n)
}
fn add_lo(&self, inputs: [U256; 4]) -> U256 {
let [y1, x0, x1, y0] = inputs;
let x = U512::from(x0) + (U512::from(x1) << 256);
let y = U512::from(y0) + (U512::from(y1) << 256);
let z = BLS381 { val: x } + BLS381 { val: y };
z.lo()
}
fn add_hi(&self, inputs: [U256; 4]) -> U256 {
let [x0, x1, y0, y1] = inputs;
let x = U512::from(x0) + (U512::from(x1) << 256);
let y = U512::from(y0) + (U512::from(y1) << 256);
let z = BLS381 { val: x } + BLS381 { val: y };
z.hi()
}
fn mul_lo(&self, inputs: [U256; 4]) -> U256 {
let [y1, x0, x1, y0] = inputs;
let x = U512::from(x0) + (U512::from(x1) << 256);
let y = U512::from(y0) + (U512::from(y1) << 256);
let z = BLS381 { val: x } * BLS381 { val: y };
z.lo()
}
fn mul_hi(&self, inputs: [U256; 4]) -> U256 {
let [x0, x1, y0, y1] = inputs;
let x = U512::from(x0) + (U512::from(x1) << 256);
let y = U512::from(y0) + (U512::from(y1) << 256);
let z = BLS381 { val: x } * BLS381 { val: y };
z.hi()
}
fn sub_lo(&self, inputs: [U256; 4]) -> U256 {
let [y1, x0, x1, y0] = inputs;
let x = U512::from(x0) + (U512::from(x1) << 256);
let y = U512::from(y0) + (U512::from(y1) << 256);
let z = BLS381 { val: x } - BLS381 { val: y };
z.lo()
}
fn sub_hi(&self, inputs: [U256; 4]) -> U256 {
let [x0, x1, y0, y1] = inputs;
let x = U512::from(x0) + (U512::from(x1) << 256);
let y = U512::from(y0) + (U512::from(y1) << 256);
let z = BLS381 { val: x } - BLS381 { val: y };
z.hi()
}
fn field_extension_inverse(&self, n: usize, f: [U256; 12]) -> U256 {
let f: Fp12<BN254> = unsafe { transmute(f) };
let f_inv: [U256; 12] = unsafe { transmute(f.inv()) };