Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
0xKitsune committed Mar 12, 2024
2 parents 74e1a9c + 0af6b37 commit 868328a
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 44 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: Build and Test
on: push

env:
RUST_VERSION: 1.70.0
NIGHTLY_VERSION: nightly-2023-05-31
RUST_VERSION: 1.76.0
NIGHTLY_VERSION: nightly-2024-02-04
CARGO_VET_VERSION: 0.7.0
CARGO_VET_REPO: https://github.com/mozilla/cargo-vet

Expand Down
46 changes: 36 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ version = "0.1.0"
edition = "2021"
authors = [
"Remco Bloemen <[email protected]>",
"Philipp Sippl <[email protected]>"]
"Philipp Sippl <[email protected]>",
]
homepage = "https://github.com/worldcoin/semaphore-rs"
repository = "https://github.com/worldcoin/semaphore-rs"
description = "Rust support library for Semaphore"
Expand All @@ -20,9 +21,18 @@ members = ["crates/*"]
default = []
bench = ["criterion", "proptest"]
dylib = ["wasmer/dylib", "wasmer-engine-dylib", "wasmer-compiler-cranelift"]
depth_16 = ["semaphore-depth-config/depth_16", "semaphore-depth-macros/depth_16"]
depth_20 = ["semaphore-depth-config/depth_20", "semaphore-depth-macros/depth_20"]
depth_30 = ["semaphore-depth-config/depth_30", "semaphore-depth-macros/depth_30"]
depth_16 = [
"semaphore-depth-config/depth_16",
"semaphore-depth-macros/depth_16",
]
depth_20 = [
"semaphore-depth-config/depth_20",
"semaphore-depth-macros/depth_20",
]
depth_30 = [
"semaphore-depth-config/depth_30",
"semaphore-depth-macros/depth_30",
]

[[bench]]
name = "criterion"
Expand All @@ -32,12 +42,23 @@ required-features = ["bench", "proptest"]

