PR feedback

This commit is contained in:
wborgeaud 2022-07-15 09:56:52 +02:00
parent 62c094615d
commit 48f9b7fdf3
5 changed files with 31 additions and 102 deletions

View File

@ -12,6 +12,18 @@ global ecrecover:
// stack: v, hash, isValid(v,r,s), r, s, retdest
DUP4
// stack: r, v, hash, isValid(v,r,s), r, s, retdest
// Compute v-27 which gives the parity of the y-coordinate of the lifted point.
SWAP1
// stack: v, r, hash, isValid(v,r,s), r, s, retdest
PUSH 27
// stack: 27, v, r, hash, isValid(v,r,s), r, s, retdest
SWAP1
// stack: v, 27, r, hash, isValid(v,r,s), r, s, retdest
SUB
// stack: v - 27, r, hash, isValid(v,r,s), r, s, retdest
SWAP1
// stack: r, v - 27, hash, isValid(v,r,s), r, s, retdest
%secp_lift_x
// stack: y, sqrtOk, hash, isValid(v,r,s), r, s, retdest

View File

@ -1,34 +1,5 @@
// #define N 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 // Secp256k1 scalar field order
// Secp256k1 elliptic curve addition.
// Uses the standard affine addition formula.
global ec_add_secp:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
// Check if points are valid Secp256k1 points.
DUP2
// stack: y0, x0, y0, x1, y1, retdest
DUP2
// stack: x0, y0, x0, y0, x1, y1, retdest
%ec_check_secp
// 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_secp
// 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(ec_add_valid_points_secp)
// stack: x0, y0, x1, y1, retdest
// Otherwise return
%pop4
// stack: retdest
%ec_invalid_input
// Secp256k1 elliptic curve addition.
// Assumption: (x0,y0) and (x1,y1) are valid points.
global ec_add_valid_points_secp:
@ -232,7 +203,7 @@ ec_add_equal_points:
// stack: lambda, x0, y0, x1, y1, retdest
%jump(ec_add_valid_points_with_lambda)
// BN254 elliptic curve doubling.
// Secp256k1 elliptic curve doubling.
// Assumption: (x0,y0) is a valid point.
// Standard doubling formula.
global ec_double_secp:
@ -249,6 +220,7 @@ global ec_double_secp:
PUSH 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
%endmacro
// Modular subtraction. Subtraction x-y underflows iff x<x-y, so can be computed as N*(x<x-y) + x-y.
%macro submod_secp_base
// stack: x, y
SWAP1

View File

@ -1,27 +1,3 @@
// Secp256k1 elliptic curve scalar multiplication.
// Recursive implementation, same algorithm as in `exp.asm`.
global ec_mul_secp:
JUMPDEST
// 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
%ec_check_secp
// stack: isValid(x, y), x, y, s, retdest
%jumpi(ec_mul_valid_point_secp)
// stack: x, y, s, retdest
%pop3
%ec_invalid_input
// Same algorithm as in `exp.asm`
global ec_mul_valid_point_secp:
JUMPDEST

View File

