Browse Source

Add inline comments describing the usage of methods

and update the Semaphore link to the current one.
ivc
arnaucube 6 months ago
parent
commit
80994f96b7
5 changed files with 28 additions and 11 deletions
  1. +2
    -2
      README.md
  2. +2
    -0
      src/access_set.rs
  3. +15
    -0
      src/circuit.rs
  4. +7
    -9
      src/recursion.rs
  5. +2
    -0
      src/signal.rs

+ 2
- 2
README.md

@ -1,4 +1,4 @@
# 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.
@ -6,4 +6,4 @@ Used as an example in the ZKHack Plonky2 presentation.
```bash
rustup override set nightly # Requires nightly Rust
cargo test --release
```
```

+ 2
- 0
src/access_set.rs

@ -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,
@ -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,

+ 15
- 0
src/circuit.rs

@ -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);
@ -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>,

+ 7
- 9
src/recursion.rs

@ -39,8 +39,13 @@ 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 {
@ -48,10 +53,12 @@ impl AccessSet {
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(
@ -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};
@ -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
@ -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
- 0
src/signal.rs

@ -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)
}
}

Loading…
Cancel
Save