arnaucube
arnaucube/plonky2-semaphorePublic Self-hosted repository
plonky2-semaphore/src/signal.rs
src/signal.rsRaw
 1use plonky2::field::goldilocks_field::GoldilocksField;
 2use plonky2::plonk::config::PoseidonGoldilocksConfig;
 3use plonky2::plonk::proof::Proof;
 4
 5pub type F = GoldilocksField;
 6pub type Digest = [F; 4];
 7pub type C = PoseidonGoldilocksConfig;
 8pub type PlonkyProof = Proof<F, PoseidonGoldilocksConfig, 2>;
 9
10#[derive(Debug, Clone)]
11pub struct Signal {
12    pub nullifier: Digest,
13    pub proof: PlonkyProof,
14}
15
16#[cfg(test)]
17mod tests {
18    use anyhow::Result;
19    use plonky2::field::types::{Field, Sample};
20    use plonky2::hash::merkle_tree::MerkleTree;
21    use plonky2::hash::poseidon::PoseidonHash;
22    use plonky2::plonk::config::Hasher;
23
24    use crate::access_set::AccessSet;
25    use crate::signal::{Digest, F};
26
27    #[test]
28    fn test_semaphore() -> Result<()> {
29        let n = 1 << 20;
30        let private_keys: Vec<Digest> = (0..n).map(|_| F::rand_array()).collect();
31        let public_keys: Vec<Vec<F>> = private_keys
32            .iter()
33            .map(|&sk| {
34                PoseidonHash::hash_no_pad(&[sk, [F::ZERO; 4]].concat())
35                    .elements
36                    .to_vec()
37            })
38            .collect();
39        let access_set = AccessSet(MerkleTree::new(public_keys, 0));
40
41        let i = 12;
42        let topic = F::rand_array();
43
44        // generate the plonky2 proof for the given key
45        let (signal, vd) = access_set.make_signal(private_keys[i], topic, i)?;
46        // verify the plonky2 proof (contained in `signal`)
47        access_set.verify_signal(topic, signal, &vd)
48    }
49}