plonky2-semaphore/src/access_set.rs
src/access_set.rsRaw
1use anyhow::Result;
2use plonky2::hash::merkle_tree::MerkleTree;
3use plonky2::hash::poseidon::PoseidonHash;
4use plonky2::iop::witness::PartialWitness;
5use plonky2::plonk::circuit_builder::CircuitBuilder;
6use plonky2::plonk::circuit_data::{CircuitConfig, VerifierCircuitData};
7use plonky2::plonk::config::Hasher;
8use plonky2::plonk::proof::ProofWithPublicInputs;
9
10use crate::signal::{Digest, Signal, C, F};
11
12pub struct AccessSet(pub MerkleTree<F, PoseidonHash>);
13
14impl AccessSet {
15 pub fn verify_signal(
16 &self,
17 topic: Digest,
18 signal: Signal,
19 verifier_data: &VerifierCircuitData<F, C, 2>,
20 ) -> Result<()> {
21 let public_inputs: Vec<F> = self
22 .0
23 .cap
24 .0
25 .iter()
26 .flat_map(|h| h.elements)
27 .chain(signal.nullifier)
28 .chain(topic)
29 .collect();
30
31 verifier_data.verify(ProofWithPublicInputs {
32 proof: signal.proof,
33 public_inputs,
34 })
35 }
36
37 pub fn make_signal(
38 &self,
39 private_key: Digest,
40 topic: Digest,
41 public_key_index: usize,
42 ) -> Result<(Signal, VerifierCircuitData<F, C, 2>)> {
43 let nullifier = PoseidonHash::hash_no_pad(&[private_key, topic].concat()).elements;
44 let config = CircuitConfig::standard_recursion_zk_config();
45 let mut builder = CircuitBuilder::new(config);
46 let mut pw = PartialWitness::new();
47
48 let targets = self.semaphore_circuit(&mut builder);
49 self.fill_semaphore_targets(&mut pw, private_key, topic, public_key_index, targets)?;
50
51 let data = builder.build();
52 let proof = data.prove(pw)?;
53
54 Ok((
55 Signal {
56 nullifier,
57 proof: proof.proof,
58 },
59 data.verifier_data(),
60 ))
61 }
62}