mirror of
https://github.com/vacp2p/zerokit.git
synced 2025-02-16 16:37:03 +00:00
chore(rln): remove unnecessary test, restyle
This commit is contained in:
parent
8f738ef327
commit
cf6168bf4e
@ -1,20 +1,16 @@
|
||||
use ark_bn254::{Bn254, Fq, Fq2, Fr, G1Affine, G2Affine};
|
||||
use ark_bn254::{G1Projective, G2Projective};
|
||||
use ark_bn254::{Bn254, Fq, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
|
||||
use ark_circom::{read_zkey, CircomBuilder, CircomConfig, WitnessCalculator};
|
||||
use ark_ff::BigInteger256;
|
||||
/// Adapted from semaphore-rs
|
||||
use ark_groth16::{ProvingKey, VerifyingKey};
|
||||
use ark_relations::r1cs::ConstraintMatrices;
|
||||
use core::include_bytes;
|
||||
use num_bigint::BigUint;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde_json::Value;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
use std::io::{Cursor, Write};
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
const ZKEY_PATH: &str = "./resources/rln_final.zkey";
|
||||
const VK_PATH: &str = "./resources/verifying_key.json";
|
||||
@ -23,19 +19,19 @@ const WASM_PATH: &str = "./resources/rln.wasm";
|
||||
|
||||
pub fn ZKEY() -> ProvingKey<Bn254> /*, ConstraintMatrices<Fr>)*/ {
|
||||
let mut file = File::open(ZKEY_PATH).unwrap();
|
||||
let (provingKey, _matrices) = read_zkey(&mut file).unwrap();
|
||||
provingKey
|
||||
let (proving_key, _matrices) = read_zkey(&mut file).unwrap();
|
||||
proving_key
|
||||
}
|
||||
|
||||
pub fn VK() -> VerifyingKey<Bn254> {
|
||||
let verifyingKey: VerifyingKey<Bn254>;
|
||||
let verifying_key: VerifyingKey<Bn254>;
|
||||
|
||||
if Path::new(VK_PATH).exists() {
|
||||
let verifyingKey = vk_from_json(VK_PATH);
|
||||
verifyingKey
|
||||
verifying_key = vk_from_json(VK_PATH);
|
||||
verifying_key
|
||||
} else if Path::new(ZKEY_PATH).exists() {
|
||||
verifyingKey = ZKEY().vk;
|
||||
verifyingKey
|
||||
verifying_key = ZKEY().vk;
|
||||
verifying_key
|
||||
} else {
|
||||
panic!("No proving/verification key present!");
|
||||
}
|
||||
@ -44,11 +40,8 @@ pub fn VK() -> VerifyingKey<Bn254> {
|
||||
pub fn CIRCOM() -> CircomBuilder<Bn254> {
|
||||
// Load the WASM and R1CS for witness and proof generation
|
||||
let cfg = CircomConfig::<Bn254>::new(WASM_PATH, R1CS_PATH).unwrap(); // should be )?; but need to address "the trait `From<ErrReport>` is not implemented for `protocol::ProofError`"
|
||||
|
||||
// We build the circuit
|
||||
let builder = CircomBuilder::new(cfg);
|
||||
|
||||
builder
|
||||
// We build and return the circuit
|
||||
CircomBuilder::new(cfg)
|
||||
}
|
||||
|
||||
// Utilities to convert a json verification key in a groth16::VerificationKey
|
||||
@ -127,30 +120,15 @@ fn vk_from_json(vk_path: &str) -> VerifyingKey<Bn254> {
|
||||
let json = std::fs::read_to_string(vk_path).unwrap();
|
||||
let json: Value = serde_json::from_str(&json).unwrap();
|
||||
|
||||
let vk = VerifyingKey {
|
||||
VerifyingKey {
|
||||
alpha_g1: json_to_g1(&json, "vk_alpha_1"),
|
||||
beta_g2: json_to_g2(&json, "vk_beta_2"),
|
||||
gamma_g2: json_to_g2(&json, "vk_gamma_2"),
|
||||
delta_g2: json_to_g2(&json, "vk_delta_2"),
|
||||
gamma_abc_g1: json_to_g1_vec(&json, "IC"),
|
||||
};
|
||||
|
||||
return vk;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_vk_from_zkey(verifyingKey: VerifyingKey<Bn254>) {
|
||||
assert_eq!(ZKEY().vk, verifyingKey);
|
||||
pub fn check_vk_from_zkey(verifying_key: VerifyingKey<Bn254>) {
|
||||
assert_eq!(ZKEY().vk, verifying_key);
|
||||
}
|
||||
|
||||
// Not sure this is still useful...
|
||||
const WASM: &[u8] = include_bytes!("../resources/rln.wasm");
|
||||
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
|
||||
});
|
||||
|
150
rln/src/lib.rs
150
rln/src/lib.rs
@ -1,20 +1,17 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
pub mod ffi;
|
||||
pub mod public;
|
||||
|
||||
use crate::circuit::{CIRCOM, VK, ZKEY};
|
||||
use ark_bn254::{Fr, Parameters};
|
||||
use ark_ec::bn::Bn;
|
||||
use ark_std::str::FromStr;
|
||||
|
||||
pub mod circuit;
|
||||
pub mod ffi;
|
||||
pub mod protocol;
|
||||
pub mod public;
|
||||
|
||||
pub type Field = Fr;
|
||||
pub type Groth16Proof = ark_groth16::Proof<Bn<Parameters>>;
|
||||
pub type EthereumGroth16Proof = ark_circom::ethereum::Proof;
|
||||
|
||||
use crate::circuit::{CIRCOM, VK, ZKEY};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
@ -28,68 +25,68 @@ mod test {
|
||||
};
|
||||
|
||||
#[test]
|
||||
// We test Merkle Tree generation, proofs and verification
|
||||
fn test_merkle_proof() {
|
||||
let leaf = Field::from(0);
|
||||
let tree_height = 16;
|
||||
let leaf_index = 3;
|
||||
|
||||
// generate identity
|
||||
let id = Identity::from_seed(b"hello");
|
||||
// We follow zk-kit approach for identity generation
|
||||
let id = Identity::from_seed(b"test-merkle-proof");
|
||||
let identity_secret = poseidon_hash(&vec![id.trapdoor, id.nullifier]);
|
||||
let id_commitment = poseidon_hash(&vec![identity_secret]);
|
||||
|
||||
// generate merkle tree
|
||||
let mut tree = PoseidonTree::new(21, leaf);
|
||||
tree.set(0, id.commitment());
|
||||
let default_leaf = Field::from(0);
|
||||
let mut tree = PoseidonTree::new(tree_height, default_leaf);
|
||||
tree.set(leaf_index, id_commitment.into());
|
||||
|
||||
let merkle_proof = tree.proof(0).expect("proof should exist");
|
||||
let root: Field = tree.root().into();
|
||||
|
||||
println!("Root: {:#}", root);
|
||||
println!("Merkle proof: {:#?}", merkle_proof);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_semaphore() {
|
||||
let leaf = Field::from(0);
|
||||
|
||||
// generate identity
|
||||
let id = Identity::from_seed(b"hello");
|
||||
|
||||
// generate merkle tree
|
||||
let mut tree = PoseidonTree::new(21, leaf);
|
||||
tree.set(0, id.commitment());
|
||||
|
||||
let merkle_proof = tree.proof(0).expect("proof should exist");
|
||||
let root = tree.root().into();
|
||||
|
||||
// change signal_hash and external_nullifier here
|
||||
let signal_hash = hash_to_field(b"xxx");
|
||||
let external_nullifier_hash = hash_to_field(b"appId");
|
||||
|
||||
let nullifier_hash =
|
||||
semaphore::protocol::generate_nullifier_hash(&id, external_nullifier_hash);
|
||||
|
||||
let proof = semaphore::protocol::generate_proof(
|
||||
&id,
|
||||
&merkle_proof,
|
||||
external_nullifier_hash,
|
||||
signal_hash,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let success = semaphore::protocol::verify_proof(
|
||||
// We check correct computation of the root
|
||||
let root = tree.root();
|
||||
assert_eq!(
|
||||
root,
|
||||
nullifier_hash,
|
||||
signal_hash,
|
||||
external_nullifier_hash,
|
||||
&proof,
|
||||
)
|
||||
.unwrap();
|
||||
Field::from_str("0x27401a4559ce263630907ce3b77c570649e28ede22d2a7f5296839627a16e870")
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
assert!(success);
|
||||
let merkle_proof = tree.proof(leaf_index).expect("proof should exist");
|
||||
let path_elements = get_path_elements(&merkle_proof);
|
||||
let identity_path_index = get_identity_path_index(&merkle_proof);
|
||||
|
||||
// We check correct computation of the path and indexes
|
||||
let expected_path_elements = vec![
|
||||
"0",
|
||||
"14744269619966411208579211824598458697587494354926760081771325075741142829156",
|
||||
"7423237065226347324353380772367382631490014989348495481811164164159255474657",
|
||||
"11286972368698509976183087595462810875513684078608517520839298933882497716792",
|
||||
"3607627140608796879659380071776844901612302623152076817094415224584923813162",
|
||||
"19712377064642672829441595136074946683621277828620209496774504837737984048981",
|
||||
"20775607673010627194014556968476266066927294572720319469184847051418138353016",
|
||||
"3396914609616007258851405644437304192397291162432396347162513310381425243293",
|
||||
"21551820661461729022865262380882070649935529853313286572328683688269863701601",
|
||||
"6573136701248752079028194407151022595060682063033565181951145966236778420039",
|
||||
"12413880268183407374852357075976609371175688755676981206018884971008854919922",
|
||||
"14271763308400718165336499097156975241954733520325982997864342600795471836726",
|
||||
"20066985985293572387227381049700832219069292839614107140851619262827735677018",
|
||||
"9394776414966240069580838672673694685292165040808226440647796406499139370960",
|
||||
"11331146992410411304059858900317123658895005918277453009197229807340014528524",
|
||||
];
|
||||
|
||||
let expected_identity_path_index: Vec<u8> =
|
||||
vec![1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
assert_eq!(path_elements, expected_path_elements);
|
||||
assert_eq!(identity_path_index, expected_identity_path_index);
|
||||
|
||||
// We check correct verification of the proof
|
||||
assert!(tree.verify(id_commitment.into(), &merkle_proof));
|
||||
}
|
||||
|
||||
#[test]
|
||||
// We test a RLN proof generation and verification
|
||||
fn test_end_to_end() {
|
||||
let TREE_HEIGHT = 16;
|
||||
let leafIndex = 3;
|
||||
let tree_height = 16;
|
||||
let leaf_index = 3;
|
||||
|
||||
// Generate identity
|
||||
// We follow zk-kit approach for identity generation
|
||||
@ -98,11 +95,11 @@ mod test {
|
||||
let id_commitment = poseidon_hash(&vec![identity_secret]);
|
||||
|
||||
//// generate merkle tree
|
||||
let leaf = Field::from(0);
|
||||
let mut tree = PoseidonTree::new(TREE_HEIGHT, leaf);
|
||||
tree.set(leafIndex, id_commitment.into());
|
||||
let default_leaf = Field::from(0);
|
||||
let mut tree = PoseidonTree::new(tree_height, default_leaf);
|
||||
tree.set(leaf_index, id_commitment.into());
|
||||
|
||||
let merkle_proof = tree.proof(leafIndex).expect("proof should exist");
|
||||
let merkle_proof = tree.proof(leaf_index).expect("proof should exist");
|
||||
|
||||
let signal = b"hey hey";
|
||||
let x = hash_to_field(signal);
|
||||
@ -111,39 +108,20 @@ mod test {
|
||||
let epoch = hash_to_field(b"test-epoch");
|
||||
let rln_identifier = hash_to_field(b"test-rln-identifier");
|
||||
|
||||
let rlnWitness: RLNWitnessInput =
|
||||
initRLNWitnessFromValues(identity_secret, &merkle_proof, x, epoch, rln_identifier);
|
||||
|
||||
println!("rlnWitness: {:#?}", rlnWitness);
|
||||
let rln_witness: RLNWitnessInput =
|
||||
rln_witness_from_values(identity_secret, &merkle_proof, x, epoch, rln_identifier);
|
||||
|
||||
// We generate all relevant keys
|
||||
let provingKey = &ZKEY();
|
||||
let verificationKey = &VK();
|
||||
let proving_key = &ZKEY();
|
||||
let verification_key = &VK();
|
||||
let builder = CIRCOM();
|
||||
|
||||
// Let's generate a zkSNARK proof
|
||||
let (proof, inputs) = generate_proof(builder, provingKey, rlnWitness).unwrap();
|
||||
let (proof, inputs) = generate_proof(builder, proving_key, rln_witness).unwrap();
|
||||
|
||||
// Let's verify the proof
|
||||
let success = verify_proof(verificationKey, proof, inputs).unwrap();
|
||||
let success = verify_proof(verification_key, proof, inputs).unwrap();
|
||||
|
||||
assert!(success);
|
||||
}
|
||||
|
||||
//to_str_radix(10);
|
||||
|
||||
//
|
||||
//// change signal_hash and external_nullifier_hash here
|
||||
//let signal_hash = hash_to_field(b"xxx");
|
||||
//let external_nullifier_hash = hash_to_field(b"appId");
|
||||
//
|
||||
//let nullifier_hash = generate_nullifier_hash(&id, external_nullifier_hash);
|
||||
//
|
||||
//
|
||||
//// We generate all relevant keys
|
||||
//let provingKey = &ZKEY();
|
||||
//let verificationKey = &VK();
|
||||
//let mut builder = CIRCOM();
|
||||
|
||||
//println!("Proof: {:#?}", proof);
|
||||
}
|
||||
|
@ -1,19 +1,13 @@
|
||||
|
||||
|
||||
use color_eyre::Result;
|
||||
|
||||
|
||||
|
||||
|
||||
// Tracing
|
||||
use ark_relations::r1cs::{ConstraintLayer, ConstraintTrace, TracingMode};
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
|
||||
// JSON
|
||||
|
||||
|
||||
use rln::circuit::{CIRCOM, VK, ZKEY};
|
||||
use rln::protocol::{generate_proof, initRLNWitnessFromJSON, verify_proof};
|
||||
use rln::protocol::{generate_proof, rln_witness_from_json, verify_proof};
|
||||
|
||||
// RLN
|
||||
fn groth16_proof_example() -> Result<()> {
|
||||
@ -72,18 +66,18 @@ fn groth16_proof_example() -> Result<()> {
|
||||
"#;
|
||||
|
||||
// We generate all relevant keys
|
||||
let provingKey = &ZKEY();
|
||||
let verificationKey = &VK();
|
||||
let proving_key = &ZKEY();
|
||||
let verification_key = &VK();
|
||||
let builder = CIRCOM();
|
||||
|
||||
// We compute witness from the json input example
|
||||
let rlnWitness = initRLNWitnessFromJSON(input_json_str);
|
||||
let rln_witness = rln_witness_from_json(input_json_str);
|
||||
|
||||
// Let's generate a zkSNARK proof
|
||||
let (proof, inputs) = generate_proof(builder, provingKey, rlnWitness).unwrap();
|
||||
let (proof, inputs) = generate_proof(builder, proving_key, rln_witness).unwrap();
|
||||
|
||||
// Let's verify the proof
|
||||
let verified = verify_proof(verificationKey, proof, inputs);
|
||||
let verified = verify_proof(verification_key, proof, inputs);
|
||||
|
||||
assert!(verified.unwrap());
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/// Adapted from semaphore-rs
|
||||
use crate::circuit::{VK, WITNESS_CALCULATOR, ZKEY};
|
||||
use crate::circuit::{VK, ZKEY};
|
||||
use ark_bn254::{Bn254, Fr, Parameters};
|
||||
use ark_circom::{read_zkey, CircomBuilder, CircomConfig, CircomReduction};
|
||||
use ark_ec::bn::Bn;
|
||||
use ark_ff::{Fp256, PrimeField};
|
||||
use ark_groth16::{
|
||||
@ -25,7 +25,9 @@ use serde::{Deserialize, Serialize};
|
||||
use std::time::Instant;
|
||||
use thiserror::Error;
|
||||
|
||||
use ark_circom::{read_zkey, CircomBuilder, CircomConfig, CircomReduction};
|
||||
///////////////////////////////////////////////////////
|
||||
// RLN Witness data structure and utility functions
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct RLNWitnessInput {
|
||||
@ -37,36 +39,37 @@ pub struct RLNWitnessInput {
|
||||
rln_identifier: String,
|
||||
}
|
||||
|
||||
pub fn initRLNWitnessFromJSON(input_json_str: &str) -> RLNWitnessInput {
|
||||
let rlnWitness: RLNWitnessInput =
|
||||
serde_json::from_str(&input_json_str).expect("JSON was not well-formatted");
|
||||
return rlnWitness;
|
||||
pub fn rln_witness_from_json(input_json_str: &str) -> RLNWitnessInput {
|
||||
let rln_witness: RLNWitnessInput =
|
||||
serde_json::from_str(input_json_str).expect("JSON was not well-formatted");
|
||||
rln_witness
|
||||
}
|
||||
|
||||
pub fn initRLNWitnessFromValues(
|
||||
pub fn rln_witness_from_values(
|
||||
identity_secret: Field,
|
||||
merkle_proof: &merkle_tree::Proof<PoseidonHash>,
|
||||
x: Field,
|
||||
epoch: Field,
|
||||
rln_identifier: Field,
|
||||
) -> RLNWitnessInput {
|
||||
//println!("Merkle proof: {:#?}", merkle_proof);
|
||||
let path_elements = getPathElements(merkle_proof);
|
||||
let identity_path_index = getIdentityPathIndex(merkle_proof);
|
||||
let path_elements = get_path_elements(merkle_proof);
|
||||
let identity_path_index = get_identity_path_index(merkle_proof);
|
||||
|
||||
let rlnWitness = RLNWitnessInput {
|
||||
let rln_witness = RLNWitnessInput {
|
||||
identity_secret: BigInt::from(identity_secret).to_str_radix(10),
|
||||
path_elements: path_elements,
|
||||
identity_path_index: identity_path_index,
|
||||
path_elements,
|
||||
identity_path_index,
|
||||
x: BigInt::from(x).to_str_radix(10),
|
||||
epoch: format!("{:#066x}", BigInt::from(epoch)), //We format it as a padded 32 bytes hex with leading 0x for compatibility with zk-kit
|
||||
rln_identifier: BigInt::from(rln_identifier).to_str_radix(10),
|
||||
};
|
||||
|
||||
return rlnWitness;
|
||||
rln_witness
|
||||
}
|
||||
|
||||
// TODO Fields need to be updated to RLN based ones
|
||||
///////////////////////////////////////////////////////
|
||||
// Proof data structure and utility functions
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
// Matches the private G1Tup type in ark-circom.
|
||||
pub type G1 = (U256, U256);
|
||||
@ -108,9 +111,13 @@ impl From<Proof> for ArkProof<Bn<Parameters>> {
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Merkle tree utility functions
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
/// Helper to merkle proof into a bigint vector
|
||||
/// TODO: we should create a From trait for this
|
||||
pub fn getPathElements(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<String> {
|
||||
pub fn get_path_elements(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<String> {
|
||||
proof
|
||||
.0
|
||||
.iter()
|
||||
@ -120,7 +127,7 @@ pub fn getPathElements(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<String>
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn getIdentityPathIndex(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<u8> {
|
||||
pub fn get_identity_path_index(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<u8> {
|
||||
proof
|
||||
.0
|
||||
.iter()
|
||||
@ -131,6 +138,10 @@ pub fn getIdentityPathIndex(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<u8>
|
||||
.collect()
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Signal/nullifier utility functions
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
/// Internal helper to hash the signal to make sure it's in the field
|
||||
fn hash_signal(signal: &[u8]) -> Field {
|
||||
let hash = keccak256(signal);
|
||||
@ -146,6 +157,10 @@ pub fn generate_nullifier_hash(identity: &Identity, external_nullifier: Field) -
|
||||
poseidon_hash(&[external_nullifier, identity.nullifier])
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// zkSNARK utility functions
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ProofError {
|
||||
#[error("Error reading circuit key: {0}")]
|
||||
@ -232,12 +247,12 @@ pub fn generate_proof(
|
||||
/// Returns a [`ProofError`] if verifying fails. Verification failure does not
|
||||
/// necessarily mean the proof is incorrect.
|
||||
pub fn verify_proof(
|
||||
verifyingKey: &VerifyingKey<Bn254>,
|
||||
verifying_key: &VerifyingKey<Bn254>,
|
||||
proof: Proof,
|
||||
inputs: Vec<Fr>,
|
||||
) -> Result<bool, ProofError> {
|
||||
// Check that the proof is valid
|
||||
let pvk = prepare_verifying_key(verifyingKey);
|
||||
let pvk = prepare_verifying_key(verifying_key);
|
||||
let pr: ArkProof<Bn254> = proof.into();
|
||||
let verified = ark_verify_proof(&pvk, &pr, &inputs)?;
|
||||
|
||||
|
@ -1,32 +1,21 @@
|
||||
/// This is the main public API for RLN. It is used by the FFI, and should be
|
||||
/// used by tests etc as well
|
||||
///
|
||||
use semaphore::{
|
||||
hash_to_field, identity::Identity, poseidon_tree::PoseidonTree, protocol::*, Field,
|
||||
};
|
||||
|
||||
use ark_circom::{CircomBuilder, CircomCircuit, CircomConfig};
|
||||
use ark_std::rand::thread_rng;
|
||||
|
||||
use ark_bn254::Bn254;
|
||||
use ark_circom::{CircomBuilder, CircomCircuit, CircomConfig};
|
||||
use ark_groth16::{
|
||||
create_random_proof as prove, generate_random_parameters, prepare_verifying_key, verify_proof,
|
||||
Proof, ProvingKey,
|
||||
};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
// , SerializationError};
|
||||
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
use ark_std::rand::thread_rng;
|
||||
use num_bigint::BigInt;
|
||||
|
||||
// JSON
|
||||
use semaphore::{
|
||||
hash_to_field, identity::Identity, poseidon_tree::PoseidonTree, protocol::*, Field,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json;
|
||||
|
||||
// For RLN Rust version
|
||||
//use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine};
|
||||
//use sapling_crypto::bellman::pairing::bn256::Bn256;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
// TODO Add Engine here? i.e. <E: Engine> not <Bn254>
|
||||
// TODO Assuming we want to use IncrementalMerkleTree, figure out type/trait conversions
|
||||
@ -34,8 +23,6 @@ use serde_json;
|
||||
pub struct RLN {
|
||||
circom: CircomCircuit<Bn254>,
|
||||
params: ProvingKey<Bn254>,
|
||||
// RLN Rust version
|
||||
//tree: IncrementalMerkleTree<Bn256>,
|
||||
tree: PoseidonTree,
|
||||
}
|
||||
|
||||
@ -81,131 +68,6 @@ impl RLN {
|
||||
}
|
||||
}
|
||||
|
||||
// XXX This is a tempory hack to get end to end proving/verification working
|
||||
// Not supposed to be part of public API
|
||||
pub fn new_json_spike() -> RLN {
|
||||
let cfg =
|
||||
CircomConfig::<Bn254>::new("./resources/rln.wasm", "./resources/rln.r1cs").unwrap();
|
||||
|
||||
// TODO Refactor
|
||||
// From rln JSON witness
|
||||
// Input generated with https://github.com/oskarth/zk-kit/commit/b6a872f7160c7c14e10a0ea40acab99cbb23c9a8
|
||||
let input_json_str = r#"
|
||||
{
|
||||
"identity_secret": "12825549237505733615964533204745049909430608936689388901883576945030025938736",
|
||||
"path_elements": [
|
||||
"18622655742232062119094611065896226799484910997537830749762961454045300666333",
|
||||
"20590447254980891299813706518821659736846425329007960381537122689749540452732",
|
||||
"7423237065226347324353380772367382631490014989348495481811164164159255474657",
|
||||
"11286972368698509976183087595462810875513684078608517520839298933882497716792",
|
||||
"3607627140608796879659380071776844901612302623152076817094415224584923813162",
|
||||
"19712377064642672829441595136074946683621277828620209496774504837737984048981",
|
||||
"20775607673010627194014556968476266066927294572720319469184847051418138353016",
|
||||
"3396914609616007258851405644437304192397291162432396347162513310381425243293",
|
||||
"21551820661461729022865262380882070649935529853313286572328683688269863701601",
|
||||
"6573136701248752079028194407151022595060682063033565181951145966236778420039",
|
||||
"12413880268183407374852357075976609371175688755676981206018884971008854919922",
|
||||
"14271763308400718165336499097156975241954733520325982997864342600795471836726",
|
||||
"20066985985293572387227381049700832219069292839614107140851619262827735677018",
|
||||
"9394776414966240069580838672673694685292165040808226440647796406499139370960",
|
||||
"11331146992410411304059858900317123658895005918277453009197229807340014528524"
|
||||
],
|
||||
"identity_path_index": [
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"x": "8143228284048792769012135629627737459844825626241842423967352803501040982",
|
||||
"epoch": "0x0000005b612540fc986b42322f8cb91c2273afad58ed006fdba0c97b4b16b12f",
|
||||
"rln_identifier": "11412926387081627876309792396682864042420635853496105400039841573530884328439"
|
||||
}
|
||||
"#;
|
||||
|
||||
let witness_input: WitnessInput =
|
||||
serde_json::from_str(input_json_str).expect("JSON was not well-formatted");
|
||||
|
||||
println!("Witness input JSON: {:?}", witness_input);
|
||||
|
||||
let mut builder = CircomBuilder::new(cfg);
|
||||
|
||||
builder.push_input(
|
||||
"identity_secret",
|
||||
BigInt::parse_bytes(witness_input.identity_secret.as_bytes(), 10).unwrap(),
|
||||
);
|
||||
|
||||
for v in witness_input.path_elements.iter() {
|
||||
builder.push_input(
|
||||
"path_elements",
|
||||
BigInt::parse_bytes(v.as_bytes(), 10).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
for v in witness_input.identity_path_index.iter() {
|
||||
builder.push_input("identity_path_index", BigInt::from(*v));
|
||||
}
|
||||
|
||||
builder.push_input(
|
||||
"x",
|
||||
BigInt::parse_bytes(witness_input.x.as_bytes(), 10).unwrap(),
|
||||
);
|
||||
|
||||
builder.push_input(
|
||||
"epoch",
|
||||
BigInt::parse_bytes(
|
||||
witness_input.epoch.strip_prefix("0x").unwrap().as_bytes(),
|
||||
16,
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
builder.push_input(
|
||||
"rln_identifier",
|
||||
BigInt::parse_bytes(witness_input.rln_identifier.as_bytes(), 10).unwrap(),
|
||||
);
|
||||
|
||||
println!("Builder input:\n {:#?}", builder.inputs);
|
||||
|
||||
// create an empty instance for setting it up
|
||||
let circom = builder.setup();
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let params = generate_random_parameters::<Bn254, _, _>(circom, &mut rng).unwrap();
|
||||
|
||||
let circom = builder.build().unwrap();
|
||||
|
||||
let inputs = circom.get_public_inputs().unwrap();
|
||||
|
||||
println!("Public inputs {:#?} ", inputs);
|
||||
|
||||
// Sapling based tree
|
||||
// // TODO Add as parameter(s)
|
||||
// let merkle_depth: usize = 3;
|
||||
// let poseidon_params = PoseidonParams::<Bn256>::new(8, 55, 3, None, None, None);
|
||||
// let hasher = PoseidonHasher::new(poseidon_params.clone());
|
||||
// let tree = IncrementalMerkleTree::empty(hasher, merkle_depth);
|
||||
|
||||
let leaf = Field::from(0);
|
||||
let tree = PoseidonTree::new(21, leaf);
|
||||
|
||||
RLN {
|
||||
circom,
|
||||
params,
|
||||
tree,
|
||||
}
|
||||
}
|
||||
|
||||
/// returns current membership root
|
||||
/// * `root` is a scalar field element in 32 bytes
|
||||
pub fn get_root<W: Write>(&self, _result_data: W) -> io::Result<()> {
|
||||
@ -260,26 +122,3 @@ impl Default for RLN {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Expensive test, ignoring by default
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn rln_proof() {
|
||||
let rln = RLN::new();
|
||||
let rln_spike = RLN::new_json_spike();
|
||||
//let inputs = mul.circom.get_public_inputs().unwrap();
|
||||
|
||||
let mut output_data: Vec<u8> = Vec::new();
|
||||
let _ = rln_spike.prove(&mut output_data);
|
||||
|
||||
let proof_data = &output_data[..];
|
||||
|
||||
// XXX Pass as arg?
|
||||
//let pvk = prepare_verifying_key(&mul.params.vk);
|
||||
|
||||
// XXX: Something is wrong here I think, because it doesn't verify with the
|
||||
// full proof fields like yShare - just witness? Might be a bug
|
||||
let verified = rln.verify(proof_data).unwrap();
|
||||
|
||||
assert!(verified);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user