diff --git a/evm/src/cpu/kernel/asm/ecrecover.asm b/evm/src/cpu/kernel/asm/ecrecover.asm index 0d1776dd..d0994054 100644 --- a/evm/src/cpu/kernel/asm/ecrecover.asm +++ b/evm/src/cpu/kernel/asm/ecrecover.asm @@ -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 diff --git a/evm/src/cpu/kernel/asm/secp256k1/curve_add.asm b/evm/src/cpu/kernel/asm/secp256k1/curve_add.asm index f150e20e..7f9c1fff 100644 --- a/evm/src/cpu/kernel/asm/secp256k1/curve_add.asm +++ b/evm/src/cpu/kernel/asm/secp256k1/curve_add.asm @@ -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 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);