mirror of
https://github.com/vacp2p/semaphore-rs.git
synced 2025-02-24 01:28:28 +00:00
commit
124043470e
@ -44,6 +44,7 @@ proptest = { version = "1.0", optional = true }
|
|||||||
rayon = "1.5.1"
|
rayon = "1.5.1"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
sha2 = "0.10.1"
|
sha2 = "0.10.1"
|
||||||
|
tempfile = "3.3.0"
|
||||||
thiserror = "1.0.0"
|
thiserror = "1.0.0"
|
||||||
tiny-keccak = { version = "2.0.2", optional = true }
|
tiny-keccak = { version = "2.0.2", optional = true }
|
||||||
zkp-u256 = { version = "0.2", optional = true }
|
zkp-u256 = { version = "0.2", optional = true }
|
||||||
|
16
README.md
16
README.md
@ -1,4 +1,4 @@
|
|||||||
# 🦀 semaphore-rs
|
# 🦀 semaphore-rs
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@ -33,8 +33,7 @@ let id = Identity::new(b"secret");
|
|||||||
const LEAF: Hash = Hash::from_bytes_be([0u8; 32]);
|
const LEAF: Hash = Hash::from_bytes_be([0u8; 32]);
|
||||||
|
|
||||||
let mut tree = PoseidonTree::new(21, LEAF);
|
let mut tree = PoseidonTree::new(21, LEAF);
|
||||||
let (_, leaf) = id.commitment().to_bytes_be();
|
tree.set(0, id.commitment().into());
|
||||||
tree.set(0, leaf.into());
|
|
||||||
|
|
||||||
let merkle_proof = tree.proof(0).expect("proof should exist");
|
let merkle_proof = tree.proof(0).expect("proof should exist");
|
||||||
let root = tree.root();
|
let root = tree.root();
|
||||||
@ -44,15 +43,10 @@ let signal = b"xxx";
|
|||||||
let external_nullifier = b"appId";
|
let external_nullifier = b"appId";
|
||||||
|
|
||||||
let external_nullifier_hash = hash_external_nullifier(external_nullifier);
|
let external_nullifier_hash = hash_external_nullifier(external_nullifier);
|
||||||
let nullifier_hash = generate_nullifier_hash(&id, &external_nullifier_hash);
|
let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash);
|
||||||
|
|
||||||
let config = SnarkFileConfig {
|
let proof = generate_proof(&id, &merkle_proof, external_nullifier, signal).unwrap();
|
||||||
zkey: "./semaphore/build/snark/semaphore_final.zkey".to_string(),
|
let success = verify_proof(root.into(), nullifier_hash, signal, external_nullifier, &proof).unwrap();
|
||||||
wasm: "./semaphore/build/snark/semaphore.wasm".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let proof = generate_proof(&config, &id, &merkle_proof, &external_nullifier_hash, signal).unwrap();
|
|
||||||
let success = verify_proof(&config, &root.into(), &nullifier_hash, signal, &external_nullifier_hash, &proof).unwrap();
|
|
||||||
|
|
||||||
assert!(success);
|
assert!(success);
|
||||||
```
|
```
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"dictionaries": [],
|
"dictionaries": [],
|
||||||
"words": [
|
"words": [
|
||||||
"biguint",
|
"biguint",
|
||||||
|
"chacha",
|
||||||
"circom",
|
"circom",
|
||||||
"groth",
|
"groth",
|
||||||
"hasher",
|
"hasher",
|
||||||
@ -14,7 +15,9 @@
|
|||||||
"mmaped",
|
"mmaped",
|
||||||
"modpow",
|
"modpow",
|
||||||
"Repr",
|
"Repr",
|
||||||
|
"Seedable",
|
||||||
"snarkfiles",
|
"snarkfiles",
|
||||||
|
"thiserror",
|
||||||
"zkey"
|
"zkey"
|
||||||
],
|
],
|
||||||
"ignoreWords": [],
|
"ignoreWords": [],
|
||||||
|
27
src/circuit.rs
Normal file
27
src/circuit.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use ark_bn254::{Bn254, Fr};
|
||||||
|
use ark_circom::{read_zkey, WitnessCalculator};
|
||||||
|
use ark_groth16::ProvingKey;
|
||||||
|
use ark_relations::r1cs::ConstraintMatrices;
|
||||||
|
use core::include_bytes;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use std::io::{Cursor, Write};
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
|
const ZKEY_BYTES: &[u8] = include_bytes!("../semaphore/build/snark/semaphore_final.zkey");
|
||||||
|
const WASM: &[u8] = include_bytes!("../semaphore/build/snark/semaphore.wasm");
|
||||||
|
|
||||||
|
pub static ZKEY: Lazy<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)> = Lazy::new(|| {
|
||||||
|
let mut reader = Cursor::new(ZKEY_BYTES);
|
||||||
|
read_zkey(&mut reader).expect("zkey should be valid")
|
||||||
|
});
|
||||||
|
|
||||||
|
pub static WITNESS_CALCULATOR: Lazy<WitnessCalculator> = Lazy::new(|| {
|
||||||
|
// HACK: ark-circom requires a file, so we make one!
|
||||||
|
let mut tmpfile = NamedTempFile::new().expect("Failed to create temp file");
|
||||||
|
let written = tmpfile.write(WASM).expect("Failed to write to temp file");
|
||||||
|
assert_eq!(written, WASM.len());
|
||||||
|
let path = tmpfile.into_temp_path();
|
||||||
|
let result = WitnessCalculator::new(&path).expect("Failed to create witness calculator");
|
||||||
|
path.close().expect("Could not remove tempfile");
|
||||||
|
result
|
||||||
|
});
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{posseidon_hash, Field};
|
use crate::{poseidon_hash, Field};
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
@ -42,11 +42,11 @@ impl Identity {
|
|||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn secret_hash(&self) -> Field {
|
pub fn secret_hash(&self) -> Field {
|
||||||
posseidon_hash(&[self.nullifier, self.trapdoor])
|
poseidon_hash(&[self.nullifier, self.trapdoor])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn commitment(&self) -> Field {
|
pub fn commitment(&self) -> Field {
|
||||||
posseidon_hash(&[self.secret_hash()])
|
poseidon_hash(&[self.secret_hash()])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
src/lib.rs
41
src/lib.rs
@ -1,13 +1,14 @@
|
|||||||
#![doc = include_str!("../Readme.md")]
|
#![doc = include_str!("../Readme.md")]
|
||||||
#![warn(clippy::all, clippy::pedantic, clippy::cargo, clippy::nursery)]
|
#![warn(clippy::all, clippy::pedantic, clippy::cargo, clippy::nursery)]
|
||||||
// TODO: ark-circom and ethers-core pull in a lot of deps, some duplicate.
|
// TODO: ark-circom and ethers-core pull in a lot of dependencies, some duplicate.
|
||||||
#![allow(clippy::multiple_crate_versions)]
|
#![allow(clippy::multiple_crate_versions)]
|
||||||
|
|
||||||
|
mod circuit;
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
pub mod identity;
|
pub mod identity;
|
||||||
pub mod merkle_tree;
|
pub mod merkle_tree;
|
||||||
|
mod poseidon_hash;
|
||||||
pub mod poseidon_tree;
|
pub mod poseidon_tree;
|
||||||
mod posseidon_hash;
|
|
||||||
pub mod protocol;
|
pub mod protocol;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
@ -16,10 +17,10 @@ pub mod mimc_hash;
|
|||||||
#[cfg(feature = "mimc")]
|
#[cfg(feature = "mimc")]
|
||||||
pub mod mimc_tree;
|
pub mod mimc_tree;
|
||||||
|
|
||||||
use ark_bn254::{Fr, FrParameters, Parameters};
|
use ark_bn254::{Fr, Parameters};
|
||||||
use ark_ec::bn::Bn;
|
use ark_ec::bn::Bn;
|
||||||
|
|
||||||
pub use crate::posseidon_hash::posseidon_hash;
|
pub use crate::poseidon_hash::poseidon_hash;
|
||||||
|
|
||||||
pub type Field = Fr;
|
pub type Field = Fr;
|
||||||
pub type Groth16Proof = ark_groth16::Proof<Bn<Parameters>>;
|
pub type Groth16Proof = ark_groth16::Proof<Bn<Parameters>>;
|
||||||
@ -33,7 +34,6 @@ mod test {
|
|||||||
poseidon_tree::PoseidonTree,
|
poseidon_tree::PoseidonTree,
|
||||||
protocol::{
|
protocol::{
|
||||||
generate_nullifier_hash, generate_proof, hash_external_nullifier, verify_proof,
|
generate_nullifier_hash, generate_proof, hash_external_nullifier, verify_proof,
|
||||||
SnarkFileConfig,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
@ -61,23 +61,10 @@ mod test {
|
|||||||
let external_nullifier_hash = hash_external_nullifier(external_nullifier);
|
let external_nullifier_hash = hash_external_nullifier(external_nullifier);
|
||||||
let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash);
|
let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash);
|
||||||
|
|
||||||
let config = SnarkFileConfig {
|
let proof = generate_proof(&id, &merkle_proof, external_nullifier, signal).unwrap();
|
||||||
zkey: "./semaphore/build/snark/semaphore_final.zkey".to_string(),
|
|
||||||
wasm: "./semaphore/build/snark/semaphore.wasm".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let proof =
|
let success =
|
||||||
generate_proof(&config, &id, &merkle_proof, external_nullifier, signal).unwrap();
|
verify_proof(root, nullifier_hash, signal, external_nullifier, &proof).unwrap();
|
||||||
|
|
||||||
let success = verify_proof(
|
|
||||||
&config,
|
|
||||||
root,
|
|
||||||
nullifier_hash,
|
|
||||||
signal,
|
|
||||||
external_nullifier,
|
|
||||||
&proof,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(success);
|
assert!(success);
|
||||||
}
|
}
|
||||||
@ -86,10 +73,7 @@ mod test {
|
|||||||
#[cfg(feature = "bench")]
|
#[cfg(feature = "bench")]
|
||||||
pub mod bench {
|
pub mod bench {
|
||||||
use crate::{
|
use crate::{
|
||||||
hash::Hash,
|
hash::Hash, identity::Identity, poseidon_tree::PoseidonTree, protocol::generate_proof,
|
||||||
identity::Identity,
|
|
||||||
poseidon_tree::PoseidonTree,
|
|
||||||
protocol::{generate_proof, SnarkFileConfig},
|
|
||||||
};
|
};
|
||||||
use criterion::Criterion;
|
use criterion::Criterion;
|
||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
@ -117,14 +101,9 @@ pub mod bench {
|
|||||||
let signal = b"xxx";
|
let signal = b"xxx";
|
||||||
let external_nullifier = b"appId";
|
let external_nullifier = b"appId";
|
||||||
|
|
||||||
let config = SnarkFileConfig {
|
|
||||||
zkey: "./semaphore/build/snark/semaphore_final.zkey".to_string(),
|
|
||||||
wasm: "./semaphore/build/snark/semaphore.wasm".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
criterion.bench_function("proof", move |b| {
|
criterion.bench_function("proof", move |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
generate_proof(&config, &id, &merkle_proof, external_nullifier, signal).unwrap();
|
generate_proof(&id, &merkle_proof, external_nullifier, signal).unwrap();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,41 @@
|
|||||||
use crate::{
|
use crate::Field;
|
||||||
hash::Hash,
|
|
||||||
merkle_tree::{self, Hasher, MerkleTree},
|
|
||||||
Field,
|
|
||||||
};
|
|
||||||
use ark_ff::{BigInteger256, PrimeField as _};
|
use ark_ff::{BigInteger256, PrimeField as _};
|
||||||
use ff::{PrimeField as _, PrimeFieldRepr as _};
|
use ff::PrimeField as _;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use poseidon_rs::{Fr, FrRepr, Poseidon};
|
use poseidon_rs::{Fr, FrRepr, Poseidon};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
static POSEIDON: Lazy<Poseidon> = Lazy::new(Poseidon::new);
|
static POSEIDON: Lazy<Poseidon> = Lazy::new(Poseidon::new);
|
||||||
|
|
||||||
fn ark_to_posseidon(n: Field) -> Fr {
|
#[must_use]
|
||||||
|
fn ark_to_poseidon(n: Field) -> Fr {
|
||||||
Fr::from_repr(FrRepr(n.into_repr().0)).expect("n is a valid field element")
|
Fr::from_repr(FrRepr(n.into_repr().0)).expect("n is a valid field element")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn posseidon_to_ark(n: Fr) -> Field {
|
#[must_use]
|
||||||
|
fn poseidon_to_ark(n: Fr) -> Field {
|
||||||
Field::from_repr(BigInteger256(n.into_repr().0)).expect("n is a valid field element")
|
Field::from_repr(BigInteger256(n.into_repr().0)).expect("n is a valid field element")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn posseidon_hash(input: &[Field]) -> Field {
|
#[must_use]
|
||||||
|
pub fn poseidon_hash(input: &[Field]) -> Field {
|
||||||
let input = input
|
let input = input
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.map(ark_to_posseidon)
|
.map(ark_to_poseidon)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
POSEIDON
|
POSEIDON
|
||||||
.hash(input)
|
.hash(input)
|
||||||
.map(posseidon_to_ark)
|
.map(poseidon_to_ark)
|
||||||
.expect("hash with fixed input size can't fail")
|
.expect("hash with fixed input size can't fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{ark_to_posseidon, posseidon_to_ark};
|
use super::{ark_to_poseidon, poseidon_to_ark};
|
||||||
use crate::Field;
|
use crate::Field;
|
||||||
use ark_ff::{Field as _, UniformRand};
|
use ark_ff::{Field as _, UniformRand};
|
||||||
use ff::{Field as _, PrimeField, PrimeFieldRepr};
|
use ff::PrimeField;
|
||||||
use poseidon_rs::Fr;
|
use poseidon_rs::Fr;
|
||||||
use rand_chacha::ChaChaRng;
|
use rand_chacha::ChaChaRng;
|
||||||
use rand_core::SeedableRng;
|
use rand_core::SeedableRng;
|
||||||
@ -50,10 +48,10 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_ark_pos_ark_roundtrip() {
|
fn test_ark_pos_ark_roundtrip() {
|
||||||
let mut rng = ChaChaRng::seed_from_u64(123);
|
let mut rng = ChaChaRng::seed_from_u64(123);
|
||||||
for i in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let n = Field::rand(&mut rng);
|
let n = Field::rand(&mut rng);
|
||||||
let m = posseidon_to_ark(ark_to_posseidon(n));
|
let m = poseidon_to_ark(ark_to_poseidon(n));
|
||||||
assert_eq!(n, m)
|
assert_eq!(n, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
merkle_tree::{self, Hasher, MerkleTree},
|
merkle_tree::{self, Hasher, MerkleTree},
|
||||||
posseidon_hash, Field,
|
poseidon_hash, Field,
|
||||||
};
|
};
|
||||||
use ark_ff::{PrimeField, ToBytes};
|
use ark_ff::{PrimeField, ToBytes};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -19,14 +19,14 @@ pub struct PoseidonHash;
|
|||||||
#[allow(clippy::fallible_impl_from)] // TODO
|
#[allow(clippy::fallible_impl_from)] // TODO
|
||||||
impl From<&Hash> for Field {
|
impl From<&Hash> for Field {
|
||||||
fn from(hash: &Hash) -> Self {
|
fn from(hash: &Hash) -> Self {
|
||||||
Field::from_be_bytes_mod_order(&hash.0)
|
Self::from_be_bytes_mod_order(&hash.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::fallible_impl_from)] // TODO
|
#[allow(clippy::fallible_impl_from)] // TODO
|
||||||
impl From<Hash> for Field {
|
impl From<Hash> for Field {
|
||||||
fn from(hash: Hash) -> Self {
|
fn from(hash: Hash) -> Self {
|
||||||
Field::from_be_bytes_mod_order(&hash.0)
|
Self::from_be_bytes_mod_order(&hash.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ impl Hasher for PoseidonHash {
|
|||||||
type Hash = Hash;
|
type Hash = Hash;
|
||||||
|
|
||||||
fn hash_node(left: &Self::Hash, right: &Self::Hash) -> Self::Hash {
|
fn hash_node(left: &Self::Hash, right: &Self::Hash) -> Self::Hash {
|
||||||
posseidon_hash(&[left.into(), right.into()]).into()
|
poseidon_hash(&[left.into(), right.into()]).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,11 +60,9 @@ pub mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ark_hash_ark_roundtrip() {
|
fn test_ark_hash_ark_roundtrip() {
|
||||||
use ark_ff::One;
|
|
||||||
let mut rng = ChaChaRng::seed_from_u64(123);
|
let mut rng = ChaChaRng::seed_from_u64(123);
|
||||||
for i in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let n = Field::rand(&mut rng);
|
let n = Field::rand(&mut rng);
|
||||||
let n = Field::one();
|
|
||||||
let m = Hash::from(n).into();
|
let m = Hash::from(n).into();
|
||||||
assert_eq!(n, m);
|
assert_eq!(n, m);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
circuit::{WITNESS_CALCULATOR, ZKEY},
|
||||||
identity::Identity,
|
identity::Identity,
|
||||||
merkle_tree::{self, Branch},
|
merkle_tree::{self, Branch},
|
||||||
|
poseidon_hash,
|
||||||
poseidon_tree::PoseidonHash,
|
poseidon_tree::PoseidonHash,
|
||||||
posseidon_hash, Field,
|
Field,
|
||||||
};
|
};
|
||||||
use ark_bn254::{Bn254, Parameters};
|
use ark_bn254::{Bn254, Parameters};
|
||||||
use ark_circom::{read_zkey, CircomReduction, WitnessCalculator};
|
use ark_circom::CircomReduction;
|
||||||
use ark_ec::bn::Bn;
|
use ark_ec::bn::Bn;
|
||||||
use ark_ff::{Fp256, PrimeField};
|
use ark_ff::{Fp256, PrimeField};
|
||||||
use ark_groth16::{create_proof_with_reduction_and_matrices, prepare_verifying_key, Proof};
|
use ark_groth16::{create_proof_with_reduction_and_matrices, prepare_verifying_key, Proof};
|
||||||
@ -14,14 +16,9 @@ use ark_std::{rand::thread_rng, UniformRand};
|
|||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use ethers_core::utils::keccak256;
|
use ethers_core::utils::keccak256;
|
||||||
use num_bigint::{BigInt, BigUint, ToBigInt};
|
use num_bigint::{BigInt, BigUint, ToBigInt};
|
||||||
use std::{collections::HashMap, fs::File, ops::Shr, time::Instant};
|
use std::time::Instant;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub struct SnarkFileConfig {
|
|
||||||
pub zkey: String,
|
|
||||||
pub wasm: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper to merkle proof into a bigint vector
|
/// Helper to merkle proof into a bigint vector
|
||||||
/// TODO: we should create a From trait for this
|
/// TODO: we should create a From trait for this
|
||||||
fn merkle_proof_to_vec(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<Field> {
|
fn merkle_proof_to_vec(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<Field> {
|
||||||
@ -59,7 +56,7 @@ pub fn hash_external_nullifier(nullifier: &[u8]) -> Field {
|
|||||||
/// Generates the nullifier hash
|
/// Generates the nullifier hash
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn generate_nullifier_hash(identity: &Identity, external_nullifier: Field) -> Field {
|
pub fn generate_nullifier_hash(identity: &Identity, external_nullifier: Field) -> Field {
|
||||||
posseidon_hash(&[external_nullifier, identity.nullifier])
|
poseidon_hash(&[external_nullifier, identity.nullifier])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@ -83,17 +80,11 @@ fn ark_to_bigint(n: Field) -> BigInt {
|
|||||||
///
|
///
|
||||||
/// Returns a [`ProofError`] if proving fails.
|
/// Returns a [`ProofError`] if proving fails.
|
||||||
pub fn generate_proof(
|
pub fn generate_proof(
|
||||||
config: &SnarkFileConfig,
|
|
||||||
identity: &Identity,
|
identity: &Identity,
|
||||||
merkle_proof: &merkle_tree::Proof<PoseidonHash>,
|
merkle_proof: &merkle_tree::Proof<PoseidonHash>,
|
||||||
external_nullifier: &[u8],
|
external_nullifier: &[u8],
|
||||||
signal: &[u8],
|
signal: &[u8],
|
||||||
) -> Result<Proof<Bn<Parameters>>, ProofError> {
|
) -> Result<Proof<Bn<Parameters>>, ProofError> {
|
||||||
let mut file = File::open(&config.zkey)?;
|
|
||||||
let (params, matrices) = read_zkey(&mut file)?;
|
|
||||||
let num_inputs = matrices.num_instance_variables;
|
|
||||||
let num_constraints = matrices.num_constraints;
|
|
||||||
|
|
||||||
let external_nullifier = hash_external_nullifier(external_nullifier);
|
let external_nullifier = hash_external_nullifier(external_nullifier);
|
||||||
let signal = hash_signal(signal);
|
let signal = hash_signal(signal);
|
||||||
let inputs = [
|
let inputs = [
|
||||||
@ -104,7 +95,7 @@ pub fn generate_proof(
|
|||||||
("externalNullifier", vec![external_nullifier]),
|
("externalNullifier", vec![external_nullifier]),
|
||||||
("signalHash", vec![signal]),
|
("signalHash", vec![signal]),
|
||||||
];
|
];
|
||||||
let inputs = inputs.iter().map(|(name, values)| {
|
let inputs = inputs.into_iter().map(|(name, values)| {
|
||||||
(
|
(
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
values
|
values
|
||||||
@ -117,9 +108,8 @@ pub fn generate_proof(
|
|||||||
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
let mut witness = WitnessCalculator::new(&config.wasm).map_err(ProofError::WitnessError)?;
|
let full_assignment = WITNESS_CALCULATOR
|
||||||
|
.clone()
|
||||||
let full_assignment = witness
|
|
||||||
.calculate_witness_element::<Bn254, _>(inputs, false)
|
.calculate_witness_element::<Bn254, _>(inputs, false)
|
||||||
.map_err(ProofError::WitnessError)?;
|
.map_err(ProofError::WitnessError)?;
|
||||||
|
|
||||||
@ -134,12 +124,12 @@ pub fn generate_proof(
|
|||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
let proof = create_proof_with_reduction_and_matrices::<_, CircomReduction>(
|
let proof = create_proof_with_reduction_and_matrices::<_, CircomReduction>(
|
||||||
¶ms,
|
&ZKEY.0,
|
||||||
r,
|
r,
|
||||||
s,
|
s,
|
||||||
&matrices,
|
&ZKEY.1,
|
||||||
num_inputs,
|
ZKEY.1.num_instance_variables,
|
||||||
num_constraints,
|
ZKEY.1.num_constraints,
|
||||||
full_assignment.as_slice(),
|
full_assignment.as_slice(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -155,17 +145,13 @@ pub fn generate_proof(
|
|||||||
/// Returns a [`ProofError`] if verifying fails. Verification failure does not
|
/// Returns a [`ProofError`] if verifying fails. Verification failure does not
|
||||||
/// necessarily mean the proof is incorrect.
|
/// necessarily mean the proof is incorrect.
|
||||||
pub fn verify_proof(
|
pub fn verify_proof(
|
||||||
config: &SnarkFileConfig,
|
|
||||||
root: Field,
|
root: Field,
|
||||||
nullifier_hash: Field,
|
nullifier_hash: Field,
|
||||||
signal: &[u8],
|
signal: &[u8],
|
||||||
external_nullifier: &[u8],
|
external_nullifier: &[u8],
|
||||||
proof: &Proof<Bn<Parameters>>,
|
proof: &Proof<Bn<Parameters>>,
|
||||||
) -> Result<bool, ProofError> {
|
) -> Result<bool, ProofError> {
|
||||||
let mut file = File::open(&config.zkey)?;
|
let pvk = prepare_verifying_key(&ZKEY.0.vk);
|
||||||
let (params, _) = read_zkey(&mut file)?;
|
|
||||||
|
|
||||||
let pvk = prepare_verifying_key(¶ms.vk);
|
|
||||||
|
|
||||||
let public_inputs = vec![
|
let public_inputs = vec![
|
||||||
root,
|
root,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user