fix(rln): resolve circuit parameter mismatch for customizable compilation (#288)

Trying out ideas to solve problems from this [Discord
conversation](https://discord.com/channels/864066763682218004/1344911294092017716):

- Completely remove the verification key file and use `vk_from_raw` or
derive it from ZK.
- To handle tree height mismatches, improve the documentation to provide
users with clear guidelines, preventing the generation of an incorrect
`graph.bin` file.
- Remove compressed `ark-zkey` usage and conduct benchmarking and
testing.
- Add documentation for the specific Circom compiler version 2.1.0.
- Update documentation on `rln.circom` parameters `N` and `M`.

---------

Co-authored-by: seemenkina <seemenkina@gmail.com>
This commit is contained in:
Vinh Trịnh
2025-03-14 13:17:52 +07:00
committed by GitHub
parent fb0ffd74a3
commit 759d312680
16 changed files with 120 additions and 165 deletions

View File

@@ -53,7 +53,9 @@ or with the **arkzkey** feature flag:
cargo run --example relay --features arkzkey
```
You can also change **MESSAGE_LIMIT** constant in the [relay.rs](src/examples/relay.rs) file to see how the RLN instance behaves with different parameters.
You can also change **MESSAGE_LIMIT** and **TREEE_HEIGHT** in the [relay.rs](src/examples/relay.rs) file to see how the RLN instance behaves with different parameters.
The customize **TREEE_HEIGHT** constant differs from the default value of `20` should follow [Custom Circuit Compilation](../rln/README.md#advanced-custom-circuit-compilation) instructions.
## Stateless Example

View File

@@ -1,12 +1,14 @@
use std::{
collections::HashMap,
io::{stdin, stdout, Cursor, Write},
fs::File,
io::{stdin, stdout, Cursor, Read, Write},
path::{Path, PathBuf},
};
use clap::{Parser, Subcommand};
use color_eyre::{eyre::eyre, Result};
use rln::{
circuit::{Fr, TEST_TREE_HEIGHT},
circuit::Fr,
hashers::{hash_to_field, poseidon_hash},
protocol::{keygen, prepare_prove_input, prepare_verify_input},
public::RLN,
@@ -15,6 +17,8 @@ use rln::{
const MESSAGE_LIMIT: u32 = 1;
const TREEE_HEIGHT: usize = 20;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
@@ -62,7 +66,27 @@ struct RLNSystem {
impl RLNSystem {
fn new() -> Result<Self> {
let rln = RLN::new(TEST_TREE_HEIGHT, generate_input_buffer())?;
let mut resources: Vec<Vec<u8>> = Vec::new();
let resources_path: PathBuf = format!("../rln/resources/tree_height_{TREEE_HEIGHT}").into();
#[cfg(feature = "arkzkey")]
let filenames = ["rln_final.arkzkey", "graph.bin"];
#[cfg(not(feature = "arkzkey"))]
let filenames = ["rln_final.zkey", "graph.bin"];
for filename in filenames {
let fullpath = resources_path.join(Path::new(filename));
let mut file = File::open(&fullpath)?;
let metadata = std::fs::metadata(&fullpath)?;
let mut output_buffer = vec![0; metadata.len() as usize];
file.read_exact(&mut output_buffer)?;
resources.push(output_buffer);
}
let rln = RLN::new_with_params(
TREEE_HEIGHT,
resources[0].clone(),
resources[1].clone(),
generate_input_buffer(),
)?;
println!("RLN instance initialized successfully");
Ok(RLNSystem {
rln,
used_nullifiers: HashMap::new(),
@@ -99,7 +123,7 @@ impl RLNSystem {
self.local_identities.insert(index, identity);
}
Err(_) => {
println!("Maximum user limit reached: 2^{TEST_TREE_HEIGHT}");
println!("Maximum user limit reached: 2^{TREEE_HEIGHT}");
}
};

View File

@@ -52,9 +52,9 @@ fn main() -> Result<()> {
}) => {
let mut resources: Vec<Vec<u8>> = Vec::new();
#[cfg(feature = "arkzkey")]
let filenames = ["rln_final.arkzkey", "verification_key.arkvkey", "graph.bin"];
let filenames = ["rln_final.arkzkey", "graph.bin"];
#[cfg(not(feature = "arkzkey"))]
let filenames = ["rln_final.zkey", "verification_key.arkvkey", "graph.bin"];
let filenames = ["rln_final.zkey", "graph.bin"];
for filename in filenames {
let fullpath = resources_path.join(Path::new(filename));
let mut file = File::open(&fullpath)?;
@@ -74,7 +74,6 @@ fn main() -> Result<()> {
tree_height,
resources[0].clone(),
resources[1].clone(),
resources[2].clone(),
Cursor::new(tree_config.to_string().as_bytes()),
)?)
} else {
@@ -83,7 +82,6 @@ fn main() -> Result<()> {
tree_height,
resources[0].clone(),
resources[1].clone(),
resources[2].clone(),
Cursor::new(json!({}).to_string()),
)?)
};

View File

@@ -98,10 +98,6 @@ name = "circuit_loading_arkzkey_benchmark"
harness = false
required-features = ["arkzkey"]
[[bench]]
name = "circuit_deser_benchmark"
harness = false
[[bench]]
name = "poseidon_tree_benchmark"
harness = false

View File

@@ -154,20 +154,48 @@ If you want to compile your own RLN circuit, you can follow the instructions bel
This script actually generates not only the zkey and verification key files for the RLN circuit, but also the execution wasm file used for witness calculation.
However, the wasm file is not needed for the `rln` module, because current implementation uses the iden3 graph file for witness calculation.
This graph file is generated by the `circom-witnesscalc` tool in step 2.
This graph file is generated by the `circom-witnesscalc` tool in [step 2](#2-generate-witness-calculation-graph).
To customize the circuit parameters, modify `circom-rln/circuit/rln.circom`:
To customize the circuit parameters, modify `circom-rln/circuits/rln.circom`:
```circom
pragma circom 2.1.0;
include "./rln.circom";
component main { public [x, externalNullifier] } = RLN(N, M); // N = tree height, M = limit bit size
component main { public [x, externalNullifier] } = RLN(N, M);
```
Where:
- `N`: Merkle tree height, determining the maximum membership capacity (2^N members).
- `M`: Bit size for range checks, setting an upper bound for the number of messages per epoch (2^M messages).
> [!NOTE]
> 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 one [pre-compiled](https://github.com/vacp2p/zerokit/tree/master/rln/resources) RLN circuit having Merkle tree of height `20`.
> However, if `N` is too big, this might require a larger 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. \
> Additionally, while `M` sets an upper bound on the number of messages per epoch (`2^M`), you can configure lower message limit for your use case, as long as it satisfies `user_message_limit ≤ 2^M`. \
> Currently, the `rln` module comes with a [pre-compiled](https://github.com/vacp2p/zerokit/tree/master/rln/resources) RLN circuit with a Merkle tree of height `20` and a bit size of `16`, allowing up to `2^20` registered members and a `2^16` message limit per epoch.
#### Install circom compiler
You can follow the instructions below or refer to the [installing Circom](https://docs.circom.io/getting-started/installation/#installing-circom) guide for more details, but make sure to use the specific version `v2.1.0`.
```sh
# Clone the circom repository
git clone https://github.com/iden3/circom.git
# Checkout the specific version
cd circom && git checkout v2.1.0
# Build the circom compiler
cargo build --release
# Install the circom binary globally
cargo install --path circom
# Check the circom version to ensure it's v2.1.0
circom --version
```
#### Generate the zkey and verification key files example
@@ -181,8 +209,8 @@ cd circom-rln && npm install
# Build circuits
./scripts/build-circuits.sh rln
# Copy assets to resources directory
cp build/zkeyFiles/final.zkey ./resources/tree_height_20/rln_final.zkey
# Use the generated zkey file in subsequent steps
cp zkeyFiles/rln/final.zkey <path_to_rln_final.zkey>
```
### 2. Generate Witness Calculation Graph
@@ -195,7 +223,7 @@ As mentioned in step 1, we should use `rln.circom` file from `circom-rln` reposi
git clone https://github.com/iden3/circom-witnesscalc
# Load the submodules
git submodule update --init --recursive
cd circom-witnesscalc && git submodule update --init --recursive
# Build the circom-witnesscalc tool
cargo build
@@ -208,7 +236,18 @@ The `rln` module comes with [pre-compiled](https://github.com/vacp2p/zerokit/tre
### 3. Generate Arkzkey Representation for zkey and verification key files
For faster loading, compile the zkey file into the arkzkey format using [ark-zkey](https://github.com/zkmopro/ark-zkey).
For faster loading, compile the zkey file into the arkzkey format using [ark-zkey](https://github.com/seemenkina/ark-zkey). This is fork of the [original](https://github.com/zkmopro/ark-zkey) repository with the uncompressed zkey support.
```sh
# Clone the ark-zkey repository
git clone https://github.com/seemenkina/ark-zkey.git
# Build the ark-zkey tool
cd ark-zkey && cargo build
# Generate the arkzkey representation for the zkey file
cargo run --bin arkzkey-util <path_to_rln_final.zkey>
```
Currently, the `rln` module comes with [pre-compiled](https://github.com/vacp2p/zerokit/tree/master/rln/resources) arkzkey keys for the RLN circuit.

View File

@@ -1,22 +0,0 @@
use criterion::{criterion_group, criterion_main, Criterion};
use rln::circuit::{vk_from_ark_serialized, VK_BYTES};
// Here we benchmark how long the deserialization of the
// verifying_key takes, only testing the json => verifying_key conversion,
// and skipping conversion from bytes => string => serde_json::Value
pub fn vk_deserialize_benchmark(c: &mut Criterion) {
let vk = VK_BYTES;
c.bench_function("vk::vk_from_ark_serialized", |b| {
b.iter(|| {
let _ = vk_from_ark_serialized(vk);
})
});
}
criterion_group! {
name = benches;
config = Criterion::default().measurement_time(std::time::Duration::from_secs(10));
targets = vk_deserialize_benchmark
}
criterion_main!(benches);

View File

@@ -1,11 +1,8 @@
use criterion::{criterion_group, criterion_main, Criterion};
use rln::circuit::{
read_arkzkey_from_bytes_compressed, read_arkzkey_from_bytes_uncompressed, ARKZKEY_BYTES,
ARKZKEY_BYTES_UNCOMPR,
};
use rln::circuit::{read_arkzkey_from_bytes_uncompressed, ARKZKEY_BYTES};
pub fn uncompressed_bench(c: &mut Criterion) {
let arkzkey = ARKZKEY_BYTES_UNCOMPR.to_vec();
let arkzkey = ARKZKEY_BYTES.to_vec();
let size = arkzkey.len() as f32;
println!(
"Size of uncompressed arkzkey: {:.2?} MB",
@@ -19,25 +16,10 @@ pub fn uncompressed_bench(c: &mut Criterion) {
})
});
}
pub fn compressed_bench(c: &mut Criterion) {
let arkzkey = ARKZKEY_BYTES.to_vec();
let size = arkzkey.len() as f32;
println!(
"Size of compressed arkzkey: {:.2?} MB",
size / 1024.0 / 1024.0
);
c.bench_function("arkzkey::arkzkey_from_raw_compressed", |b| {
b.iter(|| {
let r = read_arkzkey_from_bytes_compressed(&arkzkey);
assert_eq!(r.is_ok(), true);
})
});
}
criterion_group! {
name = benches;
config = Criterion::default().sample_size(10);
targets = uncompressed_bench, compressed_bench
targets = uncompressed_bench
}
criterion_main!(benches);

View File

@@ -8,40 +8,36 @@ use ark_bn254::{
};
use ark_groth16::{ProvingKey, VerifyingKey};
use ark_relations::r1cs::ConstraintMatrices;
use ark_serialize::CanonicalDeserialize;
use cfg_if::cfg_if;
use color_eyre::{Report, Result};
use num_bigint::BigInt;
#[cfg(feature = "arkzkey")]
use {ark_ff::Field, ark_serialize::CanonicalSerialize, color_eyre::eyre::WrapErr};
use {
ark_ff::Field, ark_serialize::CanonicalDeserialize, ark_serialize::CanonicalSerialize,
color_eyre::eyre::WrapErr,
};
#[cfg(not(feature = "arkzkey"))]
use {ark_circom::read_zkey, std::io::Cursor};
#[cfg(feature = "arkzkey")]
pub const ARKZKEY_BYTES: &[u8] = include_bytes!("../resources/tree_height_20/rln_final.arkzkey");
#[cfg(feature = "arkzkey")]
pub const ARKZKEY_BYTES_UNCOMPR: &[u8] =
include_bytes!("../resources/tree_height_20/rln_final_uncompr.arkzkey");
pub const ZKEY_BYTES: &[u8] = include_bytes!("../resources/tree_height_20/rln_final.zkey");
pub const VK_BYTES: &[u8] = include_bytes!("../resources/tree_height_20/verification_key.arkvkey");
const GRAPH_BYTES: &[u8] = include_bytes!("../resources/tree_height_20/graph.bin");
lazy_static! {
static ref ZKEY: (ProvingKey<Curve>, ConstraintMatrices<Fr>) = {
cfg_if! {
if #[cfg(feature = "arkzkey")] {
read_arkzkey_from_bytes_uncompressed(ARKZKEY_BYTES_UNCOMPR).expect("Failed to read arkzkey")
read_arkzkey_from_bytes_uncompressed(ARKZKEY_BYTES).expect("Failed to read arkzkey")
} else {
let mut reader = Cursor::new(ZKEY_BYTES);
read_zkey(&mut reader).expect("Failed to read zkey")
}
}
};
static ref VK: VerifyingKey<Curve> =
vk_from_ark_serialized(VK_BYTES).expect("Failed to read vk");
}
pub const TEST_TREE_HEIGHT: usize = 20;
@@ -82,11 +78,7 @@ pub fn zkey_from_folder() -> &'static (ProvingKey<Curve>, ConstraintMatrices<Fr>
}
// Loads the verification key from a bytes vector
pub fn vk_from_raw(vk_data: &[u8], zkey_data: &[u8]) -> Result<VerifyingKey<Curve>> {
if !vk_data.is_empty() {
return vk_from_ark_serialized(vk_data);
}
pub fn vk_from_raw(zkey_data: &[u8]) -> Result<VerifyingKey<Curve>> {
if !zkey_data.is_empty() {
let (proving_key, _matrices) = zkey_from_raw(zkey_data)?;
return Ok(proving_key.vk);
@@ -95,18 +87,6 @@ pub fn vk_from_raw(vk_data: &[u8], zkey_data: &[u8]) -> Result<VerifyingKey<Curv
Err(Report::msg("No proving/verification key found!"))
}
// Loads the verification key
pub fn vk_from_folder() -> &'static VerifyingKey<Curve> {
&VK
}
// Computes the verification key from a bytes vector containing pre-processed ark-serialized verification key
// uncompressed, unchecked
pub fn vk_from_ark_serialized(data: &[u8]) -> Result<VerifyingKey<Curve>> {
let vk = VerifyingKey::<Curve>::deserialize_uncompressed_unchecked(data)?;
Ok(vk)
}
// Checks verification key to be correct with respect to proving key
pub fn check_vk_from_zkey(verifying_key: VerifyingKey<Curve>) -> Result<()> {
let (proving_key, _matrices) = zkey_from_folder();
@@ -191,38 +171,3 @@ pub fn read_arkzkey_from_bytes_uncompressed(
Ok((proving_key, constraint_matrices))
}
#[cfg(feature = "arkzkey")]
pub fn read_arkzkey_from_bytes_compressed(
arkzkey_data: &[u8],
) -> Result<(ProvingKey<Curve>, ConstraintMatrices<Fr>)> {
if arkzkey_data.is_empty() {
return Err(Report::msg("No proving key found!"));
}
let mut cursor = std::io::Cursor::new(arkzkey_data);
let serialized_proving_key =
SerializableProvingKey::deserialize_compressed_unchecked(&mut cursor)
.wrap_err("Failed to deserialize proving key")?;
let serialized_constraint_matrices =
SerializableConstraintMatrices::deserialize_compressed_unchecked(&mut cursor)
.wrap_err("Failed to deserialize constraint matrices")?;
// Get on right form for API
let proving_key: ProvingKey<Bn254> = serialized_proving_key.0;
let constraint_matrices: ConstraintMatrices<ark_bn254::Fr> = ConstraintMatrices {
num_instance_variables: serialized_constraint_matrices.num_instance_variables,
num_witness_variables: serialized_constraint_matrices.num_witness_variables,
num_constraints: serialized_constraint_matrices.num_constraints,
a_num_non_zero: serialized_constraint_matrices.a_num_non_zero,
b_num_non_zero: serialized_constraint_matrices.b_num_non_zero,
c_num_non_zero: serialized_constraint_matrices.c_num_non_zero,
a: serialized_constraint_matrices.a.data,
b: serialized_constraint_matrices.b.data,
c: serialized_constraint_matrices.c.data,
};
Ok((proving_key, constraint_matrices))
}

View File

@@ -8,6 +8,7 @@ use crate::public::{hash as public_hash, poseidon_hash as public_poseidon_hash,
// First argument to the macro is context,
// second is the actual method on `RLN`
// rest are all other arguments to the method
#[cfg(not(feature = "stateless"))]
macro_rules! call {
($instance:expr, $method:ident $(, $arg:expr)*) => {
{
@@ -229,7 +230,6 @@ pub extern "C" fn new(ctx: *mut *mut RLN) -> bool {
pub extern "C" fn new_with_params(
tree_height: usize,
zkey_buffer: *const Buffer,
vk_buffer: *const Buffer,
graph_data: *const Buffer,
tree_config: *const Buffer,
ctx: *mut *mut RLN,
@@ -237,7 +237,6 @@ pub extern "C" fn new_with_params(
match RLN::new_with_params(
tree_height,
zkey_buffer.process().to_vec(),
vk_buffer.process().to_vec(),
graph_data.process().to_vec(),
tree_config.process(),
) {
@@ -257,13 +256,11 @@ pub extern "C" fn new_with_params(
#[no_mangle]
pub extern "C" fn new_with_params(
zkey_buffer: *const Buffer,
vk_buffer: *const Buffer,
graph_buffer: *const Buffer,
ctx: *mut *mut RLN,
) -> bool {
match RLN::new_with_params(
zkey_buffer.process().to_vec(),
vk_buffer.process().to_vec(),
graph_buffer.process().to_vec(),
) {
Ok(rln) => {

View File

@@ -1,11 +1,15 @@
/// This is the main public API for RLN module. It is used by the FFI, and should be
/// used by tests etc. as well
use crate::circuit::{
graph_from_folder, vk_from_folder, vk_from_raw, zkey_from_folder, zkey_from_raw, Curve, Fr,
TEST_TREE_HEIGHT,
#[cfg(not(feature = "stateless"))]
use {
crate::{circuit::TEST_TREE_HEIGHT, poseidon_tree::PoseidonTree},
serde_json::{json, Value},
std::str::FromStr,
utils::{Hasher, ZerokitMerkleProof, ZerokitMerkleTree},
};
use crate::circuit::{graph_from_folder, vk_from_raw, zkey_from_folder, zkey_from_raw, Curve, Fr};
use crate::hashers::{hash_to_field, poseidon_hash as utils_poseidon_hash};
use crate::poseidon_tree::PoseidonTree;
use crate::protocol::*;
use crate::utils::*;
@@ -13,11 +17,7 @@ use ark_groth16::{Proof as ArkProof, ProvingKey, VerifyingKey};
use ark_relations::r1cs::ConstraintMatrices;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, Write};
use color_eyre::{Report, Result};
use serde_json::{json, Value};
use std::{default::Default, io::Cursor, str::FromStr};
#[cfg(not(feature = "stateless"))]
use utils::{Hasher, ZerokitMerkleProof, ZerokitMerkleTree};
use std::{default::Default, io::Cursor};
/// The application-specific RLN identifier.
///
@@ -64,7 +64,7 @@ impl RLN {
let tree_config = rln_config["tree_config"].to_string();
let proving_key = zkey_from_folder();
let verification_key = vk_from_folder();
let verification_key = &proving_key.0.vk;
let graph_data = graph_from_folder();
let tree_config: <PoseidonTree as ZerokitMerkleTree>::Config = if tree_config.is_empty() {
@@ -101,7 +101,7 @@ impl RLN {
#[cfg(feature = "stateless")]
pub fn new() -> Result<RLN> {
let proving_key = zkey_from_folder();
let verification_key = vk_from_folder();
let verification_key = &proving_key.0.vk;
let graph_data = graph_from_folder();
Ok(RLN {
@@ -116,7 +116,6 @@ impl RLN {
/// Input parameters are
/// - `tree_height`: the height of the internal Merkle tree
/// - `zkey_vec`: a byte vector containing to the proving key (`rln_final.zkey`) or (`rln_final.arkzkey`) as binary file
/// - `vk_vec`: a byte vector containing to the verification key (`verification_key.arkvkey`) as binary file
/// - `tree_config_input`: a reader for a string containing a json with the merkle tree configuration
///
/// Example:
@@ -128,7 +127,7 @@ impl RLN {
/// let resources_folder = "./resources/tree_height_20/";
///
/// let mut resources: Vec<Vec<u8>> = Vec::new();
/// for filename in ["rln_final.zkey", "verification_key.arkvkey", "graph.bin"] {
/// for filename in ["rln_final.zkey", "graph.bin"] {
/// let fullpath = format!("{resources_folder}{filename}");
/// let mut file = File::open(&fullpath).expect("no file found");
/// let metadata = std::fs::metadata(&fullpath).expect("unable to read metadata");
@@ -152,12 +151,11 @@ impl RLN {
pub fn new_with_params<R: Read>(
tree_height: usize,
zkey_vec: Vec<u8>,
vk_vec: Vec<u8>,
graph_data: Vec<u8>,
mut tree_config_input: R,
) -> Result<RLN> {
let proving_key = zkey_from_raw(&zkey_vec)?;
let verification_key = vk_from_raw(&vk_vec, &zkey_vec)?;
let verification_key = vk_from_raw(&zkey_vec)?;
let mut tree_config_vec: Vec<u8> = Vec::new();
tree_config_input.read_to_end(&mut tree_config_vec)?;
@@ -189,7 +187,6 @@ impl RLN {
///
/// Input parameters are
/// - `zkey_vec`: a byte vector containing to the proving key (`rln_final.zkey`) or (`rln_final.arkzkey`) as binary file
/// - `vk_vec`: a byte vector containing to the verification key (`verification_key.arkvkey`) as binary file
///
/// Example:
/// ```
@@ -199,7 +196,7 @@ impl RLN {
/// let resources_folder = "./resources/tree_height_20/";
///
/// let mut resources: Vec<Vec<u8>> = Vec::new();
/// for filename in ["rln_final.zkey", "verification_key.arkvkey", "graph.bin"] {
/// for filename in ["rln_final.zkey", "graph.bin"] {
/// let fullpath = format!("{resources_folder}{filename}");
/// let mut file = File::open(&fullpath).expect("no file found");
/// let metadata = std::fs::metadata(&fullpath).expect("unable to read metadata");
@@ -215,9 +212,9 @@ impl RLN {
/// );
/// ```
#[cfg(feature = "stateless")]
pub fn new_with_params(zkey_vec: Vec<u8>, vk_vec: Vec<u8>, graph_data: Vec<u8>) -> Result<RLN> {
pub fn new_with_params(zkey_vec: Vec<u8>, graph_data: Vec<u8>) -> Result<RLN> {
let proving_key = zkey_from_raw(&zkey_vec)?;
let verification_key = vk_from_raw(&vk_vec, &zkey_vec)?;
let verification_key = vk_from_raw(&zkey_vec)?;
Ok(RLN {
proving_key,

View File

@@ -409,7 +409,7 @@ mod test {
let root_rln_folder = get_tree_root(rln_pointer);
#[cfg(feature = "arkzkey")]
let zkey_path = "./resources/tree_height_20/rln_final_uncompr.arkzkey";
let zkey_path = "./resources/tree_height_20/rln_final.arkzkey";
#[cfg(not(feature = "arkzkey"))]
let zkey_path = "./resources/tree_height_20/rln_final.zkey";
let mut zkey_file = File::open(&zkey_path).expect("no file found");
@@ -419,14 +419,7 @@ mod test {
.read_exact(&mut zkey_buffer)
.expect("buffer overflow");
let vk_path = "./resources/tree_height_20/verification_key.arkvkey";
let mut vk_file = File::open(&vk_path).expect("no file found");
let metadata = std::fs::metadata(&vk_path).expect("unable to read metadata");
let mut vk_buffer = vec![0; metadata.len() as usize];
vk_file.read_exact(&mut vk_buffer).expect("buffer overflow");
let zkey_data = &Buffer::from(&zkey_buffer[..]);
let vk_data = &Buffer::from(&vk_buffer[..]);
let graph_data = "./resources/tree_height_20/graph.bin";
let mut graph_file = File::open(&graph_data).expect("no file found");
@@ -445,7 +438,6 @@ mod test {
let success = new_with_params(
TEST_TREE_HEIGHT,
zkey_data,
vk_data,
graph_data,
tree_config_buffer,
rln_pointer_raw_bytes.as_mut_ptr(),

View File

@@ -2,7 +2,7 @@
mod test {
use ark_ff::BigInt;
use rln::circuit::{graph_from_folder, zkey_from_folder};
use rln::circuit::{vk_from_folder, Fr, TEST_TREE_HEIGHT};
use rln::circuit::{Fr, TEST_TREE_HEIGHT};
use rln::hashers::{hash_to_field, poseidon_hash};
use rln::poseidon_tree::PoseidonTree;
use rln::protocol::*;
@@ -128,7 +128,7 @@ mod test {
fn test_witness_from_json() {
// We generate all relevant keys
let proving_key = zkey_from_folder();
let verification_key = vk_from_folder();
let verification_key = &proving_key.0.vk;
let graph_data = graph_from_folder();
// We compute witness from the json input
let rln_witness = get_test_witness();
@@ -156,7 +156,7 @@ mod test {
// We generate all relevant keys
let proving_key = zkey_from_folder();
let verification_key = vk_from_folder();
let verification_key = &proving_key.0.vk;
let graph_data = graph_from_folder();
// Let's generate a zkSNARK proof

View File

@@ -1,11 +1,16 @@
#[cfg(test)]
mod test {
use ark_ff::BigInt;
#[cfg(not(feature = "stateless"))]
use {
ark_ff::BigInt,
rln::{circuit::TEST_TREE_HEIGHT, protocol::compute_tree_root},
};
use ark_std::{rand::thread_rng, UniformRand};
use rand::Rng;
use rln::circuit::{Fr, TEST_TREE_HEIGHT};
use rln::circuit::Fr;
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::protocol::deserialize_identity_tuple;
use rln::public::{hash as public_hash, poseidon_hash as public_poseidon_hash, RLN};
use rln::utils::*;
use std::io::Cursor;