plonky2-semaphore/src/recursion.rs
src/recursion.rsRaw
1use anyhow::Result;
2use plonky2::iop::witness::{PartialWitness, WitnessWrite};
3use plonky2::plonk::circuit_builder::CircuitBuilder;
4use plonky2::plonk::circuit_data::{CircuitConfig, VerifierCircuitData};
5use plonky2::plonk::proof::ProofWithPublicInputs;
6
7use crate::access_set::AccessSet;
8use crate::signal::{Digest, PlonkyProof, Signal, C, F};
9
10impl AccessSet {
11 pub fn aggregate_signals(
12 &self,
13 topic0: Digest,
14 signal0: Signal,
15 topic1: Digest,
16 signal1: Signal,
17 verifier_data: &VerifierCircuitData<F, C, 2>,
18 ) -> Result<(Digest, Digest, PlonkyProof, VerifierCircuitData<F, C, 2>)> {
19 let config = CircuitConfig::standard_recursion_zk_config();
20 let mut builder = CircuitBuilder::new(config);
21 let mut pw = PartialWitness::new();
22
23 let public_inputs0: Vec<F> = self
24 .0
25 .cap
26 .0
27 .iter()
28 .flat_map(|h| h.elements)
29 .chain(signal0.nullifier)
30 .chain(topic0)
31 .collect();
32 let public_inputs1: Vec<F> = self
33 .0
34 .cap
35 .0
36 .iter()
37 .flat_map(|h| h.elements)
38 .chain(signal1.nullifier)
39 .chain(topic1)
40 .collect();
41
42 let proof_target0 = builder.add_virtual_proof_with_pis(&verifier_data.common);
43 pw.set_proof_with_pis_target(
44 &proof_target0,
45 &ProofWithPublicInputs {
46 proof: signal0.proof,
47 public_inputs: public_inputs0,
48 },
49 )?;
50 let proof_target1 = builder.add_virtual_proof_with_pis(&verifier_data.common);
51 pw.set_proof_with_pis_target(
52 &proof_target1,
53 &ProofWithPublicInputs {
54 proof: signal1.proof,
55 public_inputs: public_inputs1,
56 },
57 )?;
58
59 let vd_target =
60 builder.add_virtual_verifier_data(verifier_data.common.config.fri_config.cap_height);
61 pw.set_cap_target(
62 &vd_target.constants_sigmas_cap,
63 &verifier_data.verifier_only.constants_sigmas_cap,
64 )?;
65
66 builder.verify_proof::<C>(&proof_target0, &vd_target, &verifier_data.common);
67 builder.verify_proof::<C>(&proof_target1, &vd_target, &verifier_data.common);
68
69 let data = builder.build();
70 let recursive_proof = data.prove(pw).unwrap();
71
72 data.verify(recursive_proof.clone()).unwrap();
73
74 Ok((
75 signal0.nullifier,
76 signal1.nullifier,
77 recursive_proof.proof,
78 data.verifier_data(),
79 ))
80 }
81}