From b9e921f6400578bfe5822a7a74e63fef6a1d9924 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Wed, 11 May 2022 16:09:12 +0200 Subject: [PATCH] CTL verification --- starky2/src/cross_table_lookup.rs | 39 +++++++++++++++++++++++++++++++ starky2/src/get_challenges.rs | 2 -- starky2/src/proof.rs | 22 +++++++++++------ starky2/src/prover.rs | 4 +--- starky2/src/verifier.rs | 19 ++++++++++----- 5 files changed, 68 insertions(+), 18 deletions(-) diff --git a/starky2/src/cross_table_lookup.rs b/starky2/src/cross_table_lookup.rs index 9e485d07..63f41c6b 100644 --- a/starky2/src/cross_table_lookup.rs +++ b/starky2/src/cross_table_lookup.rs @@ -1,3 +1,4 @@ +use anyhow::{ensure, Result}; use plonky2::field::extension_field::{Extendable, FieldExtension}; use plonky2::field::field_types::Field; use plonky2::field::packed_field::PackedField; @@ -12,6 +13,7 @@ use crate::all_stark::Table; use crate::config::StarkConfig; use crate::constraint_consumer::ConstraintConsumer; use crate::permutation::PermutationChallenge; +use crate::proof::StarkProofWithPublicInputs; use crate::stark::Stark; use crate::vars::StarkEvaluationVars; @@ -170,3 +172,40 @@ pub(crate) fn eval_cross_table_lookup_checks, + C: GenericConfig, + const D: usize, +>( + cross_table_lookups: Vec, + proofs: &[&StarkProofWithPublicInputs], + challenges: PermutationChallenge, + config: &StarkConfig, +) -> Result<()> { + let degrees_bits = proofs + .iter() + .map(|p| p.proof.recover_degree_bits(config)) + .collect::>(); + let mut lookup_zs_openings = proofs + .iter() + .map(|p| p.proof.openings.lookup_zs_last.iter()) + .collect::>(); + for CrossTableLookup { + looking_table, + looked_table, + .. + } in cross_table_lookups + { + 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), + "Cross-table lookup verification failed." + ); + } + + Ok(()) +} diff --git a/starky2/src/get_challenges.rs b/starky2/src/get_challenges.rs index dc69d857..a6e3506d 100644 --- a/starky2/src/get_challenges.rs +++ b/starky2/src/get_challenges.rs @@ -77,8 +77,6 @@ impl, C: GenericConfig, const D: usize> A all_stark: &AllStark, config: &StarkConfig, ) -> AllProofChallenges { - let num_challenges = config.num_challenges; - let mut challenger = Challenger::::new(); for proof in self.proofs() { diff --git a/starky2/src/proof.rs b/starky2/src/proof.rs index 89c116df..a7a31fa4 100644 --- a/starky2/src/proof.rs +++ b/starky2/src/proof.rs @@ -1,6 +1,5 @@ use itertools::Itertools; use plonky2::field::extension_field::{Extendable, FieldExtension}; -use plonky2::field::field_types::Field; use plonky2::fri::oracle::PolynomialBatch; use plonky2::fri::proof::{ CompressedFriProof, FriChallenges, FriChallengesTarget, FriProof, FriProofTarget, @@ -147,7 +146,7 @@ pub struct StarkOpeningSet, const D: usize> { pub next_values: Vec, pub permutation_lookup_zs: Option>, pub permutation_lookup_zs_right: Option>, - pub lookup_zs_last: Vec, + pub lookup_zs_last: Vec, pub quotient_polys: Vec, } @@ -167,6 +166,12 @@ impl, const D: usize> StarkOpeningSet { .map(|p| p.to_extension().eval(z)) .collect::>() }; + let eval_commitment_base = |z: F, c: &PolynomialBatch| { + c.polynomials + .par_iter() + .map(|p| p.eval(z)) + .collect::>() + }; let zeta_right = zeta.scalar_mul(g); Self { local_values: eval_commitment(zeta, trace_commitment), @@ -177,10 +182,8 @@ impl, const D: usize> StarkOpeningSet { .map(|c| eval_commitment(zeta_right, c)), lookup_zs_last: permutation_lookup_zs_commitment .map(|c| { - eval_commitment( - F::Extension::primitive_root_of_unity(degree_bits).inverse(), - c, - )[num_permutation_zs..] + eval_commitment_base(F::primitive_root_of_unity(degree_bits).inverse(), c) + [num_permutation_zs..] .to_vec() }) .unwrap_or_default(), @@ -210,7 +213,12 @@ impl, const D: usize> StarkOpeningSet { if !self.lookup_zs_last.is_empty() { batches.push(FriOpeningBatch { - values: self.lookup_zs_last.clone(), + values: self + .lookup_zs_last + .iter() + .copied() + .map(F::Extension::from_basefield) + .collect(), }); } diff --git a/starky2/src/prover.rs b/starky2/src/prover.rs index 0f5013a4..ebebd915 100644 --- a/starky2/src/prover.rs +++ b/starky2/src/prover.rs @@ -21,9 +21,7 @@ use rayon::prelude::*; 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, CrossTableLookup, LookupData, -}; +use crate::cross_table_lookup::{cross_table_lookup_zs, CTLCheckVars, LookupData}; use crate::permutation::{ compute_permutation_z_polys, get_n_permutation_challenge_sets, PermutationChallengeSet, }; diff --git a/starky2/src/verifier.rs b/starky2/src/verifier.rs index b5f144fb..6e60e601 100644 --- a/starky2/src/verifier.rs +++ b/starky2/src/verifier.rs @@ -12,6 +12,7 @@ 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::cross_table_lookup::verify_cross_table_lookups; use crate::permutation::PermutationCheckVars; use crate::proof::{ AllProof, AllProofChallenges, StarkOpeningSet, StarkProofChallenges, StarkProofWithPublicInputs, @@ -35,16 +36,22 @@ where ctl_challenges, } = all_proof.get_challenges(&all_stark, config); - // Verify CTL + let AllStark { + cpu_stark, + keccak_stark, + cross_table_lookups, + } = all_stark; - verify_stark_proof_with_challenges( - all_stark.cpu_stark, - all_proof.cpu_proof, - cpu_challenges, + 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( - all_stark.keccak_stark, + keccak_stark, all_proof.keccak_proof, keccak_challenges, config,