Wired CPU and Keccak

This commit is contained in:
wborgeaud 2022-06-10 21:02:56 +02:00
parent 039d4efa10
commit fdd6a7cad8
3 changed files with 167 additions and 25 deletions

View File

@ -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, D> {
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::<Vec<_>>()
.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::<Vec<_>>()
.try_into()
.unwrap()
})
.collect();
let mut cpu_trace_rows = vec![];
for i in 0..cpu_rows {
let mut cpu_trace_row = [F::ZERO; CpuStark::<F, D>::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::<Vec<_>>();
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 {

View File

@ -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;

View File

@ -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;