diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index b82bacaf..bb861ade 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -15,7 +15,7 @@ pub(crate) fn combined_kernel() -> Kernel { "global jumped_to_1: PANIC", include_str!("asm/bignum/add.asm"), include_str!("asm/bignum/addmul.asm"), - include_str!("asm/bignum/ge.asm"), + include_str!("asm/bignum/cmp.asm"), include_str!("asm/bignum/iszero.asm"), include_str!("asm/bignum/mul.asm"), include_str!("asm/bignum/shr.asm"), diff --git a/evm/src/cpu/kernel/asm/bignum/ge.asm b/evm/src/cpu/kernel/asm/bignum/cmp.asm similarity index 91% rename from evm/src/cpu/kernel/asm/bignum/ge.asm rename to evm/src/cpu/kernel/asm/bignum/cmp.asm index e7f5aca2..ff8fb3e6 100644 --- a/evm/src/cpu/kernel/asm/bignum/ge.asm +++ b/evm/src/cpu/kernel/asm/bignum/cmp.asm @@ -2,8 +2,8 @@ // All integers must be under a given length bound, and are padded with leading zeroes. // Compares two bignums of the same given length. Assumes that len > 0. -// Returns 1 if a > b, 3 if a == b, and 0 if a < b. -global ge_bignum: +// Returns 1 if a > b, 0 if a == b, and -1 (that is, 2^256 - 1) if a < b. +global cmp_bignum: // stack: len, a_start_loc, b_start_loc, retdest SWAP1 // stack: a_start_loc, len, b_start_loc, retdest @@ -59,8 +59,8 @@ equal: // stack: i, a_i_loc, b_i_loc, retdest %pop3 // stack: retdest - PUSH 3 - // stack: 3, retdest + PUSH 0 + // stack: 0, retdest SWAP1 JUMP greater: @@ -75,7 +75,7 @@ less: // stack: i, a_i_loc, b_i_loc, retdest %pop3 // stack: retdest - PUSH 0 - // stack: 0, retdest + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + // stack: -1, retdest SWAP1 JUMP diff --git a/evm/src/cpu/kernel/tests/bignum.rs b/evm/src/cpu/kernel/tests/bignum.rs index 141761ba..9dbcf6b7 100644 --- a/evm/src/cpu/kernel/tests/bignum.rs +++ b/evm/src/cpu/kernel/tests/bignum.rs @@ -179,14 +179,14 @@ where Ok(()) } -fn test_ge_bignum(prepare_two_bignums_fn: &F) -> Result<()> +fn test_cmp_bignum(prepare_two_bignums_fn: &F) -> Result<()> where F: Fn(usize) -> (BigUint, BigUint, U256, Vec), { let (_a, _b, length, memory) = prepare_two_bignums_fn(1000); let retdest = 0xDEADBEEFu32.into(); - let ge_bignum = KERNEL.global_labels["ge_bignum"]; + let cmp_bignum = KERNEL.global_labels["cmp_bignum"]; let a_start_loc = 0.into(); let b_start_loc = length; @@ -194,7 +194,7 @@ where // Test with a > b. let mut initial_stack: Vec = vec![length, a_start_loc, b_start_loc, retdest]; initial_stack.reverse(); - let mut interpreter = Interpreter::new_with_kernel(ge_bignum, initial_stack); + let mut interpreter = Interpreter::new_with_kernel(cmp_bignum, initial_stack); interpreter.set_kernel_general_memory(memory.clone()); interpreter.run()?; let result = interpreter.stack()[0]; @@ -203,11 +203,21 @@ where // Swap a and b, to test the less-than case. let mut initial_stack: Vec = vec![length, b_start_loc, a_start_loc, retdest]; initial_stack.reverse(); - let mut interpreter = Interpreter::new_with_kernel(ge_bignum, initial_stack); + let mut interpreter = Interpreter::new_with_kernel(cmp_bignum, initial_stack); + interpreter.set_kernel_general_memory(memory.clone()); + interpreter.run()?; + let result = interpreter.stack()[0]; + let minus_one = ((U256::one() << 255) - 1) * 2 + 1; + assert_eq!(result, minus_one); + + // Test equal case. + let mut initial_stack: Vec = vec![length, a_start_loc, a_start_loc, retdest]; + initial_stack.reverse(); + let mut interpreter = Interpreter::new_with_kernel(cmp_bignum, initial_stack); interpreter.set_kernel_general_memory(memory); interpreter.run()?; let result = interpreter.stack()[0]; - assert_eq!(result, 0.into()); + assert_eq!(result, U256::zero()); Ok(()) } @@ -350,11 +360,11 @@ fn test_iszero_bignum_all() -> Result<()> { } #[test] -fn test_ge_bignum_all() -> Result<()> { - test_ge_bignum(&prepare_two_bignums_random)?; - test_ge_bignum(&prepare_two_bignums_max)?; - test_ge_bignum(&prepare_two_bignums_min)?; - test_ge_bignum(&prepare_two_bignums_diff)?; +fn test_cmp_bignum_all() -> Result<()> { + test_cmp_bignum(&prepare_two_bignums_random)?; + test_cmp_bignum(&prepare_two_bignums_max)?; + test_cmp_bignum(&prepare_two_bignums_min)?; + test_cmp_bignum(&prepare_two_bignums_diff)?; Ok(()) }