use std::iter; use plonky2::field::extension::Extendable; use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use crate::config::StarkConfig; use crate::cpu::cpu_stark; use crate::cpu::cpu_stark::CpuStark; use crate::cpu::membus::NUM_GP_CHANNELS; use crate::cross_table_lookup::{Column, CrossTableLookup, TableWithColumns}; use crate::keccak::keccak_stark; use crate::keccak::keccak_stark::KeccakStark; use crate::keccak_sponge::columns::KECCAK_RATE_BYTES; use crate::keccak_sponge::keccak_sponge_stark; use crate::keccak_sponge::keccak_sponge_stark::{num_logic_ctls, KeccakSpongeStark}; use crate::logic; use crate::logic::LogicStark; use crate::memory::memory_stark; use crate::memory::memory_stark::MemoryStark; use crate::stark::Stark; #[derive(Clone)] pub struct AllStark, const D: usize> { pub cpu_stark: CpuStark, pub keccak_stark: KeccakStark, pub keccak_sponge_stark: KeccakSpongeStark, pub logic_stark: LogicStark, pub memory_stark: MemoryStark, pub cross_table_lookups: Vec>, } impl, const D: usize> Default for AllStark { fn default() -> Self { Self { cpu_stark: CpuStark::default(), keccak_stark: KeccakStark::default(), keccak_sponge_stark: KeccakSpongeStark::default(), logic_stark: LogicStark::default(), memory_stark: MemoryStark::default(), cross_table_lookups: all_cross_table_lookups(), } } } impl, const D: usize> AllStark { pub(crate) fn nums_permutation_zs(&self, config: &StarkConfig) -> [usize; NUM_TABLES] { [ self.cpu_stark.num_permutation_batches(config), self.keccak_stark.num_permutation_batches(config), self.keccak_sponge_stark.num_permutation_batches(config), self.logic_stark.num_permutation_batches(config), self.memory_stark.num_permutation_batches(config), ] } pub(crate) fn permutation_batch_sizes(&self) -> [usize; NUM_TABLES] { [ self.cpu_stark.permutation_batch_size(), self.keccak_stark.permutation_batch_size(), self.keccak_sponge_stark.permutation_batch_size(), self.logic_stark.permutation_batch_size(), self.memory_stark.permutation_batch_size(), ] } } #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum Table { Cpu = 0, Keccak = 1, KeccakSponge = 2, Logic = 3, Memory = 4, } pub(crate) const NUM_TABLES: usize = Table::Memory as usize + 1; pub(crate) fn all_cross_table_lookups() -> Vec> { let mut ctls = vec![ctl_keccak(), ctl_logic(), ctl_memory(), ctl_keccak_sponge()]; // TODO: Some CTLs temporarily disabled while we get them working. disable_ctl(&mut ctls[0]); disable_ctl(&mut ctls[1]); disable_ctl(&mut ctls[2]); disable_ctl(&mut ctls[3]); ctls } fn disable_ctl(ctl: &mut CrossTableLookup) { for table in &mut ctl.looking_tables { table.filter_column = Some(Column::zero()); } ctl.looked_table.filter_column = Some(Column::zero()); } fn ctl_keccak() -> CrossTableLookup { let keccak_sponge_looking = TableWithColumns::new( Table::KeccakSponge, keccak_sponge_stark::ctl_looking_keccak(), Some(keccak_sponge_stark::ctl_looking_keccak_filter()), ); let keccak_looked = TableWithColumns::new( Table::Keccak, keccak_stark::ctl_data(), Some(keccak_stark::ctl_filter()), ); CrossTableLookup::new(vec![keccak_sponge_looking], keccak_looked, None) } fn ctl_keccak_sponge() -> CrossTableLookup { let cpu_looking = TableWithColumns::new( Table::Cpu, cpu_stark::ctl_data_keccak_sponge(), Some(cpu_stark::ctl_filter_keccak_sponge()), ); let keccak_sponge_looked = TableWithColumns::new( Table::KeccakSponge, keccak_sponge_stark::ctl_looked_data(), Some(keccak_sponge_stark::ctl_looked_filter()), ); CrossTableLookup::new(vec![cpu_looking], keccak_sponge_looked, None) } fn ctl_logic() -> CrossTableLookup { let cpu_looking = TableWithColumns::new( Table::Cpu, cpu_stark::ctl_data_logic(), Some(cpu_stark::ctl_filter_logic()), ); let mut all_lookers = vec![cpu_looking]; for i in 0..num_logic_ctls() { let keccak_sponge_looking = TableWithColumns::new( Table::KeccakSponge, keccak_sponge_stark::ctl_looking_logic(i), // TODO: Double check, but I think it's the same filter for memory and logic? Some(keccak_sponge_stark::ctl_looking_memory_filter(i)), ); all_lookers.push(keccak_sponge_looking); } let logic_looked = TableWithColumns::new(Table::Logic, logic::ctl_data(), Some(logic::ctl_filter())); CrossTableLookup::new(all_lookers, logic_looked, None) } fn ctl_memory() -> CrossTableLookup { let cpu_memory_code_read = TableWithColumns::new( Table::Cpu, cpu_stark::ctl_data_code_memory(), Some(cpu_stark::ctl_filter_code_memory()), ); let cpu_memory_gp_ops = (0..NUM_GP_CHANNELS).map(|channel| { TableWithColumns::new( Table::Cpu, cpu_stark::ctl_data_gp_memory(channel), Some(cpu_stark::ctl_filter_gp_memory(channel)), ) }); let keccak_sponge_reads = (0..KECCAK_RATE_BYTES).map(|i| { TableWithColumns::new( Table::KeccakSponge, keccak_sponge_stark::ctl_looking_memory(i), Some(keccak_sponge_stark::ctl_looking_memory_filter(i)), ) }); let all_lookers = iter::once(cpu_memory_code_read) .chain(cpu_memory_gp_ops) .chain(keccak_sponge_reads) .collect(); let memory_looked = TableWithColumns::new( Table::Memory, memory_stark::ctl_data(), Some(memory_stark::ctl_filter()), ); CrossTableLookup::new(all_lookers, memory_looked, None) }