diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 5f153c637e..eaa11f2b35 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -531,6 +531,14 @@ impl, const D: usize> CircuitBuilder { } } + /// If `condition`, enforces that two routable `Target` values are equal, using Plonk's permutation argument. + pub fn conditional_assert_eq(&mut self, condition: Target, x: Target, y: Target) { + let zero = self.zero(); + let diff = self.sub(x, y); + let constr = self.mul(condition, diff); + self.connect(constr, zero); + } + /// Enforces that a routable `Target` value is 0, using Plonk's permutation argument. pub fn assert_zero(&mut self, x: Target) { let zero = self.zero(); diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index 2dc6966a20..c41a9b583a 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -34,18 +34,8 @@ impl, const D: usize> CircuitBuilder { { let selected_proof = self.select_proof_with_pis(condition, proof_with_pis0, proof_with_pis1); - let selected_verifier_data = VerifierCircuitTarget { - constants_sigmas_cap: self.select_cap( - condition, - &inner_verifier_data0.constants_sigmas_cap, - &inner_verifier_data1.constants_sigmas_cap, - ), - circuit_digest: self.select_hash( - condition, - inner_verifier_data0.circuit_digest, - inner_verifier_data1.circuit_digest, - ), - }; + let selected_verifier_data = + self.select_verifier_data(condition, inner_verifier_data0, inner_verifier_data1); self.verify_proof::(&selected_proof, &selected_verifier_data, inner_common_data); } @@ -75,7 +65,7 @@ impl, const D: usize> CircuitBuilder { } /// Computes `if b { proof_with_pis0 } else { proof_with_pis1 }`. - fn select_proof_with_pis( + pub fn select_proof_with_pis( &mut self, b: BoolTarget, proof_with_pis0: &ProofWithPublicInputsTarget, @@ -179,6 +169,23 @@ impl, const D: usize> CircuitBuilder { .collect() } + /// Computes `if b { vk0 } else { vk1 }`. + pub fn select_verifier_data( + &mut self, + b: BoolTarget, + vk0: &VerifierCircuitTarget, + vk1: &VerifierCircuitTarget, + ) -> VerifierCircuitTarget { + VerifierCircuitTarget { + constants_sigmas_cap: self.select_cap( + b, + &vk0.constants_sigmas_cap, + &vk1.constants_sigmas_cap, + ), + circuit_digest: self.select_hash(b, vk0.circuit_digest, vk1.circuit_digest), + } + } + /// Computes `if b { os0 } else { os1 }`. fn select_opening_set( &mut self, diff --git a/plonky2/src/recursion/dummy_circuit.rs b/plonky2/src/recursion/dummy_circuit.rs index 75b3929e82..1dc872db5a 100644 --- a/plonky2/src/recursion/dummy_circuit.rs +++ b/plonky2/src/recursion/dummy_circuit.rs @@ -67,11 +67,7 @@ where /// Generate a proof for a dummy circuit. The `public_inputs` parameter let the caller specify /// certain public inputs (identified by their indices) which should be given specific values. /// The rest will default to zero. -pub(crate) fn dummy_proof< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, ->( +pub fn dummy_proof, C: GenericConfig, const D: usize>( circuit: &CircuitData, nonzero_public_inputs: HashMap, ) -> anyhow::Result> @@ -86,11 +82,7 @@ where } /// Generate a circuit matching a given `CommonCircuitData`. -pub(crate) fn dummy_circuit< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, ->( +pub fn dummy_circuit, C: GenericConfig, const D: usize>( common_data: &CommonCircuitData, ) -> CircuitData { let config = common_data.config.clone(); @@ -143,6 +135,20 @@ impl, const D: usize> CircuitBuilder { Ok((dummy_proof_with_pis_target, dummy_verifier_data_target)) } + + pub fn dummy_proof_and_constant_vk_no_generator + 'static>( + &mut self, + common_data: &CommonCircuitData, + ) -> anyhow::Result<(ProofWithPublicInputsTarget, VerifierCircuitTarget)> + where + C::Hasher: AlgebraicHasher, + { + let dummy_circuit = dummy_circuit::(common_data); + let dummy_proof_with_pis_target = self.add_virtual_proof_with_pis(common_data); + let dummy_verifier_data_target = self.constant_verifier_data(&dummy_circuit.verifier_only); + + Ok((dummy_proof_with_pis_target, dummy_verifier_data_target)) + } } #[derive(Debug)]