diff --git a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/curve_add.asm b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/curve_add.asm index e85838ea..f562f7ad 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/curve_add.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/curve_add.asm @@ -1,16 +1,6 @@ -// #define N 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 // BN254 base field order - // BN254 elliptic curve addition. // Uses the standard affine addition formula. global bn_add: - // Uncomment for test inputs. - // PUSH 0xdeadbeef - // PUSH 2 - // PUSH 1 - // PUSH 0x1bf9384aa3f0b3ad763aee81940cacdde1af71617c06f46e11510f14f3d5d121 - // PUSH 0xe7313274bb29566ff0c8220eb9841de1d96c2923c6a4028f7dd3c6a14cee770 - // stack: x0, y0, x1, y1, retdest - // Check if points are valid BN254 points. DUP2 // stack: y0, x0, y0, x1, y1, retdest @@ -46,7 +36,7 @@ global bn_add_valid_points: // stack: x0, y0, x0, y0, x1, y1, retdest %ec_isidentity // stack: (x0,y0)==(0,0), x0, y0, x1, y1, retdest - %jumpi(bn_add_first_zero) + %jumpi(bn_add_fst_zero) // stack: x0, y0, x1, y1, retdest // Check if the second point is the identity. @@ -75,13 +65,13 @@ global bn_add_valid_points: // stack: y1, x0, y0, x1, y1, retdest DUP3 // stack: y0, y1, x0, y0, x1, y1, retdest - %submod + SUBFP254 // stack: y0 - y1, x0, y0, x1, y1, retdest DUP4 // stack: x1, y0 - y1, x0, y0, x1, y1, retdest DUP3 // stack: x0, x1, y0 - y1, x0, y0, x1, y1, retdest - %submod + SUBFP254 // stack: x0 - x1, y0 - y1, x0, y0, x1, y1, retdest %divr_fp254 // stack: lambda, x0, y0, x1, y1, retdest @@ -89,7 +79,7 @@ global bn_add_valid_points: // BN254 elliptic curve addition. // Assumption: (x0,y0) == (0,0) -bn_add_first_zero: +bn_add_fst_zero: // stack: x0, y0, x1, y1, retdest // Just return (x1,y1) %stack (x0, y0, x1, y1, retdest) -> (retdest, x1, y1) @@ -114,37 +104,33 @@ bn_add_valid_points_with_lambda: // stack: x0, lambda, x0, y0, x1, y1, retdest DUP5 // stack: x1, x0, lambda, x0, y0, x1, y1, retdest - %bn_base - // stack: N, x1, x0, lambda, x0, y0, x1, y1, retdest - DUP4 - // stack: lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest + DUP3 + // stack: lambda, x1, x0, lambda, x0, y0, x1, y1, retdest DUP1 - // stack: lambda, lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest - MULMOD + // stack: lambda, lambda, x1, x0, lambda, x0, y0, x1, y1, retdest + MULFP254 // stack: lambda^2, x1, x0, lambda, x0, y0, x1, y1, retdest - %submod + SUBFP254 // stack: lambda^2 - x1, x0, lambda, x0, y0, x1, y1, retdest - %submod + SUBFP254 // stack: x2, lambda, x0, y0, x1, y1, retdest // Compute y2 = lambda*(x1 - x2) - y1 - %bn_base - // stack: N, x2, lambda, x0, y0, x1, y1, retdest - DUP2 - // stack: x2, N, x2, lambda, x0, y0, x1, y1, retdest - DUP7 - // stack: x1, x2, N, x2, lambda, x0, y0, x1, y1, retdest - %submod - // stack: x1 - x2, N, x2, lambda, x0, y0, x1, y1, retdest - DUP4 - // stack: lambda, x1 - x2, N, x2, lambda, x0, y0, x1, y1, retdest - MULMOD + DUP1 + // stack: x2, x2, lambda, x0, y0, x1, y1, retdest + DUP6 + // stack: x1, x2, x2, lambda, x0, y0, x1, y1, retdest + SUBFP254 + // stack: x1 - x2, x2, lambda, x0, y0, x1, y1, retdest + DUP3 + // stack: lambda, x1 - x2, x2, lambda, x0, y0, x1, y1, retdest + MULFP254 // stack: lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest DUP7 // stack: y1, lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest SWAP1 // stack: lambda * (x1 - x2), y1, x2, lambda, x0, y0, x1, y1, retdest - %submod + SUBFP254 // stack: y2, x2, lambda, x0, y0, x1, y1, retdest // Return x2,y2 @@ -185,19 +171,15 @@ bn_add_equal_points: // stack: x0, y0, x1, y1, retdest // Compute lambda = 3/2 * x0^2 / y0 - %bn_base - // stack: N, x0, y0, x1, y1, retdest - %bn_base - // stack: N, N, x0, y0, x1, y1, retdest - DUP3 - // stack: x0, N, N, x0, y0, x1, y1, retdest DUP1 - // stack: x0, x0, N, N, x0, y0, x1, y1, retdest - MULMOD - // stack: x0^2, N, x0, y0, x1, y1, retdest with + // stack: x0, x0, y0, x1, y1, retdest + DUP1 + // stack: x0, x0, x0, y0, x1, y1, retdest + MULFP254 + // stack: x0^2, x0, y0, x1, y1, retdest with PUSH 0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea5 // 3/2 in the base field - // stack: 3/2, x0^2, N, x0, y0, x1, y1, retdest - MULMOD + // stack: 3/2, x0^2, x0, y0, x1, y1, retdest + MULFP254 // stack: 3/2 * x0^2, x0, y0, x1, y1, retdest DUP3 // stack: y0, 3/2 * x0^2, x0, y0, x1, y1, retdest @@ -217,79 +199,59 @@ global bn_double: // stack: x, y, x, y, retdest %jump(bn_add_equal_points) -// Push the order of the BN254 base field. -%macro bn_base - PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 -%endmacro - -// Assumption: x, y < N and 2N < 2^256. -// Note: Doesn't hold for Secp256k1 base field. -%macro submod - // stack: x, y - %bn_base - // stack: N, x, y - ADD - // stack: N + x, y // Doesn't overflow since 2N < 2^256 - SUB - // stack: N + x - y // Doesn't underflow since y < N - %bn_base - // stack: N, N + x - y - SWAP1 - // stack: N + x - y, N - MOD - // stack: (N + x - y) % N = (x-y) % N -%endmacro - // Check if (x,y) is a valid curve point. -// Puts y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0) on top of the stack. +// Returns range & curve || is_identity +// where +// range = (x < N) & (y < N) +// curve = y^2 == (x^3 + 3) +// ident = (x,y) == (0,0) %macro bn_check - // stack: x, y - %bn_base - // stack: N, x, y - DUP2 - // stack: x, N, x, y - LT - // stack: x < N, x, y - %bn_base - // stack: N, x < N, x, y - DUP4 - // stack: y, N, x < N, x, y - LT - // stack: y < N, x < N, x, y - AND - // stack: (y < N) & (x < N), x, y - %stack (b, x, y) -> (x, x, @BN_BASE, x, @BN_BASE, @BN_BASE, x, y, b) - // stack: x, x, N, x, N, N, x, y, b - MULMOD - // stack: x^2 % N, x, N, N, x, y, b - MULMOD - // stack: x^3 % N, N, x, y, b - PUSH 3 - // stack: 3, x^3 % N, N, x, y, b - ADDMOD - // stack: (x^3 + 3) % N, x, y, b - DUP3 - // stack: y, (x^3 + 3) % N, x, y, b - %bn_base - // stack: N, y, (x^3 + 3) % N, x, y, b - SWAP1 - // stack: y, N, (x^3 + 3) % N, x, y, b + // stack: x, y DUP1 - // stack: y, y, N, (x^3 + 3) % N, x, y, b - MULMOD - // stack: y^2 % N, (x^3 + 3) % N, x, y, b - EQ - // stack: y^2 % N == (x^3 + 3) % N, x, y, b + // stack: x, x, y + PUSH @BN_BASE + // stack: N , x, x, y + DUP1 + // stack: N, N , x, x, y + DUP5 + // stack: y , N, N , x, x, y + LT + // stack: y < N, N , x, x, y SWAP2 - // stack: y, x, y^2 % N == (x^3 + 3) % N, b - %ec_isidentity - // stack: (x,y)==(0,0), y^2 % N == (x^3 + 3) % N, b - SWAP2 - // stack: b, y^2 % N == (x^3 + 3) % N, (x,y)==(0,0) + // stack: x , N, y < N, x, y + LT + // stack: x < N, y < N, x, y AND - // stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N), (x,y)==(0,0) + // stack: range, x, y + SWAP2 + // stack: y, x, range + DUP2 + // stack: x , y, x, range + DUP1 + DUP1 + MULFP254 + MULFP254 + // stack: x^3, y, x, range + PUSH 3 + ADDFP254 + // stack: 3 + x^3, y, x, range + DUP2 + // stack: y , 3 + x^3, y, x, range + DUP1 + MULFP254 + // stack: y^2, 3 + x^3, y, x, range + EQ + // stack: curve, y, x, range + SWAP2 + // stack: x, y, curve, range + %ec_isidentity + // stack: ident , curve, range + SWAP2 + // stack: range , curve, ident + AND + // stack: range & curve, ident OR - // stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0) + // stack: is_valid %endmacro // Return (u256::MAX, u256::MAX) which is used to indicate the input was invalid. @@ -297,9 +259,9 @@ global bn_double: // stack: retdest PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff // stack: u256::MAX, retdest - PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + DUP1 // stack: u256::MAX, u256::MAX, retdest SWAP2 // stack: retdest, u256::MAX, u256::MAX JUMP -%endmacro \ No newline at end of file +%endmacro 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 375f9bc4..a4cebd72 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 @@ -33,6 +33,7 @@ global bn254_tate: /// def miller_zero(): /// 0xnm -= 1 /// mul_tangent() + global bn254_miller: // stack: ptr, out, retdest %stack (ptr, out) -> (out, 1, ptr, out) diff --git a/evm/src/cpu/kernel/tests/bn254.rs b/evm/src/cpu/kernel/tests/bn254.rs index 6e618e9b..a4c81ab2 100644 --- a/evm/src/cpu/kernel/tests/bn254.rs +++ b/evm/src/cpu/kernel/tests/bn254.rs @@ -41,11 +41,11 @@ impl InterpreterSetup { fn extract_kernel_memory(range: Range, interpreter: Interpreter<'static>) -> Vec { let mut output: Vec = vec![]; for i in range { - let term = interpreter.generation_state.memory.get(MemoryAddress::new( - 0, - Segment::BnPairing, - i, - )); + let term = + interpreter + .generation_state + .memory + .get(MemoryAddress::new(0, Segment::BnPairing, i)); output.push(term); } output diff --git a/evm/src/memory/segments.rs b/evm/src/memory/segments.rs index c6ded3dd..6793089f 100644 --- a/evm/src/memory/segments.rs +++ b/evm/src/memory/segments.rs @@ -103,7 +103,6 @@ impl Segment { Segment::BnWnafB => "SEGMENT_KERNEL_BN_WNAF_B", Segment::BnTableQ => "SEGMENT_KERNEL_BN_TABLE_Q", Segment::BnPairing => "SEGMENT_KERNEL_BN_PAIRING", - } }