fix compilation warnings, disable sonics in default features
This commit is contained in:
parent
2a453c3325
commit
f12986aaeb
@ -32,8 +32,8 @@ git = "https://github.com/gtank/blake2-rfc"
|
|||||||
rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
#default = ["multicore"]
|
default = ["multicore"]
|
||||||
default = ["multicore", "gm17", "sonic"]
|
#default = ["multicore", "gm17", "sonic"]
|
||||||
#default = ["singlecore"]
|
#default = ["singlecore"]
|
||||||
multicore = ["futures-cpupool", "num_cpus", "crossbeam"]
|
multicore = ["futures-cpupool", "num_cpus", "crossbeam"]
|
||||||
sonic = ["tiny-keccak"]
|
sonic = ["tiny-keccak"]
|
||||||
|
@ -185,6 +185,7 @@ pub fn multiexp<Q, D, G, S>(
|
|||||||
|
|
||||||
/// Perform multi-exponentiation. The caller is responsible for ensuring that
|
/// Perform multi-exponentiation. The caller is responsible for ensuring that
|
||||||
/// the number of bases is the same as the number of exponents.
|
/// the number of bases is the same as the number of exponents.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn dense_multiexp<G: CurveAffine>(
|
pub fn dense_multiexp<G: CurveAffine>(
|
||||||
pool: &Worker,
|
pool: &Worker,
|
||||||
bases: & [G],
|
bases: & [G],
|
||||||
@ -220,7 +221,6 @@ fn dense_multiexp_inner<G: CurveAffine>(
|
|||||||
let this_region = Mutex::new(<G as CurveAffine>::Projective::zero());
|
let this_region = Mutex::new(<G as CurveAffine>::Projective::zero());
|
||||||
let arc = Arc::new(this_region);
|
let arc = Arc::new(this_region);
|
||||||
pool.scope(bases.len(), |scope, chunk| {
|
pool.scope(bases.len(), |scope, chunk| {
|
||||||
let mut this_acc = <G as CurveAffine>::Projective::zero();
|
|
||||||
for (base, exp) in bases.chunks(chunk).zip(exponents.chunks(chunk)) {
|
for (base, exp) in bases.chunks(chunk).zip(exponents.chunks(chunk)) {
|
||||||
let this_region_rwlock = arc.clone();
|
let this_region_rwlock = arc.clone();
|
||||||
// let handle =
|
// let handle =
|
||||||
@ -265,7 +265,7 @@ fn dense_multiexp_inner<G: CurveAffine>(
|
|||||||
|
|
||||||
let mut guard = match this_region_rwlock.lock() {
|
let mut guard = match this_region_rwlock.lock() {
|
||||||
Ok(guard) => guard,
|
Ok(guard) => guard,
|
||||||
Err(poisoned) => {
|
Err(_) => {
|
||||||
panic!("poisoned!");
|
panic!("poisoned!");
|
||||||
// poisoned.into_inner()
|
// poisoned.into_inner()
|
||||||
}
|
}
|
||||||
@ -387,7 +387,7 @@ fn test_dense_multiexp() {
|
|||||||
const SAMPLES: usize = 1 << 16;
|
const SAMPLES: usize = 1 << 16;
|
||||||
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
|
||||||
let mut v = (0..SAMPLES).map(|_| <Bn256 as ScalarEngine>::Fr::rand(rng).into_repr()).collect::<Vec<_>>();
|
let v = (0..SAMPLES).map(|_| <Bn256 as ScalarEngine>::Fr::rand(rng).into_repr()).collect::<Vec<_>>();
|
||||||
let g = (0..SAMPLES).map(|_| <Bn256 as Engine>::G1::rand(rng).into_affine()).collect::<Vec<_>>();
|
let g = (0..SAMPLES).map(|_| <Bn256 as Engine>::G1::rand(rng).into_affine()).collect::<Vec<_>>();
|
||||||
|
|
||||||
println!("Done generating test points and scalars");
|
println!("Done generating test points and scalars");
|
||||||
@ -397,7 +397,7 @@ fn test_dense_multiexp() {
|
|||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
let dense = dense_multiexp(
|
let dense = dense_multiexp(
|
||||||
&pool, &g, &mut v.clone()).unwrap();
|
&pool, &g, &v.clone()).unwrap();
|
||||||
|
|
||||||
let duration_ns = start.elapsed().as_nanos() as f64;
|
let duration_ns = start.elapsed().as_nanos() as f64;
|
||||||
println!("{} ns for dense for {} samples", duration_ns, SAMPLES);
|
println!("{} ns for dense for {} samples", duration_ns, SAMPLES);
|
||||||
|
@ -11,5 +11,7 @@ pub mod unhelped;
|
|||||||
|
|
||||||
mod transcript;
|
mod transcript;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
|
|
||||||
|
436
src/sonic/tests/sonics.rs
Normal file
436
src/sonic/tests/sonics.rs
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
extern crate bellman;
|
||||||
|
extern crate pairing;
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
|
// For randomness (during paramgen and proof generation)
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
|
// For benchmarking
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
// Bring in some tools for using pairing-friendly curves
|
||||||
|
use pairing::{
|
||||||
|
Engine
|
||||||
|
};
|
||||||
|
|
||||||
|
use pairing::ff::{
|
||||||
|
Field,
|
||||||
|
};
|
||||||
|
|
||||||
|
// We're going to use the BLS12-381 pairing-friendly elliptic curve.
|
||||||
|
use pairing::bls12_381::{
|
||||||
|
Bls12
|
||||||
|
};
|
||||||
|
|
||||||
|
use pairing::bn256::{
|
||||||
|
Bn256
|
||||||
|
};
|
||||||
|
|
||||||
|
// We'll use these interfaces to construct our circuit.
|
||||||
|
use bellman::{
|
||||||
|
Circuit,
|
||||||
|
ConstraintSystem,
|
||||||
|
SynthesisError
|
||||||
|
};
|
||||||
|
|
||||||
|
// We're going to use the Groth16 proving system.
|
||||||
|
use bellman::groth16::{
|
||||||
|
Proof,
|
||||||
|
generate_random_parameters,
|
||||||
|
prepare_verifying_key,
|
||||||
|
create_random_proof,
|
||||||
|
verify_proof,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MIMC_ROUNDS: usize = 322;
|
||||||
|
|
||||||
|
/// This is our demo circuit for proving knowledge of the
|
||||||
|
/// preimage of a MiMC hash invocation.
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct MiMCDemoNoInputs<'a, E: Engine> {
|
||||||
|
xl: Option<E::Fr>,
|
||||||
|
xr: Option<E::Fr>,
|
||||||
|
image: Option<E::Fr>,
|
||||||
|
constants: &'a [E::Fr]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Our demo circuit implements this `Circuit` trait which
|
||||||
|
/// is used during paramgen and proving in order to
|
||||||
|
/// synthesize the constraint system.
|
||||||
|
impl<'a, E: Engine> Circuit<E> for MiMCDemoNoInputs<'a, E> {
|
||||||
|
fn synthesize<CS: ConstraintSystem<E>>(
|
||||||
|
self,
|
||||||
|
cs: &mut CS
|
||||||
|
) -> Result<(), SynthesisError>
|
||||||
|
{
|
||||||
|
assert_eq!(self.constants.len(), MIMC_ROUNDS);
|
||||||
|
|
||||||
|
// Allocate the first component of the preimage.
|
||||||
|
let mut xl_value = self.xl;
|
||||||
|
let mut xl = cs.alloc(|| "preimage xl", || {
|
||||||
|
xl_value.ok_or(SynthesisError::AssignmentMissing)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Allocate the second component of the preimage.
|
||||||
|
let mut xr_value = self.xr;
|
||||||
|
let mut xr = cs.alloc(|| "preimage xr", || {
|
||||||
|
xr_value.ok_or(SynthesisError::AssignmentMissing)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
for i in 0..MIMC_ROUNDS {
|
||||||
|
// xL, xR := xR + (xL + Ci)^3, xL
|
||||||
|
let cs = &mut cs.namespace(|| format!("round {}", i));
|
||||||
|
|
||||||
|
// tmp = (xL + Ci)^2
|
||||||
|
let tmp_value = xl_value.map(|mut e| {
|
||||||
|
e.add_assign(&self.constants[i]);
|
||||||
|
e.square();
|
||||||
|
e
|
||||||
|
});
|
||||||
|
let tmp = cs.alloc(|| "tmp", || {
|
||||||
|
tmp_value.ok_or(SynthesisError::AssignmentMissing)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
cs.enforce(
|
||||||
|
|| "tmp = (xL + Ci)^2",
|
||||||
|
|lc| lc + xl + (self.constants[i], CS::one()),
|
||||||
|
|lc| lc + xl + (self.constants[i], CS::one()),
|
||||||
|
|lc| lc + tmp
|
||||||
|
);
|
||||||
|
|
||||||
|
// new_xL = xR + (xL + Ci)^3
|
||||||
|
// new_xL = xR + tmp * (xL + Ci)
|
||||||
|
// new_xL - xR = tmp * (xL + Ci)
|
||||||
|
let new_xl_value = xl_value.map(|mut e| {
|
||||||
|
e.add_assign(&self.constants[i]);
|
||||||
|
e.mul_assign(&tmp_value.unwrap());
|
||||||
|
e.add_assign(&xr_value.unwrap());
|
||||||
|
e
|
||||||
|
});
|
||||||
|
|
||||||
|
let new_xl = if i == (MIMC_ROUNDS-1) {
|
||||||
|
// This is the last round, xL is our image and so
|
||||||
|
// we use the image
|
||||||
|
let image_value = self.image;
|
||||||
|
cs.alloc(|| "image", || {
|
||||||
|
image_value.ok_or(SynthesisError::AssignmentMissing)
|
||||||
|
})?
|
||||||
|
} else {
|
||||||
|
cs.alloc(|| "new_xl", || {
|
||||||
|
new_xl_value.ok_or(SynthesisError::AssignmentMissing)
|
||||||
|
})?
|
||||||
|
};
|
||||||
|
|
||||||
|
cs.enforce(
|
||||||
|
|| "new_xL = xR + (xL + Ci)^3",
|
||||||
|
|lc| lc + tmp,
|
||||||
|
|lc| lc + xl + (self.constants[i], CS::one()),
|
||||||
|
|lc| lc + new_xl - xr
|
||||||
|
);
|
||||||
|
|
||||||
|
// xR = xL
|
||||||
|
xr = xl;
|
||||||
|
xr_value = xl_value;
|
||||||
|
|
||||||
|
// xL = new_xL
|
||||||
|
xl = new_xl;
|
||||||
|
xl_value = new_xl_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sonic_mimc() {
|
||||||
|
use pairing::ff::{Field, PrimeField};
|
||||||
|
use pairing::{Engine, CurveAffine, CurveProjective};
|
||||||
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
|
use std::time::{Instant};
|
||||||
|
use bellman::sonic::srs::SRS;
|
||||||
|
|
||||||
|
let srs_x = Fr::from_str("23923").unwrap();
|
||||||
|
let srs_alpha = Fr::from_str("23728792").unwrap();
|
||||||
|
println!("making srs");
|
||||||
|
let start = Instant::now();
|
||||||
|
let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
{
|
||||||
|
// This may not be cryptographically safe, use
|
||||||
|
// `OsRng` (for example) in production software.
|
||||||
|
let rng = &mut thread_rng();
|
||||||
|
|
||||||
|
// Generate the MiMC round constants
|
||||||
|
let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::<Vec<_>>();
|
||||||
|
let samples: usize = 100;
|
||||||
|
|
||||||
|
let xl = rng.gen();
|
||||||
|
let xr = rng.gen();
|
||||||
|
let image = mimc::<Bls12>(xl, xr, &constants);
|
||||||
|
|
||||||
|
// Create an instance of our circuit (with the
|
||||||
|
// witness)
|
||||||
|
let circuit = MiMCDemoNoInputs {
|
||||||
|
xl: Some(xl),
|
||||||
|
xr: Some(xr),
|
||||||
|
image: Some(image),
|
||||||
|
constants: &constants
|
||||||
|
};
|
||||||
|
|
||||||
|
use bellman::sonic::cs::Basic;
|
||||||
|
use bellman::sonic::sonic::AdaptorCircuit;
|
||||||
|
use bellman::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs};
|
||||||
|
use bellman::sonic::helped::{MultiVerifier, get_circuit_parameters};
|
||||||
|
use bellman::sonic::helped::helper::{create_aggregate_on_srs};
|
||||||
|
|
||||||
|
println!("creating proof");
|
||||||
|
let start = Instant::now();
|
||||||
|
let proof = create_proof_on_srs::<Bls12, _, Basic>(&AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
println!("creating advice");
|
||||||
|
let start = Instant::now();
|
||||||
|
let advice = create_advice_on_srs::<Bls12, _, Basic>(&AdaptorCircuit(circuit.clone()), &proof, &srs).unwrap();
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
println!("creating aggregate for {} proofs", samples);
|
||||||
|
let start = Instant::now();
|
||||||
|
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
||||||
|
let aggregate = create_aggregate_on_srs::<Bls12, _, Basic>(&AdaptorCircuit(circuit.clone()), &proofs, &srs);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
{
|
||||||
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
|
println!("verifying 1 proof without advice");
|
||||||
|
let start = Instant::now();
|
||||||
|
{
|
||||||
|
for _ in 0..1 {
|
||||||
|
verifier.add_proof(&proof, &[], |_, _| None);
|
||||||
|
}
|
||||||
|
assert_eq!(verifier.check_all(), true); // TODO
|
||||||
|
}
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
|
println!("verifying {} proofs without advice", samples);
|
||||||
|
let start = Instant::now();
|
||||||
|
{
|
||||||
|
for _ in 0..samples {
|
||||||
|
verifier.add_proof(&proof, &[], |_, _| None);
|
||||||
|
}
|
||||||
|
assert_eq!(verifier.check_all(), true); // TODO
|
||||||
|
}
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
|
println!("verifying 100 proofs with advice");
|
||||||
|
let start = Instant::now();
|
||||||
|
{
|
||||||
|
for (ref proof, ref advice) in &proofs {
|
||||||
|
verifier.add_proof_with_advice(proof, &[], advice);
|
||||||
|
}
|
||||||
|
verifier.add_aggregate(&proofs, &aggregate);
|
||||||
|
assert_eq!(verifier.check_all(), true); // TODO
|
||||||
|
}
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_inputs_into_sonic_mimc() {
|
||||||
|
use pairing::ff::{Field, PrimeField};
|
||||||
|
use pairing::{Engine, CurveAffine, CurveProjective};
|
||||||
|
use pairing::bn256::{Bn256, Fr};
|
||||||
|
// use pairing::bls12_381::{Bls12, Fr};
|
||||||
|
use std::time::{Instant};
|
||||||
|
use bellman::sonic::srs::SRS;
|
||||||
|
|
||||||
|
let srs_x = Fr::from_str("23923").unwrap();
|
||||||
|
let srs_alpha = Fr::from_str("23728792").unwrap();
|
||||||
|
println!("making srs");
|
||||||
|
let start = Instant::now();
|
||||||
|
let srs = SRS::<Bn256>::dummy(830564, srs_x, srs_alpha);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
{
|
||||||
|
// This may not be cryptographically safe, use
|
||||||
|
// `OsRng` (for example) in production software.
|
||||||
|
let rng = &mut thread_rng();
|
||||||
|
|
||||||
|
// Generate the MiMC round constants
|
||||||
|
let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::<Vec<_>>();
|
||||||
|
let samples: usize = 100;
|
||||||
|
|
||||||
|
let xl = rng.gen();
|
||||||
|
let xr = rng.gen();
|
||||||
|
let image = mimc::<Bn256>(xl, xr, &constants);
|
||||||
|
|
||||||
|
// Create an instance of our circuit (with the
|
||||||
|
// witness)
|
||||||
|
let circuit = MiMCDemo {
|
||||||
|
xl: Some(xl),
|
||||||
|
xr: Some(xr),
|
||||||
|
constants: &constants
|
||||||
|
};
|
||||||
|
|
||||||
|
use bellman::sonic::cs::Basic;
|
||||||
|
use bellman::sonic::sonic::AdaptorCircuit;
|
||||||
|
use bellman::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs};
|
||||||
|
use bellman::sonic::helped::{MultiVerifier, get_circuit_parameters};
|
||||||
|
use bellman::sonic::helped::helper::{create_aggregate_on_srs};
|
||||||
|
|
||||||
|
let info = get_circuit_parameters::<Bn256, _>(circuit.clone()).expect("Must get circuit info");
|
||||||
|
println!("{:?}", info);
|
||||||
|
|
||||||
|
println!("creating proof");
|
||||||
|
let start = Instant::now();
|
||||||
|
let proof = create_proof_on_srs::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
println!("creating advice");
|
||||||
|
let start = Instant::now();
|
||||||
|
let advice = create_advice_on_srs::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &proof, &srs).unwrap();
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
println!("creating aggregate for {} proofs", samples);
|
||||||
|
let start = Instant::now();
|
||||||
|
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
||||||
|
let aggregate = create_aggregate_on_srs::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &proofs, &srs);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
{
|
||||||
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
|
println!("verifying 1 proof without advice");
|
||||||
|
let start = Instant::now();
|
||||||
|
{
|
||||||
|
for _ in 0..1 {
|
||||||
|
verifier.add_proof(&proof, &[image], |_, _| None);
|
||||||
|
}
|
||||||
|
assert_eq!(verifier.check_all(), true); // TODO
|
||||||
|
}
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
|
println!("verifying {} proofs without advice", samples);
|
||||||
|
let start = Instant::now();
|
||||||
|
{
|
||||||
|
for _ in 0..samples {
|
||||||
|
verifier.add_proof(&proof, &[image], |_, _| None);
|
||||||
|
}
|
||||||
|
assert_eq!(verifier.check_all(), true); // TODO
|
||||||
|
}
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
|
println!("verifying 100 proofs with advice and aggregate");
|
||||||
|
let start = Instant::now();
|
||||||
|
{
|
||||||
|
for (ref proof, ref advice) in &proofs {
|
||||||
|
verifier.add_proof_with_advice(proof, &[image], advice);
|
||||||
|
}
|
||||||
|
verifier.add_aggregate(&proofs, &aggregate);
|
||||||
|
assert_eq!(verifier.check_all(), true); // TODO
|
||||||
|
}
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_high_level_sonic_api() {
|
||||||
|
use pairing::bn256::{Bn256};
|
||||||
|
use std::time::{Instant};
|
||||||
|
use bellman::sonic::helped::{
|
||||||
|
generate_random_parameters,
|
||||||
|
verify_aggregate,
|
||||||
|
verify_proofs,
|
||||||
|
create_proof,
|
||||||
|
create_advice,
|
||||||
|
create_aggregate,
|
||||||
|
get_circuit_parameters
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
// This may not be cryptographically safe, use
|
||||||
|
// `OsRng` (for example) in production software.
|
||||||
|
let mut rng = &mut thread_rng();
|
||||||
|
|
||||||
|
// Generate the MiMC round constants
|
||||||
|
let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::<Vec<_>>();
|
||||||
|
let samples: usize = 100;
|
||||||
|
|
||||||
|
let xl = rng.gen();
|
||||||
|
let xr = rng.gen();
|
||||||
|
let image = mimc::<Bn256>(xl, xr, &constants);
|
||||||
|
|
||||||
|
// Create an instance of our circuit (with the
|
||||||
|
// witness)
|
||||||
|
let circuit = MiMCDemo {
|
||||||
|
xl: Some(xl),
|
||||||
|
xr: Some(xr),
|
||||||
|
constants: &constants
|
||||||
|
};
|
||||||
|
|
||||||
|
let info = get_circuit_parameters::<Bn256, _>(circuit.clone()).expect("Must get circuit info");
|
||||||
|
println!("{:?}", info);
|
||||||
|
|
||||||
|
let params = generate_random_parameters(circuit.clone(), &mut rng).unwrap();
|
||||||
|
|
||||||
|
println!("creating proof");
|
||||||
|
let start = Instant::now();
|
||||||
|
let proof = create_proof(circuit.clone(), ¶ms).unwrap();
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
println!("creating advice");
|
||||||
|
let start = Instant::now();
|
||||||
|
let advice = create_advice(circuit.clone(), &proof, ¶ms).unwrap();
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
println!("creating aggregate for {} proofs", samples);
|
||||||
|
let start = Instant::now();
|
||||||
|
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
||||||
|
|
||||||
|
let aggregate = create_aggregate::<Bn256, _>(circuit.clone(), &proofs, ¶ms);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
{
|
||||||
|
println!("verifying 1 proof without advice");
|
||||||
|
let rng = thread_rng();
|
||||||
|
let start = Instant::now();
|
||||||
|
assert_eq!(verify_proofs(&vec![proof.clone()], &vec![vec![image.clone()]], circuit.clone(), rng, ¶ms).unwrap(), true);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
println!("verifying {} proofs without advice", samples);
|
||||||
|
let rng = thread_rng();
|
||||||
|
let start = Instant::now();
|
||||||
|
assert_eq!(verify_proofs(&vec![proof.clone(); 100], &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), true);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
println!("verifying 100 proofs with advice and aggregate");
|
||||||
|
let rng = thread_rng();
|
||||||
|
let start = Instant::now();
|
||||||
|
assert_eq!(verify_aggregate(&vec![(proof.clone(), advice.clone()); 100], &aggregate, &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), true);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
399
tests/mimc.rs
399
tests/mimc.rs
@ -116,12 +116,12 @@ impl<'a, E: Engine> Circuit<E> for MiMCDemo<'a, E> {
|
|||||||
let cs = &mut cs.namespace(|| format!("round {}", i));
|
let cs = &mut cs.namespace(|| format!("round {}", i));
|
||||||
|
|
||||||
// tmp = (xL + Ci)^2
|
// tmp = (xL + Ci)^2
|
||||||
let mut tmp_value = xl_value.map(|mut e| {
|
let tmp_value = xl_value.map(|mut e| {
|
||||||
e.add_assign(&self.constants[i]);
|
e.add_assign(&self.constants[i]);
|
||||||
e.square();
|
e.square();
|
||||||
e
|
e
|
||||||
});
|
});
|
||||||
let mut tmp = cs.alloc(|| "tmp", || {
|
let tmp = cs.alloc(|| "tmp", || {
|
||||||
tmp_value.ok_or(SynthesisError::AssignmentMissing)
|
tmp_value.ok_or(SynthesisError::AssignmentMissing)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -135,14 +135,14 @@ impl<'a, E: Engine> Circuit<E> for MiMCDemo<'a, E> {
|
|||||||
// new_xL = xR + (xL + Ci)^3
|
// new_xL = xR + (xL + Ci)^3
|
||||||
// new_xL = xR + tmp * (xL + Ci)
|
// new_xL = xR + tmp * (xL + Ci)
|
||||||
// new_xL - xR = tmp * (xL + Ci)
|
// new_xL - xR = tmp * (xL + Ci)
|
||||||
let mut new_xl_value = xl_value.map(|mut e| {
|
let new_xl_value = xl_value.map(|mut e| {
|
||||||
e.add_assign(&self.constants[i]);
|
e.add_assign(&self.constants[i]);
|
||||||
e.mul_assign(&tmp_value.unwrap());
|
e.mul_assign(&tmp_value.unwrap());
|
||||||
e.add_assign(&xr_value.unwrap());
|
e.add_assign(&xr_value.unwrap());
|
||||||
e
|
e
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut new_xl = if i == (MIMC_ROUNDS-1) {
|
let new_xl = if i == (MIMC_ROUNDS-1) {
|
||||||
// This is the last round, xL is our image and so
|
// This is the last round, xL is our image and so
|
||||||
// we allocate a public input.
|
// we allocate a public input.
|
||||||
cs.alloc_input(|| "image", || {
|
cs.alloc_input(|| "image", || {
|
||||||
@ -341,394 +341,3 @@ fn test_mimc_bn256() {
|
|||||||
println!("Average proving time: {:?} seconds", proving_avg);
|
println!("Average proving time: {:?} seconds", proving_avg);
|
||||||
println!("Average verifying time: {:?} seconds", verifying_avg);
|
println!("Average verifying time: {:?} seconds", verifying_avg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is our demo circuit for proving knowledge of the
|
|
||||||
/// preimage of a MiMC hash invocation.
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct MiMCDemoNoInputs<'a, E: Engine> {
|
|
||||||
xl: Option<E::Fr>,
|
|
||||||
xr: Option<E::Fr>,
|
|
||||||
image: Option<E::Fr>,
|
|
||||||
constants: &'a [E::Fr]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Our demo circuit implements this `Circuit` trait which
|
|
||||||
/// is used during paramgen and proving in order to
|
|
||||||
/// synthesize the constraint system.
|
|
||||||
impl<'a, E: Engine> Circuit<E> for MiMCDemoNoInputs<'a, E> {
|
|
||||||
fn synthesize<CS: ConstraintSystem<E>>(
|
|
||||||
self,
|
|
||||||
cs: &mut CS
|
|
||||||
) -> Result<(), SynthesisError>
|
|
||||||
{
|
|
||||||
assert_eq!(self.constants.len(), MIMC_ROUNDS);
|
|
||||||
|
|
||||||
// Allocate the first component of the preimage.
|
|
||||||
let mut xl_value = self.xl;
|
|
||||||
let mut xl = cs.alloc(|| "preimage xl", || {
|
|
||||||
xl_value.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Allocate the second component of the preimage.
|
|
||||||
let mut xr_value = self.xr;
|
|
||||||
let mut xr = cs.alloc(|| "preimage xr", || {
|
|
||||||
xr_value.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
for i in 0..MIMC_ROUNDS {
|
|
||||||
// xL, xR := xR + (xL + Ci)^3, xL
|
|
||||||
let cs = &mut cs.namespace(|| format!("round {}", i));
|
|
||||||
|
|
||||||
// tmp = (xL + Ci)^2
|
|
||||||
let mut tmp_value = xl_value.map(|mut e| {
|
|
||||||
e.add_assign(&self.constants[i]);
|
|
||||||
e.square();
|
|
||||||
e
|
|
||||||
});
|
|
||||||
let mut tmp = cs.alloc(|| "tmp", || {
|
|
||||||
tmp_value.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
cs.enforce(
|
|
||||||
|| "tmp = (xL + Ci)^2",
|
|
||||||
|lc| lc + xl + (self.constants[i], CS::one()),
|
|
||||||
|lc| lc + xl + (self.constants[i], CS::one()),
|
|
||||||
|lc| lc + tmp
|
|
||||||
);
|
|
||||||
|
|
||||||
// new_xL = xR + (xL + Ci)^3
|
|
||||||
// new_xL = xR + tmp * (xL + Ci)
|
|
||||||
// new_xL - xR = tmp * (xL + Ci)
|
|
||||||
let mut new_xl_value = xl_value.map(|mut e| {
|
|
||||||
e.add_assign(&self.constants[i]);
|
|
||||||
e.mul_assign(&tmp_value.unwrap());
|
|
||||||
e.add_assign(&xr_value.unwrap());
|
|
||||||
e
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut new_xl = if i == (MIMC_ROUNDS-1) {
|
|
||||||
// This is the last round, xL is our image and so
|
|
||||||
// we use the image
|
|
||||||
let image_value = self.image;
|
|
||||||
cs.alloc(|| "image", || {
|
|
||||||
image_value.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})?
|
|
||||||
} else {
|
|
||||||
cs.alloc(|| "new_xl", || {
|
|
||||||
new_xl_value.ok_or(SynthesisError::AssignmentMissing)
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
|
|
||||||
cs.enforce(
|
|
||||||
|| "new_xL = xR + (xL + Ci)^3",
|
|
||||||
|lc| lc + tmp,
|
|
||||||
|lc| lc + xl + (self.constants[i], CS::one()),
|
|
||||||
|lc| lc + new_xl - xr
|
|
||||||
);
|
|
||||||
|
|
||||||
// xR = xL
|
|
||||||
xr = xl;
|
|
||||||
xr_value = xl_value;
|
|
||||||
|
|
||||||
// xL = new_xL
|
|
||||||
xl = new_xl;
|
|
||||||
xl_value = new_xl_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_sonic_mimc() {
|
|
||||||
use pairing::ff::{Field, PrimeField};
|
|
||||||
use pairing::{Engine, CurveAffine, CurveProjective};
|
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
|
||||||
use std::time::{Instant};
|
|
||||||
use bellman::sonic::srs::SRS;
|
|
||||||
|
|
||||||
let srs_x = Fr::from_str("23923").unwrap();
|
|
||||||
let srs_alpha = Fr::from_str("23728792").unwrap();
|
|
||||||
println!("making srs");
|
|
||||||
let start = Instant::now();
|
|
||||||
let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
{
|
|
||||||
// This may not be cryptographically safe, use
|
|
||||||
// `OsRng` (for example) in production software.
|
|
||||||
let rng = &mut thread_rng();
|
|
||||||
|
|
||||||
// Generate the MiMC round constants
|
|
||||||
let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::<Vec<_>>();
|
|
||||||
let samples: usize = 100;
|
|
||||||
|
|
||||||
let xl = rng.gen();
|
|
||||||
let xr = rng.gen();
|
|
||||||
let image = mimc::<Bls12>(xl, xr, &constants);
|
|
||||||
|
|
||||||
// Create an instance of our circuit (with the
|
|
||||||
// witness)
|
|
||||||
let circuit = MiMCDemoNoInputs {
|
|
||||||
xl: Some(xl),
|
|
||||||
xr: Some(xr),
|
|
||||||
image: Some(image),
|
|
||||||
constants: &constants
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::sonic::cs::Basic;
|
|
||||||
use bellman::sonic::sonic::AdaptorCircuit;
|
|
||||||
use bellman::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs};
|
|
||||||
use bellman::sonic::helped::{MultiVerifier, get_circuit_parameters};
|
|
||||||
use bellman::sonic::helped::helper::{create_aggregate_on_srs};
|
|
||||||
|
|
||||||
println!("creating proof");
|
|
||||||
let start = Instant::now();
|
|
||||||
let proof = create_proof_on_srs::<Bls12, _, Basic>(&AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
println!("creating advice");
|
|
||||||
let start = Instant::now();
|
|
||||||
let advice = create_advice_on_srs::<Bls12, _, Basic>(&AdaptorCircuit(circuit.clone()), &proof, &srs).unwrap();
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
println!("creating aggregate for {} proofs", samples);
|
|
||||||
let start = Instant::now();
|
|
||||||
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
|
||||||
let aggregate = create_aggregate_on_srs::<Bls12, _, Basic>(&AdaptorCircuit(circuit.clone()), &proofs, &srs);
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
{
|
|
||||||
let rng = thread_rng();
|
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
|
||||||
println!("verifying 1 proof without advice");
|
|
||||||
let start = Instant::now();
|
|
||||||
{
|
|
||||||
for _ in 0..1 {
|
|
||||||
verifier.add_proof(&proof, &[], |_, _| None);
|
|
||||||
}
|
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
|
||||||
}
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let rng = thread_rng();
|
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
|
||||||
println!("verifying {} proofs without advice", samples);
|
|
||||||
let start = Instant::now();
|
|
||||||
{
|
|
||||||
for _ in 0..samples {
|
|
||||||
verifier.add_proof(&proof, &[], |_, _| None);
|
|
||||||
}
|
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
|
||||||
}
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let rng = thread_rng();
|
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
|
||||||
println!("verifying 100 proofs with advice");
|
|
||||||
let start = Instant::now();
|
|
||||||
{
|
|
||||||
for (ref proof, ref advice) in &proofs {
|
|
||||||
verifier.add_proof_with_advice(proof, &[], advice);
|
|
||||||
}
|
|
||||||
verifier.add_aggregate(&proofs, &aggregate);
|
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
|
||||||
}
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_inputs_into_sonic_mimc() {
|
|
||||||
use pairing::ff::{Field, PrimeField};
|
|
||||||
use pairing::{Engine, CurveAffine, CurveProjective};
|
|
||||||
use pairing::bn256::{Bn256, Fr};
|
|
||||||
// use pairing::bls12_381::{Bls12, Fr};
|
|
||||||
use std::time::{Instant};
|
|
||||||
use bellman::sonic::srs::SRS;
|
|
||||||
|
|
||||||
let srs_x = Fr::from_str("23923").unwrap();
|
|
||||||
let srs_alpha = Fr::from_str("23728792").unwrap();
|
|
||||||
println!("making srs");
|
|
||||||
let start = Instant::now();
|
|
||||||
let srs = SRS::<Bn256>::dummy(830564, srs_x, srs_alpha);
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
{
|
|
||||||
// This may not be cryptographically safe, use
|
|
||||||
// `OsRng` (for example) in production software.
|
|
||||||
let rng = &mut thread_rng();
|
|
||||||
|
|
||||||
// Generate the MiMC round constants
|
|
||||||
let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::<Vec<_>>();
|
|
||||||
let samples: usize = 100;
|
|
||||||
|
|
||||||
let xl = rng.gen();
|
|
||||||
let xr = rng.gen();
|
|
||||||
let image = mimc::<Bn256>(xl, xr, &constants);
|
|
||||||
|
|
||||||
// Create an instance of our circuit (with the
|
|
||||||
// witness)
|
|
||||||
let circuit = MiMCDemo {
|
|
||||||
xl: Some(xl),
|
|
||||||
xr: Some(xr),
|
|
||||||
constants: &constants
|
|
||||||
};
|
|
||||||
|
|
||||||
use bellman::sonic::cs::Basic;
|
|
||||||
use bellman::sonic::sonic::AdaptorCircuit;
|
|
||||||
use bellman::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs};
|
|
||||||
use bellman::sonic::helped::{MultiVerifier, get_circuit_parameters};
|
|
||||||
use bellman::sonic::helped::helper::{create_aggregate_on_srs};
|
|
||||||
|
|
||||||
let info = get_circuit_parameters::<Bn256, _>(circuit.clone()).expect("Must get circuit info");
|
|
||||||
println!("{:?}", info);
|
|
||||||
|
|
||||||
println!("creating proof");
|
|
||||||
let start = Instant::now();
|
|
||||||
let proof = create_proof_on_srs::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
println!("creating advice");
|
|
||||||
let start = Instant::now();
|
|
||||||
let advice = create_advice_on_srs::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &proof, &srs).unwrap();
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
println!("creating aggregate for {} proofs", samples);
|
|
||||||
let start = Instant::now();
|
|
||||||
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
|
||||||
let aggregate = create_aggregate_on_srs::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &proofs, &srs);
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
{
|
|
||||||
let rng = thread_rng();
|
|
||||||
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
|
||||||
println!("verifying 1 proof without advice");
|
|
||||||
let start = Instant::now();
|
|
||||||
{
|
|
||||||
for _ in 0..1 {
|
|
||||||
verifier.add_proof(&proof, &[image], |_, _| None);
|
|
||||||
}
|
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
|
||||||
}
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let rng = thread_rng();
|
|
||||||
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
|
||||||
println!("verifying {} proofs without advice", samples);
|
|
||||||
let start = Instant::now();
|
|
||||||
{
|
|
||||||
for _ in 0..samples {
|
|
||||||
verifier.add_proof(&proof, &[image], |_, _| None);
|
|
||||||
}
|
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
|
||||||
}
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let rng = thread_rng();
|
|
||||||
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
|
||||||
println!("verifying 100 proofs with advice and aggregate");
|
|
||||||
let start = Instant::now();
|
|
||||||
{
|
|
||||||
for (ref proof, ref advice) in &proofs {
|
|
||||||
verifier.add_proof_with_advice(proof, &[image], advice);
|
|
||||||
}
|
|
||||||
verifier.add_aggregate(&proofs, &aggregate);
|
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
|
||||||
}
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_high_level_sonic_api() {
|
|
||||||
use pairing::bn256::{Bn256};
|
|
||||||
use std::time::{Instant};
|
|
||||||
use bellman::sonic::helped::{
|
|
||||||
generate_random_parameters,
|
|
||||||
verify_aggregate,
|
|
||||||
verify_proofs,
|
|
||||||
create_proof,
|
|
||||||
create_advice,
|
|
||||||
create_aggregate,
|
|
||||||
get_circuit_parameters
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
// This may not be cryptographically safe, use
|
|
||||||
// `OsRng` (for example) in production software.
|
|
||||||
let mut rng = &mut thread_rng();
|
|
||||||
|
|
||||||
// Generate the MiMC round constants
|
|
||||||
let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::<Vec<_>>();
|
|
||||||
let samples: usize = 100;
|
|
||||||
|
|
||||||
let xl = rng.gen();
|
|
||||||
let xr = rng.gen();
|
|
||||||
let image = mimc::<Bn256>(xl, xr, &constants);
|
|
||||||
|
|
||||||
// Create an instance of our circuit (with the
|
|
||||||
// witness)
|
|
||||||
let circuit = MiMCDemo {
|
|
||||||
xl: Some(xl),
|
|
||||||
xr: Some(xr),
|
|
||||||
constants: &constants
|
|
||||||
};
|
|
||||||
|
|
||||||
let info = get_circuit_parameters::<Bn256, _>(circuit.clone()).expect("Must get circuit info");
|
|
||||||
println!("{:?}", info);
|
|
||||||
|
|
||||||
let params = generate_random_parameters(circuit.clone(), &mut rng).unwrap();
|
|
||||||
|
|
||||||
println!("creating proof");
|
|
||||||
let start = Instant::now();
|
|
||||||
let proof = create_proof(circuit.clone(), ¶ms).unwrap();
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
println!("creating advice");
|
|
||||||
let start = Instant::now();
|
|
||||||
let advice = create_advice(circuit.clone(), &proof, ¶ms).unwrap();
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
println!("creating aggregate for {} proofs", samples);
|
|
||||||
let start = Instant::now();
|
|
||||||
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
|
||||||
|
|
||||||
let aggregate = create_aggregate::<Bn256, _>(circuit.clone(), &proofs, ¶ms);
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
|
|
||||||
{
|
|
||||||
println!("verifying 1 proof without advice");
|
|
||||||
let rng = thread_rng();
|
|
||||||
let start = Instant::now();
|
|
||||||
assert_eq!(verify_proofs(&vec![proof.clone()], &vec![vec![image.clone()]], circuit.clone(), rng, ¶ms).unwrap(), true);
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
println!("verifying {} proofs without advice", samples);
|
|
||||||
let rng = thread_rng();
|
|
||||||
let start = Instant::now();
|
|
||||||
assert_eq!(verify_proofs(&vec![proof.clone(); 100], &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), true);
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
println!("verifying 100 proofs with advice and aggregate");
|
|
||||||
let rng = thread_rng();
|
|
||||||
let start = Instant::now();
|
|
||||||
assert_eq!(verify_aggregate(&vec![(proof.clone(), advice.clone()); 100], &aggregate, &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), true);
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user