update curve add with ops

This commit is contained in:
Dmitry Vagner 2023-02-13 13:21:47 -08:00
parent 787cc8903b
commit d320fbfbca
4 changed files with 82 additions and 120 deletions

View File

@ -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
%endmacro

View File

@ -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)

View File

@ -41,11 +41,11 @@ impl InterpreterSetup {
fn extract_kernel_memory(range: Range<usize>, interpreter: Interpreter<'static>) -> Vec<U256> {
let mut output: Vec<U256> = 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

View File

@ -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",
}
}