diff --git a/Cargo.toml b/Cargo.toml index 0085f48..54d2477 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,10 +64,14 @@ zip32 = "0.1" [dev-dependencies] chacha20poly1305 = "0.10" +criterion = "0.4" incrementalmerkletree = { version = "0.5", features = ["legacy-api", "test-dependencies"] } proptest = "1" rand_xorshift = "0.3" +[target.'cfg(unix)'.dev-dependencies] +pprof = { version = "0.11", features = ["criterion", "flamegraph"] } # MSRV 1.56 + [features] multicore = ["bellman/multicore"] test-dependencies = [ diff --git a/examples/bench.rs b/examples/bench.rs index 4b7a707..caa1db0 100644 --- a/examples/bench.rs +++ b/examples/bench.rs @@ -1,102 +1,105 @@ -extern crate sapling_crypto; -extern crate bellman; -extern crate rand; -extern crate pairing; +#[macro_use] +extern crate criterion; -use std::time::{Duration, Instant}; -use sapling_crypto::jubjub::{ - JubjubBls12, - edwards, - fs, -}; -use sapling_crypto::circuit::sapling::{ - Spend -}; -use sapling_crypto::primitives::{ - Diversifier, - ProofGenerationKey, - ValueCommitment -}; use bellman::groth16::*; -use rand::{XorShiftRng, SeedableRng, Rng}; -use pairing::bls12_381::{Bls12, Fr}; +use bls12_381::Bls12; +use criterion::Criterion; +use group::ff::Field; +use rand::{Rng, RngCore, SeedableRng}; +use rand_xorshift::XorShiftRng; +use sapling_crypto::{ + circuit::{Spend, ValueCommitmentOpening}, + keys::ExpandedSpendingKey, + value::NoteValue, + Diversifier, +}; + +#[cfg(unix)] +use pprof::criterion::{Output, PProfProfiler}; const TREE_DEPTH: usize = 32; -fn main() { - let jubjub_params = &JubjubBls12::new(); - let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); +fn criterion_benchmark(c: &mut Criterion) { + let mut rng = XorShiftRng::from_seed([ + 0x59, 0x62, 0xbe, 0x3d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, + 0xe5, + ]); - println!("Creating sample parameters..."); let groth_params = generate_random_parameters::( Spend { - params: jubjub_params, - value_commitment: None, + value_commitment_opening: None, proof_generation_key: None, payment_address: None, commitment_randomness: None, ar: None, auth_path: vec![None; TREE_DEPTH], - anchor: None + anchor: None, }, - rng - ).unwrap(); + &mut rng, + ) + .unwrap(); - const SAMPLES: u32 = 50; - - let mut total_time = Duration::new(0, 0); - for _ in 0..SAMPLES { - let value_commitment = ValueCommitment { - value: 1, - randomness: rng.gen() + c.bench_function("sapling-spend-prove", |b| { + let value_commitment = ValueCommitmentOpening { + value: NoteValue::from_raw(1), + randomness: jubjub::Fr::random(&mut rng), }; - let nsk: fs::Fs = rng.gen(); - let ak = edwards::Point::rand(rng, jubjub_params).mul_by_cofactor(jubjub_params); + let sk: [u8; 32] = rng.gen(); + let expsk = ExpandedSpendingKey::from_spending_key(&sk); - let proof_generation_key = ProofGenerationKey { - ak: ak.clone(), - nsk: nsk.clone() - }; + let proof_generation_key = expsk.proof_generation_key(); - let viewing_key = proof_generation_key.into_viewing_key(jubjub_params); + let viewing_key = proof_generation_key.to_viewing_key(); - let payment_address; + let payment_address = loop { + let diversifier = { + let mut d = [0; 11]; + rng.fill_bytes(&mut d); + Diversifier(d) + }; - loop { - let diversifier = Diversifier(rng.gen()); - - if let Some(p) = viewing_key.into_payment_address( - diversifier, - jubjub_params - ) - { - payment_address = p; - break; + if let Some(p) = viewing_key.to_payment_address(diversifier) { + break p; } - } + }; - let commitment_randomness: fs::Fs = rng.gen(); - let auth_path = vec![Some((rng.gen(), rng.gen())); TREE_DEPTH]; - let ar: fs::Fs = rng.gen(); - let anchor: Fr = rng.gen(); + let commitment_randomness = jubjub::Fr::random(&mut rng); + let auth_path = + vec![Some((bls12_381::Scalar::random(&mut rng), rng.next_u32() % 2 != 0)); TREE_DEPTH]; + let ar = jubjub::Fr::random(&mut rng); + let anchor = bls12_381::Scalar::random(&mut rng); - let start = Instant::now(); - let _ = create_random_proof(Spend { - params: jubjub_params, - value_commitment: Some(value_commitment), - proof_generation_key: Some(proof_generation_key), - payment_address: Some(payment_address), - commitment_randomness: Some(commitment_randomness), - ar: Some(ar), - auth_path: auth_path, - anchor: Some(anchor) - }, &groth_params, rng).unwrap(); - total_time += start.elapsed(); - } - let avg = total_time / SAMPLES; - let avg = avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (avg.as_secs() as f64); - - println!("Average proving time (in seconds): {}", avg); + b.iter(|| { + create_random_proof( + Spend { + value_commitment_opening: Some(value_commitment.clone()), + proof_generation_key: Some(proof_generation_key.clone()), + payment_address: Some(payment_address), + commitment_randomness: Some(commitment_randomness), + ar: Some(ar), + auth_path: auth_path.clone(), + anchor: Some(anchor), + }, + &groth_params, + &mut rng, + ) + }); + }); } + +#[cfg(unix)] +criterion_group! { + name = benches; + config = Criterion::default() + .sample_size(10) + .with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); + targets = criterion_benchmark +} +#[cfg(windows)] +criterion_group! { + name = benches; + config = Criterion::default().sample_size(10); + targets = criterion_benchmark +} +criterion_main!(benches);