From afe89a61f4f74f108046c5990fbbd4f903d5d178 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 7 Feb 2022 11:23:49 +0100 Subject: [PATCH 1/7] Add methods --- plonky2/src/fri/challenges.rs | 54 ++++++++++++++++++++++- plonky2/src/fri/proof.rs | 7 +++ plonky2/src/plonk/get_challenges.rs | 68 ++++++++++++++++++++++++++--- plonky2/src/plonk/proof.rs | 12 ++++- plonky2/src/plonk/verifier.rs | 6 +-- 5 files changed, 136 insertions(+), 11 deletions(-) diff --git a/plonky2/src/fri/challenges.rs b/plonky2/src/fri/challenges.rs index ad1cfa5c..82438383 100644 --- a/plonky2/src/fri/challenges.rs +++ b/plonky2/src/fri/challenges.rs @@ -1,12 +1,16 @@ use plonky2_field::extension_field::Extendable; use plonky2_field::polynomial::PolynomialCoeffs; -use crate::fri::proof::FriChallenges; +use crate::fri::proof::{FriChallenges, FriChallengesTarget}; use crate::fri::structure::{FriOpenings, FriOpeningsTarget}; use crate::fri::FriConfig; -use crate::hash::hash_types::RichField; +use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; +use crate::hash::hash_types::{MerkleCapTarget, RichField}; use crate::hash::merkle_tree::MerkleCap; use crate::iop::challenger::{Challenger, RecursiveChallenger}; +use crate::iop::target::Target; +use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; impl> Challenger { @@ -78,4 +82,50 @@ impl, H: AlgebraicHasher, const D: usize> self.observe_extension_elements(&v.values); } } + + pub fn fri_challenges>( + &mut self, + builder: &mut CircuitBuilder, + commit_phase_merkle_caps: &[MerkleCapTarget], + final_poly: &PolynomialCoeffsExtTarget, + pow_witness: Target, + inner_common_data: &CommonCircuitData, + ) -> FriChallengesTarget { + let num_fri_queries = inner_common_data.config.fri_config.num_query_rounds; + // Scaling factor to combine polynomials. + let fri_alpha = self.get_extension_challenge(builder); + + // Recover the random betas used in the FRI reductions. + let fri_betas = commit_phase_merkle_caps + .iter() + .map(|cap| { + self.observe_cap(cap); + self.get_extension_challenge(builder) + }) + .collect(); + + self.observe_extension_elements(&final_poly.0); + + let pow_inputs = self + .get_hash(builder) + .elements + .iter() + .copied() + .chain(Some(pow_witness)) + .collect(); + let fri_pow_response = builder + .hash_n_to_hash_no_pad::(pow_inputs) + .elements[0]; + + let fri_query_indices = (0..num_fri_queries) + .map(|_| self.get_challenge(builder)) + .collect(); + + FriChallengesTarget { + fri_alpha, + fri_betas, + fri_pow_response, + fri_query_indices, + } + } } diff --git a/plonky2/src/fri/proof.rs b/plonky2/src/fri/proof.rs index 1f9e6b16..44f74cba 100644 --- a/plonky2/src/fri/proof.rs +++ b/plonky2/src/fri/proof.rs @@ -375,3 +375,10 @@ pub struct FriChallenges, const D: usize> { // Indices at which the oracle is queried in FRI. pub fri_query_indices: Vec, } + +pub struct FriChallengesTarget { + pub fri_alpha: ExtensionTarget, + pub fri_betas: Vec>, + pub fri_pow_response: Target, + pub fri_query_indices: Vec, +} diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index fb1517e4..59701a55 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -5,14 +5,17 @@ use plonky2_field::polynomial::PolynomialCoeffs; use crate::fri::proof::{CompressedFriProof, FriChallenges, FriProof}; use crate::fri::verifier::{compute_evaluation, fri_combine_initial, PrecomputedReducedOpenings}; -use crate::hash::hash_types::RichField; +use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; +use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_tree::MerkleCap; -use crate::iop::challenger::Challenger; +use crate::iop::challenger::{Challenger, RecursiveChallenger}; +use crate::iop::target::Target; +use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CommonCircuitData; -use crate::plonk::config::{GenericConfig, Hasher}; +use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; use crate::plonk::proof::{ - CompressedProof, CompressedProofWithPublicInputs, FriInferredElements, OpeningSet, Proof, - ProofChallenges, ProofWithPublicInputs, + CompressedProof, CompressedProofWithPublicInputs, FriInferredElements, OpeningSet, + OpeningSetTarget, Proof, ProofChallenges, ProofChallengesTarget, ProofWithPublicInputs, }; use crate::util::reverse_bits; @@ -219,3 +222,58 @@ impl, C: GenericConfig, const D: usize> FriInferredElements(fri_inferred_elements) } } + +impl, const D: usize> CircuitBuilder { + pub(crate) fn get_challenges>( + &mut self, + public_inputs_hash: HashOutTarget, + wires_cap: &MerkleCapTarget, + plonk_zs_partial_products_cap: &MerkleCapTarget, + quotient_polys_cap: &MerkleCapTarget, + openings: &OpeningSetTarget, + commit_phase_merkle_caps: &[MerkleCapTarget], + final_poly: &PolynomialCoeffsExtTarget, + pow_witness: Target, + inner_common_data: &CommonCircuitData, + ) -> ProofChallengesTarget + where + C::Hasher: AlgebraicHasher, + { + let config = &inner_common_data.config; + let num_challenges = config.num_challenges; + + let mut challenger = RecursiveChallenger::::new(self); + + // Observe the instance. + let digest = + HashOutTarget::from_vec(self.constants(&inner_common_data.circuit_digest.elements)); + challenger.observe_hash(&digest); + challenger.observe_hash(&public_inputs_hash); + + challenger.observe_cap(wires_cap); + let plonk_betas = challenger.get_n_challenges(self, num_challenges); + let plonk_gammas = challenger.get_n_challenges(self, num_challenges); + + challenger.observe_cap(plonk_zs_partial_products_cap); + let plonk_alphas = challenger.get_n_challenges(self, num_challenges); + + challenger.observe_cap(quotient_polys_cap); + let plonk_zeta = challenger.get_extension_challenge(self); + + challenger.observe_openings(&openings.to_fri_openings()); + + ProofChallengesTarget { + plonk_betas, + plonk_gammas, + plonk_alphas, + plonk_zeta, + fri_challenges: challenger.fri_challenges::( + self, + commit_phase_merkle_caps, + final_poly, + pow_witness, + inner_common_data, + ), + } + } +} diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index 2cf0a885..a9bb1210 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -3,7 +3,9 @@ use rayon::prelude::*; use serde::{Deserialize, Serialize}; use crate::fri::oracle::PolynomialBatch; -use crate::fri::proof::{CompressedFriProof, FriChallenges, FriProof, FriProofTarget}; +use crate::fri::proof::{ + CompressedFriProof, FriChallenges, FriChallengesTarget, FriProof, FriProofTarget, +}; use crate::fri::structure::{ FriOpeningBatch, FriOpeningBatchTarget, FriOpenings, FriOpeningsTarget, }; @@ -242,6 +244,14 @@ pub(crate) struct ProofChallenges, const D: usize> pub fri_challenges: FriChallenges, } +pub(crate) struct ProofChallengesTarget { + pub plonk_betas: Vec, + pub plonk_gammas: Vec, + pub plonk_alphas: Vec, + pub plonk_zeta: ExtensionTarget, + pub fri_challenges: FriChallengesTarget, +} + /// Coset elements that can be inferred in the FRI reduction steps. pub(crate) struct FriInferredElements, const D: usize>( pub Vec, diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index 46d41bfe..da5c9718 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -30,9 +30,9 @@ pub(crate) fn verify_with_challenges< verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, ) -> Result<()> { - assert_eq!( - proof_with_pis.public_inputs.len(), - common_data.num_public_inputs + ensure!( + proof_with_pis.public_inputs.len() == common_data.num_public_inputs, + "Number of public inputs doesn't match circuit data." ); let public_inputs_hash = &proof_with_pis.get_public_inputs_hash(); From 61fcc9048e6a78c0863c975b795e50b5e02f1985 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 7 Feb 2022 11:47:58 +0100 Subject: [PATCH 2/7] Working --- plonky2/src/fri/recursive_verifier.rs | 59 ++++++-------------- plonky2/src/plonk/get_challenges.rs | 46 +++++++++++++++- plonky2/src/plonk/recursive_verifier.rs | 71 +++++++++---------------- 3 files changed, 87 insertions(+), 89 deletions(-) diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index 65e6e024..a07d0137 100644 --- a/plonky2/src/fri/recursive_verifier.rs +++ b/plonky2/src/fri/recursive_verifier.rs @@ -3,9 +3,12 @@ use plonky2_field::extension_field::Extendable; use plonky2_util::{log2_strict, reverse_index_bits_in_place}; use crate::fri::proof::{ - FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, + FriChallengesTarget, FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, + FriQueryStepTarget, +}; +use crate::fri::structure::{ + FriBatchInfoTarget, FriInstanceInfoTarget, FriOpenings, FriOpeningsTarget, }; -use crate::fri::structure::{FriBatchInfoTarget, FriInstanceInfoTarget, FriOpeningsTarget}; use crate::fri::{FriConfig, FriParams}; use crate::gadgets::interpolation::InterpolationGate; use crate::gates::gate::Gate; @@ -107,16 +110,11 @@ impl, const D: usize> CircuitBuilder { fn fri_verify_proof_of_work>( &mut self, - proof: &FriProofTarget, - challenger: &mut RecursiveChallenger, + fri_pow_response: Target, config: &FriConfig, ) { - let mut inputs = challenger.get_hash(self).elements.to_vec(); - inputs.push(proof.pow_witness); - - let hash = self.hash_n_to_m_no_pad::(inputs, 1)[0]; self.assert_leading_zeros( - hash, + fri_pow_response, config.proof_of_work_bits + (64 - F::order().bits()) as u32, ); } @@ -124,11 +122,10 @@ impl, const D: usize> CircuitBuilder { pub fn verify_fri_proof>( &mut self, instance: &FriInstanceInfoTarget, - // Openings of the PLONK polynomials. - os: &OpeningSetTarget, + os: &FriOpeningsTarget, + challenges: &FriChallengesTarget, initial_merkle_caps: &[MerkleCapTarget], proof: &FriProofTarget, - challenger: &mut RecursiveChallenger, params: &FriParams, ) where C::Hasher: AlgebraicHasher, @@ -146,29 +143,10 @@ impl, const D: usize> CircuitBuilder { // Size of the LDE domain. let n = params.lde_size(); - challenger.observe_openings(&os.to_fri_openings()); - - // Scaling factor to combine polynomials. - let alpha = challenger.get_extension_challenge(self); - - let betas = with_context!( - self, - "recover the random betas used in the FRI reductions.", - proof - .commit_phase_merkle_caps - .iter() - .map(|cap| { - challenger.observe_cap(cap); - challenger.get_extension_challenge(self) - }) - .collect::>() - ); - challenger.observe_extension_elements(&proof.final_poly.0); - with_context!( self, "check PoW", - self.fri_verify_proof_of_work::(proof, challenger, ¶ms.config) + self.fri_verify_proof_of_work::(challenges.fri_pow_response, ¶ms.config) ); // Check that parameters are coherent. @@ -181,7 +159,7 @@ impl, const D: usize> CircuitBuilder { let precomputed_reduced_evals = with_context!( self, "precompute reduced evaluations", - PrecomputedReducedOpeningsTarget::from_os_and_alpha(&os.to_fri_openings(), alpha, self) + PrecomputedReducedOpeningsTarget::from_os_and_alpha(os, challenges.fri_alpha, self) ); for (i, round_proof) in proof.query_round_proofs.iter().enumerate() { @@ -201,13 +179,12 @@ impl, const D: usize> CircuitBuilder { &format!("verify one (of {}) query rounds", num_queries), self.fri_verifier_query_round::( instance, - alpha, + challenges, &precomputed_reduced_evals, initial_merkle_caps, proof, - challenger, + challenges.fri_query_indices[i], n, - &betas, round_proof, params, ) @@ -291,13 +268,12 @@ impl, const D: usize> CircuitBuilder { fn fri_verifier_query_round>( &mut self, instance: &FriInstanceInfoTarget, - alpha: ExtensionTarget, + challenges: &FriChallengesTarget, precomputed_reduced_evals: &PrecomputedReducedOpeningsTarget, initial_merkle_caps: &[MerkleCapTarget], proof: &FriProofTarget, - challenger: &mut RecursiveChallenger, + x_index: Target, n: usize, - betas: &[ExtensionTarget], round_proof: &FriQueryRoundTarget, params: &FriParams, ) where @@ -308,7 +284,6 @@ impl, const D: usize> CircuitBuilder { // Note that this `low_bits` decomposition permits non-canonical binary encodings. Here we // verify that this has a negligible impact on soundness error. Self::assert_noncanonical_indices_ok(¶ms.config); - let x_index = challenger.get_challenge(self); let mut x_index_bits = self.low_bits(x_index, n_log, F::BITS); let cap_index = @@ -341,7 +316,7 @@ impl, const D: usize> CircuitBuilder { self.fri_combine_initial::( instance, &round_proof.initial_trees_proof, - alpha, + challenges.fri_alpha, subgroup_x, precomputed_reduced_evals, params, @@ -368,7 +343,7 @@ impl, const D: usize> CircuitBuilder { x_index_within_coset_bits, arity_bits, evals, - betas[i], + challenges.fri_betas[i], ) ); diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index 59701a55..507123bf 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use plonky2_field::extension_field::Extendable; use plonky2_field::polynomial::PolynomialCoeffs; -use crate::fri::proof::{CompressedFriProof, FriChallenges, FriProof}; +use crate::fri::proof::{CompressedFriProof, FriChallenges, FriProof, FriProofTarget}; use crate::fri::verifier::{compute_evaluation, fri_combine_initial, PrecomputedReducedOpenings}; use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; @@ -15,7 +15,8 @@ use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; use crate::plonk::proof::{ CompressedProof, CompressedProofWithPublicInputs, FriInferredElements, OpeningSet, - OpeningSetTarget, Proof, ProofChallenges, ProofChallengesTarget, ProofWithPublicInputs, + OpeningSetTarget, Proof, ProofChallenges, ProofChallengesTarget, ProofTarget, + ProofWithPublicInputs, ProofWithPublicInputsTarget, }; use crate::util::reverse_bits; @@ -277,3 +278,44 @@ impl, const D: usize> CircuitBuilder { } } } + +impl ProofWithPublicInputsTarget { + pub(crate) fn get_challenges, C: GenericConfig>( + &self, + builder: &mut CircuitBuilder, + public_inputs_hash: HashOutTarget, + inner_common_data: &CommonCircuitData, + ) -> ProofChallengesTarget + where + C::Hasher: AlgebraicHasher, + { + let ProofTarget { + wires_cap, + plonk_zs_partial_products_cap, + quotient_polys_cap, + openings, + opening_proof: + FriProofTarget { + commit_phase_merkle_caps, + final_poly, + pow_witness, + .. + }, + } = &self.proof; + + let public_inputs_hash = + builder.hash_n_to_hash_no_pad::(self.public_inputs.clone()); + + builder.get_challenges( + public_inputs_hash, + wires_cap, + plonk_zs_partial_products_cap, + quotient_polys_cap, + openings, + commit_phase_merkle_caps, + final_poly, + *pow_witness, + inner_common_data, + ) + } +} diff --git a/plonky2/src/plonk/recursive_verifier.rs b/plonky2/src/plonk/recursive_verifier.rs index cb2bc1e0..57ff3dd7 100644 --- a/plonky2/src/plonk/recursive_verifier.rs +++ b/plonky2/src/plonk/recursive_verifier.rs @@ -5,7 +5,9 @@ use crate::iop::challenger::RecursiveChallenger; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{CommonCircuitData, VerifierCircuitTarget}; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; -use crate::plonk::proof::{OpeningSetTarget, ProofTarget, ProofWithPublicInputsTarget}; +use crate::plonk::proof::{ + OpeningSetTarget, ProofChallengesTarget, ProofTarget, ProofWithPublicInputsTarget, +}; use crate::plonk::vanishing_poly::eval_vanishing_poly_recursively; use crate::plonk::vars::EvaluationTargets; use crate::util::reducing::ReducingFactorTarget; @@ -13,7 +15,7 @@ use crate::with_context; impl, const D: usize> CircuitBuilder { /// Recursively verifies an inner proof. - pub fn verify_proof_with_pis>( + pub fn verify_proof>( &mut self, proof_with_pis: ProofWithPublicInputsTarget, inner_verifier_data: &VerifierCircuitTarget, @@ -21,27 +23,29 @@ impl, const D: usize> CircuitBuilder { ) where C::Hasher: AlgebraicHasher, { - let ProofWithPublicInputsTarget { - proof, - public_inputs, - } = proof_with_pis; + assert_eq!( + proof_with_pis.public_inputs.len(), + inner_common_data.num_public_inputs + ); + let public_inputs_hash = + self.hash_n_to_hash_no_pad::(proof_with_pis.public_inputs.clone()); + let challenges = proof_with_pis.get_challenges(self, public_inputs_hash, inner_common_data); - assert_eq!(public_inputs.len(), inner_common_data.num_public_inputs); - let public_inputs_hash = self.hash_n_to_hash_no_pad::(public_inputs); - - self.verify_proof( - proof, + self.verify_proof_with_challenges( + proof_with_pis.proof, public_inputs_hash, + challenges, inner_verifier_data, inner_common_data, ); } /// Recursively verifies an inner proof. - pub fn verify_proof>( + fn verify_proof_with_challenges>( &mut self, proof: ProofTarget, public_inputs_hash: HashOutTarget, + challenges: ProofChallengesTarget, inner_verifier_data: &VerifierCircuitTarget, inner_common_data: &CommonCircuitData, ) where @@ -51,30 +55,6 @@ impl, const D: usize> CircuitBuilder { let num_challenges = inner_common_data.config.num_challenges; - let mut challenger = RecursiveChallenger::::new(self); - - let (betas, gammas, alphas, zeta) = - with_context!(self, "observe proof and generates challenges", { - // Observe the instance. - let digest = HashOutTarget::from_vec( - self.constants(&inner_common_data.circuit_digest.elements), - ); - challenger.observe_hash(&digest); - challenger.observe_hash(&public_inputs_hash); - - challenger.observe_cap(&proof.wires_cap); - let betas = challenger.get_n_challenges(self, num_challenges); - let gammas = challenger.get_n_challenges(self, num_challenges); - - challenger.observe_cap(&proof.plonk_zs_partial_products_cap); - let alphas = challenger.get_n_challenges(self, num_challenges); - - challenger.observe_cap(&proof.quotient_polys_cap); - let zeta = challenger.get_extension_challenge(self); - - (betas, gammas, alphas, zeta) - }); - let local_constants = &proof.openings.constants; let local_wires = &proof.openings.wires; let vars = EvaluationTargets { @@ -87,23 +67,24 @@ impl, const D: usize> CircuitBuilder { let s_sigmas = &proof.openings.plonk_sigmas; let partial_products = &proof.openings.partial_products; - let zeta_pow_deg = self.exp_power_of_2_extension(zeta, inner_common_data.degree_bits); + let zeta_pow_deg = + self.exp_power_of_2_extension(challenges.plonk_zeta, inner_common_data.degree_bits); let vanishing_polys_zeta = with_context!( self, "evaluate the vanishing polynomial at our challenge point, zeta.", eval_vanishing_poly_recursively( self, inner_common_data, - zeta, + challenges.plonk_zeta, zeta_pow_deg, vars, local_zs, next_zs, partial_products, s_sigmas, - &betas, - &gammas, - &alphas, + &challenges.plonk_betas, + &challenges.plonk_gammas, + &challenges.plonk_alphas, ) ); @@ -128,16 +109,16 @@ impl, const D: usize> CircuitBuilder { proof.quotient_polys_cap, ]; - let fri_instance = inner_common_data.get_fri_instance_target(self, zeta); + let fri_instance = inner_common_data.get_fri_instance_target(self, challenges.plonk_zeta); with_context!( self, "verify FRI proof", self.verify_fri_proof::( &fri_instance, - &proof.openings, + &proof.openings.to_fri_openings(), + &challenges.fri_challenges, merkle_caps, &proof.opening_proof, - &mut challenger, &inner_common_data.fri_params, ) ); @@ -392,7 +373,7 @@ mod tests { &inner_vd.constants_sigmas_cap, ); - builder.verify_proof_with_pis(pt, &inner_data, &inner_cd); + builder.verify_proof(pt, &inner_data, &inner_cd); if print_gate_counts { builder.print_gate_counts(0); From d7bdc75082c935c79263cdbaabea6ca9a67b9ae7 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 7 Feb 2022 11:56:16 +0100 Subject: [PATCH 3/7] Further cleaning --- plonky2/src/plonk/get_challenges.rs | 11 +++++----- plonky2/src/plonk/proof.rs | 11 +++++----- plonky2/src/plonk/verifier.rs | 32 ++++++++++++++++------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index 507123bf..dd6dbb5a 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -75,7 +75,7 @@ impl, C: GenericConfig, const D: usize> common_data: &CommonCircuitData, ) -> anyhow::Result> { Ok(self - .get_challenges(common_data)? + .get_challenges(self.get_public_inputs_hash(), common_data)? .fri_challenges .fri_query_indices) } @@ -83,6 +83,7 @@ impl, C: GenericConfig, const D: usize> /// Computes all Fiat-Shamir challenges used in the Plonk proof. pub(crate) fn get_challenges( &self, + public_inputs_hash: <>::InnerHasher as Hasher>::Hash, common_data: &CommonCircuitData, ) -> anyhow::Result> { let Proof { @@ -100,7 +101,7 @@ impl, C: GenericConfig, const D: usize> } = &self.proof; get_challenges( - self.get_public_inputs_hash(), + public_inputs_hash, wires_cap, plonk_zs_partial_products_cap, quotient_polys_cap, @@ -119,6 +120,7 @@ impl, C: GenericConfig, const D: usize> /// Computes all Fiat-Shamir challenges used in the Plonk proof. pub(crate) fn get_challenges( &self, + public_inputs_hash: <>::InnerHasher as Hasher>::Hash, common_data: &CommonCircuitData, ) -> anyhow::Result> { let CompressedProof { @@ -136,7 +138,7 @@ impl, C: GenericConfig, const D: usize> } = &self.proof; get_challenges( - self.get_public_inputs_hash(), + public_inputs_hash, wires_cap, plonk_zs_partial_products_cap, quotient_polys_cap, @@ -303,9 +305,6 @@ impl ProofWithPublicInputsTarget { }, } = &self.proof; - let public_inputs_hash = - builder.hash_n_to_hash_no_pad::(self.public_inputs.clone()); - builder.get_challenges( public_inputs_hash, wires_cap, diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index a9bb1210..9fc4d3f6 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -174,7 +174,7 @@ impl, C: GenericConfig, const D: usize> self, common_data: &CommonCircuitData, ) -> anyhow::Result> { - let challenges = self.get_challenges(common_data)?; + let challenges = self.get_challenges(self.get_public_inputs_hash(), common_data)?; let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data); let decompressed_proof = self.proof @@ -190,16 +190,15 @@ impl, C: GenericConfig, const D: usize> verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, ) -> anyhow::Result<()> { - let challenges = self.get_challenges(common_data)?; + let public_inputs_hash = self.get_public_inputs_hash(); + let challenges = self.get_challenges(public_inputs_hash, common_data)?; let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data); let decompressed_proof = self.proof .decompress(&challenges, fri_inferred_elements, &common_data.fri_params); verify_with_challenges( - ProofWithPublicInputs { - public_inputs: self.public_inputs, - proof: decompressed_proof, - }, + decompressed_proof, + public_inputs_hash, challenges, verifier_data, common_data, diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index da5c9718..1f5a18d2 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -5,9 +5,9 @@ use plonky2_field::field_types::Field; use crate::fri::verifier::verify_fri_proof; use crate::hash::hash_types::RichField; use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData}; -use crate::plonk::config::GenericConfig; +use crate::plonk::config::{GenericConfig, Hasher}; use crate::plonk::plonk_common::reduce_with_powers; -use crate::plonk::proof::{ProofChallenges, ProofWithPublicInputs}; +use crate::plonk::proof::{Proof, ProofChallenges, ProofWithPublicInputs}; use crate::plonk::vanishing_poly::eval_vanishing_poly; use crate::plonk::vars::EvaluationVars; @@ -16,8 +16,19 @@ pub(crate) fn verify, C: GenericConfig, c verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, ) -> Result<()> { - let challenges = proof_with_pis.get_challenges(common_data)?; - verify_with_challenges(proof_with_pis, challenges, verifier_data, common_data) + ensure!( + proof_with_pis.public_inputs.len() == common_data.num_public_inputs, + "Number of public inputs doesn't match circuit data." + ); + let public_inputs_hash = proof_with_pis.get_public_inputs_hash(); + let challenges = proof_with_pis.get_challenges(public_inputs_hash, common_data)?; + verify_with_challenges( + proof_with_pis.proof, + public_inputs_hash, + challenges, + verifier_data, + common_data, + ) } pub(crate) fn verify_with_challenges< @@ -25,25 +36,18 @@ pub(crate) fn verify_with_challenges< C: GenericConfig, const D: usize, >( - proof_with_pis: ProofWithPublicInputs, + proof: Proof, + public_inputs_hash: <>::InnerHasher as Hasher>::Hash, challenges: ProofChallenges, verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, ) -> Result<()> { - ensure!( - proof_with_pis.public_inputs.len() == common_data.num_public_inputs, - "Number of public inputs doesn't match circuit data." - ); - let public_inputs_hash = &proof_with_pis.get_public_inputs_hash(); - - let ProofWithPublicInputs { proof, .. } = proof_with_pis; - let local_constants = &proof.openings.constants; let local_wires = &proof.openings.wires; let vars = EvaluationVars { local_constants, local_wires, - public_inputs_hash, + public_inputs_hash: &public_inputs_hash, }; let local_zs = &proof.openings.plonk_zs; let next_zs = &proof.openings.plonk_zs_right; From f39352896fc4b40ab46a3ca724ffe9c3c5c44cc9 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 7 Feb 2022 12:02:37 +0100 Subject: [PATCH 4/7] Unused --- plonky2/src/fri/recursive_verifier.rs | 6 +----- plonky2/src/plonk/proof.rs | 5 +++++ plonky2/src/plonk/recursive_verifier.rs | 3 --- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index a07d0137..221cb928 100644 --- a/plonky2/src/fri/recursive_verifier.rs +++ b/plonky2/src/fri/recursive_verifier.rs @@ -6,9 +6,7 @@ use crate::fri::proof::{ FriChallengesTarget, FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, }; -use crate::fri::structure::{ - FriBatchInfoTarget, FriInstanceInfoTarget, FriOpenings, FriOpeningsTarget, -}; +use crate::fri::structure::{FriBatchInfoTarget, FriInstanceInfoTarget, FriOpeningsTarget}; use crate::fri::{FriConfig, FriParams}; use crate::gadgets::interpolation::InterpolationGate; use crate::gates::gate::Gate; @@ -17,12 +15,10 @@ use crate::gates::low_degree_interpolation::LowDegreeInterpolationGate; use crate::gates::random_access::RandomAccessGate; use crate::hash::hash_types::MerkleCapTarget; use crate::hash::hash_types::RichField; -use crate::iop::challenger::RecursiveChallenger; use crate::iop::ext_target::{flatten_target, ExtensionTarget}; use crate::iop::target::{BoolTarget, Target}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; -use crate::plonk::proof::OpeningSetTarget; use crate::util::reducing::ReducingFactorTarget; use crate::with_context; diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index 9fc4d3f6..3de608d4 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -1,3 +1,4 @@ +use anyhow::ensure; use plonky2_field::extension_field::Extendable; use rayon::prelude::*; use serde::{Deserialize, Serialize}; @@ -190,6 +191,10 @@ impl, C: GenericConfig, const D: usize> verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, ) -> anyhow::Result<()> { + ensure!( + self.public_inputs.len() == common_data.num_public_inputs, + "Number of public inputs doesn't match circuit data." + ); let public_inputs_hash = self.get_public_inputs_hash(); let challenges = self.get_challenges(public_inputs_hash, common_data)?; let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data); diff --git a/plonky2/src/plonk/recursive_verifier.rs b/plonky2/src/plonk/recursive_verifier.rs index 57ff3dd7..dfa415f4 100644 --- a/plonky2/src/plonk/recursive_verifier.rs +++ b/plonky2/src/plonk/recursive_verifier.rs @@ -1,7 +1,6 @@ use plonky2_field::extension_field::Extendable; use crate::hash::hash_types::{HashOutTarget, RichField}; -use crate::iop::challenger::RecursiveChallenger; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{CommonCircuitData, VerifierCircuitTarget}; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; @@ -53,8 +52,6 @@ impl, const D: usize> CircuitBuilder { { let one = self.one_extension(); - let num_challenges = inner_common_data.config.num_challenges; - let local_constants = &proof.openings.constants; let local_wires = &proof.openings.wires; let vars = EvaluationTargets { From 02746d8a0f8659de1e6a36533298ddaf060b80e4 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 7 Feb 2022 12:03:52 +0100 Subject: [PATCH 5/7] Minor --- plonky2/src/plonk/verifier.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index 1f5a18d2..5d69dcb1 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -22,6 +22,7 @@ pub(crate) fn verify, C: GenericConfig, c ); let public_inputs_hash = proof_with_pis.get_public_inputs_hash(); let challenges = proof_with_pis.get_challenges(public_inputs_hash, common_data)?; + verify_with_challenges( proof_with_pis.proof, public_inputs_hash, From 415da246a53c0c005849085aea79eac0468f1508 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 7 Feb 2022 12:10:14 +0100 Subject: [PATCH 6/7] Naming --- plonky2/src/fri/recursive_verifier.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index 221cb928..f51b8fe6 100644 --- a/plonky2/src/fri/recursive_verifier.rs +++ b/plonky2/src/fri/recursive_verifier.rs @@ -118,7 +118,7 @@ impl, const D: usize> CircuitBuilder { pub fn verify_fri_proof>( &mut self, instance: &FriInstanceInfoTarget, - os: &FriOpeningsTarget, + openings: &FriOpeningsTarget, challenges: &FriChallengesTarget, initial_merkle_caps: &[MerkleCapTarget], proof: &FriProofTarget, @@ -155,7 +155,11 @@ impl, const D: usize> CircuitBuilder { let precomputed_reduced_evals = with_context!( self, "precompute reduced evaluations", - PrecomputedReducedOpeningsTarget::from_os_and_alpha(os, challenges.fri_alpha, self) + PrecomputedReducedOpeningsTarget::from_os_and_alpha( + openings, + challenges.fri_alpha, + self + ) ); for (i, round_proof) in proof.query_round_proofs.iter().enumerate() { From 0cc776922a60886e2761bca77ab59c055a55e61a Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 7 Feb 2022 22:11:37 +0100 Subject: [PATCH 7/7] Make `get_challenges` private. --- plonky2/src/plonk/get_challenges.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index dd6dbb5a..a67a6207 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -227,7 +227,7 @@ impl, C: GenericConfig, const D: usize> } impl, const D: usize> CircuitBuilder { - pub(crate) fn get_challenges>( + fn get_challenges>( &mut self, public_inputs_hash: HashOutTarget, wires_cap: &MerkleCapTarget,