Fix clippies

This commit is contained in:
Remco Bloemen 2022-03-11 16:11:06 -08:00
parent b4b2e50121
commit 545c6b0a83
8 changed files with 45 additions and 56 deletions

View File

@ -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.
@ -46,13 +46,8 @@ let external_nullifier = b"appId";
let external_nullifier_hash = hash_external_nullifier(external_nullifier);
let nullifier_hash = generate_nullifier_hash(&id, &external_nullifier_hash);
let config = SnarkFileConfig {
zkey: "./semaphore/build/snark/semaphore_final.zkey".to_string(),
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();
let proof = generate_proof(&id, &merkle_proof, &external_nullifier_hash, signal).unwrap();
let success = verify_proof(&root.into(), &nullifier_hash, signal, &external_nullifier_hash, &proof).unwrap();
assert!(success);
```

View File

@ -5,6 +5,7 @@
"dictionaries": [],
"words": [
"biguint",
"chacha",
"circom",
"groth",
"hasher",
@ -14,7 +15,9 @@
"mmaped",
"modpow",
"Repr",
"Seedable",
"snarkfiles",
"thiserror",
"zkey"
],
"ignoreWords": [],

View File

@ -7,18 +7,19 @@ use once_cell::sync::Lazy;
use std::io::{Cursor, Write};
use tempfile::NamedTempFile;
const ZKEY_BYTES: &'static [u8] = include_bytes!("../semaphore/build/snark/semaphore_final.zkey");
const WASM: &'static [u8] = include_bytes!("../semaphore/build/snark/semaphore.wasm");
const ZKEY_BYTES: &[u8] = include_bytes!("../semaphore/build/snark/semaphore_final.zkey");
const WASM: &[u8] = include_bytes!("../semaphore/build/snark/semaphore.wasm");
pub(crate) static ZKEY: Lazy<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)> = Lazy::new(|| {
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(crate) static WITNESS_CALCULATOR: Lazy<WitnessCalculator> = Lazy::new(|| {
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");
tmpfile.write(WASM).expect("Failed to write to 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");

View File

@ -1,4 +1,4 @@
use crate::{posseidon_hash, Field};
use crate::{poseidon_hash, Field};
use ark_ff::PrimeField;
use sha2::{Digest, Sha256};
@ -42,11 +42,11 @@ impl Identity {
#[must_use]
pub fn secret_hash(&self) -> Field {
posseidon_hash(&[self.nullifier, self.trapdoor])
poseidon_hash(&[self.nullifier, self.trapdoor])
}
#[must_use]
pub fn commitment(&self) -> Field {
posseidon_hash(&[self.secret_hash()])
poseidon_hash(&[self.secret_hash()])
}
}

View File

@ -1,14 +1,14 @@
#![doc = include_str!("../Readme.md")]
#![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)]
mod circuit;
pub mod hash;
pub mod identity;
pub mod merkle_tree;
mod poseidon_hash;
pub mod poseidon_tree;
mod posseidon_hash;
pub mod protocol;
pub mod util;
@ -17,10 +17,10 @@ pub mod mimc_hash;
#[cfg(feature = "mimc")]
pub mod mimc_tree;
use ark_bn254::{Fr, FrParameters, Parameters};
use ark_bn254::{Fr, Parameters};
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 Groth16Proof = ark_groth16::Proof<Bn<Parameters>>;

View File

@ -1,43 +1,41 @@
use crate::{
hash::Hash,
merkle_tree::{self, Hasher, MerkleTree},
Field,
};
use crate::Field;
use ark_ff::{BigInteger256, PrimeField as _};
use ff::{PrimeField as _, PrimeFieldRepr as _};
use ff::PrimeField as _;
use once_cell::sync::Lazy;
use poseidon_rs::{Fr, FrRepr, Poseidon};
use serde::{Deserialize, Serialize};
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")
}
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")
}
pub fn posseidon_hash(input: &[Field]) -> Field {
#[must_use]
pub fn poseidon_hash(input: &[Field]) -> Field {
let input = input
.iter()
.copied()
.map(ark_to_posseidon)
.map(ark_to_poseidon)
.collect::<Vec<_>>();
POSEIDON
.hash(input)
.map(posseidon_to_ark)
.map(poseidon_to_ark)
.expect("hash with fixed input size can't fail")
}
#[cfg(test)]
mod test {
use super::{ark_to_posseidon, posseidon_to_ark};
use super::{ark_to_poseidon, poseidon_to_ark};
use crate::Field;
use ark_ff::{Field as _, UniformRand};
use ff::{Field as _, PrimeField, PrimeFieldRepr};
use ff::PrimeField;
use poseidon_rs::Fr;
use rand_chacha::ChaChaRng;
use rand_core::SeedableRng;
@ -50,10 +48,10 @@ mod test {
#[test]
fn test_ark_pos_ark_roundtrip() {
let mut rng = ChaChaRng::seed_from_u64(123);
for i in 0..1000 {
for _ in 0..1000 {
let n = Field::rand(&mut rng);
let m = posseidon_to_ark(ark_to_posseidon(n));
assert_eq!(n, m)
let m = poseidon_to_ark(ark_to_poseidon(n));
assert_eq!(n, m);
}
}
}

View File

@ -1,7 +1,7 @@
use crate::{
hash::Hash,
merkle_tree::{self, Hasher, MerkleTree},
posseidon_hash, Field,
poseidon_hash, Field,
};
use ark_ff::{PrimeField, ToBytes};
use serde::{Deserialize, Serialize};
@ -19,14 +19,14 @@ pub struct PoseidonHash;
#[allow(clippy::fallible_impl_from)] // TODO
impl From<&Hash> for Field {
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
impl From<Hash> for Field {
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;
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]
fn test_ark_hash_ark_roundtrip() {
use ark_ff::One;
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::one();
let m = Hash::from(n).into();
assert_eq!(n, m);
}

View File

@ -2,11 +2,12 @@ use crate::{
circuit::{WITNESS_CALCULATOR, ZKEY},
identity::Identity,
merkle_tree::{self, Branch},
poseidon_hash,
poseidon_tree::PoseidonHash,
posseidon_hash, Field,
Field,
};
use ark_bn254::{Bn254, Parameters};
use ark_circom::{read_zkey, CircomReduction, WitnessCalculator};
use ark_circom::CircomReduction;
use ark_ec::bn::Bn;
use ark_ff::{Fp256, PrimeField};
use ark_groth16::{create_proof_with_reduction_and_matrices, prepare_verifying_key, Proof};
@ -15,14 +16,9 @@ use ark_std::{rand::thread_rng, UniformRand};
use color_eyre::Result;
use ethers_core::utils::keccak256;
use num_bigint::{BigInt, BigUint, ToBigInt};
use std::{collections::HashMap, fs::File, ops::Shr, time::Instant};
use std::time::Instant;
use thiserror::Error;
pub struct SnarkFileConfig {
pub zkey: String,
pub wasm: String,
}
/// Helper to merkle proof into a bigint vector
/// TODO: we should create a From trait for this
fn merkle_proof_to_vec(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<Field> {
@ -60,7 +56,7 @@ pub fn hash_external_nullifier(nullifier: &[u8]) -> Field {
/// Generates the nullifier hash
#[must_use]
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)]
@ -84,7 +80,6 @@ fn ark_to_bigint(n: Field) -> BigInt {
///
/// Returns a [`ProofError`] if proving fails.
pub fn generate_proof(
config: &SnarkFileConfig,
identity: &Identity,
merkle_proof: &merkle_tree::Proof<PoseidonHash>,
external_nullifier: &[u8],
@ -100,7 +95,7 @@ pub fn generate_proof(
("externalNullifier", vec![external_nullifier]),
("signalHash", vec![signal]),
];
let inputs = inputs.iter().map(|(name, values)| {
let inputs = inputs.into_iter().map(|(name, values)| {
(
name.to_string(),
values
@ -150,7 +145,6 @@ pub fn generate_proof(
/// Returns a [`ProofError`] if verifying fails. Verification failure does not
/// necessarily mean the proof is incorrect.
pub fn verify_proof(
config: &SnarkFileConfig,
root: Field,
nullifier_hash: Field,
signal: &[u8],