mirror of
https://github.com/vacp2p/zerokit.git
synced 2026-01-09 13:47:58 -05:00
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:
@@ -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
|
||||
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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()),
|
||||
)?)
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user