diff --git a/evm/src/bn254.rs b/evm/src/bn254.rs index 1ffe5211..d07ab02e 100644 --- a/evm/src/bn254.rs +++ b/evm/src/bn254.rs @@ -1,7 +1,7 @@ use std::str::FromStr; -use itertools::Itertools; use ethereum_types::U256; +use itertools::Itertools; use rand::{thread_rng, Rng}; pub const BN_BASE: U256 = U256([ @@ -38,6 +38,27 @@ pub fn vec_to_fp12(xs: Vec) -> Fp12 { pub type Curve = [Fp; 2]; pub type TwistedCurve = [Fp2; 2]; +pub fn curve_generator() -> Curve { + [U256::one(), U256::from(2)] +} + +pub fn twisted_curve_generator() -> TwistedCurve { + [ + [ + U256::from_str("0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed") + .unwrap(), + U256::from_str("0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2") + .unwrap(), + ], + [ + U256::from_str("0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa") + .unwrap(), + U256::from_str("0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b") + .unwrap(), + ], + ] +} + const ZERO: Fp = U256([0, 0, 0, 0]); fn embed_fp2(x: Fp) -> Fp2 { @@ -707,6 +728,18 @@ pub fn miller_loop(p: Curve, q: TwistedCurve) -> Fp12 { acc } -// pub fn tate(p: Curve, q: TwistedCurve) -> Fp12 { +pub fn tate(p: Curve, q: TwistedCurve) -> Fp12 { + let mut out = miller_loop(p, q); -// } + let inv = inv_fp12(out); + out = frob_fp12(6, out); + out = mul_fp12(out, inv); + + let acc = frob_fp12(2, out); + out = mul_fp12(out, acc); + + let pow = power(out); + out = frob_fp12(3, out); + + mul_fp12(out, pow) +} diff --git a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/miller_loop.asm b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/miller_loop.asm index ba73fed1..3ef6ddb7 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/miller_loop.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/miller_loop.asm @@ -78,9 +78,9 @@ miller_final: %jump(miller_zero_final) miller_end: // stack: m, times, O, P, Q, out, retdest - %pop2 %pop2 %pop2 %pop4 + %pop2 %pop2 %pop2 %pop4 POP // stack: out, retdest - SWAP1 JUMP + JUMP miller_one: @@ -126,12 +126,6 @@ miller_zero_final: /// out = mul_fp12_sparse(out, line) /// O += O -global test_mul_tan: - // stack: out, f, retdest, 0xnm, times, O, P, Q, out - %store_fp12 - // stack: retdest, 0xnm, times, O, P, Q, out - %jump(mul_tangent) - mul_tangent: // stack: retdest, 0xnm, times, O, P, Q, out PUSH mul_tangent_2 DUP13 PUSH mul_tangent_1 @@ -169,12 +163,6 @@ after_double: /// out = mul_fp12_sparse(out, line) /// O += P -global test_mul_cord: - // stack: out, f, 0xnm, times, O, P, Q, out - %store_fp12 - // stack: 0xnm, times, O, P, Q, out - %jump(mul_cord) - mul_cord: // stack: 0xnm, times, O, P, Q, out PUSH mul_cord_1 diff --git a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/tate_pairing.asm b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/tate_pairing.asm index 27185084..7e0f6d77 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/tate_pairing.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/tate_pairing.asm @@ -1,25 +1,35 @@ -/// def tate(P : [Fp; 2], Q: [Fp2; 2]) -> Fp12: +/// def tate(P: Curve, Q: TwistedCurve) -> Fp12: /// out = miller_loop(P, Q) /// /// inv = inv_fp12(out) -/// out = frob_fp12_6(out) +/// out = frob_fp12(6, out) /// out = mul_fp12(out, inv) /// -/// acc = frob_fp12_2_(out) +/// acc = frob_fp12(2, out) /// out = mul_fp12(out, acc) /// -/// pow = fast_exp(out) -/// out = frob_fp12_3(out) +/// pow = power(out) +/// out = frob_fp12(3, out) /// out = mul_fp12(out, pow) /// /// return out +global test_tate: + // stack: ptr, P, Q, ptr, out, retdest + %store_fp6 + // stack: ptr, out, retdest + %jump(tate) + global tate: - // stack: ptr, out, retdest - PUSH post_mllr SWAP2 SWAP1 - // stack: ptr, out, post_mllr, retdest + // stack: ptr, out, retdest + DUP2 + // stack: out, ptr, out, retdest + PUSH post_mllr + // stack: post_mllr, out, ptr, out, retdest + SWAP2 + // stack: ptr, out, post_mllr, out, retdest %jump(miller_init) -global post_mllr: +global post_mllr: // stack: out, retdest PUSH tate_inv // stack: tate_inv, out, retdest @@ -29,6 +39,8 @@ global post_mllr: // stack: out, 100, tate_inv, out, retdest %jump(inv_fp12) tate_inv: + // stack: out, retdest {100: inv} + %frob_fp12_6 // stack: out, retdest {100: inv} PUSH tate_mul1 // stack: tate_mul1, out, retdest {100: inv} @@ -38,8 +50,6 @@ tate_inv: // stack: 100, out, tate_mul1, out, retdest {100: inv} DUP2 // stack: out, 100, out, tate_mul1, out, retdest {100: inv} - %frob_fp12_6 - // stack: out, 100, out, tate_mul1, out, retdest {100: inv} %jump(mul_fp12) tate_mul1: // stack: out, retdest {100: inv} @@ -52,7 +62,9 @@ tate_mul1: DUP2 // stack: out, 100, out, tate_mul2, out, retdest {100: inv} %frob_fp12_2_ - // stack: out, 100, out, tate_mul2, out, retdest {100: inv} + // stack: 100, out, tate_mul2, out, retdest {100: acc} + DUP2 + // stack: out, 100, out, tate_mul2, out, retdest {100: acc} %jump(mul_fp12) tate_mul2: // stack: out, retdest {100: acc} @@ -60,8 +72,12 @@ tate_mul2: // stack: post_pow, out, retdest {100: acc} PUSH 100 // stack: 100, post_pow, out, retdest {100: acc} - DUP3 - // stack: out, 100, post_pow, out, retdest {100: acc} + PUSH 300 + // stack: 300, 100, post_pow, out, retdest {100: acc} + DUP4 + // stack: out, 300, 100, post_pow, out, retdest {100: acc} + %move_fp12 + // stack: 300, 100, post_pow, out, retdest {100: acc, 300: out} %jump(power) post_pow: // stack: out, retdest {100: pow} diff --git a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/inverse.asm b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/inverse.asm index e8815fc3..e2fbb17b 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/inverse.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/inverse.asm @@ -40,14 +40,14 @@ global inv_fp12: // stack: inv, f, ptr, inv, retdest POP %pop4 %pop4 %pop4 // stack: ptr, inv, retdest - PUSH 100 PUSH check_inv - // stack: check_inv, 100, ptr, inv, retdest + PUSH 50 PUSH check_inv + // stack: check_inv, 50, ptr, inv, retdest SWAP3 SWAP1 SWAP2 - // stack: ptr, inv, 100, check_inv, retdest + // stack: ptr, inv, 50, check_inv, retdest %jump(mul_fp12) global check_inv: // stack: retdest - PUSH 100 %load_fp12 + PUSH 50 %load_fp12 // stack: unit?, retdest %assert_eq_unit_fp12 // stack: retdest diff --git a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/power.asm b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/power.asm index e83732a5..af0eb48b 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/power.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/power.asm @@ -227,8 +227,3 @@ power_loop_0_end: PUSH 200 PUSH power_return SWAP2 DUP2 // stack: 200, ptr, 200, power_return %jump(mul_fp12) - -%macro check(lbl) - PUSH $lbl - %jump(ret_stack) -%endmacro diff --git a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/utils.asm b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/utils.asm index 7a664a94..f134c1aa 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/utils.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/utils.asm @@ -972,6 +972,105 @@ // stack: %endmacro +%macro move_fp12 + // stack: ptr, ptr' + DUP1 + // stack: ind00, ptr, ptr' + %mload_kernel_general + // stack: x00, ptr, ptr' + DUP3 + // stack: ind00', x00, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(1) + // stack: ind01, ptr, ptr' + %mload_kernel_general + // stack: x01, ptr, ptr' + DUP3 %add_const(1) + // stack: ind01', x01, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(2) + // stack: ind02, ptr, ptr' + %mload_kernel_general + // stack: x02, ptr, ptr' + DUP3 %add_const(2) + // stack: ind02', x02, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(3) + // stack: ind03, ptr, ptr' + %mload_kernel_general + // stack: x03, ptr, ptr' + DUP3 %add_const(3) + // stack: ind03', x03, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(4) + // stack: ind04, ptr, ptr' + %mload_kernel_general + // stack: x04, ptr, ptr' + DUP3 %add_const(4) + // stack: ind04', x04, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(5) + // stack: ind05, ptr, ptr' + %mload_kernel_general + // stack: x05, ptr, ptr' + DUP3 %add_const(5) + // stack: ind05', x05, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(6) + // stack: ind06, ptr, ptr' + %mload_kernel_general + // stack: x06, ptr, ptr' + DUP3 %add_const(6) + // stack: ind06', x06, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(7) + // stack: ind07, ptr, ptr' + %mload_kernel_general + // stack: x07, ptr, ptr' + DUP3 %add_const(7) + // stack: ind07', x07, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(8) + // stack: ind08, ptr, ptr' + %mload_kernel_general + // stack: x08, ptr, ptr' + DUP3 %add_const(8) + // stack: ind08', x08, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(9) + // stack: ind09, ptr, ptr' + %mload_kernel_general + // stack: x09, ptr, ptr' + DUP3 %add_const(9) + // stack: ind09', x09, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + DUP1 %add_const(10) + // stack: ind10, ptr, ptr' + %mload_kernel_general + // stack: x10, ptr, ptr' + DUP3 %add_const(10) + // stack: ind10', x10, ptr, ptr' + %mstore_kernel_general + // stack: ptr, ptr' + %add_const(11) + // stack: ind11, ptr' + %mload_kernel_general + // stack: x11, ptr' + DUP2 %add_const(11) + // stack: ind11', x11, ptr' + %mstore_kernel_general +%endmacro + global ret_stack: // stack: out %load_fp12 diff --git a/evm/src/cpu/kernel/tests/bn254.rs b/evm/src/cpu/kernel/tests/bn254.rs index a4710f08..cc29dc43 100644 --- a/evm/src/cpu/kernel/tests/bn254.rs +++ b/evm/src/cpu/kernel/tests/bn254.rs @@ -4,8 +4,8 @@ use anyhow::Result; use ethereum_types::U256; use crate::bn254::{ - fp12_to_vec, frob_fp12, gen_fp12, gen_fp12_sparse, miller_loop, mul_fp12, power, Curve, Fp12, - TwistedCurve, + curve_generator, fp12_to_vec, frob_fp12, gen_fp12, gen_fp12_sparse, miller_loop, mul_fp12, + power, tate, twisted_curve_generator, Curve, Fp12, TwistedCurve, }; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::interpreter::run_interpreter; @@ -110,9 +110,11 @@ fn test_inv_fp12() -> Result<()> { let f: Fp12 = gen_fp12(); - let mut stack = vec![ptr]; - stack.extend(fp12_to_vec(f)); - stack.extend(vec![ptr, inv, U256::from_str("0xdeadbeef").unwrap()]); + let stack = make_stack(vec![ + vec![ptr], + fp12_to_vec(f), + vec![ptr, inv, U256::from_str("0xdeadbeef").unwrap()], + ]); let output: Vec = get_output("test_inv_fp12", stack); @@ -142,38 +144,42 @@ fn test_power() -> Result<()> { Ok(()) } -#[test] -fn test_miller() -> Result<()> { +fn make_tate_stack(p: Curve, q: TwistedCurve) -> Vec { let ptr = U256::from(300); let out = U256::from(400); - let p: Curve = [U256::one(), U256::from(2)]; - let q: TwistedCurve = [ - [ - U256::from_str("0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed") - .unwrap(), - U256::from_str("0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2") - .unwrap(), - ], - [ - U256::from_str("0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa") - .unwrap(), - U256::from_str("0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b") - .unwrap(), - ], - ]; - let p_: Vec = p.into_iter().collect(); let q_: Vec = q.into_iter().flatten().collect(); let ret_stack = make_label("ret_stack"); - let initial_stack = make_stack(vec![vec![ptr], p_, q_, vec![ptr, out, ret_stack]]); + make_stack(vec![vec![ptr], p_, q_, vec![ptr, out, ret_stack, out]]) +} - let output = get_output("test_miller", initial_stack); +#[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 = get_output("test_miller", stack); let expected = fp12_to_vec(miller_loop(p, q)); assert_eq!(output, expected); Ok(()) } + +#[test] +fn test_tate() -> Result<()> { + let p: Curve = curve_generator(); + let q: TwistedCurve = twisted_curve_generator(); + + let stack = make_tate_stack(p, q); + let output = get_output("test_tate", stack); + let expected = fp12_to_vec(tate(p, q)); + + assert_eq!(output, expected); + + Ok(()) +}