mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-06 07:43:10 +00:00
Files shuffling
This commit is contained in:
parent
f053932791
commit
c8c3cc9a8f
@ -22,6 +22,10 @@ pub(crate) fn combined_kernel() -> Kernel {
|
||||
include_str!("asm/curve_mul.asm"),
|
||||
include_str!("asm/curve_add.asm"),
|
||||
include_str!("asm/moddiv.asm"),
|
||||
// include_str!("asm/secp256k1/curve_mul.asm"),
|
||||
// include_str!("asm/secp256k1/curve_add.asm"),
|
||||
// include_str!("asm/secp256k1/moddiv.asm"),
|
||||
include_str!("asm/ecrecover.asm"),
|
||||
include_str!("asm/storage_read.asm"),
|
||||
include_str!("asm/storage_write.asm"),
|
||||
];
|
||||
@ -32,14 +36,7 @@ pub(crate) fn combined_kernel() -> Kernel {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use ethereum_types::U256;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::cpu::kernel::aggregator::combined_kernel;
|
||||
use crate::cpu::kernel::interpreter::run;
|
||||
|
||||
#[test]
|
||||
fn make_kernel() {
|
||||
@ -47,171 +44,4 @@ mod tests {
|
||||
let kernel = combined_kernel();
|
||||
println!("Kernel size: {} bytes", kernel.code.len());
|
||||
}
|
||||
|
||||
fn u256ify<'a>(hexes: impl IntoIterator<Item = &'a str>) -> Result<Vec<U256>> {
|
||||
Ok(hexes
|
||||
.into_iter()
|
||||
.map(U256::from_str)
|
||||
.collect::<Result<Vec<_>, _>>()?)
|
||||
}
|
||||
#[test]
|
||||
fn test_exp() -> Result<()> {
|
||||
// Make sure we can parse and assemble the entire kernel.
|
||||
let kernel = combined_kernel();
|
||||
let exp = kernel.global_labels["exp"];
|
||||
let mut rng = thread_rng();
|
||||
let a = U256([0; 4].map(|_| rng.gen()));
|
||||
let b = U256([0; 4].map(|_| rng.gen()));
|
||||
|
||||
// Random input
|
||||
let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, a];
|
||||
let stack_with_kernel = run(&kernel.code, exp, initial_stack);
|
||||
let initial_stack = vec![b, a];
|
||||
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
|
||||
let stack_with_opcode = run(&code, 0, initial_stack);
|
||||
assert_eq!(stack_with_kernel, stack_with_opcode);
|
||||
|
||||
// 0 base
|
||||
let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, U256::zero()];
|
||||
let stack_with_kernel = run(&kernel.code, exp, initial_stack);
|
||||
let initial_stack = vec![b, U256::zero()];
|
||||
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
|
||||
let stack_with_opcode = run(&code, 0, initial_stack);
|
||||
assert_eq!(stack_with_kernel, stack_with_opcode);
|
||||
|
||||
// 0 exponent
|
||||
let initial_stack = vec![U256::from_str("0xdeadbeef")?, U256::zero(), a];
|
||||
let stack_with_kernel = run(&kernel.code, exp, initial_stack);
|
||||
let initial_stack = vec![U256::zero(), a];
|
||||
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
|
||||
let stack_with_opcode = run(&code, 0, initial_stack);
|
||||
assert_eq!(stack_with_kernel, stack_with_opcode);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
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"];
|
||||
let ec_double = kernel.global_labels["ec_double"];
|
||||
let ec_mul = kernel.global_labels["ec_mul"];
|
||||
let identity = ("0x0", "0x0");
|
||||
let invalid = ("0x0", "0x3"); // Not on curve
|
||||
let point0 = (
|
||||
"0x1feee7ec986e198890cb83be8b8ba09ee953b3f149db6d9bfdaa5c308a33e58d",
|
||||
"0x2051cc9a9edd46231604fd88f351e95ec72a285be93e289ac59cb48561efb2c6",
|
||||
);
|
||||
let point1 = (
|
||||
"0x15b64d0a5f329fb672029298be8050f444626e6de11903caffa74b388075be1b",
|
||||
"0x2d9e07340bd5cd7b70687b98f2500ff930a89a30d7b6a3e04b1b4d345319d234",
|
||||
);
|
||||
// point2 = point0 + point1
|
||||
let point2 = (
|
||||
"0x18659c0e0a8fedcb8747cf463fc7cfa05f667d84e771d0a9521fc1a550688f0c",
|
||||
"0x283ed10b42703e187e7a808aeb45c6b457bc4cc7d704e53b3348a1e3b0bfa55b",
|
||||
);
|
||||
// point3 = 2 * point0
|
||||
let point3 = (
|
||||
"0x17da2b7b1a01c8dfdf0f5a6415833c7d755d219aa7e2c4cd0ac83d87d0ca4217",
|
||||
"0xc9ace9de14aac8114541b50c19320eb40f0eeac3621526d9e34dbcf4c3a6c0f",
|
||||
);
|
||||
let s = "0xabb2a34c0e7956cfe6cef9ddb7e810c45ea19a6ebadd79c21959af09f5ba480a";
|
||||
// point4 = s * point0
|
||||
let point4 = (
|
||||
"0xe519344959cc17021fe98878f947f5c1b1675325533a620c1684cfa6367e6c0",
|
||||
"0x7496a7575b0b6a821e19ce780ecc3e0b156e605327798693defeb9f265b7a6f",
|
||||
);
|
||||
|
||||
// Standard addition #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point1.1, point1.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point2.1, point2.0])?);
|
||||
// Standard addition #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point2.1, point2.0])?);
|
||||
|
||||
// Standard doubling #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point3.1, point3.0])?);
|
||||
// Standard doubling #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_double, initial_stack);
|
||||
assert_eq!(stack, u256ify([point3.1, point3.0])?);
|
||||
// Standard doubling #3
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x2", point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_mul, initial_stack);
|
||||
assert_eq!(stack, u256ify([point3.1, point3.0])?);
|
||||
|
||||
// Addition with identity #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, point1.1, point1.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point1.1, point1.0])?);
|
||||
// Addition with identity #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, identity.1, identity.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point1.1, point1.0])?);
|
||||
// Addition with identity #3
|
||||
let initial_stack =
|
||||
u256ify(["0xdeadbeef", identity.1, identity.0, identity.1, identity.0])?;
|
||||
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);
|
||||
assert_eq!(stack, u256ify([point4.1, point4.0])?);
|
||||
// Scalar multiplication #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x0", point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_mul, initial_stack);
|
||||
assert_eq!(stack, u256ify([identity.1, identity.0])?);
|
||||
// Scalar multiplication #3
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x1", point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_mul, initial_stack);
|
||||
assert_eq!(stack, u256ify([point0.1, point0.0])?);
|
||||
// Scalar multiplication #4
|
||||
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);
|
||||
let initial_stack = u256ify([
|
||||
"0xdeadbeef",
|
||||
s,
|
||||
&ec_mul_hex,
|
||||
identity.1,
|
||||
identity.0,
|
||||
point0.1,
|
||||
point0.0,
|
||||
])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point4.1, point4.0])?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
0
evm/src/cpu/kernel/asm/ecrecover.asm
Normal file
0
evm/src/cpu/kernel/asm/ecrecover.asm
Normal file
340
evm/src/cpu/kernel/asm/secp256k1/curve_add.asm
Normal file
340
evm/src/cpu/kernel/asm/secp256k1/curve_add.asm
Normal file
@ -0,0 +1,340 @@
|
||||
// #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:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Check if the first point is the identity.
|
||||
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
|
||||
%jumpi(ec_add_first_zero)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Check if the first point is the identity.
|
||||
DUP4
|
||||
// stack: y1, x0, y0, x1, y1, retdest
|
||||
DUP4
|
||||
// stack: x1, y1, x0, y0, x1, y1, retdest
|
||||
%ec_isidentity
|
||||
// stack: (x1,y1)==(0,0), x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_snd_zero)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Check if both points have the same x-coordinate.
|
||||
DUP3
|
||||
// stack: x1, x0, y0, x1, y1, retdest
|
||||
DUP2
|
||||
// stack: x0, x1, x0, y0, x1, y1, retdest
|
||||
EQ
|
||||
// stack: x0 == x1, x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_equal_first_coord)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Otherwise, we can use the standard formula.
|
||||
// Compute lambda = (y0 - y1)/(x0 - x1)
|
||||
DUP4
|
||||
// stack: y1, x0, y0, x1, y1, retdest
|
||||
DUP3
|
||||
// stack: y0, y1, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// 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
|
||||
// stack: x0 - x1, y0 - y1, x0, y0, x1, y1, retdest
|
||||
%moddiv_secp
|
||||
// stack: lambda, x0, y0, x1, y1, retdest
|
||||
%jump(ec_add_valid_points_with_lambda)
|
||||
|
||||
// Secp256k1 elliptic curve addition.
|
||||
// Assumption: (x0,y0) == (0,0)
|
||||
ec_add_first_zero:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Just return (x1,y1)
|
||||
%pop2
|
||||
// stack: x1, y1, retdest
|
||||
SWAP1
|
||||
// stack: y1, x1, retdest
|
||||
SWAP2
|
||||
// stack: retdest, x1, y1
|
||||
JUMP
|
||||
|
||||
// Secp256k1 elliptic curve addition.
|
||||
// Assumption: (x1,y1) == (0,0)
|
||||
ec_add_snd_zero:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Just return (x1,y1)
|
||||
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
|
||||
|
||||
// Secp256k1 elliptic curve addition.
|
||||
// Assumption: lambda = (y0 - y1)/(x0 - x1)
|
||||
ec_add_valid_points_with_lambda:
|
||||
JUMPDEST
|
||||
// stack: lambda, x0, y0, x1, y1, retdest
|
||||
|
||||
// Compute x2 = lambda^2 - x1 - x0
|
||||
DUP2
|
||||
// stack: x0, lambda, x0, y0, x1, y1, retdest
|
||||
DUP5
|
||||
// stack: x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
%secp_base
|
||||
// stack: N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
DUP4
|
||||
// stack: lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
DUP1
|
||||
// stack: lambda, lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
MULMOD
|
||||
// stack: lambda^2, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// stack: lambda^2 - x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// stack: x2, lambda, x0, y0, x1, y1, retdest
|
||||
|
||||
// Compute y2 = lambda*(x1 - x2) - y1
|
||||
%secp_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
|
||||
// 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
|
||||
// stack: y2, x2, lambda, x0, y0, x1, y1, retdest
|
||||
|
||||
// Return x2,y2
|
||||
SWAP5
|
||||
// stack: x1, x2, lambda, x0, y0, y2, y1, retdest
|
||||
POP
|
||||
// stack: x2, lambda, x0, y0, y2, y1, retdest
|
||||
SWAP5
|
||||
// stack: y1, lambda, x0, y0, y2, x2, retdest
|
||||
%pop4
|
||||
// stack: y2, x2, retdest
|
||||
SWAP2
|
||||
// stack: retdest, x2, y2
|
||||
JUMP
|
||||
|
||||
// Secp256k1 elliptic curve addition.
|
||||
// Assumption: (x0,y0) and (x1,y1) are valid points and x0 == x1
|
||||
ec_add_equal_first_coord:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest with x0 == x1
|
||||
|
||||
// Check if the points are equal
|
||||
DUP2
|
||||
// stack: y0, x0, y0, x1, y1, retdest
|
||||
DUP5
|
||||
// stack: y1, y0, x0, y0, x1, y1, retdest
|
||||
EQ
|
||||
// stack: y1 == y0, x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_equal_points)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Otherwise, one is the negation of the other so we can return (0,0).
|
||||
%pop4
|
||||
// stack: retdest
|
||||
PUSH 0
|
||||
// stack: 0, retdest
|
||||
PUSH 0
|
||||
// stack: 0, 0, retdest
|
||||
SWAP2
|
||||
// stack: retdest, 0, 0
|
||||
JUMP
|
||||
|
||||
|
||||
// Secp256k1 elliptic curve addition.
|
||||
// Assumption: x0 == x1 and y0 == y1
|
||||
// Standard doubling formula.
|
||||
ec_add_equal_points:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Compute lambda = 3/2 * x0^2 / y0
|
||||
%secp_base
|
||||
// stack: N, x0, y0, x1, y1, retdest
|
||||
%secp_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
|
||||
PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe19 // 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
|
||||
DUP3
|
||||
// stack: y0, 3/2 * x0^2, x0, y0, x1, y1, retdest
|
||||
%moddiv_secp
|
||||
// stack: lambda, x0, y0, x1, y1, retdest
|
||||
%jump(ec_add_valid_points_with_lambda)
|
||||
|
||||
// BN254 elliptic curve doubling.
|
||||
// Assumption: (x0,y0) is a valid point.
|
||||
// Standard doubling formula.
|
||||
global ec_double_secp:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, retdest
|
||||
DUP2
|
||||
// stack: y0, x0, y0, retdest
|
||||
DUP2
|
||||
// stack: x0, y0, x0, y0, retdest
|
||||
%jump(ec_add_equal_points)
|
||||
|
||||
// Push the order of the Secp256k1 scalar field.
|
||||
%macro secp_base
|
||||
PUSH 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
|
||||
%endmacro
|
||||
|
||||
// Assumption: x, y < N and 2N < 2^256.
|
||||
// Note: Doesn't hold for Secp256k1 base field.
|
||||
%macro submod_secp
|
||||
// stack: x, y
|
||||
SWAP1
|
||||
// stack: y, x
|
||||
DUP2
|
||||
// stack: x, y, x
|
||||
SUB
|
||||
// stack: x - y, x
|
||||
DUP1
|
||||
// stack: x - y, x - y, x
|
||||
SWAP2
|
||||
// stack: x, x - y, x - y
|
||||
LT
|
||||
// stack: x < x - y, x - y
|
||||
%secp_base
|
||||
// stack: N, x < x - y, x - y
|
||||
MUL
|
||||
// stack: N * (x < x - y), x - y
|
||||
ADD
|
||||
// (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_secp
|
||||
// stack: x, y
|
||||
%secp_base
|
||||
// stack: N, x, y
|
||||
DUP2
|
||||
// stack: x, N, x, y
|
||||
LT
|
||||
// stack: x < N, x, y
|
||||
%secp_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
|
||||
SWAP2
|
||||
// stack: y, x, (y < N) & (x < N), x
|
||||
SWAP1
|
||||
// stack: x, y, (y < N) & (x < N)
|
||||
%secp_base
|
||||
// stack: N, x, y, b
|
||||
%secp_base
|
||||
// stack: N, N, x, y, b
|
||||
DUP3
|
||||
// stack: x, N, N, x, y, b
|
||||
%secp_base
|
||||
// stack: N, x, N, N, x, y, b
|
||||
DUP2
|
||||
// stack: x, N, x, N, N, x, y, b
|
||||
DUP1
|
||||
// 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
|
||||
%secp_base
|
||||
// stack: N, y, (x^3 + 3) % N, x, y, b
|
||||
SWAP1
|
||||
// stack: y, N, (x^3 + 3) % N, x, y, b
|
||||
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
|
||||
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)
|
||||
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
|
||||
0
evm/src/cpu/kernel/asm/secp256k1/curve_mul.asm
Normal file
0
evm/src/cpu/kernel/asm/secp256k1/curve_mul.asm
Normal file
788
evm/src/cpu/kernel/asm/secp256k1/moddiv.asm
Normal file
788
evm/src/cpu/kernel/asm/secp256k1/moddiv.asm
Normal file
@ -0,0 +1,788 @@
|
||||
/// Division modulo 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f, the Secp256k1 base field order
|
||||
/// To replace with more efficient method using non-determinism later.
|
||||
|
||||
// Returns y * (x^-1) where the inverse is taken modulo N
|
||||
%macro moddiv_secp
|
||||
// stack: x, y
|
||||
%inverse
|
||||
// stack: x^-1, y
|
||||
%mulmodn
|
||||
%endmacro
|
||||
|
||||
%macro mulmodn_secp
|
||||
// stack: x, y
|
||||
%secp_base
|
||||
// stack: N, x, y
|
||||
SWAP2
|
||||
// stack: y, x, N
|
||||
MULMOD
|
||||
%endmacro
|
||||
|
||||
%macro squaremodn_secp
|
||||
// stack: x
|
||||
DUP1
|
||||
// stack: x, x
|
||||
%mulmodn_secp
|
||||
%endmacro
|
||||
|
||||
// Computes the inverse modulo N using x^-1 = x^(N-2) mod N and square-and-multiply modular exponentiation.
|
||||
%macro inverse
|
||||
DUP1
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
%squaremodn
|
||||
%squaremodn
|
||||
%squaremodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
%squaremodn
|
||||
DUP2
|
||||
%mulmodn
|
||||
SWAP1
|
||||
// stack: x, x^-1
|
||||
POP
|
||||
// stack: x^-1
|
||||
%endmacro
|
||||
@ -6,6 +6,8 @@ mod parser;
|
||||
|
||||
#[cfg(test)]
|
||||
mod interpreter;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use assembler::assemble;
|
||||
use parser::parse;
|
||||
|
||||
134
evm/src/cpu/kernel/tests/curve_ops.rs
Normal file
134
evm/src/cpu/kernel/tests/curve_ops.rs
Normal file
@ -0,0 +1,134 @@
|
||||
#[cfg(test)]
|
||||
mod bn {
|
||||
use anyhow::Result;
|
||||
use ethereum_types::U256;
|
||||
|
||||
use crate::cpu::kernel::aggregator::combined_kernel;
|
||||
use crate::cpu::kernel::interpreter::run;
|
||||
use crate::cpu::kernel::tests::u256ify;
|
||||
|
||||
#[test]
|
||||
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"];
|
||||
let ec_double = kernel.global_labels["ec_double"];
|
||||
let ec_mul = kernel.global_labels["ec_mul"];
|
||||
let identity = ("0x0", "0x0");
|
||||
let invalid = ("0x0", "0x3"); // Not on curve
|
||||
let point0 = (
|
||||
"0x1feee7ec986e198890cb83be8b8ba09ee953b3f149db6d9bfdaa5c308a33e58d",
|
||||
"0x2051cc9a9edd46231604fd88f351e95ec72a285be93e289ac59cb48561efb2c6",
|
||||
);
|
||||
let point1 = (
|
||||
"0x15b64d0a5f329fb672029298be8050f444626e6de11903caffa74b388075be1b",
|
||||
"0x2d9e07340bd5cd7b70687b98f2500ff930a89a30d7b6a3e04b1b4d345319d234",
|
||||
);
|
||||
// point2 = point0 + point1
|
||||
let point2 = (
|
||||
"0x18659c0e0a8fedcb8747cf463fc7cfa05f667d84e771d0a9521fc1a550688f0c",
|
||||
"0x283ed10b42703e187e7a808aeb45c6b457bc4cc7d704e53b3348a1e3b0bfa55b",
|
||||
);
|
||||
// point3 = 2 * point0
|
||||
let point3 = (
|
||||
"0x17da2b7b1a01c8dfdf0f5a6415833c7d755d219aa7e2c4cd0ac83d87d0ca4217",
|
||||
"0xc9ace9de14aac8114541b50c19320eb40f0eeac3621526d9e34dbcf4c3a6c0f",
|
||||
);
|
||||
let s = "0xabb2a34c0e7956cfe6cef9ddb7e810c45ea19a6ebadd79c21959af09f5ba480a";
|
||||
// point4 = s * point0
|
||||
let point4 = (
|
||||
"0xe519344959cc17021fe98878f947f5c1b1675325533a620c1684cfa6367e6c0",
|
||||
"0x7496a7575b0b6a821e19ce780ecc3e0b156e605327798693defeb9f265b7a6f",
|
||||
);
|
||||
|
||||
// Standard addition #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point1.1, point1.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point2.1, point2.0])?);
|
||||
// Standard addition #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point2.1, point2.0])?);
|
||||
|
||||
// Standard doubling #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point3.1, point3.0])?);
|
||||
// Standard doubling #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_double, initial_stack);
|
||||
assert_eq!(stack, u256ify([point3.1, point3.0])?);
|
||||
// Standard doubling #3
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x2", point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_mul, initial_stack);
|
||||
assert_eq!(stack, u256ify([point3.1, point3.0])?);
|
||||
|
||||
// Addition with identity #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, point1.1, point1.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point1.1, point1.0])?);
|
||||
// Addition with identity #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, identity.1, identity.0])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point1.1, point1.0])?);
|
||||
// Addition with identity #3
|
||||
let initial_stack =
|
||||
u256ify(["0xdeadbeef", identity.1, identity.0, identity.1, identity.0])?;
|
||||
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);
|
||||
assert_eq!(stack, u256ify([point4.1, point4.0])?);
|
||||
// Scalar multiplication #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x0", point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_mul, initial_stack);
|
||||
assert_eq!(stack, u256ify([identity.1, identity.0])?);
|
||||
// Scalar multiplication #3
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x1", point0.1, point0.0])?;
|
||||
let stack = run(&kernel.code, ec_mul, initial_stack);
|
||||
assert_eq!(stack, u256ify([point0.1, point0.0])?);
|
||||
// Scalar multiplication #4
|
||||
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);
|
||||
let initial_stack = u256ify([
|
||||
"0xdeadbeef",
|
||||
s,
|
||||
&ec_mul_hex,
|
||||
identity.1,
|
||||
identity.0,
|
||||
point0.1,
|
||||
point0.0,
|
||||
])?;
|
||||
let stack = run(&kernel.code, ec_add, initial_stack);
|
||||
assert_eq!(stack, u256ify([point4.1, point4.0])?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
44
evm/src/cpu/kernel/tests/exp.rs
Normal file
44
evm/src/cpu/kernel/tests/exp.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use ethereum_types::U256;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::cpu::kernel::aggregator::combined_kernel;
|
||||
use crate::cpu::kernel::interpreter::run;
|
||||
|
||||
#[test]
|
||||
fn test_exp() -> Result<()> {
|
||||
// Make sure we can parse and assemble the entire kernel.
|
||||
let kernel = combined_kernel();
|
||||
let exp = kernel.global_labels["exp"];
|
||||
let mut rng = thread_rng();
|
||||
let a = U256([0; 4].map(|_| rng.gen()));
|
||||
let b = U256([0; 4].map(|_| rng.gen()));
|
||||
|
||||
// Random input
|
||||
let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, a];
|
||||
let stack_with_kernel = run(&kernel.code, exp, initial_stack);
|
||||
let initial_stack = vec![b, a];
|
||||
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
|
||||
let stack_with_opcode = run(&code, 0, initial_stack);
|
||||
assert_eq!(stack_with_kernel, stack_with_opcode);
|
||||
|
||||
// 0 base
|
||||
let initial_stack = vec![U256::from_str("0xdeadbeef")?, b, U256::zero()];
|
||||
let stack_with_kernel = run(&kernel.code, exp, initial_stack);
|
||||
let initial_stack = vec![b, U256::zero()];
|
||||
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
|
||||
let stack_with_opcode = run(&code, 0, initial_stack);
|
||||
assert_eq!(stack_with_kernel, stack_with_opcode);
|
||||
|
||||
// 0 exponent
|
||||
let initial_stack = vec![U256::from_str("0xdeadbeef")?, U256::zero(), a];
|
||||
let stack_with_kernel = run(&kernel.code, exp, initial_stack);
|
||||
let initial_stack = vec![U256::zero(), a];
|
||||
let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP
|
||||
let stack_with_opcode = run(&code, 0, initial_stack);
|
||||
assert_eq!(stack_with_kernel, stack_with_opcode);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
14
evm/src/cpu/kernel/tests/mod.rs
Normal file
14
evm/src/cpu/kernel/tests/mod.rs
Normal file
@ -0,0 +1,14 @@
|
||||
mod curve_ops;
|
||||
mod exp;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use ethereum_types::U256;
|
||||
|
||||
pub(crate) fn u256ify<'a>(hexes: impl IntoIterator<Item = &'a str>) -> Result<Vec<U256>> {
|
||||
Ok(hexes
|
||||
.into_iter()
|
||||
.map(U256::from_str)
|
||||
.collect::<Result<Vec<_>, _>>()?)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user