diff --git a/rln/README.md b/rln/README.md index fe6ae2b..4271908 100644 --- a/rln/README.md +++ b/rln/README.md @@ -3,6 +3,7 @@ This module provides APIs to manage, compute and verify [RLN](https://rfc.vac.dev/spec/32/) zkSNARK proofs and RLN primitives. ## Pre-requisites + ### Install dependencies and clone repo ```sh @@ -14,6 +15,7 @@ cd zerokit/rln ### Build and Test To build and test, run the following commands within the module folder + ```bash cargo make build cargo make test @@ -21,11 +23,11 @@ cargo make test ### Compile ZK circuits -The `rln` (https://github.com/privacy-scaling-explorations/rln) repository, which contains the RLN circuit implementation is a submodule of zerokit RLN. +The `rln` (https://github.com/rate-limiting-nullifier/circom-rln) repository, which contains the RLN circuit implementation is a submodule of zerokit RLN. To compile the RLN circuit -``` sh +```sh # Update submodules git submodule update --init --recursive @@ -52,10 +54,9 @@ include "./rln-base.circom"; component main {public [x, epoch, rln_identifier ]} = RLN(N); ``` -However, if `N` is too big, this might require a bigger Powers of Tau ceremony than the one hardcoded in `./scripts/build-circuits.sh`, which is `2^14`. +However, if `N` is too big, this might require a bigger Powers of Tau ceremony than the one hardcoded in `./scripts/build-circuits.sh`, which is `2^14`. In such case we refer to the official [Circom documentation](https://docs.circom.io/getting-started/proving-circuits/#powers-of-tau) for instructions on how to run an appropriate Powers of Tau ceremony and Phase 2 in order to compile the desired circuit. - Currently, the `rln` module comes with 2 [pre-compiled](https://github.com/vacp2p/zerokit/tree/master/rln/resources) RLN circuits having Merkle tree of height `20` and `32`, respectively. ## Getting started @@ -73,7 +74,7 @@ rln = { git = "https://github.com/vacp2p/zerokit" } First, we need to create a RLN object for a chosen input Merkle tree size. -Note that we need to pass to RLN object constructor the path where the circuit (`rln.wasm`, built for the input tree size), the corresponding proving key (`rln_final.zkey`) and verification key (`verification_key.json`, optional) are found. +Note that we need to pass to RLN object constructor the path where the circuit (`rln.wasm`, built for the input tree size), the corresponding proving key (`rln_final.zkey`) or (`rln_final.arkzkey`) and verification key (`verification_key.json`, optional) are found. In the following we will use [cursors](https://doc.rust-lang.org/std/io/struct.Cursor.html) as readers/writers for interfacing with RLN public APIs. @@ -82,14 +83,14 @@ use rln::protocol::*; use rln::public::*; use std::io::Cursor; -// We set the RLN parameters: +// We set the RLN parameters: // - the tree height; -// - the circuit resource folder (requires a trailing "/"). +// - the tree config, if it is not defined, the default value will be set let tree_height = 20; -let resources = Cursor::new("../zerokit/rln/resources/tree_height_20/"); +let input = Cursor::new(json!({}).to_string()); // We create a new RLN instance -let mut rln = RLN::new(tree_height, resources); +let mut rln = RLN::new(tree_height, input); ``` ### Generate an identity keypair @@ -121,33 +122,43 @@ rln.set_leaf(id_index, &mut buffer).unwrap(); Note that when tree leaves are not explicitly set by the user (in this example, all those with index less and greater than `10`), their values is set to an hardcoded default (all-`0` bytes in current implementation). -### Set epoch +### Set external nullifier -The epoch, sometimes referred to as _external nullifier_, is used to identify messages received in a certain time frame. It usually corresponds to the current UNIX time but can also be set to a random value or generated by a seed, provided that it corresponds to a field element. +The `external nullifier` includes two parameters. + +The first one is `epoch` and it's used to identify messages received in a certain time frame. It usually corresponds to the current UNIX time but can also be set to a random value or generated by a seed, provided that it corresponds to a field element. + +The second one is `rln_identifier` and it's used to prevent a RLN ZK proof generated for one application to be re-used in another one. ```rust // We generate epoch from a date seed and we ensure is // mapped to a field element by hashing-to-field its content let epoch = hash_to_field(b"Today at noon, this year"); +// We generate rln_identifier from a date seed and we ensure is +// mapped to a field element by hashing-to-field its content +let rln_identifier = hash_to_field(b"test-rln-identifier"); + +let external_nullifier = poseidon_hash(&[epoch, rln_identifier]); ``` + ### Set signal The signal is the message for which we are computing a RLN proof. ```rust -// We set our signal +// We set our signal let signal = b"RLN is awesome"; ``` ### Generate a RLN proof -We prepare the input to the proof generation routine. +We prepare the input to the proof generation routine. -Input buffer is serialized as `[ identity_key | id_index | epoch | rln_identifier | user_message_limit | message_id | signal_len | signal ]`. +Input buffer is serialized as `[ identity_key | id_index | external_nullifier | user_message_limit | message_id | signal_len | signal ]`. ```rust // We prepare input to the proof generation routine -let proof_input = prepare_prove_input(identity_secret_hash, id_index, epoch, rln_identifier, user_message_limit, message_id, signal); +let proof_input = prepare_prove_input(identity_secret_hash, id_index, external_nullifier, signal); ``` We are now ready to generate a RLN ZK proof along with the _public outputs_ of the ZK circuit evaluation. @@ -164,12 +175,11 @@ rln.generate_rln_proof(&mut in_buffer, &mut out_buffer) let proof_data = out_buffer.into_inner(); ``` -The byte vector `proof_data` is serialized as `[ zk-proof | tree_root | epoch | share_x | share_y | nullifier | rln_identifier ]`. - +The byte vector `proof_data` is serialized as `[ zk-proof | tree_root | external_nullifier | share_x | share_y | nullifier ]`. ### Verify a RLN proof -We prepare the input to the proof verification routine. +We prepare the input to the proof verification routine. Input buffer is serialized as `[proof_data | signal_len | signal ]`, where `proof_data` is (computed as) the output obtained by `generate_rln_proof`. @@ -182,17 +192,21 @@ let mut in_buffer = Cursor::new(verify_data); let verified = rln.verify(&mut in_buffer).unwrap(); ``` -We check if the proof verification was successful: +We check if the proof verification was successful: + ```rust // We ensure the proof is valid assert!(verified); ``` ## Get involved! + Zerokit RLN public and FFI APIs allow interaction with many more features than what briefly showcased above. We invite you to check our API documentation by running + ```rust cargo doc --no-deps ``` -and look at unit tests to have an hint on how to interface and use them. \ No newline at end of file + +and look at unit tests to have an hint on how to interface and use them. diff --git a/rln/benches/circuit_loading_benchmark.rs b/rln/benches/circuit_loading_benchmark.rs index b929b1e..6f6870d 100644 --- a/rln/benches/circuit_loading_benchmark.rs +++ b/rln/benches/circuit_loading_benchmark.rs @@ -1,12 +1,11 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use rln::circuit::TEST_RESOURCES_FOLDER; // Depending on the key type (enabled by the `--features arkzkey` flag) // the upload speed from the `rln_final.zkey` or `rln_final.arkzkey` file is calculated pub fn key_load_benchmark(c: &mut Criterion) { c.bench_function("zkey::upload_from_folder", |b| { b.iter(|| { - let _ = rln::circuit::zkey_from_folder(TEST_RESOURCES_FOLDER); + let _ = rln::circuit::zkey_from_folder(); }) }); } diff --git a/rln/src/circuit.rs b/rln/src/circuit.rs index 82fcae2..97b5632 100644 --- a/rln/src/circuit.rs +++ b/rln/src/circuit.rs @@ -26,7 +26,7 @@ cfg_if! { cfg_if! { if #[cfg(feature = "arkzkey")] { use ark_zkey::read_arkzkey_from_bytes; - const ARKZKEY_FILENAME: &str = "rln_final.arkzkey"; + const ARKZKEY_FILENAME: &str = "tree_height_20/rln_final.arkzkey"; } else { use std::io::Cursor; @@ -34,12 +34,11 @@ cfg_if! { } } -const ZKEY_FILENAME: &str = "rln_final.zkey"; -const VK_FILENAME: &str = "verification_key.json"; -const WASM_FILENAME: &str = "rln.wasm"; +const ZKEY_FILENAME: &str = "tree_height_20/rln_final.zkey"; +const VK_FILENAME: &str = "tree_height_20/verification_key.json"; +const WASM_FILENAME: &str = "tree_height_20/rln.wasm"; pub const TEST_TREE_HEIGHT: usize = 20; -pub const TEST_RESOURCES_FOLDER: &str = "tree_height_20"; #[cfg(not(target_arch = "wasm32"))] static RESOURCES_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/resources"); @@ -75,13 +74,11 @@ pub fn zkey_from_raw(zkey_data: &Vec) -> Result<(ProvingKey, Constrai // Loads the proving key #[cfg(not(target_arch = "wasm32"))] -pub fn zkey_from_folder( - resources_folder: &str, -) -> Result<(ProvingKey, ConstraintMatrices)> { +pub fn zkey_from_folder() -> Result<(ProvingKey, ConstraintMatrices)> { #[cfg(feature = "arkzkey")] - let zkey = RESOURCES_DIR.get_file(Path::new(resources_folder).join(ARKZKEY_FILENAME)); + let zkey = RESOURCES_DIR.get_file(Path::new(ARKZKEY_FILENAME)); #[cfg(not(feature = "arkzkey"))] - let zkey = RESOURCES_DIR.get_file(Path::new(resources_folder).join(ZKEY_FILENAME)); + let zkey = RESOURCES_DIR.get_file(Path::new(ZKEY_FILENAME)); if let Some(zkey) = zkey { let proving_key_and_matrices = match () { @@ -117,9 +114,9 @@ pub fn vk_from_raw(vk_data: &[u8], zkey_data: &Vec) -> Result Result> { - let vk = RESOURCES_DIR.get_file(Path::new(resources_folder).join(VK_FILENAME)); - let zkey = RESOURCES_DIR.get_file(Path::new(resources_folder).join(ZKEY_FILENAME)); +pub fn vk_from_folder() -> Result> { + let vk = RESOURCES_DIR.get_file(Path::new(VK_FILENAME)); + let zkey = RESOURCES_DIR.get_file(Path::new(ZKEY_FILENAME)); let verifying_key: VerifyingKey; if let Some(vk) = vk { @@ -128,7 +125,7 @@ pub fn vk_from_folder(resources_folder: &str) -> Result> { ))?)?; Ok(verifying_key) } else if let Some(_zkey) = zkey { - let (proving_key, _matrices) = zkey_from_folder(resources_folder)?; + let (proving_key, _matrices) = zkey_from_folder()?; verifying_key = proving_key.vk; Ok(verifying_key) } else { @@ -152,9 +149,9 @@ pub fn circom_from_raw(wasm_buffer: Vec) -> Result<&'static Mutex Result<&'static Mutex> { +pub fn circom_from_folder() -> Result<&'static Mutex> { // We read the wasm file - let wasm = RESOURCES_DIR.get_file(Path::new(resources_folder).join(WASM_FILENAME)); + let wasm = RESOURCES_DIR.get_file(Path::new(WASM_FILENAME)); if let Some(wasm) = wasm { let wasm_buffer = wasm.contents(); @@ -277,11 +274,8 @@ fn vk_from_vector(vk: &[u8]) -> Result> { // Checks verification key to be correct with respect to proving key #[cfg(not(target_arch = "wasm32"))] -pub fn check_vk_from_zkey( - resources_folder: &str, - verifying_key: VerifyingKey, -) -> Result<()> { - let (proving_key, _matrices) = zkey_from_folder(resources_folder)?; +pub fn check_vk_from_zkey(verifying_key: VerifyingKey) -> Result<()> { + let (proving_key, _matrices) = zkey_from_folder()?; if proving_key.vk == verifying_key { Ok(()) } else { diff --git a/rln/src/public.rs b/rln/src/public.rs index 814ff46..1d4ba3e 100644 --- a/rln/src/public.rs +++ b/rln/src/public.rs @@ -19,7 +19,7 @@ cfg_if! { if #[cfg(not(target_arch = "wasm32"))] { use std::default::Default; use std::sync::Mutex; - use crate::circuit::{circom_from_folder, vk_from_folder, circom_from_raw, zkey_from_folder, TEST_RESOURCES_FOLDER, TEST_TREE_HEIGHT}; + use crate::circuit::{circom_from_folder, vk_from_folder, circom_from_raw, zkey_from_folder, TEST_TREE_HEIGHT}; use ark_circom::WitnessCalculator; use serde_json::{json, Value}; use utils::{Hasher}; @@ -58,18 +58,16 @@ impl RLN<'_> { /// /// Input parameters are /// - `tree_height`: the height of the internal Merkle tree - /// - `input_data`: include next parameters - /// - `resources_folder`: a reader for the string path of the resource folder containing the ZK circuit (`rln.wasm`), the proving key (`rln_final.zkey`) or (`rln_final.arkzkey`) and the verification key (`verification_key.json`). - /// - `tree_config`: a reader for a string containing a json with the merkle tree configuration + /// - `input_data`: include `tree_config` a reader for a string containing a json with the merkle tree configuration /// Example: /// ``` /// use std::io::Cursor; /// /// let tree_height = 20; - /// let resources = Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string());; + /// let input = Cursor::new(json!({}).to_string());; /// /// // We create a new RLN instance - /// let mut rln = RLN::new(tree_height, resources); + /// let mut rln = RLN::new(tree_height, input); /// ``` #[cfg(not(target_arch = "wasm32"))] pub fn new(tree_height: usize, mut input_data: R) -> Result> { @@ -78,15 +76,12 @@ impl RLN<'_> { input_data.read_to_end(&mut input)?; let rln_config: Value = serde_json::from_str(&String::from_utf8(input)?)?; - let resources_folder = rln_config["resources_folder"] - .as_str() - .unwrap_or(TEST_RESOURCES_FOLDER); let tree_config = rln_config["tree_config"].to_string(); - let witness_calculator = circom_from_folder(resources_folder)?; - let proving_key = zkey_from_folder(resources_folder)?; + let witness_calculator = circom_from_folder()?; + let proving_key = zkey_from_folder()?; - let verification_key = vk_from_folder(resources_folder)?; + let verification_key = vk_from_folder()?; let tree_config: ::Config = if tree_config.is_empty() { ::Config::default() @@ -1204,7 +1199,7 @@ impl RLN<'_> { impl Default for RLN<'_> { fn default() -> Self { let tree_height = TEST_TREE_HEIGHT; - let buffer = Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); + let buffer = Cursor::new(json!({}).to_string()); Self::new(tree_height, buffer).unwrap() } } diff --git a/rln/src/public_api_tests.rs b/rln/src/public_api_tests.rs index 1216e9d..ef70fac 100644 --- a/rln/src/public_api_tests.rs +++ b/rln/src/public_api_tests.rs @@ -1,4 +1,4 @@ -use crate::circuit::{Curve, Fr, TEST_RESOURCES_FOLDER, TEST_TREE_HEIGHT}; +use crate::circuit::{Curve, Fr, TEST_TREE_HEIGHT}; use crate::hashers::{hash_to_field, poseidon_hash as utils_poseidon_hash}; use crate::protocol::*; use crate::public::RLN; @@ -28,9 +28,7 @@ fn test_merkle_operations() { } // We create a new tree - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We first add leaves one by one specifying the index for (i, leaf) in leaves.iter().enumerate() { @@ -124,9 +122,7 @@ fn test_leaf_setting_with_index() { let set_index = rng.gen_range(0..no_of_leaves) as usize; // We create a new tree - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We add leaves in a batch into the tree let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap()); @@ -196,9 +192,7 @@ fn test_atomic_operation() { } // We create a new tree - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We add leaves in a batch into the tree let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap()); @@ -247,9 +241,7 @@ fn test_atomic_operation_zero_indexed() { } // We create a new tree - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We add leaves in a batch into the tree let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap()); @@ -293,9 +285,7 @@ fn test_atomic_operation_consistency() { } // We create a new tree - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We add leaves in a batch into the tree let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap()); @@ -348,9 +338,7 @@ fn test_set_leaves_bad_index() { let bad_index = (1 << tree_height) - rng.gen_range(0..no_of_leaves) as usize; // We create a new tree - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // Get root of empty tree let mut buffer = Cursor::new(Vec::::new()); @@ -413,9 +401,7 @@ fn value_to_string_vec(value: &Value) -> Vec { fn test_groth16_proof_hardcoded() { let tree_height = TEST_TREE_HEIGHT; - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let rln = RLN::new(tree_height, input_buffer).unwrap(); + let rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); let valid_snarkjs_proof = json!({ "pi_a": [ @@ -495,9 +481,7 @@ fn test_groth16_proof_hardcoded() { fn test_groth16_proof() { let tree_height = TEST_TREE_HEIGHT; - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // Note: we only test Groth16 proof generation, so we ignore setting the tree in the RLN object let rln_witness = random_rln_witness(tree_height); @@ -543,9 +527,7 @@ fn test_rln_proof() { } // We create a new RLN instance - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We add leaves in a batch into the tree let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap()); @@ -588,11 +570,11 @@ fn test_rln_proof() { rln.generate_rln_proof(&mut input_buffer, &mut output_buffer) .unwrap(); - // output_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ] + // output_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> ] let mut proof_data = output_buffer.into_inner(); // We prepare input for verify_rln_proof API - // input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal ] + // input_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> | signal_len<8> | signal ] // that is [ proof_data || signal_len<8> | signal ] proof_data.append(&mut normalize_usize(signal.len())); proof_data.append(&mut signal.to_vec()); @@ -616,9 +598,7 @@ fn test_rln_with_witness() { } // We create a new RLN instance - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We add leaves in a batch into the tree let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap()); @@ -693,11 +673,11 @@ fn test_rln_with_witness() { ) .unwrap(); - // output_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ] + // output_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> ] let mut proof_data = output_buffer.into_inner(); // We prepare input for verify_rln_proof API - // input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal ] + // input_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> | signal_len<8> | signal ] // that is [ proof_data || signal_len<8> | signal ] proof_data.append(&mut normalize_usize(signal.len())); proof_data.append(&mut signal.to_vec()); @@ -722,9 +702,7 @@ fn proof_verification_with_roots() { } // We create a new RLN instance - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We add leaves in a batch into the tree let mut buffer = Cursor::new(vec_fr_to_bytes_le(&leaves).unwrap()); @@ -751,7 +729,7 @@ fn proof_verification_with_roots() { let external_nullifier = utils_poseidon_hash(&[epoch, rln_identifier]); // We prepare input for generate_rln_proof API - // input_data is [ identity_secret<32> | id_index<8> | epoch<32> | rln_identifier<32> | user_message_limit<32> | message_id<32> | signal_len<8> | signal ] + // input_data is [ identity_secret<32> | id_index<8> | external_nullifier<32> | user_message_limit<32> | message_id<32> | signal_len<8> | signal ] let mut serialized: Vec = Vec::new(); serialized.append(&mut fr_to_bytes_le(&identity_secret_hash)); serialized.append(&mut normalize_usize(identity_index)); @@ -766,11 +744,11 @@ fn proof_verification_with_roots() { rln.generate_rln_proof(&mut input_buffer, &mut output_buffer) .unwrap(); - // output_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ] + // output_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> ] let mut proof_data = output_buffer.into_inner(); // We prepare input for verify_rln_proof API - // input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal ] + // input_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> | signal_len<8> | signal ] // that is [ proof_data || signal_len<8> | signal ] proof_data.append(&mut normalize_usize(signal.len())); proof_data.append(&mut signal.to_vec()); @@ -816,9 +794,7 @@ fn test_recover_id_secret() { let tree_height = TEST_TREE_HEIGHT; // We create a new RLN instance - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // Generate identity pair let (identity_secret_hash, id_commitment) = keygen(); @@ -953,9 +929,7 @@ fn test_get_leaf() { // We generate a random tree let tree_height = 10; let mut rng = thread_rng(); - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); // We generate a random leaf let leaf = Fr::rand(&mut rng); @@ -980,9 +954,7 @@ fn test_get_leaf() { fn test_valid_metadata() { let tree_height = TEST_TREE_HEIGHT; - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(tree_height, input_buffer).unwrap(); + let mut rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); let arbitrary_metadata: &[u8] = b"block_number:200000"; rln.set_metadata(arbitrary_metadata).unwrap(); @@ -998,9 +970,7 @@ fn test_valid_metadata() { fn test_empty_metadata() { let tree_height = TEST_TREE_HEIGHT; - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let rln = RLN::new(tree_height, input_buffer).unwrap(); + let rln = RLN::new(tree_height, generate_input_buffer()).unwrap(); let mut buffer = Cursor::new(Vec::::new()); rln.get_metadata(&mut buffer).unwrap(); diff --git a/rln/src/utils.rs b/rln/src/utils.rs index 581d070..93382cb 100644 --- a/rln/src/utils.rs +++ b/rln/src/utils.rs @@ -5,6 +5,8 @@ use ark_ff::PrimeField; use color_eyre::{Report, Result}; use num_bigint::{BigInt, BigUint}; use num_traits::Num; +use serde_json::json; +use std::io::Cursor; use std::iter::Extend; pub fn to_bigint(el: &Fr) -> Result { @@ -179,6 +181,11 @@ pub fn normalize_usize(input: usize) -> Vec { normalized_usize } +// using for test +pub fn generate_input_buffer() -> Cursor { + Cursor::new(json!({}).to_string()) +} + /* Old conversion utilities between different libraries data types // Conversion Utilities between poseidon-rs Field and arkworks Fr (in order to call directly poseidon-rs' poseidon_hash) diff --git a/rln/tests/ffi.rs b/rln/tests/ffi.rs index 63e6e11..30b977a 100644 --- a/rln/tests/ffi.rs +++ b/rln/tests/ffi.rs @@ -18,7 +18,7 @@ mod test { fn create_rln_instance() -> &'static mut RLN<'static> { let mut rln_pointer = MaybeUninit::<*mut RLN>::uninit(); - let input_config = json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string(); + let input_config = json!({}).to_string(); let input_buffer = &Buffer::from(input_config.as_bytes()); let success = new(TEST_TREE_HEIGHT, input_buffer, rln_pointer.as_mut_ptr()); assert!(success, "RLN object creation failed"); @@ -509,11 +509,11 @@ mod test { serialized.append(&mut signal.to_vec()); // We call generate_rln_proof - // result_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ] + // result_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> ] let mut proof_data = rln_proof_gen(rln_pointer, serialized.as_ref()); // We prepare input for verify_rln_proof API - // input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal ] + // input_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> | signal_len<8> | signal ] // that is [ proof_data | signal_len<8> | signal ] proof_data.append(&mut normalize_usize(signal.len())); proof_data.append(&mut signal.to_vec()); @@ -576,11 +576,11 @@ mod test { serialized.append(&mut signal.to_vec()); // We call generate_rln_proof - // result_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ] + // result_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> ] let mut proof_data = rln_proof_gen(rln_pointer, serialized.as_ref()); // We prepare input for verify_rln_proof API - // input_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> | signal_len<8> | signal ] + // input_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> | signal_len<8> | signal ] // that is [ proof_data | signal_len<8> | signal ] proof_data.append(&mut normalize_usize(signal.len())); proof_data.append(&mut signal.to_vec()); @@ -688,11 +688,11 @@ mod test { serialized2.append(&mut signal2.to_vec()); // We call generate_rln_proof for first proof values - // result_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ] + // result_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> ] let proof_data_1 = rln_proof_gen(rln_pointer, serialized1.as_ref()); // We call generate_rln_proof - // result_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ] + // result_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> ] let proof_data_2 = rln_proof_gen(rln_pointer, serialized2.as_ref()); let input_proof_buffer_1 = &Buffer::from(proof_data_1.as_ref()); @@ -746,7 +746,7 @@ mod test { serialized.append(&mut signal3.to_vec()); // We call generate_rln_proof - // result_data is [ proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32> ] + // result_data is [ proof<128> | root<32> | external_nullifier<32> | x<32> | y<32> | nullifier<32> ] let proof_data_3 = rln_proof_gen(rln_pointer, serialized.as_ref()); // We attempt to recover the secret using share1 (coming from identity_secret_hash) and share3 (coming from identity_secret_hash_new) diff --git a/rln/tests/protocol.rs b/rln/tests/protocol.rs index 165e22c..148aec4 100644 --- a/rln/tests/protocol.rs +++ b/rln/tests/protocol.rs @@ -2,9 +2,7 @@ mod test { use ark_ff::BigInt; use rln::circuit::zkey_from_folder; - use rln::circuit::{ - circom_from_folder, vk_from_folder, Fr, TEST_RESOURCES_FOLDER, TEST_TREE_HEIGHT, - }; + use rln::circuit::{circom_from_folder, vk_from_folder, Fr, TEST_TREE_HEIGHT}; use rln::hashers::{hash_to_field, poseidon_hash}; use rln::poseidon_tree::PoseidonTree; use rln::protocol::*; @@ -146,9 +144,9 @@ mod test { // We test a RLN proof generation and verification fn test_witness_from_json() { // We generate all relevant keys - let proving_key = zkey_from_folder(TEST_RESOURCES_FOLDER).unwrap(); - let verification_key = vk_from_folder(TEST_RESOURCES_FOLDER).unwrap(); - let builder = circom_from_folder(TEST_RESOURCES_FOLDER).unwrap(); + let proving_key = zkey_from_folder().unwrap(); + let verification_key = vk_from_folder().unwrap(); + let builder = circom_from_folder().unwrap(); // We compute witness from the json input example let witness_json = WITNESS_JSON_20; @@ -205,9 +203,9 @@ mod test { .unwrap(); // We generate all relevant keys - let proving_key = zkey_from_folder(TEST_RESOURCES_FOLDER).unwrap(); - let verification_key = vk_from_folder(TEST_RESOURCES_FOLDER).unwrap(); - let builder = circom_from_folder(TEST_RESOURCES_FOLDER).unwrap(); + let proving_key = zkey_from_folder().unwrap(); + let verification_key = vk_from_folder().unwrap(); + let builder = circom_from_folder().unwrap(); // Let's generate a zkSNARK proof let proof = generate_proof(builder, &proving_key, &rln_witness).unwrap(); diff --git a/rln/tests/public.rs b/rln/tests/public.rs index f863207..5b8dde3 100644 --- a/rln/tests/public.rs +++ b/rln/tests/public.rs @@ -3,12 +3,11 @@ mod test { use ark_ff::BigInt; use ark_std::{rand::thread_rng, UniformRand}; use rand::Rng; - use rln::circuit::{Fr, TEST_RESOURCES_FOLDER, TEST_TREE_HEIGHT}; + use rln::circuit::{Fr, TEST_TREE_HEIGHT}; use rln::hashers::{hash_to_field, poseidon_hash as utils_poseidon_hash, ROUND_PARAMS}; use rln::protocol::{compute_tree_root, deserialize_identity_tuple}; use rln::public::{hash as public_hash, poseidon_hash as public_poseidon_hash, RLN}; use rln::utils::*; - use serde_json::json; use std::io::Cursor; #[test] @@ -17,9 +16,7 @@ mod test { let leaf_index = 3; let user_message_limit = 1; - let input_buffer = - Cursor::new(json!({ "resources_folder": TEST_RESOURCES_FOLDER }).to_string()); - let mut rln = RLN::new(TEST_TREE_HEIGHT, input_buffer).unwrap(); + let mut rln = RLN::new(TEST_TREE_HEIGHT, generate_input_buffer()).unwrap(); // generate identity let identity_secret_hash = hash_to_field(b"test-merkle-proof");