diff --git a/evm/src/cpu/kernel/asm/bignum/add.asm b/evm/src/cpu/kernel/asm/bignum/add.asm index 038c7675..64293f11 100644 --- a/evm/src/cpu/kernel/asm/bignum/add.asm +++ b/evm/src/cpu/kernel/asm/bignum/add.asm @@ -4,6 +4,11 @@ // Adds two bignums of the same given length. Assumes that len > 0. // Replaces a with a + b, leaving b unchanged, and returns the final carry. global add_bignum: + // stack: len, a_start_loc, b_start_loc, retdest + DUP1 + // stack: len, len, a_start_loc, b_start_loc, retdest + ISZERO + %jumpi(len_zero) // stack: len, a_start_loc, b_start_loc, retdest PUSH 0 // stack: carry=0, i=len, a_cur_loc=a_start_loc, b_cur_loc=b_start_loc, retdest @@ -55,3 +60,11 @@ add_end: SWAP1 // stack: retdest, carry_new JUMP +len_zero: + // stack: len, a_start_loc, b_start_loc, retdest + %pop3 + // stack: retdest + PUSH 0 + // stack: carry=0, retdest + SWAP1 + JUMP \ No newline at end of file diff --git a/evm/src/cpu/kernel/asm/bignum/addmul.asm b/evm/src/cpu/kernel/asm/bignum/addmul.asm index e1bd3bf2..9e4ce2ba 100644 --- a/evm/src/cpu/kernel/asm/bignum/addmul.asm +++ b/evm/src/cpu/kernel/asm/bignum/addmul.asm @@ -4,6 +4,10 @@ // Sets a[0:len] += b[0:len] * val, and returns the carry. global addmul_bignum: // stack: len, a_start_loc, b_start_loc, val, retdest + DUP1 + // stack: len, len, a_start_loc, b_start_loc, val, retdest + ISZERO + %jumpi(len_zero) PUSH 0 // stack: carry=0, i=len, a_cur_loc=a_start_loc, b_cur_loc=b_start_loc, val, retdest addmul_loop: @@ -97,3 +101,11 @@ addmul_end: SWAP1 // stack: retdest, carry_new JUMP +len_zero: + // stack: len, a_start_loc, b_start_loc, val, retdest + %pop4 + // stack: retdest + PUSH 0 + // stack: carry=0, retdest + SWAP1 + JUMP diff --git a/evm/src/cpu/kernel/asm/bignum/mul.asm b/evm/src/cpu/kernel/asm/bignum/mul.asm index d62ce907..cbf6a645 100644 --- a/evm/src/cpu/kernel/asm/bignum/mul.asm +++ b/evm/src/cpu/kernel/asm/bignum/mul.asm @@ -7,6 +7,10 @@ global mul_bignum: // stack: len, a_start_loc, b_start_loc, output_loc, retdest DUP1 + // stack: len, len, a_start_loc, b_start_loc, output_loc, retdest + ISZERO + %jumpi(len_zero) + DUP1 // stack: n=len, len, a_start_loc, bi=b_start_loc, output_cur=output_loc, retdest mul_loop: // stack: n, len, a_start_loc, bi, output_cur, retdest @@ -51,3 +55,8 @@ mul_end: %pop5 // stack: retdest JUMP +len_zero: + // stack: len, a_start_loc, b_start_loc, output_loc, retdest + %pop4 + // stack: retdest + JUMP diff --git a/evm/src/cpu/kernel/asm/bignum/shr.asm b/evm/src/cpu/kernel/asm/bignum/shr.asm index 399b372e..42f5cd3b 100644 --- a/evm/src/cpu/kernel/asm/bignum/shr.asm +++ b/evm/src/cpu/kernel/asm/bignum/shr.asm @@ -8,7 +8,7 @@ global shr_bignum: DUP1 // stack: len, len, start_loc, retdest ISZERO - %jumpi(shr_end_len_zero) + %jumpi(len_zero) // stack: len, start_loc, retdest DUP2 // stack: start_loc, len, start_loc, retdest @@ -60,7 +60,7 @@ shr_end: %pop3 // stack: retdest JUMP -shr_end_len_zero: +len_zero: // stack: len, start_loc, retdest %pop2 // stack: retdest diff --git a/evm/src/cpu/kernel/tests/bignum.rs b/evm/src/cpu/kernel/tests/bignum.rs index db4faebd..141761ba 100644 --- a/evm/src/cpu/kernel/tests/bignum.rs +++ b/evm/src/cpu/kernel/tests/bignum.rs @@ -104,6 +104,15 @@ fn prepare_two_bignums_diff(bit_size: usize) -> (BigUint, BigUint, U256, Vec (BigUint, BigUint, U256, Vec) { + let a = BigUint::zero(); + let b = BigUint::zero(); + let length: U256 = bignum_len(&a).into(); + let memory = pad_bignums(&[a.clone(), b.clone()], length.try_into().unwrap()); + + (a, b, length, memory) +} + fn test_shr_bignum(prepare_bignum_fn: &F) -> Result<()> where F: Fn(usize) -> (BigUint, U256, Vec), @@ -356,6 +365,7 @@ fn test_add_bignum_all() -> Result<()> { test_add_bignum(&prepare_two_bignums_max)?; test_add_bignum(&prepare_two_bignums_min)?; test_add_bignum(&prepare_two_bignums_diff)?; + test_add_bignum(&prepare_two_bignums_zero)?; Ok(()) } @@ -366,6 +376,7 @@ fn test_addmul_bignum_all() -> Result<()> { test_addmul_bignum(&prepare_two_bignums_max)?; test_addmul_bignum(&prepare_two_bignums_min)?; test_addmul_bignum(&prepare_two_bignums_diff)?; + test_addmul_bignum(&prepare_two_bignums_zero)?; Ok(()) } @@ -376,6 +387,7 @@ fn test_mul_bignum_all() -> Result<()> { test_mul_bignum(&prepare_two_bignums_max)?; test_mul_bignum(&prepare_two_bignums_min)?; test_mul_bignum(&prepare_two_bignums_diff)?; + test_mul_bignum(&prepare_two_bignums_zero)?; Ok(()) }