mirror of https://github.com/vacp2p/zerokit.git
fix(rln): switch to field type, add field arithmetic
This commit is contained in:
parent
cf6168bf4e
commit
7ac5b60cb6
|
@ -51,6 +51,7 @@ fn fq_from_str(s: &str) -> Fq {
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extracts the element in G1 corresponding to its JSON serialization
|
||||||
fn json_to_g1(json: &Value, key: &str) -> G1Affine {
|
fn json_to_g1(json: &Value, key: &str) -> G1Affine {
|
||||||
let els: Vec<String> = json
|
let els: Vec<String> = json
|
||||||
.get(key)
|
.get(key)
|
||||||
|
@ -67,6 +68,7 @@ fn json_to_g1(json: &Value, key: &str) -> G1Affine {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extracts the vector of G1 elements corresponding to its JSON serialization
|
||||||
fn json_to_g1_vec(json: &Value, key: &str) -> Vec<G1Affine> {
|
fn json_to_g1_vec(json: &Value, key: &str) -> Vec<G1Affine> {
|
||||||
let els: Vec<Vec<String>> = json
|
let els: Vec<Vec<String>> = json
|
||||||
.get(key)
|
.get(key)
|
||||||
|
@ -94,6 +96,7 @@ fn json_to_g1_vec(json: &Value, key: &str) -> Vec<G1Affine> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extracts the element in G2 corresponding to its JSON serialization
|
||||||
fn json_to_g2(json: &Value, key: &str) -> G2Affine {
|
fn json_to_g2(json: &Value, key: &str) -> G2Affine {
|
||||||
let els: Vec<Vec<String>> = json
|
let els: Vec<Vec<String>> = json
|
||||||
.get(key)
|
.get(key)
|
||||||
|
@ -116,6 +119,7 @@ fn json_to_g2(json: &Value, key: &str) -> G2Affine {
|
||||||
G2Affine::from(G2Projective::new(x, y, z))
|
G2Affine::from(G2Projective::new(x, y, z))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Computes the verification key from its JSON serialization
|
||||||
fn vk_from_json(vk_path: &str) -> VerifyingKey<Bn254> {
|
fn vk_from_json(vk_path: &str) -> VerifyingKey<Bn254> {
|
||||||
let json = std::fs::read_to_string(vk_path).unwrap();
|
let json = std::fs::read_to_string(vk_path).unwrap();
|
||||||
let json: Value = serde_json::from_str(&json).unwrap();
|
let json: Value = serde_json::from_str(&json).unwrap();
|
||||||
|
@ -129,6 +133,7 @@ fn vk_from_json(vk_path: &str) -> VerifyingKey<Bn254> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks verification key to be correct with respect to proving key
|
||||||
pub fn check_vk_from_zkey(verifying_key: VerifyingKey<Bn254>) {
|
pub fn check_vk_from_zkey(verifying_key: VerifyingKey<Bn254>) {
|
||||||
assert_eq!(ZKEY().vk, verifying_key);
|
assert_eq!(ZKEY().vk, verifying_key);
|
||||||
}
|
}
|
||||||
|
|
103
rln/src/lib.rs
103
rln/src/lib.rs
|
@ -10,8 +10,7 @@ pub mod circuit;
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
pub mod protocol;
|
pub mod protocol;
|
||||||
pub mod public;
|
pub mod public;
|
||||||
|
pub mod utils;
|
||||||
pub type Field = Fr;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
@ -55,8 +54,59 @@ mod test {
|
||||||
|
|
||||||
// We check correct computation of the path and indexes
|
// We check correct computation of the path and indexes
|
||||||
let expected_path_elements = vec![
|
let expected_path_elements = vec![
|
||||||
"0",
|
Field::from_str("0x0000000000000000000000000000000000000000000000000000000000000000")
|
||||||
"14744269619966411208579211824598458697587494354926760081771325075741142829156",
|
.unwrap(),
|
||||||
|
Field::from_str("0x2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e1")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0")
|
||||||
|
.unwrap(),
|
||||||
|
Field::from_str("0x190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c")
|
||||||
|
.unwrap(),
|
||||||
|
];
|
||||||
|
|
||||||
|
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_witness_from_json() {
|
||||||
|
// 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",
|
"7423237065226347324353380772367382631490014989348495481811164164159255474657",
|
||||||
"11286972368698509976183087595462810875513684078608517520839298933882497716792",
|
"11286972368698509976183087595462810875513684078608517520839298933882497716792",
|
||||||
"3607627140608796879659380071776844901612302623152076817094415224584923813162",
|
"3607627140608796879659380071776844901612302623152076817094415224584923813162",
|
||||||
|
@ -69,17 +119,46 @@ mod test {
|
||||||
"14271763308400718165336499097156975241954733520325982997864342600795471836726",
|
"14271763308400718165336499097156975241954733520325982997864342600795471836726",
|
||||||
"20066985985293572387227381049700832219069292839614107140851619262827735677018",
|
"20066985985293572387227381049700832219069292839614107140851619262827735677018",
|
||||||
"9394776414966240069580838672673694685292165040808226440647796406499139370960",
|
"9394776414966240069580838672673694685292165040808226440647796406499139370960",
|
||||||
"11331146992410411304059858900317123658895005918277453009197229807340014528524",
|
"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 expected_identity_path_index: Vec<u8> =
|
// We generate all relevant keys
|
||||||
vec![1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
let proving_key = &ZKEY();
|
||||||
|
let verification_key = &VK();
|
||||||
|
let builder = CIRCOM();
|
||||||
|
|
||||||
assert_eq!(path_elements, expected_path_elements);
|
// We compute witness from the json input example
|
||||||
assert_eq!(identity_path_index, expected_identity_path_index);
|
let rln_witness = rln_witness_from_json(input_json_str);
|
||||||
|
|
||||||
// We check correct verification of the proof
|
// Let's generate a zkSNARK proof
|
||||||
assert!(tree.verify(id_commitment.into(), &merkle_proof));
|
let (proof, inputs) = generate_proof(builder, proving_key, rln_witness).unwrap();
|
||||||
|
|
||||||
|
// Let's verify the proof
|
||||||
|
let verified = verify_proof(verification_key, proof, inputs);
|
||||||
|
|
||||||
|
assert!(verified.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -9,7 +9,7 @@ use ark_groth16::{
|
||||||
VerifyingKey,
|
VerifyingKey,
|
||||||
};
|
};
|
||||||
use ark_relations::r1cs::SynthesisError;
|
use ark_relations::r1cs::SynthesisError;
|
||||||
use ark_std::{rand::thread_rng, UniformRand};
|
use ark_std::{rand::thread_rng, str::FromStr, 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};
|
||||||
|
@ -25,24 +25,52 @@ use serde::{Deserialize, Serialize};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
pub use crate::utils::{str_to_field, vec_to_field, vec_to_fr};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// RLN Witness data structure and utility functions
|
// RLN Witness data structure and utility functions
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct RLNWitnessInput {
|
pub struct RLNWitnessInput {
|
||||||
identity_secret: String,
|
identity_secret: Field,
|
||||||
path_elements: Vec<String>,
|
path_elements: Vec<Field>,
|
||||||
identity_path_index: Vec<u8>,
|
identity_path_index: Vec<u8>,
|
||||||
x: String,
|
x: Field,
|
||||||
epoch: String,
|
epoch: Field,
|
||||||
rln_identifier: String,
|
rln_identifier: Field,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rln_witness_from_json(input_json_str: &str) -> RLNWitnessInput {
|
pub fn rln_witness_from_json(input_json_str: &str) -> RLNWitnessInput {
|
||||||
let rln_witness: RLNWitnessInput =
|
let input_json: serde_json::Value =
|
||||||
serde_json::from_str(input_json_str).expect("JSON was not well-formatted");
|
serde_json::from_str(input_json_str).expect("JSON was not well-formatted");
|
||||||
rln_witness
|
|
||||||
|
let identity_secret = str_to_field(input_json["identity_secret"].to_string(), 10);
|
||||||
|
|
||||||
|
let mut path_elements: Vec<Field> = vec![];
|
||||||
|
for v in input_json["path_elements"].as_array().unwrap().iter() {
|
||||||
|
path_elements.push(str_to_field(v.to_string(), 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut identity_path_index: Vec<u8> = vec![];
|
||||||
|
for v in input_json["identity_path_index"].as_array().unwrap().iter() {
|
||||||
|
identity_path_index.push(v.as_u64().unwrap() as u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = str_to_field(input_json["x"].to_string(), 10);
|
||||||
|
|
||||||
|
let epoch = str_to_field(input_json["epoch"].to_string(), 16);
|
||||||
|
|
||||||
|
let rln_identifier = str_to_field(input_json["rln_identifier"].to_string(), 10);
|
||||||
|
|
||||||
|
RLNWitnessInput {
|
||||||
|
identity_secret,
|
||||||
|
path_elements,
|
||||||
|
identity_path_index,
|
||||||
|
x,
|
||||||
|
epoch,
|
||||||
|
rln_identifier,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rln_witness_from_values(
|
pub fn rln_witness_from_values(
|
||||||
|
@ -55,16 +83,14 @@ pub fn rln_witness_from_values(
|
||||||
let path_elements = get_path_elements(merkle_proof);
|
let path_elements = get_path_elements(merkle_proof);
|
||||||
let identity_path_index = get_identity_path_index(merkle_proof);
|
let identity_path_index = get_identity_path_index(merkle_proof);
|
||||||
|
|
||||||
let rln_witness = RLNWitnessInput {
|
RLNWitnessInput {
|
||||||
identity_secret: BigInt::from(identity_secret).to_str_radix(10),
|
identity_secret,
|
||||||
path_elements,
|
path_elements,
|
||||||
identity_path_index,
|
identity_path_index,
|
||||||
x: BigInt::from(x).to_str_radix(10),
|
x,
|
||||||
epoch: format!("{:#066x}", BigInt::from(epoch)), //We format it as a padded 32 bytes hex with leading 0x for compatibility with zk-kit
|
epoch,
|
||||||
rln_identifier: BigInt::from(rln_identifier).to_str_radix(10),
|
rln_identifier,
|
||||||
};
|
}
|
||||||
|
|
||||||
rln_witness
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
@ -117,12 +143,12 @@ impl From<Proof> for ArkProof<Bn<Parameters>> {
|
||||||
|
|
||||||
/// 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
|
||||||
pub fn get_path_elements(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<String> {
|
pub fn get_path_elements(proof: &merkle_tree::Proof<PoseidonHash>) -> Vec<Field> {
|
||||||
proof
|
proof
|
||||||
.0
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| match x {
|
.map(|x| match x {
|
||||||
Branch::Left(value) | Branch::Right(value) => BigInt::from(*value).to_str_radix(10),
|
Branch::Left(value) | Branch::Right(value) => *value,
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -180,44 +206,29 @@ pub fn generate_proof(
|
||||||
mut builder: CircomBuilder<Bn254>,
|
mut builder: CircomBuilder<Bn254>,
|
||||||
proving_key: &ProvingKey<Bn254>,
|
proving_key: &ProvingKey<Bn254>,
|
||||||
rln_witness: RLNWitnessInput,
|
rln_witness: RLNWitnessInput,
|
||||||
) -> Result<(Proof, Vec<Fr>), ProofError> {
|
) -> Result<(Proof, Vec<Field>), ProofError> {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
builder.push_input(
|
builder.push_input("identity_secret", BigInt::from(rln_witness.identity_secret));
|
||||||
"identity_secret",
|
|
||||||
BigInt::parse_bytes(rln_witness.identity_secret.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
for v in rln_witness.path_elements.iter() {
|
for v in rln_witness.path_elements.iter() {
|
||||||
builder.push_input(
|
builder.push_input("path_elements", BigInt::from(*v));
|
||||||
"path_elements",
|
|
||||||
BigInt::parse_bytes(v.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for v in rln_witness.identity_path_index.iter() {
|
for v in rln_witness.identity_path_index.iter() {
|
||||||
builder.push_input("identity_path_index", BigInt::from(*v));
|
builder.push_input("identity_path_index", BigInt::from(*v));
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.push_input(
|
builder.push_input("x", BigInt::from(rln_witness.x));
|
||||||
"x",
|
|
||||||
BigInt::parse_bytes(rln_witness.x.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
builder.push_input("epoch", BigInt::from(rln_witness.epoch));
|
||||||
"epoch",
|
|
||||||
BigInt::parse_bytes(rln_witness.epoch.strip_prefix("0x").unwrap().as_bytes(), 16).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
builder.push_input("rln_identifier", BigInt::from(rln_witness.rln_identifier));
|
||||||
"rln_identifier",
|
|
||||||
BigInt::parse_bytes(rln_witness.rln_identifier.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let circom = builder.build().unwrap();
|
let circom = builder.build().unwrap();
|
||||||
|
|
||||||
// Get the populated instance of the circuit with the witness
|
// Get the populated instance of the circuit with the witness
|
||||||
let inputs = circom.get_public_inputs().unwrap();
|
let inputs = vec_to_field(circom.get_public_inputs().unwrap());
|
||||||
|
|
||||||
println!("witness generation took: {:.2?}", now.elapsed());
|
println!("witness generation took: {:.2?}", now.elapsed());
|
||||||
|
|
||||||
|
@ -249,12 +260,12 @@ pub fn generate_proof(
|
||||||
pub fn verify_proof(
|
pub fn verify_proof(
|
||||||
verifying_key: &VerifyingKey<Bn254>,
|
verifying_key: &VerifyingKey<Bn254>,
|
||||||
proof: Proof,
|
proof: Proof,
|
||||||
inputs: Vec<Fr>,
|
inputs: Vec<Field>,
|
||||||
) -> Result<bool, ProofError> {
|
) -> Result<bool, ProofError> {
|
||||||
// Check that the proof is valid
|
// Check that the proof is valid
|
||||||
let pvk = prepare_verifying_key(verifying_key);
|
let pvk = prepare_verifying_key(verifying_key);
|
||||||
let pr: ArkProof<Bn254> = proof.into();
|
let pr: ArkProof<Bn254> = proof.into();
|
||||||
let verified = ark_verify_proof(&pvk, &pr, &inputs)?;
|
let verified = ark_verify_proof(&pvk, &pr, &vec_to_fr(inputs))?;
|
||||||
|
|
||||||
Ok(verified)
|
Ok(verified)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,26 +17,18 @@ use serde::Deserialize;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
|
use crate::circuit::{CIRCOM, ZKEY};
|
||||||
|
use crate::protocol;
|
||||||
|
|
||||||
// TODO Add Engine here? i.e. <E: Engine> not <Bn254>
|
// TODO Add Engine here? i.e. <E: Engine> not <Bn254>
|
||||||
// TODO Assuming we want to use IncrementalMerkleTree, figure out type/trait conversions
|
// TODO Assuming we want to use IncrementalMerkleTree, figure out type/trait conversions
|
||||||
// TODO Adopt to new protocol structure
|
// TODO Adopt to new protocol structure
|
||||||
pub struct RLN {
|
pub struct RLN {
|
||||||
circom: CircomCircuit<Bn254>,
|
circom: CircomCircuit<Bn254>, //Was CircomCircuit
|
||||||
params: ProvingKey<Bn254>,
|
params: ProvingKey<Bn254>,
|
||||||
tree: PoseidonTree,
|
tree: PoseidonTree,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
//#[serde(rename_all = "camelCase")]
|
|
||||||
struct WitnessInput {
|
|
||||||
identity_secret: String,
|
|
||||||
path_elements: Vec<String>,
|
|
||||||
identity_path_index: Vec<i32>,
|
|
||||||
x: String,
|
|
||||||
epoch: String,
|
|
||||||
rln_identifier: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Expand API to have better coverage of things needed
|
// TODO Expand API to have better coverage of things needed
|
||||||
|
|
||||||
impl RLN {
|
impl RLN {
|
||||||
|
@ -47,19 +39,18 @@ impl RLN {
|
||||||
|
|
||||||
let builder = CircomBuilder::new(cfg);
|
let builder = CircomBuilder::new(cfg);
|
||||||
|
|
||||||
// create an empty instance for setting it up
|
let params = ZKEY();
|
||||||
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 circom = builder.build().unwrap();
|
||||||
|
|
||||||
let inputs = circom.get_public_inputs().unwrap();
|
let inputs = circom.get_public_inputs().unwrap();
|
||||||
println!("Public inputs {:#?} ", inputs);
|
println!("Public inputs {:#?} ", inputs);
|
||||||
|
|
||||||
|
// We compute a default empty tree
|
||||||
|
// Probably better to pass it as parameter
|
||||||
|
let TREE_HEIGHT = 21;
|
||||||
let leaf = Field::from(0);
|
let leaf = Field::from(0);
|
||||||
let tree = PoseidonTree::new(21, leaf);
|
let tree = PoseidonTree::new(TREE_HEIGHT, leaf);
|
||||||
|
|
||||||
RLN {
|
RLN {
|
||||||
circom,
|
circom,
|
||||||
|
@ -68,6 +59,18 @@ impl RLN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_tree<R: Read>(&self, _input_data: R) -> io::Result<()> {
|
||||||
|
//Implement leaf and deserialization
|
||||||
|
//let leaf = Leaf::deserialize(input_data).unwrap();
|
||||||
|
|
||||||
|
//returns H::Hash, which is a 256 bit hash value
|
||||||
|
//let root = self.tree.root();
|
||||||
|
// TODO Return root as LE here
|
||||||
|
//root.write_le(&mut result_data)?;
|
||||||
|
//println!("NYI: root le write buffer {:#?}", root);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// returns current membership root
|
/// returns current membership root
|
||||||
/// * `root` is a scalar field element in 32 bytes
|
/// * `root` is a scalar field element in 32 bytes
|
||||||
pub fn get_root<W: Write>(&self, _result_data: W) -> io::Result<()> {
|
pub fn get_root<W: Write>(&self, _result_data: W) -> io::Result<()> {
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
use ark_bn254::{Bn254, Fr, Parameters};
|
||||||
|
use ark_ff::{Fp256, PrimeField};
|
||||||
|
use ark_std::str::FromStr;
|
||||||
|
use ethers_core::utils::keccak256;
|
||||||
|
use num_bigint::{BigInt, BigUint, ToBigInt};
|
||||||
|
use semaphore::{identity::Identity, Field};
|
||||||
|
|
||||||
|
pub fn to_fr(el: Field) -> Fr {
|
||||||
|
Fr::try_from(el).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_field(el: Fr) -> Field {
|
||||||
|
el.try_into().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vec_to_fr(v: Vec<Field>) -> Vec<Fr> {
|
||||||
|
let mut result: Vec<Fr> = vec![];
|
||||||
|
for el in v {
|
||||||
|
result.push(to_fr(el));
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vec_to_field(v: Vec<Fr>) -> Vec<Field> {
|
||||||
|
let mut result: Vec<Field> = vec![];
|
||||||
|
for el in v {
|
||||||
|
result.push(to_field(el));
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn str_to_field(input: String, radix: i32) -> Field {
|
||||||
|
assert!((radix == 10) || (radix == 16));
|
||||||
|
|
||||||
|
// We remove any quote present and we trim
|
||||||
|
let input_clean = input.replace("\"", "");
|
||||||
|
let input_clean = input_clean.trim();
|
||||||
|
|
||||||
|
if radix == 10 {
|
||||||
|
Field::from_str(&format!(
|
||||||
|
"{:01$x}",
|
||||||
|
BigUint::from_str(input_clean).unwrap(),
|
||||||
|
64
|
||||||
|
))
|
||||||
|
.unwrap()
|
||||||
|
} else {
|
||||||
|
let input_clean = input_clean.replace("0x", "");
|
||||||
|
Field::from_str(&format!("{:0>64}", &input_clean)).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arithmetic over Field elements (wrapped over arkworks algebra crate)
|
||||||
|
|
||||||
|
pub fn add(a: Field, b: Field) -> Field {
|
||||||
|
to_field(to_fr(a) + to_fr(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mul(a: Field, b: Field) -> Field {
|
||||||
|
to_field(to_fr(a) * to_fr(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn div(a: Field, b: Field) -> Field {
|
||||||
|
to_field(to_fr(a) / to_fr(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inv(a: Field) -> Field {
|
||||||
|
to_field(Fr::from(1) / to_fr(a))
|
||||||
|
}
|
Loading…
Reference in New Issue