From f194553345f460d9faf27f9c08ade481be21ea46 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 13 Oct 2022 18:13:57 +0200 Subject: [PATCH] Test not working --- plonky2/src/plonk/circuit_builder.rs | 4 + .../conditional_recursive_verifier.rs | 124 +++++----- plonky2/src/recursion/cyclic_recursion.rs | 227 ++++++++++++++++++ plonky2/src/recursion/mod.rs | 1 + plonky2/src/recursion/recursive_verifier.rs | 195 --------------- 5 files changed, 294 insertions(+), 257 deletions(-) create mode 100644 plonky2/src/recursion/cyclic_recursion.rs diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 16d42685..d5a748e5 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -144,6 +144,10 @@ impl, const D: usize> CircuitBuilder { targets.iter().for_each(|&t| self.register_public_input(t)); } + pub fn num_public_inputs(&self) -> usize { + self.public_inputs.len() + } + /// Adds a new "virtual" target. This is not an actual wire in the witness, but just a target /// that help facilitate witness generation. In particular, a generator can assign a values to a /// virtual target, which can then be copied to other (virtual or concrete) targets. When we diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index 8ac0a4f2..8f53046c 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -66,9 +66,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 +124,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 +137,10 @@ 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() + 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 +158,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 +174,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 +186,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 +241,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 +269,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 +290,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 +306,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() @@ -384,9 +384,9 @@ mod tests { 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, ); diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs new file mode 100644 index 00000000..d39bfcf7 --- /dev/null +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -0,0 +1,227 @@ +use anyhow::Result; +use plonky2_field::extension::Extendable; + +use crate::gates::noop::NoopGate; +use crate::hash::hash_types::RichField; +use crate::iop::target::BoolTarget; +use crate::iop::witness::{PartialWitness, Witness}; +use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::{ + CircuitData, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, +}; +use crate::plonk::config::Hasher; +use crate::plonk::config::{AlgebraicHasher, GenericConfig}; +use crate::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; +use crate::recursion::conditional_recursive_verifier::dummy_proof; + +pub struct CyclicRecursionData< + 'a, + F: RichField + Extendable, + C: GenericConfig, + const D: usize, +> { + proof: &'a Option>, + verifier_data: &'a VerifierOnlyCircuitData, + common_data: &'a CommonCircuitData, +} + +pub struct CyclicRecursionTarget { + pub proof: ProofWithPublicInputsTarget, + pub verifier_data: VerifierCircuitTarget, + pub dummy_proof: ProofWithPublicInputsTarget, + pub dummy_verifier_data: VerifierCircuitTarget, + pub base_case: BoolTarget, +} + +impl, const D: usize> CircuitBuilder { + pub fn cyclic_recursion>( + mut self, + mut common_data: CommonCircuitData, + ) -> Result<(CircuitData, CyclicRecursionTarget)> + where + C::Hasher: AlgebraicHasher, + [(); C::Hasher::HASH_SIZE]:, + { + let verifier_data = VerifierCircuitTarget { + constants_sigmas_cap: self.add_virtual_cap(self.config.fri_config.cap_height), + circuit_digest: self.add_virtual_hash(), + }; + self.register_public_inputs(&verifier_data.circuit_digest.elements); + for i in 0..self.config.fri_config.num_cap_elements() { + self.register_public_inputs(&verifier_data.constants_sigmas_cap.0[i].elements); + } + let dummy_verifier_data = VerifierCircuitTarget { + constants_sigmas_cap: self.add_virtual_cap(self.config.fri_config.cap_height), + circuit_digest: self.add_virtual_hash(), + }; + let base_case = self.add_virtual_bool_target(); + self.register_public_input(base_case.target); + + common_data.num_public_inputs = self.num_public_inputs(); + common_data.degree_bits = common_data.degree_bits.max(13); + dbg!(common_data.degree_bits); + + let proof = self.add_virtual_proof_with_pis(&common_data); + let dummy_proof = self.add_virtual_proof_with_pis(&common_data); + + self.conditionally_verify_proof( + base_case, + &dummy_proof, + &dummy_verifier_data, + &proof, + &verifier_data, + &common_data, + ); + + while self.num_gates() < 1 << (common_data.degree_bits - 1) { + self.add_gate(NoopGate, vec![]); + } + + let data = self.build::(); + dbg!(&data.common.degree_bits, common_data.degree_bits); + assert_eq!(&data.common, &common_data); + Ok(( + data, + CyclicRecursionTarget { + proof, + verifier_data, + dummy_proof, + dummy_verifier_data, + base_case, + }, + )) + } +} + +/// Set the targets in a `ProofTarget` to their corresponding values in a `Proof`. +pub fn set_cyclic_recursion_data_target< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, +>( + pw: &mut PartialWitness, + cyclic_recursion_data_target: &CyclicRecursionTarget, + cyclic_recursion_data: &CyclicRecursionData, +) -> Result<()> +where + F: RichField + Extendable, + C::Hasher: AlgebraicHasher, + [(); C::Hasher::HASH_SIZE]:, +{ + if let Some(proof) = cyclic_recursion_data.proof { + pw.set_bool_target(cyclic_recursion_data_target.base_case, false); + pw.set_proof_with_pis_target(&cyclic_recursion_data_target.proof, proof); + pw.set_verifier_data_target( + &cyclic_recursion_data_target.verifier_data, + cyclic_recursion_data.verifier_data, + ); + pw.set_proof_with_pis_target(&cyclic_recursion_data_target.dummy_proof, proof); + pw.set_verifier_data_target( + &cyclic_recursion_data_target.dummy_verifier_data, + cyclic_recursion_data.verifier_data, + ); + } else { + let (dummy_proof, dummy_data) = dummy_proof(cyclic_recursion_data.common_data)?; + pw.set_bool_target(cyclic_recursion_data_target.base_case, true); + pw.set_proof_with_pis_target(&cyclic_recursion_data_target.proof, &dummy_proof); + pw.set_verifier_data_target( + &cyclic_recursion_data_target.verifier_data, + &dummy_data.verifier_only, + ); + pw.set_proof_with_pis_target(&cyclic_recursion_data_target.dummy_proof, &dummy_proof); + pw.set_verifier_data_target( + &cyclic_recursion_data_target.dummy_verifier_data, + &dummy_data.verifier_only, + ); + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use anyhow::Result; + use plonky2_field::extension::Extendable; + + use crate::field::types::Field; + use crate::hash::hash_types::RichField; + use crate::hash::poseidon::PoseidonHash; + use crate::iop::witness::{PartialWitness, Witness}; + use crate::plonk::circuit_builder::CircuitBuilder; + use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData, VerifierCircuitTarget}; + use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig}; + use crate::recursion::cyclic_recursion::{ + set_cyclic_recursion_data_target, CyclicRecursionData, + }; + + fn common_data_for_recursion< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, + >() -> CommonCircuitData + where + C::Hasher: AlgebraicHasher, + [(); C::Hasher::HASH_SIZE]:, + { + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config); + let data = builder.build::(); + let config = CircuitConfig::standard_recursion_config(); + let mut pw = PartialWitness::::new(); + let mut builder = CircuitBuilder::::new(config); + let proof = builder.add_virtual_proof_with_pis(&data.common); + let verifier_data = VerifierCircuitTarget { + constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), + circuit_digest: builder.add_virtual_hash(), + }; + builder.verify_proof(proof, &verifier_data, &data.common); + let data = builder.build::(); + + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config); + let data = builder.build::(); + let config = CircuitConfig::standard_recursion_config(); + let mut pw = PartialWitness::::new(); + let mut builder = CircuitBuilder::::new(config); + let proof = builder.add_virtual_proof_with_pis(&data.common); + let verifier_data = VerifierCircuitTarget { + constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), + circuit_digest: builder.add_virtual_hash(), + }; + builder.verify_proof(proof, &verifier_data, &data.common); + builder.build::().common + } + + #[test] + fn test_cyclic_recursion() -> Result<()> { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + + let config = CircuitConfig::standard_recursion_config(); + let mut pw = PartialWitness::new(); + let mut builder = CircuitBuilder::::new(config); + + // Build realistic circuit + let t = builder.add_virtual_target(); + pw.set_target(t, F::rand()); + let t_inv = builder.inverse(t); + let h = builder.hash_n_to_hash_no_pad::(vec![t_inv]); + builder.register_public_inputs(&h.elements); + + let common_data = common_data_for_recursion::(); + dbg!(common_data.degree_bits); + + let (cyclic_circuit_data, cyclic_data_target) = builder.cyclic_recursion(common_data)?; + let cyclic_recursion_data = CyclicRecursionData { + proof: &None, + verifier_data: &cyclic_circuit_data.verifier_only, + common_data: &cyclic_circuit_data.common, + }; + set_cyclic_recursion_data_target(&mut pw, &cyclic_data_target, &cyclic_recursion_data)?; + let proof = cyclic_circuit_data.prove(pw)?; + cyclic_circuit_data.verify(proof); + + Ok(()) + } +} diff --git a/plonky2/src/recursion/mod.rs b/plonky2/src/recursion/mod.rs index b83c4a85..33e8212e 100644 --- a/plonky2/src/recursion/mod.rs +++ b/plonky2/src/recursion/mod.rs @@ -1,2 +1,3 @@ pub mod conditional_recursive_verifier; +pub mod cyclic_recursion; pub mod recursive_verifier; diff --git a/plonky2/src/recursion/recursive_verifier.rs b/plonky2/src/recursion/recursive_verifier.rs index c35f21e2..7d901236 100644 --- a/plonky2/src/recursion/recursive_verifier.rs +++ b/plonky2/src/recursion/recursive_verifier.rs @@ -455,199 +455,4 @@ mod tests { fn init_logger() { let _ = env_logger::builder().format_timestamp(None).try_init(); } - - #[test] - fn test_cyclic_recursion() -> Result<()> { - const D: usize = 2; - type C = PoseidonGoldilocksConfig; - type F = >::F; - // type FF = >::FE; - - let config = CircuitConfig::standard_recursion_config(); - let (proof, vd, cd) = dummy_proof::(&config, 1 << 14)?; - - let (proof, vd, cd) = - recursive_proof::(proof, vd, cd, &config, None, false, false)?; - let (_proof, _vd, mut cd) = - recursive_proof::(proof, vd, cd, &config, Some(14), false, false)?; - cd.num_public_inputs = 69; - - // First proof - let config = CircuitConfig::standard_recursion_config(); - let mut pw = PartialWitness::new(); - let mut builder = CircuitBuilder::::new(config); - - let verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: builder.add_virtual_cap(builder.config.fri_config.cap_height), - circuit_digest: builder.add_virtual_hash(), - }; - builder.register_public_inputs(&verifier_data.circuit_digest.elements); - for i in 0..1 << builder.config.fri_config.cap_height { - builder.register_public_inputs(&verifier_data.constants_sigmas_cap.0[i].elements); - } - let dummy_verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: builder.add_virtual_cap(builder.config.fri_config.cap_height), - circuit_digest: builder.add_virtual_hash(), - }; - let condition = builder.add_virtual_bool_target(); - builder.register_public_input(condition.target); - pw.set_bool_target(condition, false); - - let (dummy_proof, dummy_data) = - crate::recursion::conditional_recursive_verifier::dummy_proof(&cd)?; - let pt0 = builder.add_virtual_proof_with_pis(&cd); - let pt1 = builder.add_virtual_proof_with_pis(&cd); - - pw.set_proof_with_pis_target(&pt0, &dummy_proof); - pw.set_proof_with_pis_target(&pt1, &dummy_proof); - pw.set_hash_target( - dummy_verifier_data.circuit_digest, - dummy_data.verifier_only.circuit_digest, - ); - pw.set_cap_target( - &dummy_verifier_data.constants_sigmas_cap, - &dummy_data.verifier_only.constants_sigmas_cap, - ); - - builder.conditionally_verify_proof( - condition, - pt0, - &verifier_data, - pt1, - &dummy_verifier_data, - &cd, - ); - - while builder.num_gates() < 1 << 13 { - builder.add_gate(NoopGate, vec![]); - } - - let data = builder.build::(); - dbg!(cd.degree_bits); - dbg!(data.common.degree_bits); - assert_eq!(&data.common, &cd); - pw.set_verifier_data_target(&verifier_data, &data.verifier_only); - let proof = data.prove(pw)?; - assert_eq!( - data.verifier_only.circuit_digest.elements[0], - proof.public_inputs[0] - ); - data.verify(proof.clone())?; - - // Second proof - let config = CircuitConfig::standard_recursion_config(); - let mut pw = PartialWitness::new(); - let mut builder = CircuitBuilder::::new(config); - - let verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: builder.add_virtual_cap(builder.config.fri_config.cap_height), - circuit_digest: builder.add_virtual_hash(), - }; - builder.register_public_inputs(&verifier_data.circuit_digest.elements); - for i in 0..1 << builder.config.fri_config.cap_height { - builder.register_public_inputs(&verifier_data.constants_sigmas_cap.0[i].elements); - } - let dummy_verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: builder.add_virtual_cap(builder.config.fri_config.cap_height), - circuit_digest: builder.add_virtual_hash(), - }; - let condition = builder.add_virtual_bool_target(); - builder.register_public_input(condition.target); - pw.set_bool_target(condition, true); - - let pt0 = builder.add_virtual_proof_with_pis(&data.common); - let pt1 = builder.add_virtual_proof_with_pis(&data.common); - - pw.set_proof_with_pis_target(&pt0, &proof); - pw.set_proof_with_pis_target(&pt1, &proof); - - builder.conditionally_verify_proof( - condition, - pt0, - &verifier_data, - pt1, - &dummy_verifier_data, - &data.common, - ); - - while builder.num_gates() < 1 << 13 { - builder.add_gate(NoopGate, vec![]); - } - - let data1 = builder.build::(); - assert_eq!(data.common, data1.common); - assert_eq!(data.verifier_only, data1.verifier_only); - dbg!(cd.degree_bits); - dbg!(data1.common.degree_bits); - pw.set_verifier_data_target(&verifier_data, &data.verifier_only); - pw.set_verifier_data_target(&dummy_verifier_data, &data.verifier_only); - let proof = data.prove(pw)?; - assert_eq!( - data.verifier_only.circuit_digest.elements[0], - proof.public_inputs[0] - ); - assert_eq!( - data1.verifier_only.circuit_digest.elements[0], - proof.public_inputs[0] - ); - data.verify(proof.clone())?; - - // Second proof - let config = CircuitConfig::standard_recursion_config(); - let mut pw = PartialWitness::new(); - let mut builder = CircuitBuilder::::new(config); - - let verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: builder.add_virtual_cap(builder.config.fri_config.cap_height), - circuit_digest: builder.add_virtual_hash(), - }; - builder.register_public_inputs(&verifier_data.circuit_digest.elements); - for i in 0..1 << builder.config.fri_config.cap_height { - builder.register_public_inputs(&verifier_data.constants_sigmas_cap.0[i].elements); - } - let dummy_verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: builder.add_virtual_cap(builder.config.fri_config.cap_height), - circuit_digest: builder.add_virtual_hash(), - }; - let condition = builder.add_virtual_bool_target(); - builder.register_public_input(condition.target); - pw.set_bool_target(condition, true); - - let pt0 = builder.add_virtual_proof_with_pis(&data.common); - let pt1 = builder.add_virtual_proof_with_pis(&data.common); - - pw.set_proof_with_pis_target(&pt0, &proof); - pw.set_proof_with_pis_target(&pt1, &proof); - - builder.conditionally_verify_proof( - condition, - pt0, - &verifier_data, - pt1, - &dummy_verifier_data, - &data.common, - ); - - while builder.num_gates() < 1 << 13 { - builder.add_gate(NoopGate, vec![]); - } - - let data2 = builder.build::(); - assert_eq!(data.common, data2.common); - assert_eq!(data.verifier_only, data2.verifier_only); - dbg!(cd.degree_bits); - dbg!(data1.common.degree_bits); - pw.set_verifier_data_target(&verifier_data, &data.verifier_only); - pw.set_verifier_data_target(&dummy_verifier_data, &data.verifier_only); - let proof = data.prove(pw)?; - assert_eq!( - data.verifier_only.circuit_digest.elements[0], - proof.public_inputs[0] - ); - assert_eq!( - data1.verifier_only.circuit_digest.elements[0], - proof.public_inputs[0] - ); - data.verify(proof) - } }