plonky2/evm/src/cpu/kernel/asm/curve_mul.asm

115 lines
2.7 KiB
NASM
Raw Normal View History

2022-07-07 08:26:57 +02:00
// BN254 elliptic curve scalar multiplication.
// Recursive implementation, same algorithm as in `exp.asm`.
2022-07-05 11:09:25 +02:00
global ec_mul:
2022-07-05 21:12:11 +02:00
// Uncomment for test inputs.
// PUSH 0xdeadbeef
// PUSH 0xd
// PUSH 2
// PUSH 1
2022-07-05 11:09:25 +02:00
JUMPDEST
// stack: x, y, s, retdest
2022-07-05 12:11:35 +02:00
DUP2
// stack: y, x, y, s, retdest
DUP2
// stack: x, y, x, y, s, retdest
2022-07-06 09:25:41 +02:00
%ec_isidentity
// stack: (x,y)==(0,0), x, y, s, retdest
2022-07-07 19:28:11 +02:00
%jumpi(ret_zero)
2022-07-05 21:22:05 +02:00
// stack: x, y, s, retdest
DUP2
// stack: y, x, y, s, retdest
DUP2
// stack: x, y, x, y, s, retdest
2022-07-05 12:11:35 +02:00
%ec_check
// stack: isValid(x, y), x, y, s, retdest
2022-07-07 19:28:11 +02:00
%jumpi(ec_mul_valid_point)
2022-07-05 12:11:35 +02:00
// stack: x, y, s, retdest
2022-07-07 19:15:39 +02:00
%pop3
2022-07-06 09:25:41 +02:00
%ec_invalid_input
2022-07-05 12:11:35 +02:00
2022-07-05 21:24:51 +02:00
// Same algorithm as in `exp.asm`
2022-07-05 12:11:35 +02:00
ec_mul_valid_point:
JUMPDEST
// stack: x, y, s, retdest
DUP3
// stack: s, x, y, s, retdest
2022-07-07 19:28:11 +02:00
%jumpi(step_case)
2022-07-05 12:11:35 +02:00
// stack: x, y, s, retdest
2022-07-07 19:15:39 +02:00
%jump(ret_zero)
2022-07-05 12:11:35 +02:00
step_case:
JUMPDEST
// stack: x, y, s, retdest
PUSH recursion_return
// stack: recursion_return, x, y, s, retdest
PUSH 2
// stack: 2, recursion_return, x, y, s, retdest
DUP5
// stack: s, 2, recursion_return, x, y, s, retdest
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
2022-07-07 19:15:39 +02:00
%jump(ec_double)
2022-07-05 12:11:35 +02:00
// Assumption: 2(x,y) = (x',y')
step_case_contd:
JUMPDEST
// stack: x', y', s / 2, recursion_return, x, y, s, retdest
2022-07-07 19:15:39 +02:00
%jump(ec_mul_valid_point)
2022-07-05 12:11:35 +02:00
recursion_return:
JUMPDEST
// 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
2022-07-07 19:15:39 +02:00
%jumpi(odd_scalar)
2022-07-05 12:11:35 +02:00
// 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
odd_scalar:
JUMPDEST
// stack: x', y', x, y, retdest
2022-07-07 19:15:39 +02:00
%jump(ec_add_valid_points)
2022-07-05 21:22:05 +02:00
ret_zero:
JUMPDEST
// stack: x, y, s, retdest
2022-07-07 19:15:39 +02:00
%pop3
2022-07-05 21:22:05 +02:00
// stack: retdest
PUSH 0
// stack: 0, retdest
PUSH 0
// stack: 0, 0, retdest
SWAP2
// stack: retdest, 0, 0
JUMP