From 57146c83bce09848bbcef1daa60290eb324c1d11 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 7 Feb 2023 09:18:49 -0800 Subject: [PATCH] miller loop test --- evm/src/bn254_arithmetic.rs | 7 ++- evm/src/cpu/kernel/tests/bn254.rs | 94 +++++++++++++++---------------- 2 files changed, 52 insertions(+), 49 deletions(-) diff --git a/evm/src/bn254_arithmetic.rs b/evm/src/bn254_arithmetic.rs index cf26e208..8fb72d03 100644 --- a/evm/src/bn254_arithmetic.rs +++ b/evm/src/bn254_arithmetic.rs @@ -1,3 +1,4 @@ +use std::mem::transmute; use std::ops::{Add, Div, Mul, Neg, Sub}; use ethereum_types::U256; @@ -432,7 +433,6 @@ impl Fp12 { z1: -self.z1, } } - /// The nth frobenius endomorphism of a p^q field is given by mapping /// x to x^(p^n) /// which sends a + bz: Fp12 to @@ -468,6 +468,11 @@ impl Fp12 { let prod_except_six = prod_evens_except_six.scale(prod_odds_over_phi); self.conj().scale(prod_except_six) } + + pub fn on_stack(self) -> Vec { + let f: [U256; 12] = unsafe { transmute(self) }; + f.into_iter().collect() + } } #[allow(clippy::suspicious_arithmetic_impl)] diff --git a/evm/src/cpu/kernel/tests/bn254.rs b/evm/src/cpu/kernel/tests/bn254.rs index e8886e8e..daed596d 100644 --- a/evm/src/cpu/kernel/tests/bn254.rs +++ b/evm/src/cpu/kernel/tests/bn254.rs @@ -1,4 +1,3 @@ -use std::mem::transmute; use std::ops::Range; use anyhow::Result; @@ -6,7 +5,7 @@ use ethereum_types::U256; use rand::Rng; use crate::bn254_arithmetic::{Fp, Fp12, Fp2}; -use crate::bn254_pairing::{gen_fp12_sparse, tate, Curve, TwistedCurve}; +use crate::bn254_pairing::{gen_fp12_sparse, miller_loop, tate, Curve, TwistedCurve}; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::interpreter::Interpreter; use crate::memory::segments::Segment; @@ -48,19 +47,9 @@ fn extract_kernel_output(range: Range, interpreter: Interpreter<'static>) output } -fn fp12_on_stack(f: Fp12) -> Vec { - let f: [U256; 12] = unsafe { transmute(f) }; - f.into_iter().collect() -} - -fn setup_mul_test( - in0: usize, - in1: usize, - out: usize, - f: Fp12, - g: Fp12, - label: &str, -) -> InterpreterSetup { +fn setup_mul_test(out: usize, f: Fp12, g: Fp12, label: &str) -> InterpreterSetup { + let in0: usize = 64; + let in1: usize = 76; InterpreterSetup { label: label.to_string(), stack: vec![ @@ -69,14 +58,12 @@ fn setup_mul_test( U256::from(out), U256::from(0xdeadbeefu32), ], - memory: vec![(in0, fp12_on_stack(f)), (in1, fp12_on_stack(g))], + memory: vec![(in0, f.on_stack()), (in1, g.on_stack())], } } #[test] fn test_mul_fp254_12() -> Result<()> { - let in0: usize = 64; - let in1: usize = 76; let out: usize = 88; let mut rng = rand::thread_rng(); @@ -84,10 +71,9 @@ fn test_mul_fp254_12() -> Result<()> { let g: Fp12 = rng.gen::(); let h: Fp12 = gen_fp12_sparse(&mut rng); - let setup_normal: InterpreterSetup = setup_mul_test(in0, in1, out, f, g, "mul_fp254_12"); - let setup_sparse: InterpreterSetup = setup_mul_test(in0, in1, out, f, h, "mul_fp254_12_sparse"); - let setup_square: InterpreterSetup = - setup_mul_test(in0, in1, out, f, f, "square_fp254_12_test"); + let setup_normal: InterpreterSetup = setup_mul_test(out, f, g, "mul_fp254_12"); + let setup_sparse: InterpreterSetup = setup_mul_test(out, f, h, "mul_fp254_12_sparse"); + let setup_square: InterpreterSetup = setup_mul_test(out, f, f, "square_fp254_12_test"); let intrptr_normal: Interpreter = run_setup_interpreter(setup_normal).unwrap(); let intrptr_sparse: Interpreter = run_setup_interpreter(setup_sparse).unwrap(); @@ -97,9 +83,9 @@ fn test_mul_fp254_12() -> Result<()> { let out_sparse: Vec = extract_kernel_output(out..out + 12, intrptr_sparse); let out_square: Vec = extract_kernel_output(out..out + 12, intrptr_square); - let exp_normal: Vec = fp12_on_stack(f * g); - let exp_sparse: Vec = fp12_on_stack(f * h); - let exp_square: Vec = fp12_on_stack(f * f); + let exp_normal: Vec = (f * g).on_stack(); + let exp_sparse: Vec = (f * h).on_stack(); + let exp_square: Vec = (f * f).on_stack(); assert_eq!(out_normal, exp_normal); assert_eq!(out_sparse, exp_sparse); @@ -112,7 +98,7 @@ fn setup_frob_test(ptr: usize, f: Fp12, label: &str) -> InterpreterSetup { InterpreterSetup { label: label.to_string(), stack: vec![U256::from(ptr)], - memory: vec![(ptr, fp12_on_stack(f))], + memory: vec![(ptr, f.on_stack())], } } @@ -138,10 +124,10 @@ fn test_frob_fp254_12() -> Result<()> { let out_frob_3: Vec = extract_kernel_output(ptr..ptr + 12, intrptr_frob_3); let out_frob_6: Vec = extract_kernel_output(ptr..ptr + 12, intrptr_frob_6); - let exp_frob_1: Vec = fp12_on_stack(f.frob(1)); - let exp_frob_2: Vec = fp12_on_stack(f.frob(2)); - let exp_frob_3: Vec = fp12_on_stack(f.frob(3)); - let exp_frob_6: Vec = fp12_on_stack(f.frob(6)); + let exp_frob_1: Vec = f.frob(1).on_stack(); + let exp_frob_2: Vec = f.frob(2).on_stack(); + let exp_frob_3: Vec = f.frob(3).on_stack(); + let exp_frob_6: Vec = f.frob(6).on_stack(); assert_eq!(out_frob_1, exp_frob_1); assert_eq!(out_frob_2, exp_frob_2); @@ -162,11 +148,11 @@ fn test_inv_fp254_12() -> Result<()> { let setup = InterpreterSetup { label: "inv_fp254_12".to_string(), stack: vec![U256::from(ptr), U256::from(inv), U256::from(0xdeadbeefu32)], - memory: vec![(ptr, fp12_on_stack(f))], + memory: vec![(ptr, f.on_stack())], }; let interpreter: Interpreter = run_setup_interpreter(setup).unwrap(); let output: Vec = extract_kernel_output(inv..inv + 12, interpreter); - let expected: Vec = fp12_on_stack(f.inv()); + let expected: Vec = f.inv().on_stack(); assert_eq!(output, expected); @@ -197,20 +183,6 @@ fn test_inv_fp254_12() -> Result<()> { // Ok(()) // } -// #[test] -// fn test_miller() -> Result<()> { -// let p: Curve = curve_generator(); -// let q: TwistedCurve = twisted_curve_generator(); - -// let stack = make_tate_stack(p, q); -// let output = run_setup_interpreter("test_miller", stack); -// let expected = fp12_on_stack(miller_loop(p, q)); - -// assert_eq!(output, expected); - -// Ok(()) -// } - // The curve is cyclic with generator (1, 2) pub const CURVE_GENERATOR: Curve = { Curve { @@ -263,6 +235,33 @@ pub const TWISTED_GENERATOR: TwistedCurve = { } }; +#[test] +fn test_miller() -> Result<()> { + let ptr: usize = 300; + let out: usize = 400; + let inputs: Vec = vec![ + CURVE_GENERATOR.x.val, + CURVE_GENERATOR.y.val, + TWISTED_GENERATOR.x.re.val, + TWISTED_GENERATOR.x.im.val, + TWISTED_GENERATOR.y.re.val, + TWISTED_GENERATOR.y.im.val, + ]; + + let setup = InterpreterSetup { + label: "bn254_miller".to_string(), + stack: vec![U256::from(ptr), U256::from(out), U256::from(0xdeadbeefu32)], + memory: vec![(ptr, inputs)], + }; + let interpreter = run_setup_interpreter(setup).unwrap(); + let output: Vec = extract_kernel_output(out..out + 12, interpreter); + let expected = miller_loop(CURVE_GENERATOR, TWISTED_GENERATOR).on_stack(); + + assert_eq!(output, expected); + + Ok(()) +} + #[test] fn test_tate() -> Result<()> { let ptr: usize = 300; @@ -283,8 +282,7 @@ fn test_tate() -> Result<()> { }; let interpreter = run_setup_interpreter(setup).unwrap(); let output: Vec = extract_kernel_output(out..out + 12, interpreter); - // let output: Vec = interpreter.stack().to_vec(); - let expected = fp12_on_stack(tate(CURVE_GENERATOR, TWISTED_GENERATOR)); + let expected = tate(CURVE_GENERATOR, TWISTED_GENERATOR).on_stack(); assert_eq!(output, expected);