[dependencies]
ark-bn254 = { version = "0.3.0" }
ark-circom = { git = "https://github.com/gakonst/ark-circom", rev = "a93c8b0", features = ["circom-2"] }
ark-ec = { version = "0.3.0", default-features = false, features = ["parallel"] }
ark-ff = { version = "0.3.0", default-features = false, features = ["parallel", "asm"] }
ark-groth16 = { git = "https://github.com/arkworks-rs/groth16", rev = "765817f", features = ["parallel"] }
ark-circom = { git = "https://github.com/gakonst/ark-circom", rev = "a93c8b0", features = [
"circom-2",
] }
ark-ec = { version = "0.3.0", default-features = false, features = [
"parallel",
] }
ark-ff = { version = "0.3.0", default-features = false, features = [
"parallel",
"asm",
] }
ark-groth16 = { git = "https://github.com/arkworks-rs/groth16", rev = "765817f", features = [
"parallel",
] }
ark-relations = { version = "0.3.0", default-features = false }
ark-std = { version = "0.3.0", default-features = false, features = ["parallel"] }
ark-std = { version = "0.3.0", default-features = false, features = [
"parallel",
] }
color-eyre = "0.6"
criterion = { version = "0.3", optional = true, features = ["async_tokio"] }
hex = "0.4.0"
Expand All @@ -47,7 +68,12 @@ once_cell = "1.8"
proptest = { version = "1.0", optional = true }
rand = "0.8.4"
rayon = "1.5.1"
ruint = { git = "https://github.com/recmo/uint.git", rev = "1b14a406ec64e7e084c7e8116e349bc1a598e339", features = ["serde", "num-bigint", "ark-ff", "bytemuck"] }
ruint = { version = "=1.11.0", features = [
"serde",
"num-bigint",
"ark-ff",
"bytemuck",
] }
semaphore-depth-config = { path = "crates/semaphore-depth-config" }
serde = "1.0"
sha2 = "0.10.1"
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fn build_circuit(depth: usize) -> Result<()> {
#[cfg(feature = "dylib")]
fn build_dylib(depth: usize) -> Result<()> {
use color_eyre::eyre::eyre;
use enumset::enum_set;
use enumset::{enum_set, EnumSet};
use std::{env, str::FromStr};
use wasmer::{Module, Store, Target, Triple};
use wasmer_compiler_cranelift::Cranelift;
Expand Down
4 changes: 2 additions & 2 deletions crates/semaphore-depth-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ impl VisitMut for IdentReplacer {
}
}
syn::Expr::Macro(mcr) => {
let Ok(mut args) = mcr.mac.parse_body::<MacroArgs>() else {
return;
let Ok(mut args) = mcr.mac.parse_body::<MacroArgs>() else {
return;
};
for arg in &mut args.args {
self.visit_expr_mut(arg);
Expand Down
2 changes: 1 addition & 1 deletion mit-license.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The MIT License (MIT)

Copyright © 2021 Worldcoin
Copyright © 2021-2023 Worldcoin Foundation

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
2 changes: 1 addition & 1 deletion src/lazy_merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ impl<H: Hasher> MmapMutWrapper<H> {
};

file.set_len(file_size).expect("cannot set file size");
if file.write_all(&buf).is_err() {
if file.write_all(buf).is_err() {
return Err(DenseMMapError::FileCannotWriteBytes);
}

Expand Down
60 changes: 58 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ mod test {
hash_to_field,
identity::Identity,
poseidon_tree::LazyPoseidonTree,
protocol,
protocol::{generate_nullifier_hash, generate_proof, verify_proof},
Field,
};
Expand Down Expand Up @@ -90,6 +91,36 @@ mod test {
assert!(success);
}
}

#[test_all_depths]
fn test_auth_flow(depth: usize) {
let mut secret = *b"oh so secret";
let id = Identity::from_secret(&mut secret[..], None);
let signal_hash = hash_to_field(b"signal");
let external_nullifier_hash = hash_to_field(b"appId");
let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash);
let id_commitment = id.commitment();

let proof = protocol::authentication::generate_proof(
depth,
&id,
external_nullifier_hash,
signal_hash,
)
.unwrap();

let success = protocol::authentication::verify_proof(
depth,
id_commitment,
nullifier_hash,
signal_hash,
external_nullifier_hash,
&proof,
)
.unwrap();
assert!(success);
}

#[test_all_depths]
fn test_single(depth: usize) {
// Note that rust will still run tests in parallel
Expand All @@ -114,15 +145,19 @@ mod test {
#[cfg(feature = "bench")]
pub mod bench {
use crate::{
hash_to_field, identity::Identity, poseidon_tree::LazyPoseidonTree,
protocol::generate_proof, Field,
hash_to_field,
identity::Identity,
poseidon_tree::LazyPoseidonTree,
protocol::{generate_proof, generate_witness},
Field,
};
use criterion::Criterion;
use semaphore_depth_config::get_supported_depths;

pub fn group(criterion: &mut Criterion) {
for depth in get_supported_depths() {
bench_proof(criterion, *depth);
bench_witness(criterion, *depth);
}
crate::lazy_merkle_tree::bench::group(criterion);
}
Expand All @@ -147,4 +182,25 @@ pub mod bench {
});
});
}

fn bench_witness(criterion: &mut Criterion, depth: usize) {
let leaf = Field::from(0);

// Create tree
let mut hello = *b"hello";
let id = Identity::from_secret(&mut hello, None);
let mut tree = LazyPoseidonTree::new(depth, leaf).derived();
tree = tree.update(0, &id.commitment());
let merkle_proof = tree.proof(0);

// change signal and external_nullifier here
let signal_hash = hash_to_field(b"xxx");
let external_nullifier_hash = hash_to_field(b"appId");

criterion.bench_function(&format!("witness_{depth}"), move |b| {
b.iter(|| {
generate_witness(&id, &merkle_proof, external_nullifier_hash, signal_hash).unwrap();
});
});
}
}
3 changes: 2 additions & 1 deletion src/merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ pub enum Branch<H: Hasher> {
}

/// Merkle proof path, bottom to top.
#[derive(Clone, PartialEq, Eq, Serialize)]
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound(deserialize = "H::Hash: Deserialize<'de>",))]
pub struct Proof<H: Hasher>(pub Vec<Branch<H>>);

