From 189719ffe9a8132f2032885f65dcbd552312ea2a Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 6 Oct 2022 18:37:31 +0200 Subject: [PATCH 1/9] Start of `dummy_proof()` --- plonky2/src/plonk/circuit_builder.rs | 4 ++++ .../src/plonk/conditional_recursive_verifier.rs | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 579a9017..1e4067df 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -263,6 +263,10 @@ impl, const D: usize> CircuitBuilder { ); } + pub fn add_gate_to_gate_set(&mut self, gate: GateRef) { + self.gates.insert(gate); + } + pub fn connect_extension(&mut self, src: ExtensionTarget, dst: ExtensionTarget) { for i in 0..D { self.connect(src.0[i], dst.0[i]); diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index 8d5b2e88..3222dfef 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -5,6 +5,7 @@ use crate::fri::proof::{ FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, }; use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; +use crate::gates::noop::NoopGate; use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_proofs::MerkleProofTarget; use crate::iop::ext_target::ExtensionTarget; @@ -15,6 +16,22 @@ use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::plonk::proof::{OpeningSetTarget, ProofTarget, ProofWithPublicInputsTarget}; use crate::with_context; +pub fn dummy_proof, C: GenericConfig, const D: usize>( + common_data: &CommonCircuitData, +) { + let config = common_data.config.clone(); + + // let mut pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + let degree = 1 << common_data.degree_bits; + for _ in 0..degree - 10 { + builder.add_gate(NoopGate, vec![]); + } + for gate in &common_data.gates { + builder.add_gate_to_gate_set(gate.clone()); + } +} + impl, const D: usize> CircuitBuilder { /// Verify `proof0` if `condition` else verify `proof1`. /// `proof0` and `proof1` are assumed to use the same `CommonCircuitData`. From 4cc2fdb8c50022bf2ea3c5e7f87d68cd759fb7ca Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 7 Oct 2022 10:24:11 +0200 Subject: [PATCH 2/9] Implement Eq for CommonCircuitData --- plonky2/src/fri/mod.rs | 2 +- plonky2/src/gates/selectors.rs | 2 +- plonky2/src/plonk/circuit_data.rs | 4 ++-- plonky2/src/plonk/conditional_recursive_verifier.rs | 13 +++++++++++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/plonky2/src/fri/mod.rs b/plonky2/src/fri/mod.rs index 5eaf012e..38286312 100644 --- a/plonky2/src/fri/mod.rs +++ b/plonky2/src/fri/mod.rs @@ -50,7 +50,7 @@ impl FriConfig { /// FRI parameters, including generated parameters which are specific to an instance size, in /// contrast to `FriConfig` which is user-specified and independent of instance size. -#[derive(Debug)] +#[derive(Debug, Eq, PartialEq)] pub struct FriParams { /// User-specified FRI configuration. pub config: FriConfig, diff --git a/plonky2/src/gates/selectors.rs b/plonky2/src/gates/selectors.rs index fff5d967..6cea86a7 100644 --- a/plonky2/src/gates/selectors.rs +++ b/plonky2/src/gates/selectors.rs @@ -9,7 +9,7 @@ use crate::hash::hash_types::RichField; /// Placeholder value to indicate that a gate doesn't use a selector polynomial. pub(crate) const UNUSED_SELECTOR: usize = u32::MAX as usize; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Eq, PartialEq)] pub(crate) struct SelectorsInfo { pub(crate) selector_indices: Vec, pub(crate) groups: Vec>, diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index f2363f41..c22eae3e 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -29,7 +29,7 @@ use crate::plonk::prover::prove; use crate::plonk::verifier::verify; use crate::util::timing::TimingTree; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct CircuitConfig { pub num_wires: usize, pub num_routed_wires: usize, @@ -239,7 +239,7 @@ pub struct VerifierOnlyCircuitData, const D: usize> { } /// Circuit data required by both the prover and the verifier. -#[derive(Debug)] +#[derive(Debug, Eq, PartialEq)] pub struct CommonCircuitData< F: RichField + Extendable, C: GenericConfig, diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index 3222dfef..e0a5116f 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -10,15 +10,18 @@ use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_proofs::MerkleProofTarget; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; +use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{CommonCircuitData, VerifierCircuitTarget}; -use crate::plonk::config::{AlgebraicHasher, GenericConfig}; +use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; use crate::plonk::proof::{OpeningSetTarget, ProofTarget, ProofWithPublicInputsTarget}; use crate::with_context; pub fn dummy_proof, C: GenericConfig, const D: usize>( common_data: &CommonCircuitData, -) { +) where + [(); C::Hasher::HASH_SIZE]:, +{ let config = common_data.config.clone(); // let mut pw = PartialWitness::new(); @@ -30,6 +33,11 @@ pub fn dummy_proof, C: GenericConfig, con for gate in &common_data.gates { builder.add_gate_to_gate_set(gate.clone()); } + // builder.add_virtual_pub + for i in 0..common_data.num_public_inputs {} + let data = builder.build::(); + assert_eq!(&data.common, common_data); + let proof = data.prove(PartialWitness::new()); } impl, const D: usize> CircuitBuilder { @@ -326,6 +334,7 @@ mod tests { let data = builder.build::(); let proof = data.prove(pw)?; data.verify(proof.clone())?; + let dummy = dummy_proof(&data.common); let mut builder = CircuitBuilder::::new(config); let mut pw = PartialWitness::new(); From 4690db7c2d6d63d14faadafef570d1a99bbc29ff Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 7 Oct 2022 10:55:07 +0200 Subject: [PATCH 3/9] Add PI --- plonky2/src/plonk/conditional_recursive_verifier.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index e0a5116f..73c8553e 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -33,8 +33,9 @@ pub fn dummy_proof, C: GenericConfig, con for gate in &common_data.gates { builder.add_gate_to_gate_set(gate.clone()); } - // builder.add_virtual_pub - for i in 0..common_data.num_public_inputs {} + for _ in 0..common_data.num_public_inputs { + let t = builder.add_virtual_public_input(); + } let data = builder.build::(); assert_eq!(&data.common, common_data); let proof = data.prove(PartialWitness::new()); From 816e7db345799950bb1af0815a55d2eca082c51c Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 11 Oct 2022 11:02:03 +0200 Subject: [PATCH 4/9] Working --- evm/src/recursive_verifier.rs | 1 + plonky2/examples/bench_recursion.rs | 17 ++++---- plonky2/src/iop/witness.rs | 13 +++++++ plonky2/src/plonk/circuit_builder.rs | 33 ++++++++-------- plonky2/src/plonk/circuit_data.rs | 36 +++++++++++++---- .../plonk/conditional_recursive_verifier.rs | 39 +++++++++++-------- plonky2/src/plonk/get_challenges.rs | 17 +++++--- plonky2/src/plonk/proof.rs | 17 +++++--- plonky2/src/plonk/prover.rs | 2 +- plonky2/src/plonk/recursive_verifier.rs | 34 ++++++++++------ plonky2/src/plonk/verifier.rs | 6 ++- 11 files changed, 144 insertions(+), 71 deletions(-) diff --git a/evm/src/recursive_verifier.rs b/evm/src/recursive_verifier.rs index a16063c4..4f08b513 100644 --- a/evm/src/recursive_verifier.rs +++ b/evm/src/recursive_verifier.rs @@ -586,6 +586,7 @@ where VerifierCircuitTarget { constants_sigmas_cap: builder .constant_merkle_cap(&verifier_data.verifier_only.constants_sigmas_cap), + circuit_digest: builder.add_virtual_hash(), } }); RecursiveAllProofTargetWithData { diff --git a/plonky2/examples/bench_recursion.rs b/plonky2/examples/bench_recursion.rs index 8073c9dc..2c38faa7 100644 --- a/plonky2/examples/bench_recursion.rs +++ b/plonky2/examples/bench_recursion.rs @@ -117,11 +117,9 @@ where let inner_data = VerifierCircuitTarget { constants_sigmas_cap: builder.add_virtual_cap(inner_cd.config.fri_config.cap_height), + circuit_digest: builder.add_virtual_hash(), }; - pw.set_cap_target( - &inner_data.constants_sigmas_cap, - &inner_vd.constants_sigmas_cap, - ); + pw.set_verifier_data_target(&inner_data, inner_vd); builder.verify_proof(pt, &inner_data, inner_cd); builder.print_gate_counts(0); @@ -151,6 +149,7 @@ where /// Test serialization and print some size info. fn test_serialization, C: GenericConfig, const D: usize>( proof: &ProofWithPublicInputs, + vd: &VerifierOnlyCircuitData, cd: &CommonCircuitData, ) -> Result<()> where @@ -162,8 +161,10 @@ where assert_eq!(proof, &proof_from_bytes); let now = std::time::Instant::now(); - let compressed_proof = proof.clone().compress(cd)?; - let decompressed_compressed_proof = compressed_proof.clone().decompress(cd)?; + let compressed_proof = proof.clone().compress(&vd.circuit_digest, cd)?; + let decompressed_compressed_proof = compressed_proof + .clone() + .decompress(&vd.circuit_digest, cd)?; info!("{:.4}s to compress proof", now.elapsed().as_secs_f64()); assert_eq!(proof, &decompressed_compressed_proof); @@ -204,14 +205,14 @@ fn benchmark(config: &CircuitConfig, log2_inner_size: usize) -> Result<()> { // Add a second layer of recursion to shrink the proof size further let outer = recursive_proof::(&middle, config, None)?; - let (proof, _, cd) = &outer; + let (proof, vd, cd) = &outer; info!( "Double recursion proof degree {} = 2^{}", cd.degree(), cd.degree_bits ); - test_serialization(proof, cd)?; + test_serialization(proof, vd, cd)?; Ok(()) } diff --git a/plonky2/src/iop/witness.rs b/plonky2/src/iop/witness.rs index e7f21241..9a3cb662 100644 --- a/plonky2/src/iop/witness.rs +++ b/plonky2/src/iop/witness.rs @@ -13,6 +13,7 @@ use crate::hash::merkle_tree::MerkleCap; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; use crate::iop::wire::Wire; +use crate::plonk::circuit_data::{VerifierCircuitTarget, VerifierOnlyCircuitData}; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::plonk::proof::{Proof, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget}; @@ -197,6 +198,18 @@ pub trait Witness { } } + fn set_verifier_data_target, const D: usize>( + &mut self, + vdt: &VerifierCircuitTarget, + vd: &VerifierOnlyCircuitData, + ) where + F: RichField + Extendable, + C::Hasher: AlgebraicHasher, + { + self.set_cap_target(&vdt.constants_sigmas_cap, &vd.constants_sigmas_cap); + self.set_hash_target(vdt.circuit_digest, vd.circuit_digest); + } + fn set_wire(&mut self, wire: Wire, value: F) { self.set_target(Target::Wire(wire), value) } diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 521e35c5..757dbdb1 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -755,11 +755,6 @@ impl, const D: usize> CircuitBuilder { Some(&fft_root_table), ); - let constants_sigmas_cap = constants_sigmas_commitment.merkle_tree.cap.clone(); - let verifier_only = VerifierOnlyCircuitData { - constants_sigmas_cap: constants_sigmas_cap.clone(), - }; - // Map between gates where not all generators are used and the gate's number of used generators. let incomplete_gates = self .current_slots @@ -800,17 +795,6 @@ impl, const D: usize> CircuitBuilder { indices.shrink_to_fit(); } - let prover_only = ProverOnlyCircuitData { - generators: self.generators, - generator_indices_by_watches, - constants_sigmas_commitment, - sigmas: transpose_poly_values(sigma_vecs), - subgroup, - public_inputs: self.public_inputs, - representative_map: forest.parents, - fft_root_table: Some(fft_root_table), - }; - let num_gate_constraints = gates .iter() .map(|gate| gate.0.num_constraints()) @@ -820,6 +804,7 @@ impl, const D: usize> CircuitBuilder { let num_partial_products = num_partial_products(self.config.num_routed_wires, quotient_degree_factor); + let constants_sigmas_cap = constants_sigmas_commitment.merkle_tree.cap.clone(); // TODO: This should also include an encoding of gate constraints. let circuit_digest_parts = [ constants_sigmas_cap.flatten(), @@ -842,6 +827,22 @@ impl, const D: usize> CircuitBuilder { num_public_inputs, k_is, num_partial_products, + }; + + let prover_only = ProverOnlyCircuitData { + generators: self.generators, + generator_indices_by_watches, + constants_sigmas_commitment, + sigmas: transpose_poly_values(sigma_vecs), + subgroup, + public_inputs: self.public_inputs, + representative_map: forest.parents, + fft_root_table: Some(fft_root_table), + circuit_digest, + }; + + let verifier_only = VerifierOnlyCircuitData { + constants_sigmas_cap, circuit_digest, }; diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 851485cd..5b0f221c 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -15,7 +15,7 @@ use crate::fri::structure::{ use crate::fri::{FriConfig, FriParams}; use crate::gates::gate::GateRef; use crate::gates::selectors::SelectorsInfo; -use crate::hash::hash_types::{MerkleCapTarget, RichField}; +use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_tree::MerkleCap; use crate::iop::ext_target::ExtensionTarget; use crate::iop::generator::WitnessGenerator; @@ -141,6 +141,23 @@ impl, C: GenericConfig, const D: usize> compressed_proof_with_pis.verify(&self.verifier_only, &self.common) } + pub fn compress( + &self, + proof: ProofWithPublicInputs, + ) -> Result> { + proof.compress(&self.verifier_only.circuit_digest, &self.common) + } + + pub fn decompress( + &self, + proof: CompressedProofWithPublicInputs, + ) -> Result> + where + [(); C::Hasher::HASH_SIZE]:, + { + proof.decompress(&self.verifier_only.circuit_digest, &self.common) + } + pub fn verifier_data(self) -> VerifierCircuitData { let CircuitData { verifier_only, @@ -253,6 +270,9 @@ pub struct ProverOnlyCircuitData< pub representative_map: Vec, /// Pre-computed roots for faster FFT. pub fft_root_table: Option>, + /// A digest of the "circuit" (i.e. the instance, minus public inputs), which can be used to + /// seed Fiat-Shamir. + pub(crate) circuit_digest: <>::Hasher as Hasher>::Hash, } /// Circuit data required by the verifier, but not the prover. @@ -260,6 +280,9 @@ pub struct ProverOnlyCircuitData< pub struct VerifierOnlyCircuitData, const D: usize> { /// A commitment to each constant polynomial and each permutation polynomial. pub constants_sigmas_cap: MerkleCap, + /// A digest of the "circuit" (i.e. the instance, minus public inputs), which can be used to + /// seed Fiat-Shamir. + pub circuit_digest: <>::Hasher as Hasher>::Hash, } /// Circuit data required by both the prover and the verifier. @@ -276,7 +299,7 @@ pub struct CommonCircuitData< pub degree_bits: usize, /// The types of gates used in this circuit, along with their prefixes. - pub(crate) gates: Vec>, + pub(crate) gates: Vec>, /// Information on the circuit's selector polynomials. pub(crate) selectors_info: SelectorsInfo, @@ -293,14 +316,10 @@ pub struct CommonCircuitData< 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, + pub(crate) k_is: Vec, /// The number of partial products needed to compute the `Z` polynomials. pub(crate) num_partial_products: usize, - - /// A digest of the "circuit" (i.e. the instance, minus public inputs), which can be used to - /// seed Fiat-Shamir. - pub(crate) circuit_digest: <>::Hasher as Hasher>::Hash, } impl, C: GenericConfig, const D: usize> @@ -476,4 +495,7 @@ impl, C: GenericConfig, const D: usize> pub struct VerifierCircuitTarget { /// A commitment to each constant polynomial and each permutation polynomial. pub constants_sigmas_cap: MerkleCapTarget, + /// A digest of the "circuit" (i.e. the instance, minus public inputs), which can be used to + /// seed Fiat-Shamir. + pub circuit_digest: HashOutTarget, } diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index 73c8553e..c8c08e2c 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -1,3 +1,4 @@ +use anyhow::Result; use itertools::Itertools; use plonky2_field::extension::Extendable; @@ -10,21 +11,24 @@ use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_proofs::MerkleProofTarget; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; -use crate::iop::witness::PartialWitness; +use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::{CommonCircuitData, VerifierCircuitTarget}; +use crate::plonk::circuit_data::{CircuitData, CommonCircuitData, VerifierCircuitTarget}; use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; -use crate::plonk::proof::{OpeningSetTarget, ProofTarget, ProofWithPublicInputsTarget}; +use crate::plonk::proof::{ + OpeningSetTarget, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget, +}; use crate::with_context; pub fn dummy_proof, C: GenericConfig, const D: usize>( common_data: &CommonCircuitData, -) where +) -> Result<(ProofWithPublicInputs, CircuitData)> +where [(); C::Hasher::HASH_SIZE]:, { let config = common_data.config.clone(); - // let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); let degree = 1 << common_data.degree_bits; for _ in 0..degree - 10 { @@ -35,10 +39,12 @@ pub fn dummy_proof, C: GenericConfig, con } for _ in 0..common_data.num_public_inputs { let t = builder.add_virtual_public_input(); + pw.set_target(t, F::ZERO); } let data = builder.build::(); assert_eq!(&data.common, common_data); - let proof = data.prove(PartialWitness::new()); + let proof = data.prove(pw)?; + Ok((proof, data)) } impl, const D: usize> CircuitBuilder { @@ -108,6 +114,11 @@ impl, const D: usize> CircuitBuilder { inner_verifier_data0.constants_sigmas_cap.clone(), inner_verifier_data1.constants_sigmas_cap.clone(), ), + circuit_digest: self.select_hash( + condition, + inner_verifier_data0.circuit_digest, + inner_verifier_data1.circuit_digest, + ), }; self.verify_proof(selected_proof, &selected_verifier_data, inner_common_data); @@ -335,29 +346,25 @@ mod tests { let data = builder.build::(); let proof = data.prove(pw)?; data.verify(proof.clone())?; - let dummy = dummy_proof(&data.common); + let (dummy_proof, dummy_data) = dummy_proof(&data.common)?; let mut builder = CircuitBuilder::::new(config); let mut pw = PartialWitness::new(); let pt = builder.add_virtual_proof_with_pis(&data.common); pw.set_proof_with_pis_target(&pt, &proof); let dummy_pt = builder.add_virtual_proof_with_pis(&data.common); - pw.set_proof_with_pis_target(&dummy_pt, &proof); + pw.set_proof_with_pis_target(&dummy_pt, &dummy_proof); let inner_data = VerifierCircuitTarget { constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), + circuit_digest: builder.add_virtual_hash(), }; - pw.set_cap_target( - &inner_data.constants_sigmas_cap, - &data.verifier_only.constants_sigmas_cap, - ); + pw.set_verifier_data_target(&inner_data, &data.verifier_only); let dummy_inner_data = VerifierCircuitTarget { constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), + circuit_digest: builder.add_virtual_hash(), }; - pw.set_cap_target( - &dummy_inner_data.constants_sigmas_cap, - &data.verifier_only.constants_sigmas_cap, - ); + pw.set_verifier_data_target(&dummy_inner_data, &dummy_data.verifier_only); let b = builder.constant_bool(F::rand().0 % 2 == 0); builder.conditionally_verify_proof( b, diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index a8ca52e5..d716c251 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -29,6 +29,7 @@ fn get_challenges, C: GenericConfig, cons commit_phase_merkle_caps: &[MerkleCap], final_poly: &PolynomialCoeffs, pow_witness: F, + circuit_digest: &<>::Hasher as Hasher>::Hash, common_data: &CommonCircuitData, ) -> anyhow::Result> { let config = &common_data.config; @@ -37,7 +38,7 @@ fn get_challenges, C: GenericConfig, cons let mut challenger = Challenger::::new(); // Observe the instance. - challenger.observe_hash::(common_data.circuit_digest); + challenger.observe_hash::(*circuit_digest); challenger.observe_hash::(public_inputs_hash); challenger.observe_cap(wires_cap); @@ -72,10 +73,11 @@ impl, C: GenericConfig, const D: usize> { pub(crate) fn fri_query_indices( &self, + circuit_digest: &<>::Hasher as Hasher>::Hash, common_data: &CommonCircuitData, ) -> anyhow::Result> { Ok(self - .get_challenges(self.get_public_inputs_hash(), common_data)? + .get_challenges(self.get_public_inputs_hash(), circuit_digest, common_data)? .fri_challenges .fri_query_indices) } @@ -84,6 +86,7 @@ impl, C: GenericConfig, const D: usize> pub(crate) fn get_challenges( &self, public_inputs_hash: <>::InnerHasher as Hasher>::Hash, + circuit_digest: &<>::Hasher as Hasher>::Hash, common_data: &CommonCircuitData, ) -> anyhow::Result> { let Proof { @@ -109,6 +112,7 @@ impl, C: GenericConfig, const D: usize> commit_phase_merkle_caps, final_poly, *pow_witness, + circuit_digest, common_data, ) } @@ -121,6 +125,7 @@ impl, C: GenericConfig, const D: usize> pub(crate) fn get_challenges( &self, public_inputs_hash: <>::InnerHasher as Hasher>::Hash, + circuit_digest: &<>::Hasher as Hasher>::Hash, common_data: &CommonCircuitData, ) -> anyhow::Result> { let CompressedProof { @@ -146,6 +151,7 @@ impl, C: GenericConfig, const D: usize> commit_phase_merkle_caps, final_poly, *pow_witness, + circuit_digest, common_data, ) } @@ -237,6 +243,7 @@ impl, const D: usize> CircuitBuilder { commit_phase_merkle_caps: &[MerkleCapTarget], final_poly: &PolynomialCoeffsExtTarget, pow_witness: Target, + inner_circuit_digest: HashOutTarget, inner_common_data: &CommonCircuitData, ) -> ProofChallengesTarget where @@ -248,9 +255,7 @@ impl, const D: usize> CircuitBuilder { 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(&inner_circuit_digest); challenger.observe_hash(&public_inputs_hash); challenger.observe_cap(wires_cap); @@ -286,6 +291,7 @@ impl ProofWithPublicInputsTarget { &self, builder: &mut CircuitBuilder, public_inputs_hash: HashOutTarget, + inner_circuit_digest: HashOutTarget, inner_common_data: &CommonCircuitData, ) -> ProofChallengesTarget where @@ -314,6 +320,7 @@ impl ProofWithPublicInputsTarget { commit_phase_merkle_caps, final_poly, *pow_witness, + inner_circuit_digest, inner_common_data, ) } diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index 922a24bb..2ec26c75 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -81,9 +81,10 @@ impl, C: GenericConfig, const D: usize> { pub fn compress( self, + circuit_digest: &<>::Hasher as Hasher>::Hash, common_data: &CommonCircuitData, ) -> anyhow::Result> { - let indices = self.fri_query_indices(common_data)?; + let indices = self.fri_query_indices(circuit_digest, common_data)?; let compressed_proof = self.proof.compress(&indices, &common_data.fri_params); Ok(CompressedProofWithPublicInputs { public_inputs: self.public_inputs, @@ -176,12 +177,14 @@ impl, C: GenericConfig, const D: usize> { pub fn decompress( self, + circuit_digest: &<>::Hasher as Hasher>::Hash, common_data: &CommonCircuitData, ) -> anyhow::Result> where [(); C::Hasher::HASH_SIZE]:, { - let challenges = self.get_challenges(self.get_public_inputs_hash(), common_data)?; + let challenges = + self.get_challenges(self.get_public_inputs_hash(), circuit_digest, common_data)?; let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data); let decompressed_proof = self.proof @@ -205,7 +208,11 @@ impl, C: GenericConfig, const D: usize> "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 challenges = self.get_challenges( + public_inputs_hash, + &verifier_data.circuit_digest, + common_data, + )?; let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data); let decompressed_proof = self.proof @@ -418,8 +425,8 @@ mod tests { verify(proof.clone(), &data.verifier_only, &data.common)?; // Verify that `decompress ∘ compress = identity`. - let compressed_proof = proof.clone().compress(&data.common)?; - let decompressed_compressed_proof = compressed_proof.clone().decompress(&data.common)?; + let compressed_proof = data.compress(proof.clone())?; + let decompressed_compressed_proof = data.decompress(compressed_proof.clone())?; assert_eq!(proof, decompressed_compressed_proof); verify(proof, &data.verifier_only, &data.common)?; diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index 3e81942b..826e5ab4 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -81,7 +81,7 @@ where let mut challenger = Challenger::::new(); // Observe the instance. - challenger.observe_hash::(common_data.circuit_digest); + challenger.observe_hash::(prover_data.circuit_digest); challenger.observe_hash::(public_inputs_hash); challenger.observe_cap(&wires_commitment.merkle_tree.cap); diff --git a/plonky2/src/plonk/recursive_verifier.rs b/plonky2/src/plonk/recursive_verifier.rs index ecce34e1..7d901236 100644 --- a/plonky2/src/plonk/recursive_verifier.rs +++ b/plonky2/src/plonk/recursive_verifier.rs @@ -29,7 +29,12 @@ impl, const D: usize> CircuitBuilder { ); 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); + let challenges = proof_with_pis.get_challenges( + self, + public_inputs_hash, + inner_verifier_data.circuit_digest, + inner_common_data, + ); self.verify_proof_with_challenges( proof_with_pis.proof, @@ -205,9 +210,9 @@ mod tests { let config = CircuitConfig::standard_recursion_zk_config(); let (proof, vd, cd) = dummy_proof::(&config, 4_000)?; - let (proof, _vd, cd) = + let (proof, vd, cd) = recursive_proof::(proof, vd, cd, &config, None, true, true)?; - test_serialization(&proof, &cd)?; + test_serialization(&proof, &vd, &cd)?; Ok(()) } @@ -231,11 +236,11 @@ mod tests { assert_eq!(cd.degree_bits, 13); // Shrink it to 2^12. - let (proof, _vd, cd) = + let (proof, vd, cd) = recursive_proof::(proof, vd, cd, &config, None, true, true)?; assert_eq!(cd.degree_bits, 12); - test_serialization(&proof, &cd)?; + test_serialization(&proof, &vd, &cd)?; Ok(()) } @@ -287,11 +292,11 @@ mod tests { }, ..high_rate_config }; - let (proof, _vd, cd) = + let (proof, vd, cd) = recursive_proof::(proof, vd, cd, &final_config, None, true, true)?; assert_eq!(cd.degree_bits, 12, "final proof too large"); - test_serialization(&proof, &cd)?; + test_serialization(&proof, &vd, &cd)?; Ok(()) } @@ -309,11 +314,11 @@ mod tests { let (proof, vd, cd) = recursive_proof::(proof, vd, cd, &config, None, false, false)?; - test_serialization(&proof, &cd)?; + test_serialization(&proof, &vd, &cd)?; - let (proof, _vd, cd) = + let (proof, vd, cd) = recursive_proof::(proof, vd, cd, &config, None, false, false)?; - test_serialization(&proof, &cd)?; + test_serialization(&proof, &vd, &cd)?; Ok(()) } @@ -372,11 +377,13 @@ mod tests { let inner_data = VerifierCircuitTarget { constants_sigmas_cap: builder.add_virtual_cap(inner_cd.config.fri_config.cap_height), + circuit_digest: builder.add_virtual_hash(), }; pw.set_cap_target( &inner_data.constants_sigmas_cap, &inner_vd.constants_sigmas_cap, ); + pw.set_hash_target(inner_data.circuit_digest, inner_vd.circuit_digest); builder.verify_proof(pt, &inner_data, &inner_cd); @@ -414,6 +421,7 @@ mod tests { const D: usize, >( proof: &ProofWithPublicInputs, + vd: &VerifierOnlyCircuitData, cd: &CommonCircuitData, ) -> Result<()> where @@ -425,8 +433,10 @@ mod tests { assert_eq!(proof, &proof_from_bytes); let now = std::time::Instant::now(); - let compressed_proof = proof.clone().compress(cd)?; - let decompressed_compressed_proof = compressed_proof.clone().decompress(cd)?; + let compressed_proof = proof.clone().compress(&vd.circuit_digest, cd)?; + let decompressed_compressed_proof = compressed_proof + .clone() + .decompress(&vd.circuit_digest, cd)?; info!("{:.4}s to compress proof", now.elapsed().as_secs_f64()); assert_eq!(proof, &decompressed_compressed_proof); diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index 6a4f3790..78db1b2f 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -23,7 +23,11 @@ where validate_proof_with_pis_shape(&proof_with_pis, common_data)?; let public_inputs_hash = proof_with_pis.get_public_inputs_hash(); - let challenges = proof_with_pis.get_challenges(public_inputs_hash, common_data)?; + let challenges = proof_with_pis.get_challenges( + public_inputs_hash, + &verifier_data.circuit_digest, + common_data, + )?; verify_with_challenges( proof_with_pis.proof, From 3cd337ab158ff7032c35ca88bc7dfdfac795bb88 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 11 Oct 2022 11:10:58 +0200 Subject: [PATCH 5/9] Comments --- plonky2/src/plonk/conditional_recursive_verifier.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index c8c08e2c..a081efa8 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -20,6 +20,7 @@ use crate::plonk::proof::{ }; use crate::with_context; +/// Generate a proof having a given `CommonCircuitData`. pub fn dummy_proof, C: GenericConfig, const D: usize>( common_data: &CommonCircuitData, ) -> Result<(ProofWithPublicInputs, CircuitData)> @@ -31,6 +32,7 @@ where let mut pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); let degree = 1 << common_data.degree_bits; + for _ in 0..degree - 10 { builder.add_gate(NoopGate, vec![]); } @@ -41,9 +43,11 @@ where let t = builder.add_virtual_public_input(); pw.set_target(t, F::ZERO); } + let data = builder.build::(); assert_eq!(&data.common, common_data); let proof = data.prove(pw)?; + Ok((proof, data)) } @@ -334,6 +338,7 @@ mod tests { type F = >::F; let config = CircuitConfig::standard_recursion_config(); + // Generate proof. let mut builder = CircuitBuilder::::new(config.clone()); let mut pw = PartialWitness::new(); let t = builder.add_virtual_target(); @@ -346,15 +351,17 @@ mod tests { let data = builder.build::(); let proof = data.prove(pw)?; data.verify(proof.clone())?; + + // Generate dummy proof with the same `CommonCircuitData`. let (dummy_proof, dummy_data) = dummy_proof(&data.common)?; + // Conditionally verify the two proofs. let mut builder = CircuitBuilder::::new(config); let mut pw = PartialWitness::new(); let pt = builder.add_virtual_proof_with_pis(&data.common); pw.set_proof_with_pis_target(&pt, &proof); let dummy_pt = builder.add_virtual_proof_with_pis(&data.common); pw.set_proof_with_pis_target(&dummy_pt, &dummy_proof); - let inner_data = VerifierCircuitTarget { constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), circuit_digest: builder.add_virtual_hash(), From 0013bd4347978b1ed1a6de05b7c5b91b08003bdd Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 11 Oct 2022 11:41:19 +0200 Subject: [PATCH 6/9] Minor --- plonky2/src/plonk/circuit_data.rs | 2 +- plonky2/src/plonk/conditional_recursive_verifier.rs | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 5b0f221c..0eb5c5e5 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -272,7 +272,7 @@ pub struct ProverOnlyCircuitData< pub fft_root_table: Option>, /// A digest of the "circuit" (i.e. the instance, minus public inputs), which can be used to /// seed Fiat-Shamir. - pub(crate) circuit_digest: <>::Hasher as Hasher>::Hash, + pub circuit_digest: <>::Hasher as Hasher>::Hash, } /// Circuit data required by the verifier, but not the prover. diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index a081efa8..00b21fde 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -1,6 +1,7 @@ use anyhow::Result; use itertools::Itertools; use plonky2_field::extension::Extendable; +use plonky2_util::ceil_div_usize; use crate::fri::proof::{ FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, @@ -31,9 +32,13 @@ where let mut pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); - let degree = 1 << common_data.degree_bits; - for _ in 0..degree - 10 { + let degree = 1 << common_data.degree_bits; + // Number of `NoopGate`s to add to get a circuit of size `degree` in the end. + // Need to account for public input hashing, a `PublicInputGate` and a `ConstantGate`. + let num_noop_gate = degree - ceil_div_usize(common_data.num_public_inputs, 8) - 2; + + for _ in 0..num_noop_gate { builder.add_gate(NoopGate, vec![]); } for gate in &common_data.gates { From e17823e7770ed685a6d333cdb884fcadd44be490 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 11 Oct 2022 11:47:37 +0200 Subject: [PATCH 7/9] Disallow zk for dummy proof --- plonky2/src/plonk/conditional_recursive_verifier.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index 00b21fde..8ac0a4f2 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use anyhow::{ensure, Result}; use itertools::Itertools; use plonky2_field::extension::Extendable; use plonky2_util::ceil_div_usize; @@ -33,6 +33,10 @@ where let mut pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); + ensure!( + !common_data.config.zero_knowledge, + "Degree calculation can be off if zero-knowledge is on." + ); let degree = 1 << common_data.degree_bits; // Number of `NoopGate`s to add to get a circuit of size `degree` in the end. // Need to account for public input hashing, a `PublicInputGate` and a `ConstantGate`. From 972d83687ee8ba38ad9bf7aebec60538977bd457 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 17 Oct 2022 09:54:00 +0200 Subject: [PATCH 8/9] PR feedback --- .../plonk/conditional_recursive_verifier.rs | 173 +++++++++++------- 1 file changed, 106 insertions(+), 67 deletions(-) diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index 8ac0a4f2..28041b4b 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -14,7 +14,9 @@ use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::{CircuitData, CommonCircuitData, VerifierCircuitTarget}; +use crate::plonk::circuit_data::{ + CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, +}; use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; use crate::plonk::proof::{ OpeningSetTarget, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget, @@ -22,9 +24,17 @@ use crate::plonk::proof::{ use crate::with_context; /// Generate a proof having a given `CommonCircuitData`. -pub fn dummy_proof, C: GenericConfig, const D: usize>( +#[allow(unused)] // TODO: should be used soon. +pub(crate) fn dummy_proof< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, +>( common_data: &CommonCircuitData, -) -> Result<(ProofWithPublicInputs, CircuitData)> +) -> Result<( + ProofWithPublicInputs, + VerifierOnlyCircuitData, +)> where [(); C::Hasher::HASH_SIZE]:, { @@ -57,7 +67,7 @@ where assert_eq!(&data.common, common_data); let proof = data.prove(pw)?; - Ok((proof, data)) + Ok((proof, data.verifier_only)) } impl, const D: usize> CircuitBuilder { @@ -66,9 +76,9 @@ impl, const D: usize> CircuitBuilder { pub fn conditionally_verify_proof>( &mut self, condition: BoolTarget, - proof_with_pis0: ProofWithPublicInputsTarget, + proof_with_pis0: &ProofWithPublicInputsTarget, inner_verifier_data0: &VerifierCircuitTarget, - proof_with_pis1: ProofWithPublicInputsTarget, + proof_with_pis1: &ProofWithPublicInputsTarget, inner_verifier_data1: &VerifierCircuitTarget, inner_common_data: &CommonCircuitData, ) where @@ -124,8 +134,8 @@ impl, const D: usize> CircuitBuilder { let selected_verifier_data = VerifierCircuitTarget { constants_sigmas_cap: self.select_cap( condition, - inner_verifier_data0.constants_sigmas_cap.clone(), - inner_verifier_data1.constants_sigmas_cap.clone(), + &inner_verifier_data0.constants_sigmas_cap, + &inner_verifier_data1.constants_sigmas_cap, ), circuit_digest: self.select_hash( condition, @@ -137,10 +147,39 @@ impl, const D: usize> CircuitBuilder { self.verify_proof(selected_proof, &selected_verifier_data, inner_common_data); } - fn select_vec(&mut self, b: BoolTarget, v0: Vec, v1: Vec) -> Vec { - v0.into_iter() + /// Conditionally verify a proof with a new generated dummy proof. + pub fn conditionally_verify_proof_or_dummy>( + &mut self, + condition: BoolTarget, + proof_with_pis: &ProofWithPublicInputsTarget, + inner_verifier_data: &VerifierCircuitTarget, + inner_common_data: &CommonCircuitData, + ) -> (ProofWithPublicInputsTarget, VerifierCircuitTarget) + where + C::Hasher: AlgebraicHasher, + { + let dummy_proof = self.add_virtual_proof_with_pis(inner_common_data); + let dummy_verifier_data = VerifierCircuitTarget { + constants_sigmas_cap: self + .add_virtual_cap(inner_common_data.config.fri_config.cap_height), + circuit_digest: self.add_virtual_hash(), + }; + self.conditionally_verify_proof( + condition, + proof_with_pis, + inner_verifier_data, + &dummy_proof, + &dummy_verifier_data, + inner_common_data, + ); + + (dummy_proof, dummy_verifier_data) + } + + fn select_vec(&mut self, b: BoolTarget, v0: &[Target], v1: &[Target]) -> Vec { + v0.iter() .zip_eq(v1) - .map(|(t0, t1)| self.select(b, t0, t1)) + .map(|(t0, t1)| self.select(b, *t0, *t1)) .collect() } @@ -158,15 +197,15 @@ impl, const D: usize> CircuitBuilder { fn select_cap( &mut self, b: BoolTarget, - cap0: MerkleCapTarget, - cap1: MerkleCapTarget, + cap0: &MerkleCapTarget, + cap1: &MerkleCapTarget, ) -> MerkleCapTarget { assert_eq!(cap0.0.len(), cap1.0.len()); MerkleCapTarget( cap0.0 - .into_iter() - .zip_eq(cap1.0) - .map(|(h0, h1)| self.select_hash(b, h0, h1)) + .iter() + .zip_eq(&cap1.0) + .map(|(h0, h1)| self.select_hash(b, *h0, *h1)) .collect(), ) } @@ -174,10 +213,10 @@ impl, const D: usize> CircuitBuilder { fn select_vec_cap( &mut self, b: BoolTarget, - v0: Vec, - v1: Vec, + v0: &[MerkleCapTarget], + v1: &[MerkleCapTarget], ) -> Vec { - v0.into_iter() + v0.iter() .zip_eq(v1) .map(|(c0, c1)| self.select_cap(b, c0, c1)) .collect() @@ -186,53 +225,53 @@ impl, const D: usize> CircuitBuilder { fn select_opening_set( &mut self, b: BoolTarget, - os0: OpeningSetTarget, - os1: OpeningSetTarget, + os0: &OpeningSetTarget, + os1: &OpeningSetTarget, ) -> OpeningSetTarget { OpeningSetTarget { - constants: self.select_vec_ext(b, os0.constants, os1.constants), - plonk_sigmas: self.select_vec_ext(b, os0.plonk_sigmas, os1.plonk_sigmas), - wires: self.select_vec_ext(b, os0.wires, os1.wires), - plonk_zs: self.select_vec_ext(b, os0.plonk_zs, os1.plonk_zs), - plonk_zs_next: self.select_vec_ext(b, os0.plonk_zs_next, os1.plonk_zs_next), - partial_products: self.select_vec_ext(b, os0.partial_products, os1.partial_products), - quotient_polys: self.select_vec_ext(b, os0.quotient_polys, os1.quotient_polys), + constants: self.select_vec_ext(b, &os0.constants, &os1.constants), + plonk_sigmas: self.select_vec_ext(b, &os0.plonk_sigmas, &os1.plonk_sigmas), + wires: self.select_vec_ext(b, &os0.wires, &os1.wires), + plonk_zs: self.select_vec_ext(b, &os0.plonk_zs, &os1.plonk_zs), + plonk_zs_next: self.select_vec_ext(b, &os0.plonk_zs_next, &os1.plonk_zs_next), + partial_products: self.select_vec_ext(b, &os0.partial_products, &os1.partial_products), + quotient_polys: self.select_vec_ext(b, &os0.quotient_polys, &os1.quotient_polys), } } fn select_vec_ext( &mut self, b: BoolTarget, - v0: Vec>, - v1: Vec>, + v0: &[ExtensionTarget], + v1: &[ExtensionTarget], ) -> Vec> { - v0.into_iter() + v0.iter() .zip_eq(v1) - .map(|(e0, e1)| self.select_ext(b, e0, e1)) + .map(|(e0, e1)| self.select_ext(b, *e0, *e1)) .collect() } fn select_opening_proof( &mut self, b: BoolTarget, - proof0: FriProofTarget, - proof1: FriProofTarget, + proof0: &FriProofTarget, + proof1: &FriProofTarget, ) -> FriProofTarget { FriProofTarget { commit_phase_merkle_caps: self.select_vec_cap( b, - proof0.commit_phase_merkle_caps, - proof1.commit_phase_merkle_caps, + &proof0.commit_phase_merkle_caps, + &proof1.commit_phase_merkle_caps, ), query_round_proofs: self.select_vec_query_round( b, - proof0.query_round_proofs, - proof1.query_round_proofs, + &proof0.query_round_proofs, + &proof1.query_round_proofs, ), final_poly: PolynomialCoeffsExtTarget(self.select_vec_ext( b, - proof0.final_poly.0, - proof1.final_poly.0, + &proof0.final_poly.0, + &proof1.final_poly.0, )), pow_witness: self.select(b, proof0.pow_witness, proof1.pow_witness), } @@ -241,26 +280,26 @@ impl, const D: usize> CircuitBuilder { fn select_query_round( &mut self, b: BoolTarget, - qr0: FriQueryRoundTarget, - qr1: FriQueryRoundTarget, + qr0: &FriQueryRoundTarget, + qr1: &FriQueryRoundTarget, ) -> FriQueryRoundTarget { FriQueryRoundTarget { initial_trees_proof: self.select_initial_tree_proof( b, - qr0.initial_trees_proof, - qr1.initial_trees_proof, + &qr0.initial_trees_proof, + &qr1.initial_trees_proof, ), - steps: self.select_vec_query_step(b, qr0.steps, qr1.steps), + steps: self.select_vec_query_step(b, &qr0.steps, &qr1.steps), } } fn select_vec_query_round( &mut self, b: BoolTarget, - v0: Vec>, - v1: Vec>, + v0: &[FriQueryRoundTarget], + v1: &[FriQueryRoundTarget], ) -> Vec> { - v0.into_iter() + v0.iter() .zip_eq(v1) .map(|(qr0, qr1)| self.select_query_round(b, qr0, qr1)) .collect() @@ -269,14 +308,14 @@ impl, const D: usize> CircuitBuilder { fn select_initial_tree_proof( &mut self, b: BoolTarget, - proof0: FriInitialTreeProofTarget, - proof1: FriInitialTreeProofTarget, + proof0: &FriInitialTreeProofTarget, + proof1: &FriInitialTreeProofTarget, ) -> FriInitialTreeProofTarget { FriInitialTreeProofTarget { evals_proofs: proof0 .evals_proofs - .into_iter() - .zip_eq(proof1.evals_proofs) + .iter() + .zip_eq(&proof1.evals_proofs) .map(|((v0, p0), (v1, p1))| { ( self.select_vec(b, v0, v1), @@ -290,15 +329,15 @@ impl, const D: usize> CircuitBuilder { fn select_merkle_proof( &mut self, b: BoolTarget, - proof0: MerkleProofTarget, - proof1: MerkleProofTarget, + proof0: &MerkleProofTarget, + proof1: &MerkleProofTarget, ) -> MerkleProofTarget { MerkleProofTarget { siblings: proof0 .siblings - .into_iter() - .zip_eq(proof1.siblings) - .map(|(h0, h1)| self.select_hash(b, h0, h1)) + .iter() + .zip_eq(&proof1.siblings) + .map(|(h0, h1)| self.select_hash(b, *h0, *h1)) .collect(), } } @@ -306,22 +345,22 @@ impl, const D: usize> CircuitBuilder { fn select_query_step( &mut self, b: BoolTarget, - qs0: FriQueryStepTarget, - qs1: FriQueryStepTarget, + qs0: &FriQueryStepTarget, + qs1: &FriQueryStepTarget, ) -> FriQueryStepTarget { FriQueryStepTarget { - evals: self.select_vec_ext(b, qs0.evals, qs1.evals), - merkle_proof: self.select_merkle_proof(b, qs0.merkle_proof, qs1.merkle_proof), + evals: self.select_vec_ext(b, &qs0.evals, &qs1.evals), + merkle_proof: self.select_merkle_proof(b, &qs0.merkle_proof, &qs1.merkle_proof), } } fn select_vec_query_step( &mut self, b: BoolTarget, - v0: Vec>, - v1: Vec>, + v0: &[FriQueryStepTarget], + v1: &[FriQueryStepTarget], ) -> Vec> { - v0.into_iter() + v0.iter() .zip_eq(v1) .map(|(qs0, qs1)| self.select_query_step(b, qs0, qs1)) .collect() @@ -380,13 +419,13 @@ mod tests { constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), circuit_digest: builder.add_virtual_hash(), }; - pw.set_verifier_data_target(&dummy_inner_data, &dummy_data.verifier_only); + pw.set_verifier_data_target(&dummy_inner_data, &dummy_data); let b = builder.constant_bool(F::rand().0 % 2 == 0); builder.conditionally_verify_proof( b, - pt, + &pt, &inner_data, - dummy_pt, + &dummy_pt, &dummy_inner_data, &data.common, ); From fb94ace3db5b0c3f5dc41ce24a313f0f1275b64d Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 17 Oct 2022 10:02:36 +0200 Subject: [PATCH 9/9] Fix conflict --- plonky2/src/plonk/conditional_recursive_verifier.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/src/plonk/conditional_recursive_verifier.rs b/plonky2/src/plonk/conditional_recursive_verifier.rs index 28041b4b..2c406904 100644 --- a/plonky2/src/plonk/conditional_recursive_verifier.rs +++ b/plonky2/src/plonk/conditional_recursive_verifier.rs @@ -47,7 +47,7 @@ where !common_data.config.zero_knowledge, "Degree calculation can be off if zero-knowledge is on." ); - let degree = 1 << common_data.degree_bits; + let degree = common_data.degree(); // Number of `NoopGate`s to add to get a circuit of size `degree` in the end. // Need to account for public input hashing, a `PublicInputGate` and a `ConstantGate`. let num_noop_gate = degree - ceil_div_usize(common_data.num_public_inputs, 8) - 2;