Merge branch 'main' into remco/ci
This commit is contained in:
commit
030287e35a
|
@ -2,3 +2,4 @@
|
||||||
*.profraw
|
*.profraw
|
||||||
.*
|
.*
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
snarkfiles_tmp
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "semaphore"]
|
||||||
|
path = semaphore
|
||||||
|
url = git@github.com:appliedzkp/semaphore.git
|
47
README.md
47
README.md
|
@ -1,17 +1,32 @@
|
||||||
# Semaphore-rs
|
# 🦀 semaphore-rs
|
||||||
|
|
||||||
Rust support library for Semaphore
|
Rust support library for using [semaphore](https://github.com/appliedzkp/semaphore). It's mostly a Rust rewrite of [zk-kit](https://github.com/appliedzkp/zk-kit), but just focuses on semaphore (for now) and still covers a much smaller scope. It's using [ark-circom](https://github.com/gakonst/ark-circom) under the hood for generating the groth16 proofs.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Add this line to your `cargo.toml`:
|
||||||
|
```
|
||||||
|
semaphore = { git = "https://github.com/worldcoin/semaphore-rs" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building semaphore circuits
|
||||||
|
|
||||||
|
1. Check out submodule (if not done before already): `git submodule update --init --recursive`
|
||||||
|
1. Install semaphore dependencies `cd semaphore && npm install`
|
||||||
|
1. Compile circuits `ts-node ./scripts/compile-circuits.ts`
|
||||||
|
1. You'll find the `zkey` and `wasm` file in `semaphore/build/snark`
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
Example as in `src/lib.rs`, run with `cargo test`.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use semaphore::{
|
use semaphore::{identity::Identity, hash::Hash, poseidon_tree::PoseidonTree,
|
||||||
identity::Identity, hash::Hash, poseidon_tree::PoseidonTree,
|
|
||||||
protocol::* };
|
protocol::* };
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
// generate identity
|
// generate identity
|
||||||
let id = Identity::new(b"hello");
|
let id = Identity::new(b"secret");
|
||||||
|
|
||||||
// generate merkle tree
|
// generate merkle tree
|
||||||
const LEAF: Hash = Hash::from_bytes_be([0u8; 32]);
|
const LEAF: Hash = Hash::from_bytes_be([0u8; 32]);
|
||||||
|
@ -20,23 +35,23 @@ let mut tree = PoseidonTree::new(21, LEAF);
|
||||||
let (_, leaf) = id.commitment().to_bytes_be();
|
let (_, leaf) = id.commitment().to_bytes_be();
|
||||||
tree.set(0, leaf.into());
|
tree.set(0, leaf.into());
|
||||||
|
|
||||||
let root: BigInt = tree.root().into();
|
|
||||||
dbg!(root);
|
|
||||||
|
|
||||||
let merkle_proof = tree.proof(0).expect("proof should exist");
|
let merkle_proof = tree.proof(0).expect("proof should exist");
|
||||||
let root = tree.root().into();
|
let root = tree.root();
|
||||||
|
|
||||||
// change signal and external_nullifier here
|
// change signal and external_nullifier here
|
||||||
let signal = b"hello";
|
let signal = b"xxx";
|
||||||
let external_nullifier = b"123";
|
let external_nullifier = b"appId";
|
||||||
|
|
||||||
let nullifier_hash = generate_nullifier_hash(&id, external_nullifier);
|
let external_nullifier_hash = hash_external_nullifier(external_nullifier);
|
||||||
|
let nullifier_hash = generate_nullifier_hash(&id, &external_nullifier_hash);
|
||||||
|
|
||||||
let config = SnarkFileConfig {
|
let config = SnarkFileConfig {
|
||||||
zkey: "./snarkfiles/semaphore.zkey".to_string(),
|
zkey: "./semaphore/build/snark/semaphore_final.zkey".to_string(),
|
||||||
wasm: "./snarkfiles/semaphore.wasm".to_string(),
|
wasm: "./semaphore/build/snark/semaphore.wasm".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let proof = generate_proof(&config, &id, &merkle_proof, external_nullifier, signal).unwrap();
|
let proof = generate_proof(&config, &id, &merkle_proof, &external_nullifier_hash, signal).unwrap();
|
||||||
let success = verify_proof(&config, &root, &nullifier_hash, signal, external_nullifier, &proof).unwrap();
|
let success = verify_proof(&config, &root.into(), &nullifier_hash, signal, &external_nullifier_hash, &proof).unwrap();
|
||||||
|
|
||||||
|
assert!(success);
|
||||||
```
|
```
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 5186a940ff495ff163bd5779631a716d0bf96507
|
Binary file not shown.
Binary file not shown.
12
src/lib.rs
12
src/lib.rs
|
@ -52,21 +52,23 @@ mod test {
|
||||||
let signal = b"xxx";
|
let signal = b"xxx";
|
||||||
let external_nullifier = b"appId";
|
let external_nullifier = b"appId";
|
||||||
|
|
||||||
let nullifier_hash = generate_nullifier_hash(&id, external_nullifier);
|
let external_nullifier_hash = hash_external_nullifier(external_nullifier);
|
||||||
|
let nullifier_hash = generate_nullifier_hash(&id, &external_nullifier_hash);
|
||||||
|
|
||||||
let config = SnarkFileConfig {
|
let config = SnarkFileConfig {
|
||||||
zkey: "./snarkfiles/semaphore.zkey".to_string(),
|
zkey: "./semaphore/build/snark/semaphore_final.zkey".to_string(),
|
||||||
wasm: "./snarkfiles/semaphore.wasm".to_string(),
|
wasm: "./semaphore/build/snark/semaphore.wasm".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let proof =
|
let proof =
|
||||||
generate_proof(&config, &id, &merkle_proof, external_nullifier, signal).unwrap();
|
generate_proof(&config, &id, &merkle_proof, &external_nullifier_hash, signal).unwrap();
|
||||||
|
|
||||||
let success = verify_proof(
|
let success = verify_proof(
|
||||||
&config,
|
&config,
|
||||||
&root.into(),
|
&root.into(),
|
||||||
&nullifier_hash,
|
&nullifier_hash,
|
||||||
signal,
|
signal,
|
||||||
external_nullifier,
|
&external_nullifier_hash,
|
||||||
&proof,
|
&proof,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -57,7 +57,10 @@ pub fn hash_external_nullifier(nullifier: &[u8]) -> BigInt {
|
||||||
pub fn generate_nullifier_hash(identity: &Identity, external_nullifier: &[u8]) -> BigInt {
|
pub fn generate_nullifier_hash(identity: &Identity, external_nullifier: &[u8]) -> BigInt {
|
||||||
let res = POSEIDON
|
let res = POSEIDON
|
||||||
.hash(vec![
|
.hash(vec![
|
||||||
bigint_to_fr(&hash_external_nullifier(external_nullifier)),
|
bigint_to_fr(&BigInt::from_bytes_be(
|
||||||
|
Sign::Plus,
|
||||||
|
external_nullifier,
|
||||||
|
)),
|
||||||
bigint_to_fr(&identity.nullifier),
|
bigint_to_fr(&identity.nullifier),
|
||||||
])
|
])
|
||||||
.expect("hash with fixed input size can't fail");
|
.expect("hash with fixed input size can't fail");
|
||||||
|
@ -94,21 +97,21 @@ pub fn generate_proof(
|
||||||
let inputs = {
|
let inputs = {
|
||||||
let mut inputs: HashMap<String, Vec<BigInt>> = HashMap::new();
|
let mut inputs: HashMap<String, Vec<BigInt>> = HashMap::new();
|
||||||
|
|
||||||
inputs.insert("identity_nullifier".to_string(), vec![identity
|
inputs.insert("identityNullifier".to_string(), vec![identity
|
||||||
.nullifier
|
.nullifier
|
||||||
.clone()]);
|
.clone()]);
|
||||||
inputs.insert("identity_trapdoor".to_string(), vec![identity
|
inputs.insert("identityTrapdoor".to_string(), vec![identity
|
||||||
.trapdoor
|
.trapdoor
|
||||||
.clone()]);
|
.clone()]);
|
||||||
inputs.insert("identity_path_index".to_string(), merkle_proof.path_index());
|
inputs.insert("treePathIndices".to_string(), merkle_proof.path_index());
|
||||||
inputs.insert(
|
inputs.insert(
|
||||||
"path_elements".to_string(),
|
"treeSiblings".to_string(),
|
||||||
merkle_proof_to_vec(merkle_proof),
|
merkle_proof_to_vec(merkle_proof),
|
||||||
);
|
);
|
||||||
inputs.insert("external_nullifier".to_string(), vec![
|
inputs.insert("externalNullifier".to_string(), vec![
|
||||||
hash_external_nullifier(external_nullifier),
|
BigInt::from_bytes_be(Sign::Plus, external_nullifier),
|
||||||
]);
|
]);
|
||||||
inputs.insert("signal_hash".to_string(), vec![hash_signal(signal)]);
|
inputs.insert("signalHash".to_string(), vec![hash_signal(signal)]);
|
||||||
|
|
||||||
inputs
|
inputs
|
||||||
};
|
};
|
||||||
|
@ -174,7 +177,7 @@ pub fn verify_proof(
|
||||||
.expect("can not be negative"),
|
.expect("can not be negative"),
|
||||||
),
|
),
|
||||||
Fp256::from(
|
Fp256::from(
|
||||||
hash_external_nullifier(external_nullifier)
|
BigInt::from_bytes_be(Sign::Plus, external_nullifier)
|
||||||
.to_biguint()
|
.to_biguint()
|
||||||
.expect("can not be negative"),
|
.expect("can not be negative"),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue