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]
|
[features]
|
||||||
multicore = ["sapling-crypto/multicore", "bellman/multicore"]
|
multicore = ["sapling-crypto/multicore", "bellman/multicore"]
|
||||||
wasm = ["sapling-crypto/wasm", "bellman/wasm", "bellman/nolog"]
|
wasm = ["sapling-crypto/wasm", "bellman/wasm", "bellman/nolog"]
|
||||||
|
bench = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
blake2 = "0.8.1"
|
blake2 = "0.8.1"
|
||||||
sapling-crypto = { package = "sapling-crypto_ce", version = "0.1.3", default-features = false }
|
# 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", 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]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
console_error_panic_hook = { version = "0.1.1" }
|
console_error_panic_hook = { version = "0.1.1" }
|
||||||
|
|
|
@ -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;
|
mod polynomial;
|
||||||
pub mod poseidon;
|
pub mod poseidon;
|
||||||
pub mod rln;
|
pub mod rln;
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "bench"))]
|
||||||
|
pub mod bench;
|
||||||
|
|
|
@ -49,7 +49,7 @@ impl<E> RLNInputs<E>
|
||||||
where
|
where
|
||||||
E: Engine,
|
E: Engine,
|
||||||
{
|
{
|
||||||
fn public_inputs(&self) -> Vec<E::Fr> {
|
pub fn public_inputs(&self) -> Vec<E::Fr> {
|
||||||
vec![
|
vec![
|
||||||
self.root.unwrap(),
|
self.root.unwrap(),
|
||||||
self.epoch.unwrap(),
|
self.epoch.unwrap(),
|
||||||
|
@ -371,187 +371,20 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod 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>
|
use super::RLNInputs;
|
||||||
where
|
use crate::circuit::bench;
|
||||||
E: Engine,
|
|
||||||
{
|
|
||||||
// cs: TestConstraintSystem<E>,
|
|
||||||
merkle_depth: usize,
|
|
||||||
poseidon_params: PoseidonParams<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E> RLNTest<E>
|
#[test]
|
||||||
where
|
fn test_rln_bn_24() {
|
||||||
E: Engine,
|
let result = bench::run_rln_bn_24();
|
||||||
{
|
result.print();
|
||||||
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]
|
#[test]
|
||||||
fn test_rln_24() {
|
fn test_rln_bn_32() {
|
||||||
use sapling_crypto::bellman::pairing::bn256::Bn256;
|
let result = bench::run_rln_bn_32();
|
||||||
let poseidon_params = PoseidonParams::<Bn256>::default();
|
result.print();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue