mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-05-28 04:39:55 +00:00
fix pairing code after big BN PR merge
This commit is contained in:
parent
2158c1d267
commit
71243fd728
@ -27,18 +27,16 @@ pub(crate) fn combined_kernel() -> Kernel {
|
|||||||
include_str!("asm/curve/bn254/curve_arithmetic/constants.asm"),
|
include_str!("asm/curve/bn254/curve_arithmetic/constants.asm"),
|
||||||
include_str!("asm/curve/bn254/curve_arithmetic/curve_add.asm"),
|
include_str!("asm/curve/bn254/curve_arithmetic/curve_add.asm"),
|
||||||
include_str!("asm/curve/bn254/curve_arithmetic/curve_mul.asm"),
|
include_str!("asm/curve/bn254/curve_arithmetic/curve_mul.asm"),
|
||||||
|
include_str!("asm/curve/bn254/curve_arithmetic/glv.asm"),
|
||||||
include_str!("asm/curve/bn254/curve_arithmetic/invariant_exponent.asm"),
|
include_str!("asm/curve/bn254/curve_arithmetic/invariant_exponent.asm"),
|
||||||
|
include_str!("asm/curve/bn254/curve_arithmetic/msm.asm"),
|
||||||
|
include_str!("asm/curve/bn254/curve_arithmetic/precomputation.asm"),
|
||||||
include_str!("asm/curve/bn254/curve_arithmetic/tate_pairing.asm"),
|
include_str!("asm/curve/bn254/curve_arithmetic/tate_pairing.asm"),
|
||||||
include_str!("asm/curve/bn254/field_arithmetic/inverse.asm"),
|
include_str!("asm/curve/bn254/field_arithmetic/inverse.asm"),
|
||||||
include_str!("asm/curve/bn254/field_arithmetic/degree_6_mul.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/degree_12_mul.asm"),
|
||||||
include_str!("asm/curve/bn254/field_arithmetic/frobenius.asm"),
|
include_str!("asm/curve/bn254/field_arithmetic/frobenius.asm"),
|
||||||
include_str!("asm/curve/bn254/field_arithmetic/util.asm"),
|
include_str!("asm/curve/bn254/field_arithmetic/util.asm"),
|
||||||
include_str!("asm/curve/bn254/curve_add.asm"),
|
|
||||||
include_str!("asm/curve/bn254/curve_mul.asm"),
|
|
||||||
include_str!("asm/curve/bn254/glv.asm"),
|
|
||||||
include_str!("asm/curve/bn254/msm.asm"),
|
|
||||||
include_str!("asm/curve/bn254/precomputation.asm"),
|
|
||||||
include_str!("asm/curve/common.asm"),
|
include_str!("asm/curve/common.asm"),
|
||||||
include_str!("asm/curve/secp256k1/curve_add.asm"),
|
include_str!("asm/curve/secp256k1/curve_add.asm"),
|
||||||
include_str!("asm/curve/secp256k1/ecrecover.asm"),
|
include_str!("asm/curve/secp256k1/ecrecover.asm"),
|
||||||
|
|||||||
@ -1,305 +0,0 @@
|
|||||||
// #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
|
|
||||||
DUP2
|
|
||||||
// stack: x0, y0, x0, y0, x1, y1, retdest
|
|
||||||
%bn_check
|
|
||||||
// stack: isValid(x0, y0), x0, y0, x1, y1, retdest
|
|
||||||
DUP5
|
|
||||||
// stack: x1, isValid(x0, y0), x0, y0, x1, y1, retdest
|
|
||||||
DUP5
|
|
||||||
// stack: x1, y1, isValid(x0, y0), x0, y0, x1, y1, retdest
|
|
||||||
%bn_check
|
|
||||||
// stack: isValid(x1, y1), isValid(x0, y0), x0, y0, x1, y1, retdest
|
|
||||||
AND
|
|
||||||
// stack: isValid(x1, y1) & isValid(x0, y0), x0, y0, x1, y1, retdest
|
|
||||||
%jumpi(bn_add_valid_points)
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Otherwise return
|
|
||||||
%pop4
|
|
||||||
// stack: retdest
|
|
||||||
%bn_invalid_input
|
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
|
||||||
// Assumption: (x0,y0) and (x1,y1) are valid points.
|
|
||||||
global bn_add_valid_points:
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Check if the first point is the identity.
|
|
||||||
DUP2
|
|
||||||
// stack: y0, x0, y0, x1, y1, retdest
|
|
||||||
DUP2
|
|
||||||
// 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)
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Check if the second point is the identity.
|
|
||||||
DUP4
|
|
||||||
// stack: y1, x0, y0, x1, y1, retdest
|
|
||||||
DUP4
|
|
||||||
// stack: x1, y1, x0, y0, x1, y1, retdest
|
|
||||||
%ec_isidentity
|
|
||||||
// stack: (x1,y1)==(0,0), x0, y0, x1, y1, retdest
|
|
||||||
%jumpi(bn_add_snd_zero)
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Check if both points have the same x-coordinate.
|
|
||||||
DUP3
|
|
||||||
// stack: x1, x0, y0, x1, y1, retdest
|
|
||||||
DUP2
|
|
||||||
// stack: x0, x1, x0, y0, x1, y1, retdest
|
|
||||||
EQ
|
|
||||||
// stack: x0 == x1, x0, y0, x1, y1, retdest
|
|
||||||
%jumpi(bn_add_equal_first_coord)
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Otherwise, we can use the standard formula.
|
|
||||||
// Compute lambda = (y0 - y1)/(x0 - x1)
|
|
||||||
DUP4
|
|
||||||
// stack: y1, x0, y0, x1, y1, retdest
|
|
||||||
DUP3
|
|
||||||
// stack: y0, y1, x0, y0, x1, y1, retdest
|
|
||||||
%submod
|
|
||||||
// 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
|
|
||||||
// stack: x0 - x1, y0 - y1, x0, y0, x1, y1, retdest
|
|
||||||
%moddiv
|
|
||||||
// stack: lambda, x0, y0, x1, y1, retdest
|
|
||||||
%jump(bn_add_valid_points_with_lambda)
|
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
|
||||||
// Assumption: (x0,y0) == (0,0)
|
|
||||||
bn_add_first_zero:
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
// Just return (x1,y1)
|
|
||||||
%stack (x0, y0, x1, y1, retdest) -> (retdest, x1, y1)
|
|
||||||
JUMP
|
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
|
||||||
// Assumption: (x1,y1) == (0,0)
|
|
||||||
bn_add_snd_zero:
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Just return (x0,y0)
|
|
||||||
%stack (x0, y0, x1, y1, retdest) -> (retdest, x0, y0)
|
|
||||||
JUMP
|
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
|
||||||
// Assumption: lambda = (y0 - y1)/(x0 - x1)
|
|
||||||
bn_add_valid_points_with_lambda:
|
|
||||||
// stack: lambda, x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Compute x2 = lambda^2 - x1 - x0
|
|
||||||
DUP2
|
|
||||||
// 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
|
|
||||||
DUP1
|
|
||||||
// stack: lambda, lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
|
||||||
MULMOD
|
|
||||||
// stack: lambda^2, x1, x0, lambda, x0, y0, x1, y1, retdest
|
|
||||||
%submod
|
|
||||||
// stack: lambda^2 - x1, x0, lambda, x0, y0, x1, y1, retdest
|
|
||||||
%submod
|
|
||||||
// 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
|
|
||||||
// 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
|
|
||||||
// stack: y2, x2, lambda, x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Return x2,y2
|
|
||||||
%stack (y2, x2, lambda, x0, y0, x1, y1, retdest) -> (retdest, x2, y2)
|
|
||||||
JUMP
|
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
|
||||||
// Assumption: (x0,y0) and (x1,y1) are valid points and x0 == x1
|
|
||||||
bn_add_equal_first_coord:
|
|
||||||
// stack: x0, y0, x1, y1, retdest with x0 == x1
|
|
||||||
|
|
||||||
// Check if the points are equal
|
|
||||||
DUP2
|
|
||||||
// stack: y0, x0, y0, x1, y1, retdest
|
|
||||||
DUP5
|
|
||||||
// stack: y1, y0, x0, y0, x1, y1, retdest
|
|
||||||
EQ
|
|
||||||
// stack: y1 == y0, x0, y0, x1, y1, retdest
|
|
||||||
%jumpi(bn_add_equal_points)
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
|
|
||||||
// Otherwise, one is the negation of the other so we can return (0,0).
|
|
||||||
%pop4
|
|
||||||
// stack: retdest
|
|
||||||
PUSH 0
|
|
||||||
// stack: 0, retdest
|
|
||||||
PUSH 0
|
|
||||||
// stack: 0, 0, retdest
|
|
||||||
SWAP2
|
|
||||||
// stack: retdest, 0, 0
|
|
||||||
JUMP
|
|
||||||
|
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
|
||||||
// Assumption: x0 == x1 and y0 == y1
|
|
||||||
// Standard doubling formula.
|
|
||||||
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
|
|
||||||
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
|
|
||||||
DUP3
|
|
||||||
// stack: y0, 3/2 * x0^2, x0, y0, x1, y1, retdest
|
|
||||||
%moddiv
|
|
||||||
// stack: lambda, x0, y0, x1, y1, retdest
|
|
||||||
%jump(bn_add_valid_points_with_lambda)
|
|
||||||
|
|
||||||
// BN254 elliptic curve doubling.
|
|
||||||
// Assumption: (x0,y0) is a valid point.
|
|
||||||
// Standard doubling formula.
|
|
||||||
global bn_double:
|
|
||||||
// stack: x, y, retdest
|
|
||||||
DUP2 DUP2 %ec_isidentity
|
|
||||||
// stack: (x,y)==(0,0), x, y, retdest
|
|
||||||
%jumpi(ec_double_retself)
|
|
||||||
DUP2 DUP2
|
|
||||||
// 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.
|
|
||||||
%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
|
|
||||||
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
|
|
||||||
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)
|
|
||||||
AND
|
|
||||||
// stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N), (x,y)==(0,0)
|
|
||||||
OR
|
|
||||||
// stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0)
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
// Return (u256::MAX, u256::MAX) which is used to indicate the input was invalid.
|
|
||||||
%macro bn_invalid_input
|
|
||||||
// stack: retdest
|
|
||||||
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
||||||
// stack: u256::MAX, retdest
|
|
||||||
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
||||||
// stack: u256::MAX, u256::MAX, retdest
|
|
||||||
SWAP2
|
|
||||||
// stack: retdest, u256::MAX, u256::MAX
|
|
||||||
JUMP
|
|
||||||
%endmacro
|
|
||||||
@ -1,81 +1,95 @@
|
|||||||
// BN254 elliptic curve addition via the standard affine addition formula.
|
// #define N 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 // BN254 base field order
|
||||||
|
|
||||||
global ec_add:
|
// BN254 elliptic curve addition.
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// 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.
|
// Check if points are valid BN254 points.
|
||||||
DUP2
|
DUP2
|
||||||
|
// stack: y0, x0, y0, x1, y1, retdest
|
||||||
DUP2
|
DUP2
|
||||||
// stack: x0, y0, x0, y0, x1, y1, retdest
|
// stack: x0, y0, x0, y0, x1, y1, retdest
|
||||||
%ec_check
|
%bn_check
|
||||||
// stack: isValid(x0, y0), x0, y0, x1, y1, retdest
|
// stack: isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||||
DUP5
|
DUP5
|
||||||
|
// stack: x1, isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||||
DUP5
|
DUP5
|
||||||
// stack: x1, y1 , isValid(x0, y0), x0, y0, x1, y1, retdest
|
// stack: x1, y1, isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||||
%ec_check
|
%bn_check
|
||||||
// stack: isValid(x1, y1) , isValid(x0, y0), x0, y0, x1, y1, retdest
|
// stack: isValid(x1, y1), isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||||
AND
|
AND
|
||||||
// stack: isValid(x1, y1) & isValid(x0, y0), x0, y0, x1, y1, retdest
|
// stack: isValid(x1, y1) & isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||||
%jumpi(ec_add_valid_points)
|
%jumpi(bn_add_valid_points)
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// stack: x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Otherwise return
|
// Otherwise return
|
||||||
%pop4
|
%pop4
|
||||||
// stack: retdest
|
// stack: retdest
|
||||||
%ec_invalid_input
|
%bn_invalid_input
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
// BN254 elliptic curve addition.
|
||||||
// Assumption: (x0,y0) and (x1,y1) are valid points.
|
// Assumption: (x0,y0) and (x1,y1) are valid points.
|
||||||
global ec_add_valid_points:
|
global bn_add_valid_points:
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// stack: x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Check if the first point is the identity.
|
// Check if the first point is the identity.
|
||||||
DUP2
|
DUP2
|
||||||
|
// stack: y0, x0, y0, x1, y1, retdest
|
||||||
DUP2
|
DUP2
|
||||||
// stack: x0,y0 , x0, y0, x1, y1, retdest
|
// stack: x0, y0, x0, y0, x1, y1, retdest
|
||||||
%ec_isidentity
|
%ec_isidentity
|
||||||
// stack: (0,0)==(x0,y0), x0, y0, x1, y1, retdest
|
// stack: (x0,y0)==(0,0), x0, y0, x1, y1, retdest
|
||||||
%jumpi(ec_add_fst_zero)
|
%jumpi(bn_add_first_zero)
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// stack: x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Check if the second point is the identity.
|
// Check if the second point is the identity.
|
||||||
DUP4
|
DUP4
|
||||||
|
// stack: y1, x0, y0, x1, y1, retdest
|
||||||
DUP4
|
DUP4
|
||||||
// stack: x1,y1 , x0, y0, x1, y1, retdest
|
// stack: x1, y1, x0, y0, x1, y1, retdest
|
||||||
%ec_isidentity
|
%ec_isidentity
|
||||||
// stack: (0,0)==(x1,y1), x0, y0, x1, y1, retdest
|
// stack: (x1,y1)==(0,0), x0, y0, x1, y1, retdest
|
||||||
%jumpi(ec_add_snd_zero)
|
%jumpi(bn_add_snd_zero)
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// stack: x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Check if both points have the same x-coordinate.
|
// Check if both points have the same x-coordinate.
|
||||||
DUP3
|
DUP3
|
||||||
|
// stack: x1, x0, y0, x1, y1, retdest
|
||||||
DUP2
|
DUP2
|
||||||
// stack: x0 , x1, x0, y0, x1, y1, retdest
|
// stack: x0, x1, x0, y0, x1, y1, retdest
|
||||||
EQ
|
EQ
|
||||||
// stack: x0 == x1, x0, y0, x1, y1, retdest
|
// stack: x0 == x1, x0, y0, x1, y1, retdest
|
||||||
%jumpi(ec_add_equal_first_coord)
|
%jumpi(bn_add_equal_first_coord)
|
||||||
|
// stack: x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
|
|
||||||
// stack: x0, y0, x1, y1, retdest
|
|
||||||
// Otherwise, we can use the standard formula.
|
// Otherwise, we can use the standard formula.
|
||||||
// Compute lambda = (y0 - y1)/(x0 - x1)
|
// Compute lambda = (y0 - y1)/(x0 - x1)
|
||||||
DUP4
|
DUP4
|
||||||
|
// stack: y1, x0, y0, x1, y1, retdest
|
||||||
DUP3
|
DUP3
|
||||||
// stack: y0 , y1, x0, y0, x1, y1, retdest
|
// stack: y0, y1, x0, y0, x1, y1, retdest
|
||||||
SUBFP254
|
%submod
|
||||||
// stack: y0 - y1, x0, y0, x1, y1, retdest
|
// stack: y0 - y1, x0, y0, x1, y1, retdest
|
||||||
DUP4
|
DUP4
|
||||||
|
// stack: x1, y0 - y1, x0, y0, x1, y1, retdest
|
||||||
DUP3
|
DUP3
|
||||||
// stack: x0 , x1, y0 - y1, x0, y0, x1, y1, retdest
|
// stack: x0, x1, y0 - y1, x0, y0, x1, y1, retdest
|
||||||
SUBFP254
|
%submod
|
||||||
// stack: x0 - x1, y0 - y1, x0, y0, x1, y1, retdest
|
// stack: x0 - x1, y0 - y1, x0, y0, x1, y1, retdest
|
||||||
%divfp254
|
%divr_fp254
|
||||||
// stack: lambda, x0, y0, x1, y1, retdest
|
// stack: lambda, x0, y0, x1, y1, retdest
|
||||||
%jump(ec_add_valid_points_with_lambda)
|
%jump(bn_add_valid_points_with_lambda)
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
// BN254 elliptic curve addition.
|
||||||
// Assumption: (x0,y0) == (0,0)
|
// Assumption: (x0,y0) == (0,0)
|
||||||
ec_add_fst_zero:
|
bn_add_first_zero:
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// stack: x0, y0, x1, y1, retdest
|
||||||
// Just return (x1,y1)
|
// Just return (x1,y1)
|
||||||
%stack (x0, y0, x1, y1, retdest) -> (retdest, x1, y1)
|
%stack (x0, y0, x1, y1, retdest) -> (retdest, x1, y1)
|
||||||
@ -83,48 +97,55 @@ ec_add_fst_zero:
|
|||||||
|
|
||||||
// BN254 elliptic curve addition.
|
// BN254 elliptic curve addition.
|
||||||
// Assumption: (x1,y1) == (0,0)
|
// Assumption: (x1,y1) == (0,0)
|
||||||
ec_add_snd_zero:
|
bn_add_snd_zero:
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// stack: x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Just return (x0,y0)
|
// Just return (x0,y0)
|
||||||
%stack (x0, y0, x1, y1, retdest) -> (retdest, x0, y0)
|
%stack (x0, y0, x1, y1, retdest) -> (retdest, x0, y0)
|
||||||
JUMP
|
JUMP
|
||||||
|
|
||||||
// BN254 elliptic curve addition.
|
// BN254 elliptic curve addition.
|
||||||
// Assumption: lambda = (y0 - y1)/(x0 - x1)
|
// Assumption: lambda = (y0 - y1)/(x0 - x1)
|
||||||
ec_add_valid_points_with_lambda:
|
bn_add_valid_points_with_lambda:
|
||||||
// stack: lambda, x0, y0, x1, y1, retdest
|
// stack: lambda, x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Compute x2 = lambda^2 - x1 - x0
|
// Compute x2 = lambda^2 - x1 - x0
|
||||||
DUP2
|
DUP2
|
||||||
|
// stack: x0, lambda, x0, y0, x1, y1, retdest
|
||||||
DUP5
|
DUP5
|
||||||
// stack: x1, x0, lambda, x0, y0, x1, y1, retdest
|
// stack: x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||||
DUP3
|
%bn_base
|
||||||
// stack: lambda , x1, x0, lambda, x0, y0, x1, y1, retdest
|
// stack: N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||||
|
DUP4
|
||||||
|
// stack: lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||||
DUP1
|
DUP1
|
||||||
MULFP254
|
// stack: lambda, lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||||
// stack: lambda^2 , x1, x0, lambda, x0, y0, x1, y1, retdest
|
MULMOD
|
||||||
SUBFP254
|
// stack: lambda^2, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||||
// stack: lambda^2 - x1, x0, lambda, x0, y0, x1, y1, retdest
|
%submod
|
||||||
SUBFP254
|
// stack: lambda^2 - x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||||
// stack: x2, lambda, x0, y0, x1, y1, retdest
|
%submod
|
||||||
|
// stack: x2, lambda, x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Compute y2 = lambda*(x1 - x2) - y1
|
// Compute y2 = lambda*(x1 - x2) - y1
|
||||||
DUP1
|
%bn_base
|
||||||
// stack: x2 , x2, lambda, x0, y0, x1, y1, retdest
|
// stack: N, x2, lambda, x0, y0, x1, y1, retdest
|
||||||
DUP6
|
DUP2
|
||||||
// stack: x1 , x2 , x2, lambda, x0, y0, x1, y1, retdest
|
// stack: x2, N, x2, lambda, x0, y0, x1, y1, retdest
|
||||||
SUBFP254
|
DUP7
|
||||||
// stack: x1 - x2 , x2, lambda, x0, y0, x1, y1, retdest
|
// stack: x1, x2, N, x2, lambda, x0, y0, x1, y1, retdest
|
||||||
DUP3
|
%submod
|
||||||
// stack: lambda , x1 - x2 , x2, lambda, x0, y0, x1, y1, retdest
|
// stack: x1 - x2, N, x2, lambda, x0, y0, x1, y1, retdest
|
||||||
MULFP254
|
DUP4
|
||||||
// stack: lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest
|
// stack: lambda, x1 - x2, N, x2, lambda, x0, y0, x1, y1, retdest
|
||||||
|
MULMOD
|
||||||
|
// stack: lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest
|
||||||
DUP7
|
DUP7
|
||||||
// stack: y1, lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest
|
// stack: y1, lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest
|
||||||
SWAP1
|
SWAP1
|
||||||
// stack: lambda * (x1 - x2), y1, x2, lambda, x0, y0, x1, y1, retdest
|
// stack: lambda * (x1 - x2), y1, x2, lambda, x0, y0, x1, y1, retdest
|
||||||
SUBFP254
|
%submod
|
||||||
// stack: y2, x2, lambda, x0, y0, x1, y1, retdest
|
// stack: y2, x2, lambda, x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Return x2,y2
|
// Return x2,y2
|
||||||
%stack (y2, x2, lambda, x0, y0, x1, y1, retdest) -> (retdest, x2, y2)
|
%stack (y2, x2, lambda, x0, y0, x1, y1, retdest) -> (retdest, x2, y2)
|
||||||
@ -132,22 +153,25 @@ ec_add_valid_points_with_lambda:
|
|||||||
|
|
||||||
// BN254 elliptic curve addition.
|
// BN254 elliptic curve addition.
|
||||||
// Assumption: (x0,y0) and (x1,y1) are valid points and x0 == x1
|
// Assumption: (x0,y0) and (x1,y1) are valid points and x0 == x1
|
||||||
ec_add_equal_first_coord:
|
bn_add_equal_first_coord:
|
||||||
// stack: x0, y0, x1, y1, retdest with x0 == x1
|
// stack: x0, y0, x1, y1, retdest with x0 == x1
|
||||||
|
|
||||||
// Check if the points are equal
|
// Check if the points are equal
|
||||||
DUP2
|
DUP2
|
||||||
|
// stack: y0, x0, y0, x1, y1, retdest
|
||||||
DUP5
|
DUP5
|
||||||
// stack: y1 , y0, x0, y0, x1, y1, retdest
|
// stack: y1, y0, x0, y0, x1, y1, retdest
|
||||||
EQ
|
EQ
|
||||||
// stack: y1 == y0, x0, y0, x1, y1, retdest
|
// stack: y1 == y0, x0, y0, x1, y1, retdest
|
||||||
%jumpi(ec_add_equal_points)
|
%jumpi(bn_add_equal_points)
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// stack: x0, y0, x1, y1, retdest
|
||||||
|
|
||||||
// Otherwise, one is the negation of the other so we can return (0,0).
|
// Otherwise, one is the negation of the other so we can return (0,0).
|
||||||
%pop4
|
%pop4
|
||||||
// stack: retdest
|
// stack: retdest
|
||||||
PUSH 0 PUSH 0
|
PUSH 0
|
||||||
|
// stack: 0, retdest
|
||||||
|
PUSH 0
|
||||||
// stack: 0, 0, retdest
|
// stack: 0, 0, retdest
|
||||||
SWAP2
|
SWAP2
|
||||||
// stack: retdest, 0, 0
|
// stack: retdest, 0, 0
|
||||||
@ -157,116 +181,123 @@ ec_add_equal_first_coord:
|
|||||||
// BN254 elliptic curve addition.
|
// BN254 elliptic curve addition.
|
||||||
// Assumption: x0 == x1 and y0 == y1
|
// Assumption: x0 == x1 and y0 == y1
|
||||||
// Standard doubling formula.
|
// Standard doubling formula.
|
||||||
ec_add_equal_points:
|
bn_add_equal_points:
|
||||||
// stack: x0, y0, x1, y1, retdest
|
// stack: x0, y0, x1, y1, retdest
|
||||||
// Compute lambda = 3/2 * x0^2 / y0
|
|
||||||
|
|
||||||
|
// 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
|
DUP1
|
||||||
// stack: x0 , x0, y0, x1, y1, retdest
|
// stack: x0, x0, N, N, x0, y0, x1, y1, retdest
|
||||||
DUP1
|
MULMOD
|
||||||
MULFP254
|
// stack: x0^2, N, x0, y0, x1, y1, retdest with
|
||||||
// stack: x0^2, x0, y0, x1, y1, retdest
|
PUSH 0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea5 // 3/2 in the base field
|
||||||
%bn_3_over_2
|
// stack: 3/2, x0^2, N, x0, y0, x1, y1, retdest
|
||||||
// stack: 3/2 , x0^2, x0, y0, x1, y1, retdest
|
MULMOD
|
||||||
MULFP254
|
// stack: 3/2 * x0^2, x0, y0, x1, y1, retdest
|
||||||
// stack: 3/2 * x0^2, x0, y0, x1, y1, retdest
|
|
||||||
DUP3
|
DUP3
|
||||||
// stack: y0, 3/2 * x0^2, x0, y0, x1, y1, retdest
|
// stack: y0, 3/2 * x0^2, x0, y0, x1, y1, retdest
|
||||||
%divfp254
|
%divr_fp254
|
||||||
// stack: lambda, x0, y0, x1, y1, retdest
|
// stack: lambda, x0, y0, x1, y1, retdest
|
||||||
%jump(ec_add_valid_points_with_lambda)
|
%jump(bn_add_valid_points_with_lambda)
|
||||||
|
|
||||||
// BN254 elliptic curve doubling.
|
// BN254 elliptic curve doubling.
|
||||||
// Assumption: (x0,y0) is a valid point.
|
// Assumption: (x0,y0) is a valid point.
|
||||||
// Standard doubling formula.
|
// Standard doubling formula.
|
||||||
global ec_double:
|
global bn_double:
|
||||||
// stack: x0, y0, retdest
|
// stack: x, y, retdest
|
||||||
DUP2
|
DUP2 DUP2 %ec_isidentity
|
||||||
DUP2
|
// stack: (x,y)==(0,0), x, y, retdest
|
||||||
// stack: x0, y0, x0, y0, retdest
|
%jumpi(ec_double_retself)
|
||||||
%jump(ec_add_equal_points)
|
DUP2 DUP2
|
||||||
|
// stack: x, y, x, y, retdest
|
||||||
|
%jump(bn_add_equal_points)
|
||||||
|
|
||||||
// Push the order of the BN254 base field.
|
// Push the order of the BN254 base field.
|
||||||
%macro bn_base
|
%macro bn_base
|
||||||
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
|
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
%macro bn_3_over_2
|
// Assumption: x, y < N and 2N < 2^256.
|
||||||
// 3/2 in the base field
|
// Note: Doesn't hold for Secp256k1 base field.
|
||||||
PUSH 0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea5
|
%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
|
%endmacro
|
||||||
|
|
||||||
// Check if (x,y) is a valid curve point.
|
// Check if (x,y) is a valid curve point.
|
||||||
// Returns range & curve || is_identity
|
// Puts y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0) on top of the stack.
|
||||||
// where
|
%macro bn_check
|
||||||
// range = (x < N) & (y < N)
|
// stack: x, y
|
||||||
// curve = y^2 == (x^3 + 3)
|
|
||||||
// ident = (x,y) == (0,0)
|
|
||||||
|
|
||||||
%macro ec_check
|
|
||||||
// stack: x, y
|
|
||||||
DUP1
|
|
||||||
// stack: x, x, y
|
|
||||||
%bn_base
|
%bn_base
|
||||||
// stack: N , x, x, y
|
// stack: N, 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: x , N, y < N, x, y
|
|
||||||
LT
|
|
||||||
// stack: x < N, y < N, x, y
|
|
||||||
AND
|
|
||||||
// stack: range, x, y
|
|
||||||
SWAP2
|
|
||||||
// stack: y, x, range
|
|
||||||
DUP2
|
DUP2
|
||||||
// stack: x , y, x, range
|
// stack: x, N, x, y
|
||||||
DUP1
|
LT
|
||||||
DUP1
|
// stack: x < N, x, y
|
||||||
MULFP254
|
%bn_base
|
||||||
MULFP254
|
// stack: N, x < N, x, y
|
||||||
// stack: x^3, y, x, range
|
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
|
PUSH 3
|
||||||
ADDFP254
|
// stack: 3, x^3 % N, N, x, y, b
|
||||||
// stack: 3 + x^3, y, x, range
|
ADDMOD
|
||||||
DUP2
|
// stack: (x^3 + 3) % N, x, y, b
|
||||||
// stack: y , 3 + x^3, y, x, range
|
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
|
||||||
DUP1
|
DUP1
|
||||||
MULFP254
|
// stack: y, y, N, (x^3 + 3) % N, x, y, b
|
||||||
// stack: y^2, 3 + x^3, y, x, range
|
MULMOD
|
||||||
|
// stack: y^2 % N, (x^3 + 3) % N, x, y, b
|
||||||
EQ
|
EQ
|
||||||
// stack: curve, y, x, range
|
// stack: y^2 % N == (x^3 + 3) % N, x, y, b
|
||||||
SWAP2
|
SWAP2
|
||||||
// stack: x, y, curve, range
|
// stack: y, x, y^2 % N == (x^3 + 3) % N, b
|
||||||
%ec_isidentity
|
%ec_isidentity
|
||||||
// stack: ident , curve, range
|
// stack: (x,y)==(0,0), y^2 % N == (x^3 + 3) % N, b
|
||||||
SWAP2
|
SWAP2
|
||||||
// stack: range , curve, ident
|
// stack: b, y^2 % N == (x^3 + 3) % N, (x,y)==(0,0)
|
||||||
AND
|
AND
|
||||||
// stack: range & curve, ident
|
// stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N), (x,y)==(0,0)
|
||||||
OR
|
OR
|
||||||
// stack: is_valid
|
// stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0)
|
||||||
%endmacro
|
|
||||||
|
|
||||||
// Check if (x,y)==(0,0)
|
|
||||||
%macro ec_isidentity
|
|
||||||
// stack: x , y
|
|
||||||
OR
|
|
||||||
// stack: x | y
|
|
||||||
ISZERO
|
|
||||||
// stack: (x,y) == (0,0)
|
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
// Return (u256::MAX, u256::MAX) which is used to indicate the input was invalid.
|
// Return (u256::MAX, u256::MAX) which is used to indicate the input was invalid.
|
||||||
%macro ec_invalid_input
|
%macro bn_invalid_input
|
||||||
// stack: retdest
|
// stack: retdest
|
||||||
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
// stack: u256::MAX, retdest
|
// stack: u256::MAX, retdest
|
||||||
DUP1
|
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
// stack: u256::MAX, u256::MAX, retdest
|
// stack: u256::MAX, u256::MAX, retdest
|
||||||
SWAP2
|
SWAP2
|
||||||
// stack: retdest, u256::MAX, u256::MAX
|
// stack: retdest, u256::MAX, u256::MAX
|
||||||
|
|||||||
@ -1,90 +1,41 @@
|
|||||||
// BN254 elliptic curve scalar multiplication.
|
// BN254 elliptic curve scalar multiplication.
|
||||||
// Recursive implementation, same algorithm as in `exp.asm`.
|
// Uses GLV, wNAF with w=5, and a MSM algorithm.
|
||||||
global ec_mul:
|
global bn_mul:
|
||||||
// stack: x, y, s, retdest
|
// stack: x, y, s, retdest
|
||||||
DUP2
|
DUP2
|
||||||
// stack: y , x, y, s, retdest
|
// stack: y, x, y, s, retdest
|
||||||
DUP2
|
DUP2
|
||||||
// stack: x,y , x, y, s, retdest
|
// stack: x, y, x, y, s, retdest
|
||||||
%ec_isidentity
|
%ec_isidentity
|
||||||
// stack: (0,0)==(x,y), x, y, s, retdest
|
// stack: (x,y)==(0,0), x, y, s, retdest
|
||||||
%jumpi(ret_zero_ec_mul)
|
%jumpi(ret_zero_ec_mul)
|
||||||
// stack: x, y, s, retdest
|
// stack: x, y, s, retdest
|
||||||
DUP2
|
DUP2
|
||||||
// stack: y, x, y, s, retdest
|
// stack: y, x, y, s, retdest
|
||||||
DUP2
|
DUP2
|
||||||
// stack: x, y, x, y, s, retdest
|
// stack: x, y, x, y, s, retdest
|
||||||
%ec_check
|
%bn_check
|
||||||
// stack: isValid(x, y), x, y, s, retdest
|
// stack: isValid(x, y), x, y, s, retdest
|
||||||
%jumpi(ec_mul_valid_point)
|
%jumpi(bn_mul_valid_point)
|
||||||
// stack: x, y, s, retdest
|
// stack: x, y, s, retdest
|
||||||
%pop3
|
%pop3
|
||||||
%ec_invalid_input
|
%bn_invalid_input
|
||||||
|
|
||||||
// Same algorithm as in `exp.asm`
|
bn_mul_valid_point:
|
||||||
ec_mul_valid_point:
|
%stack (x, y, s, retdest) -> (s, bn_mul_after_glv, x, y, bn_msm, bn_mul_end, retdest)
|
||||||
// stack: x, y, s, retdest
|
%jump(bn_glv_decompose)
|
||||||
DUP3
|
bn_mul_after_glv:
|
||||||
// stack: s, x, y, s, retdest
|
// stack: bneg, a, b, x, y, bn_msm, bn_mul_end, retdest
|
||||||
%jumpi(step_case)
|
// Store bneg at this (otherwise unused) location. Will be used later in the MSM.
|
||||||
// stack: x, y, s, retdest
|
%mstore_kernel(@SEGMENT_KERNEL_BN_TABLE_Q, @BN_BNEG_LOC)
|
||||||
%jump(ret_zero_ec_mul)
|
// stack: a, b, x, y, bn_msm, bn_mul_end, retdest
|
||||||
|
PUSH bn_mul_after_a SWAP1 PUSH @SEGMENT_KERNEL_BN_WNAF_A PUSH @BN_SCALAR %jump(wnaf)
|
||||||
step_case:
|
bn_mul_after_a:
|
||||||
// stack: x, y, s, retdest
|
// stack: b, x, y, bn_msm, bn_mul_end, retdest
|
||||||
PUSH recursion_return
|
PUSH bn_mul_after_b SWAP1 PUSH @SEGMENT_KERNEL_BN_WNAF_B PUSH @BN_SCALAR %jump(wnaf)
|
||||||
// stack: recursion_return, x, y, s, retdest
|
bn_mul_after_b:
|
||||||
PUSH 2
|
// stack: x, y, bn_msm, bn_mul_end, retdest
|
||||||
// stack: 2, recursion_return, x, y, s, retdest
|
%jump(bn_precompute_table)
|
||||||
DUP5
|
bn_mul_end:
|
||||||
// stack: s , 2, recursion_return, x, y, s, retdest
|
%stack (Ax, Ay, retdest) -> (retdest, Ax, Ay)
|
||||||
DIV
|
|
||||||
// stack: s / 2, recursion_return, x, y, s, retdest
|
|
||||||
PUSH step_case_contd
|
|
||||||
// stack: step_case_contd, s / 2, recursion_return, x, y, s, retdest
|
|
||||||
DUP5
|
|
||||||
// stack: y, step_case_contd, s / 2, recursion_return, x, y, s, retdest
|
|
||||||
DUP5
|
|
||||||
// stack: x, y, step_case_contd, s / 2, recursion_return, x, y, s, retdest
|
|
||||||
%jump(ec_double)
|
|
||||||
|
|
||||||
// Assumption: 2(x,y) = (x',y')
|
|
||||||
step_case_contd:
|
|
||||||
// stack: x', y', s / 2, recursion_return, x, y, s, retdest
|
|
||||||
%jump(ec_mul_valid_point)
|
|
||||||
|
|
||||||
recursion_return:
|
|
||||||
// stack: x', y', x, y, s, retdest
|
|
||||||
SWAP4
|
|
||||||
// stack: s, y', x, y, x', retdest
|
|
||||||
PUSH 1
|
|
||||||
// stack: 1, s, y', x, y, x', retdest
|
|
||||||
AND
|
|
||||||
// stack: s & 1, y', x, y, x', retdest
|
|
||||||
SWAP1
|
|
||||||
// stack: y', s & 1, x, y, x', retdest
|
|
||||||
SWAP2
|
|
||||||
// stack: x, s & 1, y', y, x', retdest
|
|
||||||
SWAP3
|
|
||||||
// stack: y, s & 1, y', x, x', retdest
|
|
||||||
SWAP4
|
|
||||||
// stack: x', s & 1, y', x, y, retdest
|
|
||||||
SWAP1
|
|
||||||
// stack: s & 1, x', y', x, y, retdest
|
|
||||||
%jumpi(odd_scalar)
|
|
||||||
// stack: x', y', x, y, retdest
|
|
||||||
SWAP3
|
|
||||||
// stack: y, y', x, x', retdest
|
|
||||||
POP
|
|
||||||
// stack: y', x, x', retdest
|
|
||||||
SWAP1
|
|
||||||
// stack: x, y', x', retdest
|
|
||||||
POP
|
|
||||||
// stack: y', x', retdest
|
|
||||||
SWAP2
|
|
||||||
// stack: retdest, x', y'
|
|
||||||
JUMP
|
JUMP
|
||||||
|
|
||||||
odd_scalar:
|
|
||||||
// stack: x', y', x, y, retdest
|
|
||||||
%jump(ec_add_valid_points)
|
|
||||||
|
|||||||
@ -129,7 +129,7 @@ mul_tangent_2:
|
|||||||
DUP6
|
DUP6
|
||||||
DUP6
|
DUP6
|
||||||
// stack: O, after_double, retdest, 0xnm, times, O, P, Q, out {100: line}
|
// stack: O, after_double, retdest, 0xnm, times, O, P, Q, out {100: line}
|
||||||
%jump(ec_double)
|
%jump(bn_double)
|
||||||
after_double:
|
after_double:
|
||||||
// stack: 2*O, retdest, 0xnm, times, O, P, Q, out {100: line}
|
// stack: 2*O, retdest, 0xnm, times, O, P, Q, out {100: line}
|
||||||
SWAP5
|
SWAP5
|
||||||
@ -175,7 +175,7 @@ mul_cord_1:
|
|||||||
DUP7
|
DUP7
|
||||||
DUP7
|
DUP7
|
||||||
// stack: O , P, after_add, 0xnm, times, O , P, Q, out
|
// stack: O , P, after_add, 0xnm, times, O , P, Q, out
|
||||||
%jump(ec_add_valid_points)
|
%jump(bn_add_valid_points)
|
||||||
after_add:
|
after_add:
|
||||||
// stack: O + P, 0xnm, times, O , P, Q, out
|
// stack: O + P, 0xnm, times, O , P, Q, out
|
||||||
SWAP4
|
SWAP4
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
// BN254 elliptic curve scalar multiplication.
|
|
||||||
// Uses GLV, wNAF with w=5, and a MSM algorithm.
|
|
||||||
global bn_mul:
|
|
||||||
// stack: x, y, s, retdest
|
|
||||||
DUP2
|
|
||||||
// stack: y, x, y, s, retdest
|
|
||||||
DUP2
|
|
||||||
// stack: x, y, x, y, s, retdest
|
|
||||||
%ec_isidentity
|
|
||||||
// stack: (x,y)==(0,0), x, y, s, retdest
|
|
||||||
%jumpi(ret_zero_ec_mul)
|
|
||||||
// stack: x, y, s, retdest
|
|
||||||
DUP2
|
|
||||||
// stack: y, x, y, s, retdest
|
|
||||||
DUP2
|
|
||||||
// stack: x, y, x, y, s, retdest
|
|
||||||
%bn_check
|
|
||||||
// stack: isValid(x, y), x, y, s, retdest
|
|
||||||
%jumpi(bn_mul_valid_point)
|
|
||||||
// stack: x, y, s, retdest
|
|
||||||
%pop3
|
|
||||||
%bn_invalid_input
|
|
||||||
|
|
||||||
bn_mul_valid_point:
|
|
||||||
%stack (x, y, s, retdest) -> (s, bn_mul_after_glv, x, y, bn_msm, bn_mul_end, retdest)
|
|
||||||
%jump(bn_glv_decompose)
|
|
||||||
bn_mul_after_glv:
|
|
||||||
// stack: bneg, a, b, x, y, bn_msm, bn_mul_end, retdest
|
|
||||||
// Store bneg at this (otherwise unused) location. Will be used later in the MSM.
|
|
||||||
%mstore_kernel(@SEGMENT_KERNEL_BN_TABLE_Q, @BN_BNEG_LOC)
|
|
||||||
// stack: a, b, x, y, bn_msm, bn_mul_end, retdest
|
|
||||||
PUSH bn_mul_after_a SWAP1 PUSH @SEGMENT_KERNEL_BN_WNAF_A PUSH @BN_SCALAR %jump(wnaf)
|
|
||||||
bn_mul_after_a:
|
|
||||||
// stack: b, x, y, bn_msm, bn_mul_end, retdest
|
|
||||||
PUSH bn_mul_after_b SWAP1 PUSH @SEGMENT_KERNEL_BN_WNAF_B PUSH @BN_SCALAR %jump(wnaf)
|
|
||||||
bn_mul_after_b:
|
|
||||||
// stack: x, y, bn_msm, bn_mul_end, retdest
|
|
||||||
%jump(bn_precompute_table)
|
|
||||||
bn_mul_end:
|
|
||||||
%stack (Ax, Ay, retdest) -> (retdest, Ax, Ay)
|
|
||||||
JUMP
|
|
||||||
@ -1,7 +1,5 @@
|
|||||||
/// Division modulo the BN254 prime
|
// Returns reverse order divison y/x, modulo N
|
||||||
|
%macro divr_fp254
|
||||||
// Returns y * (x^-1) where the inverse is taken modulo N
|
|
||||||
%macro divfp254
|
|
||||||
// stack: x , y
|
// stack: x , y
|
||||||
%inv_fp254
|
%inv_fp254
|
||||||
// stack: x^-1, y
|
// stack: x^-1, y
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user