From 2b8c3de10ec9d31d715a5ec9843ba5cedff2ebdb Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 12 May 2022 13:47:55 +0200 Subject: [PATCH] Finish verifier --- starky2/src/cross_table_lookup.rs | 107 ++++++++++++++++++++++++------ starky2/src/get_challenges.rs | 8 +-- starky2/src/permutation.rs | 2 +- starky2/src/proof.rs | 4 +- starky2/src/prover.rs | 9 +-- starky2/src/verifier.rs | 46 ++++++++----- 6 files changed, 126 insertions(+), 50 deletions(-) diff --git a/starky2/src/cross_table_lookup.rs b/starky2/src/cross_table_lookup.rs index 63f41c6b..6dfec2d2 100644 --- a/starky2/src/cross_table_lookup.rs +++ b/starky2/src/cross_table_lookup.rs @@ -12,11 +12,14 @@ use plonky2::util::reducing::ReducingFactor; use crate::all_stark::Table; use crate::config::StarkConfig; use crate::constraint_consumer::ConstraintConsumer; -use crate::permutation::PermutationChallenge; +use crate::permutation::{ + get_permutation_challenge_set, PermutationChallenge, PermutationChallengeSet, +}; use crate::proof::StarkProofWithPublicInputs; use crate::stark::Stark; use crate::vars::StarkEvaluationVars; +#[derive(Clone)] pub struct CrossTableLookup { pub looking_table: Table, pub looking_columns: Vec, @@ -44,16 +47,14 @@ impl CrossTableLookup { /// Lookup data for one table. #[derive(Clone)] pub struct LookupData { - pub beta: F, - pub gamma: F, + pub(crate) challenges: PermutationChallengeSet, pub zs_columns: Vec<(PolynomialValues, Vec)>, } impl LookupData { - pub fn new(beta: F, gamma: F) -> Self { + pub(crate) fn new(challenges: PermutationChallengeSet) -> Self { Self { - beta, - gamma, + challenges, zs_columns: vec![], } } @@ -77,10 +78,9 @@ 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(); + let challenges = get_permutation_challenge_set(challenger, config.num_challenges); cross_table_lookups.iter().fold( - vec![LookupData::new(beta, gamma); trace_poly_values.len()], + vec![LookupData::new(challenges.clone()); trace_poly_values.len()], |mut acc, cross_table_lookup| { let CrossTableLookup { looking_table, @@ -89,7 +89,7 @@ pub fn cross_table_lookup_zs, const D: looked_columns, } = cross_table_lookup; - for _ in 0..config.num_challenges { + for &PermutationChallenge { beta, gamma } in &challenges.challenges { let z_looking = partial_products( &trace_poly_values[*looking_table as usize], looking_columns, @@ -131,7 +131,8 @@ fn partial_products( res.into() } -pub struct CTLCheckVars +#[derive(Clone)] +pub struct CTLCheckVars<'a, F, FE, P, const D2: usize> where F: Field, FE: FieldExtension, @@ -140,7 +141,68 @@ where pub(crate) local_z: P, pub(crate) next_z: P, pub(crate) challenges: PermutationChallenge, - pub(crate) columns: Vec, + pub(crate) columns: &'a [usize], +} + +impl<'a, F: RichField + Extendable, const D: usize> + CTLCheckVars<'a, F, F::Extension, F::Extension, D> +{ + pub(crate) fn from_proofs>( + proofs: &[&StarkProofWithPublicInputs], + cross_table_lookups: &'a [CrossTableLookup], + ctl_challenges: &'a PermutationChallengeSet, + ) -> Vec> { + let mut ctl_zs = proofs + .iter() + .map(|p| { + p.proof + .openings + .permutation_lookup_zs + .as_ref() + .unwrap() // TODO: fix unwrap + .iter() + .zip( + p.proof + .openings + .permutation_lookup_zs_right + .as_ref() + .unwrap() + .iter(), + ) + }) + .collect::>(); + + cross_table_lookups + .iter() + .fold(vec![vec![]; proofs.len()], |mut acc, ctl| { + let CrossTableLookup { + looking_table, + looking_columns, + looked_table, + looked_columns, + } = ctl; + + for &challenges in &ctl_challenges.challenges { + let (looking_z, looking_z_next) = + ctl_zs[*looking_table as usize].next().unwrap(); + acc[*looking_table as usize].push(Self { + local_z: *looking_z, + next_z: *looking_z_next, + challenges, + columns: &looking_columns, + }); + + let (looked_z, looked_z_next) = ctl_zs[*looked_table as usize].next().unwrap(); + acc[*looked_table as usize].push(Self { + local_z: *looked_z, + next_z: *looked_z_next, + challenges, + columns: &looked_columns, + }); + } + acc + }) + } } pub(crate) fn eval_cross_table_lookup_checks( @@ -180,7 +242,7 @@ pub(crate) fn verify_cross_table_lookups< >( cross_table_lookups: Vec, proofs: &[&StarkProofWithPublicInputs], - challenges: PermutationChallenge, + challenges: PermutationChallengeSet, config: &StarkConfig, ) -> Result<()> { let degrees_bits = proofs @@ -191,18 +253,25 @@ pub(crate) fn verify_cross_table_lookups< .iter() .map(|p| p.proof.openings.lookup_zs_last.iter()) .collect::>(); - for CrossTableLookup { - looking_table, - looked_table, - .. - } in cross_table_lookups + for ( + i, + CrossTableLookup { + looking_table, + looked_table, + .. + }, + ) in cross_table_lookups.into_iter().enumerate() { let looking_degree = 1 << degrees_bits[looking_table as usize]; let looked_degree = 1 << degrees_bits[looked_table as usize]; let looking_z = *lookup_zs_openings[looking_table as usize].next().unwrap(); let looked_z = *lookup_zs_openings[looked_table as usize].next().unwrap(); ensure!( - looking_z == looked_z * challenges.gamma.exp_u64(looking_degree - looked_degree), + looking_z + == looked_z + * challenges.challenges[i % config.num_challenges] + .gamma + .exp_u64(looking_degree - looked_degree), "Cross-table lookup verification failed." ); } diff --git a/starky2/src/get_challenges.rs b/starky2/src/get_challenges.rs index a6e3506d..acc0bbc0 100644 --- a/starky2/src/get_challenges.rs +++ b/starky2/src/get_challenges.rs @@ -12,7 +12,8 @@ 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, PermutationChallenge, + get_n_permutation_challenge_sets, get_n_permutation_challenge_sets_target, + get_permutation_challenge_set, }; use crate::proof::*; use crate::stark::Stark; @@ -83,10 +84,7 @@ impl, C: GenericConfig, const D: usize> A challenger.observe_cap(&proof.proof.trace_cap); } - let ctl_challenges = PermutationChallenge { - beta: challenger.get_challenge(), - gamma: challenger.get_challenge(), - }; + let ctl_challenges = get_permutation_challenge_set(&mut challenger, config.num_challenges); AllProofChallenges { cpu_challenges: self.cpu_proof.get_challenges( diff --git a/starky2/src/permutation.rs b/starky2/src/permutation.rs index ad3efd0c..2f0b5378 100644 --- a/starky2/src/permutation.rs +++ b/starky2/src/permutation.rs @@ -155,7 +155,7 @@ fn get_permutation_challenge>( PermutationChallenge { beta, gamma } } -fn get_permutation_challenge_set>( +pub(crate) fn get_permutation_challenge_set>( challenger: &mut Challenger, num_challenges: usize, ) -> PermutationChallengeSet { diff --git a/starky2/src/proof.rs b/starky2/src/proof.rs index a7a31fa4..1dd40d3f 100644 --- a/starky2/src/proof.rs +++ b/starky2/src/proof.rs @@ -15,7 +15,7 @@ use plonky2::plonk::config::GenericConfig; use rayon::prelude::*; use crate::config::StarkConfig; -use crate::permutation::{PermutationChallenge, PermutationChallengeSet}; +use crate::permutation::PermutationChallengeSet; #[derive(Debug, Clone)] pub struct AllProof, C: GenericConfig, const D: usize> { @@ -32,7 +32,7 @@ impl, C: GenericConfig, const D: usize> A pub(crate) struct AllProofChallenges, const D: usize> { pub cpu_challenges: StarkProofChallenges, pub keccak_challenges: StarkProofChallenges, - pub ctl_challenges: PermutationChallenge, + pub ctl_challenges: PermutationChallengeSet, } #[derive(Debug, Clone)] diff --git a/starky2/src/prover.rs b/starky2/src/prover.rs index ebebd915..f6a412c6 100644 --- a/starky2/src/prover.rs +++ b/starky2/src/prover.rs @@ -22,10 +22,10 @@ use crate::all_stark::{AllStark, Table}; use crate::config::StarkConfig; use crate::constraint_consumer::ConstraintConsumer; use crate::cross_table_lookup::{cross_table_lookup_zs, CTLCheckVars, LookupData}; +use crate::permutation::PermutationCheckVars; use crate::permutation::{ compute_permutation_z_polys, get_n_permutation_challenge_sets, PermutationChallengeSet, }; -use crate::permutation::{PermutationChallenge, PermutationCheckVars}; use crate::proof::{AllProof, StarkOpeningSet, StarkProof, StarkProofWithPublicInputs}; use crate::stark::Stark; use crate::vanishing_poly::eval_vanishing_poly; @@ -387,11 +387,8 @@ where .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(), + challenges: lookup_data.challenges.challenges[i % config.num_challenges], + columns: &columns, }) .collect::>(); eval_vanishing_poly::( diff --git a/starky2/src/verifier.rs b/starky2/src/verifier.rs index 6e60e601..723b9e78 100644 --- a/starky2/src/verifier.rs +++ b/starky2/src/verifier.rs @@ -9,10 +9,10 @@ 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::all_stark::{AllStark, KeccakStark, Table}; use crate::config::StarkConfig; use crate::constraint_consumer::ConstraintConsumer; -use crate::cross_table_lookup::verify_cross_table_lookups; +use crate::cross_table_lookup::{verify_cross_table_lookups, CTLCheckVars}; use crate::permutation::PermutationCheckVars; use crate::proof::{ AllProof, AllProofChallenges, StarkOpeningSet, StarkProofChallenges, StarkProofWithPublicInputs, @@ -42,19 +42,29 @@ where cross_table_lookups, } = all_stark; + let ctl_vars_per_table = + CTLCheckVars::from_proofs(&all_proof.proofs(), &cross_table_lookups, &ctl_challenges); + + verify_stark_proof_with_challenges( + cpu_stark, + &all_proof.cpu_proof, + cpu_challenges, + &ctl_vars_per_table[Table::Cpu as usize], + config, + )?; + verify_stark_proof_with_challenges( + keccak_stark, + &all_proof.keccak_proof, + keccak_challenges, + &ctl_vars_per_table[Table::Keccak as usize], + config, + )?; + verify_cross_table_lookups( cross_table_lookups, &all_proof.proofs(), ctl_challenges, config, - )?; - - verify_stark_proof_with_challenges(cpu_stark, all_proof.cpu_proof, cpu_challenges, config)?; - verify_stark_proof_with_challenges( - keccak_stark, - all_proof.keccak_proof, - keccak_challenges, - config, ) } @@ -86,8 +96,9 @@ pub(crate) fn verify_stark_proof_with_challenges< const D: usize, >( stark: S, - proof_with_pis: StarkProofWithPublicInputs, + proof_with_pis: &StarkProofWithPublicInputs, challenges: StarkProofChallenges, + lookup_data: &[CTLCheckVars], config: &StarkConfig, ) -> Result<()> where @@ -112,7 +123,8 @@ where local_values, next_values, public_inputs: &public_inputs - .into_iter() + .iter() + .copied() .map(F::Extension::from_basefield) .collect::>(), }; @@ -141,7 +153,7 @@ where config, vars, permutation_data, - &[/*TODO*/], + lookup_data, &mut consumer, ); let vanishing_polys_zeta = consumer.accumulators(); @@ -164,9 +176,9 @@ where ); } - let merkle_caps = once(proof.trace_cap) - .chain(proof.permutation_zs_cap) - .chain(once(proof.quotient_polys_cap)) + let merkle_caps = once(proof.trace_cap.clone()) + .chain(proof.permutation_zs_cap.clone()) + .chain(once(proof.quotient_polys_cap.clone())) .collect_vec(); verify_fri_proof::( @@ -174,7 +186,7 @@ where challenges.stark_zeta, F::primitive_root_of_unity(degree_bits), degree_bits, - todo!(), + lookup_zs_last.len(), config, ), &proof.openings.to_fri_openings(),