plonky2/evm/src/cpu/cpu_stark.rs

136 lines
4.2 KiB
Rust
Raw Normal View History

2022-05-18 09:22:58 +02:00
use std::marker::PhantomData;
2022-06-23 14:36:14 -07:00
use itertools::Itertools;
use plonky2::field::extension::{Extendable, FieldExtension};
2022-05-18 09:22:58 +02:00
use plonky2::field::packed_field::PackedField;
use plonky2::field::types::Field;
2022-05-18 09:22:58 +02:00
use plonky2::hash::hash_types::RichField;
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::cpu::{columns, decode, simple_logic};
use crate::cross_table_lookup::Column;
2022-05-18 09:22:58 +02:00
use crate::permutation::PermutationPair;
use crate::stark::Stark;
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
pub fn ctl_data_keccak<F: Field>() -> Vec<Column<F>> {
let mut res: Vec<_> = columns::KECCAK_INPUT_LIMBS.map(Column::single).collect();
res.extend(columns::KECCAK_OUTPUT_LIMBS.map(Column::single));
res
}
pub fn ctl_filter_keccak<F: Field>() -> Column<F> {
Column::single(columns::IS_KECCAK)
}
pub fn ctl_data_logic<F: Field>() -> Vec<Column<F>> {
2022-06-23 14:36:14 -07:00
let mut res = Column::singles([columns::IS_AND, columns::IS_OR, columns::IS_XOR]).collect_vec();
res.extend(columns::LOGIC_INPUT0.map(Column::single));
res.extend(columns::LOGIC_INPUT1.map(Column::single));
res.extend(columns::LOGIC_OUTPUT.map(Column::single));
res
}
pub fn ctl_filter_logic<F: Field>() -> Column<F> {
Column::sum([columns::IS_AND, columns::IS_OR, columns::IS_XOR])
}
2022-06-23 14:36:14 -07:00
pub fn ctl_data_memory<F: Field>(op: usize) -> Vec<Column<F>> {
let mut cols: Vec<Column<F>> = Column::singles([
columns::CLOCK,
columns::memop_is_read(op),
columns::memop_addr_context(op),
columns::memop_addr_segment(op),
columns::memop_addr_virtual(op),
])
.collect_vec();
cols.extend(Column::singles((0..8).map(|j| columns::memop_value(op, j))));
cols
}
pub fn ctl_filter_memory<F: Field>(op: usize) -> Column<F> {
Column::single(columns::uses_memop(op))
}
2022-05-18 09:22:58 +02:00
#[derive(Copy, Clone)]
pub struct CpuStark<F, const D: usize> {
pub f: PhantomData<F>,
}
impl<F: RichField, const D: usize> CpuStark<F, D> {
pub fn generate(&self, local_values: &mut [F; columns::NUM_CPU_COLUMNS]) {
decode::generate(local_values);
simple_logic::generate(local_values);
}
}
2022-05-18 09:22:58 +02:00
impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for CpuStark<F, D> {
const COLUMNS: usize = columns::NUM_CPU_COLUMNS;
2022-05-18 09:22:58 +02:00
const PUBLIC_INPUTS: usize = 0;
fn eval_packed_generic<FE, P, const D2: usize>(
&self,
vars: StarkEvaluationVars<FE, P, { Self::COLUMNS }, { Self::PUBLIC_INPUTS }>,
yield_constr: &mut ConstraintConsumer<P>,
2022-05-18 09:22:58 +02:00
) where
FE: FieldExtension<D2, BaseField = F>,
P: PackedField<Scalar = FE>,
{
decode::eval_packed_generic(vars.local_values, yield_constr);
simple_logic::eval_packed(vars.local_values, yield_constr);
2022-05-18 09:22:58 +02:00
}
fn eval_ext_circuit(
&self,
builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder<F, D>,
vars: StarkEvaluationTargets<D, { Self::COLUMNS }, { Self::PUBLIC_INPUTS }>,
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
2022-05-18 09:22:58 +02:00
) {
decode::eval_ext_circuit(builder, vars.local_values, yield_constr);
simple_logic::eval_ext_circuit(builder, vars.local_values, yield_constr);
2022-05-18 09:22:58 +02:00
}
fn constraint_degree(&self) -> usize {
3
}
fn permutation_pairs(&self) -> Vec<PermutationPair> {
vec![]
2022-05-18 09:22:58 +02:00
}
}
2022-05-19 11:10:10 +02:00
#[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]
2022-05-20 08:34:25 +02:00
fn test_stark_degree() -> Result<()> {
2022-05-19 11:10:10 +02:00
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type S = CpuStark<F, D>;
let stark = S {
f: Default::default(),
};
2022-05-20 08:34:25 +02:00
test_stark_low_degree(stark)
2022-05-19 11:10:10 +02:00
}
#[test]
fn test_stark_circuit() -> Result<()> {
const D: usize = 2;
type C = PoseidonGoldilocksConfig;
type F = <C as GenericConfig<D>>::F;
type S = CpuStark<F, D>;
let stark = S {
f: Default::default(),
};
test_stark_circuit_constraints::<F, C, S, D>(stark)
}
}