mirror of https://github.com/status-im/rln.git
seperate test runners
This commit is contained in:
parent
73da37a841
commit
72085d2e42
|
@ -10,12 +10,15 @@ crate-type = ["cdylib", "rlib"]
|
|||
[features]
|
||||
multicore = ["sapling-crypto/multicore", "bellman/multicore"]
|
||||
wasm = ["sapling-crypto/wasm", "bellman/wasm", "bellman/nolog"]
|
||||
bench = []
|
||||
|
||||
[dependencies]
|
||||
rand = "0.4"
|
||||
blake2 = "0.8.1"
|
||||
sapling-crypto = { package = "sapling-crypto_ce", version = "0.1.3", default-features = false }
|
||||
bellman = { package = "bellman_ce", version = "0.3.4", default-features = false }
|
||||
# sapling-crypto = { package = "sapling-crypto_ce", version = "0.1.3", default-features = false }
|
||||
sapling-crypto = {package = "sapling-crypto_ce", path = "../sapling-crypto" }
|
||||
# bellman = { package = "bellman_ce", version = "0.3.4", default-features = false }
|
||||
bellman = {package = "bellman_ce", path = "../bellman" }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
console_error_panic_hook = { version = "0.1.1" }
|
||||
|
@ -24,4 +27,4 @@ wee_alloc = "0.4.5"
|
|||
web-sys = {version = "0.3", features = ["console", "Performance", "Window"]}
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = "0.3"
|
||||
wasm-bindgen-test = "0.3"
|
|
@ -0,0 +1,196 @@
|
|||
use crate::circuit::poseidon::PoseidonCircuit;
|
||||
use crate::circuit::rln::{RLNCircuit, RLNInputs};
|
||||
use crate::merkle::MerkleTree;
|
||||
use crate::poseidon::{Poseidon as PoseidonHasher, PoseidonParams};
|
||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||
use sapling_crypto::bellman::groth16::*;
|
||||
use sapling_crypto::bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
use sapling_crypto::bellman::pairing::Engine;
|
||||
use sapling_crypto::bellman::Circuit;
|
||||
use sapling_crypto::circuit::test::TestConstraintSystem;
|
||||
use std::error::Error;
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub struct BenchResult {
|
||||
pub number_of_constaints: usize,
|
||||
pub prover_key_size: usize,
|
||||
pub prover_time: f64,
|
||||
}
|
||||
|
||||
impl BenchResult {
|
||||
pub fn new() -> BenchResult {
|
||||
BenchResult {
|
||||
number_of_constaints: 0,
|
||||
prover_key_size: 0,
|
||||
prover_time: 0f64,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print(&self) {
|
||||
println!("number of constraints\n{}", self.number_of_constaints);
|
||||
println!("prover key size\n{}", self.prover_key_size);
|
||||
println!("prover time\n{}", self.prover_time);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO make it composable: curve, poseidon, merkle
|
||||
pub fn run_rln_bn_24() -> BenchResult {
|
||||
use sapling_crypto::bellman::pairing::bn256::Bn256;
|
||||
let poseidon_params = PoseidonParams::<Bn256>::default();
|
||||
let rln_test = RLNTest::new(poseidon_params, 24);
|
||||
rln_test.run()
|
||||
}
|
||||
pub fn run_rln_bn_32() -> BenchResult {
|
||||
use sapling_crypto::bellman::pairing::bn256::Bn256;
|
||||
let poseidon_params = PoseidonParams::<Bn256>::default();
|
||||
let rln_test = RLNTest::new(poseidon_params, 32);
|
||||
rln_test.run()
|
||||
}
|
||||
|
||||
pub struct RLNTest<E>
|
||||
where
|
||||
E: Engine,
|
||||
{
|
||||
merkle_depth: usize,
|
||||
poseidon_params: PoseidonParams<E>,
|
||||
}
|
||||
|
||||
impl<E> RLNTest<E>
|
||||
where
|
||||
E: Engine,
|
||||
{
|
||||
pub fn new(poseidon_params: PoseidonParams<E>, merkle_depth: usize) -> RLNTest<E> {
|
||||
// let cs = TestConstraintSystem::<E>::new();
|
||||
RLNTest::<E> {
|
||||
poseidon_params,
|
||||
merkle_depth,
|
||||
}
|
||||
}
|
||||
|
||||
fn inputs(&self) -> RLNInputs<E> {
|
||||
let mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let mut hasher = PoseidonHasher::new(self.poseidon_params.clone());
|
||||
// Initialize empty merkle tree
|
||||
let merkle_depth = self.merkle_depth;
|
||||
let mut membership_tree = MerkleTree::empty(hasher.clone(), merkle_depth);
|
||||
|
||||
// A. setup an identity
|
||||
|
||||
let id_key = E::Fr::rand(&mut rng);
|
||||
let id_comm = hasher.hash(vec![id_key.clone()]);
|
||||
|
||||
// B. insert to the membership tree
|
||||
|
||||
let id_index = 6; // any number below 2^depth will work
|
||||
membership_tree.update(id_index, id_comm);
|
||||
|
||||
// C.1 get membership witness
|
||||
|
||||
let auth_path = membership_tree.witness(id_index);
|
||||
assert!(membership_tree.check_inclusion(auth_path.clone(), id_index, id_key.clone()));
|
||||
|
||||
// C.2 prepare sss
|
||||
|
||||
// get current epoch
|
||||
let epoch = E::Fr::rand(&mut rng);
|
||||
|
||||
let signal_hash = E::Fr::rand(&mut rng);
|
||||
// evaluation point is the signal_hash
|
||||
let share_x = signal_hash.clone();
|
||||
|
||||
// calculate current line equation
|
||||
let a_0 = id_key.clone();
|
||||
let a_1 = hasher.hash(vec![a_0, epoch]);
|
||||
|
||||
// evaluate line equation
|
||||
let mut share_y = a_1.clone();
|
||||
share_y.mul_assign(&share_x);
|
||||
share_y.add_assign(&a_0);
|
||||
|
||||
// calculate nullfier
|
||||
let nullifier = hasher.hash(vec![a_1]);
|
||||
|
||||
// compose the circuit
|
||||
|
||||
let inputs = RLNInputs::<E> {
|
||||
share_x: Some(share_x),
|
||||
share_y: Some(share_y),
|
||||
epoch: Some(epoch),
|
||||
nullifier: Some(nullifier),
|
||||
root: Some(membership_tree.root()),
|
||||
id_key: Some(id_key),
|
||||
auth_path: auth_path.into_iter().map(|w| Some(w)).collect(),
|
||||
};
|
||||
|
||||
inputs
|
||||
}
|
||||
|
||||
fn empty_inputs(&self) -> RLNInputs<E> {
|
||||
RLNInputs::<E> {
|
||||
share_x: None,
|
||||
share_y: None,
|
||||
epoch: None,
|
||||
nullifier: None,
|
||||
root: None,
|
||||
id_key: None,
|
||||
auth_path: vec![None; self.merkle_depth],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self) -> BenchResult {
|
||||
let mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
|
||||
let hasher = PoseidonCircuit::new(self.poseidon_params.clone());
|
||||
let inputs = self.inputs();
|
||||
let circuit = RLNCircuit::<E> {
|
||||
inputs: inputs.clone(),
|
||||
hasher: hasher.clone(),
|
||||
};
|
||||
|
||||
let mut result = BenchResult::new();
|
||||
|
||||
let mut cs = TestConstraintSystem::<E>::new();
|
||||
{
|
||||
let circuit = circuit.clone();
|
||||
circuit.synthesize(&mut cs).unwrap();
|
||||
let unsatisfied = cs.which_is_unsatisfied();
|
||||
if unsatisfied.is_some() {
|
||||
panic!("unsatisfied\n{}", unsatisfied.unwrap());
|
||||
}
|
||||
let unconstrained = cs.find_unconstrained();
|
||||
if !unconstrained.is_empty() {
|
||||
panic!("unconstrained\n{}", unconstrained);
|
||||
}
|
||||
assert!(cs.is_satisfied());
|
||||
result.number_of_constaints = cs.num_constraints();
|
||||
}
|
||||
|
||||
{
|
||||
let parameters = {
|
||||
let inputs = self.empty_inputs();
|
||||
let circuit = RLNCircuit::<E> {
|
||||
inputs,
|
||||
hasher: hasher.clone(),
|
||||
};
|
||||
let parameters = generate_random_parameters(circuit, &mut rng).unwrap();
|
||||
parameters
|
||||
};
|
||||
|
||||
let mut v = vec![];
|
||||
parameters.write(&mut v).unwrap();
|
||||
|
||||
result.prover_key_size = v.len();
|
||||
|
||||
let now = Instant::now();
|
||||
let proof = create_random_proof(circuit, ¶meters, &mut rng).unwrap();
|
||||
|
||||
result.prover_time = now.elapsed().as_millis() as f64 / 1000.0;
|
||||
|
||||
let verifing_key = prepare_verifying_key(¶meters.vk);
|
||||
assert!(verify_proof(&verifing_key, &proof, &inputs.public_inputs()).unwrap());
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
mod polynomial;
|
||||
pub mod poseidon;
|
||||
pub mod rln;
|
||||
|
||||
#[cfg(any(test, feature = "bench"))]
|
||||
pub mod bench;
|
||||
|
|
|
@ -49,7 +49,7 @@ impl<E> RLNInputs<E>
|
|||
where
|
||||
E: Engine,
|
||||
{
|
||||
fn public_inputs(&self) -> Vec<E::Fr> {
|
||||
pub fn public_inputs(&self) -> Vec<E::Fr> {
|
||||
vec![
|
||||
self.root.unwrap(),
|
||||
self.epoch.unwrap(),
|
||||
|
@ -371,187 +371,20 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{RLNCircuit, RLNInputs};
|
||||
use crate::circuit::poseidon::PoseidonCircuit;
|
||||
use crate::merkle::MerkleTree;
|
||||
use crate::poseidon::{Poseidon as PoseidonHasher, PoseidonParams};
|
||||
use rand::{Rand, SeedableRng, XorShiftRng};
|
||||
// use sapling_crypto::bellman::groth16::{
|
||||
// create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, Parameters,
|
||||
// };
|
||||
use sapling_crypto::bellman::groth16::*;
|
||||
use sapling_crypto::bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
use sapling_crypto::bellman::pairing::Engine;
|
||||
use sapling_crypto::bellman::Circuit;
|
||||
use sapling_crypto::circuit::test::TestConstraintSystem;
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
struct RLNTest<E>
|
||||
where
|
||||
E: Engine,
|
||||
{
|
||||
// cs: TestConstraintSystem<E>,
|
||||
merkle_depth: usize,
|
||||
poseidon_params: PoseidonParams<E>,
|
||||
}
|
||||
use super::RLNInputs;
|
||||
use crate::circuit::bench;
|
||||
|
||||
impl<E> RLNTest<E>
|
||||
where
|
||||
E: Engine,
|
||||
{
|
||||
pub fn new(poseidon_params: PoseidonParams<E>, merkle_depth: usize) -> RLNTest<E> {
|
||||
// let cs = TestConstraintSystem::<E>::new();
|
||||
RLNTest::<E> {
|
||||
poseidon_params,
|
||||
merkle_depth,
|
||||
}
|
||||
}
|
||||
|
||||
fn inputs(&self) -> RLNInputs<E> {
|
||||
let mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
let mut hasher = PoseidonHasher::new(self.poseidon_params.clone());
|
||||
// Initialize empty merkle tree
|
||||
let merkle_depth = self.merkle_depth;
|
||||
let mut membership_tree = MerkleTree::empty(hasher.clone(), merkle_depth);
|
||||
|
||||
// A. setup an identity
|
||||
|
||||
let id_key = E::Fr::rand(&mut rng);
|
||||
let id_comm = hasher.hash(vec![id_key.clone()]);
|
||||
|
||||
// B. insert to the membership tree
|
||||
|
||||
let id_index = 6; // any number below 2^depth will work
|
||||
membership_tree.update(id_index, id_comm);
|
||||
|
||||
// C.1 get membership witness
|
||||
|
||||
let auth_path = membership_tree.witness(id_index);
|
||||
assert!(membership_tree.check_inclusion(auth_path.clone(), id_index, id_key.clone()));
|
||||
|
||||
// C.2 prepare sss
|
||||
|
||||
// get current epoch
|
||||
let epoch = E::Fr::rand(&mut rng);
|
||||
|
||||
let signal_hash = E::Fr::rand(&mut rng);
|
||||
// evaluation point is the signal_hash
|
||||
let share_x = signal_hash.clone();
|
||||
|
||||
// calculate current line equation
|
||||
let a_0 = id_key.clone();
|
||||
let a_1 = hasher.hash(vec![a_0, epoch]);
|
||||
|
||||
// evaluate line equation
|
||||
let mut share_y = a_1.clone();
|
||||
share_y.mul_assign(&share_x);
|
||||
share_y.add_assign(&a_0);
|
||||
|
||||
// calculate nullfier
|
||||
let nullifier = hasher.hash(vec![a_1]);
|
||||
|
||||
// compose the circuit
|
||||
|
||||
let inputs = RLNInputs::<E> {
|
||||
share_x: Some(share_x),
|
||||
share_y: Some(share_y),
|
||||
epoch: Some(epoch),
|
||||
nullifier: Some(nullifier),
|
||||
root: Some(membership_tree.root()),
|
||||
id_key: Some(id_key),
|
||||
auth_path: auth_path.into_iter().map(|w| Some(w)).collect(),
|
||||
};
|
||||
|
||||
inputs
|
||||
}
|
||||
|
||||
fn empty_inputs(&self) -> RLNInputs<E> {
|
||||
RLNInputs::<E> {
|
||||
share_x: None,
|
||||
share_y: None,
|
||||
epoch: None,
|
||||
nullifier: None,
|
||||
root: None,
|
||||
id_key: None,
|
||||
auth_path: vec![None; self.merkle_depth],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self) {
|
||||
let mut rng = XorShiftRng::from_seed([0x3dbe6258, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
|
||||
let hasher = PoseidonCircuit::new(self.poseidon_params.clone());
|
||||
let inputs = self.inputs();
|
||||
let circuit = RLNCircuit::<E> {
|
||||
inputs: inputs.clone(),
|
||||
hasher: hasher.clone(),
|
||||
};
|
||||
let mut cs = TestConstraintSystem::<E>::new();
|
||||
{
|
||||
let circuit = circuit.clone();
|
||||
circuit.synthesize(&mut cs).unwrap();
|
||||
let unsatisfied = cs.which_is_unsatisfied();
|
||||
if unsatisfied.is_some() {
|
||||
panic!("unsatisfied\n{}", unsatisfied.unwrap());
|
||||
}
|
||||
let unconstrained = cs.find_unconstrained();
|
||||
if !unconstrained.is_empty() {
|
||||
panic!("unconstrained\n{}", unconstrained);
|
||||
}
|
||||
assert!(cs.is_satisfied());
|
||||
println!("number of constaints: {}", cs.num_constraints());
|
||||
}
|
||||
|
||||
{
|
||||
let parameters = {
|
||||
let inputs = self.empty_inputs();
|
||||
let circuit = RLNCircuit::<E> {
|
||||
inputs,
|
||||
hasher: hasher.clone(),
|
||||
};
|
||||
let parameters = generate_random_parameters(circuit, &mut rng).unwrap();
|
||||
parameters
|
||||
};
|
||||
|
||||
// let mut key_size = 0;
|
||||
// let point_size = (((E::Fr::NUM_BITS / 64) + 1) * 8 * 2) as usize;
|
||||
// key_size += parameters.a.len() * point_size;
|
||||
// key_size += parameters.l.len() * point_size;
|
||||
// key_size += parameters.h.len() * point_size;
|
||||
// key_size += parameters.b_g1.len() * point_size;
|
||||
// key_size += parameters.b_g2.len() * point_size * 2;
|
||||
// println!("prover key size in bytes: {}", key_size);
|
||||
|
||||
let mut v = vec![];
|
||||
parameters.write(&mut v).unwrap();
|
||||
|
||||
println!("circuit parameter size in bytes: {}", v.len());
|
||||
|
||||
let now = Instant::now();
|
||||
let proof = create_random_proof(circuit, ¶meters, &mut rng).unwrap();
|
||||
println!("prover time: {}", now.elapsed().as_millis() as f64 / 1000.0);
|
||||
|
||||
let verifing_key = prepare_verifying_key(¶meters.vk);
|
||||
assert!(verify_proof(&verifing_key, &proof, &inputs.public_inputs()).unwrap());
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_rln_bn_24() {
|
||||
let result = bench::run_rln_bn_24();
|
||||
result.print();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rln_24() {
|
||||
use sapling_crypto::bellman::pairing::bn256::Bn256;
|
||||
let poseidon_params = PoseidonParams::<Bn256>::default();
|
||||
let rln_test = RLNTest::new(poseidon_params, 24);
|
||||
rln_test.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rln_32() {
|
||||
use sapling_crypto::bellman::pairing::bn256::Bn256;
|
||||
let poseidon_params = PoseidonParams::<Bn256>::default();
|
||||
let rln_test = RLNTest::new(poseidon_params, 32);
|
||||
rln_test.run();
|
||||
fn test_rln_bn_32() {
|
||||
let result = bench::run_rln_bn_32();
|
||||
result.print();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue