diff --git a/starky2/src/cross_table_lookups.rs b/starky2/src/cross_table_lookups.rs index b35733a2..5ad5680e 100644 --- a/starky2/src/cross_table_lookups.rs +++ b/starky2/src/cross_table_lookups.rs @@ -1,4 +1,4 @@ -use plonky2::field::extension_field::FieldExtension; +use plonky2::field::extension_field::{Extendable, FieldExtension}; use plonky2::field::field_types::Field; use plonky2::field::packed_field::PackedField; use plonky2::field::polynomial::PolynomialValues; @@ -6,14 +6,19 @@ use plonky2::hash::hash_types::RichField; use plonky2::iop::challenger::Challenger; use plonky2::plonk::config::GenericConfig; use plonky2::plonk::plonk_common::reduce_with_powers; +use plonky2::util::reducing::ReducingFactor; use crate::config::StarkConfig; +use crate::constraint_consumer::ConstraintConsumer; +use crate::permutation::PermutationChallenge; use crate::prover::CrossTableLookup; +use crate::stark::Stark; +use crate::vars::StarkEvaluationVars; /// Lookup data for one table. #[derive(Clone)] pub struct LookupData { - zs_beta_gammas: Vec<(PolynomialValues, F, F)>, + pub zs_beta_gammas: Vec<(PolynomialValues, F, F, Vec)>, } impl Default for LookupData { @@ -32,7 +37,7 @@ impl LookupData { pub fn z_polys(&self) -> Vec> { self.zs_beta_gammas .iter() - .map(|(p, _, _)| p.clone()) + .map(|(p, _, _, _)| p.clone()) .collect() } } @@ -70,12 +75,18 @@ pub fn cross_table_lookup_zs, const D: gamma, ); - acc[*looking_table as usize] - .zs_beta_gammas - .push((z_looking, beta, gamma)); - acc[*looked_table as usize] - .zs_beta_gammas - .push((z_looked, beta, gamma)); + acc[*looking_table as usize].zs_beta_gammas.push(( + z_looking, + beta, + gamma, + looking_columns.clone(), + )); + acc[*looked_table as usize].zs_beta_gammas.push(( + z_looked, + beta, + gamma, + looked_columns.clone(), + )); } acc }, @@ -104,16 +115,15 @@ where FE: FieldExtension, P: PackedField, { - pub(crate) local_zs: Vec

, - pub(crate) next_zs: Vec

