arnaucube
arnaucube/plonky2-semaphorePublic Self-hosted repository
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}