diff --git a/starky2/src/all_stark.rs b/starky2/src/all_stark.rs index c8b7fa76..67445856 100644 --- a/starky2/src/all_stark.rs +++ b/starky2/src/all_stark.rs @@ -5,12 +5,14 @@ use plonky2::field::packed_field::PackedField; use plonky2::hash::hash_types::RichField; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::cross_table_lookup::CrossTableLookup; use crate::stark::Stark; use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; pub struct AllStark, const D: usize> { - pub cpu: CpuStark, - pub keccak: KeccakStark, + pub cpu_stark: CpuStark, + pub keccak_stark: KeccakStark, + pub cross_table_lookups: Vec, } pub struct CpuStark { diff --git a/starky2/src/cross_table_lookup.rs b/starky2/src/cross_table_lookup.rs index 3d689b50..9e485d07 100644 --- a/starky2/src/cross_table_lookup.rs +++ b/starky2/src/cross_table_lookup.rs @@ -42,31 +42,30 @@ impl CrossTableLookup { /// Lookup data for one table. #[derive(Clone)] pub struct LookupData { - pub zs_beta_gammas: Vec<(PolynomialValues, F, F, Vec)>, -} - -impl Default for LookupData { - fn default() -> Self { - Self { - zs_beta_gammas: Vec::new(), - } - } + pub beta: F, + pub gamma: F, + pub zs_columns: Vec<(PolynomialValues, Vec)>, } impl LookupData { + pub fn new(beta: F, gamma: F) -> Self { + Self { + beta, + gamma, + zs_columns: vec![], + } + } + pub fn len(&self) -> usize { - self.zs_beta_gammas.len() + self.zs_columns.len() } pub fn is_empty(&self) -> bool { - self.zs_beta_gammas.is_empty() + self.zs_columns.is_empty() } pub fn z_polys(&self) -> Vec> { - self.zs_beta_gammas - .iter() - .map(|(p, _, _, _)| p.clone()) - .collect() + self.zs_columns.iter().map(|(p, _)| p.clone()).collect() } } @@ -76,20 +75,19 @@ pub fn cross_table_lookup_zs, const D: cross_table_lookups: &[CrossTableLookup], challenger: &mut Challenger, ) -> Vec> { + let beta = challenger.get_challenge(); + let gamma = challenger.get_challenge(); cross_table_lookups.iter().fold( - vec![LookupData::default(); trace_poly_values.len()], + vec![LookupData::new(beta, gamma); trace_poly_values.len()], |mut acc, cross_table_lookup| { let CrossTableLookup { looking_table, looking_columns, looked_table, looked_columns, - .. } = cross_table_lookup; for _ in 0..config.num_challenges { - let beta = challenger.get_challenge(); - let gamma = challenger.get_challenge(); let z_looking = partial_products( &trace_poly_values[*looking_table as usize], looking_columns, @@ -103,18 +101,12 @@ pub fn cross_table_lookup_zs, const D: 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[*looking_table as usize] + .zs_columns + .push((z_looking, looking_columns.clone())); + acc[*looked_table as usize] + .zs_columns + .push((z_looked, looked_columns.clone())); } acc }, diff --git a/starky2/src/get_challenges.rs b/starky2/src/get_challenges.rs index ceafa297..dc69d857 100644 --- a/starky2/src/get_challenges.rs +++ b/starky2/src/get_challenges.rs @@ -9,14 +9,16 @@ use plonky2::iop::target::Target; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; +use crate::all_stark::AllStark; use crate::config::StarkConfig; use crate::permutation::{ - get_n_permutation_challenge_sets, get_n_permutation_challenge_sets_target, + get_n_permutation_challenge_sets, get_n_permutation_challenge_sets_target, PermutationChallenge, }; use crate::proof::*; use crate::stark::Stark; fn get_challenges( + challenger: &mut Challenger, stark: &S, trace_cap: &MerkleCap, permutation_zs_cap: Option<&MerkleCap>, @@ -35,13 +37,11 @@ where { let num_challenges = config.num_challenges; - let mut challenger = Challenger::::new(); - challenger.observe_cap(trace_cap); let permutation_challenge_sets = permutation_zs_cap.map(|permutation_zs_cap| { let tmp = get_n_permutation_challenge_sets( - &mut challenger, + challenger, num_challenges, stark.permutation_batch_size(), ); @@ -70,6 +70,42 @@ where } } +impl, C: GenericConfig, const D: usize> AllProof { + /// Computes all Fiat-Shamir challenges used in the STARK proof. + pub(crate) fn get_challenges( + &self, + all_stark: &AllStark, + config: &StarkConfig, + ) -> AllProofChallenges { + let num_challenges = config.num_challenges; + + let mut challenger = Challenger::::new(); + + for proof in self.proofs() { + challenger.observe_cap(&proof.proof.trace_cap); + } + + let ctl_challenges = PermutationChallenge { + beta: challenger.get_challenge(), + gamma: challenger.get_challenge(), + }; + + AllProofChallenges { + cpu_challenges: self.cpu_proof.get_challenges( + &mut challenger, + &all_stark.cpu_stark, + config, + ), + keccak_challenges: self.keccak_proof.get_challenges( + &mut challenger, + &all_stark.keccak_stark, + config, + ), + ctl_challenges, + } + } +} + impl StarkProofWithPublicInputs where F: RichField + Extendable, @@ -81,9 +117,9 @@ where &self, stark: &S, config: &StarkConfig, - degree_bits: usize, ) -> Vec { - self.get_challenges(stark, config, degree_bits) + let mut challenger = Challenger::new(); + self.get_challenges(&mut challenger, stark, config) .fri_challenges .fri_query_indices } @@ -91,10 +127,12 @@ where /// Computes all Fiat-Shamir challenges used in the STARK proof. pub(crate) fn get_challenges>( &self, + challenger: &mut Challenger, stark: &S, config: &StarkConfig, - degree_bits: usize, ) -> StarkProofChallenges { + let degree_bits = self.proof.recover_degree_bits(config); + let StarkProof { trace_cap, permutation_zs_cap, @@ -110,6 +148,7 @@ where } = &self.proof; get_challenges::( + challenger, stark, trace_cap, permutation_zs_cap.as_ref(), diff --git a/starky2/src/proof.rs b/starky2/src/proof.rs index 3fa51a51..89c116df 100644 --- a/starky2/src/proof.rs +++ b/starky2/src/proof.rs @@ -16,7 +16,25 @@ use plonky2::plonk::config::GenericConfig; use rayon::prelude::*; use crate::config::StarkConfig; -use crate::permutation::PermutationChallengeSet; +use crate::permutation::{PermutationChallenge, PermutationChallengeSet}; + +#[derive(Debug, Clone)] +pub struct AllProof, C: GenericConfig, const D: usize> { + pub cpu_proof: StarkProofWithPublicInputs, + pub keccak_proof: StarkProofWithPublicInputs, +} + +impl, C: GenericConfig, const D: usize> AllProof { + pub fn proofs(&self) -> [&StarkProofWithPublicInputs; 2] { + [&self.cpu_proof, &self.keccak_proof] + } +} + +pub(crate) struct AllProofChallenges, const D: usize> { + pub cpu_challenges: StarkProofChallenges, + pub keccak_challenges: StarkProofChallenges, + pub ctl_challenges: PermutationChallenge, +} #[derive(Debug, Clone)] pub struct StarkProof, C: GenericConfig, const D: usize> { diff --git a/starky2/src/prover.rs b/starky2/src/prover.rs index aba1f830..0f5013a4 100644 --- a/starky2/src/prover.rs +++ b/starky2/src/prover.rs @@ -28,19 +28,18 @@ 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::proof::{AllProof, StarkOpeningSet, StarkProof, StarkProofWithPublicInputs}; use crate::stark::Stark; use crate::vanishing_poly::eval_vanishing_poly; use crate::vars::StarkEvaluationVars; pub fn prove( - all_starks: AllStark, + all_stark: AllStark, config: &StarkConfig, trace_poly_values: Vec>>, - cross_table_lookups: Vec, public_inputs: Vec>, timing: &mut TimingTree, -) -> Result>> +) -> Result> where F: RichField + Extendable, C: GenericConfig, @@ -93,12 +92,12 @@ where let lookup_zs = cross_table_lookup_zs::( config, &trace_poly_values, - &cross_table_lookups, + &all_stark.cross_table_lookups, &mut challenger, ); let cpu_proof = prove_single_table( - &all_starks.cpu, + &all_stark.cpu_stark, config, &trace_poly_values[Table::Cpu as usize], &trace_commitments[Table::Cpu as usize], @@ -108,7 +107,7 @@ where timing, )?; let keccak_proof = prove_single_table( - &all_starks.keccak, + &all_stark.keccak_stark, config, &trace_poly_values[Table::Keccak as usize], &trace_commitments[Table::Keccak as usize], @@ -118,7 +117,10 @@ where timing, )?; - Ok(vec![cpu_proof, keccak_proof]) + Ok(AllProof { + cpu_proof, + keccak_proof, + }) } fn prove_single_table( @@ -375,26 +377,24 @@ where }, ); let lookup_check_data = lookup_data - .zs_beta_gammas + .zs_columns .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(), + .map(|(i, (_, 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: lookup_data.beta, + gamma: lookup_data.gamma, }, - ) + columns: columns.to_vec(), + }) .collect::>(); eval_vanishing_poly::( stark, diff --git a/starky2/src/verifier.rs b/starky2/src/verifier.rs index 9375c9f4..b5f144fb 100644 --- a/starky2/src/verifier.rs +++ b/starky2/src/verifier.rs @@ -9,35 +9,69 @@ use plonky2::hash::hash_types::RichField; use plonky2::plonk::config::{GenericConfig, Hasher}; use plonky2::plonk::plonk_common::reduce_with_powers; +use crate::all_stark::{AllStark, KeccakStark}; use crate::config::StarkConfig; use crate::constraint_consumer::ConstraintConsumer; use crate::permutation::PermutationCheckVars; -use crate::proof::{StarkOpeningSet, StarkProofChallenges, StarkProofWithPublicInputs}; +use crate::proof::{ + AllProof, AllProofChallenges, StarkOpeningSet, StarkProofChallenges, StarkProofWithPublicInputs, +}; use crate::stark::Stark; use crate::vanishing_poly::eval_vanishing_poly; use crate::vars::StarkEvaluationVars; -pub fn verify_stark_proof< - F: RichField + Extendable, - C: GenericConfig, - S: Stark, - const D: usize, ->( - stark: S, - proof_with_pis: StarkProofWithPublicInputs, +pub fn verify_proof, C: GenericConfig, const D: usize>( + all_stark: AllStark, + all_proof: AllProof, config: &StarkConfig, ) -> Result<()> where - [(); S::COLUMNS]:, - [(); S::PUBLIC_INPUTS]:, + [(); KeccakStark::::COLUMNS]:, [(); C::Hasher::HASH_SIZE]:, { - ensure!(proof_with_pis.public_inputs.len() == S::PUBLIC_INPUTS); - let degree_bits = proof_with_pis.proof.recover_degree_bits(config); - let challenges = proof_with_pis.get_challenges(&stark, config, degree_bits); - verify_stark_proof_with_challenges(stark, proof_with_pis, challenges, degree_bits, config) + let AllProofChallenges { + cpu_challenges, + keccak_challenges, + ctl_challenges, + } = all_proof.get_challenges(&all_stark, config); + + // Verify CTL + + verify_stark_proof_with_challenges( + all_stark.cpu_stark, + all_proof.cpu_proof, + cpu_challenges, + config, + )?; + verify_stark_proof_with_challenges( + all_stark.keccak_stark, + all_proof.keccak_proof, + keccak_challenges, + config, + ) } +// pub fn verify_stark_proof< +// F: RichField + Extendable, +// C: GenericConfig, +// S: Stark, +// const D: usize, +// >( +// stark: S, +// proof_with_pis: StarkProofWithPublicInputs, +// config: &StarkConfig, +// ) -> Result<()> +// where +// [(); S::COLUMNS]:, +// [(); S::PUBLIC_INPUTS]:, +// [(); C::Hasher::HASH_SIZE]:, +// { +// ensure!(proof_with_pis.public_inputs.len() == S::PUBLIC_INPUTS); +// let degree_bits = proof_with_pis.proof.recover_degree_bits(config); +// let challenges = proof_with_pis.get_challenges(&stark, config, degree_bits); +// verify_stark_proof_with_challenges(stark, proof_with_pis, challenges, degree_bits, config) +// } + pub(crate) fn verify_stark_proof_with_challenges< F: RichField + Extendable, C: GenericConfig, @@ -47,7 +81,6 @@ pub(crate) fn verify_stark_proof_with_challenges< stark: S, proof_with_pis: StarkProofWithPublicInputs, challenges: StarkProofChallenges, - degree_bits: usize, config: &StarkConfig, ) -> Result<()> where @@ -77,6 +110,7 @@ where .collect::>(), }; + let degree_bits = proof.recover_degree_bits(config); let (l_1, l_last) = eval_l_1_and_l_last(degree_bits, challenges.stark_zeta); let last = F::primitive_root_of_unity(degree_bits).inverse(); let z_last = challenges.stark_zeta - last.into();