diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1aab984 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +table1a: + N=128 cargo bench --bench veceq + N=1024 cargo bench --bench veceq + N=8192 cargo bench --bench veceq + N=128 cargo bench --bench nonzero + N=1024 cargo bench --bench nonzero + N=8192 cargo bench --bench nonzero + N=128 cargo bench --bench lderivative + N=1024 cargo bench --bench lderivative + N=8192 cargo bench --bench lderivative + N=128 cargo bench --bench ipa + N=1024 cargo bench --bench ipa + N=8192 cargo bench --bench ipa + +table1b: + M=32 N=128 cargo bench --bench auctioneer_r1 + M=32 N=1024 cargo bench --bench auctioneer_r1 + M=32 N=8192 cargo bench --bench auctioneer_r1 + M=128 N=128 cargo bench --bench auctioneer_r1 + M=128 N=1024 cargo bench --bench auctioneer_r1 + M=128 N=8192 cargo bench --bench auctioneer_r1 + M=256 N=128 cargo bench --bench auctioneer_r1 + M=256 N=1024 cargo bench --bench auctioneer_r1 + M=256 N=8192 cargo bench --bench auctioneer_r1 + +table1c: + M=32 N=128 cargo bench --bench auctioneer_r2 + M=32 N=1024 cargo bench --bench auctioneer_r2 + M=32 N=8192 cargo bench --bench auctioneer_r2 + M=128 N=128 cargo bench --bench auctioneer_r2 + M=128 N=1024 cargo bench --bench auctioneer_r2 + M=128 N=8192 cargo bench --bench auctioneer_r2 + M=256 N=128 cargo bench --bench auctioneer_r2 + M=256 N=1024 cargo bench --bench auctioneer_r2 + M=256 N=8192 cargo bench --bench auctioneer_r2 \ No newline at end of file diff --git a/README.md b/README.md index 562fd53..5cb9fb0 100644 --- a/README.md +++ b/README.md @@ -10,41 +10,67 @@ To setup Rust, please follow the [official installation instructions](https://ww ## Benchmarks -There are six microbenchmarks, namely for the computation of the four validity proofs, the AV protocol, and the results vector: - -- **Benchmark 1: Validity proof $\pi_{x_i}$ (Table 1a)** - ``` - cargo bench --bench veceq - ``` - -- **Benchmark 2: Validity proof $\pi_{r_i}$ (Table 1a)** - ``` - cargo bench --bench nonzero - ``` - -- **Benchmark 3: Validity proof $\pi_{b_i}$ (Table 1a)** - ``` - cargo bench --bench lderivative - ``` - -- **Benchmark 4: Validity proof $\pi_{Z_i}$ (Table 1a)** - ``` - cargo bench --bench ipa - ``` - -- **Benchmark 5: AV matrix $Y$ (Table 1b)** - ``` - cargo bench --bench auctioneer_r1 - ``` - -- **Benchmark 6: Results vector $R$ (Table 1c)** - ``` - cargo bench --bench auctioneer_r2 - ``` - - - - - - - +There are six different microbenchmarks in total, namely for the computation of the four validity proofs, the AV protocol, and the results vector. +To reproduce the benchmarks presented in Table 1, simply execute: + +``` +make table1a +make table1b +make table1c +``` + +For more fine-grained benchmarking, consider the following instructions. + +**Benchmark 1: Validity proof $\pi_{x_i}$ (Table 1a)** +``` +N=128 cargo bench --bench veceq +N=1024 cargo bench --bench veceq +N=8192 cargo bench --bench veceq +``` + +**Benchmark 2: Validity proof $\pi_{r_i}$ (Table 1a)** +``` +N=128 cargo bench --bench nonzero +N=1024 cargo bench --bench nonzero +N=8192 cargo bench --bench nonzero +``` + +**Benchmark 3: Validity proof $\pi_{b_i}$ (Table 1a)** +``` +N=128 cargo bench --bench lderivative +N=1024 cargo bench --bench lderivative +N=8192 cargo bench --bench lderivative +``` + +**Benchmark 4: Validity proof $\pi_{Z_i}$ (Table 1a)** +``` +N=128 cargo bench --bench ipa +N=1024 cargo bench --bench ipa +N=8192 cargo bench --bench ipa +``` + +**Benchmark 5: AV matrix $Y$ (Table 1b)** +``` +M=32 N=128 cargo bench --bench auctioneer_r1 +M=32 N=1024 cargo bench --bench auctioneer_r1 +M=32 N=8192 cargo bench --bench auctioneer_r1 +M=128 N=128 cargo bench --bench auctioneer_r1 +M=128 N=1024 cargo bench --bench auctioneer_r1 +M=128 N=8192 cargo bench --bench auctioneer_r1 +M=256 N=128 cargo bench --bench auctioneer_r1 +M=256 N=1024 cargo bench --bench auctioneer_r1 +M=256 N=8192 cargo bench --bench auctioneer_r1 +``` + +**Benchmark 6: Results vector $R$ (Table 1c)** +``` +M=32 N=128 cargo bench --bench auctioneer_r2 +M=32 N=1024 cargo bench --bench auctioneer_r2 +M=32 N=8192 cargo bench --bench auctioneer_r2 +M=128 N=128 cargo bench --bench auctioneer_r2 +M=128 N=1024 cargo bench --bench auctioneer_r2 +M=128 N=8192 cargo bench --bench auctioneer_r2 +M=256 N=128 cargo bench --bench auctioneer_r2 +M=256 N=1024 cargo bench --bench auctioneer_r2 +M=256 N=8192 cargo bench --bench auctioneer_r2 +``` \ No newline at end of file diff --git a/benches/auctioneer_r1.rs b/benches/auctioneer_r1.rs index 6b593fe..ca0cf26 100644 --- a/benches/auctioneer_r1.rs +++ b/benches/auctioneer_r1.rs @@ -6,8 +6,9 @@ use ark_ff::Zero; use ark_std::{test_rng, UniformRand}; use cipher_bazaar::auctioneer::Auctioneer; use criterion::{criterion_group, criterion_main, Criterion}; +use std::env; -/* RUN WITH: cargo bench --bench auctioneer_r1 */ +/* RUN WITH: M=32 N=128 cargo bench --bench auctioneer_r1 */ fn setup_round_1() -> Auctioneer { let mut rng = test_rng(); @@ -39,59 +40,6 @@ fn setup_round_1() -> Auctioneer() -> Auctioneer { - let mut rng = test_rng(); - let g = G1Projective::generator(); - - let mut a = Auctioneer::::new(); - let mut secrets = vec![vec![F::zero(); N]; B]; - let mut first_msgs = vec![vec![G1Affine::zero(); N]; B]; - - // initialize n msgs fro each party - for i in 0..B { - for j in 0..N { - secrets[i][j] = F::rand(&mut rng); - } - } - - // initialize n msgs fro each party - for i in 0..B { - for j in 0..N { - first_msgs[i][j] = g.mul(secrets[i][j]).into(); - } - } - - // each party sends it's first round msgs - for i in 0..B { - a.register_msgs(&first_msgs[i], i).unwrap(); - } - - // we get output for each party per round - // where each row is of len B (output of av for each party) - let fr_result = a.output_first_round(); - - let mut second_msgs = vec![vec![G1Affine::zero(); N]; B]; - for i in 0..B { - for j in 0..N { - second_msgs[i][j] = fr_result[j][i].mul(secrets[i][j]).into(); - } - } - - // each party sends it's second round msgs - for i in 0..B { - a.register_msgs(&second_msgs[i], i).unwrap(); - } - - a -} - -fn bench_second_round( - a: Auctioneer, -) -> Vec { - let mut a_clone = a.clone(); - a_clone.output_second_round() -} - fn bench_first_round( a: Auctioneer, ) -> Vec> { @@ -99,27 +47,37 @@ fn bench_first_round( a_clone.output_first_round() } -fn round_1(c: &mut Criterion) { - const N: usize = 8192; - const B: usize = 256; - - let a = setup_round_1::(); - let id = format!("Round1: range = {}, bidders = {}", N, B); +fn round_1(c: &mut Criterion) { + let a = setup_round_1::(); + let id = format!("Round1: range = {}, bidders = {}", N, M); c.bench_function(&id, |b| b.iter(|| bench_first_round(a.clone()))); } -fn round_2(c: &mut Criterion) { - const N: usize = 32; - const B: usize = 32; - - let a = setup_round_2::(); - let id = format!("Round2: range = {}, bidders = {}", N, B); - c.bench_function(&id, |b| b.iter(|| bench_second_round(a.clone()))); -} - fn criterion_benchmark(c: &mut Criterion) { - round_1(c); - // round_2(c); + // bidders + let m: usize = env::var("M") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(32); // default value + + // range + let n: usize = env::var("N") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(128); // default value + + match (m, n) { + (32, 128) => round_1::<32, 128>(c), + (32, 1024) => round_1::<32, 1024>(c), + (32, 8192) => round_1::<32, 8192>(c), + (128, 128) => round_1::<128, 128>(c), + (128, 1024) => round_1::<128, 1024>(c), + (128, 8192) => round_1::<128, 8192>(c), + (256, 128) => round_1::<256, 128>(c), + (256, 1024) => round_1::<256, 1024>(c), + (256, 8192) => round_1::<256, 8192>(c), + _ => panic!("Unsupported parameter combination (M, N): ({}, {})", m, n), + } } criterion_group!(benches, criterion_benchmark); diff --git a/benches/auctioneer_r2.rs b/benches/auctioneer_r2.rs index 6e04b35..80b7778 100644 --- a/benches/auctioneer_r2.rs +++ b/benches/auctioneer_r2.rs @@ -6,38 +6,9 @@ use ark_ff::Zero; use ark_std::{test_rng, UniformRand}; use cipher_bazaar::auctioneer::Auctioneer; use criterion::{criterion_group, criterion_main, Criterion}; +use std::env; -/* RUN WITH: cargo bench --bench auctioneer_r2 */ - -fn setup_round_1() -> Auctioneer { - let mut rng = test_rng(); - let g = G1Projective::generator(); - - let mut a = Auctioneer::::new(); - let mut secrets = vec![vec![F::zero(); N]; B]; - let mut first_msgs = vec![vec![G1Affine::zero(); N]; B]; - - // initialize n msgs fro each party - for i in 0..B { - for j in 0..N { - secrets[i][j] = F::rand(&mut rng); - } - } - - // initialize n msgs fro each party - for i in 0..B { - for j in 0..N { - first_msgs[i][j] = g.mul(secrets[i][j]).into(); - } - } - - // each party sends it's first round msgs - for i in 0..B { - a.register_msgs(&first_msgs[i], i).unwrap(); - } - - a -} +/* RUN WITH: M=32 N=1024 cargo bench --bench auctioneer_r2 */ fn setup_round_2() -> Auctioneer { let mut rng = test_rng(); @@ -92,34 +63,37 @@ fn bench_second_round( a_clone.output_second_round() } -fn bench_first_round( - a: Auctioneer, -) -> Vec> { - let mut a_clone = a.clone(); - a_clone.output_first_round() -} - -fn round_1(c: &mut Criterion) { - const N: usize = 8192; - const B: usize = 256; - - let a = setup_round_1::(); - let id = format!("Round1: range = {}, bidders = {}", N, B); - c.bench_function(&id, |b| b.iter(|| bench_first_round(a.clone()))); -} - -fn round_2(c: &mut Criterion) { - const N: usize = 8192; - const B: usize = 256; - - let a = setup_round_2::(); - let id = format!("Round2: range = {}, bidders = {}", N, B); +fn round_2(c: &mut Criterion) { + let a = setup_round_2::(); + let id = format!("Round2: range = {}, bidders = {}", N, M); c.bench_function(&id, |b| b.iter(|| bench_second_round(a.clone()))); } fn criterion_benchmark(c: &mut Criterion) { - // round_1(c); - round_2(c); + // bidders + let m: usize = env::var("M") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(32); // default value + + // range + let n: usize = env::var("N") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(128); // default value + + match (m, n) { + (32, 128) => round_2::<32, 128>(c), + (32, 1024) => round_2::<32, 1024>(c), + (32, 8192) => round_2::<32, 8192>(c), + (128, 128) => round_2::<128, 128>(c), + (128, 1024) => round_2::<128, 1024>(c), + (128, 8192) => round_2::<128, 8192>(c), + (256, 128) => round_2::<256, 128>(c), + (256, 1024) => round_2::<256, 1024>(c), + (256, 8192) => round_2::<256, 8192>(c), + _ => panic!("Unsupported parameter combination (M, N): ({}, {})", m, n), + } } criterion_group!(benches, criterion_benchmark); diff --git a/benches/ipa.rs b/benches/ipa.rs index 02dc5fe..90ab3b8 100644 --- a/benches/ipa.rs +++ b/benches/ipa.rs @@ -14,13 +14,11 @@ use cipher_bazaar::{ utils::srs::unsafe_setup_from_tau, }; use criterion::{criterion_group, criterion_main, Criterion}; +use std::env; -/* RUN WITH: cargo bench --bench ipa */ +/* RUN WITH: N={128,1024,8192} cargo bench --bench ipa */ -const N: usize = 8192; -const LOG_N: usize = 13; - -fn prove( +fn prove( instance: &Instance, witness: &Witness, pk: &PK, @@ -30,6 +28,20 @@ fn prove( } fn criterion_benchmark(criterion: &mut Criterion) { + let n: usize = env::var("N") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(128); // default value + + match n { + 128 => run::<128, 7>(criterion), + 1024 => run::<1024, 10>(criterion), + 8192 => run::<8192, 13>(criterion), + _ => panic!("Unsupported price range N"), + } +} + +fn run(criterion: &mut Criterion) { let mut rng = ark_std::test_rng(); let domain = GeneralEvaluationDomain::::new(N).unwrap(); @@ -66,9 +78,9 @@ fn criterion_benchmark(criterion: &mut Criterion) { a: a.try_into().unwrap(), }; - let id = format!("proof {}", N); + let id = format!(r"proof \pi_{{Z_i}} N={}", N); criterion.bench_function(&id, |b| { - b.iter(|| prove::(&instance, &witness, &pk, &mut rng)) + b.iter(|| prove::(&instance, &witness, &pk, &mut rng)) }); } diff --git a/benches/lderivative.rs b/benches/lderivative.rs index 6014e39..568679c 100644 --- a/benches/lderivative.rs +++ b/benches/lderivative.rs @@ -1,12 +1,10 @@ -use std::ops::Mul; - -use cipher_bazaar::kzg::{Kzg, PK, VK}; -use ark_ec::{pairing::Pairing, Group}; +use cipher_bazaar::kzg::{Kzg, PK}; +use ark_ec::{pairing::Pairing}; use ark_ff::{One, Zero}; use ark_poly::{ univariate::DensePolynomial, DenseUVPolynomial, EvaluationDomain, GeneralEvaluationDomain }; -use ark_bn254::{Bn254, Fr as F, G1Projective, G2Projective}; +use ark_bn254::{Bn254, Fr as F, G1Projective}; use cipher_bazaar::{ zk_log_derivative::{ structs::{Instance, Witness, ProverIndex, VerifierIndex}, @@ -15,10 +13,10 @@ use cipher_bazaar::{ utils::srs::unsafe_setup_from_tau, }; use criterion::{criterion_group, criterion_main, Criterion}; +use std::env; -/* RUN WITH: cargo bench --bench lderivative */ +/* RUN WITH: N={128,1024,8192} cargo bench --bench lderivative */ -const N: usize = 8192; const B: usize = 1; fn prove( @@ -32,43 +30,39 @@ fn prove( } fn criterion_benchmark(criterion: &mut Criterion) { - let domain = GeneralEvaluationDomain::::new(N).unwrap(); + let n: usize = env::var("N") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(128); // default value + + match n { + 128 => run::<128>(criterion), + 1024 => run::<1024>(criterion), + 8192 => run::<8192>(criterion), + _ => panic!("Unsupported price range N"), + } +} +fn run(criterion: &mut Criterion) { + let domain = GeneralEvaluationDomain::::new(N).unwrap(); let tau = F::from(17u64); let srs = unsafe_setup_from_tau::(N - 1, tau); - let x_g2 = G2Projective::generator().mul(tau); - let pk = PK:: { srs: srs.clone() }; - let vk = VK::::new(x_g2); - let index_v = Argument::::index_v(&pk); let index_p = Argument::::index_p(); // let's make f such that it has just one 1 and 14 zeros let mut f_evals = vec![F::zero(); N - B]; f_evals[3] = F::one(); - let mut blinders: Vec<_> = (0..B).map(|i| F::from((i + 10) as u64)).collect(); - let mut blinders_cloned = blinders.clone(); f_evals.append(&mut blinders); - let f = DensePolynomial::from_coefficients_slice(&domain.ifft(&f_evals)); let f_cm = Kzg::commit(&pk, &f); let instance = Instance:: { f_cm }; - let witness = Witness { f }; - // RHS = 1/(beta + 1) + (N - B - 1)/(beta) - // let relation = |beta: F| { - // let beta_inv = beta.inverse().unwrap(); - // let beta_plus_one_inv = (F::one() + beta).inverse().unwrap(); - // let n_minus_one = F::from((N - B - 1) as u64); - - // beta_plus_one_inv + n_minus_one * beta_inv - // }; - - let id = format!("proof {}", N); + let id = format!(r"proof \pi_{{b_i}} N={}", N); criterion.bench_function(&id, |b| { b.iter(|| prove::(&index_p, &index_v, &instance, &witness, &pk)) }); diff --git a/benches/nonzero.rs b/benches/nonzero.rs index e0e26e9..60d31b0 100644 --- a/benches/nonzero.rs +++ b/benches/nonzero.rs @@ -1,44 +1,38 @@ -use std::ops::Mul; - -use cipher_bazaar::kzg::{Kzg, PK, VK}; -use ark_ec::{pairing::Pairing, Group, ScalarMul}; -use ark_ff::{batch_inversion, FftField, Field, One, Zero}; +use cipher_bazaar::kzg::{Kzg, PK}; use ark_poly::{ univariate::DensePolynomial, DenseUVPolynomial, EvaluationDomain, GeneralEvaluationDomain, - Polynomial, }; -use ark_bn254::{Bn254, Fr as F, G1Affine, G1Projective, G2Projective}; +use ark_bn254::{Bn254, Fr as F, G1Projective}; use cipher_bazaar::{ utils::srs::unsafe_setup_from_tau, }; use criterion::{criterion_group, criterion_main, Criterion}; use ark_std::UniformRand; +use std::env; -/* RUN WITH: cargo bench --bench nonzero */ - -const N: usize = 8192; +/* RUN WITH: N={128,1024,8192} cargo bench --bench nonzero */ fn criterion_benchmark(criterion: &mut Criterion) { + let n: usize = env::var("N") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(128); // default value + + match n { + 128 => run::<128>(criterion), + 1024 => run::<1024>(criterion), + 8192 => run::<8192>(criterion), + _ => panic!("Unsupported price range N"), + } +} + +fn run(criterion: &mut Criterion) { let mut rng = ark_std::test_rng(); let domain = GeneralEvaluationDomain::::new(N).unwrap(); - let tau = F::from(17u64); let srs = unsafe_setup_from_tau::(N - 1, tau); - let x_g2 = G2Projective::generator().mul(tau); - let pk = PK:: { srs: srs.clone() }; - let vk = VK::::new(x_g2); - - let x: Vec = (0..N).map(|_| F::rand(&mut rng)).collect(); - let x_poly: DensePolynomial<_> = DensePolynomial::from_coefficients_slice(&domain.ifft(&x)); - - // let a_cm = Kzg::commit(&pk, &x_poly); - // let gamma = F::rand(&mut rng); - // let one = F::from(1u64); - // let g1 = G1Projective::generator(); - // let x_vec: Vec = x.iter().map(|xi| g1.mul(xi).into()).collect(); - - let id = format!("proof {}", N); + let id = format!(r"proof \pi_{{r_i}} N={}", N); criterion.bench_function(&id, |b| { b.iter(|| { /* diff --git a/benches/veceq.rs b/benches/veceq.rs index e322a57..cde8102 100644 --- a/benches/veceq.rs +++ b/benches/veceq.rs @@ -1,54 +1,36 @@ use std::ops::Mul; - -use cipher_bazaar::kzg::{Kzg, PK, VK}; -use ark_ec::{pairing::Pairing, Group, ScalarMul}; -use ark_ff::{batch_inversion, FftField, Field, One, Zero}; -use ark_poly::{ - univariate::DensePolynomial, DenseUVPolynomial, EvaluationDomain, GeneralEvaluationDomain, - Polynomial, -}; -use ark_bn254::{Bn254, Fr as F, G1Affine, G1Projective, G2Projective}; -use cipher_bazaar::{ - utils::srs::unsafe_setup_from_tau, -}; +use ark_ec::{Group}; +use ark_bn254::{Fr as F, G1Projective}; use criterion::{criterion_group, criterion_main, Criterion}; use ark_std::UniformRand; +use std::env; -/* RUN WITH: cargo bench --bench veceq */ - -const N: usize = 8192; +/* RUN WITH: N={128,1024,8192} cargo bench --bench veceq */ fn criterion_benchmark(criterion: &mut Criterion) { - let mut rng = ark_std::test_rng(); - let domain = GeneralEvaluationDomain::::new(N).unwrap(); - - let tau = F::from(17u64); - let srs = unsafe_setup_from_tau::(N - 1, tau); - let x_g2 = G2Projective::generator().mul(tau); - - let pk = PK:: { srs: srs.clone() }; - let vk = VK::::new(x_g2); + let n: usize = env::var("N") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(128); // default value + + match n { + 128 => run::<128>(criterion), + 1024 => run::<1024>(criterion), + 8192 => run::<8192>(criterion), + _ => panic!("Unsupported price range N"), + } +} +fn run(criterion: &mut Criterion) { + let mut rng = ark_std::test_rng(); let x: Vec = (0..N).map(|_| F::rand(&mut rng)).collect(); - let x_poly: DensePolynomial<_> = DensePolynomial::from_coefficients_slice(&domain.ifft(&x)); - - - // let a_cm = Kzg::commit(&pk, &x_poly); - let gamma = F::rand(&mut rng); - let one = F::from(1u64); let g1 = G1Projective::generator(); - // let x_vec: Vec = x.iter().map(|xi| g1.mul(xi).into()).collect(); - - let id = format!("proof {}", N); + let id = format!(r"proof \pi_{{x_i}} N={}", N); criterion.bench_function(&id, |b| { b.iter(|| { - // let _ = Kzg::commit(&pk, &x_poly); - let x_vec: Vec = x.iter().map(|xi| g1.mul(xi).into()).collect(); - // let _: Vec = G1Projective::batch_convert_to_mul_base(&x_vec); - // Kzg::open(&pk, &[x_poly.clone()], gamma, one) + let _x_vec: Vec = x.iter().map(|xi| g1.mul(xi).into()).collect(); }) }); - } criterion_group!(benches, criterion_benchmark); diff --git a/src/verifiable_folding_sumcheck/mod.rs b/src/verifiable_folding_sumcheck/mod.rs index 4697167..e5293c3 100644 --- a/src/verifiable_folding_sumcheck/mod.rs +++ b/src/verifiable_folding_sumcheck/mod.rs @@ -83,7 +83,7 @@ impl Argument { // // deg(r_mod_x) <= n - 2 let r_degree = { let shift_factor = pk.srs.len() - 1 - (instance.n - 2); - let mut coeffs = r_mod_x.coeffs().clone().to_vec(); + let mut coeffs = r_mod_x.coeffs().to_vec(); let mut shifted_coeffs = vec![E::ScalarField::zero(); shift_factor]; shifted_coeffs.append(&mut coeffs); DensePolynomial::from_coefficients_slice(&shifted_coeffs)