PR feedback

This commit is contained in:
wborgeaud 2022-07-06 09:25:41 +02:00
parent 5bae732ea0
commit 9747343ac2
2 changed files with 185 additions and 225 deletions

View File

@ -13,14 +13,40 @@ global ec_add:
// stack: y0, x0, y0, x1, y1, retdest
DUP2
// stack: x0, y0, x0, y0, x1, y1, retdest
ISZERO
// stack: x0==0, y0, x0, y0, x1, y1, retdest
SWAP1
// stack: y0, x0==0, x0, y0, x1, y1, retdest
ISZERO
// stack: y0==0, x0==0, x0, y0, x1, y1, retdest
%ec_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
%ec_check
// stack: isValid(x1, y1), isValid(x0, y0), x0, y0, x1, y1, retdest
AND
// stack: y0==0 & x0==0, x0, y0, x1, y1, retdest
// stack: isValid(x1, y1) & isValid(x0, y0), x0, y0, x1, y1, retdest
PUSH ec_add_valid_points
// stack: ec_add_valid_points, isValid(x1, y1) & isValid(x0, y0), x0, y0, x1, y1, retdest
JUMPI
// stack: x0, y0, x1, y1, retdest
POP
// stack: y0, x1, y1, retdest
POP
// stack: x1, y1, retdest
POP
// stack: y1, retdest
POP
// stack: retdest
%ec_invalid_input
// Assumption: (x0,y0) and (x1,y1) are valid points.
global ec_add_valid_points:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
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
PUSH ec_add_first_zero
// stack: ec_add_first_zero, y0==0 & x0==0, x0, y0, x1, y1, retdest
JUMPI
@ -29,165 +55,12 @@ global ec_add:
// stack: y1, x0, y0, x1, y1, retdest
DUP4
// stack: x1, y1, x0, y0, x1, y1, retdest
ISZERO
// stack: x1==0, y1, x0, y0, x1, y1, retdest
SWAP1
// stack: y1, x1==0, x0, y0, x1, y1, retdest
ISZERO
// stack: y1==0, x1==0, x0, y0, x1, y1, retdest
AND
// stack: y1==0 & x1==0, x0, y0, x1, y1, retdest
%ec_isidentity
// stack: (x1,y1)==(0,0), x0, y0, x1, y1, retdest
PUSH ec_add_snd_zero
// stack: ec_add_snd_zero, y1==0 & x1==0, x0, y0, x1, y1, retdest
JUMPI
// stack: x0, y0, x1, y1, retdest
DUP4
// stack: y1, x0, y0, x1, y1, retdest
DUP4
// stack: x1, y1, x0, y0, x1, y1, retdest
DUP4
// stack: y0, x1, y1, x0, y0, x1, y1, retdest
DUP4
// stack: x0, y0, x1, y1, x0, y0, x1, y1, retdest
%ec_check
// stack: isValid(x0, y0), x1, y1, x0, y0, x1, y1, retdest
PUSH ec_add_valid_first_point
// stack: ec_add_valid_first_point, isValid(x0, y0), x1, y1, x0, y0, x1, y1, retdest
JUMPI
// stack: x1, y1, x0, y0, x1, y1, retdest
POP
// stack: y1, x0, y0, x1, y1, retdest
POP
// stack: x0, y0, x1, y1, retdest
POP
// stack: y0, x1, y1, retdest
POP
// stack: x1, y1, retdest
POP
// stack: y1, retdest
POP
// stack: retdest
JUMP
// Assumption: (x0,y0) == (0,0)
ec_add_first_zero:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
POP
// stack: y0, x1, y1, retdest
POP
// stack: x1, y1, retdest
DUP2
// stack: y1, x1, y1, retdest
DUP2
// stack: x1, y1, x1, y1, retdest
ISZERO
// stack: x1==0, y1, x1, y1, retdest
SWAP1
// stack: y1, x1==0, x1, y1, retdest
ISZERO
// stack: y1==0, x1==0, x1, y1, retdest
AND
// stack: y1==0 & x1==0, x1, y1, retdest
PUSH ret_zero
// stack: ret_zero, y1==0 & x1==0, x1, y1, retdest
JUMPI
// stack: x1, y1, retdest
DUP2
// stack: y1, x1, y1, retdest
DUP2
// stack: x1, y1, x1, y1, retdest
%ec_check
// stack: isValid(x1, y1), x1, y1, retdest
PUSH ec_noop
// stack: ec_noop, isValid(x1, y1), x1, y1, retdest
JUMPI
// stack: x1, y1, retdest
POP
// stack: y1, retdest
POP
// stack: retdest
JUMP
// Assumption: (x1,y1) == (0,0) and (x0,y0) != (0,0)
ec_add_snd_zero:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
SWAP2
// stack: x1, y0, x0, y1, retdest
POP
// stack: y0, x0, y1, retdest
SWAP2
// stack: y1, x0, y0, retdest
POP
// stack: x0, y0, retdest
DUP2
// stack: y0, x0, y0, retdest
DUP2
// stack: x0, y0, x0, y0, retdest
%ec_check
// stack: isValid(x0, y0), x0, y0, retdest
PUSH ec_noop
// stack: ec_noop, isValid(x0, y0), x0, y0, retdest
JUMPI
// stack: x0, y0, retdest
POP
// stack: y0, retdest
POP
// stack: retdest
JUMP
ec_noop:
JUMPDEST
// x, y, retdest
SWAP1
// y, x, retdest
SWAP2
// retdest, x, y
JUMP
ret_zero:
JUMPDEST
// stack: x, y, retdest
POP
// stack: y, retdest
POP
// stack: retdest
PUSH 0
// stack: 0, retdest
PUSH 0
// stack: 0, 0, retdest
SWAP2
// stack: 0, retdest, 0
SWAP1
// stack: retdest, 0, 0
JUMP
// Assumption: (x0,y0) is a valid point.
ec_add_valid_first_point:
JUMPDEST
// stack: x1, y1, x0, y0, x1, y1, retdest
%ec_check
// stack: isValid(x1, y1), x0, y0, x1, y1, retdest
PUSH ec_add_valid_points
// stack: ec_add_valid_points, isValid(x1, y1), x0, y0, x1, y1, retdest
JUMPI
// stack: x0, y0, x1, y1, retdest
POP
// stack: y0, x1, y1, retdest
POP
// stack: x1, y1, retdest
POP
// stack: y1, retdest
POP
// stack: retdest
JUMP
// Assumption: (x0,y0) and (x1,y1) are valid points.
global ec_add_valid_points:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
DUP3
// stack: x1, x0, y0, x1, y1, retdest
DUP2
@ -216,6 +89,63 @@ global ec_add_valid_points:
// stack: ec_add_valid_points_with_lambda, lambda, x0, y0, x1, y1, retdest
JUMP
// Assumption: (x0,y0) == (0,0)
ec_add_first_zero:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
POP
// stack: y0, x1, y1, retdest
POP
// stack: x1, y1, retdest
DUP2
// stack: y1, x1, y1, retdest
DUP2
// stack: x1, y1, x1, y1, retdest
%ec_isidentity
// stack: (x1,y1)==(0,0), x1, y1, retdest
PUSH ret_zero
// stack: ret_zero, (x1,y1)==(0,0), x1, y1, retdest
JUMPI
// stack: x1, y1, retdest
SWAP1
// stack: y1, x1, retdest
SWAP2
// stack: retdest, x1, y1
JUMP
// Assumption: (x1,y1) == (0,0) and (x0,y0) != (0,0)
ec_add_snd_zero:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
SWAP2
// stack: x1, y0, x0, y1, retdest
POP
// stack: y0, x0, y1, retdest
SWAP2
// stack: y1, x0, y0, retdest
POP
// stack: x0, y0, retdest
SWAP1
// stack: y0, x0, retdest
SWAP2
// stack: retdest, x0, y0
JUMP
ret_zero:
JUMPDEST
// stack: x, y, retdest
POP
// stack: y, retdest
POP
// stack: retdest
PUSH 0
// stack: 0, retdest
PUSH 0
// stack: 0, 0, retdest
SWAP2
// stack: retdest, 0, 0
JUMP
ec_add_valid_points_with_lambda:
JUMPDEST
// stack: lambda, x0, y0, x1, y1, retdest
@ -223,7 +153,7 @@ ec_add_valid_points_with_lambda:
// stack: x0, lambda, x0, y0, x1, y1, retdest
DUP5
// stack: x1, x0, lambda, x0, y0, x1, y1, retdest
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
%bn_base
// stack: N, x1, x0, lambda, x0, y0, x1, y1, retdest
DUP4
// stack: lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest
@ -235,7 +165,7 @@ ec_add_valid_points_with_lambda:
// stack: lambda^2 - x1, x0, lambda, x0, y0, x1, y1, retdest
%submod
// stack: x2, lambda, x0, y0, x1, y1, retdest
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
%bn_base
// stack: N, x2, lambda, x0, y0, x1, y1, retdest
DUP2
// stack: x2, N, x2, lambda, x0, y0, x1, y1, retdest
@ -275,7 +205,7 @@ ec_add_valid_points_with_lambda:
ec_add_equal_first_coord:
JUMPDEST
// stack: x0, y0, x1, y1, retdest with x0 == x1
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
%bn_base
// stack: N, x0, y0, x1, y1, retdest
DUP3
// stack: y0, N, x0, y0, x1, y1, retdest
@ -291,16 +221,8 @@ ec_add_equal_first_coord:
// stack: y0, x1, y1, retdest
POP
// stack: x1, y1, retdest
POP
// stack: y1, retdest
POP
// stack: retdest
PUSH 0
// stack: 0, retdest
PUSH 0
// stack: 0, 0, retdest
SWAP2
// stack: retdest, 0, 0
PUSH ret_zero
// stack: ret_zero, x1, y1, retdest
JUMP
@ -308,9 +230,9 @@ ec_add_equal_first_coord:
ec_add_equal_points:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
%bn_base
// stack: N, x0, y0, x1, y1, retdest
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
%bn_base
// stack: N, N, x0, y0, x1, y1, retdest
DUP3
// stack: x0, N, N, x0, y0, x1, y1, retdest
@ -342,17 +264,22 @@ global ec_double:
// stack: ec_add_equal_points, x0, y0, x0, y0, retdest
JUMP
// 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
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
%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
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
%bn_base
// stack: N, N + x - y
SWAP1
// stack: N + x - y, N
@ -360,58 +287,97 @@ global ec_double:
// 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 ec_check
// stack: x0, y0
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
// stack: N, x0, y0
// stack: x, y
%bn_base
// stack: N, x, y
DUP2
// stack: x0, N, x0, y0
// stack: x, N, x, y
LT
// stack: x0 < N, x0, y0
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
// stack: N, x0 < N, x0, y0
// stack: x < N, x, y
%bn_base
// stack: N, x < N, x, y
DUP4
// stack: y0, N, x0 < N, x0, y0
// stack: y, N, x < N, x, y
LT
// stack: y0 < N, x0 < N, x0, y0
// stack: y < N, x < N, x, y
AND
// stack: (y0 < N) & (x0 < N), x0, y0
// stack: (y < N) & (x < N), x, y
SWAP2
// stack: y0, x0, (y0 < N) & (x0 < N), x0
// stack: y, x, (y < N) & (x < N), x
SWAP1
// stack: x0, y0, (y0 < N) & (x0 < N)
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
// stack: N, x0, y0, b
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
// stack: N, N, x0, y0, b
SWAP2
// stack: x0, N, N, y0, b
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
// stack: N, x0, N, N, y0, b
// stack: x, y, (y < N) & (x < N)
%bn_base
// stack: N, x, y, b
%bn_base
// stack: N, N, x, y, b
DUP3
// stack: x, N, N, x, y, b
%bn_base
// stack: N, x, N, N, x, y, b
DUP2
// stack: x0, N, x0, N, N, y0, b
// stack: x, N, x, N, N, x, y, b
DUP1
// stack: x0, x0, N, x0, N, N, y0, b
// stack: x, x, N, x, N, N, x, y, b
MULMOD
// stack: x0^2 % N, x0, N, N, y0, b
// stack: x^2 % N, x, N, N, x, y, b
MULMOD
// stack: x0^3 % N, N, y0, b
// stack: x^3 % N, N, x, y, b
PUSH 3
// stack: 3, x0^3 % N, N, y0, b
// stack: 3, x^3 % N, N, x, y, b
ADDMOD
// stack: (x0^3 + 3) % N, y0, b
// 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: y0, (x0^3 + 3) % N, b
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
// stack: N, y0, (x0^3 + 3) % N, b
SWAP1
// stack: y0, N, (x0^3 + 3) % N, b
// stack: y, N, (x^3 + 3) % N, x, y, b
DUP1
// stack: y0, y0, N, (x0^3 + 3) % N, b
// stack: y, y, N, (x^3 + 3) % N, x, y, b
MULMOD
// stack: y0^2 % N, (x0^3 + 3) % N, b
// stack: y^2 % N, (x^3 + 3) % N, x, y, b
EQ
// stack: y0^2 % N == (x0^3 + 3) % N, b
// stack: y^2 % N == (x^3 + 3) % N, x, y, b
SWAP2
// stack: y, x, y^2 % N == (x^3 + 3) % N, b
ISZERO
// stack: y==0, x, y^2 % N == (x^3 + 3) % N, b
SWAP1
// stack: x, y==0, y^2 % N == (x^3 + 3) % N, b
ISZERO
// stack: x==0, y==0, y^2 % N == (x^3 + 3) % N, b
AND
// stack: y0^2 % N == (x0^3 + 3) % N & (x < N) & (y < N)
// 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
%macro ec_isidentity
// stack: x, y
ISZERO
// stack: x==0, y
SWAP1
// stack: y, x==0
ISZERO
// stack: y==0, x==0
AND
// stack: y==0 & x==0
%endmacro
%macro ec_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

View File

@ -10,14 +10,8 @@ global ec_mul:
// stack: y, x, y, s, retdest
DUP2
// stack: x, y, x, y, s, retdest
ISZERO
// stack: x==0, y, x, y, s, retdest
SWAP1
// stack: y, x==0, x, y, s, retdest
ISZERO
// stack: y==0, x==0, x, y, s, retdest
AND
// stack: y==0 & x==0, x, y, s, retdest
%ec_isidentity
// stack: (x,y)==(0,0), x, y, s, retdest
PUSH ret_zero
// stack: ret_zero, y==0 & x==0, x, y, s, retdest
JUMPI
@ -38,7 +32,7 @@ global ec_mul:
// stack: s, retdest
POP
// stack: retdest
JUMP
%ec_invalid_input
// Same algorithm as in `exp.asm`
ec_mul_valid_point:
@ -131,8 +125,8 @@ recursion_return:
odd_scalar:
JUMPDEST
// stack: x', y', x, y, retdest
PUSH ec_add
// stack: ec_add, x', y', x, y, retdest
PUSH ec_add_valid_points
// stack: ec_add_valid_points, x', y', x, y, retdest
JUMP
ret_zero: