use std::borrow::{Borrow, BorrowMut}; use std::marker::PhantomData; use itertools::Itertools; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::packed::PackedField; use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::cpu::columns::{CpuColumnsView, COL_MAP, NUM_CPU_COLUMNS}; use crate::cpu::{decode, simple_logic}; use crate::cross_table_lookup::Column; use crate::memory::NUM_CHANNELS; use crate::stark::Stark; use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; pub fn ctl_data_keccak() -> Vec> { let mut res: Vec<_> = Column::singles(COL_MAP.keccak_input_limbs).collect(); res.extend(Column::singles(COL_MAP.keccak_output_limbs)); res } pub fn ctl_filter_keccak() -> Column { Column::single(COL_MAP.is_keccak) } pub fn ctl_data_logic() -> Vec> { let mut res = Column::singles([COL_MAP.is_and, COL_MAP.is_or, COL_MAP.is_xor]).collect_vec(); res.extend(Column::singles(COL_MAP.logic_input0)); res.extend(Column::singles(COL_MAP.logic_input1)); res.extend(Column::singles(COL_MAP.logic_output)); res } pub fn ctl_filter_logic() -> Column { Column::sum([COL_MAP.is_and, COL_MAP.is_or, COL_MAP.is_xor]) } pub fn ctl_data_memory(channel: usize) -> Vec> { debug_assert!(channel < NUM_CHANNELS); let mut cols: Vec> = Column::singles([ COL_MAP.clock, COL_MAP.mem_is_read[channel], COL_MAP.mem_addr_context[channel], COL_MAP.mem_addr_segment[channel], COL_MAP.mem_addr_virtual[channel], ]) .collect_vec(); cols.extend(Column::singles(COL_MAP.mem_value[channel])); cols } pub fn ctl_filter_memory(channel: usize) -> Column { Column::single(COL_MAP.mem_channel_used[channel]) } #[derive(Copy, Clone)] pub struct CpuStark { pub f: PhantomData, } impl CpuStark { pub fn generate(&self, local_values: &mut [F; NUM_CPU_COLUMNS]) { let local_values: &mut CpuColumnsView<_> = local_values.borrow_mut(); decode::generate(local_values); simple_logic::generate(local_values); } } impl, const D: usize> Stark for CpuStark { const COLUMNS: usize = NUM_CPU_COLUMNS; const PUBLIC_INPUTS: usize = 0; fn eval_packed_generic( &self, vars: StarkEvaluationVars, yield_constr: &mut ConstraintConsumer

, ) where FE: FieldExtension, P: PackedField, { let local_values = vars.local_values.borrow(); decode::eval_packed_generic(local_values, yield_constr); simple_logic::eval_packed(local_values, yield_constr); } fn eval_ext_circuit( &self, builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder, vars: StarkEvaluationTargets, yield_constr: &mut RecursiveConstraintConsumer, ) { let local_values = vars.local_values.borrow(); decode::eval_ext_circuit(builder, local_values, yield_constr); simple_logic::eval_ext_circuit(builder, local_values, yield_constr); } fn constraint_degree(&self) -> usize { 3 } } #[cfg(test)] mod tests { use anyhow::Result; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use crate::cpu::cpu_stark::CpuStark; use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; #[test] fn test_stark_degree() -> Result<()> { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; type S = CpuStark; let stark = S { f: Default::default(), }; test_stark_low_degree(stark) } #[test] fn test_stark_circuit() -> Result<()> { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; type S = CpuStark; let stark = S { f: Default::default(), }; test_stark_circuit_constraints::(stark) } }