use rand::thread_rng;
use std::time::{Duration, Instant};
use ff::Field;
use bls12_381::{Bls12, Scalar};
use bellman::groth16::{
batch, create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
Proof,
};
mod common;
use common::*;
#[test]
fn test_mimc() {
let mut rng = thread_rng();
let constants = (0..MIMC_ROUNDS)
.map(|_| Scalar::random(&mut rng))
.collect::<Vec<_>>();
println!("Creating parameters...");
let params = {
let c = MiMCDemo {
xl: None,
xr: None,
constants: &constants,
};
generate_random_parameters::<Bls12, _, _>(c, &mut rng).unwrap()
};
let pvk = prepare_verifying_key(¶ms.vk);
println!("Creating proofs...");
const SAMPLES: u32 = 50;
let mut total_proving = Duration::new(0, 0);
let mut total_verifying = Duration::new(0, 0);
let mut proof_vec = vec![];
for _ in 0..SAMPLES {
let xl = Scalar::random(&mut rng);
let xr = Scalar::random(&mut rng);
let image = mimc(xl, xr, &constants);
proof_vec.truncate(0);
let start = Instant::now();
{
let c = MiMCDemo {
xl: Some(xl),
xr: Some(xr),
constants: &constants,
};
let proof = create_random_proof(c, ¶ms, &mut rng).unwrap();
proof.write(&mut proof_vec).unwrap();
}
total_proving += start.elapsed();
let start = Instant::now();
let proof = Proof::read(&proof_vec[..]).unwrap();
assert!(verify_proof(&pvk, &proof, &[image]).is_ok());
total_verifying += start.elapsed();
}
let proving_avg = total_proving / SAMPLES;
let proving_avg =
proving_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (proving_avg.as_secs() as f64);
let verifying_avg = total_verifying / SAMPLES;
let verifying_avg =
verifying_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (verifying_avg.as_secs() as f64);
println!("Average proving time: {:?} seconds", proving_avg);
println!("Average verifying time: {:?} seconds", verifying_avg);
}
#[test]
fn batch_verify() {
let mut rng = thread_rng();
let mut batch = batch::Verifier::new();
let constants = (0..MIMC_ROUNDS)
.map(|_| Scalar::random(&mut rng))
.collect::<Vec<_>>();
println!("Creating parameters...");
let params = {
let c = MiMCDemo {
xl: None,
xr: None,
constants: &constants,
};
generate_random_parameters::<Bls12, _, _>(c, &mut rng).unwrap()
};
let pvk = prepare_verifying_key(¶ms.vk);
println!("Creating proofs...");
const SAMPLES: u32 = 50;
let mut total_proving = Duration::new(0, 0);
let mut total_verifying = Duration::new(0, 0);
let mut proof_vec = vec![];
for _ in 0..SAMPLES {
let xl = Scalar::random(&mut rng);
let xr = Scalar::random(&mut rng);
let image = mimc(xl, xr, &constants);
proof_vec.truncate(0);
let start = Instant::now();
{
let c = MiMCDemo {
xl: Some(xl),
xr: Some(xr),
constants: &constants,
};
let proof = create_random_proof(c, ¶ms, &mut rng).unwrap();
proof.write(&mut proof_vec).unwrap();
}
total_proving += start.elapsed();
let start = Instant::now();
let proof = Proof::read(&proof_vec[..]).unwrap();
assert!(verify_proof(&pvk, &proof, &[image]).is_ok());
total_verifying += start.elapsed();
batch.queue((proof, [image].into()));
}
let mut batch_verifying = Duration::new(0, 0);
let batch_start = Instant::now();
assert!(batch.verify(rng, ¶ms.vk).is_ok());
batch_verifying += batch_start.elapsed();
let proving_avg = total_proving / SAMPLES;
let proving_avg =
proving_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (proving_avg.as_secs() as f64);
let verifying_avg = total_verifying / SAMPLES;
let verifying_avg =
verifying_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (verifying_avg.as_secs() as f64);
let batch_amortized = batch_verifying / SAMPLES;
let batch_amortized = batch_amortized.subsec_nanos() as f64 / 1_000_000_000f64
+ (batch_amortized.as_secs() as f64);
println!("Average proving time: {:?} seconds", proving_avg);
println!("Average verifying time: {:?} seconds", verifying_avg);
println!(
"Amortized batch verifying time: {:?} seconds",
batch_amortized
);
}