@ -1,41 +1,33 @@
// Returns y such that (x,y) is on Secp256k1 and y&1 = v - 27,
// Returns y such that (x,y) is on Secp256k1 and y&1 = parity,
// as well as a flag indicating whether such a y exists.
%macro secp_lift_x
// stack: x, v
// stack: x, parity
%cubemodn_secp_base
// stack: x^3, v
// stack: x^3, parity
PUSH 7
// stack: 7, x^3, v
// stack: 7, x^3, parity
%addmodn_secp_base
// stack: x^3+7, x, v
// stack: x^3+7, x, parity
DUP1
// stack: x^3+7, x^3+7, v
// stack: x^3+7, x^3+7, parity
%sqrt_secp_base
// stack: y, x^3+7, x, v
// stack: y, x^3+7, x, parity
SWAP1
// stack: x^3+7, y, v
// stack: x^3+7, y, parity
DUP2
// stack: y, x^3+7, y, v
// stack: y, x^3+7, y, parity
%squaremodn_secp_base
// stack: y^2, x^3+7, y, v
// stack: y^2, x^3+7, y, parity
EQ
// stack: sqrtOk, y, v
// stack: sqrtOk, y, parity
SWAP2
// stack: v, y, sqrtOk
// stack: parity, y, sqrtOk
DUP2
// stack: y, v, y, sqrtOk
// stack: y, parity, y, sqrtOk
PUSH 1
// stack: 1, y, v, y, sqrtOk
// stack: 1, y, parity, y, sqrtOk
AND
// stack: 1 & y, v, y, sqrtOk
PUSH 27
// stack: 27, 1 & y, v, y, sqrtOk
SWAP1
// stack: 1 & y, 27, v, y, sqrtOk
SWAP2
// stack: v, 27, 1 & y, y, sqrtOk
SUB
// stack: v - 27, 1 & y, y, sqrtOk
// stack: 1 & y, parity, y, sqrtOk
EQ
// stack: correctParity, y, sqrtOk
DUP2

View File

@ -136,7 +136,6 @@ mod bn {
#[cfg(test)]
mod secp {
use anyhow::Result;
use ethereum_types::U256;
use crate::cpu::kernel::aggregator::combined_kernel;
use crate::cpu::kernel::interpreter::run;
@ -146,11 +145,10 @@ mod secp {
fn test_ec_ops() -> Result<()> {
// Make sure we can parse and assemble the entire kernel.
let kernel = combined_kernel();
let ec_add = kernel.global_labels["ec_add_secp"];
let ec_add = kernel.global_labels["ec_add_valid_points_secp"];
let ec_double = kernel.global_labels["ec_double_secp"];
let ec_mul = kernel.global_labels["ec_mul_secp"];
let ec_mul = kernel.global_labels["ec_mul_valid_point_secp"];
let identity = ("0x0", "0x0");
let invalid = ("0x0", "0x3"); // Not on curve
let point0 = (
"0xc82ccceebd739e646631b7270ed8c33e96c4940b19db91eaf67da6ec92d109b",
"0xe0d241d2de832656c3eed78271bb06b5602d6473742c7c48a38b9f0350a76164",
@ -212,23 +210,6 @@ mod secp {
let stack = run(&kernel.code, ec_add, initial_stack);
assert_eq!(stack, u256ify([identity.1, identity.0])?);
// Addition with invalid point(s) #1
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, invalid.1, invalid.0])?;
let stack = run(&kernel.code, ec_add, initial_stack);
assert_eq!(stack, vec![U256::MAX, U256::MAX]);
// Addition with invalid point(s) #2
let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, point0.1, point0.0])?;
let stack = run(&kernel.code, ec_add, initial_stack);
assert_eq!(stack, vec![U256::MAX, U256::MAX]);
// Addition with invalid point(s) #3
let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, identity.1, identity.0])?;
let stack = run(&kernel.code, ec_add, initial_stack);
assert_eq!(stack, vec![U256::MAX, U256::MAX]);
// Addition with invalid point(s) #4
let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, invalid.1, invalid.0])?;
let stack = run(&kernel.code, ec_add, initial_stack);
assert_eq!(stack, vec![U256::MAX, U256::MAX]);
// Scalar multiplication #1
let initial_stack = u256ify(["0xdeadbeef", s, point0.1, point0.0])?;
let stack = run(&kernel.code, ec_mul, initial_stack);
@ -245,10 +226,6 @@ mod secp {
let initial_stack = u256ify(["0xdeadbeef", s, identity.1, identity.0])?;
let stack = run(&kernel.code, ec_mul, initial_stack);
assert_eq!(stack, u256ify([identity.1, identity.0])?);
// Scalar multiplication #5
let initial_stack = u256ify(["0xdeadbeef", s, invalid.1, invalid.0])?;
let stack = run(&kernel.code, ec_mul, initial_stack);
assert_eq!(stack, vec![U256::MAX, U256::MAX]);
// Multiple calls
let ec_mul_hex = format!("0x{:x}", ec_mul);