/// For a given node index, return the parent node index
Expand Down
39 changes: 39 additions & 0 deletions src/protocol/authentication.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::{
identity::Identity,
poseidon_tree::LazyPoseidonTree,
protocol::{Proof, ProofError},
Field,
};

pub fn generate_proof(
depth: usize,
identity: &Identity,
ext_nullifier_hash: Field,
signal_hash: Field,
) -> Result<Proof, ProofError> {

Check warning on line 13 in src/protocol/authentication.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function returning `Result` missing `# Errors` section

warning: docs for function returning `Result` missing `# Errors` section --> src/protocol/authentication.rs:8:1 | 8 | / pub fn generate_proof( 9 | | depth: usize, 10 | | identity: &Identity, 11 | | ext_nullifier_hash: Field, 12 | | signal_hash: Field, 13 | | ) -> Result<Proof, ProofError> { | |______________________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc = note: `#[warn(clippy::missing_errors_doc)]` implied by `#[warn(clippy::pedantic)]`
let merkle_proof = LazyPoseidonTree::new(depth, Field::from(0))
.update(0, &identity.commitment())
.proof(0);
return super::generate_proof(identity, &merkle_proof, ext_nullifier_hash, signal_hash);

Check warning on line 17 in src/protocol/authentication.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/protocol/authentication.rs:17:5 | 17 | return super::generate_proof(identity, &merkle_proof, ext_nullifier_hash, signal_hash); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return = note: `#[warn(clippy::needless_return)]` implied by `#[warn(clippy::all)]` help: remove `return` | 17 - return super::generate_proof(identity, &merkle_proof, ext_nullifier_hash, signal_hash); 17 + super::generate_proof(identity, &merkle_proof, ext_nullifier_hash, signal_hash) |
}

pub fn verify_proof(
depth: usize,
id_commitment: Field,
nullifier_hash: Field,
signal_hash: Field,
ext_nullifier_hash: Field,
proof: &Proof,
) -> Result<bool, ProofError> {

Check warning on line 27 in src/protocol/authentication.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function returning `Result` missing `# Errors` section

warning: docs for function returning `Result` missing `# Errors` section --> src/protocol/authentication.rs:20:1 | 20 | / pub fn verify_proof( 21 | | depth: usize, 22 | | id_commitment: Field, 23 | | nullifier_hash: Field, ... | 26 | | proof: &Proof, 27 | | ) -> Result<bool, ProofError> { | |_____________________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc
let root = LazyPoseidonTree::new(depth, Field::from(0))
.update(0, &id_commitment)
.root();
return super::verify_proof(
root,
nullifier_hash,
signal_hash,
ext_nullifier_hash,
proof,
depth,
);

Check warning on line 38 in src/protocol/authentication.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/protocol/authentication.rs:31:5 | 31 | / return super::verify_proof( 32 | | root, 33 | | nullifier_hash, 34 | | signal_hash, ... | 37 | | depth, 38 | | ); | |_____^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 31 ~ super::verify_proof( 32 + root, 33 + nullifier_hash, 34 + signal_hash, 35 + ext_nullifier_hash, 36 + proof, 37 + depth, 38 ~ ) |
}
55 changes: 31 additions & 24 deletions src/protocol.rs → src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ use crate::{
poseidon_tree::PoseidonHash,
Field,
};
use ark_bn254::{Bn254, Parameters};
use ark_bn254::{Bn254, FrParameters, Parameters};
use ark_circom::CircomReduction;
use ark_ec::bn::Bn;
use ark_ff::Fp256;
use ark_groth16::{
create_proof_with_reduction_and_matrices, prepare_verifying_key, Proof as ArkProof,
};
Expand All @@ -18,9 +19,10 @@ use color_eyre::Result;
use ethers_core::types::U256;
use rand::{thread_rng, Rng};
use serde::{Deserialize, Serialize};
use std::time::Instant;
use thiserror::Error;

pub mod authentication;

// Matches the private G1Tup type in ark-circom.
pub type G1 = (U256, U256);

Expand Down Expand Up @@ -141,6 +143,31 @@ fn generate_proof_rs(
r: ark_bn254::Fr,
s: ark_bn254::Fr,
) -> Result<Proof, ProofError> {
let depth = merkle_proof.0.len();
let full_assignment =
generate_witness(identity, merkle_proof, external_nullifier_hash, signal_hash)?;

let zkey = zkey(depth);
let ark_proof = create_proof_with_reduction_and_matrices::<_, CircomReduction>(
&zkey.0,
r,
s,
&zkey.1,
zkey.1.num_instance_variables,
zkey.1.num_constraints,
full_assignment.as_slice(),
)?;
let proof = ark_proof.into();

Ok(proof)
}

pub fn generate_witness(
identity: &Identity,
merkle_proof: &merkle_tree::Proof<PoseidonHash>,
external_nullifier_hash: Field,
signal_hash: Field,
) -> Result<Vec<Fp256<FrParameters>>, ProofError> {

Check warning on line 170 in src/protocol/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function returning `Result` missing `# Errors` section

warning: docs for function returning `Result` missing `# Errors` section --> src/protocol/mod.rs:165:1 | 165 | / pub fn generate_witness( 166 | | identity: &Identity, 167 | | merkle_proof: &merkle_tree::Proof<PoseidonHash>, 168 | | external_nullifier_hash: Field, 169 | | signal_hash: Field, 170 | | ) -> Result<Vec<Fp256<FrParameters>>, ProofError> { | |_________________________________________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc

Check warning on line 170 in src/protocol/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function which may panic missing `# Panics` section

warning: docs for function which may panic missing `# Panics` section --> src/protocol/mod.rs:165:1 | 165 | / pub fn generate_witness( 166 | | identity: &Identity, 167 | | merkle_proof: &merkle_tree::Proof<PoseidonHash>, 168 | | external_nullifier_hash: Field, 169 | | signal_hash: Field, 170 | | ) -> Result<Vec<Fp256<FrParameters>>, ProofError> { | |_________________________________________________^ | note: first possible panic found here --> src/protocol/mod.rs:187:5 | 187 | / witness_calculator(depth) 188 | | .lock() 189 | | .expect("witness_calculator mutex should not get poisoned") | |___________________________________________________________________^ = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc = note: `#[warn(clippy::missing_panics_doc)]` implied by `#[warn(clippy::pedantic)]`
let depth = merkle_proof.0.len();
let inputs = [
("identityNullifier", vec![identity.nullifier]),
Expand All @@ -157,31 +184,11 @@ fn generate_proof_rs(
)
});

let now = Instant::now();

let full_assignment = witness_calculator(depth)
witness_calculator(depth)
.lock()
.expect("witness_calculator mutex should not get poisoned")
.calculate_witness_element::<Bn254, _>(inputs, false)
.map_err(ProofError::WitnessError)?;

println!("witness generation took: {:.2?}", now.elapsed());

let now = Instant::now();
let zkey = zkey(depth);
let ark_proof = create_proof_with_reduction_and_matrices::<_, CircomReduction>(
&zkey.0,
r,
s,
&zkey.1,
zkey.1.num_instance_variables,
zkey.1.num_constraints,
full_assignment.as_slice(),
)?;
let proof = ark_proof.into();
println!("proof generation took: {:.2?}", now.elapsed());

Ok(proof)
.map_err(ProofError::WitnessError)
}

/// Verifies a given semaphore proof
Expand Down

0 comments on commit 868328a

Please sign in to comment.