diff --git a/evm/src/cpu/kernel/asm/bignum/modmul.asm b/evm/src/cpu/kernel/asm/bignum/modmul.asm index 351c807c..824ca290 100644 --- a/evm/src/cpu/kernel/asm/bignum/modmul.asm +++ b/evm/src/cpu/kernel/asm/bignum/modmul.asm @@ -3,8 +3,8 @@ // Stores a * b % m in output_loc, leaving a, b, and m unchanged. // a, b, and m must have the same length. -// Both output_loc and scratch_1 must have size length. -// Both scratch_2 and scratch_3 have size 2 * length and be initialized with zeroes. +// output_loc must have size length; scratch_2 must have size 2*length. +// Both scratch_2 and scratch_3 have size 2*length and be initialized with zeroes. global modmul_bignum: // stack: len, a_loc, b_loc, m_loc, out_loc, s1 (=scratch_1), s2, s3, retdest DUP1 @@ -39,28 +39,32 @@ modmul_remainder_loop: // The prover provides k := (a * b) / m, which we store in scratch_1. // stack: len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + DUP1 + // stack: len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + %mul_const(2) + // stack: 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest PUSH 0 - // stack: i=0, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + // stack: i=0, 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest modmul_quotient_loop: - // stack: i, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + // stack: i, 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest PROVER_INPUT(bignum_modmul) - // stack: PI, i, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest - DUP8 + // stack: PI, i, 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + DUP9 DUP3 ADD - // stack: s1[i], PI, i, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + // stack: s1[i], PI, i, 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest %mstore_kernel_general - // stack: i, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + // stack: i, 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest %increment DUP2 DUP2 - // stack: i+1, len, i+1, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + // stack: i+1, 2*len, i+1, 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest SUB // functions as NEQ - // stack: i+1!=len, i+1, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + // stack: i+1!=2*len, i+1, 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest %jumpi(modmul_quotient_loop) // end of modmul_quotient_loop - // stack: i, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest - POP + // stack: i, 2*len, len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest + %pop2 // stack: len, a_loc, b_loc, m_loc, out_loc, s1, s2, s3, retdest // Verification step 1: calculate x + k * m. diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 5455006a..90418cf8 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -375,7 +375,11 @@ impl<'a> Interpreter<'a> { 0xa2 => todo!(), // "LOG2", 0xa3 => todo!(), // "LOG3", 0xa4 => todo!(), // "LOG4", - 0xa5 => bail!("Executed PANIC, stack={:?}", self.stack()), // "PANIC", + 0xa5 => bail!( + "Executed PANIC, stack={:?}, memory={:?}", + self.stack(), + self.get_kernel_general_memory() + ), // "PANIC", 0xf0 => todo!(), // "CREATE", 0xf1 => todo!(), // "CALL", 0xf2 => todo!(), // "CALLCODE", diff --git a/evm/src/cpu/kernel/tests/bignum/mod.rs b/evm/src/cpu/kernel/tests/bignum/mod.rs index 00694cb5..7b0bfd4a 100644 --- a/evm/src/cpu/kernel/tests/bignum/mod.rs +++ b/evm/src/cpu/kernel/tests/bignum/mod.rs @@ -28,7 +28,7 @@ const TEST_DATA_ADD_OUTPUTS: &str = "add_outputs"; const TEST_DATA_ADDMUL_OUTPUTS: &str = "addmul_outputs"; const TEST_DATA_MUL_OUTPUTS: &str = "mul_outputs"; const TEST_DATA_MODMUL_OUTPUTS: &str = "modmul_outputs"; -const TEST_DATA_MODEXP_OUTPUTS: &str = "modexp_outputs"; +// const TEST_DATA_MODEXP_OUTPUTS: &str = "modexp_outputs"; const BIT_SIZES_TO_TEST: [usize; 15] = [ 0, 1, 2, 127, 128, 129, 255, 256, 257, 512, 1000, 1023, 1024, 1025, 31415, @@ -244,9 +244,9 @@ fn test_modmul_bignum(a: BigUint, b: BigUint, m: BigUint, expected_output: BigUi let b_start_loc = len; let m_start_loc = 2 * len; let output_start_loc = 3 * len; - let scratch_1 = 4 * len; - let scratch_2 = 5 * len; // size 2*len - let scratch_3 = 7 * len; // size 2*len + let scratch_1 = 4 * len; // size 2*len + let scratch_2 = 6 * len; // size 2*len + let scratch_3 = 8 * len; // size 2*len let (new_memory, _new_stack) = run_test( "modmul_bignum", memory, @@ -509,14 +509,13 @@ fn test_modexp_bignum_all() -> Result<()> { // Only test smaller values for exponent. let exp_bit_sizes = vec![2, 100, 127, 128, 129]; - for bit_size in &BIT_SIZES_TO_TEST[3..] { + for bit_size in &BIT_SIZES_TO_TEST[3..14] { for exp_bit_size in &exp_bit_sizes { let b = gen_bignum(*bit_size); let e = gen_bignum(*exp_bit_size); let m = gen_bignum(*bit_size); if !m.is_zero() { let output = b.clone().modpow(&e, &m); - dbg!(b.clone(), e.clone(), m.clone(), output.clone()); test_modexp_bignum(b, e, m, output)?; } @@ -525,7 +524,6 @@ fn test_modexp_bignum_all() -> Result<()> { let m = max_bignum(*bit_size); if !m.is_zero() { let output = b.clone().modpow(&e, &m); - dbg!(b.clone(), e.clone(), m.clone(), output.clone()); test_modexp_bignum(b, e, m, output)?; } } diff --git a/evm/src/generation/prover_input.rs b/evm/src/generation/prover_input.rs index 3300d9bd..bf8288cf 100644 --- a/evm/src/generation/prover_input.rs +++ b/evm/src/generation/prover_input.rs @@ -154,15 +154,12 @@ impl GenerationState { let (remainder, quotient) = self.bignum_modmul(len, a_start_loc, b_start_loc, m_start_loc); - dbg!(remainder.clone(), quotient.clone()); - self.bignum_modmul_result_limbs = remainder .iter() .cloned() .pad_using(len, |_| 0.into()) - .chain(quotient.iter().cloned().pad_using(len, |_| 0.into())) + .chain(quotient.iter().cloned().pad_using(2 * len, |_| 0.into())) .collect(); - dbg!(self.bignum_modmul_result_limbs.clone()); self.bignum_modmul_result_limbs.reverse(); } @@ -187,11 +184,10 @@ impl GenerationState { let b_biguint = mem_vec_to_biguint(b); let m_biguint = mem_vec_to_biguint(m); - dbg!(a_biguint.clone(), b_biguint.clone(), m_biguint.clone()); - let prod = a_biguint * b_biguint; let quo = prod.clone() / m_biguint.clone(); let rem = prod - quo.clone() * m_biguint; + (biguint_to_mem_vec(rem), biguint_to_mem_vec(quo)) } } diff --git a/evm/src/witness/transition.rs b/evm/src/witness/transition.rs index be6aba94..65b7ddcf 100644 --- a/evm/src/witness/transition.rs +++ b/evm/src/witness/transition.rs @@ -309,10 +309,11 @@ pub(crate) fn transition(state: &mut GenerationState) -> anyhow::Re if state.registers.is_kernel { let offset_name = KERNEL.offset_name(state.registers.program_counter); bail!( - "{:?} in kernel at pc={}, stack={:?}", + "{:?} in kernel at pc={}, stack={:?}, memory={:?}", e, offset_name, - state.stack() + state.stack(), + state.memory.contexts[0].segments[Segment::KernelGeneral as usize].content, ); } state.rollback(checkpoint);