diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 7387621b..83893cef 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -56,14 +56,12 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::util::timing::TimingTree; - use rand::{Rng, SeedableRng}; - use rand_chacha::ChaCha8Rng; + use rand::{thread_rng, Rng}; use crate::all_stark::{AllStark, Table}; use crate::config::StarkConfig; - use crate::cpu; use crate::cpu::cpu_stark::CpuStark; - use crate::cross_table_lookup::CrossTableLookup; + use crate::cross_table_lookup::{CrossTableLookup, TableWithColumns}; use crate::keccak::keccak_stark::{KeccakStark, NUM_INPUTS, NUM_ROUNDS}; use crate::proof::AllProof; use crate::prover::prove; @@ -73,6 +71,7 @@ mod tests { use crate::stark::Stark; use crate::util::trace_rows_to_poly_values; use crate::verifier::verify_proof; + use crate::{cpu, keccak}; const D: usize = 2; type C = PoseidonGoldilocksConfig; @@ -87,42 +86,74 @@ mod tests { let keccak_stark = KeccakStark:: { f: Default::default(), }; - let keccak_rows = (2 * NUM_ROUNDS + 1).next_power_of_two(); - let keccak_looked_col = 3; - let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); + let mut rng = thread_rng(); let num_inputs = 2; let keccak_inputs = (0..num_inputs) .map(|_| [0u64; NUM_INPUTS].map(|_| rng.gen())) .collect_vec(); let keccak_trace = keccak_stark.generate_trace(keccak_inputs); - let column_to_copy: Vec<_> = keccak_trace[keccak_looked_col].values[..].into(); - - let default = vec![F::ONE; 1]; + let keccak_input_limbs: Vec<[F; 2 * NUM_INPUTS]> = (0..num_inputs) + .map(|i| { + (0..2 * NUM_INPUTS) + .map(|j| { + keccak_trace[keccak::registers::reg_input_limb(j)].values + [(i + 1) * NUM_ROUNDS - 1] + }) + .collect::>() + .try_into() + .unwrap() + }) + .collect(); + let keccak_output_limbs: Vec<[F; 2 * NUM_INPUTS]> = (0..num_inputs) + .map(|i| { + (0..2 * NUM_INPUTS) + .map(|j| { + keccak_trace[keccak::registers::reg_output_limb(j)].values + [(i + 1) * NUM_ROUNDS - 1] + }) + .collect::>() + .try_into() + .unwrap() + }) + .collect(); let mut cpu_trace_rows = vec![]; for i in 0..cpu_rows { let mut cpu_trace_row = [F::ZERO; CpuStark::::COLUMNS]; cpu_trace_row[cpu::columns::IS_CPU_CYCLE] = F::ONE; - if i < keccak_rows { - cpu_trace_row[cpu::columns::OPCODE] = column_to_copy[i]; - } else { - cpu_trace_row[cpu::columns::OPCODE] = default[0]; - } + cpu_trace_row[cpu::columns::OPCODE] = F::from_canonical_usize(i); cpu_stark.generate(&mut cpu_trace_row); cpu_trace_rows.push(cpu_trace_row); } + for i in 0..num_inputs { + cpu_trace_rows[i][cpu::columns::IS_KECCAK] = F::ONE; + for j in 0..2 * NUM_INPUTS { + cpu_trace_rows[i][cpu::columns::KECCAK_INPUT_LIMBS[j]] = keccak_input_limbs[i][j]; + cpu_trace_rows[i][cpu::columns::KECCAK_OUTPUT_LIMBS[j]] = keccak_output_limbs[i][j]; + } + } let cpu_trace = trace_rows_to_poly_values(cpu_trace_rows); - // TODO: temporary until cross-table-lookup filters are implemented + let mut cpu_keccak_input_output = cpu::columns::KECCAK_INPUT_LIMBS.to_vec(); + cpu_keccak_input_output.extend(cpu::columns::KECCAK_OUTPUT_LIMBS); + let mut keccak_keccak_input_output = (0..2 * NUM_INPUTS) + .map(keccak::registers::reg_input_limb) + .collect::>(); + keccak_keccak_input_output + .extend((0..2 * NUM_INPUTS).map(keccak::registers::reg_output_limb)); let cross_table_lookups = vec![CrossTableLookup::new( vec![TableWithColumns::new( Table::Cpu, - vec![cpu::columns::OPCODE], - vec![], + cpu_keccak_input_output, + vec![cpu::columns::IS_KECCAK], )], - TableWithColumns::new(Table::Keccak, vec![keccak_looked_col], vec![]), - Some(default), + TableWithColumns::new( + Table::Keccak, + keccak_keccak_input_output, + vec![keccak::registers::reg_step(NUM_ROUNDS - 1)], + ), + None, )]; let all_stark = AllStark { diff --git a/evm/src/cpu/columns.rs b/evm/src/cpu/columns.rs index d2b2e4bf..83623797 100644 --- a/evm/src/cpu/columns.rs +++ b/evm/src/cpu/columns.rs @@ -132,4 +132,116 @@ pub const OPCODE_BITS: [usize; 8] = [ END_INSTRUCTION_FLAGS + 7, ]; -pub const NUM_CPU_COLUMNS: usize = OPCODE_BITS[OPCODE_BITS.len() - 1] + 1; +/// Filter. 1 iff a Keccak permutation is computed on this row. +pub const IS_KECCAK: usize = OPCODE_BITS[OPCODE_BITS.len() - 1] + 1; + +pub const START_KECCAK_INPUT: usize = IS_KECCAK + 1; +#[allow(dead_code)] // TODO: Remove when used +pub const KECCAK_INPUT_LIMBS: [usize; 50] = [ + START_KECCAK_INPUT, + START_KECCAK_INPUT + 1, + START_KECCAK_INPUT + 2, + START_KECCAK_INPUT + 3, + START_KECCAK_INPUT + 4, + START_KECCAK_INPUT + 5, + START_KECCAK_INPUT + 6, + START_KECCAK_INPUT + 7, + START_KECCAK_INPUT + 8, + START_KECCAK_INPUT + 9, + START_KECCAK_INPUT + 10, + START_KECCAK_INPUT + 11, + START_KECCAK_INPUT + 12, + START_KECCAK_INPUT + 13, + START_KECCAK_INPUT + 14, + START_KECCAK_INPUT + 15, + START_KECCAK_INPUT + 16, + START_KECCAK_INPUT + 17, + START_KECCAK_INPUT + 18, + START_KECCAK_INPUT + 19, + START_KECCAK_INPUT + 20, + START_KECCAK_INPUT + 21, + START_KECCAK_INPUT + 22, + START_KECCAK_INPUT + 23, + START_KECCAK_INPUT + 24, + START_KECCAK_INPUT + 25, + START_KECCAK_INPUT + 26, + START_KECCAK_INPUT + 27, + START_KECCAK_INPUT + 28, + START_KECCAK_INPUT + 29, + START_KECCAK_INPUT + 30, + START_KECCAK_INPUT + 31, + START_KECCAK_INPUT + 32, + START_KECCAK_INPUT + 33, + START_KECCAK_INPUT + 34, + START_KECCAK_INPUT + 35, + START_KECCAK_INPUT + 36, + START_KECCAK_INPUT + 37, + START_KECCAK_INPUT + 38, + START_KECCAK_INPUT + 39, + START_KECCAK_INPUT + 40, + START_KECCAK_INPUT + 41, + START_KECCAK_INPUT + 42, + START_KECCAK_INPUT + 43, + START_KECCAK_INPUT + 44, + START_KECCAK_INPUT + 45, + START_KECCAK_INPUT + 46, + START_KECCAK_INPUT + 47, + START_KECCAK_INPUT + 48, + START_KECCAK_INPUT + 49, +]; + +pub const START_KECCAK_OUTPUT: usize = START_KECCAK_INPUT + 50; +pub const KECCAK_OUTPUT_LIMBS: [usize; 50] = [ + START_KECCAK_OUTPUT, + START_KECCAK_OUTPUT + 1, + START_KECCAK_OUTPUT + 2, + START_KECCAK_OUTPUT + 3, + START_KECCAK_OUTPUT + 4, + START_KECCAK_OUTPUT + 5, + START_KECCAK_OUTPUT + 6, + START_KECCAK_OUTPUT + 7, + START_KECCAK_OUTPUT + 8, + START_KECCAK_OUTPUT + 9, + START_KECCAK_OUTPUT + 10, + START_KECCAK_OUTPUT + 11, + START_KECCAK_OUTPUT + 12, + START_KECCAK_OUTPUT + 13, + START_KECCAK_OUTPUT + 14, + START_KECCAK_OUTPUT + 15, + START_KECCAK_OUTPUT + 16, + START_KECCAK_OUTPUT + 17, + START_KECCAK_OUTPUT + 18, + START_KECCAK_OUTPUT + 19, + START_KECCAK_OUTPUT + 20, + START_KECCAK_OUTPUT + 21, + START_KECCAK_OUTPUT + 22, + START_KECCAK_OUTPUT + 23, + START_KECCAK_OUTPUT + 24, + START_KECCAK_OUTPUT + 25, + START_KECCAK_OUTPUT + 26, + START_KECCAK_OUTPUT + 27, + START_KECCAK_OUTPUT + 28, + START_KECCAK_OUTPUT + 29, + START_KECCAK_OUTPUT + 30, + START_KECCAK_OUTPUT + 31, + START_KECCAK_OUTPUT + 32, + START_KECCAK_OUTPUT + 33, + START_KECCAK_OUTPUT + 34, + START_KECCAK_OUTPUT + 35, + START_KECCAK_OUTPUT + 36, + START_KECCAK_OUTPUT + 37, + START_KECCAK_OUTPUT + 38, + START_KECCAK_OUTPUT + 39, + START_KECCAK_OUTPUT + 40, + START_KECCAK_OUTPUT + 41, + START_KECCAK_OUTPUT + 42, + START_KECCAK_OUTPUT + 43, + START_KECCAK_OUTPUT + 44, + START_KECCAK_OUTPUT + 45, + START_KECCAK_OUTPUT + 46, + START_KECCAK_OUTPUT + 47, + START_KECCAK_OUTPUT + 48, + START_KECCAK_OUTPUT + 49, +]; + +pub const NUM_CPU_COLUMNS: usize = KECCAK_OUTPUT_LIMBS[KECCAK_OUTPUT_LIMBS.len() - 1] + 1; diff --git a/evm/src/keccak/registers.rs b/evm/src/keccak/registers.rs index 2dc019e3..04704d9c 100644 --- a/evm/src/keccak/registers.rs +++ b/evm/src/keccak/registers.rs @@ -1,7 +1,7 @@ use crate::keccak::keccak_stark::{NUM_INPUTS, NUM_ROUNDS}; /// A register which is set to 1 if we are in the `i`th round, otherwise 0. -pub(crate) const fn reg_step(i: usize) -> usize { +pub const fn reg_step(i: usize) -> usize { debug_assert!(i < NUM_ROUNDS); i } @@ -9,7 +9,7 @@ pub(crate) const fn reg_step(i: usize) -> usize { /// Registers to hold permutation inputs. /// `reg_input_limb(2*i) -> input[i] as u32` /// `reg_input_limb(2*i+1) -> input[i] >> 32` -pub(crate) const fn reg_input_limb(i: usize) -> usize { +pub const fn reg_input_limb(i: usize) -> usize { debug_assert!(i < 2 * NUM_INPUTS); NUM_ROUNDS + i } @@ -17,8 +17,7 @@ pub(crate) const fn reg_input_limb(i: usize) -> usize { /// Registers to hold permutation outputs. /// `reg_output_limb(2*i) -> output[i] as u32` /// `reg_output_limb(2*i+1) -> output[i] >> 32` -#[allow(dead_code)] // TODO: Remove once it is used. -pub(crate) const fn reg_output_limb(i: usize) -> usize { +pub const fn reg_output_limb(i: usize) -> usize { debug_assert!(i < 2 * NUM_INPUTS); let ii = i / 2; let x = ii / 5;