From c47f767fc57e53aa8dc15004a2c0d8279fd6e800 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 27 Oct 2022 15:45:14 +0200 Subject: [PATCH] PR feedback --- plonky2/src/plonk/circuit_builder.rs | 22 ++++++++++- plonky2/src/recursion/cyclic_recursion.rs | 47 +++++++---------------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 5327fc9b..dfd23426 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -34,7 +34,7 @@ use crate::iop::target::{BoolTarget, Target}; use crate::iop::wire::Wire; use crate::plonk::circuit_data::{ CircuitConfig, CircuitData, CommonCircuitData, ProverCircuitData, ProverOnlyCircuitData, - VerifierCircuitData, VerifierOnlyCircuitData, + VerifierCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; use crate::plonk::config::{GenericConfig, Hasher}; use crate::plonk::copy_constraint::CopyConstraint; @@ -88,6 +88,10 @@ pub struct CircuitBuilder, const D: usize> { /// common data doesn't equal `goal_data`. /// This is used in cyclic recursion. pub(crate) goal_common_data: Option>, + + /// Optional verifier data that is registered as public inputs. + /// This is used in cyclic recursion to hold the circuit's own verifier key. + pub(crate) verifier_data_public_input: Option, } impl, const D: usize> CircuitBuilder { @@ -108,6 +112,7 @@ impl, const D: usize> CircuitBuilder { current_slots: HashMap::new(), constant_generators: Vec::new(), goal_common_data: None, + verifier_data_public_input: None, }; builder.check_config(); builder @@ -224,6 +229,21 @@ impl, const D: usize> CircuitBuilder { self.register_public_input(t); t } + /// Add a virtual verifier data, register it as a public input and set it to `self.verifier_data_public_input`. + /// WARNING: Do not register any public input after calling this! TODO: relax this + pub(crate) fn add_verifier_data_public_input(&mut self) { + let verifier_data = VerifierCircuitTarget { + constants_sigmas_cap: self.add_virtual_cap(self.config.fri_config.cap_height), + circuit_digest: self.add_virtual_hash(), + }; + // The verifier data are public inputs. + 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); + } + + self.verifier_data_public_input = Some(verifier_data); + } /// Adds a gate to the circuit, and returns its index. pub fn add_gate>(&mut self, gate_type: G, mut constants: Vec) -> usize { diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index 98661a92..f2ad7eb9 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -89,48 +89,31 @@ impl VerifierCircuitTarget { } impl, const D: usize> CircuitBuilder { - /// Add verifier data and register it as public inputs. - /// WARNING: Do not register any public input after calling this! - pub fn verifier_data_for_cyclic_recursion>( - &mut self, - ) -> VerifierCircuitTarget - 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(), - }; - // The verifier data are public inputs. - 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); - } - - verifier_data - } - /// Cyclic recursion gadget. - /// WARNING: Do not register any public input after calling this! + /// WARNING: Do not register any public input after calling this! TODO: relax this pub fn cyclic_recursion>( &mut self, + // Flag set to true for the base case of the cycle where we verify a dummy proof to bootstrap the cycle. Set to false otherwise. + base_case: BoolTarget, previous_virtual_public_inputs: &[Target], - verifier_data: &VerifierCircuitTarget, // should be registered as public inputs already - common_data: &CommonCircuitData, + common_data: &mut CommonCircuitData, ) -> Result> where C::Hasher: AlgebraicHasher, [(); C::Hasher::HASH_SIZE]:, { + if self.verifier_data_public_input.is_none() { + self.add_verifier_data_public_input(); + } + let verifier_data = self.verifier_data_public_input.clone().unwrap(); + common_data.num_public_inputs = self.num_public_inputs(); + self.goal_common_data = Some(common_data.clone()); + let dummy_verifier_data = VerifierCircuitTarget { constants_sigmas_cap: self.add_virtual_cap(self.config.fri_config.cap_height), circuit_digest: self.add_virtual_hash(), }; - // Flag set to true for the base case of the cycle where we verify a dummy proof to bootstrap the cycle. Set to false otherwise. - let base_case = self.add_virtual_bool_target_safe(); - let proof = self.add_virtual_proof_with_pis::(common_data); let dummy_proof = self.add_virtual_proof_with_pis::(common_data); @@ -159,7 +142,7 @@ impl, const D: usize> CircuitBuilder { &dummy_proof, &dummy_verifier_data, &proof, - verifier_data, + &verifier_data, common_data, ); @@ -359,12 +342,10 @@ mod tests { let mut common_data = common_data_for_recursion::(); - let verifier_data = builder.verifier_data_for_cyclic_recursion::(); - common_data.num_public_inputs = builder.num_public_inputs(); - + let base_case = builder.add_virtual_bool_target_safe(); // Add cyclic recursion gadget. let cyclic_data_target = - builder.cyclic_recursion::(&old_pis, &verifier_data, &common_data)?; + builder.cyclic_recursion::(base_case, &old_pis, &mut common_data)?; let input_hash_bis = builder.select_hash(cyclic_data_target.base_case, initial_hash, old_hash); builder.connect_hashes(input_hash, input_hash_bis);