diff --git a/plonky2/src/fri/proof.rs b/plonky2/src/fri/proof.rs index ff81c2c5..f96db781 100644 --- a/plonky2/src/fri/proof.rs +++ b/plonky2/src/fri/proof.rs @@ -26,7 +26,7 @@ pub struct FriQueryStep, H: Hasher, const D: usi pub merkle_proof: MerkleProof, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct FriQueryStepTarget { pub evals: Vec>, pub merkle_proof: MerkleProofTarget, @@ -51,7 +51,7 @@ impl> FriInitialTreeProof { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct FriInitialTreeProofTarget { pub evals_proofs: Vec<(Vec, MerkleProofTarget)>, } @@ -80,7 +80,7 @@ pub struct FriQueryRound, H: Hasher, const D: us pub steps: Vec>, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct FriQueryRoundTarget { pub initial_trees_proof: FriInitialTreeProofTarget, pub steps: Vec>, @@ -111,6 +111,7 @@ pub struct FriProof, H: Hasher, const D: usize> pub pow_witness: F, } +#[derive(Debug)] pub struct FriProofTarget { pub commit_phase_merkle_caps: Vec, pub query_round_proofs: Vec>, diff --git a/plonky2/src/fri/prover.rs b/plonky2/src/fri/prover.rs index d2731600..e814beae 100644 --- a/plonky2/src/fri/prover.rs +++ b/plonky2/src/fri/prover.rs @@ -72,9 +72,8 @@ fn fri_committed_trees, C: GenericConfig, let mut trees = Vec::new(); let mut shift = F::MULTIPLICATIVE_GROUP_GENERATOR; - let num_reductions = fri_params.reduction_arity_bits.len(); - for i in 0..num_reductions { - let arity = 1 << fri_params.reduction_arity_bits[i]; + for arity_bits in &fri_params.reduction_arity_bits { + let arity = 1 << arity_bits; reverse_index_bits_in_place(&mut values.values); let chunked_values = values diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index 63d07035..a9a224d1 100644 --- a/plonky2/src/fri/recursive_verifier.rs +++ b/plonky2/src/fri/recursive_verifier.rs @@ -2,7 +2,9 @@ use itertools::Itertools; use plonky2_field::extension_field::Extendable; use plonky2_util::{log2_strict, reverse_index_bits_in_place}; -use crate::fri::proof::{FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget}; +use crate::fri::proof::{ + FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, +}; use crate::fri::structure::{FriBatchInfoTarget, FriInstanceInfoTarget, FriOpeningsTarget}; use crate::fri::{FriConfig, FriParams}; use crate::gadgets::interpolation::InterpolationGate; @@ -420,6 +422,81 @@ impl, const D: usize> CircuitBuilder { assert!(p_ambiguous < query_error * 1e-5, "A non-negligible portion of field elements are in the range that permits non-canonical encodings. Need to do more analysis or enforce canonical encodings."); } + + pub(crate) fn add_virtual_fri_proof( + &mut self, + num_leaves_per_oracle: &[usize], + params: &FriParams, + ) -> FriProofTarget { + let cap_height = params.config.cap_height; + let num_queries = params.config.num_query_rounds; + let commit_phase_merkle_caps = (0..params.reduction_arity_bits.len()) + .map(|_| self.add_virtual_cap(cap_height)) + .collect(); + let query_round_proofs = (0..num_queries) + .map(|_| self.add_virtual_fri_query(num_leaves_per_oracle, params)) + .collect(); + let final_poly = self.add_virtual_poly_coeff_ext(params.final_poly_len()); + let pow_witness = self.add_virtual_target(); + FriProofTarget { + commit_phase_merkle_caps, + query_round_proofs, + final_poly, + pow_witness, + } + } + + fn add_virtual_fri_query( + &mut self, + num_leaves_per_oracle: &[usize], + params: &FriParams, + ) -> FriQueryRoundTarget { + let cap_height = params.config.cap_height; + assert!(params.lde_bits() >= cap_height); + let mut merkle_proof_len = params.lde_bits() - cap_height; + + let initial_trees_proof = + self.add_virtual_fri_initial_trees_proof(num_leaves_per_oracle, merkle_proof_len); + + let mut steps = vec![]; + for &arity_bits in ¶ms.reduction_arity_bits { + assert!(merkle_proof_len >= arity_bits); + merkle_proof_len -= arity_bits; + steps.push(self.add_virtual_fri_query_step(arity_bits, merkle_proof_len)); + } + + FriQueryRoundTarget { + initial_trees_proof, + steps, + } + } + + fn add_virtual_fri_initial_trees_proof( + &mut self, + num_leaves_per_oracle: &[usize], + initial_merkle_proof_len: usize, + ) -> FriInitialTreeProofTarget { + let evals_proofs = num_leaves_per_oracle + .iter() + .map(|&num_oracle_leaves| { + let leaves = self.add_virtual_targets(num_oracle_leaves); + let merkle_proof = self.add_virtual_merkle_proof(initial_merkle_proof_len); + (leaves, merkle_proof) + }) + .collect(); + FriInitialTreeProofTarget { evals_proofs } + } + + fn add_virtual_fri_query_step( + &mut self, + arity_bits: usize, + merkle_proof_len: usize, + ) -> FriQueryStepTarget { + FriQueryStepTarget { + evals: self.add_virtual_extension_targets(1 << arity_bits), + merkle_proof: self.add_virtual_merkle_proof(merkle_proof_len), + } + } } /// For each opening point, holds the reduced (by `alpha`) evaluations of each polynomial that's diff --git a/plonky2/src/gadgets/polynomial.rs b/plonky2/src/gadgets/polynomial.rs index 195eabd3..6e4a9bb4 100644 --- a/plonky2/src/gadgets/polynomial.rs +++ b/plonky2/src/gadgets/polynomial.rs @@ -6,6 +6,7 @@ use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::reducing::ReducingFactorTarget; +#[derive(Debug)] pub struct PolynomialCoeffsExtTarget(pub Vec>); impl PolynomialCoeffsExtTarget { diff --git a/plonky2/src/hash/merkle_proofs.rs b/plonky2/src/hash/merkle_proofs.rs index 60fe236a..c2f3655d 100644 --- a/plonky2/src/hash/merkle_proofs.rs +++ b/plonky2/src/hash/merkle_proofs.rs @@ -17,7 +17,7 @@ pub struct MerkleProof> { pub siblings: Vec, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct MerkleProofTarget { /// The Merkle digest of each sibling subtree, staying from the bottommost layer. pub siblings: Vec, diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 33b44054..e4abe611 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -15,6 +15,7 @@ use crate::fri::{FriConfig, FriParams}; use crate::gadgets::arithmetic::BaseArithmeticOperation; use crate::gadgets::arithmetic_extension::ExtensionArithmeticOperation; use crate::gadgets::arithmetic_u32::U32Target; +use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; use crate::gates::arithmetic_base::ArithmeticGate; use crate::gates::arithmetic_extension::ArithmeticExtensionGate; use crate::gates::arithmetic_u32::U32ArithmeticGate; @@ -28,6 +29,7 @@ use crate::gates::random_access::RandomAccessGate; use crate::gates::subtraction_u32::U32SubtractionGate; use crate::gates::switch::SwitchGate; use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; +use crate::hash::merkle_proofs::MerkleProofTarget; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::{ CopyGenerator, RandomValueGenerator, SimpleGenerator, WitnessGenerator, @@ -172,6 +174,12 @@ impl, const D: usize> CircuitBuilder { (0..n).map(|_i| self.add_virtual_hash()).collect() } + pub(crate) fn add_virtual_merkle_proof(&mut self, len: usize) -> MerkleProofTarget { + MerkleProofTarget { + siblings: self.add_virtual_hashes(len), + } + } + pub fn add_virtual_extension_target(&mut self) -> ExtensionTarget { ExtensionTarget(self.add_virtual_targets(D).try_into().unwrap()) } @@ -182,6 +190,14 @@ impl, const D: usize> CircuitBuilder { .collect() } + pub(crate) fn add_virtual_poly_coeff_ext( + &mut self, + num_coeffs: usize, + ) -> PolynomialCoeffsExtTarget { + let coeffs = self.add_virtual_extension_targets(num_coeffs); + PolynomialCoeffsExtTarget(coeffs) + } + // TODO: Unsafe pub fn add_virtual_bool_target(&mut self) -> BoolTarget { BoolTarget::new_unsafe(self.add_virtual_target()) @@ -596,6 +612,7 @@ impl, const D: usize> CircuitBuilder { // Hash the public inputs, and route them to a `PublicInputGate` which will enforce that // those hash wires match the claimed public inputs. + let num_public_inputs = self.public_inputs.len(); let public_inputs_hash = self.hash_n_to_hash::(self.public_inputs.clone(), true); let pi_gate = self.add_gate(PublicInputGate, vec![]); @@ -736,6 +753,7 @@ impl, const D: usize> CircuitBuilder { num_gate_constraints, num_constants, num_virtual_targets: self.virtual_target_index, + num_public_inputs, k_is, num_partial_products, circuit_digest, diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 35c37991..dd7ebc25 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -234,6 +234,8 @@ pub struct CommonCircuitData< pub(crate) num_virtual_targets: usize, + pub(crate) num_public_inputs: usize, + /// The `{k_i}` valued used in `S_ID_i` in Plonk's permutation argument. pub(crate) k_is: Vec, @@ -341,34 +343,42 @@ impl, C: GenericConfig, const D: usize> } fn fri_preprocessed_polys(&self) -> Vec { - let num_preprocessed_polys = self.sigmas_range().end; FriPolynomialInfo::from_range( PlonkOracle::CONSTANTS_SIGMAS.index, - 0..num_preprocessed_polys, + 0..self.num_preprocessed_polys(), ) } + pub(crate) fn num_preprocessed_polys(&self) -> usize { + self.sigmas_range().end + } + fn fri_wire_polys(&self) -> Vec { let num_wire_polys = self.config.num_wires; FriPolynomialInfo::from_range(PlonkOracle::WIRES.index, 0..num_wire_polys) } fn fri_zs_partial_products_polys(&self) -> Vec { - let num_zs_partial_products_polys = - self.config.num_challenges * (1 + self.num_partial_products); FriPolynomialInfo::from_range( PlonkOracle::ZS_PARTIAL_PRODUCTS.index, - 0..num_zs_partial_products_polys, + 0..self.num_zs_partial_products_polys(), ) } + pub(crate) fn num_zs_partial_products_polys(&self) -> usize { + self.config.num_challenges * (1 + self.num_partial_products) + } + fn fri_zs_polys(&self) -> Vec { FriPolynomialInfo::from_range(PlonkOracle::ZS_PARTIAL_PRODUCTS.index, self.zs_range()) } fn fri_quotient_polys(&self) -> Vec { - let num_quotient_polys = self.config.num_challenges * self.quotient_degree_factor; - FriPolynomialInfo::from_range(PlonkOracle::QUOTIENT.index, 0..num_quotient_polys) + FriPolynomialInfo::from_range(PlonkOracle::QUOTIENT.index, 0..self.num_quotient_polys()) + } + + pub(crate) fn num_quotient_polys(&self) -> usize { + self.config.num_challenges * self.quotient_degree_factor } fn fri_all_polys(&self) -> Vec { diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index 07ca7c9e..7fbdc671 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -32,6 +32,7 @@ pub struct Proof, C: GenericConfig, const pub opening_proof: FriProof, } +#[derive(Debug)] pub struct ProofTarget { pub wires_cap: MerkleCapTarget, pub plonk_zs_partial_products_cap: MerkleCapTarget, @@ -255,6 +256,7 @@ pub(crate) struct FriInferredElements, const D: usi pub Vec, ); +#[derive(Debug)] pub struct ProofWithPublicInputsTarget { pub proof: ProofTarget, pub public_inputs: Vec, diff --git a/plonky2/src/plonk/recursive_verifier.rs b/plonky2/src/plonk/recursive_verifier.rs index 38024eea..6b3b6b0c 100644 --- a/plonky2/src/plonk/recursive_verifier.rs +++ b/plonky2/src/plonk/recursive_verifier.rs @@ -5,7 +5,7 @@ use crate::iop::challenger::RecursiveChallenger; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData, VerifierCircuitTarget}; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; -use crate::plonk::proof::ProofWithPublicInputsTarget; +use crate::plonk::proof::{OpeningSetTarget, ProofTarget, ProofWithPublicInputsTarget}; use crate::plonk::vanishing_poly::eval_vanishing_poly_recursively; use crate::plonk::vars::EvaluationTargets; use crate::util::reducing::ReducingFactorTarget; @@ -13,7 +13,7 @@ use crate::with_context; impl, const D: usize> CircuitBuilder { /// Recursively verifies an inner proof. - pub fn add_recursive_verifier>( + pub fn verify_proof_with_pis>( &mut self, proof_with_pis: ProofWithPublicInputsTarget, inner_config: &CircuitConfig, @@ -26,12 +26,34 @@ impl, const D: usize> CircuitBuilder { proof, public_inputs, } = proof_with_pis; + + assert_eq!(public_inputs.len(), inner_common_data.num_public_inputs); + let public_inputs_hash = self.hash_n_to_hash::(public_inputs, true); + + self.verify_proof( + proof, + public_inputs_hash, + inner_config, + inner_verifier_data, + inner_common_data, + ); + } + + /// Recursively verifies an inner proof. + pub fn verify_proof>( + &mut self, + proof: ProofTarget, + public_inputs_hash: HashOutTarget, + inner_config: &CircuitConfig, + inner_verifier_data: &VerifierCircuitTarget, + inner_common_data: &CommonCircuitData, + ) where + C::Hasher: AlgebraicHasher, + { let one = self.one_extension(); let num_challenges = inner_config.num_challenges; - let public_inputs_hash = &self.hash_n_to_hash::(public_inputs, true); - let mut challenger = RecursiveChallenger::::new(self); let (betas, gammas, alphas, zeta) = @@ -41,7 +63,7 @@ impl, const D: usize> CircuitBuilder { self.constants(&inner_common_data.circuit_digest.elements), ); challenger.observe_hash(&digest); - challenger.observe_hash(public_inputs_hash); + challenger.observe_hash(&public_inputs_hash); challenger.observe_cap(&proof.wires_cap); let betas = challenger.get_n_challenges(self, num_challenges); @@ -61,7 +83,7 @@ impl, const D: usize> CircuitBuilder { let vars = EvaluationTargets { 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; @@ -123,137 +145,81 @@ impl, const D: usize> CircuitBuilder { ) ); } -} -#[cfg(test)] -mod tests { - use anyhow::Result; - use log::{info, Level}; - use plonky2_util::log2_strict; - - use super::*; - use crate::fri::proof::{ - FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, - }; - use crate::fri::reduction_strategies::FriReductionStrategy; - use crate::fri::FriConfig; - use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; - use crate::gates::noop::NoopGate; - use crate::hash::merkle_proofs::MerkleProofTarget; - use crate::iop::witness::{PartialWitness, Witness}; - use crate::plonk::circuit_data::VerifierOnlyCircuitData; - use crate::plonk::config::{ - GMiMCGoldilocksConfig, GenericConfig, KeccakGoldilocksConfig, PoseidonGoldilocksConfig, - }; - use crate::plonk::proof::{ - CompressedProofWithPublicInputs, OpeningSetTarget, Proof, ProofTarget, - ProofWithPublicInputs, - }; - use crate::plonk::prover::prove; - use crate::util::timing::TimingTree; - - // Construct a `FriQueryRoundTarget` with the same dimensions as the ones in `proof`. - fn get_fri_query_round< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - proof: &Proof, - builder: &mut CircuitBuilder, - ) -> FriQueryRoundTarget { - let mut query_round = FriQueryRoundTarget { - initial_trees_proof: FriInitialTreeProofTarget { - evals_proofs: vec![], - }, - steps: vec![], - }; - for (v, merkle_proof) in &proof.opening_proof.query_round_proofs[0] - .initial_trees_proof - .evals_proofs - { - query_round.initial_trees_proof.evals_proofs.push(( - builder.add_virtual_targets(v.len()), - MerkleProofTarget { - siblings: builder.add_virtual_hashes(merkle_proof.siblings.len()), - }, - )); - } - for step in &proof.opening_proof.query_round_proofs[0].steps { - query_round.steps.push(FriQueryStepTarget { - evals: builder.add_virtual_extension_targets(step.evals.len()), - merkle_proof: MerkleProofTarget { - siblings: builder.add_virtual_hashes(step.merkle_proof.siblings.len()), - }, - }); - } - query_round - } - - // Construct a `ProofTarget` with the same dimensions as `proof`. - fn proof_to_proof_target< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - proof_with_pis: &ProofWithPublicInputs, - builder: &mut CircuitBuilder, + pub fn add_virtual_proof_with_pis>( + &mut self, + common_data: &CommonCircuitData, ) -> ProofWithPublicInputsTarget { - let ProofWithPublicInputs { - proof, - public_inputs, - } = proof_with_pis; - - let wires_cap = builder.add_virtual_cap(log2_strict(proof.wires_cap.0.len())); - let plonk_zs_cap = - builder.add_virtual_cap(log2_strict(proof.plonk_zs_partial_products_cap.0.len())); - let quotient_polys_cap = - builder.add_virtual_cap(log2_strict(proof.quotient_polys_cap.0.len())); - - let openings = OpeningSetTarget { - constants: builder.add_virtual_extension_targets(proof.openings.constants.len()), - plonk_sigmas: builder.add_virtual_extension_targets(proof.openings.plonk_sigmas.len()), - wires: builder.add_virtual_extension_targets(proof.openings.wires.len()), - plonk_zs: builder.add_virtual_extension_targets(proof.openings.plonk_zs.len()), - plonk_zs_right: builder - .add_virtual_extension_targets(proof.openings.plonk_zs_right.len()), - partial_products: builder - .add_virtual_extension_targets(proof.openings.partial_products.len()), - quotient_polys: builder - .add_virtual_extension_targets(proof.openings.quotient_polys.len()), - }; - let query_round_proofs = (0..proof.opening_proof.query_round_proofs.len()) - .map(|_| get_fri_query_round(proof, builder)) - .collect(); - let commit_phase_merkle_caps = proof - .opening_proof - .commit_phase_merkle_caps - .iter() - .map(|r| builder.add_virtual_cap(log2_strict(r.0.len()))) - .collect(); - let opening_proof = FriProofTarget { - commit_phase_merkle_caps, - query_round_proofs, - final_poly: PolynomialCoeffsExtTarget( - builder.add_virtual_extension_targets(proof.opening_proof.final_poly.len()), - ), - pow_witness: builder.add_virtual_target(), - }; - - let proof = ProofTarget { - wires_cap, - plonk_zs_partial_products_cap: plonk_zs_cap, - quotient_polys_cap, - openings, - opening_proof, - }; - - let public_inputs = builder.add_virtual_targets(public_inputs.len()); + let proof = self.add_virtual_proof(common_data); + let public_inputs = self.add_virtual_targets(common_data.num_public_inputs); ProofWithPublicInputsTarget { proof, public_inputs, } } + fn add_virtual_proof>( + &mut self, + common_data: &CommonCircuitData, + ) -> ProofTarget { + let config = &common_data.config; + let fri_params = &common_data.fri_params; + let cap_height = fri_params.config.cap_height; + + let num_leaves_per_oracle = &[ + common_data.num_preprocessed_polys(), + config.num_wires, + common_data.num_zs_partial_products_polys(), + common_data.num_quotient_polys(), + ]; + + ProofTarget { + wires_cap: self.add_virtual_cap(cap_height), + plonk_zs_partial_products_cap: self.add_virtual_cap(cap_height), + quotient_polys_cap: self.add_virtual_cap(cap_height), + openings: self.add_opening_set(common_data), + opening_proof: self.add_virtual_fri_proof(num_leaves_per_oracle, fri_params), + } + } + + fn add_opening_set>( + &mut self, + common_data: &CommonCircuitData, + ) -> OpeningSetTarget { + let config = &common_data.config; + let num_challenges = config.num_challenges; + let total_partial_products = num_challenges * common_data.num_partial_products; + OpeningSetTarget { + constants: self.add_virtual_extension_targets(common_data.num_constants), + plonk_sigmas: self.add_virtual_extension_targets(config.num_routed_wires), + wires: self.add_virtual_extension_targets(config.num_wires), + plonk_zs: self.add_virtual_extension_targets(num_challenges), + plonk_zs_right: self.add_virtual_extension_targets(num_challenges), + partial_products: self.add_virtual_extension_targets(total_partial_products), + quotient_polys: self.add_virtual_extension_targets(common_data.num_quotient_polys()), + } + } +} + +#[cfg(test)] +mod tests { + use anyhow::Result; + use itertools::Itertools; + use log::{info, Level}; + + use super::*; + use crate::fri::reduction_strategies::FriReductionStrategy; + use crate::fri::FriConfig; + use crate::gates::noop::NoopGate; + use crate::iop::witness::{PartialWitness, Witness}; + use crate::plonk::circuit_data::VerifierOnlyCircuitData; + use crate::plonk::config::{ + GMiMCGoldilocksConfig, GenericConfig, KeccakGoldilocksConfig, PoseidonGoldilocksConfig, + }; + use crate::plonk::proof::{CompressedProofWithPublicInputs, ProofWithPublicInputs}; + use crate::plonk::prover::prove; + use crate::util::timing::TimingTree; + // Set the targets in a `ProofTarget` to their corresponding values in a `Proof`. fn set_proof_target, C: GenericConfig, const D: usize>( proof: &ProofWithPublicInputs, @@ -272,7 +238,7 @@ mod tests { } = pt; // Set public inputs. - for (&pi_t, &pi) in pi_targets.iter().zip(public_inputs) { + for (&pi_t, &pi) in pi_targets.iter().zip_eq(public_inputs) { pw.set_target(pi_t, pi); } @@ -283,28 +249,33 @@ mod tests { ); pw.set_cap_target(&pt.quotient_polys_cap, &proof.quotient_polys_cap); - for (&t, &x) in pt.openings.wires.iter().zip(&proof.openings.wires) { + for (&t, &x) in pt.openings.wires.iter().zip_eq(&proof.openings.wires) { pw.set_extension_target(t, x); } - for (&t, &x) in pt.openings.constants.iter().zip(&proof.openings.constants) { + for (&t, &x) in pt + .openings + .constants + .iter() + .zip_eq(&proof.openings.constants) + { pw.set_extension_target(t, x); } for (&t, &x) in pt .openings .plonk_sigmas .iter() - .zip(&proof.openings.plonk_sigmas) + .zip_eq(&proof.openings.plonk_sigmas) { pw.set_extension_target(t, x); } - for (&t, &x) in pt.openings.plonk_zs.iter().zip(&proof.openings.plonk_zs) { + for (&t, &x) in pt.openings.plonk_zs.iter().zip_eq(&proof.openings.plonk_zs) { pw.set_extension_target(t, x); } for (&t, &x) in pt .openings .plonk_zs_right .iter() - .zip(&proof.openings.plonk_zs_right) + .zip_eq(&proof.openings.plonk_zs_right) { pw.set_extension_target(t, x); } @@ -312,7 +283,7 @@ mod tests { .openings .partial_products .iter() - .zip(&proof.openings.partial_products) + .zip_eq(&proof.openings.partial_products) { pw.set_extension_target(t, x); } @@ -320,7 +291,7 @@ mod tests { .openings .quotient_polys .iter() - .zip(&proof.openings.quotient_polys) + .zip_eq(&proof.openings.quotient_polys) { pw.set_extension_target(t, x); } @@ -330,14 +301,14 @@ mod tests { pw.set_target(fpt.pow_witness, fri_proof.pow_witness); - for (&t, &x) in fpt.final_poly.0.iter().zip(&fri_proof.final_poly.coeffs) { + for (&t, &x) in fpt.final_poly.0.iter().zip_eq(&fri_proof.final_poly.coeffs) { pw.set_extension_target(t, x); } for (t, x) in fpt .commit_phase_merkle_caps .iter() - .zip(&fri_proof.commit_phase_merkle_caps) + .zip_eq(&fri_proof.commit_phase_merkle_caps) { pw.set_cap_target(t, x); } @@ -345,31 +316,31 @@ mod tests { for (qt, q) in fpt .query_round_proofs .iter() - .zip(&fri_proof.query_round_proofs) + .zip_eq(&fri_proof.query_round_proofs) { for (at, a) in qt .initial_trees_proof .evals_proofs .iter() - .zip(&q.initial_trees_proof.evals_proofs) + .zip_eq(&q.initial_trees_proof.evals_proofs) { - for (&t, &x) in at.0.iter().zip(&a.0) { + for (&t, &x) in at.0.iter().zip_eq(&a.0) { pw.set_target(t, x); } - for (&t, &x) in at.1.siblings.iter().zip(&a.1.siblings) { + for (&t, &x) in at.1.siblings.iter().zip_eq(&a.1.siblings) { pw.set_hash_target(t, x); } } - for (st, s) in qt.steps.iter().zip(&q.steps) { - for (&t, &x) in st.evals.iter().zip(&s.evals) { + for (st, s) in qt.steps.iter().zip_eq(&q.steps) { + for (&t, &x) in st.evals.iter().zip_eq(&s.evals) { pw.set_extension_target(t, x); } for (&t, &x) in st .merkle_proof .siblings .iter() - .zip(&s.merkle_proof.siblings) + .zip_eq(&s.merkle_proof.siblings) { pw.set_hash_target(t, x); } @@ -582,7 +553,7 @@ mod tests { { let mut builder = CircuitBuilder::::new(config.clone()); let mut pw = PartialWitness::new(); - let pt = proof_to_proof_target(&inner_proof, &mut builder); + let pt = builder.add_virtual_proof_with_pis(&inner_cd); set_proof_target(&inner_proof, &pt, &mut pw); let inner_data = VerifierCircuitTarget { @@ -593,7 +564,7 @@ mod tests { &inner_vd.constants_sigmas_cap, ); - builder.add_recursive_verifier(pt, inner_config, &inner_data, &inner_cd); + builder.verify_proof_with_pis(pt, inner_config, &inner_data, &inner_cd); if print_gate_counts { builder.print_gate_counts(0); diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index e612a1c9..cbaec6d9 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -30,6 +30,10 @@ 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 + ); let public_inputs_hash = &proof_with_pis.get_public_inputs_hash(); let ProofWithPublicInputs { proof, .. } = proof_with_pis;