From b661a70904d69f572b8150ec5c49a9e45c1cd032 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 19 Apr 2023 23:06:02 -0700 Subject: [PATCH] twisted check --- evm/src/cpu/kernel/aggregator.rs | 1 + .../curve/bn254/curve_arithmetic/pairing.asm | 54 ++++++++++- .../bn254/curve_arithmetic/twisted_curve.asm | 94 +++++++++++++++++++ .../asm/curve/bn254/field_arithmetic/util.asm | 50 ++++++++++ evm/src/cpu/kernel/constants/mod.rs | 10 +- 5 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve.asm diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 52aa09c3..2e6c38f1 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -60,6 +60,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/bn254/curve_arithmetic/msm.asm"), include_str!("asm/curve/bn254/curve_arithmetic/pairing.asm"), include_str!("asm/curve/bn254/curve_arithmetic/precomputation.asm"), + include_str!("asm/curve/bn254/curve_arithmetic/twisted_curve.asm"), include_str!("asm/curve/bn254/field_arithmetic/degree_6_mul.asm"), include_str!("asm/curve/bn254/field_arithmetic/degree_12_mul.asm"), include_str!("asm/curve/bn254/field_arithmetic/frobenius.asm"), diff --git a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/pairing.asm b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/pairing.asm index 829ceff2..5de0e5e0 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/pairing.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/pairing.asm @@ -1,10 +1,56 @@ -/// def tate(pairs: List((Curve, TwistedCurve))) -> Fp12: +/// def bn254_pairing(pairs: List((Curve, TwistedCurve))) -> Fp12: +/// +/// for P, Q in pairs: +/// assert(is_valid(P)) +/// assert(is_valid(Q)) +/// /// out = 1 /// for P, Q in pairs: /// out *= miller_loop(P, Q) +/// /// return bn254_final_exponent(out) global bn254_pairing: + // stack: k, inp, out, retdest + DUP1 + // stack: k, k, inp, out, retdest + +bn254_input_check: + // stack: j , k, inp + DUP1 + ISZERO + // stack: end?, j , k, inp + %jump(bn254_pairing_start) + // stack: j , k, inp + %sub_const(1) + // stack: j=j-1, k, inp + + stack (j, k, inp) -> (j, inp, j, k, inp) + // stack: j, inp, j, k, inp + %mul_const(6) + ADD + // stack: inp_j=inp+6j, j, k, inp + DUP1 + %load_fp254_2 + // stack: P_j, inp_j, j, k, inp + %bn_check + // stack: valid?, inp_j, j, k, inp + %assert_nonzero + // stack: inp_j, j, k, inp + %add_const(2) + %load_fp254_4 + // stack: Q_j, j, k, inp + %bn_check_twisted + // stack: valid?, j, k, inp + %assert_nonzero + // stack: j, k, inp + %jump(bn254_input_check) + +bn254_pairing_start: + // stack: k, k, inp, out, retdest + POP + +bn254_pairing_loop: // stack: k , inp, out, retdest DUP1 ISZERO @@ -14,9 +60,9 @@ global bn254_pairing: %sub_const(1) // stack: k=k-1, inp, out, retdest - %stack (k, inp, out) -> (k, inp, 200, mul_fp254_12, 200, out, out, bn254_pairing, k, inp, out) - // stack: k, inp, 200, mul_fp254_12, 200, out, out, bn254_pairing, k, inp, out retdest + %stack (k, inp, out) -> (k, inp, 200, mul_fp254_12, 200, out, out, bn254_pairing_loop, k, inp, out) + // stack: k, inp, 200, mul_fp254_12, 200, out, out, bn254_pairing_loop, k, inp, out retdest %mul_const(6) ADD - // stack: inp_k, 200, mul_fp254_12, 200, out, out, bn254_pairing, k, inp, out retdest + // stack: inp_k, 200, mul_fp254_12, 200, out, out, bn254_pairing_loop, k, inp, out retdest %jump(bn254_miller) diff --git a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve.asm b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve.asm new file mode 100644 index 00000000..d2029848 --- /dev/null +++ b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve.asm @@ -0,0 +1,94 @@ +// Check if (X,Y) is a valid curve point. +// Returns (range & curve) || is_identity +// where +// range = (x < N) & (x_ < N) & (y < N) & (y_ < N) +// curve = Y^2 == X^3 + A +// ident = (x,y) == (0,0) + +%macro bn_check_twisted + // stack: x, x_, y, y_ + %bn_check_twisted_range + // stack: range, x, x_, y, y_ + %bn_check_twisted_curve + // stack: curve , range, x, x_, y, y_ + AND + // stack: curve & range, x, x_, y, y_ + SWAP4 + // stack: y_, x, x_, y, curve & range + %bn_check_twisted_ident + // stack: ident , curve & range + OR + // stack: ident || (curve & range) + +%macro bn_check_twisted_range + // stack: x, x_, y, y_ + PUSH @BN_BASE + // stack: N, x, x_, y, y_ + %stack (N) -> (N, N, N, N) + // stack: N, N, N, N, x, x_, y, y_ + DUP8 + // stack: y_ , N, N, N, N, x, x_, y, y_ + LT + // stack: y_ < N, N, N, N, x, x_, y, y_ + SWAP3 + // stack: N, N, N, y_ < N, x, x_, y, y_ + DUP7 + // stack: y , N, N, N, y_ < N, x, x_, y, y_ + LT + // stack: y < N, N, N, y_ < N, x, x_, y, y_ + SWAP2 + // stack: N, N, y < N, y_ < N, x, x_, y, y_ + DUP6 + // stack: x_ , N, N, y < N, y_ < N, x, x_, y, y_ + LT + // stack: x_ < N, N, y < N, y_ < N, x, x_, y, y_ + SWAP1 + // stack: N, x_ < N, y < N, y_ < N, x, x_, y, y_ + DUP5 + // stack: x , N, x_ < N, y < N, y_ < N, x, x_, y, y_ + LT + // stack: x < N, x_ < N, y < N, y_ < N, x, x_, y, y_ + AND + AND + AND + // stack: range, x, x_, y, y_ +%endmacro + +%macro bn_check_twisted_curve + // stack: range, X, Y + %stack (range, X: 2, Y: 2) -> (Y, Y, range, X) + // stack: Y, Y, range, X, Y + %mul_fp254_2 + // stack: Y^2, range, X, Y + PUSH @BN_TWISTED_IM + PUSH @BN_TWISTED_RE + // stack: A, Y^2, range, X, Y + %stack (A: 2, Y2: 2, range, X: 2) -> (X, X, X, A, Y2, range, X) + // stack: X, X, X, A, Y^2, range, X, Y + %mul_fp254_2 + %mul_fp254_2 + // stack: X^3 , A, Y^2, range, X, Y + %add_fp254_2 + // stack: X^3 + A, Y^2, range, X, Y + %eq_fp254_2 + // stack: curve, range, X, Y +%endmacro + +%macro bn_check_twisted_ident + SWAP2 + // stack: a , b , c , d + ISZERO + SWAP3 + // stack: d , b , c , a==0 + ISZERO + SWAP2 + // stack: c , b , d==0, a==0 + ISZERO + SWAP1 + // stack: b , c==0, d==0, a==0 + ISZERO + // stack: b==0, c==0, d==0, a==0 + AND + AND + AND +%endmacro diff --git a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/util.asm b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/util.asm index af074714..82617e8f 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/util.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/util.asm @@ -67,6 +67,31 @@ // stack: cx, cy %endmacro +%macro eq_fp254_2 + // stack: x, x_, y, y_ + SWAP3 + // stack: y_, x_, y, x + EQ + // stack: y_==x_, y, x + SWAP2 + // stack: x, y, y_==x_ + EQ + // stack: x==y, y_==x_ + AND +%endmacro + +%macro add_fp254_2 + // stack: x, x_, y, y_ + SWAP3 + // stack: y_, x_, y, x + ADDFP254 + // stack: z_, y, x + SWAP2 + // stack: x, y, z_ + ADDFP254 + // stack: z, z_ +%endmacro + /// Given z = x + iy: Fp254_2, return complex conjugate z': Fp254_2 /// where input is represented z.re, z.im and output as z'.im, z'.re /// cost: 9; note this returns y, x for the output x + yi @@ -116,6 +141,31 @@ // stack: ac - bd, bc + ad %endmacro +// load twisted curve + +%macro load_fp254_4 + // stack: ptr + DUP1 + %add_const(2) + // stack: ind2, ptr + %mload_kernel_bn254_pairing + // stack: x2, ptr + DUP2 + %add_const(1) + // stack: ind1, x2, ptr + %mload_kernel_bn254_pairing + // stack: x1, x2, ptr + DUP3 + %add_const(3) + // stack: ind3, x1, x2, ptr + %mload_kernel_bn254_pairing + // stack: x3, x1, x2, ptr + SWAP3 + // stack: ind0, x1, x2, x3 + %mload_kernel_bn254_pairing + // stack: x0, x1, x2, x3 +%endmacro + // fp254_6 macros %macro load_fp254_6 diff --git a/evm/src/cpu/kernel/constants/mod.rs b/evm/src/cpu/kernel/constants/mod.rs index 75a96403..0f64bcc9 100644 --- a/evm/src/cpu/kernel/constants/mod.rs +++ b/evm/src/cpu/kernel/constants/mod.rs @@ -83,7 +83,7 @@ const HASH_CONSTANTS: [(&str, [u8; 32]); 2] = [ ), ]; -const EC_CONSTANTS: [(&str, [u8; 32]); 18] = [ +const EC_CONSTANTS: [(&str, [u8; 32]); 20] = [ ( "U256_MAX", hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), @@ -92,6 +92,14 @@ const EC_CONSTANTS: [(&str, [u8; 32]); 18] = [ "BN_BASE", hex!("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"), ), + ( + "BN_TWISTED_RE", + hex!("2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5"), + ), + ( + "BN_TWISTED_IM", + hex!("009713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2"), + ), ( "BN_SCALAR", hex!("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"),