mirror of
https://github.com/vacp2p/zerokit.git
synced 2026-01-09 21:58:06 -05:00
chore(rln): update dependencies and refactor code for compatibility (#291)
While publishing the release on crate io it turned out that we can't use libraries without a version as it was for arc-circom. During the upgrade to the new version it was also discovered that it is possible to speed up input preparation for witness calculator by 4 times by switching from bigint to Fr:  it was also checked that it is also possible to use iden3 as a sub-module instead of copying code, but benchmarks showed that the new iden3 version with u256 calculations and subsequent conversion of the result to Fr is slower than the current implementation:  ---- - Updated dependencies to their latest versions, including ark-ff, ark-bn254, ark-std, and others to 0.5.0. - Refactored circuit and iden3calc modules to use Fr instead of BigInt for better type consistency. - Improved utility functions for type conversions between Fr and U256. - Adjusted Cargo.toml files for rln and utils to reflect new dependency versions and features. - Enhanced documentation and comments for clarity on changes made. This update ensures compatibility with the latest versions of the Ark framework and improves overall code quality.
This commit is contained in:
committed by
GitHub
parent
ffd5851d7d
commit
ba467d370c
930
Cargo.lock
generated
930
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -15,23 +15,21 @@ bench = false
|
||||
# This flag disable cargo doctests, i.e. testing example code-snippets in documentation
|
||||
doctest = false
|
||||
|
||||
|
||||
[dependencies]
|
||||
# ZKP Generation
|
||||
ark-ec = { version = "=0.4.2", default-features = false }
|
||||
ark-ff = { version = "=0.4.2", default-features = false, features = ["asm"] }
|
||||
ark-std = { version = "=0.4.0", default-features = false }
|
||||
ark-bn254 = { version = "=0.4.0" }
|
||||
ark-groth16 = { version = "=0.4.0", features = [
|
||||
ark-bn254 = { version = "0.5.0", features = ["std"] }
|
||||
ark-ff = { version = "0.5.0", features = ["std", "asm"] }
|
||||
ark-serialize = { version = "0.5.0", features = ["derive"] }
|
||||
ark-ec = { version = "0.5.0", default-features = false }
|
||||
ark-std = { version = "0.5.0", default-features = false }
|
||||
ark-groth16 = { version = "0.5.0", features = [
|
||||
"parallel",
|
||||
], default-features = false }
|
||||
ark-relations = { version = "=0.4.0", default-features = false, features = [
|
||||
ark-relations = { version = "0.5.0", default-features = false, features = [
|
||||
"std",
|
||||
] }
|
||||
ark-serialize = { version = "=0.4.2", default-features = false }
|
||||
# v0.5.0 use all other ark 0.5.0 versions and they are not compatible with current code.
|
||||
# master branch contains commit with compatible version
|
||||
ark-circom = { git = "https://github.com/gakonst/ark-circom.git", rev = "7f80002" }
|
||||
ark-circom = { version = "0.5.0" }
|
||||
ark-r1cs-std = { version = "0.5.0" }
|
||||
|
||||
# error handling
|
||||
color-eyre = "0.6.2"
|
||||
@@ -40,7 +38,7 @@ thiserror = "2.0.11"
|
||||
# utilities
|
||||
byteorder = "1.4.3"
|
||||
cfg-if = "1.0"
|
||||
num-bigint = { version = "0.4.3", default-features = false, features = [
|
||||
num-bigint = { version = "0.4.6", default-features = false, features = [
|
||||
"rand",
|
||||
] }
|
||||
num-traits = "0.2.19"
|
||||
@@ -48,26 +46,20 @@ once_cell = "1.19.0"
|
||||
lazy_static = "1.4.0"
|
||||
rand = "0.8.5"
|
||||
rand_chacha = "0.3.1"
|
||||
ruint = { version = "1.10.0", features = [
|
||||
"rand",
|
||||
"serde",
|
||||
"ark-ff-04",
|
||||
"num-bigint",
|
||||
] }
|
||||
ruint = { version = "1.12.4", features = ["rand", "serde", "ark-ff-04"] }
|
||||
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
|
||||
utils = { package = "zerokit_utils", path = "../utils/", default-features = false }
|
||||
|
||||
utils = { package = "zerokit_utils", version = "0.5.2", path = "../utils/", default-features = false }
|
||||
|
||||
# serialization
|
||||
prost = "0.13.1"
|
||||
serde_json = "1.0.138"
|
||||
serde = { version = "1.0.217", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
document-features = { version = "=0.2.10", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
sled = "=0.34.7"
|
||||
criterion = { version = "=0.4.0", features = ["html_reports"] }
|
||||
sled = "0.34.7"
|
||||
criterion = { version = "0.4.0", features = ["html_reports"] }
|
||||
|
||||
[features]
|
||||
default = ["parallel", "pmtree-ft"]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// This crate provides interfaces for the zero-knowledge circuit and keys
|
||||
|
||||
use crate::iden3calc::calc_witness;
|
||||
use ::lazy_static::lazy_static;
|
||||
use ark_bn254::{
|
||||
Bn254, Fq as ArkFq, Fq2 as ArkFq2, Fr as ArkFr, G1Affine as ArkG1Affine,
|
||||
@@ -10,7 +9,8 @@ use ark_groth16::{ProvingKey, VerifyingKey};
|
||||
use ark_relations::r1cs::ConstraintMatrices;
|
||||
use cfg_if::cfg_if;
|
||||
use color_eyre::{Report, Result};
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::iden3calc::calc_witness;
|
||||
|
||||
#[cfg(feature = "arkzkey")]
|
||||
use {
|
||||
@@ -97,7 +97,7 @@ pub fn check_vk_from_zkey(verifying_key: VerifyingKey<Curve>) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calculate_rln_witness<I: IntoIterator<Item = (String, Vec<BigInt>)>>(
|
||||
pub fn calculate_rln_witness<I: IntoIterator<Item = (String, Vec<Fr>)>>(
|
||||
inputs: I,
|
||||
graph_data: &[u8],
|
||||
) -> Vec<Fr> {
|
||||
|
||||
@@ -5,22 +5,22 @@ pub mod graph;
|
||||
pub mod proto;
|
||||
pub mod storage;
|
||||
|
||||
use ark_bn254::Fr;
|
||||
use graph::Node;
|
||||
use num_bigint::BigInt;
|
||||
use ruint::aliases::U256;
|
||||
use std::collections::HashMap;
|
||||
use storage::deserialize_witnesscalc_graph;
|
||||
|
||||
use crate::circuit::Fr;
|
||||
use graph::{fr_to_u256, Node};
|
||||
|
||||
pub type InputSignalsInfo = HashMap<String, (usize, usize)>;
|
||||
|
||||
pub fn calc_witness<I: IntoIterator<Item = (String, Vec<BigInt>)>>(
|
||||
pub fn calc_witness<I: IntoIterator<Item = (String, Vec<Fr>)>>(
|
||||
inputs: I,
|
||||
graph_data: &[u8],
|
||||
) -> Vec<Fr> {
|
||||
let inputs: HashMap<String, Vec<U256>> = inputs
|
||||
.into_iter()
|
||||
.map(|(key, value)| (key, value.iter().map(|v| U256::from(v)).collect()))
|
||||
.map(|(key, value)| (key, value.iter().map(fr_to_u256).collect()))
|
||||
.collect();
|
||||
|
||||
let (nodes, signals, input_mapping): (Vec<Node>, Vec<usize>, InputSignalsInfo) =
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
// This file is based on the code by iden3. Its preimage can be found here:
|
||||
// https://github.com/iden3/circom-witnesscalc/blob/5cb365b6e4d9052ecc69d4567fcf5bc061c20e94/src/graph.rs
|
||||
|
||||
use crate::iden3calc::proto;
|
||||
use ark_bn254::Fr;
|
||||
use ark_ff::{BigInt, BigInteger, One, PrimeField, Zero};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate};
|
||||
use rand::Rng;
|
||||
use ruint::aliases::U256;
|
||||
use ruint::{aliases::U256, uint};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
use std::error::Error;
|
||||
use std::ops::{BitOr, BitXor, Deref};
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::HashMap,
|
||||
ops::{BitAnd, Shl, Shr},
|
||||
error::Error,
|
||||
ops::{BitAnd, BitOr, BitXor, Deref, Shl, Shr},
|
||||
};
|
||||
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate};
|
||||
use ruint::uint;
|
||||
use crate::circuit::Fr;
|
||||
use crate::iden3calc::proto;
|
||||
|
||||
pub const M: U256 =
|
||||
uint!(21888242871839275222246405745257275088548364400416034343698204186575808495617_U256);
|
||||
@@ -40,6 +38,16 @@ where
|
||||
a.map_err(serde::de::Error::custom)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fr_to_u256(x: &Fr) -> U256 {
|
||||
U256::from_limbs(x.into_bigint().0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn u256_to_fr(x: &U256) -> Fr {
|
||||
Fr::from_bigint(BigInt::new(x.into_limbs())).expect("Failed to convert U256 to Fr")
|
||||
}
|
||||
|
||||
#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum Operation {
|
||||
Mul,
|
||||
@@ -125,14 +133,18 @@ impl Operation {
|
||||
if b.is_zero() {
|
||||
Fr::zero()
|
||||
} else {
|
||||
Fr::new((Into::<U256>::into(a) / Into::<U256>::into(b)).into())
|
||||
let a_u256 = fr_to_u256(&a);
|
||||
let b_u256 = fr_to_u256(&b);
|
||||
u256_to_fr(&(a_u256 / b_u256))
|
||||
}
|
||||
}
|
||||
Mod => {
|
||||
if b.is_zero() {
|
||||
Fr::zero()
|
||||
} else {
|
||||
Fr::new((Into::<U256>::into(a) % Into::<U256>::into(b)).into())
|
||||
let a_u256 = fr_to_u256(&a);
|
||||
let b_u256 = fr_to_u256(&b);
|
||||
u256_to_fr(&(a_u256 % b_u256))
|
||||
}
|
||||
}
|
||||
Eq => match a.cmp(&b) {
|
||||
@@ -143,10 +155,10 @@ impl Operation {
|
||||
Ordering::Equal => Fr::zero(),
|
||||
_ => Fr::one(),
|
||||
},
|
||||
Lt => Fr::new(u_lt(&a.into(), &b.into()).into()),
|
||||
Gt => Fr::new(u_gt(&a.into(), &b.into()).into()),
|
||||
Leq => Fr::new(u_lte(&a.into(), &b.into()).into()),
|
||||
Geq => Fr::new(u_gte(&a.into(), &b.into()).into()),
|
||||
Lt => u256_to_fr(&u_lt(&fr_to_u256(&a), &fr_to_u256(&b))),
|
||||
Gt => u256_to_fr(&u_gt(&fr_to_u256(&a), &fr_to_u256(&b))),
|
||||
Leq => u256_to_fr(&u_lte(&fr_to_u256(&a), &fr_to_u256(&b))),
|
||||
Geq => u256_to_fr(&u_gte(&fr_to_u256(&a), &fr_to_u256(&b))),
|
||||
Land => {
|
||||
if a.is_zero() || b.is_zero() {
|
||||
Fr::zero()
|
||||
@@ -415,9 +427,9 @@ pub fn evaluate(nodes: &[Node], inputs: &[U256], outputs: &[usize]) -> Vec<Fr> {
|
||||
let mut values = Vec::with_capacity(nodes.len());
|
||||
for &node in nodes.iter() {
|
||||
let value = match node {
|
||||
Node::Constant(c) => Fr::new(c.into()),
|
||||
Node::Constant(c) => u256_to_fr(&c),
|
||||
Node::MontConstant(c) => c,
|
||||
Node::Input(i) => Fr::new(inputs[i].into()),
|
||||
Node::Input(i) => u256_to_fr(&inputs[i]),
|
||||
Node::Op(op, a, b) => op.eval_fr(values[a], values[b]),
|
||||
Node::UnoOp(op, a) => op.eval_fr(values[a]),
|
||||
Node::TresOp(op, a, b, c) => op.eval_fr(values[a], values[b], values[c]),
|
||||
@@ -633,7 +645,7 @@ pub fn montgomery_form(nodes: &mut [Node]) {
|
||||
use Node::*;
|
||||
use Operation::*;
|
||||
match node {
|
||||
Constant(c) => *node = MontConstant(Fr::new((*c).into())),
|
||||
Constant(c) => *node = MontConstant(u256_to_fr(c)),
|
||||
MontConstant(..) => (),
|
||||
Input(..) => (),
|
||||
Op(
|
||||
@@ -659,10 +671,8 @@ fn shl(a: Fr, b: Fr) -> Fr {
|
||||
}
|
||||
|
||||
let n = b.into_bigint().0[0] as u32;
|
||||
|
||||
let mut a = a.into_bigint();
|
||||
a.muln(n);
|
||||
Fr::from_bigint(a).unwrap()
|
||||
let a = a.into_bigint();
|
||||
Fr::from_bigint(a << n).unwrap()
|
||||
}
|
||||
|
||||
fn shr(a: Fr, b: Fr) -> Fr {
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
// This file is based on the code by iden3. Its preimage can be found here:
|
||||
// https://github.com/iden3/circom-witnesscalc/blob/5cb365b6e4d9052ecc69d4567fcf5bc061c20e94/src/storage.rs
|
||||
|
||||
use ark_bn254::Fr;
|
||||
use ark_ff::PrimeField;
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use prost::Message;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use crate::iden3calc::{
|
||||
graph,
|
||||
graph::{Operation, TresOperation, UnoOperation},
|
||||
proto, InputSignalsInfo,
|
||||
};
|
||||
use ark_bn254::Fr;
|
||||
use ark_ff::PrimeField;
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use prost::Message;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
// format of the wtns.graph file:
|
||||
// + magic line: wtns.graph.001
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// This crate collects all the underlying primitives used to implement RLN
|
||||
|
||||
use ark_bn254::Fr;
|
||||
use ark_circom::CircomReduction;
|
||||
use ark_groth16::{prepare_verifying_key, Groth16, Proof as ArkProof, ProvingKey, VerifyingKey};
|
||||
use ark_relations::r1cs::ConstraintMatrices;
|
||||
use ark_relations::r1cs::SynthesisError;
|
||||
use ark_relations::r1cs::{ConstraintMatrices, SynthesisError};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
use ark_std::{rand::thread_rng, UniformRand};
|
||||
use color_eyre::{Report, Result};
|
||||
@@ -16,9 +16,8 @@ use std::time::Instant;
|
||||
use thiserror::Error;
|
||||
use tiny_keccak::{Hasher as _, Keccak};
|
||||
|
||||
use crate::circuit::{calculate_rln_witness, Curve, Fr};
|
||||
use crate::hashers::hash_to_field;
|
||||
use crate::hashers::poseidon_hash;
|
||||
use crate::circuit::{calculate_rln_witness, Curve};
|
||||
use crate::hashers::{hash_to_field, poseidon_hash};
|
||||
use crate::poseidon_tree::*;
|
||||
use crate::public::RLN_IDENTIFIER;
|
||||
use crate::utils::*;
|
||||
@@ -606,40 +605,23 @@ pub fn generate_proof_with_witness(
|
||||
/// Returns an error if `rln_witness.message_id` is not within `rln_witness.user_message_limit`.
|
||||
pub fn inputs_for_witness_calculation(
|
||||
rln_witness: &RLNWitnessInput,
|
||||
) -> Result<[(&str, Vec<BigInt>); 7]> {
|
||||
) -> Result<[(&str, Vec<Fr>); 7]> {
|
||||
message_id_range_check(&rln_witness.message_id, &rln_witness.user_message_limit)?;
|
||||
|
||||
// We convert the path indexes to field elements
|
||||
// TODO: check if necessary
|
||||
let mut path_elements = Vec::new();
|
||||
|
||||
for v in rln_witness.path_elements.iter() {
|
||||
path_elements.push(to_bigint(v)?);
|
||||
}
|
||||
|
||||
let mut identity_path_index = Vec::new();
|
||||
let mut identity_path_index = Vec::with_capacity(rln_witness.identity_path_index.len());
|
||||
rln_witness
|
||||
.identity_path_index
|
||||
.iter()
|
||||
.for_each(|v| identity_path_index.push(BigInt::from(*v)));
|
||||
.for_each(|v| identity_path_index.push(Fr::from(*v)));
|
||||
|
||||
Ok([
|
||||
(
|
||||
"identitySecret",
|
||||
vec![to_bigint(&rln_witness.identity_secret)?],
|
||||
),
|
||||
(
|
||||
"userMessageLimit",
|
||||
vec![to_bigint(&rln_witness.user_message_limit)?],
|
||||
),
|
||||
("messageId", vec![to_bigint(&rln_witness.message_id)?]),
|
||||
("pathElements", path_elements),
|
||||
("identitySecret", vec![rln_witness.identity_secret]),
|
||||
("userMessageLimit", vec![rln_witness.user_message_limit]),
|
||||
("messageId", vec![rln_witness.message_id]),
|
||||
("pathElements", rln_witness.path_elements.clone()),
|
||||
("identityPathIndex", identity_path_index),
|
||||
("x", vec![to_bigint(&rln_witness.x)?]),
|
||||
(
|
||||
"externalNullifier",
|
||||
vec![to_bigint(&rln_witness.external_nullifier)?],
|
||||
),
|
||||
("x", vec![rln_witness.x]),
|
||||
("externalNullifier", vec![rln_witness.external_nullifier]),
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// This crate provides cross-module useful utilities (mainly type conversions) not necessarily specific to RLN
|
||||
|
||||
use crate::circuit::Fr;
|
||||
use ark_ff::PrimeField;
|
||||
use color_eyre::{Report, Result};
|
||||
use num_bigint::{BigInt, BigUint};
|
||||
@@ -8,6 +7,8 @@ use num_traits::Num;
|
||||
use serde_json::json;
|
||||
use std::io::Cursor;
|
||||
|
||||
use crate::circuit::Fr;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_bigint(el: &Fr) -> Result<BigInt> {
|
||||
Ok(BigUint::from(*el).into())
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "zerokit_utils"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Various utilities for Zerokit"
|
||||
@@ -12,19 +12,19 @@ repository = "https://github.com/vacp2p/zerokit"
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { version = "=0.4.2", default-features = false, features = ["asm"] }
|
||||
num-bigint = { version = "0.4.3", default-features = false, features = [
|
||||
ark-ff = { version = "0.5.0", features = ["asm"] }
|
||||
num-bigint = { version = "0.4.6", default-features = false, features = [
|
||||
"rand",
|
||||
] }
|
||||
color-eyre = "0.6.2"
|
||||
pmtree = { package = "vacp2p_pmtree", version = "=2.0.2", optional = true }
|
||||
sled = "=0.34.7"
|
||||
sled = "0.34.7"
|
||||
serde = "1.0"
|
||||
lazy_static = "1.4.0"
|
||||
hex = "0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
ark-bn254 = "=0.4.0"
|
||||
ark-bn254 = { version = "0.5.0", features = ["std"] }
|
||||
num-traits = "0.2.19"
|
||||
hex-literal = "0.3.4"
|
||||
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
|
||||
|
||||
Reference in New Issue
Block a user