, - pub(crate) permutation_challenge_sets: Vec>, + pub(crate) local_z: P, + pub(crate) next_z: P, + pub(crate) challenges: PermutationChallenge, + pub(crate) columns: Vec, } -pub(crate) fn eval_permutation_checks( - stark: &S, - config: &StarkConfig, +pub(crate) fn eval_cross_table_lookup_checks( vars: StarkEvaluationVars, - permutation_data: PermutationCheckVars, + lookup_data: &[CTLCheckVars], consumer: &mut ConstraintConsumer

, ) where F: RichField + Extendable, @@ -122,49 +132,21 @@ pub(crate) fn eval_permutation_checks, S: Stark, { - let PermutationCheckVars { - local_zs, - next_zs, - permutation_challenge_sets, - } = permutation_data; + for lookup_datum in lookup_data { + let CTLCheckVars { + local_z, + next_z, + challenges, + columns, + } = lookup_datum; + let mut factor = ReducingFactor::new(challenges.beta); + let mut combine = |v: &[P]| -> P { + factor.reduce_ext(columns.iter().map(|&i| v[i])) + FE::from_basefield(challenges.gamma) + }; - // Check that Z(1) = 1; - for &z in &local_zs { - consumer.constraint_first_row(z - FE::ONE); - } - - let permutation_pairs = stark.permutation_pairs(); - - let permutation_batches = get_permutation_batches( - &permutation_pairs, - &permutation_challenge_sets, - config.num_challenges, - stark.permutation_batch_size(), - ); - - // Each zs value corresponds to a permutation batch. - for (i, instances) in permutation_batches.iter().enumerate() { - // Z(gx) * down = Z x * up - let (reduced_lhs, reduced_rhs): (Vec

, Vec

) = instances - .iter() - .map(|instance| { - let PermutationInstance { - pair: PermutationPair { column_pairs }, - challenge: PermutationChallenge { beta, gamma }, - } = instance; - let mut factor = ReducingFactor::new(*beta); - let (lhs, rhs): (Vec<_>, Vec<_>) = column_pairs - .iter() - .map(|&(i, j)| (vars.local_values[i], vars.local_values[j])) - .unzip(); - ( - factor.reduce_ext(lhs.into_iter()) + FE::from_basefield(*gamma), - factor.reduce_ext(rhs.into_iter()) + FE::from_basefield(*gamma), - ) - }) - .unzip(); - let constraint = next_zs[i] * reduced_rhs.into_iter().product::

() - - local_zs[i] * reduced_lhs.into_iter().product::

(); - consumer.constraint(constraint); + // Check value of `Z(1)` + consumer.constraint_first_row(*local_z - combine(vars.local_values)); + // Check `Z(gw) = combination * Z(w)` + consumer.constraint_transition(*next_z - *local_z * combine(vars.next_values)); } } diff --git a/starky2/src/lib.rs b/starky2/src/lib.rs index 03ce7076..a545b2c0 100644 --- a/starky2/src/lib.rs +++ b/starky2/src/lib.rs @@ -7,7 +7,7 @@ pub mod config; pub mod constraint_consumer; pub mod cross_table_lookups; mod get_challenges; -pub mod mock_stark; +// pub mod mock_stark; pub mod permutation; pub mod proof; pub mod prover; diff --git a/starky2/src/prover.rs b/starky2/src/prover.rs index d998b074..7413dcba 100644 --- a/starky2/src/prover.rs +++ b/starky2/src/prover.rs @@ -13,7 +13,6 @@ use plonky2::fri::oracle::PolynomialBatch; use plonky2::hash::hash_types::RichField; use plonky2::iop::challenger::Challenger; use plonky2::plonk::config::{GenericConfig, Hasher}; -use plonky2::plonk::plonk_common::reduce_with_powers; use plonky2::timed; use plonky2::util::timing::TimingTree; use plonky2::util::transpose; @@ -22,11 +21,11 @@ use rayon::prelude::*; use crate::config::StarkConfig; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use crate::cross_table_lookups::{cross_table_lookup_zs, LookupData}; -use crate::permutation::PermutationCheckVars; +use crate::cross_table_lookups::{cross_table_lookup_zs, CTLCheckVars, LookupData}; use crate::permutation::{ compute_permutation_z_polys, get_n_permutation_challenge_sets, PermutationChallengeSet, }; +use crate::permutation::{PermutationChallenge, PermutationCheckVars}; use crate::proof::{StarkOpeningSet, StarkProof, StarkProofWithPublicInputs}; use crate::stark::Stark; use crate::vanishing_poly::eval_vanishing_poly; @@ -48,8 +47,8 @@ impl, const D: usize> Stark for CpuStark( &self, - vars: StarkEvaluationVars, - yield_constr: &mut ConstraintConsumer

, + _vars: StarkEvaluationVars, + _yield_constr: &mut ConstraintConsumer

, ) where FE: FieldExtension, P: PackedField, @@ -59,9 +58,9 @@ impl, const D: usize> Stark for CpuStark, - vars: StarkEvaluationTargets, - yield_constr: &mut RecursiveConstraintConsumer, + _builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder, + _vars: StarkEvaluationTargets, + _yield_constr: &mut RecursiveConstraintConsumer, ) { todo!() } @@ -81,8 +80,8 @@ impl, const D: usize> Stark for KeccakStark( &self, - vars: StarkEvaluationVars, - yield_constr: &mut ConstraintConsumer

, + _vars: StarkEvaluationVars, + _yield_constr: &mut ConstraintConsumer

, ) where FE: FieldExtension, P: PackedField, @@ -92,9 +91,9 @@ impl, const D: usize> Stark for KeccakStark, - vars: StarkEvaluationTargets, - yield_constr: &mut RecursiveConstraintConsumer, + _builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder, + _vars: StarkEvaluationTargets, + _yield_constr: &mut RecursiveConstraintConsumer, ) { todo!() } @@ -110,11 +109,11 @@ pub struct AllStarks, const D: usize> { } pub struct CrossTableLookup { - looking_table: Table, - looking_columns: Vec, - looked_table: usize, - looked_columns: Vec, - default: F, + pub looking_table: Table, + pub looking_columns: Vec, + pub looked_table: usize, + pub looked_columns: Vec, + pub default: F, } impl CrossTableLookup { @@ -247,7 +246,7 @@ where let degree_bits = log2_strict(degree); let fri_params = config.fri_params(degree_bits); let rate_bits = config.fri_config.rate_bits; - let cap_height = config.fri_config.cap_height; + let _cap_height = config.fri_config.cap_height; // Permutation arguments. let permutation_challenges = stark.uses_permutation_args().then(|| { @@ -258,8 +257,9 @@ where ) }); let permutation_zs = permutation_challenges.as_ref().map(|challenges| { - compute_permutation_z_polys::(&stark, config, &trace_poly_values, challenges) + compute_permutation_z_polys::(stark, config, trace_poly_values, challenges) }); + let num_permutation_zs = permutation_zs.as_ref().map(|v| v.len()).unwrap_or(0); let z_polys = match (permutation_zs, lookup_data.is_empty()) { (None, true) => lookup_data.z_polys(), @@ -288,6 +288,7 @@ where challenger.observe_cap(cap); } + // TODO: if no permutation but lookup, this is wrong. let zipped = if let (Some(x), Some(y)) = ( permutation_lookup_zs_commitment.as_ref(), permutation_challenges.as_ref(), @@ -299,13 +300,14 @@ where let alphas = challenger.get_n_challenges(config.num_challenges); let quotient_polys = compute_quotient_polys::::Packing, C, S, D>( - &stark, - &trace_commitment, + stark, + trace_commitment, zipped, lookup_data, public_inputs, alphas, degree_bits, + num_permutation_zs, config, ); let all_quotient_chunks = quotient_polys @@ -346,7 +348,7 @@ where let openings = StarkOpeningSet::new( zeta, g, - &trace_commitment, + trace_commitment, permutation_lookup_zs_commitment.as_ref(), "ient_commitment, ); @@ -395,6 +397,7 @@ fn compute_quotient_polys<'a, F, P, C, S, const D: usize>( public_inputs: &[F], alphas: Vec, degree_bits: usize, + num_permutation_zs: usize, config: &StarkConfig, ) -> Vec> where @@ -459,20 +462,47 @@ where let vars = StarkEvaluationVars { local_values: &get_trace_values_packed(i_start), next_values: &get_trace_values_packed(i_next_start), - public_inputs: &public_inputs, + public_inputs, }; let permutation_check_data = permutation_zs_commitment_challenges.as_ref().map( |(permutation_zs_commitment, permutation_challenge_sets)| PermutationCheckVars { - local_zs: permutation_zs_commitment.get_lde_values_packed(i_start, step), - next_zs: permutation_zs_commitment.get_lde_values_packed(i_next_start, step), + local_zs: permutation_zs_commitment.get_lde_values_packed(i_start, step) + [..num_permutation_zs] + .to_vec(), + next_zs: permutation_zs_commitment.get_lde_values_packed(i_next_start, step) + [..num_permutation_zs] + .to_vec(), permutation_challenge_sets: permutation_challenge_sets.to_vec(), }, ); + let lookup_check_data = lookup_data + .zs_beta_gammas + .iter() + .enumerate() + .map( + |(i, (_, beta, gamma, columns))| CTLCheckVars:: { + local_z: permutation_zs_commitment_challenges + .unwrap() + .0 + .get_lde_values_packed(i_start, step)[num_permutation_zs + i], + next_z: permutation_zs_commitment_challenges + .unwrap() + .0 + .get_lde_values_packed(i_next_start, step)[num_permutation_zs + i], + challenges: PermutationChallenge { + beta: *beta, + gamma: *gamma, + }, + columns: columns.to_vec(), + }, + ) + .collect::>(); eval_vanishing_poly::( stark, config, vars, permutation_check_data, + &lookup_check_data, &mut consumer, ); let mut constraints_evals = consumer.accumulators(); diff --git a/starky2/src/vanishing_poly.rs b/starky2/src/vanishing_poly.rs index 0a3f4514..7d43feb3 100644 --- a/starky2/src/vanishing_poly.rs +++ b/starky2/src/vanishing_poly.rs @@ -6,6 +6,7 @@ use plonky2::plonk::config::GenericConfig; use crate::config::StarkConfig; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::cross_table_lookups::{eval_cross_table_lookup_checks, CTLCheckVars}; use crate::permutation::{ eval_permutation_checks, eval_permutation_checks_recursively, PermutationCheckDataTarget, PermutationCheckVars, @@ -18,6 +19,7 @@ pub(crate) fn eval_vanishing_poly, permutation_data: Option>, + lookup_data: &[CTLCheckVars], consumer: &mut ConstraintConsumer

, ) where F: RichField + Extendable, @@ -36,6 +38,7 @@ pub(crate) fn eval_vanishing_poly(vars, lookup_data, consumer); } pub(crate) fn eval_vanishing_poly_recursively( diff --git a/starky2/src/verifier.rs b/starky2/src/verifier.rs index d5344a44..9ac05d96 100644 --- a/starky2/src/verifier.rs +++ b/starky2/src/verifier.rs @@ -99,6 +99,7 @@ where config, vars, permutation_data, + &[/*TODO*/], &mut consumer, ); let vanishing_polys_zeta = consumer.accumulators();