From 3c566e987ccc3b711db8cf4a783f248f9441c8a6 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 20 Dec 2022 21:53:52 -0800 Subject: [PATCH] tangent and cords work --- .../bn254/curve_arithmetic/miller_loop.asm | 50 +++++--- evm/src/cpu/kernel/tests/bn254.rs | 113 +++++++++++++++++- 2 files changed, 139 insertions(+), 24 deletions(-) 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 1f2d2fc6..37d17be8 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 @@ -196,6 +196,12 @@ after_add: %jump(miller_one) +global test_store_cord: + // stack: p1x , p1y, p2x , p2y, qx, qx_, qy, qy_ + %store_cord + // stack: + %check(100) + /// def store_cord(p1x, p1y, p2x, p2y, qx, qy): /// return sparse_store( /// p1y*p2x - p2y*p1x, @@ -243,6 +249,12 @@ after_add: %endmacro +global test_store_tangent: + // stack: px, py, qx, qx_, qy, qy_ + %store_tangent + // stack: + %check(100) + /// def store_tangent(px, py, qx, qy): /// return sparse_store( /// py**2 - 9, @@ -251,42 +263,42 @@ after_add: /// ) %macro store_tangent - // stack: px, py, qx, qx_, qy, qy_ + // stack: px, py, qx, qx_, qy, qy_ PUSH 9 - // stack: 9, px, py, qx, qx_, qy, qy_ + // stack: 9, px, py, qx, qx_, qy, qy_ DUP3 - // stack: py , 9, px, py, qx, qx_, qy, qy_ + // stack: py , 9, px, py, qx, qx_, qy, qy_ DUP1 MULFP254 - // stack: py**2 , 9, px, py, qx, qx_, qy, qy_ + // stack: py**2 , 9, px, py, qx, qx_, qy, qy_ SUBFP254 - // stack: py**2 - 9, px, py, qx, qx_, qy, qy_ + // stack: py**2 - 9, px, py, qx, qx_, qy, qy_ %mstore_kernel_general(100) - // stack: px, py, qx, qx_, qy, qy_ + // stack: px, py, qx, qx_, qy, qy_ DUP1 MULFP254 - // stack: px**2, py, qx, qx_, qy, qy_ + // stack: px**2, py, qx, qx_, qy, qy_ PUSH 3 MULFP254 - // stack: 3*px**2, py, qx, qx_, qy, qy_ + // stack: 3*px**2, py, qx, qx_, qy, qy_ PUSH 0 SUBFP254 - // stack: -3*px**2, py, qx, qx_, qy, qy_ + // stack: -3*px**2, py, qx, qx_, qy, qy_ SWAP2 - // stack: qx, py, -3px**2, qx_, qy, qy_ + // stack: qx, py, -3px**2, qx_, qy, qy_ DUP3 MULFP254 - // stack: (-3*px**2)qx, py, -3px**2, qx_, qy, qy_ + // stack: (-3*px**2)qx, py, -3px**2, qx_, qy, qy_ %mstore_kernel_general(102) - // stack: py, -3px**2, qx_, qy, qy_ + // stack: py, -3px**2, qx_, qy, qy_ PUSH 2 MULFP254 - // stack: 2py, -3px**2, qx_, qy, qy_ + // stack: 2py, -3px**2, qx_, qy, qy_ SWAP3 - // stack: qy, -3px**2, qx_, 2py, qy_ + // stack: qy, -3px**2, qx_, 2py, qy_ DUP4 MULFP254 - // stack: (2py)qy, -3px**2, qx_, 2py, qy_ + // stack: (2py)qy, -3px**2, qx_, 2py, qy_ %mstore_kernel_general(108) - // stack: -3px**2, qx_, 2py, qy_ + // stack: -3px**2, qx_, 2py, qy_ MULFP254 - // stack: (-3px**2)qx_, 2py, qy_ + // stack: (-3px**2)*qx_, 2py, qy_ %mstore_kernel_general(103) - // stack: 2py, qy_ + // stack: 2py, qy_ MULFP254 - // stack: (2py)qy_ + // stack: (2py)*qy_ %mstore_kernel_general(109) %endmacro diff --git a/evm/src/cpu/kernel/tests/bn254.rs b/evm/src/cpu/kernel/tests/bn254.rs index 68a77425..16054cd7 100644 --- a/evm/src/cpu/kernel/tests/bn254.rs +++ b/evm/src/cpu/kernel/tests/bn254.rs @@ -49,7 +49,7 @@ fn gen_fp12() -> Fp12 { } fn gen_fp12_sparse() -> Fp12 { - sparse_embed([gen_fp(), gen_fp(), gen_fp(), gen_fp(), gen_fp()]) + sparse_embed(gen_fp(), [gen_fp(), gen_fp()], [gen_fp(), gen_fp()]) } fn add_fp(x: Fp, y: Fp) -> Fp { @@ -166,11 +166,10 @@ fn sh(c: Fp6) -> Fp6 { [i9(c2), c0, c1] } -fn sparse_embed(x: [U256; 5]) -> Fp12 { - let [g0, g1, g1_, g2, g2_] = x; +fn sparse_embed(g0: Fp, g1: Fp2, g2: Fp2) -> Fp12 { [ - [embed_fp2(g0), [g1, g1_], embed_fp2(ZERO)], - [embed_fp2(ZERO), [g2, g2_], embed_fp2(ZERO)], + [embed_fp2(g0), g1, embed_fp2(ZERO)], + [embed_fp2(ZERO), g2, embed_fp2(ZERO)], ] } @@ -779,6 +778,110 @@ fn make_miller_stack(p: [Fp; 2], q: [Fp2; 2]) -> Vec { input } +fn store_tangent(p: [Fp; 2], q: [Fp2; 2]) -> Fp12 { + let [px, py] = p; + let [qx, qy] = q; + + let cx = neg_fp(mul_fp(U256::from(3), mul_fp(px, px))); + let cy = mul_fp(U256::from(2), py); + + sparse_embed( + sub_fp(mul_fp(py, py), U256::from(9)), + mul_fp2(embed_fp2(cx), qx), + mul_fp2(embed_fp2(cy), qy), + ) +} + +fn store_cord(p1: [Fp; 2], p2: [Fp; 2], q: [Fp2; 2]) -> Fp12 { + let [p1x, p1y] = p1; + let [p2x, p2y] = p2; + let [qx, qy] = q; + + let cx = sub_fp(p2y,p1y); + let cy = sub_fp(p1x,p2x); + + sparse_embed( + sub_fp(mul_fp(p1y, p2x), mul_fp(p2y, p1x)), + mul_fp2(embed_fp2(cx), qx), + mul_fp2(embed_fp2(cy), qy), + ) +} + +fn make_tan_stack(p: [Fp; 2], q: [Fp2; 2]) -> Vec { + let p: Vec = p.into_iter().collect(); + let q: Vec = q.into_iter().flatten().collect(); + + let mut input = p; + input.extend(q); + input.reverse(); + input +} + +fn make_tan_expected(p: [Fp; 2], q: [Fp2; 2]) -> Vec { + store_tangent(p, q) + .into_iter() + .flatten() + .flatten() + .rev() + .collect() +} + +#[test] +fn test_store_tangent() -> Result<()> { + let p = [gen_fp(), gen_fp()]; + let q = [[gen_fp(), gen_fp()], [gen_fp(), gen_fp()]]; + + let expected = make_tan_expected(p, q); + + let stack = make_tan_stack(p, q); + let test_tan = KERNEL.global_labels["test_store_tangent"]; + + let output: Vec = run_interpreter(test_tan, stack)?.stack().to_vec(); + + assert_eq!(output, expected); + + Ok(()) +} + +fn make_cord_stack(p1: [Fp; 2], p2: [Fp; 2], q: [Fp2; 2]) -> Vec { + let p1: Vec = p1.into_iter().collect(); + let p2: Vec = p2.into_iter().collect(); + let q: Vec = q.into_iter().flatten().collect(); + + let mut input = p1; + input.extend(p2); + input.extend(q); + input.reverse(); + input +} + +fn make_cord_expected(p1: [Fp; 2],p2: [Fp; 2], q: [Fp2; 2]) -> Vec { + store_cord(p1, p2, q) + .into_iter() + .flatten() + .flatten() + .rev() + .collect() +} + +#[test] +fn test_store_cord() -> Result<()> { + let p1 = [gen_fp(), gen_fp()]; + let p2 = [gen_fp(), gen_fp()]; + let q = [[gen_fp(), gen_fp()], [gen_fp(), gen_fp()]]; + + let expected = make_cord_expected(p1, p2, q); + + let stack = make_cord_stack(p1, p2, q); + let test_cord = KERNEL.global_labels["test_store_cord"]; + + let output: Vec = run_interpreter(test_cord, stack)?.stack().to_vec(); + + assert_eq!(output, expected); + + Ok(()) +} + #[test] fn test_miller() -> Result<()> { let p = [U256::from(1), U256::from(2)];