Skip to content

Commit

Permalink
Add inline comments describing the usage of methods
Browse files Browse the repository at this point in the history
and update the Semaphore link to the current one.
  • Loading branch information
arnaucube committed Sep 27, 2024
1 parent dc9c32c commit 80994f9
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 11 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Plonky2 implementation of the [Semaphore protocol](http://semaphore.appliedzkp.org/)
# Plonky2 implementation of the [Semaphore protocol](https://semaphore.pse.dev)

Used as an example in the ZKHack Plonky2 presentation.

## Compilation
```bash
rustup override set nightly # Requires nightly Rust
cargo test --release
```
```
2 changes: 2 additions & 0 deletions src/access_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::signal::{Digest, Signal, C, F};
pub struct AccessSet(pub MerkleTree<F, PoseidonHash>);

impl AccessSet {
// Verify the plonky2 proof of the given nullifier (in the signal structure) and topic.
pub fn verify_signal(
&self,
topic: Digest,
Expand All @@ -34,6 +35,7 @@ impl AccessSet {
})
}

// Generate the plonky2 proof for the given key pair and topic.
pub fn make_signal(
&self,
private_key: Digest,
Expand Down
15 changes: 15 additions & 0 deletions src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ impl AccessSet {
}

pub fn semaphore_circuit(&self, builder: &mut CircuitBuilder<F, 2>) -> SemaphoreTargets {
// To create the circuit 'values', we call the `add_virtual_target` and it's variants (ie.
// `add_virtual_target_arr`, or `add_virtual_hash` which internally calls it for the 4
// field values that conform the hash.
// The method `add_virtual_target` keeps an incremental index for each new virtual target
// created, and returns a new `VirtualTarget`, used for intermediate values in witness
// generation (which when needed can be copied to specific witness location (Wire)).
//
// The `register_public_input` and it's variants, append to the CircuitBuilder's
// `public_inputs` vector the given Target (either VirtualTarget or Wire).
//
// Notice that when created, the targets are not given any value, and they will be set later
// at the method `fill_semaphore_targets`.

// Register public inputs.
let merkle_root = builder.add_virtual_hash();
builder.register_public_inputs(&merkle_root.elements);
Expand Down Expand Up @@ -65,6 +78,8 @@ impl AccessSet {
}
}

// Fill the semaphore targets that we defined at the method `semaphore_circuit` with the given
// values.
pub fn fill_semaphore_targets(
&self,
pw: &mut PartialWitness<F>,
Expand Down
16 changes: 7 additions & 9 deletions src/recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,26 @@ impl AccessSet {
.chain(topic1)
.collect();

// `add_virtual_proof_with_pis` is an extended version of the `add_virtual_target`, but
// that takes care of adding all the values of the proof and the public inputs (pis).
let proof_target0 = builder.add_virtual_proof_with_pis(&verifier_data.common);
// set the public inputs
builder.register_public_inputs(&proof_target0.public_inputs);
// `set_proof_with_pis_target` is an extended version of the `set_target`, but that takes
// care of adding all the values of the proof and the public inputs.
pw.set_proof_with_pis_target(
&proof_target0,
&ProofWithPublicInputs {
proof: signal0.proof,
public_inputs: public_inputs0,
},
)?;
// add & set the verifier data
let vd_target =
builder.add_virtual_verifier_data(verifier_data.common.config.fri_config.cap_height);
pw.set_verifier_data_target(&vd_target, &verifier_data.verifier_only)?;

// now, the same as we did with the proof0, with the proof1 related values:
let proof_target1 = builder.add_virtual_proof_with_pis(&verifier_data.common);
builder.register_public_inputs(&proof_target1.public_inputs);
pw.set_proof_with_pis_target(
Expand Down Expand Up @@ -95,7 +102,6 @@ mod tests {
use plonky2::hash::poseidon::PoseidonHash;
use plonky2::plonk::config::Hasher;
use plonky2::plonk::proof::ProofWithPublicInputs;
use std::time::Instant;

use crate::access_set::AccessSet;
use crate::signal::{Digest, F};
Expand All @@ -117,24 +123,18 @@ mod tests {
// first proof
let i0 = 12;
let topic0 = F::rand_array();
let start = Instant::now();
let (signal0, vd0) = access_set.make_signal(private_keys[i0], topic0, i0)?;
println!("generate proof: {:?}", start.elapsed());
access_set.verify_signal(topic0, signal0.clone(), &vd0)?;

// second proof
let i1 = 42;
let topic1 = F::rand_array();
let start = Instant::now();
let (signal1, vd1) = access_set.make_signal(private_keys[i1], topic1, i1)?;
println!("generate proof: {:?}", start.elapsed());
access_set.verify_signal(topic1, signal1.clone(), &vd1)?;

// generate recursive proof
let start = Instant::now();
let (nullifier0, nullifier1, recursive_proof, vd2) =
access_set.aggregate_signals(topic0, signal0, topic1, signal1, &vd0)?;
println!("aggregate_signals (recursive prove): {:?}", start.elapsed());

// verify recursive proof
let public_inputs: Vec<F> = access_set
Expand All @@ -150,12 +150,10 @@ mod tests {
.chain(topic1)
.collect();

let start = Instant::now();
vd2.verify(ProofWithPublicInputs {
proof: recursive_proof,
public_inputs,
})?;
println!("verify recursive proof: {:?}", start.elapsed());
Ok(())
}
}
2 changes: 2 additions & 0 deletions src/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ mod tests {
let i = 12;
let topic = F::rand_array();

// generate the plonky2 proof for the given key
let (signal, vd) = access_set.make_signal(private_keys[i], topic, i)?;
// verify the plonky2 proof (contained in `signal`
access_set.verify_signal(topic, signal, &vd)
}
}

0 comments on commit 80994f9

Please sign in to comment.