mirror of https://github.com/vacp2p/zerokit.git
chore(rln): add ark-zkey support (#242)
* Add Submodule * Add arkzkey * make arkzkey support as feature * update submodule url * add abstract around feature * new bench file * update ci
This commit is contained in:
parent
5937a67ee6
commit
8581ac0b78
|
@ -123,6 +123,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: boa-dev/criterion-compare-action@v3
|
||||
with:
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "mopro"]
|
||||
path = mopro
|
||||
url = https://github.com/zkmopro/mopro.git
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
Subproject commit 3c8d73433632ff497dff238e87e37b152251eece
|
|
@ -37,7 +37,11 @@ fn main() -> Result<()> {
|
|||
tree_config_input,
|
||||
}) => {
|
||||
let mut resources: Vec<Vec<u8>> = Vec::new();
|
||||
for filename in ["rln.wasm", "rln_final.zkey", "verification_key.json"] {
|
||||
#[cfg(feature = "arkzkey")]
|
||||
let filenames = ["rln.wasm", "rln_final.arkzkey", "verification_key.json"];
|
||||
#[cfg(not(feature = "arkzkey"))]
|
||||
let filenames = ["rln.wasm", "rln_final.zkey", "verification_key.json"];
|
||||
for filename in filenames {
|
||||
let fullpath = config.join(Path::new(filename));
|
||||
let mut file = File::open(&fullpath)?;
|
||||
let metadata = std::fs::metadata(&fullpath)?;
|
||||
|
|
|
@ -32,6 +32,7 @@ ark-serialize = { version = "=0.4.1", default-features = false }
|
|||
ark-circom = { version = "=0.1.0", default-features = false, features = [
|
||||
"circom-2",
|
||||
] }
|
||||
ark-zkey = { path = "../mopro/ark-zkey", optional = true, default-features = false }
|
||||
|
||||
# WASM
|
||||
wasmer = { version = "=2.3.0", default-features = false }
|
||||
|
@ -74,6 +75,7 @@ parallel = [
|
|||
]
|
||||
wasm = ["wasmer/js", "wasmer/std"]
|
||||
fullmerkletree = ["default"]
|
||||
arkzkey = ["ark-zkey"]
|
||||
|
||||
# Note: pmtree feature is still experimental
|
||||
pmtree-ft = ["utils/pmtree-ft"]
|
||||
|
@ -81,3 +83,7 @@ pmtree-ft = ["utils/pmtree-ft"]
|
|||
[[bench]]
|
||||
name = "pmtree_benchmark"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "circuit_loading_benchmark"
|
||||
harness = false
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
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);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, key_load_benchmark);
|
||||
criterion_main!(benches);
|
|
@ -1,7 +1,6 @@
|
|||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use utils::ZerokitMerkleTree;
|
||||
|
||||
use rln::{circuit::Fr, pm_tree_adapter::PmTree};
|
||||
use utils::ZerokitMerkleTree;
|
||||
|
||||
pub fn pmtree_benchmark(c: &mut Criterion) {
|
||||
let mut tree = PmTree::default(2).unwrap();
|
||||
|
|
Binary file not shown.
|
@ -4,14 +4,12 @@ use ark_bn254::{
|
|||
Bn254, Fq as ArkFq, Fq2 as ArkFq2, Fr as ArkFr, G1Affine as ArkG1Affine,
|
||||
G1Projective as ArkG1Projective, G2Affine as ArkG2Affine, G2Projective as ArkG2Projective,
|
||||
};
|
||||
use ark_circom::read_zkey;
|
||||
use ark_groth16::{ProvingKey, VerifyingKey};
|
||||
use ark_relations::r1cs::ConstraintMatrices;
|
||||
use cfg_if::cfg_if;
|
||||
use color_eyre::{Report, Result};
|
||||
use num_bigint::BigUint;
|
||||
use serde_json::Value;
|
||||
use std::io::Cursor;
|
||||
use std::str::FromStr;
|
||||
|
||||
cfg_if! {
|
||||
|
@ -25,6 +23,17 @@ cfg_if! {
|
|||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "arkzkey")] {
|
||||
use ark_zkey::read_arkzkey_from_bytes;
|
||||
const ARKZKEY_FILENAME: &str = "rln_final.arkzkey";
|
||||
|
||||
} else {
|
||||
use std::io::Cursor;
|
||||
use ark_circom::read_zkey;
|
||||
}
|
||||
}
|
||||
|
||||
const ZKEY_FILENAME: &str = "rln_final.zkey";
|
||||
const VK_FILENAME: &str = "verification_key.json";
|
||||
const WASM_FILENAME: &str = "rln.wasm";
|
||||
|
@ -49,8 +58,15 @@ pub type G2Projective = ArkG2Projective;
|
|||
// Loads the proving key using a bytes vector
|
||||
pub fn zkey_from_raw(zkey_data: &Vec<u8>) -> Result<(ProvingKey<Curve>, ConstraintMatrices<Fr>)> {
|
||||
if !zkey_data.is_empty() {
|
||||
let mut c = Cursor::new(zkey_data);
|
||||
let proving_key_and_matrices = read_zkey(&mut c)?;
|
||||
let proving_key_and_matrices = match () {
|
||||
#[cfg(feature = "arkzkey")]
|
||||
() => read_arkzkey_from_bytes(zkey_data.as_slice())?,
|
||||
#[cfg(not(feature = "arkzkey"))]
|
||||
() => {
|
||||
let mut c = Cursor::new(zkey_data);
|
||||
read_zkey(&mut c)?
|
||||
}
|
||||
};
|
||||
Ok(proving_key_and_matrices)
|
||||
} else {
|
||||
Err(Report::msg("No proving key found!"))
|
||||
|
@ -62,10 +78,21 @@ pub fn zkey_from_raw(zkey_data: &Vec<u8>) -> Result<(ProvingKey<Curve>, Constrai
|
|||
pub fn zkey_from_folder(
|
||||
resources_folder: &str,
|
||||
) -> Result<(ProvingKey<Curve>, ConstraintMatrices<Fr>)> {
|
||||
#[cfg(feature = "arkzkey")]
|
||||
let zkey = RESOURCES_DIR.get_file(Path::new(resources_folder).join(ARKZKEY_FILENAME));
|
||||
#[cfg(not(feature = "arkzkey"))]
|
||||
let zkey = RESOURCES_DIR.get_file(Path::new(resources_folder).join(ZKEY_FILENAME));
|
||||
|
||||
if let Some(zkey) = zkey {
|
||||
let mut c = Cursor::new(zkey.contents());
|
||||
let proving_key_and_matrices = read_zkey(&mut c)?;
|
||||
let proving_key_and_matrices = match () {
|
||||
#[cfg(feature = "arkzkey")]
|
||||
() => read_arkzkey_from_bytes(zkey.contents())?,
|
||||
#[cfg(not(feature = "arkzkey"))]
|
||||
() => {
|
||||
let mut c = Cursor::new(zkey.contents());
|
||||
read_zkey(&mut c)?
|
||||
}
|
||||
};
|
||||
Ok(proving_key_and_matrices)
|
||||
} else {
|
||||
Err(Report::msg("No proving key found!"))
|
||||
|
|
|
@ -58,7 +58,7 @@ impl RLN<'_> {
|
|||
///
|
||||
/// Input parameters are
|
||||
/// - `tree_height`: the height of the internal Merkle tree
|
||||
/// - `input_data`: a reader for the string path of the resource folder containing the ZK circuit (`rln.wasm`), the proving key (`rln_final.zkey`) and the verification key (`verification_key.json`).
|
||||
/// - `input_data`: 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`).
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
|
@ -83,8 +83,8 @@ impl RLN<'_> {
|
|||
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 verification_key = vk_from_folder(resources_folder)?;
|
||||
|
||||
let tree_config: <PoseidonTree as ZerokitMerkleTree>::Config = if tree_config.is_empty() {
|
||||
|
@ -115,7 +115,7 @@ impl RLN<'_> {
|
|||
/// Input parameters are
|
||||
/// - `tree_height`: the height of the internal Merkle tree
|
||||
/// - `circom_vec`: a byte vector containing the ZK circuit (`rln.wasm`) as binary file
|
||||
/// - `zkey_vec`: a byte vector containing to the proving key (`rln_final.zkey`) as binary file
|
||||
/// - `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.json`) as binary file
|
||||
/// - `tree_config`: a reader for a string containing a json with the merkle tree configuration
|
||||
///
|
||||
|
@ -684,7 +684,7 @@ impl RLN<'_> {
|
|||
/// Output values are:
|
||||
/// - `output_data`: a writer receiving the serialization of the zkSNARK proof and the circuit evaluations outputs, i.e. `[ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> ]`
|
||||
///
|
||||
/// Example
|
||||
/// Example
|
||||
/// ```
|
||||
/// use rln::protocol::*:
|
||||
/// use rln::utils::*;
|
||||
|
@ -829,7 +829,7 @@ impl RLN<'_> {
|
|||
/// Note that contrary to [`verify_rln_proof`](crate::public::RLN::verify_rln_proof), this function does not check if the internal Merkle tree root corresponds to the root provided as input, but rather checks if the root provided as input in `input_data` corresponds to one of the roots serialized in `roots_data`.
|
||||
///
|
||||
/// If `roots_data` contains no root (is empty), root validation is skipped and the proof will be correctly verified only if the other proof values results valid (i.e., zk-proof, signal, x-coordinate, RLN identifier)
|
||||
///
|
||||
///
|
||||
/// Example
|
||||
/// ```
|
||||
/// // proof_data is computed as in the example code snippet provided for rln::public::RLN::generate_rln_proof
|
||||
|
|
|
@ -618,7 +618,9 @@ mod test {
|
|||
circom_file
|
||||
.read_exact(&mut circom_buffer)
|
||||
.expect("buffer overflow");
|
||||
|
||||
#[cfg(feature = "arkzkey")]
|
||||
let zkey_path = format!("./resources/tree_height_{TEST_TREE_HEIGHT}/rln_final.arkzkey");
|
||||
#[cfg(not(feature = "arkzkey"))]
|
||||
let zkey_path = format!("./resources/tree_height_{TEST_TREE_HEIGHT}/rln_final.zkey");
|
||||
let mut zkey_file = File::open(&zkey_path).expect("no file found");
|
||||
let metadata = std::fs::metadata(&zkey_path).expect("unable to read metadata");
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use ark_ff::BigInt;
|
||||
use rln::circuit::zkey_from_folder;
|
||||
use rln::circuit::{
|
||||
circom_from_folder, vk_from_folder, zkey_from_folder, Fr, TEST_RESOURCES_FOLDER,
|
||||
TEST_TREE_HEIGHT,
|
||||
circom_from_folder, vk_from_folder, Fr, TEST_RESOURCES_FOLDER, TEST_TREE_HEIGHT,
|
||||
};
|
||||
use rln::hashers::{hash_to_field, poseidon_hash};
|
||||
use rln::poseidon_tree::PoseidonTree;
|
||||
|
|
Loading…
Reference in New Issue