From c08a4d46edc180f81b62b8d1e4bfc21b3200e143 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Fri, 19 Jan 2024 15:37:43 +0100 Subject: [PATCH 01/18] Removed extra field used for debugging only. --- src/backend/kzg_elgamal.rs | 4 ++-- src/backend/kzg_paillier.rs | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/backend/kzg_elgamal.rs b/src/backend/kzg_elgamal.rs index 0a31634..fd4da7e 100644 --- a/src/backend/kzg_elgamal.rs +++ b/src/backend/kzg_elgamal.rs @@ -217,8 +217,8 @@ mod test { use ark_std::collections::HashMap; use ark_std::{test_rng, UniformRand}; - const DATA_SIZE: usize = 64; - const SUBSET_SIZE: usize = 32; + const DATA_SIZE: usize = 16; + const SUBSET_SIZE: usize = 8; #[test] fn flow() { diff --git a/src/backend/kzg_paillier.rs b/src/backend/kzg_paillier.rs index 9053bab..7b81903 100644 --- a/src/backend/kzg_paillier.rs +++ b/src/backend/kzg_paillier.rs @@ -184,8 +184,6 @@ pub struct Proof { pub w_vec: Vec, pub z_vec: Vec, pub com_q_poly: C::G1, - // TODO delete - pub t: C::G1, _digest: PhantomData, _curve: PhantomData, } @@ -244,7 +242,6 @@ impl Proof { w_vec, z_vec, com_q_poly, - t, _digest: PhantomData, _curve: PhantomData, } @@ -293,7 +290,6 @@ impl Proof { let commitment_pow_challenge = *com_f_s_poly * challenge_scalar; let msm = powers.commit_scalars_g1(&z_scalar_vec); let t_expected = msm - commitment_pow_challenge; - assert_eq!(self.t, t_expected); let challenge_expected = challenge::( pubkey, From 8a4565135dbc565b068ff476cc5b89227e733682 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Fri, 19 Jan 2024 15:53:30 +0100 Subject: [PATCH 02/18] Renamed backend to veck. --- Cargo.toml | 7 +- benches/kzg_elgamal.rs | 4 +- benches/kzg_elgamal_slow.rs | 144 -------------------------- src/backend/kzg_elgamal_slow.rs | 136 ------------------------ src/interpolate.rs | 129 ----------------------- src/lib.rs | 3 +- src/tests/mod.rs | 7 +- src/{backend => veck}/kzg_elgamal.rs | 0 src/{backend => veck}/kzg_paillier.rs | 0 src/{backend => veck}/mod.rs | 1 - 10 files changed, 7 insertions(+), 424 deletions(-) delete mode 100644 benches/kzg_elgamal_slow.rs delete mode 100644 src/backend/kzg_elgamal_slow.rs delete mode 100644 src/interpolate.rs rename src/{backend => veck}/kzg_elgamal.rs (100%) rename src/{backend => veck}/kzg_paillier.rs (100%) rename src/{backend => veck}/mod.rs (73%) diff --git a/Cargo.toml b/Cargo.toml index 7808ffe..bff90ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,15 +54,10 @@ criterion = "0.5" sha3 = "0.10" [[bench]] -name = "kzg-elgamal-backend" +name = "kzg-elgamal-veck" path = "benches/kzg_elgamal.rs" harness = false -#[[bench]] -#name = "kzg-elgamal-slow-backend" -#path = "benches/kzg_elgamal_slow.rs" -#harness = false - [[bench]] name = "split-elgamal-encryption" path = "benches/elgamal.rs" diff --git a/benches/kzg_elgamal.rs b/benches/kzg_elgamal.rs index f8b9e30..5a309d8 100644 --- a/benches/kzg_elgamal.rs +++ b/benches/kzg_elgamal.rs @@ -13,8 +13,8 @@ const N: usize = Scalar::MODULUS_BIT_SIZE as usize / fde::encrypt::elgamal::MAX_ type Scalar = ::ScalarField; type UniPoly = DensePolynomial; -type Proof = fde::backend::kzg_elgamal::Proof<{ N }, BlsCurve, sha3::Keccak256>; -type PublicInput = fde::backend::kzg_elgamal::PublicInput<{ N }, BlsCurve>; +type Proof = fde::veck::kzg_elgamal::Proof<{ N }, BlsCurve, sha3::Keccak256>; +type PublicInput = fde::veck::kzg_elgamal::PublicInput<{ N }, BlsCurve>; fn bench_proof(c: &mut Criterion) { let mut group = c.benchmark_group("kzg-elgamal"); diff --git a/benches/kzg_elgamal_slow.rs b/benches/kzg_elgamal_slow.rs deleted file mode 100644 index 11bdff5..0000000 --- a/benches/kzg_elgamal_slow.rs +++ /dev/null @@ -1,144 +0,0 @@ -use ark_bls12_381::{Bls12_381 as BlsCurve, G1Affine}; -use ark_ec::pairing::Pairing; -use ark_ec::{AffineRepr, CurveGroup}; -use ark_poly::univariate::DensePolynomial; -use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain, Polynomial}; -use ark_std::rand::Rng; -use ark_std::{test_rng, UniformRand}; -use criterion::{criterion_group, criterion_main, Criterion}; -use fde::commit::kzg::Powers; -use fde::encrypt::elgamal::ExponentialElgamal; -use fde::encrypt::EncryptionEngine; -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -type Elgamal = ExponentialElgamal<::G1>; -type Scalar = ::ScalarField; -type UniPoly = DensePolynomial; -type Proof = fde::backend::kzg_elgamal_slow::Proof; -type Cipher = fde::encrypt::elgamal::Cipher<::G1>; - -const D: usize = 32; -const N: usize = 1; - -struct Input { - indices: Vec, - rands: Vec, - ciphers: Vec, -} - -impl Input { - fn new( - domain: GeneralEvaluationDomain, - poly: &UniPoly, - encryption_pk: G1Affine, - rng: &mut R, - ) -> Self { - let mut indices = Vec::new(); - let mut rands = Vec::new(); - let mut ciphers = Vec::new(); - - for i in 0..N { - let index = domain.element(i); - let eval = poly.evaluate(&index); - let elgamal_r = Scalar::rand(rng); - let cipher = ::encrypt_with_randomness( - &eval, - &encryption_pk, - &elgamal_r, - ); - - indices.push(index); - rands.push(elgamal_r); - ciphers.push(cipher); - } - - Self { - indices, - rands, - ciphers, - } - } -} - -fn bench_proof(c: &mut Criterion) { - assert!(D >= N); - let mut group = c.benchmark_group("elgamal-kzg-slow"); - - let rng = &mut test_rng(); - // kzg setup - let tau = Scalar::rand(rng); - let powers = Powers::::unsafe_setup(tau, D); - - // polynomial - let domain = GeneralEvaluationDomain::::new(D).unwrap(); - let data = (0..D).map(|_| Scalar::rand(rng)).collect::>(); - let evaluations = Evaluations::from_vec_and_domain(data, domain); - let f_poly: UniPoly = evaluations.interpolate_by_ref(); - let com_f_poly = powers.commit_g1(&f_poly); - // encryption secret key - let encryption_sk = Scalar::rand(rng); - let encryption_pk = (G1Affine::generator() * encryption_sk).into_affine(); - - let input = Input::new(domain, &f_poly, encryption_pk, rng); - - group.bench_function("proof-gen", |b| { - b.iter(|| { - #[cfg(not(feature = "parallel"))] - input - .indices - .iter() - .zip(&input.rands) - .for_each(|(index, elgamal_r)| { - Proof::new(&f_poly, *index, *elgamal_r, &encryption_sk, &powers, rng); - }); - #[cfg(feature = "parallel")] - input - .indices - .par_iter() - .zip(&input.rands) - .for_each(|(index, elgamal_r)| { - Proof::new( - &f_poly, - *index, - *elgamal_r, - &encryption_sk, - &powers, - &mut test_rng(), - ); - }); - }) - }); - - group.bench_function("proof-vfy", |b| { - let proofs: Vec = input - .indices - .iter() - .zip(&input.rands) - .map(|(index, elgamal_r)| { - Proof::new(&f_poly, *index, *elgamal_r, &encryption_sk, &powers, rng) - }) - .collect(); - b.iter(|| { - #[cfg(not(feature = "parallel"))] - proofs - .iter() - .zip(input.indices.iter().zip(&input.ciphers)) - .for_each(|(proof, (index, cipher))| { - proof.verify(com_f_poly, *index, &cipher, &powers); - }); - #[cfg(feature = "parallel")] - proofs - .par_iter() - .zip(input.indices.par_iter().zip(&input.ciphers)) - .for_each(|(proof, (index, cipher))| { - proof.verify(com_f_poly, *index, &cipher, &powers); - }); - }) - }); - - group.finish(); -} - -criterion_group!(benches, bench_proof); -criterion_main!(benches); diff --git a/src/backend/kzg_elgamal_slow.rs b/src/backend/kzg_elgamal_slow.rs deleted file mode 100644 index 4b760e8..0000000 --- a/src/backend/kzg_elgamal_slow.rs +++ /dev/null @@ -1,136 +0,0 @@ -use crate::commit::kzg::Powers; -use crate::encrypt::elgamal::Cipher; -use ark_ec::pairing::Pairing; -use ark_ec::{CurveGroup, Group}; -use ark_poly_commit::DenseUVPolynomial; -use ark_std::marker::PhantomData; -use ark_std::ops::{Add, Div, Sub}; -use ark_std::rand::Rng; -use ark_std::{One, UniformRand}; - -pub struct Proof { - com_r_poly: C::G1Affine, - com_t_poly: C::G1Affine, - h_secret_star: C::G2Affine, - _poly: PhantomData

, -} - -impl Proof -where - C: Pairing, - P: DenseUVPolynomial, - for<'a> &'a P: Add<&'a P, Output = P>, - for<'a> &'a P: Sub<&'a P, Output = P>, - for<'a> &'a P: Div<&'a P, Output = P>, -{ - pub fn new( - f_poly: &P, - index: C::ScalarField, - elgamal_r: C::ScalarField, - encryption_sk: &C::ScalarField, - powers: &Powers, - rng: &mut R, - ) -> Self { - // random values - let secret_star = C::ScalarField::rand(rng); - // g2^(ss*) - let h_secret_star = (C::G2::generator() * encryption_sk * secret_star).into_affine(); - // evaluate polynomial at index and split evaluation up into brute-forceable shards for - // exponential elgamal - let eval = f_poly.evaluate(&index); - // (x - eval) polynomial - let d_poly = P::from_coefficients_slice(&[-index, C::ScalarField::one()]); - let s_s_star = P::from_coefficients_slice(&[*encryption_sk * secret_star]); - // (f(x) - eval) / (x - eval) + ss* - let t_poly = &(f_poly + &P::from_coefficients_slice(&[-eval])) / &d_poly + s_s_star; - // - r / s_star - (x - eval) - let r_poly = &P::from_coefficients_slice(&[-elgamal_r / secret_star]) - &d_poly; - - // kzg commitments - let com_r_poly = powers.commit_g1(&r_poly).into(); - let com_t_poly = powers.commit_g1(&t_poly).into(); - - Self { - com_r_poly, - com_t_poly, - h_secret_star, - _poly: PhantomData, - } - } - - pub fn verify( - &self, - com_f_poly: C::G1, - index: C::ScalarField, - cipher: &Cipher, - powers: &Powers, - ) -> bool { - let d_poly = P::from_coefficients_slice(&[-index, C::ScalarField::one()]); - let com_d_poly = powers.commit_g2(&d_poly); - - let pairing_f_poly = C::pairing(com_f_poly - C::G1::from(cipher.c1()), C::G2::generator()); - let pairing_t_poly = C::pairing(self.com_t_poly, com_d_poly); - let pairing_r_poly = C::pairing(self.com_r_poly, self.h_secret_star); - - pairing_f_poly == pairing_t_poly + pairing_r_poly - } -} - -#[cfg(test)] -mod test { - use crate::commit::kzg::Powers; - use crate::encrypt::EncryptionEngine; - use crate::tests::*; - use ark_ec::{AffineRepr, CurveGroup}; - use ark_poly::domain::general::GeneralEvaluationDomain; - use ark_poly::evaluations::univariate::Evaluations; - use ark_poly::{EvaluationDomain, Polynomial}; - use ark_std::{test_rng, UniformRand}; - - #[test] - fn completeness() { - let rng = &mut test_rng(); - - // kzg setup - let tau = Scalar::rand(rng); - let powers = Powers::::unsafe_setup(tau, 10); - - // polynomial - let domain = GeneralEvaluationDomain::::new(3).unwrap(); - let data = vec![ - Scalar::from(2), - Scalar::from(3), - Scalar::from(6), - Scalar::from(11), - ]; - let evaluations = Evaluations::from_vec_and_domain(data, domain); - let f_poly: UniPoly = evaluations.interpolate_by_ref(); - let com_f_poly = powers.commit_g1(&f_poly); - - // index and eval - let index = Scalar::from(7u32); - let eval = f_poly.evaluate(&index); - - // "offline" encryption with random secret key - let encryption_sk = Scalar::rand(rng); - let encryption_pk = (G1Affine::generator() * encryption_sk).into_affine(); - let split_eval = SplitScalar::from(eval); - - // encrypt split evaluation data - let (short_ciphers, elgamal_r) = split_eval.encrypt::(&encryption_pk, rng); - - // elgamal encryption - let long_cipher = ::encrypt_with_randomness( - &eval, - &encryption_pk, - &elgamal_r, - ); - - // compute kzg proof - let proof = - KzgElgamalSlowProof::new(&f_poly, index, elgamal_r, &encryption_sk, &powers, rng); - - assert!(proof.verify(com_f_poly, index, &long_cipher, &powers)); - assert!(long_cipher.check_encrypted_sum(&short_ciphers)); - } -} diff --git a/src/interpolate.rs b/src/interpolate.rs deleted file mode 100644 index 05b5b85..0000000 --- a/src/interpolate.rs +++ /dev/null @@ -1,129 +0,0 @@ -use ark_ff::fields::PrimeField; -use ark_poly::polynomial::univariate::DensePolynomial; - -// performs textbook interpolation over a scalar field -pub fn interpolate(x: &[S], y: &[S]) -> DensePolynomial { - let n = x.len(); - let mut s = vec![S::zero(); n]; - let mut coeffs = vec![S::zero(); n]; - - s.push(S::one()); - s[n - 1] = -x[0]; - - for (i, &x_elem) in x.iter().enumerate().skip(1) { - for j in n - 1 - i..n - 1 { - let aux = x_elem * s[j + 1]; - s[j] -= aux; - } - s[n - 1] -= x_elem; - } - - for i in 0..n { - let mut phi = S::zero(); - for j in (1..=n).rev() { - phi *= x[i]; - phi += S::from(j as u64) * s[j]; - } - let mut b = S::one(); - for j in (0..n).rev() { - let aux = y[i] * b / phi; - coeffs[j] += aux; - b *= x[i]; - b += s[j]; - } - } - - DensePolynomial { coeffs } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::tests::Scalar; - use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain, Polynomial}; - use ark_std::ops::Neg; - use ark_std::{test_rng, UniformRand}; - use ark_std::{One, Zero}; - - #[test] - fn interpolation_works() { - // constant polynomial (y = 53) - let x = vec![Scalar::from(3_u64); 1]; - let y = vec![Scalar::from(53_u64); 1]; - let poly = interpolate(&x, &y); - assert_eq!(poly.coeffs, &[Scalar::from(53_u64)]); - assert_eq!( - poly.evaluate(&Scalar::from(123456_u64)), - Scalar::from(53_u64), - ); - assert_eq!( - poly.evaluate(&Scalar::from(78910_u64)), - Scalar::from(53_u64), - ); - - // simple first order polynomial (y = x) - let x = vec![Scalar::from(1_u64), Scalar::from(2_u64)]; - - let y = x.clone(); - let poly = interpolate(&x, &y); - assert_eq!(poly.coeffs, &[Scalar::zero(), Scalar::one()]); - - // first order polynomial (y = 32 * x - 13) - let x = vec![Scalar::from(2_u64), Scalar::from(3_u64)]; - let y = vec![Scalar::from(51_u64), Scalar::from(83_u64)]; - let poly = interpolate(&x, &y); - assert_eq!( - poly.coeffs, - &[Scalar::from(13_u64).neg(), Scalar::from(32_u64)] - ); - - assert_eq!(poly.evaluate(&x[0]), y[0]); - assert_eq!(poly.evaluate(&x[1]), y[1]); - assert_eq!( - poly.evaluate(&Scalar::from(100_u64)), - Scalar::from(3187_u64) - ); - - // fourth order polynomial - // y = x^4 + 0 * x^3 + 3 * x^2 + 2 * x + 14 - let x = vec![ - Scalar::from(1_u64), - Scalar::from(2_u64), - Scalar::from(3_u64), - Scalar::from(4_u64), - Scalar::from(5_u64), - Scalar::from(6_u64), - ]; - let y = vec![ - Scalar::from(20_u64), - Scalar::from(46_u64), - Scalar::from(128_u64), - Scalar::from(326_u64), - Scalar::from(724_u64), - Scalar::from(1430_u64), - ]; - let poly = interpolate(&x, &y); - x.iter() - .zip(y) - .for_each(|(x, y)| assert_eq!(poly.evaluate(x), y)); - poly.coeffs - .into_iter() - .zip([14u64, 2, 3, 0, 1]) - .for_each(|(coeff, s)| assert_eq!(coeff, Scalar::from(s))); - } - - #[test] - fn interpolation_with_domain_works() { - let rng = &mut test_rng(); - let evals: Vec = (0..64).map(|_| Scalar::rand(rng)).collect(); - let general_domain = GeneralEvaluationDomain::new(evals.len()).unwrap(); - - let domain: Vec = general_domain.elements().collect(); - let other_poly = interpolate(&domain, &evals); - - let evaluations = Evaluations::from_vec_and_domain(evals, general_domain); - let poly = evaluations.interpolate_by_ref(); - - assert_eq!(poly, other_poly); - } -} diff --git a/src/lib.rs b/src/lib.rs index 626daf5..1d46b0f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,15 +3,14 @@ #![deny(unused_crate_dependencies)] pub mod adaptor_sig; -pub mod backend; pub mod commit; pub mod dleq; pub mod encrypt; pub mod hash; -pub mod interpolate; pub mod range_proof; #[cfg(test)] mod tests; +pub mod veck; use thiserror::Error; diff --git a/src/tests/mod.rs b/src/tests/mod.rs index cd5c101..b6dbfba 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -12,9 +12,8 @@ pub type SplitScalar = crate::encrypt::elgamal::SplitScalar<{ N }, Scalar>; pub type UniPoly = DensePolynomial; pub type Elgamal = crate::encrypt::elgamal::ExponentialElgamal<::G1>; -pub type PublicInput = crate::backend::kzg_elgamal::PublicInput<{ N }, BlsCurve, Keccak256>; -pub type KzgElgamalProof = crate::backend::kzg_elgamal::Proof<{ N }, BlsCurve, Keccak256>; -pub type KzgElgamalSlowProof = crate::backend::kzg_elgamal_slow::Proof; +pub type PublicInput = crate::veck::kzg_elgamal::PublicInput<{ N }, BlsCurve, Keccak256>; +pub type KzgElgamalProof = crate::veck::kzg_elgamal::Proof<{ N }, BlsCurve, Keccak256>; pub type DleqProof = crate::dleq::Proof<::G1, Keccak256>; pub type RangeProof = crate::range_proof::RangeProof; -pub type PaillierEncryptionProof = crate::backend::kzg_paillier::Proof; +pub type PaillierEncryptionProof = crate::veck::kzg_paillier::Proof; diff --git a/src/backend/kzg_elgamal.rs b/src/veck/kzg_elgamal.rs similarity index 100% rename from src/backend/kzg_elgamal.rs rename to src/veck/kzg_elgamal.rs diff --git a/src/backend/kzg_paillier.rs b/src/veck/kzg_paillier.rs similarity index 100% rename from src/backend/kzg_paillier.rs rename to src/veck/kzg_paillier.rs diff --git a/src/backend/mod.rs b/src/veck/mod.rs similarity index 73% rename from src/backend/mod.rs rename to src/veck/mod.rs index c4d4ab3..8dc6674 100644 --- a/src/backend/mod.rs +++ b/src/veck/mod.rs @@ -1,4 +1,3 @@ pub mod kzg_elgamal; -pub mod kzg_elgamal_slow; #[cfg(feature = "paillier")] pub mod kzg_paillier; From 9ba9a98411c673a773faff63f189c58f47c2a18b Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Fri, 19 Jan 2024 19:18:22 +0100 Subject: [PATCH 03/18] wip --- src/veck/kzg_paillier.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/veck/kzg_paillier.rs b/src/veck/kzg_paillier.rs index 7b81903..b7bfd0e 100644 --- a/src/veck/kzg_paillier.rs +++ b/src/veck/kzg_paillier.rs @@ -202,7 +202,7 @@ impl Proof { rng: &mut R, ) -> Self { let vanishing_poly = DensePolynomial::from(domain.vanishing_polynomial()); - let q_poly = &(f_poly - f_s_poly) / &vanishing_poly; + let q_poly = dbg!(&(f_poly - f_s_poly)) / dbg!(&vanishing_poly); let q_poly_evals = q_poly.evaluate_over_domain_by_ref(*domain); let com_q_poly = powers.commit_scalars_g1(&q_poly_evals.evals); let random_params = PaillierRandomParameters::new(values.len(), rng); @@ -369,8 +369,8 @@ mod test { .collect(); let data_s: Vec = indices.into_iter().map(|i| data[i]).collect(); let evaluations_s = Evaluations::from_vec_and_domain(data_s, domain_s); - let f_s_poly: UniPoly = evaluations.interpolate_by_ref(); - let com_f_poly = powers.commit_scalars_g1(&evaluations_s.evals); + let f_s_poly: UniPoly = evaluations_s.interpolate_by_ref(); + let com_f_poly = powers.commit_scalars_g1(&evaluations.evals); let com_f_s_poly = powers.commit_scalars_g1(&evaluations_s.evals); let data_biguint: Vec = evaluations_s From 333c53cc09b94a5b726b6fa413da459c1857530e Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Fri, 19 Jan 2024 21:28:42 +0100 Subject: [PATCH 04/18] Asd --- src/commit/kzg.rs | 19 ++++++++ src/veck/mod.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/src/commit/kzg.rs b/src/commit/kzg.rs index 927f78d..5b0f944 100644 --- a/src/commit/kzg.rs +++ b/src/commit/kzg.rs @@ -260,4 +260,23 @@ mod test { )); } } + + #[test] + fn commitment_equality() { + let rng = &mut test_rng(); + let degree: usize = 16; + let domain = GeneralEvaluationDomain::new(degree).unwrap(); + let tau = Scalar::rand(rng); + let powers = Powers::::unsafe_setup(tau, degree); + let powers_eip = Powers::::unsafe_setup_eip_4844(tau, degree); + + let coeffs = (0..degree).map(|_| Scalar::rand(rng)).collect(); + let poly = UniPoly { coeffs }; + + let evals = poly.evaluate_over_domain_by_ref(domain); + let com_p = powers.commit_g1(&poly); + let com_p_eip = powers_eip.commit_scalars_g1(&evals.evals); + + assert_eq!(com_p, com_p_eip); + } } diff --git a/src/veck/mod.rs b/src/veck/mod.rs index 8dc6674..4de38d8 100644 --- a/src/veck/mod.rs +++ b/src/veck/mod.rs @@ -1,3 +1,112 @@ pub mod kzg_elgamal; #[cfg(feature = "paillier")] pub mod kzg_paillier; + +use crate::commit::kzg::Powers; +use ark_ec::pairing::Pairing; +use ark_ec::Group; +use ark_ff::FftField; +use ark_poly::univariate::DensePolynomial; +use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; +use ark_std::collections::HashMap; + +fn subset_pairing_check( + phi: &DensePolynomial, + phi_s: &DensePolynomial, + domain: &GeneralEvaluationDomain, + subdomain: &GeneralEvaluationDomain, + powers: &Powers, +) { + let vanishing_poly = DensePolynomial::from(domain.vanishing_polynomial()); + let quotient = &(phi - phi_s) / &vanishing_poly; + let quotient_expected = (phi - phi_s) + .divide_by_vanishing_poly(*domain) + .unwrap() + .0; + assert_eq!(quotient, quotient_expected); + // this only works with powers of tau + //let com_q = powers.commit_g1("ient); + //let com_f = powers.commit_g1(phi); + //let com_f_s = powers.commit_g1(phi_s); + //let com_v = powers.commit_g2(&vanishing_poly); + //let lhs_pairing = C::pairing(com_q, com_v); + //let rhs_pairing = C::pairing(com_f - com_f_s, C::G2::generator()); + //assert_eq!(lhs_pairing, rhs_pairing); + + let phi_evals = phi.evaluate_over_domain_by_ref(*subdomain); + let phi_s_evals = phi_s.evaluate_over_domain_by_ref(*subdomain); + let q_evals = quotient.evaluate_over_domain_by_ref(*subdomain); + let v_evals = vanishing_poly.evaluate_over_domain_by_ref(*subdomain); + let com_q = powers.commit_scalars_g1(&q_evals.evals); + let com_f = powers.commit_scalars_g1(&phi_evals.evals); + let com_f_s = powers.commit_scalars_g1(&phi_s_evals.evals); + let com_v = powers.commit_scalars_g2(&v_evals.evals); + let lhs_pairing = C::pairing(com_q, com_v); + let rhs_pairing = C::pairing(com_f - com_f_s, C::G2::generator()); + assert_eq!(lhs_pairing, rhs_pairing); +} + +// TODO move index map out of here so that it's not recomputed every time +fn subset_evals( + evaluations: &Evaluations, + subdomain: GeneralEvaluationDomain, +) -> Evaluations { + debug_assert!(evaluations.domain().size() >= subdomain.size()); + let index_map: HashMap = evaluations + .domain() + .elements() + .enumerate() + .map(|(i, e)| (e, i)) + .collect(); + let indices = subdomain + .elements() + .map(|e| *index_map.get(&e).unwrap()) + .collect::>(); + let mut subset_evals = Vec::::new(); + for index in indices { + subset_evals.push(evaluations.evals[index]); + } + Evaluations::from_vec_and_domain(subset_evals, subdomain) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::tests::{BlsCurve, Scalar}; + use ark_std::{test_rng, UniformRand}; + + const DATA_SIZE: usize = 32; + const SUBSET_SIZE: usize = 16; + + #[test] + fn mivan() { + let rng = &mut test_rng(); + let tau = Scalar::rand(rng); + let powers = Powers::::unsafe_setup_eip_4844(tau, DATA_SIZE + 1); + + let domain = GeneralEvaluationDomain::new(DATA_SIZE).unwrap(); + let subdomain = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); + + let data = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); + let evaluations = Evaluations::from_vec_and_domain(data, domain); + let subset_evaluations = subset_evals(&evaluations, subdomain); + + let phi = evaluations.interpolate_by_ref(); + let phi_s = subset_evaluations.interpolate_by_ref(); + subset_pairing_check(&phi, &phi_s, &domain, &subdomain, &powers); + + let r_scalars: Vec = (0..SUBSET_SIZE).map(|_| Scalar::rand(rng)).collect(); + let t = powers.commit_scalars_g1(&r_scalars); + let challenge = Scalar::rand(rng); + let z_scalars: Vec = r_scalars + .iter() + .zip(&subset_evaluations.evals) + .map(|(&r, &v)| r + challenge * v) + .collect(); + let com_f_s_poly = powers.commit_scalars_g1(&subset_evaluations.evals); + let commitment_pow_challenge = com_f_s_poly * challenge; + let com_z = powers.commit_scalars_g1(&z_scalars); + let t_expected = com_z - commitment_pow_challenge; + assert_eq!(t, t_expected); + } +} From a47fc8c50198f65aebb5e69f5322013fad2d895b Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Sat, 20 Jan 2024 11:12:50 +0100 Subject: [PATCH 05/18] Koolio --- src/commit/kzg.rs | 3 +++ src/veck/kzg/elgamal.rs | 0 src/veck/kzg/mod.rs | 2 ++ src/veck/kzg/paillier.rs | 0 src/veck/kzg_paillier.rs | 40 +++++++++++++++++++++++++--------------- src/veck/mod.rs | 39 +++++++++++++++++++++------------------ src/veck/server.rs | 0 7 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 src/veck/kzg/elgamal.rs create mode 100644 src/veck/kzg/mod.rs create mode 100644 src/veck/kzg/paillier.rs create mode 100644 src/veck/server.rs diff --git a/src/commit/kzg.rs b/src/commit/kzg.rs index 5b0f944..7bf48db 100644 --- a/src/commit/kzg.rs +++ b/src/commit/kzg.rs @@ -9,6 +9,9 @@ use ark_std::marker::PhantomData; use ark_std::rand::Rng; use ark_std::{One, UniformRand, Zero}; +pub struct PowersOfTau; +pub struct LagrangeBasis; + pub struct Powers { pub g1: Vec, pub g2: Vec, diff --git a/src/veck/kzg/elgamal.rs b/src/veck/kzg/elgamal.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/veck/kzg/mod.rs b/src/veck/kzg/mod.rs new file mode 100644 index 0000000..aa1c7aa --- /dev/null +++ b/src/veck/kzg/mod.rs @@ -0,0 +1,2 @@ +mod elgamal; +mod paillier; diff --git a/src/veck/kzg/paillier.rs b/src/veck/kzg/paillier.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/veck/kzg_paillier.rs b/src/veck/kzg_paillier.rs index b7bfd0e..07b9a73 100644 --- a/src/veck/kzg_paillier.rs +++ b/src/veck/kzg_paillier.rs @@ -184,6 +184,8 @@ pub struct Proof { pub w_vec: Vec, pub z_vec: Vec, pub com_q_poly: C::G1, + pub t_vec: Vec, + pub t: C::G1, _digest: PhantomData, _curve: PhantomData, } @@ -197,14 +199,16 @@ impl Proof { com_f_poly: &C::G1, com_f_s_poly: &C::G1, domain: &GeneralEvaluationDomain, + domain_s: &GeneralEvaluationDomain, pubkey: &BigUint, powers: &Powers, rng: &mut R, ) -> Self { - let vanishing_poly = DensePolynomial::from(domain.vanishing_polynomial()); - let q_poly = dbg!(&(f_poly - f_s_poly)) / dbg!(&vanishing_poly); + let vanishing_poly = DensePolynomial::from(domain_s.vanishing_polynomial()); + let q_poly = &(f_poly - f_s_poly) / &vanishing_poly; let q_poly_evals = q_poly.evaluate_over_domain_by_ref(*domain); let com_q_poly = powers.commit_scalars_g1(&q_poly_evals.evals); + let random_params = PaillierRandomParameters::new(values.len(), rng); let ct_vec = batch_encrypt(values, pubkey, &random_params.u_vec); let t_vec = batch_encrypt(&random_params.r_vec, pubkey, &random_params.s_vec); @@ -242,6 +246,8 @@ impl Proof { w_vec, z_vec, com_q_poly, + t_vec, + t, _digest: PhantomData, _curve: PhantomData, } @@ -252,12 +258,14 @@ impl Proof { com_f_poly: &C::G1, com_f_s_poly: &C::G1, domain: &GeneralEvaluationDomain, + domain_s: &GeneralEvaluationDomain, pubkey: &BigUint, powers: &Powers, ) -> bool { - let vanishing_poly = DensePolynomial::from(domain.vanishing_polynomial()); + let vanishing_poly = DensePolynomial::from(domain_s.vanishing_polynomial()); let vanishing_poly_evals = vanishing_poly.evaluate_over_domain_by_ref(*domain); let com_vanishing_poly_g2 = powers.commit_scalars_g2(&vanishing_poly_evals.evals); + let lhs_pairing = C::pairing(self.com_q_poly, com_vanishing_poly_g2); let rhs_pairing = C::pairing(*com_f_poly - com_f_s_poly, C::G2::generator()); if lhs_pairing != rhs_pairing { @@ -278,6 +286,7 @@ impl Proof { (aux * ct_pow_minus_c) % &modulo }) .collect(); + assert_eq!(self.t_vec, t_vec_expected, "t_vec is shit"); let z_scalar_vec: Vec = self .z_vec .iter() @@ -290,6 +299,7 @@ impl Proof { let commitment_pow_challenge = *com_f_s_poly * challenge_scalar; let msm = powers.commit_scalars_g1(&z_scalar_vec); let t_expected = msm - commitment_pow_challenge; + assert_eq!(self.t, t_expected, "t is shit"); let challenge_expected = challenge::( pubkey, @@ -317,6 +327,7 @@ impl Proof { #[cfg(test)] mod test { + use super::super::{index_map, subset_evals}; use super::{modular_inverse, Server, N_BITS}; use crate::commit::kzg::Powers; use crate::tests::{BlsCurve, PaillierEncryptionProof, Scalar, UniPoly}; @@ -357,21 +368,18 @@ mod test { // random data to encrypt let data: Vec = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); let domain = GeneralEvaluationDomain::new(DATA_SIZE).unwrap(); - let evaluations = Evaluations::from_vec_and_domain(data.clone(), domain); - let f_poly: UniPoly = evaluations.interpolate_by_ref(); - - let index_map: HashMap = - domain.elements().enumerate().map(|(i, e)| (e, i)).collect(); let domain_s = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); - let indices: Vec = domain_s - .elements() - .map(|elem| *index_map.get(&elem).unwrap()) - .collect(); - let data_s: Vec = indices.into_iter().map(|i| data[i]).collect(); - let evaluations_s = Evaluations::from_vec_and_domain(data_s, domain_s); + let evaluations = Evaluations::from_vec_and_domain(data, domain); + let index_map = index_map(domain); + let evaluations_s = subset_evals(&evaluations, &index_map, domain_s); + + let f_poly: UniPoly = evaluations.interpolate_by_ref(); let f_s_poly: UniPoly = evaluations_s.interpolate_by_ref(); + + let evaluations_s_d = f_s_poly.evaluate_over_domain_by_ref(domain); + let com_f_poly = powers.commit_scalars_g1(&evaluations.evals); - let com_f_s_poly = powers.commit_scalars_g1(&evaluations_s.evals); + let com_f_s_poly = powers.commit_scalars_g1(&evaluations_s_d.evals); let data_biguint: Vec = evaluations_s .evals @@ -385,6 +393,7 @@ mod test { &f_s_poly, &com_f_poly, &com_f_s_poly, + &domain, &domain_s, &server.pubkey, &powers, @@ -394,6 +403,7 @@ mod test { assert!(proof.verify( &com_f_poly, &com_f_s_poly, + &domain, &domain_s, &server.pubkey, &powers diff --git a/src/veck/mod.rs b/src/veck/mod.rs index 4de38d8..65c4a20 100644 --- a/src/veck/mod.rs +++ b/src/veck/mod.rs @@ -17,10 +17,10 @@ fn subset_pairing_check( subdomain: &GeneralEvaluationDomain, powers: &Powers, ) { - let vanishing_poly = DensePolynomial::from(domain.vanishing_polynomial()); + let vanishing_poly = DensePolynomial::from(subdomain.vanishing_polynomial()); let quotient = &(phi - phi_s) / &vanishing_poly; let quotient_expected = (phi - phi_s) - .divide_by_vanishing_poly(*domain) + .divide_by_vanishing_poly(*subdomain) .unwrap() .0; assert_eq!(quotient, quotient_expected); @@ -33,10 +33,10 @@ fn subset_pairing_check( //let rhs_pairing = C::pairing(com_f - com_f_s, C::G2::generator()); //assert_eq!(lhs_pairing, rhs_pairing); - let phi_evals = phi.evaluate_over_domain_by_ref(*subdomain); - let phi_s_evals = phi_s.evaluate_over_domain_by_ref(*subdomain); - let q_evals = quotient.evaluate_over_domain_by_ref(*subdomain); - let v_evals = vanishing_poly.evaluate_over_domain_by_ref(*subdomain); + let phi_evals = phi.evaluate_over_domain_by_ref(*domain); + let phi_s_evals = phi_s.evaluate_over_domain_by_ref(*domain); + let q_evals = quotient.evaluate_over_domain_by_ref(*domain); + let v_evals = vanishing_poly.evaluate_over_domain_by_ref(*domain); let com_q = powers.commit_scalars_g1(&q_evals.evals); let com_f = powers.commit_scalars_g1(&phi_evals.evals); let com_f_s = powers.commit_scalars_g1(&phi_s_evals.evals); @@ -46,18 +46,20 @@ fn subset_pairing_check( assert_eq!(lhs_pairing, rhs_pairing); } -// TODO move index map out of here so that it's not recomputed every time +fn index_map(domain: GeneralEvaluationDomain) -> HashMap { + domain + .elements() + .enumerate() + .map(|(i, e)| (e, i)) + .collect() +} + fn subset_evals( evaluations: &Evaluations, + index_map: &HashMap, subdomain: GeneralEvaluationDomain, ) -> Evaluations { debug_assert!(evaluations.domain().size() >= subdomain.size()); - let index_map: HashMap = evaluations - .domain() - .elements() - .enumerate() - .map(|(i, e)| (e, i)) - .collect(); let indices = subdomain .elements() .map(|e| *index_map.get(&e).unwrap()) @@ -75,21 +77,22 @@ mod test { use crate::tests::{BlsCurve, Scalar}; use ark_std::{test_rng, UniformRand}; - const DATA_SIZE: usize = 32; - const SUBSET_SIZE: usize = 16; + const DATA_SIZE: usize = 8; + const SUBSET_SIZE: usize = 4; #[test] fn mivan() { let rng = &mut test_rng(); let tau = Scalar::rand(rng); - let powers = Powers::::unsafe_setup_eip_4844(tau, DATA_SIZE + 1); + let powers = Powers::::unsafe_setup_eip_4844(tau, DATA_SIZE); let domain = GeneralEvaluationDomain::new(DATA_SIZE).unwrap(); let subdomain = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); let data = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); let evaluations = Evaluations::from_vec_and_domain(data, domain); - let subset_evaluations = subset_evals(&evaluations, subdomain); + let index_map = index_map(domain); + let subset_evaluations = subset_evals(&evaluations, &index_map, subdomain); let phi = evaluations.interpolate_by_ref(); let phi_s = subset_evaluations.interpolate_by_ref(); @@ -103,7 +106,7 @@ mod test { .zip(&subset_evaluations.evals) .map(|(&r, &v)| r + challenge * v) .collect(); - let com_f_s_poly = powers.commit_scalars_g1(&subset_evaluations.evals); + let com_f_s_poly = powers.commit_scalars_g1(&evaluations.evals); let commitment_pow_challenge = com_f_s_poly * challenge; let com_z = powers.commit_scalars_g1(&z_scalars); let t_expected = com_z - commitment_pow_challenge; diff --git a/src/veck/server.rs b/src/veck/server.rs new file mode 100644 index 0000000..e69de29 From 6a3d3a1705a9e701d43d92945cfc77aeffff43ec Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Sat, 20 Jan 2024 17:53:32 +0100 Subject: [PATCH 06/18] Wip. --- src/veck/kzg_paillier.rs | 10 ++---- src/veck/mod.rs | 66 +++++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/veck/kzg_paillier.rs b/src/veck/kzg_paillier.rs index 07b9a73..68c9cb9 100644 --- a/src/veck/kzg_paillier.rs +++ b/src/veck/kzg_paillier.rs @@ -184,8 +184,6 @@ pub struct Proof { pub w_vec: Vec, pub z_vec: Vec, pub com_q_poly: C::G1, - pub t_vec: Vec, - pub t: C::G1, _digest: PhantomData, _curve: PhantomData, } @@ -246,8 +244,6 @@ impl Proof { w_vec, z_vec, com_q_poly, - t_vec, - t, _digest: PhantomData, _curve: PhantomData, } @@ -286,7 +282,6 @@ impl Proof { (aux * ct_pow_minus_c) % &modulo }) .collect(); - assert_eq!(self.t_vec, t_vec_expected, "t_vec is shit"); let z_scalar_vec: Vec = self .z_vec .iter() @@ -299,7 +294,6 @@ impl Proof { let commitment_pow_challenge = *com_f_s_poly * challenge_scalar; let msm = powers.commit_scalars_g1(&z_scalar_vec); let t_expected = msm - commitment_pow_challenge; - assert_eq!(self.t, t_expected, "t is shit"); let challenge_expected = challenge::( pubkey, @@ -338,8 +332,8 @@ mod test { use ark_std::{test_rng, One, UniformRand}; use num_bigint::{BigUint, RandomBits}; - const DATA_SIZE: usize = 32; - const SUBSET_SIZE: usize = 8; + const DATA_SIZE: usize = 16; + const SUBSET_SIZE: usize = 16; #[test] fn compute_modular_inverse() { diff --git a/src/veck/mod.rs b/src/veck/mod.rs index 65c4a20..a03776a 100644 --- a/src/veck/mod.rs +++ b/src/veck/mod.rs @@ -10,6 +10,28 @@ use ark_poly::univariate::DensePolynomial; use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; use ark_std::collections::HashMap; +fn index_map(domain: GeneralEvaluationDomain) -> HashMap { + domain.elements().enumerate().map(|(i, e)| (e, i)).collect() +} + +fn subset_evals( + evaluations: &Evaluations, + index_map: &HashMap, + subdomain: GeneralEvaluationDomain, +) -> Evaluations { + debug_assert!(evaluations.domain().size() >= subdomain.size()); + let indices = subdomain + .elements() + .map(|e| *index_map.get(&e).unwrap()) + .collect::>(); + let mut subset_evals = Vec::::new(); + for index in indices { + subset_evals.push(evaluations.evals[index]); + } + Evaluations::from_vec_and_domain(subset_evals, subdomain) +} + +/* fn subset_pairing_check( phi: &DensePolynomial, phi_s: &DensePolynomial, @@ -46,29 +68,20 @@ fn subset_pairing_check( assert_eq!(lhs_pairing, rhs_pairing); } -fn index_map(domain: GeneralEvaluationDomain) -> HashMap { - domain - .elements() - .enumerate() - .map(|(i, e)| (e, i)) - .collect() -} -fn subset_evals( +fn subset_evals_zero_pad( evaluations: &Evaluations, - index_map: &HashMap, - subdomain: GeneralEvaluationDomain, + sub_index_map: &HashMap, ) -> Evaluations { - debug_assert!(evaluations.domain().size() >= subdomain.size()); - let indices = subdomain - .elements() - .map(|e| *index_map.get(&e).unwrap()) - .collect::>(); let mut subset_evals = Vec::::new(); - for index in indices { - subset_evals.push(evaluations.evals[index]); + for (x, eval) in evaluations.domain().elements().zip(&evaluations.evals) { + if sub_index_map.contains_key(&x) { + subset_evals.push(*eval); + } else { + subset_evals.push(S::zero()) + } } - Evaluations::from_vec_and_domain(subset_evals, subdomain) + Evaluations::from_vec_and_domain(subset_evals, evaluations.domain()) } #[cfg(test)] @@ -77,8 +90,8 @@ mod test { use crate::tests::{BlsCurve, Scalar}; use ark_std::{test_rng, UniformRand}; - const DATA_SIZE: usize = 8; - const SUBSET_SIZE: usize = 4; + const DATA_SIZE: usize = 4; + const SUBSET_SIZE: usize = 2; #[test] fn mivan() { @@ -91,11 +104,14 @@ mod test { let data = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); let evaluations = Evaluations::from_vec_and_domain(data, domain); - let index_map = index_map(domain); - let subset_evaluations = subset_evals(&evaluations, &index_map, subdomain); + let im = index_map(domain); + let sub_im = index_map(subdomain); + let subset_evaluations = subset_evals(&evaluations, &im, subdomain); + let subset_evaluations_zero_pad = subset_evals_zero_pad(&evaluations, &sub_im); let phi = evaluations.interpolate_by_ref(); - let phi_s = subset_evaluations.interpolate_by_ref(); + let phi_s_expected = dbg!(subset_evaluations.interpolate_by_ref()); + let phi_s = subset_evaluations_zero_pad.interpolate_by_ref(); subset_pairing_check(&phi, &phi_s, &domain, &subdomain, &powers); let r_scalars: Vec = (0..SUBSET_SIZE).map(|_| Scalar::rand(rng)).collect(); @@ -106,10 +122,12 @@ mod test { .zip(&subset_evaluations.evals) .map(|(&r, &v)| r + challenge * v) .collect(); - let com_f_s_poly = powers.commit_scalars_g1(&evaluations.evals); + let com_f_s_poly = dbg!(powers.commit_scalars_g1(&subset_evaluations.evals)); + let com_f_s_poly = dbg!(powers.commit_scalars_g1(&subset_evaluations_zero_pad.evals)); let commitment_pow_challenge = com_f_s_poly * challenge; let com_z = powers.commit_scalars_g1(&z_scalars); let t_expected = com_z - commitment_pow_challenge; assert_eq!(t, t_expected); } } +*/ From 1dbc742a5ccd63cb72ab1aaee06574206580acc4 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Sat, 20 Jan 2024 18:32:44 +0100 Subject: [PATCH 07/18] wipp --- benches/kzg_paillier.rs | 27 +++++++++++++++++++++++++++ src/veck/kzg/elgamal.rs | 0 src/veck/kzg/mod.rs | 2 -- src/veck/kzg/paillier.rs | 0 src/veck/kzg_paillier.rs | 28 ++++++++++------------------ src/veck/server.rs | 21 +++++++++++++++++++++ 6 files changed, 58 insertions(+), 20 deletions(-) create mode 100644 benches/kzg_paillier.rs delete mode 100644 src/veck/kzg/elgamal.rs delete mode 100644 src/veck/kzg/mod.rs delete mode 100644 src/veck/kzg/paillier.rs diff --git a/benches/kzg_paillier.rs b/benches/kzg_paillier.rs new file mode 100644 index 0000000..a84fffc --- /dev/null +++ b/benches/kzg_paillier.rs @@ -0,0 +1,27 @@ +use ark_bls12_381::Bls12_381 as BlsCurve; +use ark_ec::pairing::Pairing; +use ark_ec::{CurveGroup, Group}; +use ark_ff::PrimeField; +use ark_poly::univariate::DensePolynomial; +use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; +use ark_std::{test_rng, UniformRand}; +use criterion::{criterion_group, criterion_main, Criterion}; +use fde::commit::kzg::Powers; + +type Scalar = ::ScalarField; +type UniPoly = DensePolynomial; +type Proof = fde::veck::kzg_paillier::Proof<{ N }, BlsCurve, sha3::Keccak256>; + +fn bench_proof(c: &mut Criterion) { + let mut group = c.benchmark_group("kzg-paillier"); + + let rng = &mut test_rng(); + let tau = Scalar::rand(rng); + let powers = Powers::::unsafe_setup(tau, data_size + 1); + + todo!() + group.finish(); +} + +criterion_group!(benches, bench_proof); +criterion_main!(benches); diff --git a/src/veck/kzg/elgamal.rs b/src/veck/kzg/elgamal.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/veck/kzg/mod.rs b/src/veck/kzg/mod.rs deleted file mode 100644 index aa1c7aa..0000000 --- a/src/veck/kzg/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod elgamal; -mod paillier; diff --git a/src/veck/kzg/paillier.rs b/src/veck/kzg/paillier.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/veck/kzg_paillier.rs b/src/veck/kzg_paillier.rs index 68c9cb9..d39993f 100644 --- a/src/veck/kzg_paillier.rs +++ b/src/veck/kzg_paillier.rs @@ -308,12 +308,17 @@ impl Proof { } pub fn decrypt(&self, server: &Server) -> Vec { - let modulo = server.modulo_n2(); - let denominator = server.decryption_denominator(); + let modulo = &server.pubkey * &server.pubkey; + let denominator = ((&server.pubkey + BigUint::one()).modpow(&server.privkey, &modulo) + - BigUint::one()) + / &server.pubkey; + let denominator_inv = modular_inverse(&denominator, &server.pubkey).unwrap(); self.ct_vec .iter() .map(|ct| { - (server.lx(&ct.modpow(&server.privkey, &modulo)) / &denominator) % &server.pubkey + ((ct.modpow(&server.privkey, &modulo) - BigUint::one()) / &server.pubkey + * &denominator_inv) + % &server.pubkey }) .collect() } @@ -402,21 +407,8 @@ mod test { &server.pubkey, &powers )); - let modulo = &server.pubkey * &server.pubkey; - let denominator = ((&server.pubkey + BigUint::one()).modpow(&server.privkey, &modulo) - - BigUint::one()) - / &server.pubkey; - let denominator_inv = modular_inverse(&denominator, &server.pubkey).unwrap(); - let decrypted_data: Vec = proof - .ct_vec - .iter() - .map(|ct| { - ((ct.modpow(&server.privkey, &modulo) - BigUint::one()) / &server.pubkey - * &denominator_inv) - % &server.pubkey - }) - .collect(); - //let decrypted_data = proof.decrypt(&server); + + let decrypted_data = proof.decrypt(&server); assert_eq!(decrypted_data, data_biguint); } } diff --git a/src/veck/server.rs b/src/veck/server.rs index e69de29..067bc0a 100644 --- a/src/veck/server.rs +++ b/src/veck/server.rs @@ -0,0 +1,21 @@ +pub struct Server { + +} + +// SERVER +// encryption keys +// data of length N +// interpolate polynomial +// index map for subset generation + +// PUBLIC PARAMETERS FOR ELGAMAL - GENERATE ONCE +// cipertexts +// short ciphertexts +// range proofs +// random encryption points +// decrypt - only for elgamal? brute force? + +// PROOF +// new +// verify +// decrypt - only for paillier? From 3a1ef71555643cae9424d5d092c6dfe2d12a4dde Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Sun, 21 Jan 2024 17:53:13 +0100 Subject: [PATCH 08/18] Small elgamal cleanup. --- src/lib.rs | 2 + src/tests/mod.rs | 2 +- src/veck/kzg_elgamal.rs | 163 ++++++++++++++++++++++++++++----------- src/veck/kzg_paillier.rs | 1 - src/veck/mod.rs | 8 +- 5 files changed, 127 insertions(+), 49 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1d46b0f..074ab3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,4 +20,6 @@ pub enum Error { InvalidFftDomain(usize), #[error(transparent)] RangeProof(#[from] range_proof::RangeProofError), + #[error(transparent)] + KzgElgamalProofError(#[from] veck::kzg_elgamal::KzgElgamalError), } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index b6dbfba..3453cb4 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -12,7 +12,7 @@ pub type SplitScalar = crate::encrypt::elgamal::SplitScalar<{ N }, Scalar>; pub type UniPoly = DensePolynomial; pub type Elgamal = crate::encrypt::elgamal::ExponentialElgamal<::G1>; -pub type PublicInput = crate::veck::kzg_elgamal::PublicInput<{ N }, BlsCurve, Keccak256>; +pub type ElgamalEncryptionProof = crate::veck::kzg_elgamal::EncryptionProof<{ N }, BlsCurve, Keccak256>; pub type KzgElgamalProof = crate::veck::kzg_elgamal::Proof<{ N }, BlsCurve, Keccak256>; pub type DleqProof = crate::dleq::Proof<::G1, Keccak256>; pub type RangeProof = crate::range_proof::RangeProof; diff --git a/src/veck/kzg_elgamal.rs b/src/veck/kzg_elgamal.rs index fd4da7e..20ad249 100644 --- a/src/veck/kzg_elgamal.rs +++ b/src/veck/kzg_elgamal.rs @@ -4,6 +4,7 @@ use crate::encrypt::elgamal::{Cipher, ExponentialElgamal as Elgamal, SplitScalar use crate::encrypt::EncryptionEngine; use crate::hash::Hasher; use crate::range_proof::RangeProof; +use crate::Error; use ark_ec::pairing::Pairing; use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM as Msm}; use ark_ff::PrimeField; @@ -15,14 +16,38 @@ use ark_std::marker::PhantomData; use ark_std::rand::Rng; use digest::Digest; -pub struct PublicInput { +use thiserror::Error as ErrorT; + +#[derive(Debug, ErrorT, PartialEq)] +pub enum KzgElgamalError { + #[error("invalid DLEQ proof for split encryption points")] + InvalidDleqProof, + #[error("invalid KZG proof")] + InvalidKzgProof, + #[error("invalid subset polynomial proof")] + InvalidSubsetPolynomial, + #[error("invalid split scalar verification")] + InvalidSplitScalars, +} + +/// A publicly verifiable proof based on the Elgamal encryption scheme. +pub struct EncryptionProof { + /// The actual Elgamal ciphertexts of the encrypted data points. pub ciphers: Vec>, + /// Each ciphertext is split into a set of scalars that, once decrypted, can reconstruct the + /// original data point. Since we use the exponential Elgamal encryption scheme, these "short" + /// ciphertexts are needed to encrypt split data points in the bruteforceable range: 2^32. pub short_ciphers: Vec<[Cipher; N]>, + /// Each "short" ciphertext requires a range proof proving that the encrypted value is in the + /// bruteforceable range. pub range_proofs: Vec<[RangeProof; N]>, + /// Random encryption points used to encrypt the original data points. These are the `h^r` + /// values in the exponential Elgamal scheme: `e = g^m * h^r`, where `e` is the ciphertext, `m` + /// is the plaintext. pub random_encryption_points: Vec, } -impl PublicInput { +impl EncryptionProof { pub fn new( evaluations: &[C::ScalarField], encryption_pk: & as EncryptionEngine>::EncryptionKey, @@ -36,9 +61,9 @@ impl PublicInput { for eval in evaluations { let split_eval = SplitScalar::from(*eval); - let rp = split_eval - .splits() - .map(|s| RangeProof::new(s, MAX_BITS, powers, rng).unwrap()); + let rp = split_eval.splits().map(|s| { + RangeProof::new(s, MAX_BITS, powers, rng).expect("invalid range proof input") + }); let (sc, rand) = split_eval.encrypt::, _>(encryption_pk, rng); let cipher = as EncryptionEngine>::encrypt_with_randomness( eval, @@ -59,6 +84,10 @@ impl PublicInput { } } + /// Generates a subset from the total encrypted data. + /// + /// Clients might not be interested in the whole dataset, thus the server may generate a subset + /// encryption proof to reduce proof verification costs. pub fn subset(&self, indices: &[usize]) -> Self { let size = indices.len(); let mut ciphers = Vec::with_capacity(size); @@ -79,13 +108,36 @@ impl PublicInput { random_encryption_points, } } + + /// Checks that the sum of split scalars evaluate to the encrypted value via the homomorphic + /// properties of Elgamal encryption. + pub fn verify_split_scalars(&self) -> bool { + for (cipher, short_cipher) in self.ciphers.iter().zip(&self.short_ciphers) { + if !cipher.check_encrypted_sum(short_cipher) { + return false; + } + } + true + } + + // TODO range proofs and short ciphers are not "connected" by anything? + // TODO parallelize + pub fn verify_range_proofs(&self, powers: &Powers) -> bool { + for rps in self.range_proofs.iter() { + if !rps.iter().all(|rp| rp.verify(MAX_BITS, powers).is_ok()) { + return false + } + } + true + } } -pub struct Proof { - challenge_eval_commitment: C::G1Affine, - challenge_opening_proof: C::G1Affine, - dleq_proof: DleqProof, - com_f_q_poly: C::G1Affine, +pub struct Proof { + pub encryption_proof: EncryptionProof, + pub challenge_eval_commitment: C::G1Affine, + pub challenge_opening_proof: C::G1Affine, + pub dleq_proof: DleqProof, + pub com_f_q_poly: C::G1Affine, _poly: PhantomData>, _digest: PhantomData, } @@ -99,18 +151,19 @@ where f_poly: &DensePolynomial, f_s_poly: &DensePolynomial, encryption_sk: &C::ScalarField, - input: &PublicInput, + encryption_proof: EncryptionProof, powers: &Powers, rng: &mut R, - ) -> Self { + ) -> Result { let mut hasher = Hasher::::new(); - input + encryption_proof .ciphers .iter() .for_each(|cipher| hasher.update(&cipher.c1())); - let domain = GeneralEvaluationDomain::::new(input.ciphers.len()) - .expect("valid domain"); + let domain_size = encryption_proof.ciphers.len(); + let domain = GeneralEvaluationDomain::::new(domain_size) + .ok_or(Error::InvalidFftDomain(domain_size))?; // challenge and KZG proof let challenge = C::ScalarField::from_le_bytes_mod_order(&hasher.finalize()); @@ -118,17 +171,21 @@ where let challenge_opening_proof = Kzg::proof(f_s_poly, challenge, challenge_eval, powers); let challenge_eval_commitment = (C::G1Affine::generator() * challenge_eval).into_affine(); - // subset polynomial KZG commitment + // NOTE According to the docs this should always return Some((q, rem)), so unwrap is fine + // https://docs.rs/ark-poly/latest/src/ark_poly/polynomial/univariate/dense.rs.html#144 let f_q_poly = (f_poly - f_s_poly) .divide_by_vanishing_poly(domain) .unwrap() .0; + // subset polynomial KZG commitment let com_f_q_poly = powers.commit_g1(&f_q_poly).into(); // DLEQ proof let lagrange_evaluations = &domain.evaluate_all_lagrange_coefficients(challenge); - let q_point: C::G1 = - Msm::msm_unchecked(&input.random_encryption_points, lagrange_evaluations); + let q_point: C::G1 = Msm::msm_unchecked( + &encryption_proof.random_encryption_points, + lagrange_evaluations, + ); let dleq_proof = DleqProof::new( encryption_sk, @@ -137,14 +194,15 @@ where rng, ); - Self { + Ok(Self { + encryption_proof, challenge_eval_commitment, challenge_opening_proof, dleq_proof, com_f_q_poly, _poly: PhantomData, _digest: PhantomData, - } + }) } pub fn verify( @@ -152,11 +210,11 @@ where com_f_poly: C::G1, com_f_s_poly: C::G1, encryption_pk: C::G1Affine, - input: &PublicInput, powers: &Powers, - ) -> bool { + ) -> Result<(), Error> { let mut hasher = Hasher::::new(); - let c1_points: Vec = input + let c1_points: Vec = self + .encryption_proof .ciphers .iter() .map(|cipher| { @@ -166,8 +224,10 @@ where }) .collect(); let challenge = C::ScalarField::from_le_bytes_mod_order(&hasher.finalize()); - let domain = GeneralEvaluationDomain::::new(input.ciphers.len()) - .expect("valid domain"); + let domain_size = self.encryption_proof.ciphers.len(); + let domain = + GeneralEvaluationDomain::::new(domain_size) + .ok_or(Error::InvalidFftDomain(domain_size))?; // polynomial division check via vanishing polynomial let vanishing_poly = DensePolynomial::from(domain.vanishing_polynomial()); @@ -180,8 +240,10 @@ where // DLEQ check let lagrange_evaluations = &domain.evaluate_all_lagrange_coefficients(challenge); - let q_point: C::G1 = - Msm::msm_unchecked(&input.random_encryption_points, lagrange_evaluations); // Q + let q_point: C::G1 = Msm::msm_unchecked( + &self.encryption_proof.random_encryption_points, + lagrange_evaluations, + ); // Q let ct_point: C::G1 = Msm::msm_unchecked(&c1_points, lagrange_evaluations); // C_t let q_star = ct_point - self.challenge_eval_commitment; // Q* = C_t / C_alpha @@ -202,7 +264,18 @@ where powers, ); - dleq_check && kzg_check && subset_pairing_check + // check split scalar encryption validity + // check that split scalars are in a brute-forceable range + + if !dleq_check { + Err(KzgElgamalError::InvalidDleqProof.into()) + } else if !kzg_check { + Err(KzgElgamalError::InvalidKzgProof.into()) + } else if !subset_pairing_check { + Err(KzgElgamalError::InvalidSubsetPolynomial.into()) + } else { + Ok(()) + } } } @@ -210,7 +283,7 @@ where mod test { use crate::commit::kzg::Powers; use crate::encrypt::elgamal::MAX_BITS; - use crate::tests::{BlsCurve, KzgElgamalProof, PublicInput, Scalar, UniPoly}; + use crate::tests::*; use ark_ec::pairing::Pairing; use ark_ec::{CurveGroup, Group}; use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; @@ -233,9 +306,9 @@ mod test { // Generate random data and public inputs (encrypted data, etc) let data: Vec = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); - let input = PublicInput::new(&data, &encryption_pk, &powers, rng); + let encryption_proof = ElgamalEncryptionProof::new(&data, &encryption_pk, &powers, rng); - input + encryption_proof .range_proofs .iter() .for_each(|rps| assert!(rps.iter().all(|rp| rp.verify(MAX_BITS, &powers).is_ok()))); @@ -266,18 +339,22 @@ mod test { let f_s_poly: UniPoly = sub_evaluations.interpolate_by_ref(); let com_f_s_poly = powers.commit_g1(&f_s_poly); - let sub_input = input.subset(&sub_indices); - sub_input - .range_proofs - .iter() - .for_each(|rps| assert!(rps.iter().all(|rp| rp.verify(MAX_BITS, &powers).is_ok()))); - - let proof = - KzgElgamalProof::new(&f_poly, &f_s_poly, &encryption_sk, &sub_input, &powers, rng); - assert!(proof.verify(com_f_poly, com_f_s_poly, encryption_pk, &sub_input, &powers)); + let sub_encryption_proof = encryption_proof.subset(&sub_indices); - for (cipher, short_cipher) in sub_input.ciphers.iter().zip(&sub_input.short_ciphers) { - assert!(cipher.check_encrypted_sum(short_cipher)); - } + let proof = KzgElgamalProof::new( + &f_poly, + &f_s_poly, + &encryption_sk, + sub_encryption_proof, + &powers, + rng, + ) + .unwrap(); + assert!(proof.verify( + com_f_poly, + com_f_s_poly, + encryption_pk, + &powers + ).is_ok()); } } diff --git a/src/veck/kzg_paillier.rs b/src/veck/kzg_paillier.rs index d39993f..c5575d6 100644 --- a/src/veck/kzg_paillier.rs +++ b/src/veck/kzg_paillier.rs @@ -332,7 +332,6 @@ mod test { use crate::tests::{BlsCurve, PaillierEncryptionProof, Scalar, UniPoly}; use ark_ff::{BigInteger, PrimeField}; use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; - use ark_std::collections::HashMap; use ark_std::rand::distributions::Distribution; use ark_std::{test_rng, One, UniformRand}; use num_bigint::{BigUint, RandomBits}; diff --git a/src/veck/mod.rs b/src/veck/mod.rs index a03776a..601ee0a 100644 --- a/src/veck/mod.rs +++ b/src/veck/mod.rs @@ -2,11 +2,7 @@ pub mod kzg_elgamal; #[cfg(feature = "paillier")] pub mod kzg_paillier; -use crate::commit::kzg::Powers; -use ark_ec::pairing::Pairing; -use ark_ec::Group; use ark_ff::FftField; -use ark_poly::univariate::DensePolynomial; use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; use ark_std::collections::HashMap; @@ -32,6 +28,10 @@ fn subset_evals( } /* +use crate::commit::kzg::Powers; +use ark_ec::pairing::Pairing; +use ark_ec::Group; +use ark_poly::univariate::DensePolynomial; fn subset_pairing_check( phi: &DensePolynomial, phi_s: &DensePolynomial, From d661e12932a1869996e7bb86a6a5069693126ca1 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Sun, 21 Jan 2024 19:58:30 +0100 Subject: [PATCH 09/18] wip paillier. --- src/veck/kzg_elgamal.rs | 39 +++++++++++++------------------------- src/veck/kzg_paillier.rs | 41 ++++++++++++++++++++-------------------- src/veck/mod.rs | 18 ++++++++++++------ 3 files changed, 46 insertions(+), 52 deletions(-) diff --git a/src/veck/kzg_elgamal.rs b/src/veck/kzg_elgamal.rs index 20ad249..636b3c3 100644 --- a/src/veck/kzg_elgamal.rs +++ b/src/veck/kzg_elgamal.rs @@ -125,7 +125,7 @@ impl EncryptionProof { pub fn verify_range_proofs(&self, powers: &Powers) -> bool { for rps in self.range_proofs.iter() { if !rps.iter().all(|rp| rp.verify(MAX_BITS, powers).is_ok()) { - return false + return false; } } true @@ -225,9 +225,8 @@ where .collect(); let challenge = C::ScalarField::from_le_bytes_mod_order(&hasher.finalize()); let domain_size = self.encryption_proof.ciphers.len(); - let domain = - GeneralEvaluationDomain::::new(domain_size) - .ok_or(Error::InvalidFftDomain(domain_size))?; + let domain = GeneralEvaluationDomain::::new(domain_size) + .ok_or(Error::InvalidFftDomain(domain_size))?; // polynomial division check via vanishing polynomial let vanishing_poly = DensePolynomial::from(domain.vanishing_polynomial()); @@ -287,7 +286,6 @@ mod test { use ark_ec::pairing::Pairing; use ark_ec::{CurveGroup, Group}; use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; - use ark_std::collections::HashMap; use ark_std::{test_rng, UniformRand}; const DATA_SIZE: usize = 16; @@ -314,9 +312,7 @@ mod test { .for_each(|rps| assert!(rps.iter().all(|rp| rp.verify(MAX_BITS, &powers).is_ok()))); let domain = GeneralEvaluationDomain::new(data.len()).expect("valid domain"); - - let index_map: HashMap = - domain.elements().enumerate().map(|(i, e)| (e, i)).collect(); + let index_map = super::super::index_map(domain); // Interpolate original polynomial and compute its KZG commitment. // This is performed only once by the server @@ -326,20 +322,14 @@ mod test { // get subdomain with size suitable for interpolating a polynomial with SUBSET_SIZE // coefficients - let sub_domain = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); - let sub_indices = sub_domain - .elements() - .map(|elem| *index_map.get(&elem).unwrap()) - .collect::>(); - let sub_data = sub_indices - .iter() - .map(|&i| evaluations.evals[i]) - .collect::>(); - let sub_evaluations = Evaluations::from_vec_and_domain(sub_data, sub_domain); - let f_s_poly: UniPoly = sub_evaluations.interpolate_by_ref(); + let subdomain = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); + let subset_indices = super::super::subset_indices(&index_map, &subdomain); + let subset_evaluations = + super::super::subset_evals(&evaluations, &subset_indices, subdomain); + let f_s_poly: UniPoly = subset_evaluations.interpolate_by_ref(); let com_f_s_poly = powers.commit_g1(&f_s_poly); - let sub_encryption_proof = encryption_proof.subset(&sub_indices); + let sub_encryption_proof = encryption_proof.subset(&subset_indices); let proof = KzgElgamalProof::new( &f_poly, @@ -350,11 +340,8 @@ mod test { rng, ) .unwrap(); - assert!(proof.verify( - com_f_poly, - com_f_s_poly, - encryption_pk, - &powers - ).is_ok()); + assert!(proof + .verify(com_f_poly, com_f_s_poly, encryption_pk, &powers) + .is_ok()); } } diff --git a/src/veck/kzg_paillier.rs b/src/veck/kzg_paillier.rs index c5575d6..49510e0 100644 --- a/src/veck/kzg_paillier.rs +++ b/src/veck/kzg_paillier.rs @@ -20,8 +20,11 @@ const N_BITS: u64 = 1024; #[derive(Debug)] pub struct Server { - pub pubkey: BigUint, + pub p_prime: BigUint, + pub q_prime: BigUint, pub privkey: BigUint, + pub pubkey: BigUint, + pub mod_n2: BigUint, } impl Server { @@ -30,23 +33,25 @@ impl Server { // "N_BITS" number of bits let (p, q) = primes(N_BITS >> 1, rng); let pubkey = &p * &q; - let privkey = (p - BigUint::one()).lcm(&(q - BigUint::one())); + let privkey = (&p - BigUint::one()).lcm(&(&q - BigUint::one())); + let mod_n2 = &pubkey * &pubkey; - Self { pubkey, privkey } - } - pub fn modulo_n2(&self) -> BigUint { - &self.pubkey * &self.pubkey + Self { + p_prime: p, + q_prime: q, + privkey, + pubkey, + mod_n2, + } } pub fn lx(&self, x: &BigUint) -> BigUint { - let modulo = self.modulo_n2(); - debug_assert!(x < &modulo && (x % &self.pubkey) == BigUint::one()); + debug_assert!(x < &self.mod_n2 && (x % &self.pubkey) == BigUint::one()); (x - BigUint::one()) / &self.pubkey } pub fn decryption_denominator(&self) -> BigUint { - let n_plus_1_pow_sk = - (&self.pubkey + BigUint::one()).modpow(&self.privkey, &self.modulo_n2()); + let n_plus_1_pow_sk = (&self.pubkey + BigUint::one()).modpow(&self.privkey, &self.mod_n2); self.lx(&n_plus_1_pow_sk) } } @@ -308,17 +313,13 @@ impl Proof { } pub fn decrypt(&self, server: &Server) -> Vec { - let modulo = &server.pubkey * &server.pubkey; - let denominator = ((&server.pubkey + BigUint::one()).modpow(&server.privkey, &modulo) - - BigUint::one()) - / &server.pubkey; + let denominator = server.decryption_denominator(); let denominator_inv = modular_inverse(&denominator, &server.pubkey).unwrap(); self.ct_vec .iter() .map(|ct| { - ((ct.modpow(&server.privkey, &modulo) - BigUint::one()) / &server.pubkey - * &denominator_inv) - % &server.pubkey + let ct_lx = server.lx(&ct.modpow(&server.privkey, &server.mod_n2)); + (ct_lx * &denominator_inv) % &server.pubkey }) .collect() } @@ -326,7 +327,6 @@ impl Proof { #[cfg(test)] mod test { - use super::super::{index_map, subset_evals}; use super::{modular_inverse, Server, N_BITS}; use crate::commit::kzg::Powers; use crate::tests::{BlsCurve, PaillierEncryptionProof, Scalar, UniPoly}; @@ -368,8 +368,9 @@ mod test { let domain = GeneralEvaluationDomain::new(DATA_SIZE).unwrap(); let domain_s = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); let evaluations = Evaluations::from_vec_and_domain(data, domain); - let index_map = index_map(domain); - let evaluations_s = subset_evals(&evaluations, &index_map, domain_s); + let index_map = super::super::index_map(domain); + let subset_indices = super::super::subset_indices(&index_map, &domain_s); + let evaluations_s = super::super::subset_evals(&evaluations, &subset_indices, domain_s); let f_poly: UniPoly = evaluations.interpolate_by_ref(); let f_s_poly: UniPoly = evaluations_s.interpolate_by_ref(); diff --git a/src/veck/mod.rs b/src/veck/mod.rs index 601ee0a..8011a18 100644 --- a/src/veck/mod.rs +++ b/src/veck/mod.rs @@ -10,18 +10,24 @@ fn index_map(domain: GeneralEvaluationDomain) -> HashMap( + index_map: &HashMap, + subdomain: &GeneralEvaluationDomain, +) -> Vec { + subdomain + .elements() + .map(|e| *index_map.get(&e).unwrap()) + .collect() +} + fn subset_evals( evaluations: &Evaluations, - index_map: &HashMap, + indices: &[usize], subdomain: GeneralEvaluationDomain, ) -> Evaluations { debug_assert!(evaluations.domain().size() >= subdomain.size()); - let indices = subdomain - .elements() - .map(|e| *index_map.get(&e).unwrap()) - .collect::>(); let mut subset_evals = Vec::::new(); - for index in indices { + for &index in indices { subset_evals.push(evaluations.evals[index]); } Evaluations::from_vec_and_domain(subset_evals, subdomain) From b8f08034748953545b9d4fb0d4875048ffae5c03 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Sun, 21 Jan 2024 22:54:25 +0100 Subject: [PATCH 10/18] Koolio. --- Cargo.toml | 31 +- benches/kzg_paillier.rs | 2 +- src/commit/kzg.rs | 3 - src/dleq.rs | 5 +- src/encrypt/elgamal/mod.rs | 11 +- src/encrypt/elgamal/split_scalar.rs | 13 +- src/encrypt/mod.rs | 4 - src/lib.rs | 6 +- src/range_proof/mod.rs | 57 +-- src/range_proof/poly.rs | 32 +- src/tests/mod.rs | 11 +- src/veck/kzg/elgamal/encryption.rs | 110 +++++ .../{kzg_elgamal.rs => kzg/elgamal/mod.rs} | 146 +----- src/veck/kzg/mod.rs | 2 + src/veck/kzg/paillier/encrypt.rs | 33 ++ src/veck/kzg/paillier/mod.rs | 255 +++++++++++ src/veck/kzg/paillier/random.rs | 31 ++ src/veck/kzg/paillier/server.rs | 70 +++ src/veck/kzg/paillier/utils.rs | 86 ++++ src/veck/kzg_paillier.rs | 414 ------------------ src/veck/mod.rs | 15 +- src/veck/server.rs | 21 - 22 files changed, 711 insertions(+), 647 deletions(-) create mode 100644 src/veck/kzg/elgamal/encryption.rs rename src/veck/{kzg_elgamal.rs => kzg/elgamal/mod.rs} (58%) create mode 100644 src/veck/kzg/mod.rs create mode 100644 src/veck/kzg/paillier/encrypt.rs create mode 100644 src/veck/kzg/paillier/mod.rs create mode 100644 src/veck/kzg/paillier/random.rs create mode 100644 src/veck/kzg/paillier/server.rs create mode 100644 src/veck/kzg/paillier/utils.rs delete mode 100644 src/veck/kzg_paillier.rs delete mode 100644 src/veck/server.rs diff --git a/Cargo.toml b/Cargo.toml index bff90ad..5615914 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" opt-level = 3 [features] -default = ["std", "parallel", "paillier"] +default = ["std", "parallel"] std = [ "ark-crypto-primitives/std", "ark-ec/std", @@ -26,11 +26,6 @@ parallel = [ "ark-std/parallel", "rayon" ] -paillier = [ - "num-bigint", - "num-integer", - "num-prime", -] [dependencies] ark-crypto-primitives = { version = "0.4", default-features = false, features = ["signature"] } @@ -40,9 +35,9 @@ ark-poly = { version = "0.4", default-features = false } ark-poly-commit = { version = "0.4", default-features = false } ark-serialize = { version = "0.4", default-features = false } ark-std = { version = "0.4", default-features = false } -num-bigint = { version = "0.4", features = ["rand"], optional = true } -num-integer = { version = "0.1", optional = true } -num-prime = { version = "0.4", optional = true } +num-bigint = { version = "0.4", features = ["rand"] } +num-integer = "0.1" +num-prime = "0.4" digest = { version = "0.10", default-features = false } rayon = { version = "1.8", optional = true } thiserror = "1" @@ -53,12 +48,12 @@ ark-secp256k1 = "0.4" criterion = "0.5" sha3 = "0.10" -[[bench]] -name = "kzg-elgamal-veck" -path = "benches/kzg_elgamal.rs" -harness = false - -[[bench]] -name = "split-elgamal-encryption" -path = "benches/elgamal.rs" -harness = false +#[[bench]] +#name = "kzg-elgamal-veck" +#path = "benches/kzg_elgamal.rs" +#harness = false +# +#[[bench]] +#name = "split-elgamal-encryption" +#path = "benches/elgamal.rs" +#harness = false diff --git a/benches/kzg_paillier.rs b/benches/kzg_paillier.rs index a84fffc..4b4fdcb 100644 --- a/benches/kzg_paillier.rs +++ b/benches/kzg_paillier.rs @@ -19,7 +19,7 @@ fn bench_proof(c: &mut Criterion) { let tau = Scalar::rand(rng); let powers = Powers::::unsafe_setup(tau, data_size + 1); - todo!() + todo!(); group.finish(); } diff --git a/src/commit/kzg.rs b/src/commit/kzg.rs index 7bf48db..5b0f944 100644 --- a/src/commit/kzg.rs +++ b/src/commit/kzg.rs @@ -9,9 +9,6 @@ use ark_std::marker::PhantomData; use ark_std::rand::Rng; use ark_std::{One, UniformRand, Zero}; -pub struct PowersOfTau; -pub struct LagrangeBasis; - pub struct Powers { pub g1: Vec, pub g2: Vec, diff --git a/src/dleq.rs b/src/dleq.rs index 7da7a17..fbe5de7 100644 --- a/src/dleq.rs +++ b/src/dleq.rs @@ -60,10 +60,13 @@ where #[cfg(test)] mod test { - use crate::tests::{DleqProof, G1Affine, Scalar}; + use super::*; + use crate::tests::{G1Affine, Scalar, TestCurve, TestHash}; use ark_ec::{AffineRepr, CurveGroup}; use ark_std::{test_rng, UniformRand}; + type DleqProof = Proof<::G1, TestHash>; + #[test] fn completeness() { let rng = &mut test_rng(); diff --git a/src/encrypt/elgamal/mod.rs b/src/encrypt/elgamal/mod.rs index a1a26d0..bd5926b 100644 --- a/src/encrypt/elgamal/mod.rs +++ b/src/encrypt/elgamal/mod.rs @@ -5,7 +5,7 @@ pub use split_scalar::SplitScalar; use utils::shift_scalar; use super::EncryptionEngine; -use ark_ec::{AffineRepr, CurveGroup}; //, ScalarMul, VariableBaseMSM as Msm}; +use ark_ec::{AffineRepr, CurveGroup}; use ark_std::marker::PhantomData; use ark_std::ops::{Add, Mul}; use ark_std::rand::Rng; @@ -122,11 +122,14 @@ impl ExponentialElgamal { #[cfg(test)] mod test { - use crate::encrypt::EncryptionEngine; - use crate::tests::{Elgamal, G1Affine, Scalar, SplitScalar}; + use super::*; + use crate::tests::{G1Affine, Scalar, TestCurve, N}; + use ark_ec::pairing::Pairing; use ark_ec::{AffineRepr, CurveGroup}; use ark_std::{test_rng, UniformRand}; + type Elgamal = ExponentialElgamal<::G1>; + #[test] fn exponential_elgamal() { let rng = &mut test_rng(); @@ -197,7 +200,7 @@ mod test { fn split_encryption() { let rng = &mut test_rng(); let scalar = Scalar::rand(rng); - let split_scalar = SplitScalar::from(scalar); + let split_scalar = SplitScalar::<{ N }, Scalar>::from(scalar); let secret = Scalar::rand(rng); let encryption_key = (G1Affine::generator() * secret).into_affine(); diff --git a/src/encrypt/elgamal/split_scalar.rs b/src/encrypt/elgamal/split_scalar.rs index b61217b..c62e6b2 100644 --- a/src/encrypt/elgamal/split_scalar.rs +++ b/src/encrypt/elgamal/split_scalar.rs @@ -84,15 +84,18 @@ impl From for SplitScalar { #[cfg(test)] mod test { - use crate::encrypt::EncryptionEngine; - use crate::tests::{Elgamal, G1Affine, Scalar, SplitScalar}; + use super::*; + use crate::tests::{G1Affine, Scalar, TestCurve, N}; + use ark_ec::pairing::Pairing; use ark_ec::{AffineRepr, CurveGroup}; use ark_std::{test_rng, UniformRand, Zero}; + type Elgamal = super::super::ExponentialElgamal<::G1>; + #[test] fn scalar_splitting() { let scalar = Scalar::zero(); - let split_scalar = SplitScalar::from(scalar); + let split_scalar = SplitScalar::<{ N }, Scalar>::from(scalar); let reconstructed_scalar = split_scalar.reconstruct(); assert_eq!(scalar, reconstructed_scalar); @@ -100,7 +103,7 @@ mod test { let max_scalar = Scalar::from(u32::MAX); for _ in 0..10 { let scalar = Scalar::rand(rng); - let split_scalar = SplitScalar::from(scalar); + let split_scalar = SplitScalar::<{ N }, Scalar>::from(scalar); for split in split_scalar.splits() { assert!(split <= &max_scalar); } @@ -114,7 +117,7 @@ mod test { let rng = &mut test_rng(); let encryption_pk = (G1Affine::generator() * Scalar::rand(rng)).into_affine(); let scalar = Scalar::rand(rng); - let split_scalar = SplitScalar::from(scalar); + let split_scalar = SplitScalar::<{ N }, Scalar>::from(scalar); let (short_ciphers, elgamal_r) = split_scalar.encrypt::(&encryption_pk, rng); let long_cipher = ::encrypt_with_randomness( diff --git a/src/encrypt/mod.rs b/src/encrypt/mod.rs index ed7402f..37f0d8b 100644 --- a/src/encrypt/mod.rs +++ b/src/encrypt/mod.rs @@ -2,10 +2,6 @@ pub mod elgamal; use ark_std::rand::Rng; -// other possible encryption engines -//pub struct Generic; -//pub struct Paillier; - pub trait EncryptionEngine { type EncryptionKey; type DecryptionKey; diff --git a/src/lib.rs b/src/lib.rs index 074ab3b..5553c6a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,9 @@ pub enum Error { #[error("couldn't generate valid FFT domain of size {0}")] InvalidFftDomain(usize), #[error(transparent)] - RangeProof(#[from] range_proof::RangeProofError), + RangeProof(#[from] range_proof::Error), #[error(transparent)] - KzgElgamalProofError(#[from] veck::kzg_elgamal::KzgElgamalError), + KzgElgamalProofError(#[from] veck::kzg::elgamal::Error), + #[error(transparent)] + KzgPaillierProofError(#[from] veck::kzg::paillier::Error), } diff --git a/src/range_proof/mod.rs b/src/range_proof/mod.rs index 913986c..a266de7 100644 --- a/src/range_proof/mod.rs +++ b/src/range_proof/mod.rs @@ -12,7 +12,7 @@ mod utils; use crate::commit::kzg::{Kzg, Powers}; use crate::hash::Hasher; -use crate::Error; +use crate::Error as CrateError; use ark_ec::pairing::Pairing; use ark_ec::{AffineRepr, CurveGroup}; use ark_poly::{EvaluationDomain, GeneralEvaluationDomain, Polynomial}; @@ -23,7 +23,7 @@ use digest::Digest; use thiserror::Error as ErrorT; #[derive(ErrorT, Debug, PartialEq)] -pub enum RangeProofError { +pub enum Error { #[error("aggregated witness pairings are not equal")] AggregateWitnessCheckFailed, #[error("shifted witness pairings are not equal")] @@ -71,11 +71,11 @@ impl RangeProof { n: usize, powers: &Powers, rng: &mut R, - ) -> Result { - let domain = - GeneralEvaluationDomain::::new(n).ok_or(Error::InvalidFftDomain(n))?; + ) -> Result { + let domain = GeneralEvaluationDomain::::new(n) + .ok_or(CrateError::InvalidFftDomain(n))?; let domain_2n = GeneralEvaluationDomain::::new(2 * n) - .ok_or(Error::InvalidFftDomain(2 * n))?; + .ok_or(CrateError::InvalidFftDomain(2 * n))?; // random scalars let r = C::ScalarField::rand(rng); @@ -151,9 +151,9 @@ impl RangeProof { }) } - pub fn verify(&self, n: usize, powers: &Powers) -> Result<(), Error> { - let domain = - GeneralEvaluationDomain::::new(n).ok_or(Error::InvalidFftDomain(n))?; + pub fn verify(&self, n: usize, powers: &Powers) -> Result<(), CrateError> { + let domain = GeneralEvaluationDomain::::new(n) + .ok_or(CrateError::InvalidFftDomain(n))?; let mut hasher = Hasher::::new(); hasher.update(&PROOF_DOMAIN_SEP); @@ -180,7 +180,7 @@ impl RangeProof { ); // calculate w(ρ) that should zero since w(X) is after all a zero polynomial if sum != self.evaluations.w_cap { - return Err(RangeProofError::ExpectedZeroPolynomial.into()); + return Err(Error::ExpectedZeroPolynomial.into()); } // check aggregate witness commitment @@ -214,9 +214,9 @@ impl RangeProof { ); if !aggregation_kzg_check { - Err(RangeProofError::AggregateWitnessCheckFailed.into()) + Err(Error::AggregateWitnessCheckFailed.into()) } else if !shifted_kzg_check { - Err(RangeProofError::ShiftedWitnessCheckFailed.into()) + Err(Error::ShiftedWitnessCheckFailed.into()) } else { Ok(()) } @@ -225,10 +225,10 @@ impl RangeProof { #[cfg(test)] mod test { - use super::RangeProofError; + use super::*; use crate::commit::kzg::Powers; - use crate::tests::{BlsCurve, RangeProof, Scalar}; - use crate::Error; + use crate::tests::{Scalar, TestCurve, TestHash}; + use crate::Error as CrateError; use ark_std::{test_rng, UniformRand}; const LOG_2_UPPER_BOUND: usize = 8; // 2^8 @@ -238,14 +238,16 @@ mod test { // KZG setup simulation let rng = &mut test_rng(); let tau = Scalar::rand(rng); // "secret" tau - let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); + let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); let z = Scalar::from(100u32); - let proof = RangeProof::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap(); + let proof = + RangeProof::::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap(); assert!(proof.verify(LOG_2_UPPER_BOUND, &powers).is_ok()); let z = Scalar::from(255u32); - let proof = RangeProof::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap(); + let proof = + RangeProof::::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap(); assert!(proof.verify(LOG_2_UPPER_BOUND, &powers).is_ok()); } @@ -254,13 +256,14 @@ mod test { // KZG setup simulation let rng = &mut test_rng(); let tau = Scalar::rand(rng); // "secret" tau - let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); + let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); let z = Scalar::from(100u32); - let proof = RangeProof::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap(); + let proof = + RangeProof::::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap(); assert_eq!( proof.verify(LOG_2_UPPER_BOUND - 1, &powers), - Err(Error::RangeProof(RangeProofError::ExpectedZeroPolynomial)) + Err(CrateError::RangeProof(Error::ExpectedZeroPolynomial)) ); } @@ -269,12 +272,12 @@ mod test { // KZG setup simulation let rng = &mut test_rng(); let tau = Scalar::rand(rng); // "secret" tau - let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); + let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); let z = Scalar::from(256u32); assert_eq!( - RangeProof::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap_err(), - Error::RangeProof(RangeProofError::ExpectedZeroPolynomial) + RangeProof::::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap_err(), + CrateError::RangeProof(Error::ExpectedZeroPolynomial) ); } @@ -283,12 +286,12 @@ mod test { // KZG setup simulation let rng = &mut test_rng(); let tau = Scalar::rand(rng); // "secret" tau - let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); + let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); let z = Scalar::from(300u32); assert_eq!( - RangeProof::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap_err(), - Error::RangeProof(RangeProofError::ExpectedZeroPolynomial) + RangeProof::::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap_err(), + CrateError::RangeProof(Error::ExpectedZeroPolynomial) ); } } diff --git a/src/range_proof/poly.rs b/src/range_proof/poly.rs index b0f9fa8..fdb314b 100644 --- a/src/range_proof/poly.rs +++ b/src/range_proof/poly.rs @@ -1,5 +1,5 @@ -use super::RangeProofError; -use crate::Error; +use super::Error; +use crate::Error as CrateError; use ark_ff::{BigInteger, PrimeField}; use ark_poly::univariate::DensePolynomial; use ark_poly::{DenseUVPolynomial, EvaluationDomain, GeneralEvaluationDomain}; @@ -56,9 +56,12 @@ pub fn w1_w2( domain: &GeneralEvaluationDomain, f_poly: &DensePolynomial, g_poly: &DensePolynomial, -) -> Result<(DensePolynomial, DensePolynomial), Error> { +) -> Result<(DensePolynomial, DensePolynomial), CrateError> { let one = S::one(); - let w_n_minus_1 = domain.elements().last().ok_or(Error::InvalidFftDomain(0))?; + let w_n_minus_1 = domain + .elements() + .last() + .ok_or(CrateError::InvalidFftDomain(0))?; // polynomial: P(x) = x - w^(n-1) let x_minus_w_n_minus_1_poly = DensePolynomial::from_coefficients_slice(&[-w_n_minus_1, one]); @@ -84,13 +87,13 @@ pub fn w3( domain: &GeneralEvaluationDomain, domain_2n: &GeneralEvaluationDomain, g_poly: &DensePolynomial, -) -> Result, Error> { +) -> Result, CrateError> { // w3: [g(X) - 2g(Xw)] * [1 - g(X) + 2g(Xw)] * [X - w^(n-1)] // degree of g = n - 1 // degree of w3 = (2n - 1) + (2n - 1) + 1 = 4n - 1 // the new domain can be of size 4n let domain_4n = GeneralEvaluationDomain::::new(2 * domain_2n.size()) - .ok_or(Error::InvalidFftDomain(2 * domain_2n.size()))?; + .ok_or(CrateError::InvalidFftDomain(2 * domain_2n.size()))?; // find evaluations of g in the new domain let mut g_evals = domain_4n.fft(g_poly); @@ -104,7 +107,10 @@ pub fn w3( g_evals.push(g_evals[3]); // calculate evaluations of w3 - let w_n_minus_1 = domain.elements().last().ok_or(Error::InvalidFftDomain(0))?; + let w_n_minus_1 = domain + .elements() + .last() + .ok_or(CrateError::InvalidFftDomain(0))?; let two = S::from(2u8); let w3_evals: Vec = domain_4n .elements() @@ -140,16 +146,16 @@ pub fn quotient( w2_poly: &DensePolynomial, w3_poly: &DensePolynomial, tau: S, -) -> Result, Error> { +) -> Result, CrateError> { // find linear combination of w1, w2, w3 let lc = w1_poly + &(w2_poly * tau) + w3_poly * tau.square(); let (quotient_poly, rem) = lc .divide_by_vanishing_poly(*domain) - .ok_or(Error::InvalidFftDomain(domain.size()))?; + .ok_or(CrateError::InvalidFftDomain(domain.size()))?; // since the linear combination should also satisfy all roots of unity, q_rem should be a zero // polynomial if !rem.is_zero() { - Err(RangeProofError::ExpectedZeroPolynomial.into()) + Err(Error::ExpectedZeroPolynomial.into()) } else { Ok(quotient_poly) } @@ -158,7 +164,7 @@ pub fn quotient( #[cfg(test)] mod test { use crate::commit::kzg::Powers; - use crate::tests::{BlsCurve, Scalar}; + use crate::tests::{Scalar, TestCurve}; use ark_ec::pairing::Pairing; use ark_ec::CurveGroup; use ark_ff::{Field, PrimeField}; @@ -329,7 +335,7 @@ mod test { let domain_2n = GeneralEvaluationDomain::::new(2 * n).unwrap(); // KZG setup let tau = Scalar::rand(rng); // "secret" tau - let powers = Powers::::unsafe_setup(tau, 4 * n); + let powers = Powers::::unsafe_setup(tau, 4 * n); // random numbers let r = Scalar::rand(rng); @@ -353,7 +359,7 @@ mod test { let w_cap_commitment_expected = powers.commit_g1(&w_cap_poly); // calculate w_cap commitment fact that commitment scheme is additively homomorphic - let w_cap_commitment_calculated = super::super::utils::w_cap::<::G1>( + let w_cap_commitment_calculated = super::super::utils::w_cap::<::G1>( domain.size(), f_commitment, q_commitment, diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 3453cb4..ab1eba0 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,19 +1,20 @@ -pub use ark_bls12_381::{Bls12_381 as BlsCurve, G1Affine}; +pub use ark_bls12_381::{Bls12_381 as TestCurve, G1Affine}; use ark_ec::pairing::Pairing; use ark_ff::PrimeField; use ark_poly::univariate::DensePolynomial; use criterion as _; -use sha3::Keccak256; +pub use sha3::Keccak256 as TestHash; -const N: usize = Scalar::MODULUS_BIT_SIZE as usize / crate::encrypt::elgamal::MAX_BITS + 1; +pub const N: usize = Scalar::MODULUS_BIT_SIZE as usize / crate::encrypt::elgamal::MAX_BITS + 1; -pub type Scalar = ::ScalarField; -pub type SplitScalar = crate::encrypt::elgamal::SplitScalar<{ N }, Scalar>; +pub type Scalar = ::ScalarField; pub type UniPoly = DensePolynomial; +/* pub type Elgamal = crate::encrypt::elgamal::ExponentialElgamal<::G1>; pub type ElgamalEncryptionProof = crate::veck::kzg_elgamal::EncryptionProof<{ N }, BlsCurve, Keccak256>; pub type KzgElgamalProof = crate::veck::kzg_elgamal::Proof<{ N }, BlsCurve, Keccak256>; pub type DleqProof = crate::dleq::Proof<::G1, Keccak256>; pub type RangeProof = crate::range_proof::RangeProof; pub type PaillierEncryptionProof = crate::veck::kzg_paillier::Proof; +*/ diff --git a/src/veck/kzg/elgamal/encryption.rs b/src/veck/kzg/elgamal/encryption.rs new file mode 100644 index 0000000..e2522c7 --- /dev/null +++ b/src/veck/kzg/elgamal/encryption.rs @@ -0,0 +1,110 @@ +use crate::commit::kzg::Powers; +use crate::encrypt::elgamal::{Cipher, ExponentialElgamal as Elgamal, SplitScalar, MAX_BITS}; +use crate::encrypt::EncryptionEngine; +use crate::range_proof::RangeProof; +use ark_ec::pairing::Pairing; +use ark_ec::{AffineRepr, CurveGroup}; +use ark_std::rand::Rng; +use digest::Digest; + +/// A publicly verifiable proof based on the Elgamal encryption scheme. +pub struct EncryptionProof { + /// The actual Elgamal ciphertexts of the encrypted data points. + pub ciphers: Vec>, + /// Each ciphertext is split into a set of scalars that, once decrypted, can reconstruct the + /// original data point. Since we use the exponential Elgamal encryption scheme, these "short" + /// ciphertexts are needed to encrypt split data points in the bruteforceable range: 2^32. + pub short_ciphers: Vec<[Cipher; N]>, + /// Each "short" ciphertext requires a range proof proving that the encrypted value is in the + /// bruteforceable range. + pub range_proofs: Vec<[RangeProof; N]>, + /// Random encryption points used to encrypt the original data points. These are the `h^r` + /// values in the exponential Elgamal scheme: `e = g^m * h^r`, where `e` is the ciphertext, `m` + /// is the plaintext. + pub random_encryption_points: Vec, +} + +impl EncryptionProof { + pub fn new( + evaluations: &[C::ScalarField], + encryption_pk: & as EncryptionEngine>::EncryptionKey, + powers: &Powers, + rng: &mut R, + ) -> Self { + let mut random_encryption_points = Vec::with_capacity(evaluations.len()); + let mut ciphers = Vec::with_capacity(evaluations.len()); + let mut short_ciphers = Vec::with_capacity(evaluations.len()); + let mut range_proofs = Vec::with_capacity(evaluations.len()); + + for eval in evaluations { + let split_eval = SplitScalar::from(*eval); + let rp = split_eval.splits().map(|s| { + RangeProof::new(s, MAX_BITS, powers, rng).expect("invalid range proof input") + }); + let (sc, rand) = split_eval.encrypt::, _>(encryption_pk, rng); + let cipher = as EncryptionEngine>::encrypt_with_randomness( + eval, + encryption_pk, + &rand, + ); + random_encryption_points.push((C::G1Affine::generator() * rand).into_affine()); + ciphers.push(cipher); + short_ciphers.push(sc); + range_proofs.push(rp); + } + + Self { + ciphers, + short_ciphers, + range_proofs, + random_encryption_points, + } + } + + /// Generates a subset from the total encrypted data. + /// + /// Clients might not be interested in the whole dataset, thus the server may generate a subset + /// encryption proof to reduce proof verification costs. + pub fn subset(&self, indices: &[usize]) -> Self { + let size = indices.len(); + let mut ciphers = Vec::with_capacity(size); + let mut short_ciphers = Vec::with_capacity(size); + let mut random_encryption_points = Vec::with_capacity(size); + let mut range_proofs = Vec::with_capacity(size); + for &index in indices { + ciphers.push(self.ciphers[index]); + short_ciphers.push(self.short_ciphers[index]); + random_encryption_points.push(self.random_encryption_points[index]); + range_proofs.push(self.range_proofs[index].clone()); + } + + Self { + ciphers, + short_ciphers, + range_proofs, + random_encryption_points, + } + } + + /// Checks that the sum of split scalars evaluate to the encrypted value via the homomorphic + /// properties of Elgamal encryption. + pub fn verify_split_scalars(&self) -> bool { + for (cipher, short_cipher) in self.ciphers.iter().zip(&self.short_ciphers) { + if !cipher.check_encrypted_sum(short_cipher) { + return false; + } + } + true + } + + // TODO range proofs and short ciphers are not "connected" by anything? + // TODO parallelize + pub fn verify_range_proofs(&self, powers: &Powers) -> bool { + for rps in self.range_proofs.iter() { + if !rps.iter().all(|rp| rp.verify(MAX_BITS, powers).is_ok()) { + return false; + } + } + true + } +} diff --git a/src/veck/kzg_elgamal.rs b/src/veck/kzg/elgamal/mod.rs similarity index 58% rename from src/veck/kzg_elgamal.rs rename to src/veck/kzg/elgamal/mod.rs index 636b3c3..1873aa3 100644 --- a/src/veck/kzg_elgamal.rs +++ b/src/veck/kzg/elgamal/mod.rs @@ -1,10 +1,10 @@ +mod encryption; +pub use encryption::EncryptionProof; + use crate::commit::kzg::{Kzg, Powers}; use crate::dleq::Proof as DleqProof; -use crate::encrypt::elgamal::{Cipher, ExponentialElgamal as Elgamal, SplitScalar, MAX_BITS}; -use crate::encrypt::EncryptionEngine; use crate::hash::Hasher; -use crate::range_proof::RangeProof; -use crate::Error; +use crate::Error as CrateError; use ark_ec::pairing::Pairing; use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM as Msm}; use ark_ff::PrimeField; @@ -19,7 +19,7 @@ use digest::Digest; use thiserror::Error as ErrorT; #[derive(Debug, ErrorT, PartialEq)] -pub enum KzgElgamalError { +pub enum Error { #[error("invalid DLEQ proof for split encryption points")] InvalidDleqProof, #[error("invalid KZG proof")] @@ -30,108 +30,6 @@ pub enum KzgElgamalError { InvalidSplitScalars, } -/// A publicly verifiable proof based on the Elgamal encryption scheme. -pub struct EncryptionProof { - /// The actual Elgamal ciphertexts of the encrypted data points. - pub ciphers: Vec>, - /// Each ciphertext is split into a set of scalars that, once decrypted, can reconstruct the - /// original data point. Since we use the exponential Elgamal encryption scheme, these "short" - /// ciphertexts are needed to encrypt split data points in the bruteforceable range: 2^32. - pub short_ciphers: Vec<[Cipher; N]>, - /// Each "short" ciphertext requires a range proof proving that the encrypted value is in the - /// bruteforceable range. - pub range_proofs: Vec<[RangeProof; N]>, - /// Random encryption points used to encrypt the original data points. These are the `h^r` - /// values in the exponential Elgamal scheme: `e = g^m * h^r`, where `e` is the ciphertext, `m` - /// is the plaintext. - pub random_encryption_points: Vec, -} - -impl EncryptionProof { - pub fn new( - evaluations: &[C::ScalarField], - encryption_pk: & as EncryptionEngine>::EncryptionKey, - powers: &Powers, - rng: &mut R, - ) -> Self { - let mut random_encryption_points = Vec::with_capacity(evaluations.len()); - let mut ciphers = Vec::with_capacity(evaluations.len()); - let mut short_ciphers = Vec::with_capacity(evaluations.len()); - let mut range_proofs = Vec::with_capacity(evaluations.len()); - - for eval in evaluations { - let split_eval = SplitScalar::from(*eval); - let rp = split_eval.splits().map(|s| { - RangeProof::new(s, MAX_BITS, powers, rng).expect("invalid range proof input") - }); - let (sc, rand) = split_eval.encrypt::, _>(encryption_pk, rng); - let cipher = as EncryptionEngine>::encrypt_with_randomness( - eval, - encryption_pk, - &rand, - ); - random_encryption_points.push((C::G1Affine::generator() * rand).into_affine()); - ciphers.push(cipher); - short_ciphers.push(sc); - range_proofs.push(rp); - } - - Self { - ciphers, - short_ciphers, - range_proofs, - random_encryption_points, - } - } - - /// Generates a subset from the total encrypted data. - /// - /// Clients might not be interested in the whole dataset, thus the server may generate a subset - /// encryption proof to reduce proof verification costs. - pub fn subset(&self, indices: &[usize]) -> Self { - let size = indices.len(); - let mut ciphers = Vec::with_capacity(size); - let mut short_ciphers = Vec::with_capacity(size); - let mut random_encryption_points = Vec::with_capacity(size); - let mut range_proofs = Vec::with_capacity(size); - for &index in indices { - ciphers.push(self.ciphers[index]); - short_ciphers.push(self.short_ciphers[index]); - random_encryption_points.push(self.random_encryption_points[index]); - range_proofs.push(self.range_proofs[index].clone()); - } - - Self { - ciphers, - short_ciphers, - range_proofs, - random_encryption_points, - } - } - - /// Checks that the sum of split scalars evaluate to the encrypted value via the homomorphic - /// properties of Elgamal encryption. - pub fn verify_split_scalars(&self) -> bool { - for (cipher, short_cipher) in self.ciphers.iter().zip(&self.short_ciphers) { - if !cipher.check_encrypted_sum(short_cipher) { - return false; - } - } - true - } - - // TODO range proofs and short ciphers are not "connected" by anything? - // TODO parallelize - pub fn verify_range_proofs(&self, powers: &Powers) -> bool { - for rps in self.range_proofs.iter() { - if !rps.iter().all(|rp| rp.verify(MAX_BITS, powers).is_ok()) { - return false; - } - } - true - } -} - pub struct Proof { pub encryption_proof: EncryptionProof, pub challenge_eval_commitment: C::G1Affine, @@ -154,7 +52,7 @@ where encryption_proof: EncryptionProof, powers: &Powers, rng: &mut R, - ) -> Result { + ) -> Result { let mut hasher = Hasher::::new(); encryption_proof .ciphers @@ -163,7 +61,7 @@ where let domain_size = encryption_proof.ciphers.len(); let domain = GeneralEvaluationDomain::::new(domain_size) - .ok_or(Error::InvalidFftDomain(domain_size))?; + .ok_or(CrateError::InvalidFftDomain(domain_size))?; // challenge and KZG proof let challenge = C::ScalarField::from_le_bytes_mod_order(&hasher.finalize()); @@ -211,7 +109,7 @@ where com_f_s_poly: C::G1, encryption_pk: C::G1Affine, powers: &Powers, - ) -> Result<(), Error> { + ) -> Result<(), CrateError> { let mut hasher = Hasher::::new(); let c1_points: Vec = self .encryption_proof @@ -226,7 +124,7 @@ where let challenge = C::ScalarField::from_le_bytes_mod_order(&hasher.finalize()); let domain_size = self.encryption_proof.ciphers.len(); let domain = GeneralEvaluationDomain::::new(domain_size) - .ok_or(Error::InvalidFftDomain(domain_size))?; + .ok_or(CrateError::InvalidFftDomain(domain_size))?; // polynomial division check via vanishing polynomial let vanishing_poly = DensePolynomial::from(domain.vanishing_polynomial()); @@ -267,11 +165,11 @@ where // check that split scalars are in a brute-forceable range if !dleq_check { - Err(KzgElgamalError::InvalidDleqProof.into()) + Err(Error::InvalidDleqProof.into()) } else if !kzg_check { - Err(KzgElgamalError::InvalidKzgProof.into()) + Err(Error::InvalidKzgProof.into()) } else if !subset_pairing_check { - Err(KzgElgamalError::InvalidSubsetPolynomial.into()) + Err(Error::InvalidSubsetPolynomial.into()) } else { Ok(()) } @@ -280,27 +178,29 @@ where #[cfg(test)] mod test { - use crate::commit::kzg::Powers; + use super::*; use crate::encrypt::elgamal::MAX_BITS; use crate::tests::*; - use ark_ec::pairing::Pairing; - use ark_ec::{CurveGroup, Group}; - use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; + use ark_ec::Group; + use ark_poly::Evaluations; use ark_std::{test_rng, UniformRand}; const DATA_SIZE: usize = 16; const SUBSET_SIZE: usize = 8; + type ElgamalEncryptionProof = EncryptionProof<{ N }, TestCurve, TestHash>; + type KzgElgamalProof = Proof<{ N }, TestCurve, TestHash>; + #[test] fn flow() { // KZG setup simulation let rng = &mut test_rng(); let tau = Scalar::rand(rng); // "secret" tau - let powers = Powers::::unsafe_setup(tau, (DATA_SIZE + 1).max(MAX_BITS * 4)); // generate powers of tau size DATA_SIZE + let powers = Powers::::unsafe_setup(tau, (DATA_SIZE + 1).max(MAX_BITS * 4)); // generate powers of tau size DATA_SIZE // Server's (elphemeral?) encryption key for this session let encryption_sk = Scalar::rand(rng); - let encryption_pk = (::G1::generator() * encryption_sk).into_affine(); + let encryption_pk = (::G1::generator() * encryption_sk).into_affine(); // Generate random data and public inputs (encrypted data, etc) let data: Vec = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); @@ -312,7 +212,7 @@ mod test { .for_each(|rps| assert!(rps.iter().all(|rp| rp.verify(MAX_BITS, &powers).is_ok()))); let domain = GeneralEvaluationDomain::new(data.len()).expect("valid domain"); - let index_map = super::super::index_map(domain); + let index_map = crate::veck::index_map(domain); // Interpolate original polynomial and compute its KZG commitment. // This is performed only once by the server @@ -323,9 +223,9 @@ mod test { // get subdomain with size suitable for interpolating a polynomial with SUBSET_SIZE // coefficients let subdomain = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); - let subset_indices = super::super::subset_indices(&index_map, &subdomain); + let subset_indices = crate::veck::subset_indices(&index_map, &subdomain); let subset_evaluations = - super::super::subset_evals(&evaluations, &subset_indices, subdomain); + crate::veck::subset_evals(&evaluations, &subset_indices, subdomain); let f_s_poly: UniPoly = subset_evaluations.interpolate_by_ref(); let com_f_s_poly = powers.commit_g1(&f_s_poly); diff --git a/src/veck/kzg/mod.rs b/src/veck/kzg/mod.rs new file mode 100644 index 0000000..a3434ec --- /dev/null +++ b/src/veck/kzg/mod.rs @@ -0,0 +1,2 @@ +pub mod elgamal; +pub mod paillier; diff --git a/src/veck/kzg/paillier/encrypt.rs b/src/veck/kzg/paillier/encrypt.rs new file mode 100644 index 0000000..af9d2da --- /dev/null +++ b/src/veck/kzg/paillier/encrypt.rs @@ -0,0 +1,33 @@ +use super::utils::pow_mult_mod; +use ark_std::One; +use num_bigint::BigUint; +#[cfg(feature = "parallel")] +use rayon::prelude::*; + +pub fn encrypt(value: &BigUint, key: &BigUint, random: &BigUint) -> BigUint { + let n2 = key * key; + pow_mult_mod(&(key + BigUint::one()), value, random, key, &n2) +} + +#[cfg(not(feature = "parallel"))] +pub fn batch>(values: T, key: &BigUint, randoms: T) -> Vec { + values + .as_ref() + .iter() + .zip(randoms.as_ref()) + .map(|(val, rand)| encrypt(val, key, rand)) + .collect() +} + +#[cfg(feature = "parallel")] +pub fn batch(values: T, key: &BigUint, randoms: T) -> Vec +where + T: AsRef<[BigUint]> + rayon::iter::IntoParallelIterator, +{ + values + .as_ref() + .par_iter() + .zip(randoms.as_ref()) + .map(|(val, rand)| encrypt(val, key, rand)) + .collect() +} diff --git a/src/veck/kzg/paillier/mod.rs b/src/veck/kzg/paillier/mod.rs new file mode 100644 index 0000000..deb7e8c --- /dev/null +++ b/src/veck/kzg/paillier/mod.rs @@ -0,0 +1,255 @@ +mod encrypt; +mod random; +mod server; +mod utils; +pub use random::RandomParameters; +pub use server::Server; +use utils::{challenge, modular_inverse, pow_mult_mod}; + +use crate::commit::kzg::Powers; +use crate::Error as CrateError; +use ark_ec::pairing::Pairing; +use ark_ec::Group; +use ark_ff::fields::PrimeField; +use ark_poly::univariate::DensePolynomial; +use ark_poly::{EvaluationDomain, GeneralEvaluationDomain}; +use ark_std::marker::PhantomData; +use ark_std::rand::Rng; +use ark_std::One; +use digest::Digest; +use num_bigint::BigUint; + +use thiserror::Error as ErrorT; + +const N_BITS: u64 = 1024; + +#[derive(ErrorT, Debug, PartialEq)] +pub enum Error { + #[error("invalid encrypted value, has no modular inverse")] + InvalidEncryptedValue, + #[error("computed challenge does not match the expected one")] + ChallengeMismatch, + #[error("pairing check failed for subset polynomial")] + PairingMismatch, +} + +pub struct Proof { + pub challenge: BigUint, + pub ct_vec: Vec, + pub w_vec: Vec, + pub z_vec: Vec, + pub com_q_poly: C::G1, + _digest: PhantomData, + _curve: PhantomData, +} + +impl Proof { + #[allow(clippy::too_many_arguments)] + pub fn new( + values: &[BigUint], + f_poly: &DensePolynomial, + f_s_poly: &DensePolynomial, + com_f_poly: &C::G1, + com_f_s_poly: &C::G1, + domain: &GeneralEvaluationDomain, + domain_s: &GeneralEvaluationDomain, + pubkey: &BigUint, + powers: &Powers, + rng: &mut R, + ) -> Self { + let vanishing_poly = DensePolynomial::from(domain_s.vanishing_polynomial()); + let q_poly = &(f_poly - f_s_poly) / &vanishing_poly; + let q_poly_evals = q_poly.evaluate_over_domain_by_ref(*domain); + let com_q_poly = powers.commit_scalars_g1(&q_poly_evals.evals); + + let random_params = RandomParameters::new(values.len(), rng); + let ct_vec = encrypt::batch(values, pubkey, &random_params.u_vec); + let t_vec = encrypt::batch(&random_params.r_vec, pubkey, &random_params.s_vec); + let r_scalar_vec: Vec = random_params + .r_vec + .iter() + .map(|r| C::ScalarField::from_le_bytes_mod_order(&r.to_bytes_le())) + .collect(); + let t = powers.commit_scalars_g1(&r_scalar_vec); + let challenge = challenge::( + pubkey, + &vanishing_poly, + &ct_vec, + com_f_poly, + com_f_s_poly, + &t_vec, + &t, + ); + let w_vec: Vec = random_params + .s_vec + .iter() + .zip(&random_params.u_vec) + .map(|(s, u)| pow_mult_mod(s, &BigUint::one(), u, &challenge, pubkey)) + .collect(); + let z_vec: Vec = random_params + .r_vec + .iter() + .zip(values) + .map(|(r, val)| r + &challenge * val) + .collect(); + + Self { + challenge, + ct_vec, + w_vec, + z_vec, + com_q_poly, + _digest: PhantomData, + _curve: PhantomData, + } + } + + pub fn verify( + &self, + com_f_poly: &C::G1, + com_f_s_poly: &C::G1, + domain: &GeneralEvaluationDomain, + domain_s: &GeneralEvaluationDomain, + pubkey: &BigUint, + powers: &Powers, + ) -> Result<(), CrateError> { + let vanishing_poly = DensePolynomial::from(domain_s.vanishing_polynomial()); + let vanishing_poly_evals = vanishing_poly.evaluate_over_domain_by_ref(*domain); + let com_vanishing_poly_g2 = powers.commit_scalars_g2(&vanishing_poly_evals.evals); + + let lhs_pairing = C::pairing(self.com_q_poly, com_vanishing_poly_g2); + let rhs_pairing = C::pairing(*com_f_poly - com_f_s_poly, C::G2::generator()); + if lhs_pairing != rhs_pairing { + return Err(Error::PairingMismatch.into()); + } + + let modulo = pubkey * pubkey; + let t_vec_expected: Vec = self + .ct_vec + .iter() + .zip(self.w_vec.iter().zip(&self.z_vec)) + .flat_map(|(ct, (w, z))| -> Result { + let aux = pow_mult_mod(&(pubkey + BigUint::one()), z, w, pubkey, &modulo); + let ct_pow_c = ct.modpow(&self.challenge, &modulo); + let ct_pow_minus_c = + modular_inverse(&ct_pow_c, &modulo).ok_or(Error::InvalidEncryptedValue)?; + Ok((aux * ct_pow_minus_c) % &modulo) + }) + .collect::>(); + let z_scalar_vec: Vec = self + .z_vec + .iter() + .map(|z| C::ScalarField::from_le_bytes_mod_order(&z.to_bytes_le())) + .collect(); + + // compute t + let challenge_scalar = + C::ScalarField::from_le_bytes_mod_order(&self.challenge.to_bytes_le()); + let commitment_pow_challenge = *com_f_s_poly * challenge_scalar; + let msm = powers.commit_scalars_g1(&z_scalar_vec); + let t_expected = msm - commitment_pow_challenge; + + let challenge_expected = challenge::( + pubkey, + &vanishing_poly, + &self.ct_vec, + com_f_poly, + com_f_s_poly, + &t_vec_expected, + &t_expected, + ); + + if self.challenge != challenge_expected { + Err(Error::ChallengeMismatch.into()) + } else { + Ok(()) + } + } + + pub fn decrypt(&self, server: &Server) -> Vec { + let denominator = server.decryption_denominator(); + let denominator_inv = modular_inverse(&denominator, &server.pubkey).unwrap(); + self.ct_vec + .iter() + .map(|ct| { + let ct_lx = server.lx(&ct.modpow(&server.privkey, &server.mod_n2)); + (ct_lx * &denominator_inv) % &server.pubkey + }) + .collect() + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::tests::*; + use ark_ff::BigInteger; + use ark_poly::Evaluations; + use ark_std::{test_rng, UniformRand}; + + const DATA_SIZE: usize = 16; + const SUBSET_SIZE: usize = 16; + + type PaillierEncryptionProof = Proof; + + #[test] + fn flow() { + // KZG setup simulation + let rng = &mut test_rng(); + // "secret" tau + let tau = Scalar::rand(rng); + // generate powers of tau size DATA_SIZE + let powers = Powers::::unsafe_setup_eip_4844(tau, DATA_SIZE); + // new server (with encryption pubkey) + let server = Server::new(rng); + // random data to encrypt + let data: Vec = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); + let domain = GeneralEvaluationDomain::new(DATA_SIZE).unwrap(); + let domain_s = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); + let evaluations = Evaluations::from_vec_and_domain(data, domain); + let index_map = crate::veck::index_map(domain); + let subset_indices = crate::veck::subset_indices(&index_map, &domain_s); + let evaluations_s = crate::veck::subset_evals(&evaluations, &subset_indices, domain_s); + + let f_poly: UniPoly = evaluations.interpolate_by_ref(); + let f_s_poly: UniPoly = evaluations_s.interpolate_by_ref(); + + let evaluations_s_d = f_s_poly.evaluate_over_domain_by_ref(domain); + + let com_f_poly = powers.commit_scalars_g1(&evaluations.evals); + let com_f_s_poly = powers.commit_scalars_g1(&evaluations_s_d.evals); + + let data_biguint: Vec = evaluations_s + .evals + .iter() + .map(|d| BigUint::from_bytes_le(&d.into_bigint().to_bytes_le())) + .collect(); + + let proof = PaillierEncryptionProof::new( + &data_biguint, + &f_poly, + &f_s_poly, + &com_f_poly, + &com_f_s_poly, + &domain, + &domain_s, + &server.pubkey, + &powers, + rng, + ); + + assert!(proof + .verify( + &com_f_poly, + &com_f_s_poly, + &domain, + &domain_s, + &server.pubkey, + &powers + ) + .is_ok()); + + let decrypted_data = proof.decrypt(&server); + assert_eq!(decrypted_data, data_biguint); + } +} diff --git a/src/veck/kzg/paillier/random.rs b/src/veck/kzg/paillier/random.rs new file mode 100644 index 0000000..984c4ef --- /dev/null +++ b/src/veck/kzg/paillier/random.rs @@ -0,0 +1,31 @@ +use super::N_BITS; +use ark_std::rand::distributions::Distribution; +use ark_std::rand::Rng; +use num_bigint::{BigUint, RandomBits}; + +pub struct RandomParameters { + pub u_vec: Vec, + pub s_vec: Vec, + pub r_vec: Vec, +} + +impl RandomParameters { + pub fn new(size: usize, rng: &mut R) -> Self { + let mut u_vec = Vec::with_capacity(size); + let mut s_vec = Vec::with_capacity(size); + let mut r_vec = Vec::with_capacity(size); + let random_bits = RandomBits::new(N_BITS); + let random_bits_2 = RandomBits::new(N_BITS >> 1); + for _ in 0..size { + u_vec.push(random_bits.sample(rng)); + s_vec.push(random_bits.sample(rng)); + r_vec.push(random_bits_2.sample(rng)); + } + + Self { + u_vec, + s_vec, + r_vec, + } + } +} diff --git a/src/veck/kzg/paillier/server.rs b/src/veck/kzg/paillier/server.rs new file mode 100644 index 0000000..31bc822 --- /dev/null +++ b/src/veck/kzg/paillier/server.rs @@ -0,0 +1,70 @@ +use super::N_BITS; +use ark_std::rand::distributions::Distribution; +use ark_std::rand::Rng; +use ark_std::One; +use num_bigint::{BigUint, RandomBits}; +use num_integer::Integer; +use num_prime::nt_funcs::prev_prime; + +/// A simulated server instance tailored for the Paillier encryption scheme. +#[derive(Debug)] +pub struct Server { + pub p_prime: BigUint, + pub q_prime: BigUint, + pub privkey: BigUint, + pub pubkey: BigUint, + pub mod_n2: BigUint, +} + +impl Server { + pub fn new(rng: &mut R) -> Self { + // generate small enough primes so that their product fits + // "N_BITS" number of bits + let (p, q) = primes(N_BITS >> 1, rng); + let pubkey = &p * &q; + let privkey = (&p - BigUint::one()).lcm(&(&q - BigUint::one())); + let mod_n2 = &pubkey * &pubkey; + + Self { + p_prime: p, + q_prime: q, + privkey, + pubkey, + mod_n2, + } + } + + /// Helper function to compute L(x) = (x - 1) / N + pub fn lx(&self, x: &BigUint) -> BigUint { + debug_assert!(x < &self.mod_n2 && (x % &self.pubkey) == BigUint::one()); + (x - BigUint::one()) / &self.pubkey + } + + /// Helper function to compute the denominator in the Paillier decryption scheme equation. + /// + /// x = (N + 1)^{sk} mod N^2 + /// L(x) = (x - 1) / N + pub fn decryption_denominator(&self) -> BigUint { + let n_plus_1_pow_sk = (&self.pubkey + BigUint::one()).modpow(&self.privkey, &self.mod_n2); + self.lx(&n_plus_1_pow_sk) + } +} + +fn primes(n_bits: u64, rng: &mut R) -> (BigUint, BigUint) { + let random_bits = RandomBits::new(n_bits); + let target_p: BigUint = random_bits.sample(rng); + let target_q: BigUint = random_bits.sample(rng); + let p = find_next_smaller_prime(&target_p); + let q = find_next_smaller_prime(&target_q); + debug_assert_ne!(p, q); + (p, q) +} + +fn find_next_smaller_prime(target: &BigUint) -> BigUint { + // look for previous prime because we need to fit into 2 * n bits when we multiply p and q + loop { + if let Some(found) = prev_prime(target, None) { + return found; + } + } +} diff --git a/src/veck/kzg/paillier/utils.rs b/src/veck/kzg/paillier/utils.rs new file mode 100644 index 0000000..fe2ae7d --- /dev/null +++ b/src/veck/kzg/paillier/utils.rs @@ -0,0 +1,86 @@ +use crate::hash::Hasher; +use ark_ec::CurveGroup; +use ark_poly::univariate::DensePolynomial; +use ark_std::One; +use digest::Digest; +use num_bigint::{BigInt, BigUint, Sign}; +use num_integer::Integer; + +/// Computes `(a^alpha mod N) * (b^beta mod N) mod N`. +pub fn pow_mult_mod( + a: &BigUint, + alpha: &BigUint, + b: &BigUint, + beta: &BigUint, + modulo: &BigUint, +) -> BigUint { + (a.modpow(alpha, modulo) * b.modpow(beta, modulo)) % modulo +} + +/// Modular inverse helper for `BigUint` types. Returns `None` if the inverse does not exist. +/// +/// `BigUint`'s`modpow` cannot handle negative exponents, it panics. Thus, we are using the +/// extended GCD algorithm to find the modular inverse of `num`. However, `extended_gcd_lcm` is +/// only implemented for signed types such as `BigInt`, hence the conversions. +pub fn modular_inverse(num: &BigUint, modulo: &BigUint) -> Option { + let num_signed = BigInt::from(num.clone()); + let mod_signed = BigInt::from(modulo.clone()); + let (ext_gcd, _) = num_signed.extended_gcd_lcm(&mod_signed); + if ext_gcd.gcd != BigInt::one() { + None + } else { + let (sign, uint) = ext_gcd.x.into_parts(); + debug_assert!(&uint < modulo); + if sign == Sign::Minus { + Some(modulo - uint) + } else { + Some(uint) + } + } +} + +/// Computes the challenge for the Paillier encryption scheme. +pub fn challenge( + pubkey: &BigUint, + vanishing_poly: &DensePolynomial, + ct_slice: &[BigUint], + com_f_poly: &C, + com_f_s_poly: &C, + t_slice: &[BigUint], + t: &C, +) -> BigUint { + let mut hasher = Hasher::::new(); + hasher.update(pubkey); + hasher.update(&vanishing_poly.coeffs); + ct_slice.iter().for_each(|ct| hasher.update(ct)); + hasher.update(com_f_poly); + hasher.update(com_f_s_poly); + t_slice.iter().for_each(|t| hasher.update(t)); + hasher.update(t); + + BigUint::from_bytes_le(&hasher.finalize()) +} + +#[cfg(test)] +mod test { + use super::super::server::Server; + use super::super::N_BITS; + use super::*; + use ark_std::rand::distributions::Distribution; + use ark_std::test_rng; + use num_bigint::RandomBits; + + #[test] + fn compute_modular_inverse() { + let rng = &mut test_rng(); + let server = Server::new(rng); + let modulo = server.pubkey; + let random_bits = RandomBits::new(N_BITS); + for _ in 0..100 { + let num: BigUint = + >::sample(&random_bits, rng) % &modulo; + let inv = modular_inverse(&num, &modulo).unwrap(); + assert_eq!((num * inv) % &modulo, BigUint::one()); + } + } +} diff --git a/src/veck/kzg_paillier.rs b/src/veck/kzg_paillier.rs deleted file mode 100644 index 49510e0..0000000 --- a/src/veck/kzg_paillier.rs +++ /dev/null @@ -1,414 +0,0 @@ -use crate::commit::kzg::Powers; -use crate::hash::Hasher; -use ark_ec::pairing::Pairing; -use ark_ec::{CurveGroup, Group}; -use ark_ff::fields::PrimeField; -use ark_poly::univariate::DensePolynomial; -use ark_poly::{EvaluationDomain, GeneralEvaluationDomain}; -use ark_std::marker::PhantomData; -use ark_std::rand::distributions::Distribution; -use ark_std::rand::Rng; -use ark_std::One; -use digest::Digest; -use num_bigint::{BigInt, BigUint, RandomBits, Sign}; -use num_integer::Integer; -use num_prime::nt_funcs::prev_prime; -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -const N_BITS: u64 = 1024; - -#[derive(Debug)] -pub struct Server { - pub p_prime: BigUint, - pub q_prime: BigUint, - pub privkey: BigUint, - pub pubkey: BigUint, - pub mod_n2: BigUint, -} - -impl Server { - pub fn new(rng: &mut R) -> Self { - // generate small enough primes so that their product fits - // "N_BITS" number of bits - let (p, q) = primes(N_BITS >> 1, rng); - let pubkey = &p * &q; - let privkey = (&p - BigUint::one()).lcm(&(&q - BigUint::one())); - let mod_n2 = &pubkey * &pubkey; - - Self { - p_prime: p, - q_prime: q, - privkey, - pubkey, - mod_n2, - } - } - - pub fn lx(&self, x: &BigUint) -> BigUint { - debug_assert!(x < &self.mod_n2 && (x % &self.pubkey) == BigUint::one()); - (x - BigUint::one()) / &self.pubkey - } - - pub fn decryption_denominator(&self) -> BigUint { - let n_plus_1_pow_sk = (&self.pubkey + BigUint::one()).modpow(&self.privkey, &self.mod_n2); - self.lx(&n_plus_1_pow_sk) - } -} - -fn challenge( - pubkey: &BigUint, - vanishing_poly: &DensePolynomial, - ct_slice: &[BigUint], - com_f_poly: &C, - com_f_s_poly: &C, - t_slice: &[BigUint], - t: &C, -) -> BigUint { - let mut hasher = Hasher::::new(); - hasher.update(pubkey); - hasher.update(&vanishing_poly.coeffs); - ct_slice.iter().for_each(|ct| hasher.update(ct)); - hasher.update(com_f_poly); - hasher.update(com_f_s_poly); - t_slice.iter().for_each(|t| hasher.update(t)); - hasher.update(t); - - BigUint::from_bytes_le(&hasher.finalize()) -} - -fn primes(n_bits: u64, rng: &mut R) -> (BigUint, BigUint) { - let random_bits = RandomBits::new(n_bits); - let target_p: BigUint = random_bits.sample(rng); - let target_q: BigUint = random_bits.sample(rng); - let p = find_next_smaller_prime(&target_p); - let q = find_next_smaller_prime(&target_q); - debug_assert_ne!(p, q); - (p, q) -} - -fn find_next_smaller_prime(target: &BigUint) -> BigUint { - // look for previous prime because we need to fit into 2 * n bits when we multiply p and q - loop { - if let Some(found) = prev_prime(target, None) { - return found; - } - } -} - -// TODO move encryption-related stuff to encrypt::paillier.rs -fn encrypt(value: &BigUint, key: &BigUint, random: &BigUint) -> BigUint { - let n2 = key * key; - pow_mult_mod(&(key + BigUint::one()), value, random, key, &n2) -} - -#[cfg(not(feature = "parallel"))] -fn batch_encrypt>(values: T, key: &BigUint, randoms: T) -> Vec { - values - .as_ref() - .iter() - .zip(randoms.as_ref()) - .map(|(val, rand)| encrypt(val, key, rand)) - .collect() -} - -#[cfg(feature = "parallel")] -fn batch_encrypt(values: T, key: &BigUint, randoms: T) -> Vec -where - T: AsRef<[BigUint]> + rayon::iter::IntoParallelIterator, -{ - values - .as_ref() - .par_iter() - .zip(randoms.as_ref()) - .map(|(val, rand)| encrypt(val, key, rand)) - .collect() -} - -fn pow_mult_mod( - a: &BigUint, - a_exp: &BigUint, - b: &BigUint, - b_exp: &BigUint, - modulo: &BigUint, -) -> BigUint { - (a.modpow(a_exp, modulo) * b.modpow(b_exp, modulo)) % modulo -} - -// NOTE -// modpow cannot handle negative exponents (it panics) Thus, we are using the extended GCD -// algorithm to find the modular inverse of `num`. However, `extended_gcd_lcm` is only implemented -// for signed types such as BigInt, hence the conversions. -pub fn modular_inverse(num: &BigUint, modulo: &BigUint) -> Option { - let num_signed = BigInt::from(num.clone()); - let mod_signed = BigInt::from(modulo.clone()); - let (ext_gcd, _) = num_signed.extended_gcd_lcm(&mod_signed); - if ext_gcd.gcd != BigInt::one() { - None - } else { - let (sign, uint) = ext_gcd.x.into_parts(); - debug_assert!(&uint < modulo); - if sign == Sign::Minus { - Some(modulo - uint) - } else { - Some(uint) - } - } -} - -pub struct PaillierRandomParameters { - pub u_vec: Vec, - pub s_vec: Vec, - pub r_vec: Vec, -} - -impl PaillierRandomParameters { - pub fn new(size: usize, rng: &mut R) -> Self { - let mut u_vec = Vec::with_capacity(size); - let mut s_vec = Vec::with_capacity(size); - let mut r_vec = Vec::with_capacity(size); - let random_bits = RandomBits::new(N_BITS); - let random_bits_2 = RandomBits::new(N_BITS >> 1); - for _ in 0..size { - u_vec.push(random_bits.sample(rng)); - s_vec.push(random_bits.sample(rng)); - r_vec.push(random_bits_2.sample(rng)); - } - - Self { - u_vec, - s_vec, - r_vec, - } - } -} - -pub struct Proof { - pub challenge: BigUint, - pub ct_vec: Vec, - pub w_vec: Vec, - pub z_vec: Vec, - pub com_q_poly: C::G1, - _digest: PhantomData, - _curve: PhantomData, -} - -impl Proof { - #[allow(clippy::too_many_arguments)] - pub fn new( - values: &[BigUint], - f_poly: &DensePolynomial, - f_s_poly: &DensePolynomial, - com_f_poly: &C::G1, - com_f_s_poly: &C::G1, - domain: &GeneralEvaluationDomain, - domain_s: &GeneralEvaluationDomain, - pubkey: &BigUint, - powers: &Powers, - rng: &mut R, - ) -> Self { - let vanishing_poly = DensePolynomial::from(domain_s.vanishing_polynomial()); - let q_poly = &(f_poly - f_s_poly) / &vanishing_poly; - let q_poly_evals = q_poly.evaluate_over_domain_by_ref(*domain); - let com_q_poly = powers.commit_scalars_g1(&q_poly_evals.evals); - - let random_params = PaillierRandomParameters::new(values.len(), rng); - let ct_vec = batch_encrypt(values, pubkey, &random_params.u_vec); - let t_vec = batch_encrypt(&random_params.r_vec, pubkey, &random_params.s_vec); - let r_scalar_vec: Vec = random_params - .r_vec - .iter() - .map(|r| C::ScalarField::from_le_bytes_mod_order(&r.to_bytes_le())) - .collect(); - let t = powers.commit_scalars_g1(&r_scalar_vec); - let challenge = challenge::( - pubkey, - &vanishing_poly, - &ct_vec, - com_f_poly, - com_f_s_poly, - &t_vec, - &t, - ); - let w_vec: Vec = random_params - .s_vec - .iter() - .zip(&random_params.u_vec) - .map(|(s, u)| pow_mult_mod(s, &BigUint::one(), u, &challenge, pubkey)) - .collect(); - let z_vec: Vec = random_params - .r_vec - .iter() - .zip(values) - .map(|(r, val)| r + &challenge * val) - .collect(); - - Self { - challenge, - ct_vec, - w_vec, - z_vec, - com_q_poly, - _digest: PhantomData, - _curve: PhantomData, - } - } - - pub fn verify( - &self, - com_f_poly: &C::G1, - com_f_s_poly: &C::G1, - domain: &GeneralEvaluationDomain, - domain_s: &GeneralEvaluationDomain, - pubkey: &BigUint, - powers: &Powers, - ) -> bool { - let vanishing_poly = DensePolynomial::from(domain_s.vanishing_polynomial()); - let vanishing_poly_evals = vanishing_poly.evaluate_over_domain_by_ref(*domain); - let com_vanishing_poly_g2 = powers.commit_scalars_g2(&vanishing_poly_evals.evals); - - let lhs_pairing = C::pairing(self.com_q_poly, com_vanishing_poly_g2); - let rhs_pairing = C::pairing(*com_f_poly - com_f_s_poly, C::G2::generator()); - if lhs_pairing != rhs_pairing { - println!("failed pairing check"); - return false; - } - - let modulo = pubkey * pubkey; - let t_vec_expected: Vec = self - .ct_vec - .iter() - .zip(self.w_vec.iter().zip(&self.z_vec)) - .map(|(ct, (w, z))| { - let aux = pow_mult_mod(&(pubkey + BigUint::one()), z, w, pubkey, &modulo); - let ct_pow_c = ct.modpow(&self.challenge, &modulo); - // TODO handle unwrap - let ct_pow_minus_c = modular_inverse(&ct_pow_c, &modulo).unwrap(); - (aux * ct_pow_minus_c) % &modulo - }) - .collect(); - let z_scalar_vec: Vec = self - .z_vec - .iter() - .map(|z| C::ScalarField::from_le_bytes_mod_order(&z.to_bytes_le())) - .collect(); - - // compute t - let challenge_scalar = - C::ScalarField::from_le_bytes_mod_order(&self.challenge.to_bytes_le()); - let commitment_pow_challenge = *com_f_s_poly * challenge_scalar; - let msm = powers.commit_scalars_g1(&z_scalar_vec); - let t_expected = msm - commitment_pow_challenge; - - let challenge_expected = challenge::( - pubkey, - &vanishing_poly, - &self.ct_vec, - com_f_poly, - com_f_s_poly, - &t_vec_expected, - &t_expected, - ); - self.challenge == challenge_expected - } - - pub fn decrypt(&self, server: &Server) -> Vec { - let denominator = server.decryption_denominator(); - let denominator_inv = modular_inverse(&denominator, &server.pubkey).unwrap(); - self.ct_vec - .iter() - .map(|ct| { - let ct_lx = server.lx(&ct.modpow(&server.privkey, &server.mod_n2)); - (ct_lx * &denominator_inv) % &server.pubkey - }) - .collect() - } -} - -#[cfg(test)] -mod test { - use super::{modular_inverse, Server, N_BITS}; - use crate::commit::kzg::Powers; - use crate::tests::{BlsCurve, PaillierEncryptionProof, Scalar, UniPoly}; - use ark_ff::{BigInteger, PrimeField}; - use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; - use ark_std::rand::distributions::Distribution; - use ark_std::{test_rng, One, UniformRand}; - use num_bigint::{BigUint, RandomBits}; - - const DATA_SIZE: usize = 16; - const SUBSET_SIZE: usize = 16; - - #[test] - fn compute_modular_inverse() { - let rng = &mut test_rng(); - let server = Server::new(rng); - let modulo = server.pubkey; - let random_bits = RandomBits::new(N_BITS); - for _ in 0..100 { - let num: BigUint = - >::sample(&random_bits, rng) % &modulo; - let inv = modular_inverse(&num, &modulo).unwrap(); - assert_eq!((num * inv) % &modulo, BigUint::one()); - } - } - - #[test] - fn flow() { - // KZG setup simulation - let rng = &mut test_rng(); - // "secret" tau - let tau = Scalar::rand(rng); - // generate powers of tau size DATA_SIZE - let powers = Powers::::unsafe_setup_eip_4844(tau, DATA_SIZE); - // new server (with encryption pubkey) - let server = Server::new(rng); - // random data to encrypt - let data: Vec = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); - let domain = GeneralEvaluationDomain::new(DATA_SIZE).unwrap(); - let domain_s = GeneralEvaluationDomain::new(SUBSET_SIZE).unwrap(); - let evaluations = Evaluations::from_vec_and_domain(data, domain); - let index_map = super::super::index_map(domain); - let subset_indices = super::super::subset_indices(&index_map, &domain_s); - let evaluations_s = super::super::subset_evals(&evaluations, &subset_indices, domain_s); - - let f_poly: UniPoly = evaluations.interpolate_by_ref(); - let f_s_poly: UniPoly = evaluations_s.interpolate_by_ref(); - - let evaluations_s_d = f_s_poly.evaluate_over_domain_by_ref(domain); - - let com_f_poly = powers.commit_scalars_g1(&evaluations.evals); - let com_f_s_poly = powers.commit_scalars_g1(&evaluations_s_d.evals); - - let data_biguint: Vec = evaluations_s - .evals - .iter() - .map(|d| BigUint::from_bytes_le(&d.into_bigint().to_bytes_le())) - .collect(); - - let proof = PaillierEncryptionProof::new( - &data_biguint, - &f_poly, - &f_s_poly, - &com_f_poly, - &com_f_s_poly, - &domain, - &domain_s, - &server.pubkey, - &powers, - rng, - ); - - assert!(proof.verify( - &com_f_poly, - &com_f_s_poly, - &domain, - &domain_s, - &server.pubkey, - &powers - )); - - let decrypted_data = proof.decrypt(&server); - assert_eq!(decrypted_data, data_biguint); - } -} diff --git a/src/veck/mod.rs b/src/veck/mod.rs index 8011a18..18e5097 100644 --- a/src/veck/mod.rs +++ b/src/veck/mod.rs @@ -1,16 +1,17 @@ -pub mod kzg_elgamal; -#[cfg(feature = "paillier")] -pub mod kzg_paillier; +pub mod kzg; use ark_ff::FftField; use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; use ark_std::collections::HashMap; -fn index_map(domain: GeneralEvaluationDomain) -> HashMap { +/// Maps the evaluation domain elements (roots of unity - keys) to their respective index (value) in the FFT domain. +pub fn index_map(domain: GeneralEvaluationDomain) -> HashMap { domain.elements().enumerate().map(|(i, e)| (e, i)).collect() } -fn subset_indices( +/// Returns the indices of domain elements in the original domain, given they are also present in +/// the subset domain. +pub fn subset_indices( index_map: &HashMap, subdomain: &GeneralEvaluationDomain, ) -> Vec { @@ -20,7 +21,8 @@ fn subset_indices( .collect() } -fn subset_evals( +/// Returns the evaluations respective to the subdomain elements. +pub fn subset_evals( evaluations: &Evaluations, indices: &[usize], subdomain: GeneralEvaluationDomain, @@ -34,6 +36,7 @@ fn subset_evals( } /* +// TODO some paillier subset toy examples use crate::commit::kzg::Powers; use ark_ec::pairing::Pairing; use ark_ec::Group; diff --git a/src/veck/server.rs b/src/veck/server.rs deleted file mode 100644 index 067bc0a..0000000 --- a/src/veck/server.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub struct Server { - -} - -// SERVER -// encryption keys -// data of length N -// interpolate polynomial -// index map for subset generation - -// PUBLIC PARAMETERS FOR ELGAMAL - GENERATE ONCE -// cipertexts -// short ciphertexts -// range proofs -// random encryption points -// decrypt - only for elgamal? brute force? - -// PROOF -// new -// verify -// decrypt - only for paillier? From 76577200ff446aebcc69aacd371b4b842356f996 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 22 Jan 2024 17:09:35 +0100 Subject: [PATCH 11/18] Benchmarks. --- Cargo.toml | 10 +++ benches/kzg_elgamal.rs | 61 +++++++++------- benches/kzg_paillier.rs | 110 +++++++++++++++++++++++++++-- benches/range_proof.rs | 37 ++++++++++ src/dleq.rs | 1 + src/veck/kzg/elgamal/encryption.rs | 73 +++++++++++-------- 6 files changed, 231 insertions(+), 61 deletions(-) create mode 100644 benches/range_proof.rs diff --git a/Cargo.toml b/Cargo.toml index 5615914..c8e3178 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,3 +57,13 @@ sha3 = "0.10" #name = "split-elgamal-encryption" #path = "benches/elgamal.rs" #harness = false + +#[[bench]] +#name = "range-proof" +#path = "benches/range_proof.rs" +#harness = false + +[[bench]] +name = "kzg-paillier-veck" +path = "benches/kzg_paillier.rs" +harness = false diff --git a/benches/kzg_elgamal.rs b/benches/kzg_elgamal.rs index 5a309d8..66d6201 100644 --- a/benches/kzg_elgamal.rs +++ b/benches/kzg_elgamal.rs @@ -1,4 +1,3 @@ -use ark_bls12_381::Bls12_381 as BlsCurve; use ark_ec::pairing::Pairing; use ark_ec::{CurveGroup, Group}; use ark_ff::PrimeField; @@ -11,10 +10,12 @@ use fde::commit::kzg::Powers; const DATA_LOG_SIZE: usize = 12; // 4096 = 2^12 const N: usize = Scalar::MODULUS_BIT_SIZE as usize / fde::encrypt::elgamal::MAX_BITS + 1; -type Scalar = ::ScalarField; +type TestCurve = ark_bls12_381::Bls12_381; +type TestHash = sha3::Keccak256; +type Scalar = ::ScalarField; type UniPoly = DensePolynomial; -type Proof = fde::veck::kzg_elgamal::Proof<{ N }, BlsCurve, sha3::Keccak256>; -type PublicInput = fde::veck::kzg_elgamal::PublicInput<{ N }, BlsCurve>; +type Proof = fde::veck::kzg::elgamal::Proof<{ N }, TestCurve, TestHash>; +type EncryptionProof = fde::veck::kzg::elgamal::EncryptionProof<{ N }, TestCurve, TestHash>; fn bench_proof(c: &mut Criterion) { let mut group = c.benchmark_group("kzg-elgamal"); @@ -24,51 +25,57 @@ fn bench_proof(c: &mut Criterion) { let rng = &mut test_rng(); let tau = Scalar::rand(rng); - let powers = Powers::::unsafe_setup(tau, data_size + 1); + let powers = Powers::::unsafe_setup(tau, data_size + 1); let encryption_sk = Scalar::rand(rng); - let encryption_pk = (::G1::generator() * encryption_sk).into_affine(); + let encryption_pk = (::G1::generator() * encryption_sk).into_affine(); let data: Vec = (0..data_size).map(|_| Scalar::rand(rng)).collect(); - let input = PublicInput::new(&data, &encryption_pk, rng); + let encryption_proof = EncryptionProof::new(&data, &encryption_pk, &powers, rng); + let domain = GeneralEvaluationDomain::new(data.len()).expect("valid domain"); + let index_map = fde::veck::index_map(domain); - let evaluations = Evaluations::from_vec_and_domain(data, input.domain); + let evaluations = Evaluations::from_vec_and_domain(data, domain); let f_poly: UniPoly = evaluations.interpolate_by_ref(); let com_f_poly = powers.commit_g1(&f_poly); - let index_map = input.index_map(); - for i in 0..=12 { let subset_size = 1 << i; let proof_gen_name = format!("proof-gen-{}", subset_size); let proof_vfy_name = format!("proof-vfy-{}", subset_size); - let sub_domain = GeneralEvaluationDomain::new(subset_size).unwrap(); - let sub_indices = sub_domain - .elements() - .map(|elem| *index_map.get(&elem).unwrap()) - .collect::>(); - let sub_data = sub_indices - .iter() - .map(|&i| evaluations.evals[i]) - .collect::>(); - let sub_evaluations = Evaluations::from_vec_and_domain(sub_data, sub_domain); - let f_s_poly: UniPoly = sub_evaluations.interpolate_by_ref(); + let subdomain = GeneralEvaluationDomain::new(subset_size).unwrap(); + let subset_indices = fde::veck::subset_indices(&index_map, &subdomain); + let subset_evaluations = fde::veck::subset_evals(&evaluations, &subset_indices, subdomain); + + let f_s_poly: UniPoly = subset_evaluations.interpolate_by_ref(); let com_f_s_poly = powers.commit_g1(&f_s_poly); - let sub_input = input.subset(&sub_indices); + let sub_encryption_proof = encryption_proof.subset(&subset_indices); group.bench_function(&proof_gen_name, |b| { b.iter(|| { - Proof::new(&f_poly, &f_s_poly, &encryption_sk, &sub_input, &powers, rng); + Proof::new( + &f_poly, + &f_s_poly, + &encryption_sk, + sub_encryption_proof.clone(), + &powers, + rng, + ).unwrap(); }) }); group.bench_function(&proof_vfy_name, |b| { - let proof = Proof::new(&f_poly, &f_s_poly, &encryption_sk, &sub_input, &powers, rng); - b.iter(|| { - assert!(proof.verify(com_f_poly, com_f_s_poly, encryption_pk, &sub_input, &powers)) - }) + let proof = Proof::new( + &f_poly, + &f_s_poly, + &encryption_sk, + sub_encryption_proof.clone(), + &powers, + rng, + ).unwrap(); + b.iter(|| assert!(proof.verify(com_f_poly, com_f_s_poly, encryption_pk, &powers).is_ok())) }); } diff --git a/benches/kzg_paillier.rs b/benches/kzg_paillier.rs index 4b4fdcb..12d46e2 100644 --- a/benches/kzg_paillier.rs +++ b/benches/kzg_paillier.rs @@ -1,25 +1,125 @@ use ark_bls12_381::Bls12_381 as BlsCurve; use ark_ec::pairing::Pairing; -use ark_ec::{CurveGroup, Group}; -use ark_ff::PrimeField; +use ark_ff::{PrimeField, BigInteger}; use ark_poly::univariate::DensePolynomial; use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; use ark_std::{test_rng, UniformRand}; use criterion::{criterion_group, criterion_main, Criterion}; +use num_bigint::BigUint; use fde::commit::kzg::Powers; +use fde::veck::kzg::paillier::Server; +type TestCurve = ark_bls12_381::Bls12_381; +type TestHash = sha3::Keccak256; type Scalar = ::ScalarField; type UniPoly = DensePolynomial; -type Proof = fde::veck::kzg_paillier::Proof<{ N }, BlsCurve, sha3::Keccak256>; +type PaillierEncryptionProof = fde::veck::kzg::paillier::Proof; fn bench_proof(c: &mut Criterion) { let mut group = c.benchmark_group("kzg-paillier"); + // TODO until subset openings don't work, use full open + //let data_size = 1 << 12; + //let data: Vec = (0..data_size).map(|_| Scalar::rand(rng)).collect(); + //let domain = GeneralEvaluationDomain::new(DATA_SIZE).unwrap(); let rng = &mut test_rng(); let tau = Scalar::rand(rng); - let powers = Powers::::unsafe_setup(tau, data_size + 1); + let powers = Powers::::unsafe_setup_eip_4844(tau, 1 << 12); // TODO data_size + let server = Server::new(rng); + + for i in 0..=12 { + // TODO remove this once subset proofs work + let data_size = 1 << i; + let subset_size = 1 << i; + let proof_gen_name = format!("proof-gen-{}", subset_size); + let proof_vfy_name = format!("proof-vfy-{}", subset_size); + let decryption_name = format!("decryption-{}", subset_size); + // random data to encrypt + let data: Vec = (0..data_size).map(|_| Scalar::rand(rng)).collect(); + let domain = GeneralEvaluationDomain::new(data_size).unwrap(); + let domain_s = GeneralEvaluationDomain::new(subset_size).unwrap(); + let evaluations = Evaluations::from_vec_and_domain(data, domain); + let index_map = fde::veck::index_map(domain); + let subset_indices = fde::veck::subset_indices(&index_map, &domain_s); + let evaluations_s = fde::veck::subset_evals(&evaluations, &subset_indices, domain_s); + + let f_poly: UniPoly = evaluations.interpolate_by_ref(); + let f_s_poly: UniPoly = evaluations_s.interpolate_by_ref(); + + let evaluations_s_d = f_s_poly.evaluate_over_domain_by_ref(domain); + + let com_f_poly = powers.commit_scalars_g1(&evaluations.evals); + let com_f_s_poly = powers.commit_scalars_g1(&evaluations_s_d.evals); + + let data_biguint: Vec = evaluations_s + .evals + .iter() + .map(|d| BigUint::from_bytes_le(&d.into_bigint().to_bytes_le())) + .collect(); + + group.bench_function(&proof_gen_name, |b| { + b.iter(|| { + PaillierEncryptionProof::new( + &data_biguint, + &f_poly, + &f_s_poly, + &com_f_poly, + &com_f_s_poly, + &domain, + &domain_s, + &server.pubkey, + &powers, + rng, + ); + }) + }); + + group.bench_function(&proof_vfy_name, |b| { + let proof = PaillierEncryptionProof::new( + &data_biguint, + &f_poly, + &f_s_poly, + &com_f_poly, + &com_f_s_poly, + &domain, + &domain_s, + &server.pubkey, + &powers, + rng, + ); + b.iter(|| { + assert!(proof + .verify( + &com_f_poly, + &com_f_s_poly, + &domain, + &domain_s, + &server.pubkey, + &powers + ) + .is_ok()); + }) + }); + + group.bench_function(&decryption_name, |b| { + let proof = PaillierEncryptionProof::new( + &data_biguint, + &f_poly, + &f_s_poly, + &com_f_poly, + &com_f_s_poly, + &domain, + &domain_s, + &server.pubkey, + &powers, + rng, + ); + b.iter(|| { + proof.decrypt(&server); + }) + }); + } - todo!(); group.finish(); } diff --git a/benches/range_proof.rs b/benches/range_proof.rs new file mode 100644 index 0000000..78bfc35 --- /dev/null +++ b/benches/range_proof.rs @@ -0,0 +1,37 @@ +use ark_ec::pairing::Pairing; +use ark_std::{test_rng, UniformRand}; +use criterion::{criterion_group, criterion_main, Criterion}; +use fde::commit::kzg::Powers; + +const LOG_2_UPPER_BOUND: usize = 8; // 2^8 + +type TestCurve = ark_bls12_381::Bls12_381; +type TestHash = sha3::Keccak256; +type Scalar = ::ScalarField; +type RangeProof = fde::range_proof::RangeProof; + +fn bench_proof(c: &mut Criterion) { + let mut group = c.benchmark_group("range-proof"); + + let rng = &mut test_rng(); + let tau = Scalar::rand(rng); + let powers = Powers::::unsafe_setup(tau, 4 * LOG_2_UPPER_BOUND); + + let z = Scalar::from(100u32); + + group.bench_function("proof-gen", |b| { + b.iter(|| { + let _proof = RangeProof::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap(); + }) + }); + + group.bench_function("proof-vfy", |b| { + let proof = RangeProof::new(z, LOG_2_UPPER_BOUND, &powers, rng).unwrap(); + b.iter(|| assert!(proof.verify(LOG_2_UPPER_BOUND, &powers).is_ok())) + }); + + group.finish(); +} + +criterion_group!(benches, bench_proof); +criterion_main!(benches); diff --git a/src/dleq.rs b/src/dleq.rs index fbe5de7..2b32344 100644 --- a/src/dleq.rs +++ b/src/dleq.rs @@ -62,6 +62,7 @@ where mod test { use super::*; use crate::tests::{G1Affine, Scalar, TestCurve, TestHash}; + use ark_ec::pairing::Pairing; use ark_ec::{AffineRepr, CurveGroup}; use ark_std::{test_rng, UniformRand}; diff --git a/src/veck/kzg/elgamal/encryption.rs b/src/veck/kzg/elgamal/encryption.rs index e2522c7..a6770c6 100644 --- a/src/veck/kzg/elgamal/encryption.rs +++ b/src/veck/kzg/elgamal/encryption.rs @@ -6,8 +6,11 @@ use ark_ec::pairing::Pairing; use ark_ec::{AffineRepr, CurveGroup}; use ark_std::rand::Rng; use digest::Digest; +#[cfg(feature = "parallel")] +use rayon::prelude::*; /// A publicly verifiable proof based on the Elgamal encryption scheme. +#[derive(Clone)] pub struct EncryptionProof { /// The actual Elgamal ciphertexts of the encrypted data points. pub ciphers: Vec>, @@ -24,41 +27,53 @@ pub struct EncryptionProof { pub random_encryption_points: Vec, } -impl EncryptionProof { - pub fn new( +impl Default for EncryptionProof { + fn default() -> Self { + Self { + ciphers: Vec::new(), + short_ciphers: Vec::new(), + range_proofs: Vec::new(), + random_encryption_points: Vec::new(), + } + } +} + +impl EncryptionProof { + pub fn new( evaluations: &[C::ScalarField], encryption_pk: & as EncryptionEngine>::EncryptionKey, powers: &Powers, rng: &mut R, ) -> Self { - let mut random_encryption_points = Vec::with_capacity(evaluations.len()); - let mut ciphers = Vec::with_capacity(evaluations.len()); - let mut short_ciphers = Vec::with_capacity(evaluations.len()); - let mut range_proofs = Vec::with_capacity(evaluations.len()); - - for eval in evaluations { - let split_eval = SplitScalar::from(*eval); - let rp = split_eval.splits().map(|s| { - RangeProof::new(s, MAX_BITS, powers, rng).expect("invalid range proof input") - }); - let (sc, rand) = split_eval.encrypt::, _>(encryption_pk, rng); - let cipher = as EncryptionEngine>::encrypt_with_randomness( - eval, - encryption_pk, - &rand, - ); - random_encryption_points.push((C::G1Affine::generator() * rand).into_affine()); - ciphers.push(cipher); - short_ciphers.push(sc); - range_proofs.push(rp); - } + // TODO parallelize this somehow + evaluations.iter().fold(Self::default(), |acc, eval| { + acc.extend(eval, encryption_pk, powers, rng) + }) + } - Self { - ciphers, - short_ciphers, - range_proofs, - random_encryption_points, - } + fn extend( + mut self, + eval: &C::ScalarField, + encryption_pk: & as EncryptionEngine>::EncryptionKey, + powers: &Powers, + rng: &mut R, + ) -> Self { + let split_eval = SplitScalar::from(*eval); + let rp = split_eval + .splits() + .map(|s| RangeProof::new(s, MAX_BITS, powers, rng).expect("invalid range proof input")); + let (sc, rand) = split_eval.encrypt::, _>(encryption_pk, rng); + let cipher = as EncryptionEngine>::encrypt_with_randomness( + eval, + encryption_pk, + &rand, + ); + self.random_encryption_points + .push((C::G1Affine::generator() * rand).into_affine()); + self.ciphers.push(cipher); + self.short_ciphers.push(sc); + self.range_proofs.push(rp); + self } /// Generates a subset from the total encrypted data. From d382a52f8c36a823e9184ca1eeb461e9e320ac84 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 23 Jan 2024 14:12:10 +0100 Subject: [PATCH 12/18] Some parallelization optimizations. --- Cargo.toml | 30 +++++++++---------- benches/kzg_elgamal.rs | 18 +++++++++-- benches/kzg_paillier.rs | 4 +-- src/encrypt/elgamal/mod.rs | 8 +++++ src/veck/kzg/elgamal/encryption.rs | 48 ++++++++++++++++++++++-------- src/veck/kzg/elgamal/mod.rs | 14 +++++---- 6 files changed, 83 insertions(+), 39 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c8e3178..b318742 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,22 +48,22 @@ ark-secp256k1 = "0.4" criterion = "0.5" sha3 = "0.10" -#[[bench]] -#name = "kzg-elgamal-veck" -#path = "benches/kzg_elgamal.rs" -#harness = false -# -#[[bench]] -#name = "split-elgamal-encryption" -#path = "benches/elgamal.rs" -#harness = false - -#[[bench]] -#name = "range-proof" -#path = "benches/range_proof.rs" -#harness = false - [[bench]] name = "kzg-paillier-veck" path = "benches/kzg_paillier.rs" harness = false + +[[bench]] +name = "kzg-elgamal-veck" +path = "benches/kzg_elgamal.rs" +harness = false + +[[bench]] +name = "split-elgamal-encryption" +path = "benches/elgamal.rs" +harness = false + +[[bench]] +name = "range-proof" +path = "benches/range_proof.rs" +harness = false diff --git a/benches/kzg_elgamal.rs b/benches/kzg_elgamal.rs index 66d6201..eecd86b 100644 --- a/benches/kzg_elgamal.rs +++ b/benches/kzg_elgamal.rs @@ -30,8 +30,14 @@ fn bench_proof(c: &mut Criterion) { let encryption_sk = Scalar::rand(rng); let encryption_pk = (::G1::generator() * encryption_sk).into_affine(); + println!("Generating encryption proofs for 4096 * 8 split field elements..."); + println!("This might take a few minutes and it's not included in the actual benchmarks."); + let t_start = std::time::Instant::now(); let data: Vec = (0..data_size).map(|_| Scalar::rand(rng)).collect(); let encryption_proof = EncryptionProof::new(&data, &encryption_pk, &powers, rng); + let elapsed = std::time::Instant::now().duration_since(t_start).as_secs(); + println!("Generated encryption proofs, elapsed time: {} [s]", elapsed); + let domain = GeneralEvaluationDomain::new(data.len()).expect("valid domain"); let index_map = fde::veck::index_map(domain); @@ -62,7 +68,8 @@ fn bench_proof(c: &mut Criterion) { sub_encryption_proof.clone(), &powers, rng, - ).unwrap(); + ) + .unwrap(); }) }); @@ -74,8 +81,13 @@ fn bench_proof(c: &mut Criterion) { sub_encryption_proof.clone(), &powers, rng, - ).unwrap(); - b.iter(|| assert!(proof.verify(com_f_poly, com_f_s_poly, encryption_pk, &powers).is_ok())) + ) + .unwrap(); + b.iter(|| { + assert!(proof + .verify(com_f_poly, com_f_s_poly, encryption_pk, &powers) + .is_ok()) + }) }); } diff --git a/benches/kzg_paillier.rs b/benches/kzg_paillier.rs index 12d46e2..24f3bad 100644 --- a/benches/kzg_paillier.rs +++ b/benches/kzg_paillier.rs @@ -1,13 +1,13 @@ use ark_bls12_381::Bls12_381 as BlsCurve; use ark_ec::pairing::Pairing; -use ark_ff::{PrimeField, BigInteger}; +use ark_ff::{BigInteger, PrimeField}; use ark_poly::univariate::DensePolynomial; use ark_poly::{EvaluationDomain, Evaluations, GeneralEvaluationDomain}; use ark_std::{test_rng, UniformRand}; use criterion::{criterion_group, criterion_main, Criterion}; -use num_bigint::BigUint; use fde::commit::kzg::Powers; use fde::veck::kzg::paillier::Server; +use num_bigint::BigUint; type TestCurve = ark_bls12_381::Bls12_381; type TestHash = sha3::Keccak256; diff --git a/src/encrypt/elgamal/mod.rs b/src/encrypt/elgamal/mod.rs index bd5926b..42aa7a6 100644 --- a/src/encrypt/elgamal/mod.rs +++ b/src/encrypt/elgamal/mod.rs @@ -15,6 +15,11 @@ pub const MAX_BITS: usize = 32; pub struct ExponentialElgamal(pub PhantomData); +/// Exponential Elgamal encryption scheme ciphertext. +/// +/// It contains `c1 = g^y` and `c2 = g^m * h^y` where `g` is a group generator, `h = g^x` is the +/// public encryption key computed from the secret `x` key, `y` is some random scalar and `m` is +/// the message to be encrypted. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct Cipher([C::Affine; 2]); @@ -87,8 +92,11 @@ impl EncryptionEngine for ExponentialElgamal { key: &Self::EncryptionKey, randomness: &Self::PlainText, ) -> Self::Cipher { + // h^y let shared_secret = *key * randomness; + // g^y let c1 = ::generator() * randomness; + // g^m * h^y let c2 = ::generator() * data + shared_secret; Cipher([c1.into_affine(), c2.into_affine()]) } diff --git a/src/veck/kzg/elgamal/encryption.rs b/src/veck/kzg/elgamal/encryption.rs index a6770c6..2ea074b 100644 --- a/src/veck/kzg/elgamal/encryption.rs +++ b/src/veck/kzg/elgamal/encryption.rs @@ -104,22 +104,44 @@ impl EncryptionProo /// Checks that the sum of split scalars evaluate to the encrypted value via the homomorphic /// properties of Elgamal encryption. pub fn verify_split_scalars(&self) -> bool { - for (cipher, short_cipher) in self.ciphers.iter().zip(&self.short_ciphers) { - if !cipher.check_encrypted_sum(short_cipher) { - return false; - } - } - true + #[cfg(feature = "parallel")] + let result = self + .ciphers + .par_iter() + .zip(&self.short_ciphers) + .fold( + || true, + |acc, (cipher, short_cipher)| acc && cipher.check_encrypted_sum(short_cipher), + ) + .reduce(|| true, |acc: bool, sub_boolean: bool| acc && sub_boolean); + + #[cfg(not(feature = "parallel"))] + let result = self + .ciphers + .iter() + .zip(&self.short_ciphers) + .fold(true, |acc, (cipher, short_cipher)| { + acc && cipher.check_encrypted_sum(short_cipher) + }); + result } // TODO range proofs and short ciphers are not "connected" by anything? - // TODO parallelize pub fn verify_range_proofs(&self, powers: &Powers) -> bool { - for rps in self.range_proofs.iter() { - if !rps.iter().all(|rp| rp.verify(MAX_BITS, powers).is_ok()) { - return false; - } - } - true + #[cfg(feature = "parallel")] + let result = self + .range_proofs + .par_iter() + .fold( + || true, + |acc, rps| acc && rps.par_iter().all(|rp| rp.verify(MAX_BITS, powers).is_ok()), + ) + .reduce(|| true, |acc: bool, sub_boolean: bool| acc && sub_boolean); + + #[cfg(not(feature = "parallel"))] + let result = self.range_proofs.iter().fold(true, |acc, rps| { + acc && rps.par_iter.all(|rp| rp.verify(MAX_BITS, powers)).is_ok() + }); + result } } diff --git a/src/veck/kzg/elgamal/mod.rs b/src/veck/kzg/elgamal/mod.rs index 1873aa3..cbc22d4 100644 --- a/src/veck/kzg/elgamal/mod.rs +++ b/src/veck/kzg/elgamal/mod.rs @@ -28,6 +28,8 @@ pub enum Error { InvalidSubsetPolynomial, #[error("invalid split scalar verification")] InvalidSplitScalars, + #[error("invalid range proofs")] + InvalidRangeProofs, } pub struct Proof { @@ -43,7 +45,7 @@ pub struct Proof { impl Proof where C: Pairing, - D: Digest + Clone, + D: Digest + Clone + Send + Sync, { pub fn new( f_poly: &DensePolynomial, @@ -161,7 +163,6 @@ where powers, ); - // check split scalar encryption validity // check that split scalars are in a brute-forceable range if !dleq_check { @@ -170,6 +171,10 @@ where Err(Error::InvalidKzgProof.into()) } else if !subset_pairing_check { Err(Error::InvalidSubsetPolynomial.into()) + } else if !self.encryption_proof.verify_split_scalars() { + Err(Error::InvalidSplitScalars.into()) + } else if !self.encryption_proof.verify_range_proofs(powers) { + Err(Error::InvalidRangeProofs.into()) } else { Ok(()) } @@ -206,10 +211,7 @@ mod test { let data: Vec = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); let encryption_proof = ElgamalEncryptionProof::new(&data, &encryption_pk, &powers, rng); - encryption_proof - .range_proofs - .iter() - .for_each(|rps| assert!(rps.iter().all(|rp| rp.verify(MAX_BITS, &powers).is_ok()))); + assert!(encryption_proof.verify_range_proofs(&powers)); let domain = GeneralEvaluationDomain::new(data.len()).expect("valid domain"); let index_map = crate::veck::index_map(domain); From 7c6b9cbdd4e7236a030bc0eac6d45ec21841a974 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 23 Jan 2024 14:54:28 +0100 Subject: [PATCH 13/18] Parallelized range proof generation. --- src/encrypt/elgamal/mod.rs | 7 +++ src/veck/kzg/elgamal/encryption.rs | 70 +++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/encrypt/elgamal/mod.rs b/src/encrypt/elgamal/mod.rs index 42aa7a6..ed0fc44 100644 --- a/src/encrypt/elgamal/mod.rs +++ b/src/encrypt/elgamal/mod.rs @@ -23,10 +23,17 @@ pub struct ExponentialElgamal(pub PhantomData); #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct Cipher([C::Affine; 2]); +impl Default for Cipher { + fn default() -> Self { + Self::zero() + } +} + impl Zero for Cipher { fn zero() -> Self { Self([C::Affine::zero(); 2]) } + fn is_zero(&self) -> bool { self.c0().is_zero() && self.c1().is_zero() } diff --git a/src/veck/kzg/elgamal/encryption.rs b/src/veck/kzg/elgamal/encryption.rs index 2ea074b..8cb5cbb 100644 --- a/src/veck/kzg/elgamal/encryption.rs +++ b/src/veck/kzg/elgamal/encryption.rs @@ -43,15 +43,28 @@ impl EncryptionProo evaluations: &[C::ScalarField], encryption_pk: & as EncryptionEngine>::EncryptionKey, powers: &Powers, - rng: &mut R, + _rng: &mut R, ) -> Self { - // TODO parallelize this somehow - evaluations.iter().fold(Self::default(), |acc, eval| { - acc.extend(eval, encryption_pk, powers, rng) - }) + #[cfg(not(feature = "parallel"))] + let proof = evaluations.iter().fold(Self::default(), |acc, eval| { + acc.append(eval, encryption_pk, powers, _rng) + }); + + #[cfg(feature = "parallel")] + let proof = evaluations + .par_iter() + .fold( + || Self::default(), + |acc, eval| { + let rng = &mut ark_std::rand::thread_rng(); + acc.append(eval, encryption_pk, powers, rng) + }, + ) + .reduce(|| Self::default(), |acc, proof| acc.extend(proof)); + proof } - fn extend( + fn append( mut self, eval: &C::ScalarField, encryption_pk: & as EncryptionEngine>::EncryptionKey, @@ -76,6 +89,15 @@ impl EncryptionProo self } + fn extend(mut self, other: Self) -> Self { + self.random_encryption_points + .extend(other.random_encryption_points); + self.ciphers.extend(other.ciphers); + self.short_ciphers.extend(other.short_ciphers); + self.range_proofs.extend(other.range_proofs); + self + } + /// Generates a subset from the total encrypted data. /// /// Clients might not be interested in the whole dataset, thus the server may generate a subset @@ -145,3 +167,39 @@ impl EncryptionProo result } } + +#[cfg(test)] +mod test { + use super::*; + use crate::tests::*; + use ark_ec::Group; + use ark_std::{test_rng, UniformRand}; + + const DATA_SIZE: usize = 16; + + type ElgamalEncryptionProof = EncryptionProof<{ N }, TestCurve, TestHash>; + + #[test] + fn encryption_proof() { + let rng = &mut test_rng(); + let tau = Scalar::rand(rng); // "secret" tau + let powers = Powers::::unsafe_setup(tau, (DATA_SIZE + 1).max(MAX_BITS * 4)); // generate powers of tau size DATA_SIZE + + let encryption_sk = Scalar::rand(rng); + let encryption_pk = (::G1::generator() * encryption_sk).into_affine(); + + let data: Vec = (0..DATA_SIZE).map(|_| Scalar::rand(rng)).collect(); + let mut encryption_proof = ElgamalEncryptionProof::new(&data, &encryption_pk, &powers, rng); + + assert!(encryption_proof.verify_split_scalars()); + assert!(encryption_proof.verify_range_proofs(&powers)); + + // manually modify the encryption proof so that it fails + encryption_proof.short_ciphers[DATA_SIZE - 3][2] = Default::default(); + assert!(!encryption_proof.verify_split_scalars()); + + encryption_proof.range_proofs[DATA_SIZE - 3][3] = + RangeProof::new(Scalar::from(123u8), 10, &powers, rng).unwrap(); + assert!(!encryption_proof.verify_range_proofs(&powers)); + } +} From 170d6b484b6eaa2e75bdca39d386f9eae632dd91 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 23 Jan 2024 17:01:24 +0100 Subject: [PATCH 14/18] Some benchmarks results. --- benches/kzg-elgamal-bench-results | 27 ++++++++++++++++++++ benches/kzg-paillier-bench-results | 40 ++++++++++++++++++++++++++++++ benches/kzg_elgamal.rs | 1 + benches/kzg_paillier.rs | 1 + benches/paillier-plot.txt | 4 +++ src/range_proof/mod.rs | 6 +++++ 6 files changed, 79 insertions(+) create mode 100644 benches/kzg-elgamal-bench-results create mode 100644 benches/kzg-paillier-bench-results create mode 100644 benches/paillier-plot.txt diff --git a/benches/kzg-elgamal-bench-results b/benches/kzg-elgamal-bench-results new file mode 100644 index 0000000..c08a725 --- /dev/null +++ b/benches/kzg-elgamal-bench-results @@ -0,0 +1,27 @@ +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-1","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[170862167.0,333291695.0,454686341.0,616684940.0,782865587.0,949580541.0,1184568382.0,1265048264.0,1470642766.0,1529809390.0],"unit":"ns","throughput":[],"typical":{"estimate":159029348.31428573,"lower_bound":154856461.47311828,"upper_bound":163611297.76355356,"unit":"ns"},"mean":{"estimate":160181868.2415873,"lower_bound":156253440.76888886,"upper_bound":164312732.06984124,"unit":"ns"},"median":{"estimate":158197228.25,"lower_bound":154171235.0,"upper_bound":166645847.5,"unit":"ns"},"median_abs_dev":{"estimate":7727172.274981946,"lower_bound":1253023.8896843968,"upper_bound":11289364.426803729,"unit":"ns"},"slope":{"estimate":159029348.31428573,"lower_bound":154856461.47311828,"upper_bound":163611297.76355356,"unit":"ns"},"change":{"mean":{"estimate":-0.003684486662215103,"lower_bound":-0.032963450480611944,"upper_bound":0.027735574722946597,"unit":"%"},"median":{"estimate":0.006497940808784852,"lower_bound":-0.020613245247548262,"upper_bound":0.07001596257532006,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-1","iteration_count":[4,8,12,16,20,24,28,32,36,40],"measured_values":[74159463.0,153067622.0,297198365.0,381022954.0,540506305.0,677624207.0,882985081.0,948274311.0,1130949124.0,1285928027.0],"unit":"ns","throughput":[],"typical":{"estimate":30109851.185714286,"lower_bound":27796454.492957745,"upper_bound":31215210.502645504,"unit":"ns"},"mean":{"estimate":26624564.855248015,"lower_bound":23598398.281944446,"upper_bound":29401526.354166668,"unit":"ns"},"median":{"estimate":27629828.604166664,"lower_bound":21949991.583333336,"upper_bound":31415253.444444444,"unit":"ns"},"median_abs_dev":{"estimate":5634857.540815447,"lower_bound":706159.247825671,"upper_bound":8791626.835617425,"unit":"ns"},"slope":{"estimate":30109851.185714286,"lower_bound":27796454.492957745,"upper_bound":31215210.502645504,"unit":"ns"},"change":{"mean":{"estimate":0.4363114297779893,"lower_bound":0.3026368999537424,"upper_bound":0.5905916183412421,"unit":"%"},"median":{"estimate":0.4906804770194526,"lower_bound":0.28471410042603273,"upper_bound":0.6958642915965025,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-2","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[171013444.0,366918093.0,547442505.0,676308577.0,898056523.0,1056663137.0,1216988792.0,1399426701.0,1633469878.0,1785895896.0],"unit":"ns","throughput":[],"typical":{"estimate":88775579.09610389,"lower_bound":87447502.25186104,"upper_bound":89852719.77949506,"unit":"ns"},"mean":{"estimate":88531120.9616865,"lower_bound":87081768.75823413,"upper_bound":89932604.70694444,"unit":"ns"},"median":{"estimate":88675028.10833333,"lower_bound":86485445.40625,"upper_bound":90748326.55555555,"unit":"ns"},"median_abs_dev":{"estimate":2832177.888952127,"lower_bound":729574.0212808102,"upper_bound":4241623.184249877,"unit":"ns"},"slope":{"estimate":88775579.09610389,"lower_bound":87447502.25186104,"upper_bound":89852719.77949506,"unit":"ns"},"change":{"mean":{"estimate":0.014557392940485192,"lower_bound":-0.00810298471704747,"upper_bound":0.03662046956215965,"unit":"%"},"median":{"estimate":0.05808361255455963,"lower_bound":0.024984107116773124,"upper_bound":0.08620653142651902,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-2","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[93829556.0,189347075.0,279347384.0,364709584.0,468726500.0,571606598.0,669796250.0,755794256.0,883812605.0,944584204.0],"unit":"ns","throughput":[],"typical":{"estimate":31755635.987012986,"lower_bound":31335528.690860216,"upper_bound":32221745.826576576,"unit":"ns"},"mean":{"estimate":31487621.067566138,"lower_bound":31140403.995793648,"upper_bound":31853591.02692064,"unit":"ns"},"median":{"estimate":31488783.733333334,"lower_bound":31157558.444444448,"upper_bound":31755922.111111112,"unit":"ns"},"median_abs_dev":{"estimate":376201.42428775784,"lower_bound":53155.43446630184,"upper_bound":1010730.491422615,"unit":"ns"},"slope":{"estimate":31755635.987012986,"lower_bound":31335528.690860216,"upper_bound":32221745.826576576,"unit":"ns"},"change":{"mean":{"estimate":0.01839484838281691,"lower_bound":0.006114371254936577,"upper_bound":0.03248548511220777,"unit":"%"},"median":{"estimate":0.008580867049936991,"lower_bound":0.00008556587178430775,"upper_bound":0.018829921651676962,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-4","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[115988138.0,214462224.0,312601581.0,413788418.0,505855681.0,619198416.0,696085116.0,825275378.0,938118133.0,1032467879.0],"unit":"ns","throughput":[],"typical":{"estimate":51460884.05844156,"lower_bound":50782963.04699739,"upper_bound":51920454.234421365,"unit":"ns"},"mean":{"estimate":52266002.1409127,"lower_bound":51164495.172106154,"upper_bound":53746014.52341269,"unit":"ns"},"median":{"estimate":51673473.1,"lower_bound":51092718.05,"upper_bound":52857909.75,"unit":"ns"},"median_abs_dev":{"estimate":645665.8804104679,"lower_bound":32382.07759760541,"upper_bound":2771608.1717566233,"unit":"ns"},"slope":{"estimate":51460884.05844156,"lower_bound":50782963.04699739,"upper_bound":51920454.234421365,"unit":"ns"},"change":{"mean":{"estimate":-0.008465694908526555,"lower_bound":-0.0346206963726785,"upper_bound":0.02092736028375263,"unit":"%"},"median":{"estimate":0.020069150196685648,"lower_bound":0.0005535273689742937,"upper_bound":0.03746707776174674,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-4","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[130475529.0,261943303.0,387735198.0,520478509.0,654463515.0,783658767.0,915585124.0,1044753626.0,1165758844.0,1293790881.0],"unit":"ns","throughput":[],"typical":{"estimate":43351182.012121215,"lower_bound":43209574.84353741,"upper_bound":43549606.20698066,"unit":"ns"},"mean":{"estimate":43420476.59671958,"lower_bound":43287728.67611112,"upper_bound":43542389.89494445,"unit":"ns"},"median":{"estimate":43511622.04166667,"lower_bound":43176253.481481485,"upper_bound":43599291.61904762,"unit":"ns"},"median_abs_dev":{"estimate":191027.01443359072,"lower_bound":33177.00446098859,"upper_bound":341031.43755771173,"unit":"ns"},"slope":{"estimate":43351182.012121215,"lower_bound":43209574.84353741,"upper_bound":43549606.20698066,"unit":"ns"},"change":{"mean":{"estimate":0.005380647903423519,"lower_bound":0.0021273750944650785,"upper_bound":0.008437147533117239,"unit":"%"},"median":{"estimate":0.00518848956236484,"lower_bound":-0.002235069979841464,"upper_bound":0.012457895016416032,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-8","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[115963732.0,206789103.0,312638594.0,406675520.0,513614290.0,614680719.0,719354269.0,825925638.0,918716303.0,1062354233.0],"unit":"ns","throughput":[],"typical":{"estimate":34532631.6952381,"lower_bound":34126708.15125596,"upper_bound":35018891.844840385,"unit":"ns"},"mean":{"estimate":34824342.85034391,"lower_bound":34211992.24704034,"upper_bound":35768063.8216713,"unit":"ns"},"median":{"estimate":34334266.7202381,"lower_bound":34133741.2037037,"upper_bound":34938329.13333333,"unit":"ns"},"median_abs_dev":{"estimate":365516.391974678,"lower_bound":78604.75015449304,"upper_bound":1017016.4888026826,"unit":"ns"},"slope":{"estimate":34532631.6952381,"lower_bound":34126708.15125596,"upper_bound":35018891.844840385,"unit":"ns"},"change":{"mean":{"estimate":0.018106007680380953,"lower_bound":-0.002205665789420509,"upper_bound":0.04867780399255452,"unit":"%"},"median":{"estimate":0.02114263111674375,"lower_bound":0.012915569734522014,"upper_bound":0.035850669636830354,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-8","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[155422712.0,308437407.0,466138853.0,622424677.0,778768251.0,934584532.0,1089453303.0,1237794576.0,1402525745.0,1557337620.0],"unit":"ns","throughput":[],"typical":{"estimate":77774543.9922078,"lower_bound":77583208.62324929,"upper_bound":77880516.98760763,"unit":"ns"},"mean":{"estimate":77703770.26575395,"lower_bound":77534025.79092263,"upper_bound":77839650.29650794,"unit":"ns"},"median":{"estimate":77810588.84821428,"lower_bound":77536758.5,"upper_bound":77876825.1,"unit":"ns"},"median_abs_dev":{"estimate":126531.25925361742,"lower_bound":14743.122398248419,"upper_bound":338459.9475244804,"unit":"ns"},"slope":{"estimate":77774543.9922078,"lower_bound":77583208.62324929,"upper_bound":77880516.98760763,"unit":"ns"},"change":{"mean":{"estimate":0.004115856441050836,"lower_bound":0.0011560614316662831,"upper_bound":0.006990230233869603,"unit":"%"},"median":{"estimate":0.00446302157545686,"lower_bound":0.001693556827132286,"upper_bound":0.005379083929462736,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-16","iteration_count":[4,8,12,16,20,24,28,32,36,40],"measured_values":[107085455.0,207817667.0,309371474.0,418180269.0,519788398.0,631953231.0,724431269.0,823329524.0,925011292.0,1031787335.0],"unit":"ns","throughput":[],"typical":{"estimate":25853797.21818182,"lower_bound":25759793.250666667,"upper_bound":26038835.429301593,"unit":"ns"},"mean":{"estimate":26007763.406170633,"lower_bound":25834593.69109127,"upper_bound":26220196.354949407,"unit":"ns"},"median":{"estimate":25924876.848214284,"lower_bound":25761865.5,"upper_bound":26160402.2625,"unit":"ns"},"median_abs_dev":{"estimate":251856.59992864745,"lower_bound":50837.63238911705,"upper_bound":470797.3514104262,"unit":"ns"},"slope":{"estimate":25853797.21818182,"lower_bound":25759793.250666667,"upper_bound":26038835.429301593,"unit":"ns"},"change":{"mean":{"estimate":0.008535656041445128,"lower_bound":-0.00020298523829348584,"upper_bound":0.017327213226329834,"unit":"%"},"median":{"estimate":0.019865404397654274,"lower_bound":0.007912913976041436,"upper_bound":0.028555657516446287,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-16","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[136451284.0,272713931.0,411374027.0,546535846.0,688536059.0,822158646.0,957325926.0,1093503795.0,1233248529.0,1371124211.0],"unit":"ns","throughput":[],"typical":{"estimate":136980694.79220778,"lower_bound":136798990.89957264,"upper_bound":137152928.98820975,"unit":"ns"},"mean":{"estimate":136888939.58464283,"lower_bound":136668497.02178568,"upper_bound":137132522.59714285,"unit":"ns"},"median":{"estimate":136893643.78571427,"lower_bound":136569629.1875,"upper_bound":137112421.1,"unit":"ns"},"median_abs_dev":{"estimate":333443.5505102071,"lower_bound":63737.0469984368,"upper_bound":701540.5314851778,"unit":"ns"},"slope":{"estimate":136980694.79220778,"lower_bound":136798990.89957264,"upper_bound":137152928.98820975,"unit":"ns"},"change":{"mean":{"estimate":0.0016377832775074097,"lower_bound":-0.00016356926924895038,"upper_bound":0.003716100035005558,"unit":"%"},"median":{"estimate":0.002112647337863205,"lower_bound":-0.00027605260815410926,"upper_bound":0.004079623655056652,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-32","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[108622465.0,213180028.0,323025962.0,432080620.0,544185520.0,649147585.0,757516773.0,869360333.0,974642559.0,1080806363.0],"unit":"ns","throughput":[],"typical":{"estimate":21654827.393766236,"lower_bound":21618548.29905504,"upper_bound":21696027.964068975,"unit":"ns"},"mean":{"estimate":21623946.005642854,"lower_bound":21541839.039166667,"upper_bound":21689681.16764107,"unit":"ns"},"median":{"estimate":21640794.602380954,"lower_bound":21575595.696666665,"upper_bound":21724493.0,"unit":"ns"},"median_abs_dev":{"estimate":89298.47901463509,"lower_bound":15174.929640593355,"upper_bound":171930.92026762094,"unit":"ns"},"slope":{"estimate":21654827.393766236,"lower_bound":21618548.29905504,"upper_bound":21696027.964068975,"unit":"ns"},"change":{"mean":{"estimate":-0.005948662845505548,"lower_bound":-0.011684140045201094,"upper_bound":-0.0009796381307688733,"unit":"%"},"median":{"estimate":-0.005135922763151335,"lower_bound":-0.010829326746251255,"upper_bound":0.003694869146089408,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-32","iteration_count":[2,2,2,2,2,2,2,2,2,2],"measured_values":[529225512.0,528773252.0,528873842.0,529348103.0,529540575.0,529335279.0,529135613.0,529628469.0,530014425.0,529370335.0],"unit":"ns","throughput":[],"typical":{"estimate":264662270.25,"lower_bound":264558538.8725,"upper_bound":264770263.32625002,"unit":"ns"},"mean":{"estimate":264662270.25,"lower_bound":264558538.8725,"upper_bound":264770263.32625002,"unit":"ns"},"median":{"estimate":264670845.5,"lower_bound":264524838.5,"upper_bound":264770287.5,"unit":"ns"},"median_abs_dev":{"estimate":150099.16263520718,"lower_bound":16480.581307411194,"upper_bound":316986.17542237043,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":0.0017344090317426009,"lower_bound":0.0012196160985552707,"upper_bound":0.0022407166949714617,"unit":"%"},"median":{"estimate":0.0018058091015791256,"lower_bound":0.0011862432009681623,"upper_bound":0.0024127729347607207,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-64","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[100491311.0,194499166.0,290966123.0,388989736.0,490746726.0,587143591.0,683116991.0,783840839.0,881043579.0,974898787.0],"unit":"ns","throughput":[],"typical":{"estimate":19545905.382857144,"lower_bound":19508652.597333334,"upper_bound":19582300.539578315,"unit":"ns"},"mean":{"estimate":19578710.043595236,"lower_bound":19486200.115179166,"upper_bound":19710571.891554758,"unit":"ns"},"median":{"estimate":19544540.673809525,"lower_bound":19449916.6,"upper_bound":19604307.619999997,"unit":"ns"},"median_abs_dev":{"estimate":101416.26332900065,"lower_bound":18212.214834168368,"upper_bound":191002.7615690198,"unit":"ns"},"slope":{"estimate":19545905.382857144,"lower_bound":19508652.597333334,"upper_bound":19582300.539578315,"unit":"ns"},"change":{"mean":{"estimate":-0.0009612584900137167,"lower_bound":-0.006791145181355734,"upper_bound":0.00685419102049897,"unit":"%"},"median":{"estimate":0.0007152977845437114,"lower_bound":-0.0062431800864068965,"upper_bound":0.005793841754208717,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-64","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[518823322.0,512369732.0,514527829.0,511664185.0,512170337.0,511655720.0,510748534.0,511014555.0,511834586.0,511390000.0],"unit":"ns","throughput":[],"typical":{"estimate":512619880.0,"lower_bound":511484701.1,"upper_bound":514232717.85249996,"unit":"ns"},"mean":{"estimate":512619880.0,"lower_bound":511484701.1,"upper_bound":514232717.85249996,"unit":"ns"},"median":{"estimate":511749385.5,"lower_bound":511335137.5,"upper_bound":513349083.0,"unit":"ns"},"median_abs_dev":{"estimate":771914.1936957836,"lower_bound":138868.46783459187,"upper_bound":2255776.60125196,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":-0.005288310181835176,"lower_bound":-0.007896936928401679,"upper_bound":-0.001736288185289982,"unit":"%"},"median":{"estimate":-0.004771362272160684,"lower_bound":-0.006885361613947039,"upper_bound":-0.0015668679233135085,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-128","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[96936801.0,190414359.0,284956718.0,386105186.0,480609453.0,572612730.0,673899017.0,768360264.0,862719380.0,963205242.0],"unit":"ns","throughput":[],"typical":{"estimate":19208562.147012986,"lower_bound":19156770.815873016,"upper_bound":19246630.172881357,"unit":"ns"},"mean":{"estimate":19194154.989968255,"lower_bound":19121807.481970634,"upper_bound":19263656.54063492,"unit":"ns"},"median":{"estimate":19216692.36,"lower_bound":19087091.0,"upper_bound":19279758.464285716,"unit":"ns"},"median_abs_dev":{"estimate":100801.54225641621,"lower_bound":29449.41701316745,"upper_bound":219487.54820731812,"unit":"ns"},"slope":{"estimate":19208562.147012986,"lower_bound":19156770.815873016,"upper_bound":19246630.172881357,"unit":"ns"},"change":{"mean":{"estimate":-0.008701306827168076,"lower_bound":-0.01424603293028881,"upper_bound":-0.003844308791122217,"unit":"%"},"median":{"estimate":-0.0023257101255256263,"lower_bound":-0.010949218915978776,"upper_bound":0.0019969396450076893,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-128","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[1017871018.0,1018633913.0,1011745915.0,1018923647.0,1013985665.0,1014366471.0,1011892361.0,1019384304.0,1016349189.0,1019585863.0],"unit":"ns","throughput":[],"typical":{"estimate":1016273834.6,"lower_bound":1014435002.4175,"upper_bound":1018011899.635,"unit":"ns"},"mean":{"estimate":1016273834.6,"lower_bound":1014435002.4175,"upper_bound":1018011899.635,"unit":"ns"},"median":{"estimate":1017110103.5,"lower_bound":1013129416.0,"upper_bound":1019009108.5,"unit":"ns"},"median_abs_dev":{"estimate":3521145.285487175,"lower_bound":490900.7120847702,"upper_bound":5123809.91153419,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":-0.0025930471180278802,"lower_bound":-0.0042868298452721386,"upper_bound":-0.0008607962958950528,"unit":"%"},"median":{"estimate":-0.0012480166314169372,"lower_bound":-0.0049251925580239275,"upper_bound":0.0007090969226681842,"unit":"%"},"change":"NoChange"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-256","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[100966936.0,199492403.0,308358449.0,399274702.0,532721932.0,596061381.0,695384086.0,830958926.0,982638486.0,1126068430.0],"unit":"ns","throughput":[],"typical":{"estimate":21237347.806233767,"lower_bound":20203841.91934426,"upper_bound":21938233.048005115,"unit":"ns"},"mean":{"estimate":20684105.18061905,"lower_bound":20180116.70561905,"upper_bound":21266729.740666665,"unit":"ns"},"median":{"estimate":20375308.566666666,"lower_bound":19916223.9,"upper_bound":21308877.28,"unit":"ns"},"median_abs_dev":{"estimate":691383.9097654816,"lower_bound":60578.674864512905,"upper_bound":1458654.5756337058,"unit":"ns"},"slope":{"estimate":21237347.806233767,"lower_bound":20203841.91934426,"upper_bound":21938233.048005115,"unit":"ns"},"change":{"mean":{"estimate":0.046775371934458354,"lower_bound":0.019478597589168707,"upper_bound":0.07713490526912882,"unit":"%"},"median":{"estimate":0.03777419998455711,"lower_bound":0.013892377553136548,"upper_bound":0.08735885685398759,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-256","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[2081998508.0,2103073433.0,2242308652.0,2120921632.0,2109325557.0,2107820388.0,2115598549.0,2231449945.0,2364586112.0,2195121290.0],"unit":"ns","throughput":[],"typical":{"estimate":2167220406.6,"lower_bound":2119469869.83,"upper_bound":2223802659.1,"unit":"ns"},"mean":{"estimate":2167220406.6,"lower_bound":2119469869.83,"upper_bound":2223802659.1,"unit":"ns"},"median":{"estimate":2118260090.5,"lower_bound":2106199495.0,"upper_bound":2231449945.0,"unit":"ns"},"median_abs_dev":{"estimate":38138579.63490486,"lower_bound":5750481.198808551,"upper_bound":159881664.15973306,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":0.06077250293716574,"lower_bound":0.03873309073624074,"upper_bound":0.09478597290728896,"unit":"%"},"median":{"estimate":0.04124575062757718,"lower_bound":0.03561100272808071,"upper_bound":0.09947587479350628,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-512","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[110898696.0,222354018.0,338257903.0,449242029.0,559604788.0,667452359.0,774206053.0,889897478.0,1001011821.0,1113060578.0],"unit":"ns","throughput":[],"typical":{"estimate":22258920.00779221,"lower_bound":22213105.32734519,"upper_bound":22318669.238345865,"unit":"ns"},"mean":{"estimate":22293390.13895238,"lower_bound":22221495.94347976,"upper_bound":22375154.74066667,"unit":"ns"},"median":{"estimate":22247924.458333332,"lower_bound":22212223.166666664,"upper_bound":22384191.52,"unit":"ns"},"median_abs_dev":{"estimate":60395.459395765814,"lower_bound":3469.172743408215,"upper_bound":206674.3028967979,"unit":"ns"},"slope":{"estimate":22258920.00779221,"lower_bound":22213105.32734519,"upper_bound":22318669.238345865,"unit":"ns"},"change":{"mean":{"estimate":0.03976083394023333,"lower_bound":0.03520064998182571,"upper_bound":0.04437902449793692,"unit":"%"},"median":{"estimate":0.040219273665329736,"lower_bound":0.0379104508903485,"upper_bound":0.04675918761590906,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-512","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[4406593476.0,4401039029.0,4373862798.0,4366836012.0,4425222184.0,4407452656.0,4400896265.0,4395429662.0,4391688774.0,4372576210.0],"unit":"ns","throughput":[],"typical":{"estimate":4394159706.6,"lower_bound":4383351759.0,"upper_bound":4404840506.8175,"unit":"ns"},"mean":{"estimate":4394159706.6,"lower_bound":4383351759.0,"upper_bound":4404840506.8175,"unit":"ns"},"median":{"estimate":4398162963.5,"lower_bound":4373862798.0,"upper_bound":4406593476.0,"unit":"ns"},"median_abs_dev":{"estimate":13135987.7332896,"lower_bound":4052392.7319556475,"upper_bound":35853944.966465235,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":0.05687428718168519,"lower_bound":0.050675486418654284,"upper_bound":0.06274574788839435,"unit":"%"},"median":{"estimate":0.07129650023742196,"lower_bound":0.06106245448382164,"upper_bound":0.07430148683194204,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-1024","iteration_count":[4,8,12,16,20,24,28,32,36,40],"measured_values":[99461599.0,200011984.0,302432034.0,398331868.0,502743311.0,598062012.0,701238894.0,799902443.0,900409437.0,1008142143.0],"unit":"ns","throughput":[],"typical":{"estimate":25061815.54090909,"lower_bound":24983788.40212766,"upper_bound":25142028.194913294,"unit":"ns"},"mean":{"estimate":25027784.94330357,"lower_bound":24958465.583828125,"upper_bound":25100474.78080357,"unit":"ns"},"median":{"estimate":25006435.625,"lower_bound":24919250.5,"upper_bound":25137165.55,"unit":"ns"},"median_abs_dev":{"estimate":146687.70009577274,"lower_bound":10690.958913322538,"upper_bound":202745.6787755423,"unit":"ns"},"slope":{"estimate":25061815.54090909,"lower_bound":24983788.40212766,"upper_bound":25142028.194913294,"unit":"ns"},"change":{"mean":{"estimate":0.05203485804048302,"lower_bound":0.04852376563081521,"upper_bound":0.05567842763961314,"unit":"%"},"median":{"estimate":0.05537810676811161,"lower_bound":0.05059766232843321,"upper_bound":0.06120066132273627,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-1024","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[8752771182.0,8789092306.0,8726176752.0,8689007626.0,8742704531.0,8920376222.0,8681513979.0,8548095098.0,8559997339.0,8562868796.0],"unit":"ns","throughput":[],"typical":{"estimate":8697260383.1,"lower_bound":8630028328.2925,"upper_bound":8767110848.307499,"unit":"ns"},"mean":{"estimate":8697260383.1,"lower_bound":8630028328.2925,"upper_bound":8767110848.307499,"unit":"ns"},"median":{"estimate":8707592189.0,"lower_bound":8562868796.0,"upper_bound":8765898418.5,"unit":"ns"},"median_abs_dev":{"estimate":93907222.57581353,"lower_bound":13080353.16927731,"upper_bound":230854919.8753059,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":466.1147818414803,"lower_bound":458.6095480773689,"upper_bound":474.04594926708256,"unit":"%"},"median":{"estimate":487.81809119945694,"lower_bound":476.01845082676783,"upper_bound":492.9801366174623,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-2048","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[91015584.0,184951206.0,274138284.0,368502192.0,455288056.0,545841331.0,635193477.0,737749084.0,818270371.0,907272902.0],"unit":"ns","throughput":[],"typical":{"estimate":30384709.30909091,"lower_bound":30278764.500548165,"upper_bound":30570500.546335775,"unit":"ns"},"mean":{"estimate":30454470.34878307,"lower_bound":30334510.52164021,"upper_bound":30589109.795099206,"unit":"ns"},"median":{"estimate":30345532.53333333,"lower_bound":30285913.408730157,"upper_bound":30708516.0,"unit":"ns"},"median_abs_dev":{"estimate":149243.38475039712,"lower_bound":20770.245467921526,"upper_bound":350385.7675594093,"unit":"ns"},"slope":{"estimate":30384709.30909091,"lower_bound":30278764.500548165,"upper_bound":30570500.546335775,"unit":"ns"},"change":{"mean":{"estimate":0.03503127920650995,"lower_bound":0.03030427684613965,"upper_bound":0.04012501616039089,"unit":"%"},"median":{"estimate":0.02810770833590248,"lower_bound":0.02557271864864963,"upper_bound":0.04077346819483196,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-2048","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[17104663992.0,17135751919.0,17051039201.0,17189588335.0,17065251894.0,17003276604.0,17062222172.0,17175087955.0,17112245412.0,17017599496.0],"unit":"ns","throughput":[],"typical":{"estimate":17091672698.0,"lower_bound":17055397613.8,"upper_bound":17129321374.6325,"unit":"ns"},"mean":{"estimate":17091672698.0,"lower_bound":17055397613.8,"upper_bound":17129321374.6325,"unit":"ns"},"median":{"estimate":17084957943.0,"lower_bound":17039910834.0,"upper_bound":17143666683.5,"unit":"ns"},"median_abs_dev":{"estimate":62797536.73852086,"lower_bound":11240213.092446327,"upper_bound":110483191.40033126,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":627.7200685478234,"lower_bound":626.0162424477558,"upper_bound":629.4760218325522,"unit":"%"},"median":{"estimate":626.214908779058,"lower_bound":624.2103816891226,"upper_bound":628.7103746570979,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-4096","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[120689886.0,234840139.0,349236535.0,472068998.0,588428805.0,701254378.0,822305462.0,934502594.0,1050305704.0,1169946729.0],"unit":"ns","throughput":[],"typical":{"estimate":39013336.50735931,"lower_bound":38947814.191005945,"upper_bound":39121131.82369191,"unit":"ns"},"mean":{"estimate":39169373.79283069,"lower_bound":38975057.45414484,"upper_bound":39440537.61202381,"unit":"ns"},"median":{"estimate":39069123.733333334,"lower_bound":38929393.9074074,"upper_bound":39248243.059523806,"unit":"ns"},"median_abs_dev":{"estimate":215702.66709551032,"lower_bound":43266.1933763176,"upper_bound":406358.8658217979,"unit":"ns"},"slope":{"estimate":39013336.50735931,"lower_bound":38947814.191005945,"upper_bound":39121131.82369191,"unit":"ns"},"change":{"mean":{"estimate":0.051429152821222957,"lower_bound":0.04491705041948611,"upper_bound":0.05966072101099902,"unit":"%"},"median":{"estimate":0.05793850800525879,"lower_bound":0.04044382630995469,"upper_bound":0.06427330211893967,"unit":"%"},"change":"Regressed"}} +{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-4096","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[34026936270.0,34203631489.0,34252596002.0,34223222314.0,34137460175.0,34273340516.0,34245565259.0,34196393451.0,34146717148.0,34275059016.0],"unit":"ns","throughput":[],"typical":{"estimate":34198092164.0,"lower_bound":34149405319.0,"upper_bound":34239229000.899998,"unit":"ns"},"mean":{"estimate":34198092164.0,"lower_bound":34149405319.0,"upper_bound":34239229000.899998,"unit":"ns"},"median":{"estimate":34213426901.5,"lower_bound":34146717148.0,"upper_bound":34259452887.5,"unit":"ns"},"median_abs_dev":{"estimate":73450015.32550156,"lower_bound":13724387.926143408,"upper_bound":122328897.58072793,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":845.2180265533412,"lower_bound":842.628432394928,"upper_bound":847.7850161870736,"unit":"%"},"median":{"estimate":844.8264893763486,"lower_bound":841.9511891746489,"upper_bound":852.8107683634241,"unit":"%"},"change":"Regressed"}} +{"reason":"group-complete","group_name":"kzg-elgamal","benchmarks":["kzg-elgamal/proof-gen-1","kzg-elgamal/proof-vfy-1","kzg-elgamal/proof-gen-2","kzg-elgamal/proof-vfy-2","kzg-elgamal/proof-gen-4","kzg-elgamal/proof-vfy-4","kzg-elgamal/proof-gen-8","kzg-elgamal/proof-vfy-8","kzg-elgamal/proof-gen-16","kzg-elgamal/proof-vfy-16","kzg-elgamal/proof-gen-32","kzg-elgamal/proof-vfy-32","kzg-elgamal/proof-gen-64","kzg-elgamal/proof-vfy-64","kzg-elgamal/proof-gen-128","kzg-elgamal/proof-vfy-128","kzg-elgamal/proof-gen-256","kzg-elgamal/proof-vfy-256","kzg-elgamal/proof-gen-512","kzg-elgamal/proof-vfy-512","kzg-elgamal/proof-gen-1024","kzg-elgamal/proof-vfy-1024","kzg-elgamal/proof-gen-2048","kzg-elgamal/proof-vfy-2048","kzg-elgamal/proof-gen-4096","kzg-elgamal/proof-vfy-4096"],"report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal"} diff --git a/benches/kzg-paillier-bench-results b/benches/kzg-paillier-bench-results new file mode 100644 index 0000000..446398e --- /dev/null +++ b/benches/kzg-paillier-bench-results @@ -0,0 +1,40 @@ +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-1","iteration_count":[13,26,39,52,65,78,91,104,117,130],"measured_values":[94550142.0,183475693.0,274283562.0,366588712.0,460051601.0,553055108.0,637717680.0,736738261.0,822001848.0,920318879.0],"unit":"ns","throughput":[],"typical":{"estimate":7058627.569430569,"lower_bound":7032667.32700491,"upper_bound":7080926.276683228,"unit":"ns"},"mean":{"estimate":7077764.822609891,"lower_bound":7043197.3461996345,"upper_bound":7127912.94533631,"unit":"ns"},"median":{"estimate":7067237.180769231,"lower_bound":7032911.846153846,"upper_bound":7084913.047435898,"unit":"ns"},"median_abs_dev":{"estimate":30146.579618637734,"lower_bound":5378.150412211299,"upper_bound":72799.68833831717,"unit":"ns"},"slope":{"estimate":7058627.569430569,"lower_bound":7032667.32700491,"upper_bound":7080926.276683228,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-1","iteration_count":[14,28,42,56,70,84,98,112,126,140],"measured_values":[91945961.0,186908132.0,276631473.0,373377491.0,466809407.0,556480892.0,661370184.0,746311364.0,833147576.0,931112010.0],"unit":"ns","throughput":[],"typical":{"estimate":6655218.827272727,"lower_bound":6627727.007097069,"upper_bound":6691631.338564213,"unit":"ns"},"mean":{"estimate":6646550.83378118,"lower_bound":6616679.704761906,"upper_bound":6677509.120124716,"unit":"ns"},"median":{"estimate":6657147.196428572,"lower_bound":6605618.083333334,"upper_bound":6671372.8125,"unit":"ns"},"median_abs_dev":{"estimate":37448.9221351481,"lower_bound":4790.362587453314,"upper_bound":95066.2753455705,"unit":"ns"},"slope":{"estimate":6655218.827272727,"lower_bound":6627727.007097069,"upper_bound":6691631.338564213,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-1","iteration_count":[20,40,60,80,100,120,140,160,180,200],"measured_values":[96784081.0,190847080.0,282913778.0,379180871.0,481214735.0,575133799.0,663023163.0,754005791.0,848125583.0,943828461.0],"unit":"ns","throughput":[],"typical":{"estimate":4733174.396623377,"lower_bound":4718150.556785714,"upper_bound":4763136.264285714,"unit":"ns"},"mean":{"estimate":4754966.760807539,"lower_bound":4729588.256555555,"upper_bound":4783168.836101191,"unit":"ns"},"median":{"estimate":4737820.311607143,"lower_bound":4715229.633333334,"upper_bound":4792781.658333333,"unit":"ns"},"median_abs_dev":{"estimate":38025.45356512183,"lower_bound":3075.088918948447,"upper_bound":73841.7488171719,"unit":"ns"},"slope":{"estimate":4733174.396623377,"lower_bound":4718150.556785714,"upper_bound":4763136.264285714,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-2","iteration_count":[8,16,24,32,40,48,56,64,72,80],"measured_values":[93708312.0,210936457.0,291099648.0,386362222.0,522382097.0,575365182.0,665864552.0,796938261.0,800412295.0,1011041405.0],"unit":"ns","throughput":[],"typical":{"estimate":12126335.484415585,"lower_bound":11585816.464449365,"upper_bound":12568094.891939253,"unit":"ns"},"mean":{"estimate":12224381.979975197,"lower_bound":11854427.30066518,"upper_bound":12593218.68228125,"unit":"ns"},"median":{"estimate":12101485.71875,"lower_bound":11850156.8125,"upper_bound":12755856.3765625,"unit":"ns"},"median_abs_dev":{"estimate":547539.9808182847,"lower_bound":105544.34621371329,"upper_bound":1127650.8117906125,"unit":"ns"},"slope":{"estimate":12126335.484415585,"lower_bound":11585816.464449365,"upper_bound":12568094.891939253,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-2","iteration_count":[8,16,24,32,40,48,56,64,72,80],"measured_values":[92727546.0,182467148.0,271869823.0,369269862.0,452922411.0,549303705.0,638703256.0,731436932.0,817396911.0,930976568.0],"unit":"ns","throughput":[],"typical":{"estimate":11460889.990584416,"lower_bound":11373854.42124542,"upper_bound":11558241.610545883,"unit":"ns"},"mean":{"estimate":11445367.926488094,"lower_bound":11384302.335059525,"upper_bound":11512073.3825,"unit":"ns"},"median":{"estimate":11417058.674107142,"lower_bound":11352734.875,"upper_bound":11539683.1875,"unit":"ns"},"median_abs_dev":{"estimate":113769.66746143352,"lower_bound":18165.787833742797,"upper_bound":176434.2616489157,"unit":"ns"},"slope":{"estimate":11460889.990584416,"lower_bound":11373854.42124542,"upper_bound":11558241.610545883,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-2","iteration_count":[13,26,39,52,65,78,91,104,117,130],"measured_values":[92955870.0,182359119.0,276006131.0,364434699.0,454127900.0,545950865.0,643532764.0,737765275.0,823416002.0,923534552.0],"unit":"ns","throughput":[],"typical":{"estimate":7061481.932667333,"lower_bound":7023672.289219741,"upper_bound":7087374.611965812,"unit":"ns"},"mean":{"estimate":7054319.786260685,"lower_bound":7023717.891923077,"upper_bound":7086482.4618376065,"unit":"ns"},"median":{"estimate":7054766.111111111,"lower_bound":7006591.166666666,"upper_bound":7093896.875,"unit":"ns"},"median_abs_dev":{"estimate":64760.231373994124,"lower_bound":12466.140131566422,"upper_bound":96314.08269104415,"unit":"ns"},"slope":{"estimate":7061481.932667333,"lower_bound":7023672.289219741,"upper_bound":7087374.611965812,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-4","iteration_count":[6,12,18,24,30,36,42,48,54,60],"measured_values":[93523343.0,164284446.0,287889300.0,363919213.0,473390884.0,577544185.0,648601181.0,814750615.0,769499114.0,880304790.0],"unit":"ns","throughput":[],"typical":{"estimate":15307536.636363637,"lower_bound":14666784.22792414,"upper_bound":16249442.357174685,"unit":"ns"},"mean":{"estimate":15359592.153644178,"lower_bound":14791995.535057541,"upper_bound":15911056.175593255,"unit":"ns"},"median":{"estimate":15515054.547619049,"lower_bound":14671746.5,"upper_bound":15993850.0,"unit":"ns"},"median_abs_dev":{"estimate":746218.4622436395,"lower_bound":207256.14943296774,"upper_bound":1705621.0403702832,"unit":"ns"},"slope":{"estimate":15307536.636363637,"lower_bound":14666784.22792414,"upper_bound":16249442.357174685,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-4","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[103640549.0,208760361.0,306971507.0,413359092.0,523254115.0,627856164.0,737920455.0,826953624.0,934193093.0,1039693113.0],"unit":"ns","throughput":[],"typical":{"estimate":20812810.837922078,"lower_bound":20728217.60896597,"upper_bound":20923861.04461482,"unit":"ns"},"mean":{"estimate":20790656.197587304,"lower_bound":20686979.614916664,"upper_bound":20891089.394911114,"unit":"ns"},"median":{"estimate":20776854.385555558,"lower_bound":20673840.6,"upper_bound":20928538.8,"unit":"ns"},"median_abs_dev":{"estimate":157091.52747573584,"lower_bound":40125.45633763075,"upper_bound":304873.6795774117,"unit":"ns"},"slope":{"estimate":20812810.837922078,"lower_bound":20728217.60896597,"upper_bound":20923861.04461482,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-4","iteration_count":[8,16,24,32,40,48,56,64,72,80],"measured_values":[93588556.0,186354718.0,278326058.0,368743295.0,462600814.0,554863601.0,647753787.0,733103448.0,836317887.0,923326341.0],"unit":"ns","throughput":[],"typical":{"estimate":11551189.45064935,"lower_bound":11506935.700737266,"upper_bound":11592088.28002451,"unit":"ns"},"mean":{"estimate":11576944.388779763,"lower_bound":11537226.75212128,"upper_bound":11616761.241796875,"unit":"ns"},"median":{"estimate":11566026.130357143,"lower_bound":11541443.161458332,"upper_bound":11622044.479166668,"unit":"ns"},"median_abs_dev":{"estimate":54627.2222707984,"lower_bound":6957.187302735577,"upper_bound":118812.5437406561,"unit":"ns"},"slope":{"estimate":11551189.45064935,"lower_bound":11506935.700737266,"upper_bound":11592088.28002451,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-8","iteration_count":[7,14,21,28,35,42,49,56,63,70],"measured_values":[98709478.0,197824942.0,297808020.0,396084710.0,496271723.0,595764131.0,695699986.0,807222434.0,899514410.0,996099919.0],"unit":"ns","throughput":[],"typical":{"estimate":14253199.969202226,"lower_bound":14188342.627935417,"upper_bound":14318081.461942257,"unit":"ns"},"mean":{"estimate":14204362.670351472,"lower_bound":14158049.867414966,"upper_bound":14261893.919671202,"unit":"ns"},"median":{"estimate":14183097.273809522,"lower_bound":14145882.5,"upper_bound":14237982.702947846,"unit":"ns"},"median_abs_dev":{"estimate":62355.44385296962,"lower_bound":5227.612207190674,"upper_bound":123806.3817019963,"unit":"ns"},"slope":{"estimate":14253199.969202226,"lower_bound":14188342.627935417,"upper_bound":14318081.461942257,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-8","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[117561527.0,236226288.0,362070802.0,480182023.0,597001495.0,701946945.0,835853318.0,950397594.0,1067371151.0,1191926707.0],"unit":"ns","throughput":[],"typical":{"estimate":39630653.81212121,"lower_bound":39451751.275641024,"upper_bound":39781656.94599423,"unit":"ns"},"mean":{"estimate":39626622.731534384,"lower_bound":39404958.65870371,"upper_bound":39844332.874365084,"unit":"ns"},"median":{"estimate":39665394.99166667,"lower_bound":39359720.259259254,"upper_bound":39907634.125,"unit":"ns"},"median_abs_dev":{"estimate":319864.23732127674,"lower_bound":54921.43695494937,"upper_bound":636807.1643610802,"unit":"ns"},"slope":{"estimate":39630653.81212121,"lower_bound":39451751.275641024,"upper_bound":39781656.94599423,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-8","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[105049064.0,205221292.0,310713923.0,415484598.0,527950248.0,621056441.0,734439208.0,841758205.0,938469524.0,1032034813.0],"unit":"ns","throughput":[],"typical":{"estimate":20840195.136103895,"lower_bound":20713556.523625094,"upper_bound":20979117.875303645,"unit":"ns"},"mean":{"estimate":20836383.17875397,"lower_bound":20721249.813166667,"upper_bound":20951324.358311906,"unit":"ns"},"median":{"estimate":20814554.105555557,"lower_bound":20677478.89666667,"upper_bound":21013966.248214286,"unit":"ns"},"median_abs_dev":{"estimate":254474.2833841773,"lower_bound":44461.507933150286,"upper_bound":329309.9417635839,"unit":"ns"},"slope":{"estimate":20840195.136103895,"lower_bound":20713556.523625094,"upper_bound":20979117.875303645,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-16","iteration_count":[4,8,12,16,20,24,28,32,36,40],"measured_values":[94411850.0,190230275.0,280905930.0,375671797.0,471413744.0,568885194.0,662176522.0,757439709.0,847734717.0,942479759.0],"unit":"ns","throughput":[],"typical":{"estimate":23597286.124025974,"lower_bound":23554624.64893617,"upper_bound":23649539.048780486,"unit":"ns"},"mean":{"estimate":23597363.160208333,"lower_bound":23533916.924583334,"upper_bound":23660575.43125,"unit":"ns"},"median":{"estimate":23586824.85,"lower_bound":23520740.64375,"upper_bound":23676355.625,"unit":"ns"},"median_abs_dev":{"estimate":107861.15422820451,"lower_bound":20470.838521574016,"upper_bound":183064.30973745883,"unit":"ns"},"slope":{"estimate":23597286.124025974,"lower_bound":23554624.64893617,"upper_bound":23649539.048780486,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-16","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[154178993.0,308666745.0,462887663.0,619902942.0,768945423.0,923309590.0,1074192011.0,1232581924.0,1381752483.0,1548499322.0],"unit":"ns","throughput":[],"typical":{"estimate":77045632.37792207,"lower_bound":76828586.86052895,"upper_bound":77277671.63695653,"unit":"ns"},"mean":{"estimate":77068236.64357144,"lower_bound":76923972.39214286,"upper_bound":77220422.45775001,"unit":"ns"},"median":{"estimate":77062933.375,"lower_bound":76853246.33333333,"upper_bound":77286454.96666667,"unit":"ns"},"median_abs_dev":{"estimate":214130.88873342267,"lower_bound":57220.76065912843,"upper_bound":479528.9478966505,"unit":"ns"},"slope":{"estimate":77045632.37792207,"lower_bound":76828586.86052895,"upper_bound":77277671.63695653,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-16","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[120293203.0,235614745.0,351143054.0,473422744.0,592718579.0,699723911.0,818862485.0,939176813.0,1054900115.0,1165176323.0],"unit":"ns","throughput":[],"typical":{"estimate":39040602.03982684,"lower_bound":38925716.17481977,"upper_bound":39208571.143989325,"unit":"ns"},"mean":{"estimate":39225817.55379629,"lower_bound":39025682.35782408,"upper_bound":39467554.860740736,"unit":"ns"},"median":{"estimate":39101370.91898148,"lower_bound":38944722.75,"upper_bound":39451895.333333336,"unit":"ns"},"median_abs_dev":{"estimate":293238.67152730376,"lower_bound":57022.99143208377,"upper_bound":574025.3071056784,"unit":"ns"},"slope":{"estimate":39040602.03982684,"lower_bound":38925716.17481977,"upper_bound":39208571.143989325,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-32","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[130403659.0,260874073.0,390905156.0,519535896.0,651618486.0,784468874.0,913001769.0,1048361323.0,1174983284.0,1302708483.0],"unit":"ns","throughput":[],"typical":{"estimate":43504548.81731602,"lower_bound":43434460.38114553,"upper_bound":43586744.89298626,"unit":"ns"},"mean":{"estimate":43479781.12466931,"lower_bound":43420548.38222222,"upper_bound":43540900.20156945,"unit":"ns"},"median":{"estimate":43472080.52380952,"lower_bound":43432424.25,"upper_bound":43530308.13888889,"unit":"ns"},"median_abs_dev":{"estimate":62264.14707236922,"lower_bound":8247.580103578024,"upper_bound":167449.9912971652,"unit":"ns"},"slope":{"estimate":43504548.81731602,"lower_bound":43434460.38114553,"upper_bound":43586744.89298626,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-32","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[150952073.0,307645170.0,453674262.0,606527379.0,772317056.0,916429214.0,1058036332.0,1216677509.0,1381049203.0,1527609066.0],"unit":"ns","throughput":[],"typical":{"estimate":152620112.1090909,"lower_bound":151923265.11186868,"upper_bound":153206561.26889133,"unit":"ns"},"mean":{"estimate":152427642.43813494,"lower_bound":151728939.09139884,"upper_bound":153160089.1699524,"unit":"ns"},"median":{"estimate":152411445.4791667,"lower_bound":151224754.0,"upper_bound":153449911.44444445,"unit":"ns"},"median_abs_dev":{"estimate":1649509.1842820272,"lower_bound":259001.0021018099,"upper_bound":2030204.6656099681,"unit":"ns"},"slope":{"estimate":152620112.1090909,"lower_bound":151923265.11186868,"upper_bound":153206561.26889133,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-32","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[151507953.0,303858996.0,456775045.0,610809548.0,764747408.0,914737106.0,1054713389.0,1222430399.0,1378862564.0,1531482401.0],"unit":"ns","throughput":[],"typical":{"estimate":76327237.59610389,"lower_bound":75920897.02686568,"upper_bound":76533307.20707071,"unit":"ns"},"mean":{"estimate":76181809.25414683,"lower_bound":75931429.92494048,"upper_bound":76397436.76041667,"unit":"ns"},"median":{"estimate":76289642.83333334,"lower_bound":75941575.33333334,"upper_bound":76488009.99375,"unit":"ns"},"median_abs_dev":{"estimate":348096.0772250401,"lower_bound":91585.61186402815,"upper_bound":629733.8034366556,"unit":"ns"},"slope":{"estimate":76327237.59610389,"lower_bound":75920897.02686568,"upper_bound":76533307.20707071,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-64","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[168806628.0,338890650.0,501809629.0,664686945.0,835408435.0,1006783334.0,1168182048.0,1338833620.0,1503877557.0,1662608049.0],"unit":"ns","throughput":[],"typical":{"estimate":83477179.96493506,"lower_bound":83284824.52349271,"upper_bound":83696184.56831396,"unit":"ns"},"mean":{"estimate":83708406.91821429,"lower_bound":83425611.60809524,"upper_bound":84029288.66666666,"unit":"ns"},"median":{"estimate":83591845.66666667,"lower_bound":83335622.975,"upper_bound":84040207.625,"unit":"ns"},"median_abs_dev":{"estimate":338801.0102350881,"lower_bound":69752.37516165148,"upper_bound":876562.2155629098,"unit":"ns"},"slope":{"estimate":83477179.96493506,"lower_bound":83284824.52349271,"upper_bound":83696184.56831396,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-64","iteration_count":[2,2,2,2,2,2,2,2,2,2],"measured_values":[612105706.0,626676936.0,608542034.0,602009940.0,617771807.0,612786267.0,609024678.0,601612215.0,612471300.0,614749322.0],"unit":"ns","throughput":[],"typical":{"estimate":305887510.25,"lower_bound":303810546.25,"upper_bound":308103617.6475,"unit":"ns"},"mean":{"estimate":305887510.25,"lower_bound":303810546.25,"upper_bound":308103617.6475,"unit":"ns"},"median":{"estimate":306144251.5,"lower_bound":302758654.5,"upper_bound":307639518.5,"unit":"ns"},"median_abs_dev":{"estimate":2598365.4249697924,"lower_bound":252249.93017166853,"upper_bound":6342008.195006847,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-64","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[150758542.0,302107685.0,447600335.0,603676588.0,746972700.0,909126251.0,1044455157.0,1182488239.0,1352890782.0,1498245882.0],"unit":"ns","throughput":[],"typical":{"estimate":149692649.72467533,"lower_bound":148836523.7967685,"upper_bound":150463749.93353277,"unit":"ns"},"mean":{"estimate":150001192.06464285,"lower_bound":149319375.53695536,"upper_bound":150634109.84047619,"unit":"ns"},"median":{"estimate":150072893.1,"lower_bound":149207879.57142857,"upper_bound":150919147.0,"unit":"ns"},"median_abs_dev":{"estimate":1268562.5222785163,"lower_bound":149888.06863894433,"upper_bound":2066572.254454489,"unit":"ns"},"slope":{"estimate":149692649.72467533,"lower_bound":148836523.7967685,"upper_bound":150463749.93353277,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-128","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[162776220.0,326515042.0,491134575.0,649703767.0,821321022.0,978653863.0,1144641573.0,1305240235.0,1473361929.0,1629099119.0],"unit":"ns","throughput":[],"typical":{"estimate":163304454.0961039,"lower_bound":163019450.76753506,"upper_bound":163639802.8038741,"unit":"ns"},"mean":{"estimate":163283643.63059524,"lower_bound":162974376.05545834,"upper_bound":163602504.27,"unit":"ns"},"median":{"estimate":163206275.1875,"lower_bound":162909911.9,"upper_bound":163706881.0,"unit":"ns"},"median_abs_dev":{"estimate":551530.6849083635,"lower_bound":110115.54169506571,"upper_bound":899239.7126427861,"unit":"ns"},"slope":{"estimate":163304454.0961039,"lower_bound":163019450.76753506,"upper_bound":163639802.8038741,"unit":"ns"},"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-128","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[607722114.0,605040401.0,604948445.0,596579281.0,596400258.0,596387488.0,596003251.0,594836787.0,606028487.0,605256556.0],"unit":"ns","throughput":[],"typical":{"estimate":600920306.8,"lower_bound":597884979.0,"upper_bound":603960622.4425,"unit":"ns"},"mean":{"estimate":600920306.8,"lower_bound":597884979.0,"upper_bound":603960622.4425,"unit":"ns"},"median":{"estimate":600763863.0,"lower_bound":596201754.5,"upper_bound":605534444.0,"unit":"ns"},"median_abs_dev":{"estimate":6574639.991676807,"lower_bound":142176.1483758688,"upper_bound":7431707.314860821,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-128","iteration_count":[2,2,2,2,2,2,2,2,2,2],"measured_values":[596381584.0,593586729.0,598660773.0,595152856.0,595571221.0,598956829.0,591170285.0,594358062.0,593887891.0,595182897.0],"unit":"ns","throughput":[],"typical":{"estimate":297645456.35,"lower_bound":296964763.94,"upper_bound":298332826.51625,"unit":"ns"},"mean":{"estimate":297645456.35,"lower_bound":296964763.94,"upper_bound":298332826.51625,"unit":"ns"},"median":{"estimate":297583938.25,"lower_bound":296943945.5,"upper_bound":298557998.5,"unit":"ns"},"median_abs_dev":{"estimate":924287.2940406203,"lower_bound":166201.68094933033,"upper_bound":1990427.5296628475,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-256","iteration_count":[2,2,2,2,2,2,2,2,2,2],"measured_values":[639591121.0,663216111.0,651553076.0,643330341.0,642844521.0,647454899.0,645860660.0,639401079.0,642784874.0,650051502.0],"unit":"ns","throughput":[],"typical":{"estimate":323304409.2,"lower_bound":321438159.605,"upper_bound":325576233.95,"unit":"ns"},"mean":{"estimate":323304409.2,"lower_bound":321438159.605,"upper_bound":325576233.95,"unit":"ns"},"median":{"estimate":322297750.25,"lower_bound":320608910.5,"upper_bound":325025751.0,"unit":"ns"},"median_abs_dev":{"estimate":2914709.2639535666,"lower_bound":202177.3399606347,"upper_bound":5162465.740647912,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-256","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[1212700080.0,1243541117.0,1206615628.0,1204600073.0,1197866904.0,1197431758.0,1196586209.0,1215584140.0,1219619151.0,1211818119.0],"unit":"ns","throughput":[],"typical":{"estimate":1210636317.9,"lower_bound":1203201838.7,"upper_bound":1219621801.5800002,"unit":"ns"},"mean":{"estimate":1210636317.9,"lower_bound":1203201838.7,"upper_bound":1219621801.5800002,"unit":"ns"},"median":{"estimate":1209216873.5,"lower_bound":1197866904.0,"upper_bound":1216159615.5,"unit":"ns"},"median_abs_dev":{"estimate":12431262.746500969,"lower_bound":1271952.9107183218,"upper_bound":21633450.178429484,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-256","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[599376124.0,600483347.0,604121471.0,599024879.0,598774021.0,598931644.0,595208110.0,598748310.0,600916583.0,601486243.0],"unit":"ns","throughput":[],"typical":{"estimate":599707073.2,"lower_bound":598350671.2,"upper_bound":601062177.2049999,"unit":"ns"},"mean":{"estimate":599707073.2,"lower_bound":598350671.2,"upper_bound":601062177.2049999,"unit":"ns"},"median":{"estimate":599200501.5,"lower_bound":598774021.0,"upper_bound":600984795.0,"unit":"ns"},"median_abs_dev":{"estimate":1286182.905265689,"lower_bound":138230.20854592323,"upper_bound":3906988.9634370804,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-512","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[650804536.0,647081807.0,646055399.0,654158329.0,643665257.0,641061376.0,643051553.0,640431503.0,642698922.0,637269476.0],"unit":"ns","throughput":[],"typical":{"estimate":644627815.8,"lower_bound":641814494.3,"upper_bound":647714129.1949999,"unit":"ns"},"mean":{"estimate":644627815.8,"lower_bound":641814494.3,"upper_bound":647714129.1949999,"unit":"ns"},"median":{"estimate":643358405.0,"lower_bound":641061376.0,"upper_bound":648429967.5,"unit":"ns"},"median_abs_dev":{"estimate":4168994.0307855606,"lower_bound":716344.1227823496,"upper_bound":8311101.852348447,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-512","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[2426341374.0,2438863070.0,2418226168.0,2406024588.0,2395476385.0,2431919135.0,2402838685.0,2444429827.0,2447874465.0,2409758289.0],"unit":"ns","throughput":[],"typical":{"estimate":2422175198.6,"lower_bound":2411297141.1549997,"upper_bound":2432971724.1,"unit":"ns"},"mean":{"estimate":2422175198.6,"lower_bound":2411297141.1549997,"upper_bound":2432971724.1,"unit":"ns"},"median":{"estimate":2422283771.0,"lower_bound":2406024588.0,"upper_bound":2438863070.0,"unit":"ns"},"median_abs_dev":{"estimate":24343166.274422407,"lower_bound":5129502.354133129,"upper_bound":30699598.684573174,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-512","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[1165410798.0,1174149812.0,1201501653.0,1205492308.0,1192786380.0,1180861952.0,1183275226.0,1187712553.0,1187199141.0,1227589590.0],"unit":"ns","throughput":[],"typical":{"estimate":1190597941.3,"lower_bound":1180957121.3,"upper_bound":1201486718.2,"unit":"ns"},"mean":{"estimate":1190597941.3,"lower_bound":1180957121.3,"upper_bound":1201486718.2,"unit":"ns"},"median":{"estimate":1187455847.0,"lower_bound":1178712519.0,"upper_bound":1201501653.0,"unit":"ns"},"median_abs_dev":{"estimate":14751817.84710288,"lower_bound":3289390.446701646,"upper_bound":29115497.692796588,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-1024","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[1291465710.0,1289168419.0,1281643239.0,1282933229.0,1272561694.0,1284982299.0,1287630900.0,1285509711.0,1288563244.0,1280167273.0],"unit":"ns","throughput":[],"typical":{"estimate":1284462571.8,"lower_bound":1281042347.1175,"upper_bound":1287430211.265,"unit":"ns"},"mean":{"estimate":1284462571.8,"lower_bound":1281042347.1175,"upper_bound":1287430211.265,"unit":"ns"},"median":{"estimate":1285246005.0,"lower_bound":1281550251.0,"upper_bound":1288563244.0,"unit":"ns"},"median_abs_dev":{"estimate":5129799.615427852,"lower_bound":1139762.8144651651,"upper_bound":8699178.325858712,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-1024","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[4891309834.0,4867136450.0,4873120110.0,4853740567.0,4922521625.0,4936533393.0,4889500907.0,4812336791.0,4948796109.0,4860723249.0],"unit":"ns","throughput":[],"typical":{"estimate":4885571903.5,"lower_bound":4861088381.0,"upper_bound":4909926122.37,"unit":"ns"},"mean":{"estimate":4885571903.5,"lower_bound":4861088381.0,"upper_bound":4909926122.37,"unit":"ns"},"median":{"estimate":4881310508.5,"lower_bound":4860438508.5,"upper_bound":4922521625.0,"unit":"ns"},"median_abs_dev":{"estimate":35698932.46751726,"lower_bound":9189792.896148562,"upper_bound":76491867.1740979,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-1024","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[2387803177.0,2351740587.0,2373088274.0,2407169599.0,2403047929.0,2371174802.0,2387655954.0,2396911773.0,2370518613.0,2382000316.0],"unit":"ns","throughput":[],"typical":{"estimate":2383111102.4,"lower_bound":2372974110.0,"upper_bound":2392932717.8,"unit":"ns"},"mean":{"estimate":2383111102.4,"lower_bound":2372974110.0,"upper_bound":2392932717.8,"unit":"ns"},"median":{"estimate":2384828135.0,"lower_bound":2371174802.0,"upper_bound":2396911773.0,"unit":"ns"},"median_abs_dev":{"estimate":19078816.263583302,"lower_bound":2391322.562545538,"upper_bound":28821793.155410886,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-2048","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[2592663292.0,2604250654.0,2537895380.0,2554504984.0,2575385290.0,2537529466.0,2565608641.0,2542482533.0,2543736585.0,2569373879.0],"unit":"ns","throughput":[],"typical":{"estimate":2562343070.4,"lower_bound":2549216407.1125,"upper_bound":2576658647.1525,"unit":"ns"},"mean":{"estimate":2562343070.4,"lower_bound":2549216407.1125,"upper_bound":2576658647.1525,"unit":"ns"},"median":{"estimate":2560056812.5,"lower_bound":2540815982.5,"upper_bound":2581018585.5,"unit":"ns"},"median_abs_dev":{"estimate":25125997.593024373,"lower_bound":3942960.545298457,"upper_bound":40599452.444815636,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-2048","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[9793874282.0,9812736156.0,9774774984.0,9806655940.0,9814785847.0,9760039098.0,9782145302.0,9953902298.0,9952670090.0,9743042634.0],"unit":"ns","throughput":[],"typical":{"estimate":9819462663.1,"lower_bound":9780195676.0,"upper_bound":9866739850.905,"unit":"ns"},"mean":{"estimate":9819462663.1,"lower_bound":9780195676.0,"upper_bound":9866739850.905,"unit":"ns"},"median":{"estimate":9800265111.0,"lower_bound":9771092200.0,"upper_bound":9882703123.0,"unit":"ns"},"median_abs_dev":{"estimate":32328044.982862473,"lower_bound":6026699.952104688,"upper_bound":104040459.06961262,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-2048","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[4743695773.0,4787874011.0,4769218668.0,4784923539.0,4775180771.0,4775166640.0,4774730516.0,4808915913.0,4775687578.0,4718787459.0],"unit":"ns","throughput":[],"typical":{"estimate":4771418086.8,"lower_bound":4756136408.9,"upper_bound":4784920327.7625,"unit":"ns"},"mean":{"estimate":4771418086.8,"lower_bound":4756136408.9,"upper_bound":4784920327.7625,"unit":"ns"},"median":{"estimate":4775173705.5,"lower_bound":4759213144.5,"upper_bound":4784923539.0,"unit":"ns"},"median_abs_dev":{"estimate":11642020.665612817,"lower_bound":344249.3356883526,"upper_bound":42169301.20304525,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-4096","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[5203851628.0,5146312789.0,5074780371.0,5118172672.0,5068301005.0,5134719973.0,5076463895.0,5118995165.0,5140392773.0,5147073455.0],"unit":"ns","throughput":[],"typical":{"estimate":5122906372.6,"lower_bound":5098935651.8275,"upper_bound":5147767270.925,"unit":"ns"},"mean":{"estimate":5122906372.6,"lower_bound":5098935651.8275,"upper_bound":5147767270.925,"unit":"ns"},"median":{"estimate":5126857569.0,"lower_bound":5076463895.0,"upper_bound":5146312789.0,"unit":"ns"},"median_abs_dev":{"estimate":29408190.355700254,"lower_bound":4803153.930526972,"upper_bound":84743199.49110746,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-4096","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[19475873521.0,19503423382.0,19433330958.0,19536076166.0,19457283593.0,19442172434.0,19552693909.0,19526049470.0,19385589840.0,19641292718.0],"unit":"ns","throughput":[],"typical":{"estimate":19495378599.1,"lower_bound":19454539715.89,"upper_bound":19539592549.7875,"unit":"ns"},"mean":{"estimate":19495378599.1,"lower_bound":19454539715.89,"upper_bound":19539592549.7875,"unit":"ns"},"median":{"estimate":19489648451.5,"lower_bound":19442172434.0,"upper_bound":19539371689.5,"unit":"ns"},"median_abs_dev":{"estimate":69610835.29576063,"lower_bound":17756088.010266423,"upper_bound":124356091.36583805,"unit":"ns"},"slope":null,"change":null} +{"reason":"benchmark-complete","id":"kzg-paillier/decryption-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-4096","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[9619629203.0,9607744638.0,9630371825.0,9524445462.0,9551266834.0,9509064337.0,9546800686.0,9578859154.0,9548193833.0,9536202746.0],"unit":"ns","throughput":[],"typical":{"estimate":9565257871.8,"lower_bound":9541682552.4,"upper_bound":9590305961.7325,"unit":"ns"},"mean":{"estimate":9565257871.8,"lower_bound":9541682552.4,"upper_bound":9590305961.7325,"unit":"ns"},"median":{"estimate":9549730333.5,"lower_bound":9535623074.0,"upper_bound":9607744638.0,"unit":"ns"},"median_abs_dev":{"estimate":40336869.16347742,"lower_bound":4343495.306387544,"upper_bound":68882049.93529916,"unit":"ns"},"slope":null,"change":null} +{"reason":"group-complete","group_name":"kzg-paillier","benchmarks":["kzg-paillier/proof-gen-1","kzg-paillier/proof-vfy-1","kzg-paillier/decryption-1","kzg-paillier/proof-gen-2","kzg-paillier/proof-vfy-2","kzg-paillier/decryption-2","kzg-paillier/proof-gen-4","kzg-paillier/proof-vfy-4","kzg-paillier/decryption-4","kzg-paillier/proof-gen-8","kzg-paillier/proof-vfy-8","kzg-paillier/decryption-8","kzg-paillier/proof-gen-16","kzg-paillier/proof-vfy-16","kzg-paillier/decryption-16","kzg-paillier/proof-gen-32","kzg-paillier/proof-vfy-32","kzg-paillier/decryption-32","kzg-paillier/proof-gen-64","kzg-paillier/proof-vfy-64","kzg-paillier/decryption-64","kzg-paillier/proof-gen-128","kzg-paillier/proof-vfy-128","kzg-paillier/decryption-128","kzg-paillier/proof-gen-256","kzg-paillier/proof-vfy-256","kzg-paillier/decryption-256","kzg-paillier/proof-gen-512","kzg-paillier/proof-vfy-512","kzg-paillier/decryption-512","kzg-paillier/proof-gen-1024","kzg-paillier/proof-vfy-1024","kzg-paillier/decryption-1024","kzg-paillier/proof-gen-2048","kzg-paillier/proof-vfy-2048","kzg-paillier/decryption-2048","kzg-paillier/proof-gen-4096","kzg-paillier/proof-vfy-4096","kzg-paillier/decryption-4096"],"report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier"} diff --git a/benches/kzg_elgamal.rs b/benches/kzg_elgamal.rs index eecd86b..5b3b3a3 100644 --- a/benches/kzg_elgamal.rs +++ b/benches/kzg_elgamal.rs @@ -19,6 +19,7 @@ type EncryptionProof = fde::veck::kzg::elgamal::EncryptionProof<{ N }, TestCurve fn bench_proof(c: &mut Criterion) { let mut group = c.benchmark_group("kzg-elgamal"); + group.sample_size(10); let data_size = 1 << DATA_LOG_SIZE; assert_eq!(data_size, 4096); diff --git a/benches/kzg_paillier.rs b/benches/kzg_paillier.rs index 24f3bad..b79fbde 100644 --- a/benches/kzg_paillier.rs +++ b/benches/kzg_paillier.rs @@ -17,6 +17,7 @@ type PaillierEncryptionProof = fde::veck::kzg::paillier::Proof RangeProof { pub fn new( z: C::ScalarField, n: usize, + //maybe_randomness: Option, powers: &Powers, rng: &mut R, ) -> Result { @@ -96,6 +97,11 @@ impl RangeProof { hasher.update(&f_commitment); hasher.update(&g_commitment); + // TODO + //if let Some(rand) = maybe_randomness { + // hasher.update(C::G1::generator() * z + randomness); + //} + let tau = hasher.next_scalar(b"tau"); let rho = hasher.next_scalar(b"rho"); let aggregation_challenge = hasher.next_scalar(b"aggregation_challenge"); From 991f219aedf7e57d488b8752b818a30da43672f4 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 23 Jan 2024 17:11:08 +0100 Subject: [PATCH 15/18] Elgamal numbers. --- benches/elgamal-plot.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 benches/elgamal-plot.txt diff --git a/benches/elgamal-plot.txt b/benches/elgamal-plot.txt new file mode 100644 index 0000000..c7b58cc --- /dev/null +++ b/benches/elgamal-plot.txt @@ -0,0 +1,5 @@ +KZG-ELGAMAL - all units are [ms] +gen 154.86,87.448,50.783,34.127,25.760,21.619,19.509,19.157,20.204,22.213,24.984,30.279,38.948 +vfy 27.796,31.336,43.210,77.583,136.80,264.56,511.48,1014.4,2119.5,4383.4,8630.0,17055.0,34149.0 + +range proofs + encryptions are pre-computed in 89 seconds From 79bab512b3c3a736027d865405fc1e98f4ad70fb Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 29 Jan 2024 19:59:40 +0100 Subject: [PATCH 16/18] Linked remaining TODOs to open issues. --- benches/kzg_paillier.rs | 3 ++- src/range_proof/mod.rs | 6 ------ src/veck/kzg/elgamal/encryption.rs | 5 +++-- src/veck/mod.rs | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/benches/kzg_paillier.rs b/benches/kzg_paillier.rs index b79fbde..fabf794 100644 --- a/benches/kzg_paillier.rs +++ b/benches/kzg_paillier.rs @@ -20,6 +20,7 @@ fn bench_proof(c: &mut Criterion) { group.sample_size(10); // TODO until subset openings don't work, use full open + // https://github.com/PopcornPaws/fde/issues/9 //let data_size = 1 << 12; //let data: Vec = (0..data_size).map(|_| Scalar::rand(rng)).collect(); //let domain = GeneralEvaluationDomain::new(DATA_SIZE).unwrap(); @@ -29,7 +30,7 @@ fn bench_proof(c: &mut Criterion) { let server = Server::new(rng); for i in 0..=12 { - // TODO remove this once subset proofs work + // TODO remove this once subset proofs work https://github.com/PopcornPaws/fde/issues/9 let data_size = 1 << i; let subset_size = 1 << i; let proof_gen_name = format!("proof-gen-{}", subset_size); diff --git a/src/range_proof/mod.rs b/src/range_proof/mod.rs index b1b0749..a266de7 100644 --- a/src/range_proof/mod.rs +++ b/src/range_proof/mod.rs @@ -69,7 +69,6 @@ impl RangeProof { pub fn new( z: C::ScalarField, n: usize, - //maybe_randomness: Option, powers: &Powers, rng: &mut R, ) -> Result { @@ -97,11 +96,6 @@ impl RangeProof { hasher.update(&f_commitment); hasher.update(&g_commitment); - // TODO - //if let Some(rand) = maybe_randomness { - // hasher.update(C::G1::generator() * z + randomness); - //} - let tau = hasher.next_scalar(b"tau"); let rho = hasher.next_scalar(b"rho"); let aggregation_challenge = hasher.next_scalar(b"aggregation_challenge"); diff --git a/src/veck/kzg/elgamal/encryption.rs b/src/veck/kzg/elgamal/encryption.rs index 8cb5cbb..b82707c 100644 --- a/src/veck/kzg/elgamal/encryption.rs +++ b/src/veck/kzg/elgamal/encryption.rs @@ -54,13 +54,13 @@ impl EncryptionProo let proof = evaluations .par_iter() .fold( - || Self::default(), + Self::default, |acc, eval| { let rng = &mut ark_std::rand::thread_rng(); acc.append(eval, encryption_pk, powers, rng) }, ) - .reduce(|| Self::default(), |acc, proof| acc.extend(proof)); + .reduce(Self::default, |acc, proof| acc.extend(proof)); proof } @@ -149,6 +149,7 @@ impl EncryptionProo } // TODO range proofs and short ciphers are not "connected" by anything? + // https://github.com/PopcornPaws/fde/issues/13 pub fn verify_range_proofs(&self, powers: &Powers) -> bool { #[cfg(feature = "parallel")] let result = self diff --git a/src/veck/mod.rs b/src/veck/mod.rs index 18e5097..279454a 100644 --- a/src/veck/mod.rs +++ b/src/veck/mod.rs @@ -36,7 +36,7 @@ pub fn subset_evals( } /* -// TODO some paillier subset toy examples +// TODO some paillier subset toy examples https://github.com/PopcornPaws/fde/issues/9 use crate::commit::kzg::Powers; use ark_ec::pairing::Pairing; use ark_ec::Group; From 4a0b830eaad0770f20d533e82aec311b478e90be Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 29 Jan 2024 20:05:44 +0100 Subject: [PATCH 17/18] Fmt --- src/veck/kzg/elgamal/encryption.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/veck/kzg/elgamal/encryption.rs b/src/veck/kzg/elgamal/encryption.rs index b82707c..1bff574 100644 --- a/src/veck/kzg/elgamal/encryption.rs +++ b/src/veck/kzg/elgamal/encryption.rs @@ -53,13 +53,10 @@ impl EncryptionProo #[cfg(feature = "parallel")] let proof = evaluations .par_iter() - .fold( - Self::default, - |acc, eval| { - let rng = &mut ark_std::rand::thread_rng(); - acc.append(eval, encryption_pk, powers, rng) - }, - ) + .fold(Self::default, |acc, eval| { + let rng = &mut ark_std::rand::thread_rng(); + acc.append(eval, encryption_pk, powers, rng) + }) .reduce(Self::default, |acc, proof| acc.extend(proof)); proof } From 37b9986004e07296bd2a73b3bcf8af5d01fe3c56 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 29 Jan 2024 20:08:45 +0100 Subject: [PATCH 18/18] Deleted unnecessary files. --- benches/kzg-elgamal-bench-results | 27 -------------------- benches/kzg-paillier-bench-results | 40 ------------------------------ 2 files changed, 67 deletions(-) delete mode 100644 benches/kzg-elgamal-bench-results delete mode 100644 benches/kzg-paillier-bench-results diff --git a/benches/kzg-elgamal-bench-results b/benches/kzg-elgamal-bench-results deleted file mode 100644 index c08a725..0000000 --- a/benches/kzg-elgamal-bench-results +++ /dev/null @@ -1,27 +0,0 @@ -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-1","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[170862167.0,333291695.0,454686341.0,616684940.0,782865587.0,949580541.0,1184568382.0,1265048264.0,1470642766.0,1529809390.0],"unit":"ns","throughput":[],"typical":{"estimate":159029348.31428573,"lower_bound":154856461.47311828,"upper_bound":163611297.76355356,"unit":"ns"},"mean":{"estimate":160181868.2415873,"lower_bound":156253440.76888886,"upper_bound":164312732.06984124,"unit":"ns"},"median":{"estimate":158197228.25,"lower_bound":154171235.0,"upper_bound":166645847.5,"unit":"ns"},"median_abs_dev":{"estimate":7727172.274981946,"lower_bound":1253023.8896843968,"upper_bound":11289364.426803729,"unit":"ns"},"slope":{"estimate":159029348.31428573,"lower_bound":154856461.47311828,"upper_bound":163611297.76355356,"unit":"ns"},"change":{"mean":{"estimate":-0.003684486662215103,"lower_bound":-0.032963450480611944,"upper_bound":0.027735574722946597,"unit":"%"},"median":{"estimate":0.006497940808784852,"lower_bound":-0.020613245247548262,"upper_bound":0.07001596257532006,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-1","iteration_count":[4,8,12,16,20,24,28,32,36,40],"measured_values":[74159463.0,153067622.0,297198365.0,381022954.0,540506305.0,677624207.0,882985081.0,948274311.0,1130949124.0,1285928027.0],"unit":"ns","throughput":[],"typical":{"estimate":30109851.185714286,"lower_bound":27796454.492957745,"upper_bound":31215210.502645504,"unit":"ns"},"mean":{"estimate":26624564.855248015,"lower_bound":23598398.281944446,"upper_bound":29401526.354166668,"unit":"ns"},"median":{"estimate":27629828.604166664,"lower_bound":21949991.583333336,"upper_bound":31415253.444444444,"unit":"ns"},"median_abs_dev":{"estimate":5634857.540815447,"lower_bound":706159.247825671,"upper_bound":8791626.835617425,"unit":"ns"},"slope":{"estimate":30109851.185714286,"lower_bound":27796454.492957745,"upper_bound":31215210.502645504,"unit":"ns"},"change":{"mean":{"estimate":0.4363114297779893,"lower_bound":0.3026368999537424,"upper_bound":0.5905916183412421,"unit":"%"},"median":{"estimate":0.4906804770194526,"lower_bound":0.28471410042603273,"upper_bound":0.6958642915965025,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-2","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[171013444.0,366918093.0,547442505.0,676308577.0,898056523.0,1056663137.0,1216988792.0,1399426701.0,1633469878.0,1785895896.0],"unit":"ns","throughput":[],"typical":{"estimate":88775579.09610389,"lower_bound":87447502.25186104,"upper_bound":89852719.77949506,"unit":"ns"},"mean":{"estimate":88531120.9616865,"lower_bound":87081768.75823413,"upper_bound":89932604.70694444,"unit":"ns"},"median":{"estimate":88675028.10833333,"lower_bound":86485445.40625,"upper_bound":90748326.55555555,"unit":"ns"},"median_abs_dev":{"estimate":2832177.888952127,"lower_bound":729574.0212808102,"upper_bound":4241623.184249877,"unit":"ns"},"slope":{"estimate":88775579.09610389,"lower_bound":87447502.25186104,"upper_bound":89852719.77949506,"unit":"ns"},"change":{"mean":{"estimate":0.014557392940485192,"lower_bound":-0.00810298471704747,"upper_bound":0.03662046956215965,"unit":"%"},"median":{"estimate":0.05808361255455963,"lower_bound":0.024984107116773124,"upper_bound":0.08620653142651902,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-2","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[93829556.0,189347075.0,279347384.0,364709584.0,468726500.0,571606598.0,669796250.0,755794256.0,883812605.0,944584204.0],"unit":"ns","throughput":[],"typical":{"estimate":31755635.987012986,"lower_bound":31335528.690860216,"upper_bound":32221745.826576576,"unit":"ns"},"mean":{"estimate":31487621.067566138,"lower_bound":31140403.995793648,"upper_bound":31853591.02692064,"unit":"ns"},"median":{"estimate":31488783.733333334,"lower_bound":31157558.444444448,"upper_bound":31755922.111111112,"unit":"ns"},"median_abs_dev":{"estimate":376201.42428775784,"lower_bound":53155.43446630184,"upper_bound":1010730.491422615,"unit":"ns"},"slope":{"estimate":31755635.987012986,"lower_bound":31335528.690860216,"upper_bound":32221745.826576576,"unit":"ns"},"change":{"mean":{"estimate":0.01839484838281691,"lower_bound":0.006114371254936577,"upper_bound":0.03248548511220777,"unit":"%"},"median":{"estimate":0.008580867049936991,"lower_bound":0.00008556587178430775,"upper_bound":0.018829921651676962,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-4","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[115988138.0,214462224.0,312601581.0,413788418.0,505855681.0,619198416.0,696085116.0,825275378.0,938118133.0,1032467879.0],"unit":"ns","throughput":[],"typical":{"estimate":51460884.05844156,"lower_bound":50782963.04699739,"upper_bound":51920454.234421365,"unit":"ns"},"mean":{"estimate":52266002.1409127,"lower_bound":51164495.172106154,"upper_bound":53746014.52341269,"unit":"ns"},"median":{"estimate":51673473.1,"lower_bound":51092718.05,"upper_bound":52857909.75,"unit":"ns"},"median_abs_dev":{"estimate":645665.8804104679,"lower_bound":32382.07759760541,"upper_bound":2771608.1717566233,"unit":"ns"},"slope":{"estimate":51460884.05844156,"lower_bound":50782963.04699739,"upper_bound":51920454.234421365,"unit":"ns"},"change":{"mean":{"estimate":-0.008465694908526555,"lower_bound":-0.0346206963726785,"upper_bound":0.02092736028375263,"unit":"%"},"median":{"estimate":0.020069150196685648,"lower_bound":0.0005535273689742937,"upper_bound":0.03746707776174674,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-4","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[130475529.0,261943303.0,387735198.0,520478509.0,654463515.0,783658767.0,915585124.0,1044753626.0,1165758844.0,1293790881.0],"unit":"ns","throughput":[],"typical":{"estimate":43351182.012121215,"lower_bound":43209574.84353741,"upper_bound":43549606.20698066,"unit":"ns"},"mean":{"estimate":43420476.59671958,"lower_bound":43287728.67611112,"upper_bound":43542389.89494445,"unit":"ns"},"median":{"estimate":43511622.04166667,"lower_bound":43176253.481481485,"upper_bound":43599291.61904762,"unit":"ns"},"median_abs_dev":{"estimate":191027.01443359072,"lower_bound":33177.00446098859,"upper_bound":341031.43755771173,"unit":"ns"},"slope":{"estimate":43351182.012121215,"lower_bound":43209574.84353741,"upper_bound":43549606.20698066,"unit":"ns"},"change":{"mean":{"estimate":0.005380647903423519,"lower_bound":0.0021273750944650785,"upper_bound":0.008437147533117239,"unit":"%"},"median":{"estimate":0.00518848956236484,"lower_bound":-0.002235069979841464,"upper_bound":0.012457895016416032,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-8","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[115963732.0,206789103.0,312638594.0,406675520.0,513614290.0,614680719.0,719354269.0,825925638.0,918716303.0,1062354233.0],"unit":"ns","throughput":[],"typical":{"estimate":34532631.6952381,"lower_bound":34126708.15125596,"upper_bound":35018891.844840385,"unit":"ns"},"mean":{"estimate":34824342.85034391,"lower_bound":34211992.24704034,"upper_bound":35768063.8216713,"unit":"ns"},"median":{"estimate":34334266.7202381,"lower_bound":34133741.2037037,"upper_bound":34938329.13333333,"unit":"ns"},"median_abs_dev":{"estimate":365516.391974678,"lower_bound":78604.75015449304,"upper_bound":1017016.4888026826,"unit":"ns"},"slope":{"estimate":34532631.6952381,"lower_bound":34126708.15125596,"upper_bound":35018891.844840385,"unit":"ns"},"change":{"mean":{"estimate":0.018106007680380953,"lower_bound":-0.002205665789420509,"upper_bound":0.04867780399255452,"unit":"%"},"median":{"estimate":0.02114263111674375,"lower_bound":0.012915569734522014,"upper_bound":0.035850669636830354,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-8","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[155422712.0,308437407.0,466138853.0,622424677.0,778768251.0,934584532.0,1089453303.0,1237794576.0,1402525745.0,1557337620.0],"unit":"ns","throughput":[],"typical":{"estimate":77774543.9922078,"lower_bound":77583208.62324929,"upper_bound":77880516.98760763,"unit":"ns"},"mean":{"estimate":77703770.26575395,"lower_bound":77534025.79092263,"upper_bound":77839650.29650794,"unit":"ns"},"median":{"estimate":77810588.84821428,"lower_bound":77536758.5,"upper_bound":77876825.1,"unit":"ns"},"median_abs_dev":{"estimate":126531.25925361742,"lower_bound":14743.122398248419,"upper_bound":338459.9475244804,"unit":"ns"},"slope":{"estimate":77774543.9922078,"lower_bound":77583208.62324929,"upper_bound":77880516.98760763,"unit":"ns"},"change":{"mean":{"estimate":0.004115856441050836,"lower_bound":0.0011560614316662831,"upper_bound":0.006990230233869603,"unit":"%"},"median":{"estimate":0.00446302157545686,"lower_bound":0.001693556827132286,"upper_bound":0.005379083929462736,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-16","iteration_count":[4,8,12,16,20,24,28,32,36,40],"measured_values":[107085455.0,207817667.0,309371474.0,418180269.0,519788398.0,631953231.0,724431269.0,823329524.0,925011292.0,1031787335.0],"unit":"ns","throughput":[],"typical":{"estimate":25853797.21818182,"lower_bound":25759793.250666667,"upper_bound":26038835.429301593,"unit":"ns"},"mean":{"estimate":26007763.406170633,"lower_bound":25834593.69109127,"upper_bound":26220196.354949407,"unit":"ns"},"median":{"estimate":25924876.848214284,"lower_bound":25761865.5,"upper_bound":26160402.2625,"unit":"ns"},"median_abs_dev":{"estimate":251856.59992864745,"lower_bound":50837.63238911705,"upper_bound":470797.3514104262,"unit":"ns"},"slope":{"estimate":25853797.21818182,"lower_bound":25759793.250666667,"upper_bound":26038835.429301593,"unit":"ns"},"change":{"mean":{"estimate":0.008535656041445128,"lower_bound":-0.00020298523829348584,"upper_bound":0.017327213226329834,"unit":"%"},"median":{"estimate":0.019865404397654274,"lower_bound":0.007912913976041436,"upper_bound":0.028555657516446287,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-16","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[136451284.0,272713931.0,411374027.0,546535846.0,688536059.0,822158646.0,957325926.0,1093503795.0,1233248529.0,1371124211.0],"unit":"ns","throughput":[],"typical":{"estimate":136980694.79220778,"lower_bound":136798990.89957264,"upper_bound":137152928.98820975,"unit":"ns"},"mean":{"estimate":136888939.58464283,"lower_bound":136668497.02178568,"upper_bound":137132522.59714285,"unit":"ns"},"median":{"estimate":136893643.78571427,"lower_bound":136569629.1875,"upper_bound":137112421.1,"unit":"ns"},"median_abs_dev":{"estimate":333443.5505102071,"lower_bound":63737.0469984368,"upper_bound":701540.5314851778,"unit":"ns"},"slope":{"estimate":136980694.79220778,"lower_bound":136798990.89957264,"upper_bound":137152928.98820975,"unit":"ns"},"change":{"mean":{"estimate":0.0016377832775074097,"lower_bound":-0.00016356926924895038,"upper_bound":0.003716100035005558,"unit":"%"},"median":{"estimate":0.002112647337863205,"lower_bound":-0.00027605260815410926,"upper_bound":0.004079623655056652,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-32","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[108622465.0,213180028.0,323025962.0,432080620.0,544185520.0,649147585.0,757516773.0,869360333.0,974642559.0,1080806363.0],"unit":"ns","throughput":[],"typical":{"estimate":21654827.393766236,"lower_bound":21618548.29905504,"upper_bound":21696027.964068975,"unit":"ns"},"mean":{"estimate":21623946.005642854,"lower_bound":21541839.039166667,"upper_bound":21689681.16764107,"unit":"ns"},"median":{"estimate":21640794.602380954,"lower_bound":21575595.696666665,"upper_bound":21724493.0,"unit":"ns"},"median_abs_dev":{"estimate":89298.47901463509,"lower_bound":15174.929640593355,"upper_bound":171930.92026762094,"unit":"ns"},"slope":{"estimate":21654827.393766236,"lower_bound":21618548.29905504,"upper_bound":21696027.964068975,"unit":"ns"},"change":{"mean":{"estimate":-0.005948662845505548,"lower_bound":-0.011684140045201094,"upper_bound":-0.0009796381307688733,"unit":"%"},"median":{"estimate":-0.005135922763151335,"lower_bound":-0.010829326746251255,"upper_bound":0.003694869146089408,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-32","iteration_count":[2,2,2,2,2,2,2,2,2,2],"measured_values":[529225512.0,528773252.0,528873842.0,529348103.0,529540575.0,529335279.0,529135613.0,529628469.0,530014425.0,529370335.0],"unit":"ns","throughput":[],"typical":{"estimate":264662270.25,"lower_bound":264558538.8725,"upper_bound":264770263.32625002,"unit":"ns"},"mean":{"estimate":264662270.25,"lower_bound":264558538.8725,"upper_bound":264770263.32625002,"unit":"ns"},"median":{"estimate":264670845.5,"lower_bound":264524838.5,"upper_bound":264770287.5,"unit":"ns"},"median_abs_dev":{"estimate":150099.16263520718,"lower_bound":16480.581307411194,"upper_bound":316986.17542237043,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":0.0017344090317426009,"lower_bound":0.0012196160985552707,"upper_bound":0.0022407166949714617,"unit":"%"},"median":{"estimate":0.0018058091015791256,"lower_bound":0.0011862432009681623,"upper_bound":0.0024127729347607207,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-64","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[100491311.0,194499166.0,290966123.0,388989736.0,490746726.0,587143591.0,683116991.0,783840839.0,881043579.0,974898787.0],"unit":"ns","throughput":[],"typical":{"estimate":19545905.382857144,"lower_bound":19508652.597333334,"upper_bound":19582300.539578315,"unit":"ns"},"mean":{"estimate":19578710.043595236,"lower_bound":19486200.115179166,"upper_bound":19710571.891554758,"unit":"ns"},"median":{"estimate":19544540.673809525,"lower_bound":19449916.6,"upper_bound":19604307.619999997,"unit":"ns"},"median_abs_dev":{"estimate":101416.26332900065,"lower_bound":18212.214834168368,"upper_bound":191002.7615690198,"unit":"ns"},"slope":{"estimate":19545905.382857144,"lower_bound":19508652.597333334,"upper_bound":19582300.539578315,"unit":"ns"},"change":{"mean":{"estimate":-0.0009612584900137167,"lower_bound":-0.006791145181355734,"upper_bound":0.00685419102049897,"unit":"%"},"median":{"estimate":0.0007152977845437114,"lower_bound":-0.0062431800864068965,"upper_bound":0.005793841754208717,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-64","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[518823322.0,512369732.0,514527829.0,511664185.0,512170337.0,511655720.0,510748534.0,511014555.0,511834586.0,511390000.0],"unit":"ns","throughput":[],"typical":{"estimate":512619880.0,"lower_bound":511484701.1,"upper_bound":514232717.85249996,"unit":"ns"},"mean":{"estimate":512619880.0,"lower_bound":511484701.1,"upper_bound":514232717.85249996,"unit":"ns"},"median":{"estimate":511749385.5,"lower_bound":511335137.5,"upper_bound":513349083.0,"unit":"ns"},"median_abs_dev":{"estimate":771914.1936957836,"lower_bound":138868.46783459187,"upper_bound":2255776.60125196,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":-0.005288310181835176,"lower_bound":-0.007896936928401679,"upper_bound":-0.001736288185289982,"unit":"%"},"median":{"estimate":-0.004771362272160684,"lower_bound":-0.006885361613947039,"upper_bound":-0.0015668679233135085,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-128","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[96936801.0,190414359.0,284956718.0,386105186.0,480609453.0,572612730.0,673899017.0,768360264.0,862719380.0,963205242.0],"unit":"ns","throughput":[],"typical":{"estimate":19208562.147012986,"lower_bound":19156770.815873016,"upper_bound":19246630.172881357,"unit":"ns"},"mean":{"estimate":19194154.989968255,"lower_bound":19121807.481970634,"upper_bound":19263656.54063492,"unit":"ns"},"median":{"estimate":19216692.36,"lower_bound":19087091.0,"upper_bound":19279758.464285716,"unit":"ns"},"median_abs_dev":{"estimate":100801.54225641621,"lower_bound":29449.41701316745,"upper_bound":219487.54820731812,"unit":"ns"},"slope":{"estimate":19208562.147012986,"lower_bound":19156770.815873016,"upper_bound":19246630.172881357,"unit":"ns"},"change":{"mean":{"estimate":-0.008701306827168076,"lower_bound":-0.01424603293028881,"upper_bound":-0.003844308791122217,"unit":"%"},"median":{"estimate":-0.0023257101255256263,"lower_bound":-0.010949218915978776,"upper_bound":0.0019969396450076893,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-128","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[1017871018.0,1018633913.0,1011745915.0,1018923647.0,1013985665.0,1014366471.0,1011892361.0,1019384304.0,1016349189.0,1019585863.0],"unit":"ns","throughput":[],"typical":{"estimate":1016273834.6,"lower_bound":1014435002.4175,"upper_bound":1018011899.635,"unit":"ns"},"mean":{"estimate":1016273834.6,"lower_bound":1014435002.4175,"upper_bound":1018011899.635,"unit":"ns"},"median":{"estimate":1017110103.5,"lower_bound":1013129416.0,"upper_bound":1019009108.5,"unit":"ns"},"median_abs_dev":{"estimate":3521145.285487175,"lower_bound":490900.7120847702,"upper_bound":5123809.91153419,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":-0.0025930471180278802,"lower_bound":-0.0042868298452721386,"upper_bound":-0.0008607962958950528,"unit":"%"},"median":{"estimate":-0.0012480166314169372,"lower_bound":-0.0049251925580239275,"upper_bound":0.0007090969226681842,"unit":"%"},"change":"NoChange"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-256","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[100966936.0,199492403.0,308358449.0,399274702.0,532721932.0,596061381.0,695384086.0,830958926.0,982638486.0,1126068430.0],"unit":"ns","throughput":[],"typical":{"estimate":21237347.806233767,"lower_bound":20203841.91934426,"upper_bound":21938233.048005115,"unit":"ns"},"mean":{"estimate":20684105.18061905,"lower_bound":20180116.70561905,"upper_bound":21266729.740666665,"unit":"ns"},"median":{"estimate":20375308.566666666,"lower_bound":19916223.9,"upper_bound":21308877.28,"unit":"ns"},"median_abs_dev":{"estimate":691383.9097654816,"lower_bound":60578.674864512905,"upper_bound":1458654.5756337058,"unit":"ns"},"slope":{"estimate":21237347.806233767,"lower_bound":20203841.91934426,"upper_bound":21938233.048005115,"unit":"ns"},"change":{"mean":{"estimate":0.046775371934458354,"lower_bound":0.019478597589168707,"upper_bound":0.07713490526912882,"unit":"%"},"median":{"estimate":0.03777419998455711,"lower_bound":0.013892377553136548,"upper_bound":0.08735885685398759,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-256","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[2081998508.0,2103073433.0,2242308652.0,2120921632.0,2109325557.0,2107820388.0,2115598549.0,2231449945.0,2364586112.0,2195121290.0],"unit":"ns","throughput":[],"typical":{"estimate":2167220406.6,"lower_bound":2119469869.83,"upper_bound":2223802659.1,"unit":"ns"},"mean":{"estimate":2167220406.6,"lower_bound":2119469869.83,"upper_bound":2223802659.1,"unit":"ns"},"median":{"estimate":2118260090.5,"lower_bound":2106199495.0,"upper_bound":2231449945.0,"unit":"ns"},"median_abs_dev":{"estimate":38138579.63490486,"lower_bound":5750481.198808551,"upper_bound":159881664.15973306,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":0.06077250293716574,"lower_bound":0.03873309073624074,"upper_bound":0.09478597290728896,"unit":"%"},"median":{"estimate":0.04124575062757718,"lower_bound":0.03561100272808071,"upper_bound":0.09947587479350628,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-512","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[110898696.0,222354018.0,338257903.0,449242029.0,559604788.0,667452359.0,774206053.0,889897478.0,1001011821.0,1113060578.0],"unit":"ns","throughput":[],"typical":{"estimate":22258920.00779221,"lower_bound":22213105.32734519,"upper_bound":22318669.238345865,"unit":"ns"},"mean":{"estimate":22293390.13895238,"lower_bound":22221495.94347976,"upper_bound":22375154.74066667,"unit":"ns"},"median":{"estimate":22247924.458333332,"lower_bound":22212223.166666664,"upper_bound":22384191.52,"unit":"ns"},"median_abs_dev":{"estimate":60395.459395765814,"lower_bound":3469.172743408215,"upper_bound":206674.3028967979,"unit":"ns"},"slope":{"estimate":22258920.00779221,"lower_bound":22213105.32734519,"upper_bound":22318669.238345865,"unit":"ns"},"change":{"mean":{"estimate":0.03976083394023333,"lower_bound":0.03520064998182571,"upper_bound":0.04437902449793692,"unit":"%"},"median":{"estimate":0.040219273665329736,"lower_bound":0.0379104508903485,"upper_bound":0.04675918761590906,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-512","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[4406593476.0,4401039029.0,4373862798.0,4366836012.0,4425222184.0,4407452656.0,4400896265.0,4395429662.0,4391688774.0,4372576210.0],"unit":"ns","throughput":[],"typical":{"estimate":4394159706.6,"lower_bound":4383351759.0,"upper_bound":4404840506.8175,"unit":"ns"},"mean":{"estimate":4394159706.6,"lower_bound":4383351759.0,"upper_bound":4404840506.8175,"unit":"ns"},"median":{"estimate":4398162963.5,"lower_bound":4373862798.0,"upper_bound":4406593476.0,"unit":"ns"},"median_abs_dev":{"estimate":13135987.7332896,"lower_bound":4052392.7319556475,"upper_bound":35853944.966465235,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":0.05687428718168519,"lower_bound":0.050675486418654284,"upper_bound":0.06274574788839435,"unit":"%"},"median":{"estimate":0.07129650023742196,"lower_bound":0.06106245448382164,"upper_bound":0.07430148683194204,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-1024","iteration_count":[4,8,12,16,20,24,28,32,36,40],"measured_values":[99461599.0,200011984.0,302432034.0,398331868.0,502743311.0,598062012.0,701238894.0,799902443.0,900409437.0,1008142143.0],"unit":"ns","throughput":[],"typical":{"estimate":25061815.54090909,"lower_bound":24983788.40212766,"upper_bound":25142028.194913294,"unit":"ns"},"mean":{"estimate":25027784.94330357,"lower_bound":24958465.583828125,"upper_bound":25100474.78080357,"unit":"ns"},"median":{"estimate":25006435.625,"lower_bound":24919250.5,"upper_bound":25137165.55,"unit":"ns"},"median_abs_dev":{"estimate":146687.70009577274,"lower_bound":10690.958913322538,"upper_bound":202745.6787755423,"unit":"ns"},"slope":{"estimate":25061815.54090909,"lower_bound":24983788.40212766,"upper_bound":25142028.194913294,"unit":"ns"},"change":{"mean":{"estimate":0.05203485804048302,"lower_bound":0.04852376563081521,"upper_bound":0.05567842763961314,"unit":"%"},"median":{"estimate":0.05537810676811161,"lower_bound":0.05059766232843321,"upper_bound":0.06120066132273627,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-1024","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[8752771182.0,8789092306.0,8726176752.0,8689007626.0,8742704531.0,8920376222.0,8681513979.0,8548095098.0,8559997339.0,8562868796.0],"unit":"ns","throughput":[],"typical":{"estimate":8697260383.1,"lower_bound":8630028328.2925,"upper_bound":8767110848.307499,"unit":"ns"},"mean":{"estimate":8697260383.1,"lower_bound":8630028328.2925,"upper_bound":8767110848.307499,"unit":"ns"},"median":{"estimate":8707592189.0,"lower_bound":8562868796.0,"upper_bound":8765898418.5,"unit":"ns"},"median_abs_dev":{"estimate":93907222.57581353,"lower_bound":13080353.16927731,"upper_bound":230854919.8753059,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":466.1147818414803,"lower_bound":458.6095480773689,"upper_bound":474.04594926708256,"unit":"%"},"median":{"estimate":487.81809119945694,"lower_bound":476.01845082676783,"upper_bound":492.9801366174623,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-2048","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[91015584.0,184951206.0,274138284.0,368502192.0,455288056.0,545841331.0,635193477.0,737749084.0,818270371.0,907272902.0],"unit":"ns","throughput":[],"typical":{"estimate":30384709.30909091,"lower_bound":30278764.500548165,"upper_bound":30570500.546335775,"unit":"ns"},"mean":{"estimate":30454470.34878307,"lower_bound":30334510.52164021,"upper_bound":30589109.795099206,"unit":"ns"},"median":{"estimate":30345532.53333333,"lower_bound":30285913.408730157,"upper_bound":30708516.0,"unit":"ns"},"median_abs_dev":{"estimate":149243.38475039712,"lower_bound":20770.245467921526,"upper_bound":350385.7675594093,"unit":"ns"},"slope":{"estimate":30384709.30909091,"lower_bound":30278764.500548165,"upper_bound":30570500.546335775,"unit":"ns"},"change":{"mean":{"estimate":0.03503127920650995,"lower_bound":0.03030427684613965,"upper_bound":0.04012501616039089,"unit":"%"},"median":{"estimate":0.02810770833590248,"lower_bound":0.02557271864864963,"upper_bound":0.04077346819483196,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-2048","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[17104663992.0,17135751919.0,17051039201.0,17189588335.0,17065251894.0,17003276604.0,17062222172.0,17175087955.0,17112245412.0,17017599496.0],"unit":"ns","throughput":[],"typical":{"estimate":17091672698.0,"lower_bound":17055397613.8,"upper_bound":17129321374.6325,"unit":"ns"},"mean":{"estimate":17091672698.0,"lower_bound":17055397613.8,"upper_bound":17129321374.6325,"unit":"ns"},"median":{"estimate":17084957943.0,"lower_bound":17039910834.0,"upper_bound":17143666683.5,"unit":"ns"},"median_abs_dev":{"estimate":62797536.73852086,"lower_bound":11240213.092446327,"upper_bound":110483191.40033126,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":627.7200685478234,"lower_bound":626.0162424477558,"upper_bound":629.4760218325522,"unit":"%"},"median":{"estimate":626.214908779058,"lower_bound":624.2103816891226,"upper_bound":628.7103746570979,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-gen-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-gen-4096","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[120689886.0,234840139.0,349236535.0,472068998.0,588428805.0,701254378.0,822305462.0,934502594.0,1050305704.0,1169946729.0],"unit":"ns","throughput":[],"typical":{"estimate":39013336.50735931,"lower_bound":38947814.191005945,"upper_bound":39121131.82369191,"unit":"ns"},"mean":{"estimate":39169373.79283069,"lower_bound":38975057.45414484,"upper_bound":39440537.61202381,"unit":"ns"},"median":{"estimate":39069123.733333334,"lower_bound":38929393.9074074,"upper_bound":39248243.059523806,"unit":"ns"},"median_abs_dev":{"estimate":215702.66709551032,"lower_bound":43266.1933763176,"upper_bound":406358.8658217979,"unit":"ns"},"slope":{"estimate":39013336.50735931,"lower_bound":38947814.191005945,"upper_bound":39121131.82369191,"unit":"ns"},"change":{"mean":{"estimate":0.051429152821222957,"lower_bound":0.04491705041948611,"upper_bound":0.05966072101099902,"unit":"%"},"median":{"estimate":0.05793850800525879,"lower_bound":0.04044382630995469,"upper_bound":0.06427330211893967,"unit":"%"},"change":"Regressed"}} -{"reason":"benchmark-complete","id":"kzg-elgamal/proof-vfy-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal/proof-vfy-4096","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[34026936270.0,34203631489.0,34252596002.0,34223222314.0,34137460175.0,34273340516.0,34245565259.0,34196393451.0,34146717148.0,34275059016.0],"unit":"ns","throughput":[],"typical":{"estimate":34198092164.0,"lower_bound":34149405319.0,"upper_bound":34239229000.899998,"unit":"ns"},"mean":{"estimate":34198092164.0,"lower_bound":34149405319.0,"upper_bound":34239229000.899998,"unit":"ns"},"median":{"estimate":34213426901.5,"lower_bound":34146717148.0,"upper_bound":34259452887.5,"unit":"ns"},"median_abs_dev":{"estimate":73450015.32550156,"lower_bound":13724387.926143408,"upper_bound":122328897.58072793,"unit":"ns"},"slope":null,"change":{"mean":{"estimate":845.2180265533412,"lower_bound":842.628432394928,"upper_bound":847.7850161870736,"unit":"%"},"median":{"estimate":844.8264893763486,"lower_bound":841.9511891746489,"upper_bound":852.8107683634241,"unit":"%"},"change":"Regressed"}} -{"reason":"group-complete","group_name":"kzg-elgamal","benchmarks":["kzg-elgamal/proof-gen-1","kzg-elgamal/proof-vfy-1","kzg-elgamal/proof-gen-2","kzg-elgamal/proof-vfy-2","kzg-elgamal/proof-gen-4","kzg-elgamal/proof-vfy-4","kzg-elgamal/proof-gen-8","kzg-elgamal/proof-vfy-8","kzg-elgamal/proof-gen-16","kzg-elgamal/proof-vfy-16","kzg-elgamal/proof-gen-32","kzg-elgamal/proof-vfy-32","kzg-elgamal/proof-gen-64","kzg-elgamal/proof-vfy-64","kzg-elgamal/proof-gen-128","kzg-elgamal/proof-vfy-128","kzg-elgamal/proof-gen-256","kzg-elgamal/proof-vfy-256","kzg-elgamal/proof-gen-512","kzg-elgamal/proof-vfy-512","kzg-elgamal/proof-gen-1024","kzg-elgamal/proof-vfy-1024","kzg-elgamal/proof-gen-2048","kzg-elgamal/proof-vfy-2048","kzg-elgamal/proof-gen-4096","kzg-elgamal/proof-vfy-4096"],"report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-elgamal"} diff --git a/benches/kzg-paillier-bench-results b/benches/kzg-paillier-bench-results deleted file mode 100644 index 446398e..0000000 --- a/benches/kzg-paillier-bench-results +++ /dev/null @@ -1,40 +0,0 @@ -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-1","iteration_count":[13,26,39,52,65,78,91,104,117,130],"measured_values":[94550142.0,183475693.0,274283562.0,366588712.0,460051601.0,553055108.0,637717680.0,736738261.0,822001848.0,920318879.0],"unit":"ns","throughput":[],"typical":{"estimate":7058627.569430569,"lower_bound":7032667.32700491,"upper_bound":7080926.276683228,"unit":"ns"},"mean":{"estimate":7077764.822609891,"lower_bound":7043197.3461996345,"upper_bound":7127912.94533631,"unit":"ns"},"median":{"estimate":7067237.180769231,"lower_bound":7032911.846153846,"upper_bound":7084913.047435898,"unit":"ns"},"median_abs_dev":{"estimate":30146.579618637734,"lower_bound":5378.150412211299,"upper_bound":72799.68833831717,"unit":"ns"},"slope":{"estimate":7058627.569430569,"lower_bound":7032667.32700491,"upper_bound":7080926.276683228,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-1","iteration_count":[14,28,42,56,70,84,98,112,126,140],"measured_values":[91945961.0,186908132.0,276631473.0,373377491.0,466809407.0,556480892.0,661370184.0,746311364.0,833147576.0,931112010.0],"unit":"ns","throughput":[],"typical":{"estimate":6655218.827272727,"lower_bound":6627727.007097069,"upper_bound":6691631.338564213,"unit":"ns"},"mean":{"estimate":6646550.83378118,"lower_bound":6616679.704761906,"upper_bound":6677509.120124716,"unit":"ns"},"median":{"estimate":6657147.196428572,"lower_bound":6605618.083333334,"upper_bound":6671372.8125,"unit":"ns"},"median_abs_dev":{"estimate":37448.9221351481,"lower_bound":4790.362587453314,"upper_bound":95066.2753455705,"unit":"ns"},"slope":{"estimate":6655218.827272727,"lower_bound":6627727.007097069,"upper_bound":6691631.338564213,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-1","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-1","iteration_count":[20,40,60,80,100,120,140,160,180,200],"measured_values":[96784081.0,190847080.0,282913778.0,379180871.0,481214735.0,575133799.0,663023163.0,754005791.0,848125583.0,943828461.0],"unit":"ns","throughput":[],"typical":{"estimate":4733174.396623377,"lower_bound":4718150.556785714,"upper_bound":4763136.264285714,"unit":"ns"},"mean":{"estimate":4754966.760807539,"lower_bound":4729588.256555555,"upper_bound":4783168.836101191,"unit":"ns"},"median":{"estimate":4737820.311607143,"lower_bound":4715229.633333334,"upper_bound":4792781.658333333,"unit":"ns"},"median_abs_dev":{"estimate":38025.45356512183,"lower_bound":3075.088918948447,"upper_bound":73841.7488171719,"unit":"ns"},"slope":{"estimate":4733174.396623377,"lower_bound":4718150.556785714,"upper_bound":4763136.264285714,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-2","iteration_count":[8,16,24,32,40,48,56,64,72,80],"measured_values":[93708312.0,210936457.0,291099648.0,386362222.0,522382097.0,575365182.0,665864552.0,796938261.0,800412295.0,1011041405.0],"unit":"ns","throughput":[],"typical":{"estimate":12126335.484415585,"lower_bound":11585816.464449365,"upper_bound":12568094.891939253,"unit":"ns"},"mean":{"estimate":12224381.979975197,"lower_bound":11854427.30066518,"upper_bound":12593218.68228125,"unit":"ns"},"median":{"estimate":12101485.71875,"lower_bound":11850156.8125,"upper_bound":12755856.3765625,"unit":"ns"},"median_abs_dev":{"estimate":547539.9808182847,"lower_bound":105544.34621371329,"upper_bound":1127650.8117906125,"unit":"ns"},"slope":{"estimate":12126335.484415585,"lower_bound":11585816.464449365,"upper_bound":12568094.891939253,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-2","iteration_count":[8,16,24,32,40,48,56,64,72,80],"measured_values":[92727546.0,182467148.0,271869823.0,369269862.0,452922411.0,549303705.0,638703256.0,731436932.0,817396911.0,930976568.0],"unit":"ns","throughput":[],"typical":{"estimate":11460889.990584416,"lower_bound":11373854.42124542,"upper_bound":11558241.610545883,"unit":"ns"},"mean":{"estimate":11445367.926488094,"lower_bound":11384302.335059525,"upper_bound":11512073.3825,"unit":"ns"},"median":{"estimate":11417058.674107142,"lower_bound":11352734.875,"upper_bound":11539683.1875,"unit":"ns"},"median_abs_dev":{"estimate":113769.66746143352,"lower_bound":18165.787833742797,"upper_bound":176434.2616489157,"unit":"ns"},"slope":{"estimate":11460889.990584416,"lower_bound":11373854.42124542,"upper_bound":11558241.610545883,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-2","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-2","iteration_count":[13,26,39,52,65,78,91,104,117,130],"measured_values":[92955870.0,182359119.0,276006131.0,364434699.0,454127900.0,545950865.0,643532764.0,737765275.0,823416002.0,923534552.0],"unit":"ns","throughput":[],"typical":{"estimate":7061481.932667333,"lower_bound":7023672.289219741,"upper_bound":7087374.611965812,"unit":"ns"},"mean":{"estimate":7054319.786260685,"lower_bound":7023717.891923077,"upper_bound":7086482.4618376065,"unit":"ns"},"median":{"estimate":7054766.111111111,"lower_bound":7006591.166666666,"upper_bound":7093896.875,"unit":"ns"},"median_abs_dev":{"estimate":64760.231373994124,"lower_bound":12466.140131566422,"upper_bound":96314.08269104415,"unit":"ns"},"slope":{"estimate":7061481.932667333,"lower_bound":7023672.289219741,"upper_bound":7087374.611965812,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-4","iteration_count":[6,12,18,24,30,36,42,48,54,60],"measured_values":[93523343.0,164284446.0,287889300.0,363919213.0,473390884.0,577544185.0,648601181.0,814750615.0,769499114.0,880304790.0],"unit":"ns","throughput":[],"typical":{"estimate":15307536.636363637,"lower_bound":14666784.22792414,"upper_bound":16249442.357174685,"unit":"ns"},"mean":{"estimate":15359592.153644178,"lower_bound":14791995.535057541,"upper_bound":15911056.175593255,"unit":"ns"},"median":{"estimate":15515054.547619049,"lower_bound":14671746.5,"upper_bound":15993850.0,"unit":"ns"},"median_abs_dev":{"estimate":746218.4622436395,"lower_bound":207256.14943296774,"upper_bound":1705621.0403702832,"unit":"ns"},"slope":{"estimate":15307536.636363637,"lower_bound":14666784.22792414,"upper_bound":16249442.357174685,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-4","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[103640549.0,208760361.0,306971507.0,413359092.0,523254115.0,627856164.0,737920455.0,826953624.0,934193093.0,1039693113.0],"unit":"ns","throughput":[],"typical":{"estimate":20812810.837922078,"lower_bound":20728217.60896597,"upper_bound":20923861.04461482,"unit":"ns"},"mean":{"estimate":20790656.197587304,"lower_bound":20686979.614916664,"upper_bound":20891089.394911114,"unit":"ns"},"median":{"estimate":20776854.385555558,"lower_bound":20673840.6,"upper_bound":20928538.8,"unit":"ns"},"median_abs_dev":{"estimate":157091.52747573584,"lower_bound":40125.45633763075,"upper_bound":304873.6795774117,"unit":"ns"},"slope":{"estimate":20812810.837922078,"lower_bound":20728217.60896597,"upper_bound":20923861.04461482,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-4","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-4","iteration_count":[8,16,24,32,40,48,56,64,72,80],"measured_values":[93588556.0,186354718.0,278326058.0,368743295.0,462600814.0,554863601.0,647753787.0,733103448.0,836317887.0,923326341.0],"unit":"ns","throughput":[],"typical":{"estimate":11551189.45064935,"lower_bound":11506935.700737266,"upper_bound":11592088.28002451,"unit":"ns"},"mean":{"estimate":11576944.388779763,"lower_bound":11537226.75212128,"upper_bound":11616761.241796875,"unit":"ns"},"median":{"estimate":11566026.130357143,"lower_bound":11541443.161458332,"upper_bound":11622044.479166668,"unit":"ns"},"median_abs_dev":{"estimate":54627.2222707984,"lower_bound":6957.187302735577,"upper_bound":118812.5437406561,"unit":"ns"},"slope":{"estimate":11551189.45064935,"lower_bound":11506935.700737266,"upper_bound":11592088.28002451,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-8","iteration_count":[7,14,21,28,35,42,49,56,63,70],"measured_values":[98709478.0,197824942.0,297808020.0,396084710.0,496271723.0,595764131.0,695699986.0,807222434.0,899514410.0,996099919.0],"unit":"ns","throughput":[],"typical":{"estimate":14253199.969202226,"lower_bound":14188342.627935417,"upper_bound":14318081.461942257,"unit":"ns"},"mean":{"estimate":14204362.670351472,"lower_bound":14158049.867414966,"upper_bound":14261893.919671202,"unit":"ns"},"median":{"estimate":14183097.273809522,"lower_bound":14145882.5,"upper_bound":14237982.702947846,"unit":"ns"},"median_abs_dev":{"estimate":62355.44385296962,"lower_bound":5227.612207190674,"upper_bound":123806.3817019963,"unit":"ns"},"slope":{"estimate":14253199.969202226,"lower_bound":14188342.627935417,"upper_bound":14318081.461942257,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-8","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[117561527.0,236226288.0,362070802.0,480182023.0,597001495.0,701946945.0,835853318.0,950397594.0,1067371151.0,1191926707.0],"unit":"ns","throughput":[],"typical":{"estimate":39630653.81212121,"lower_bound":39451751.275641024,"upper_bound":39781656.94599423,"unit":"ns"},"mean":{"estimate":39626622.731534384,"lower_bound":39404958.65870371,"upper_bound":39844332.874365084,"unit":"ns"},"median":{"estimate":39665394.99166667,"lower_bound":39359720.259259254,"upper_bound":39907634.125,"unit":"ns"},"median_abs_dev":{"estimate":319864.23732127674,"lower_bound":54921.43695494937,"upper_bound":636807.1643610802,"unit":"ns"},"slope":{"estimate":39630653.81212121,"lower_bound":39451751.275641024,"upper_bound":39781656.94599423,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-8","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-8","iteration_count":[5,10,15,20,25,30,35,40,45,50],"measured_values":[105049064.0,205221292.0,310713923.0,415484598.0,527950248.0,621056441.0,734439208.0,841758205.0,938469524.0,1032034813.0],"unit":"ns","throughput":[],"typical":{"estimate":20840195.136103895,"lower_bound":20713556.523625094,"upper_bound":20979117.875303645,"unit":"ns"},"mean":{"estimate":20836383.17875397,"lower_bound":20721249.813166667,"upper_bound":20951324.358311906,"unit":"ns"},"median":{"estimate":20814554.105555557,"lower_bound":20677478.89666667,"upper_bound":21013966.248214286,"unit":"ns"},"median_abs_dev":{"estimate":254474.2833841773,"lower_bound":44461.507933150286,"upper_bound":329309.9417635839,"unit":"ns"},"slope":{"estimate":20840195.136103895,"lower_bound":20713556.523625094,"upper_bound":20979117.875303645,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-16","iteration_count":[4,8,12,16,20,24,28,32,36,40],"measured_values":[94411850.0,190230275.0,280905930.0,375671797.0,471413744.0,568885194.0,662176522.0,757439709.0,847734717.0,942479759.0],"unit":"ns","throughput":[],"typical":{"estimate":23597286.124025974,"lower_bound":23554624.64893617,"upper_bound":23649539.048780486,"unit":"ns"},"mean":{"estimate":23597363.160208333,"lower_bound":23533916.924583334,"upper_bound":23660575.43125,"unit":"ns"},"median":{"estimate":23586824.85,"lower_bound":23520740.64375,"upper_bound":23676355.625,"unit":"ns"},"median_abs_dev":{"estimate":107861.15422820451,"lower_bound":20470.838521574016,"upper_bound":183064.30973745883,"unit":"ns"},"slope":{"estimate":23597286.124025974,"lower_bound":23554624.64893617,"upper_bound":23649539.048780486,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-16","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[154178993.0,308666745.0,462887663.0,619902942.0,768945423.0,923309590.0,1074192011.0,1232581924.0,1381752483.0,1548499322.0],"unit":"ns","throughput":[],"typical":{"estimate":77045632.37792207,"lower_bound":76828586.86052895,"upper_bound":77277671.63695653,"unit":"ns"},"mean":{"estimate":77068236.64357144,"lower_bound":76923972.39214286,"upper_bound":77220422.45775001,"unit":"ns"},"median":{"estimate":77062933.375,"lower_bound":76853246.33333333,"upper_bound":77286454.96666667,"unit":"ns"},"median_abs_dev":{"estimate":214130.88873342267,"lower_bound":57220.76065912843,"upper_bound":479528.9478966505,"unit":"ns"},"slope":{"estimate":77045632.37792207,"lower_bound":76828586.86052895,"upper_bound":77277671.63695653,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-16","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-16","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[120293203.0,235614745.0,351143054.0,473422744.0,592718579.0,699723911.0,818862485.0,939176813.0,1054900115.0,1165176323.0],"unit":"ns","throughput":[],"typical":{"estimate":39040602.03982684,"lower_bound":38925716.17481977,"upper_bound":39208571.143989325,"unit":"ns"},"mean":{"estimate":39225817.55379629,"lower_bound":39025682.35782408,"upper_bound":39467554.860740736,"unit":"ns"},"median":{"estimate":39101370.91898148,"lower_bound":38944722.75,"upper_bound":39451895.333333336,"unit":"ns"},"median_abs_dev":{"estimate":293238.67152730376,"lower_bound":57022.99143208377,"upper_bound":574025.3071056784,"unit":"ns"},"slope":{"estimate":39040602.03982684,"lower_bound":38925716.17481977,"upper_bound":39208571.143989325,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-32","iteration_count":[3,6,9,12,15,18,21,24,27,30],"measured_values":[130403659.0,260874073.0,390905156.0,519535896.0,651618486.0,784468874.0,913001769.0,1048361323.0,1174983284.0,1302708483.0],"unit":"ns","throughput":[],"typical":{"estimate":43504548.81731602,"lower_bound":43434460.38114553,"upper_bound":43586744.89298626,"unit":"ns"},"mean":{"estimate":43479781.12466931,"lower_bound":43420548.38222222,"upper_bound":43540900.20156945,"unit":"ns"},"median":{"estimate":43472080.52380952,"lower_bound":43432424.25,"upper_bound":43530308.13888889,"unit":"ns"},"median_abs_dev":{"estimate":62264.14707236922,"lower_bound":8247.580103578024,"upper_bound":167449.9912971652,"unit":"ns"},"slope":{"estimate":43504548.81731602,"lower_bound":43434460.38114553,"upper_bound":43586744.89298626,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-32","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[150952073.0,307645170.0,453674262.0,606527379.0,772317056.0,916429214.0,1058036332.0,1216677509.0,1381049203.0,1527609066.0],"unit":"ns","throughput":[],"typical":{"estimate":152620112.1090909,"lower_bound":151923265.11186868,"upper_bound":153206561.26889133,"unit":"ns"},"mean":{"estimate":152427642.43813494,"lower_bound":151728939.09139884,"upper_bound":153160089.1699524,"unit":"ns"},"median":{"estimate":152411445.4791667,"lower_bound":151224754.0,"upper_bound":153449911.44444445,"unit":"ns"},"median_abs_dev":{"estimate":1649509.1842820272,"lower_bound":259001.0021018099,"upper_bound":2030204.6656099681,"unit":"ns"},"slope":{"estimate":152620112.1090909,"lower_bound":151923265.11186868,"upper_bound":153206561.26889133,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-32","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-32","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[151507953.0,303858996.0,456775045.0,610809548.0,764747408.0,914737106.0,1054713389.0,1222430399.0,1378862564.0,1531482401.0],"unit":"ns","throughput":[],"typical":{"estimate":76327237.59610389,"lower_bound":75920897.02686568,"upper_bound":76533307.20707071,"unit":"ns"},"mean":{"estimate":76181809.25414683,"lower_bound":75931429.92494048,"upper_bound":76397436.76041667,"unit":"ns"},"median":{"estimate":76289642.83333334,"lower_bound":75941575.33333334,"upper_bound":76488009.99375,"unit":"ns"},"median_abs_dev":{"estimate":348096.0772250401,"lower_bound":91585.61186402815,"upper_bound":629733.8034366556,"unit":"ns"},"slope":{"estimate":76327237.59610389,"lower_bound":75920897.02686568,"upper_bound":76533307.20707071,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-64","iteration_count":[2,4,6,8,10,12,14,16,18,20],"measured_values":[168806628.0,338890650.0,501809629.0,664686945.0,835408435.0,1006783334.0,1168182048.0,1338833620.0,1503877557.0,1662608049.0],"unit":"ns","throughput":[],"typical":{"estimate":83477179.96493506,"lower_bound":83284824.52349271,"upper_bound":83696184.56831396,"unit":"ns"},"mean":{"estimate":83708406.91821429,"lower_bound":83425611.60809524,"upper_bound":84029288.66666666,"unit":"ns"},"median":{"estimate":83591845.66666667,"lower_bound":83335622.975,"upper_bound":84040207.625,"unit":"ns"},"median_abs_dev":{"estimate":338801.0102350881,"lower_bound":69752.37516165148,"upper_bound":876562.2155629098,"unit":"ns"},"slope":{"estimate":83477179.96493506,"lower_bound":83284824.52349271,"upper_bound":83696184.56831396,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-64","iteration_count":[2,2,2,2,2,2,2,2,2,2],"measured_values":[612105706.0,626676936.0,608542034.0,602009940.0,617771807.0,612786267.0,609024678.0,601612215.0,612471300.0,614749322.0],"unit":"ns","throughput":[],"typical":{"estimate":305887510.25,"lower_bound":303810546.25,"upper_bound":308103617.6475,"unit":"ns"},"mean":{"estimate":305887510.25,"lower_bound":303810546.25,"upper_bound":308103617.6475,"unit":"ns"},"median":{"estimate":306144251.5,"lower_bound":302758654.5,"upper_bound":307639518.5,"unit":"ns"},"median_abs_dev":{"estimate":2598365.4249697924,"lower_bound":252249.93017166853,"upper_bound":6342008.195006847,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-64","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-64","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[150758542.0,302107685.0,447600335.0,603676588.0,746972700.0,909126251.0,1044455157.0,1182488239.0,1352890782.0,1498245882.0],"unit":"ns","throughput":[],"typical":{"estimate":149692649.72467533,"lower_bound":148836523.7967685,"upper_bound":150463749.93353277,"unit":"ns"},"mean":{"estimate":150001192.06464285,"lower_bound":149319375.53695536,"upper_bound":150634109.84047619,"unit":"ns"},"median":{"estimate":150072893.1,"lower_bound":149207879.57142857,"upper_bound":150919147.0,"unit":"ns"},"median_abs_dev":{"estimate":1268562.5222785163,"lower_bound":149888.06863894433,"upper_bound":2066572.254454489,"unit":"ns"},"slope":{"estimate":149692649.72467533,"lower_bound":148836523.7967685,"upper_bound":150463749.93353277,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-128","iteration_count":[1,2,3,4,5,6,7,8,9,10],"measured_values":[162776220.0,326515042.0,491134575.0,649703767.0,821321022.0,978653863.0,1144641573.0,1305240235.0,1473361929.0,1629099119.0],"unit":"ns","throughput":[],"typical":{"estimate":163304454.0961039,"lower_bound":163019450.76753506,"upper_bound":163639802.8038741,"unit":"ns"},"mean":{"estimate":163283643.63059524,"lower_bound":162974376.05545834,"upper_bound":163602504.27,"unit":"ns"},"median":{"estimate":163206275.1875,"lower_bound":162909911.9,"upper_bound":163706881.0,"unit":"ns"},"median_abs_dev":{"estimate":551530.6849083635,"lower_bound":110115.54169506571,"upper_bound":899239.7126427861,"unit":"ns"},"slope":{"estimate":163304454.0961039,"lower_bound":163019450.76753506,"upper_bound":163639802.8038741,"unit":"ns"},"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-128","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[607722114.0,605040401.0,604948445.0,596579281.0,596400258.0,596387488.0,596003251.0,594836787.0,606028487.0,605256556.0],"unit":"ns","throughput":[],"typical":{"estimate":600920306.8,"lower_bound":597884979.0,"upper_bound":603960622.4425,"unit":"ns"},"mean":{"estimate":600920306.8,"lower_bound":597884979.0,"upper_bound":603960622.4425,"unit":"ns"},"median":{"estimate":600763863.0,"lower_bound":596201754.5,"upper_bound":605534444.0,"unit":"ns"},"median_abs_dev":{"estimate":6574639.991676807,"lower_bound":142176.1483758688,"upper_bound":7431707.314860821,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-128","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-128","iteration_count":[2,2,2,2,2,2,2,2,2,2],"measured_values":[596381584.0,593586729.0,598660773.0,595152856.0,595571221.0,598956829.0,591170285.0,594358062.0,593887891.0,595182897.0],"unit":"ns","throughput":[],"typical":{"estimate":297645456.35,"lower_bound":296964763.94,"upper_bound":298332826.51625,"unit":"ns"},"mean":{"estimate":297645456.35,"lower_bound":296964763.94,"upper_bound":298332826.51625,"unit":"ns"},"median":{"estimate":297583938.25,"lower_bound":296943945.5,"upper_bound":298557998.5,"unit":"ns"},"median_abs_dev":{"estimate":924287.2940406203,"lower_bound":166201.68094933033,"upper_bound":1990427.5296628475,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-256","iteration_count":[2,2,2,2,2,2,2,2,2,2],"measured_values":[639591121.0,663216111.0,651553076.0,643330341.0,642844521.0,647454899.0,645860660.0,639401079.0,642784874.0,650051502.0],"unit":"ns","throughput":[],"typical":{"estimate":323304409.2,"lower_bound":321438159.605,"upper_bound":325576233.95,"unit":"ns"},"mean":{"estimate":323304409.2,"lower_bound":321438159.605,"upper_bound":325576233.95,"unit":"ns"},"median":{"estimate":322297750.25,"lower_bound":320608910.5,"upper_bound":325025751.0,"unit":"ns"},"median_abs_dev":{"estimate":2914709.2639535666,"lower_bound":202177.3399606347,"upper_bound":5162465.740647912,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-256","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[1212700080.0,1243541117.0,1206615628.0,1204600073.0,1197866904.0,1197431758.0,1196586209.0,1215584140.0,1219619151.0,1211818119.0],"unit":"ns","throughput":[],"typical":{"estimate":1210636317.9,"lower_bound":1203201838.7,"upper_bound":1219621801.5800002,"unit":"ns"},"mean":{"estimate":1210636317.9,"lower_bound":1203201838.7,"upper_bound":1219621801.5800002,"unit":"ns"},"median":{"estimate":1209216873.5,"lower_bound":1197866904.0,"upper_bound":1216159615.5,"unit":"ns"},"median_abs_dev":{"estimate":12431262.746500969,"lower_bound":1271952.9107183218,"upper_bound":21633450.178429484,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-256","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-256","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[599376124.0,600483347.0,604121471.0,599024879.0,598774021.0,598931644.0,595208110.0,598748310.0,600916583.0,601486243.0],"unit":"ns","throughput":[],"typical":{"estimate":599707073.2,"lower_bound":598350671.2,"upper_bound":601062177.2049999,"unit":"ns"},"mean":{"estimate":599707073.2,"lower_bound":598350671.2,"upper_bound":601062177.2049999,"unit":"ns"},"median":{"estimate":599200501.5,"lower_bound":598774021.0,"upper_bound":600984795.0,"unit":"ns"},"median_abs_dev":{"estimate":1286182.905265689,"lower_bound":138230.20854592323,"upper_bound":3906988.9634370804,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-512","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[650804536.0,647081807.0,646055399.0,654158329.0,643665257.0,641061376.0,643051553.0,640431503.0,642698922.0,637269476.0],"unit":"ns","throughput":[],"typical":{"estimate":644627815.8,"lower_bound":641814494.3,"upper_bound":647714129.1949999,"unit":"ns"},"mean":{"estimate":644627815.8,"lower_bound":641814494.3,"upper_bound":647714129.1949999,"unit":"ns"},"median":{"estimate":643358405.0,"lower_bound":641061376.0,"upper_bound":648429967.5,"unit":"ns"},"median_abs_dev":{"estimate":4168994.0307855606,"lower_bound":716344.1227823496,"upper_bound":8311101.852348447,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-512","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[2426341374.0,2438863070.0,2418226168.0,2406024588.0,2395476385.0,2431919135.0,2402838685.0,2444429827.0,2447874465.0,2409758289.0],"unit":"ns","throughput":[],"typical":{"estimate":2422175198.6,"lower_bound":2411297141.1549997,"upper_bound":2432971724.1,"unit":"ns"},"mean":{"estimate":2422175198.6,"lower_bound":2411297141.1549997,"upper_bound":2432971724.1,"unit":"ns"},"median":{"estimate":2422283771.0,"lower_bound":2406024588.0,"upper_bound":2438863070.0,"unit":"ns"},"median_abs_dev":{"estimate":24343166.274422407,"lower_bound":5129502.354133129,"upper_bound":30699598.684573174,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-512","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-512","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[1165410798.0,1174149812.0,1201501653.0,1205492308.0,1192786380.0,1180861952.0,1183275226.0,1187712553.0,1187199141.0,1227589590.0],"unit":"ns","throughput":[],"typical":{"estimate":1190597941.3,"lower_bound":1180957121.3,"upper_bound":1201486718.2,"unit":"ns"},"mean":{"estimate":1190597941.3,"lower_bound":1180957121.3,"upper_bound":1201486718.2,"unit":"ns"},"median":{"estimate":1187455847.0,"lower_bound":1178712519.0,"upper_bound":1201501653.0,"unit":"ns"},"median_abs_dev":{"estimate":14751817.84710288,"lower_bound":3289390.446701646,"upper_bound":29115497.692796588,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-1024","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[1291465710.0,1289168419.0,1281643239.0,1282933229.0,1272561694.0,1284982299.0,1287630900.0,1285509711.0,1288563244.0,1280167273.0],"unit":"ns","throughput":[],"typical":{"estimate":1284462571.8,"lower_bound":1281042347.1175,"upper_bound":1287430211.265,"unit":"ns"},"mean":{"estimate":1284462571.8,"lower_bound":1281042347.1175,"upper_bound":1287430211.265,"unit":"ns"},"median":{"estimate":1285246005.0,"lower_bound":1281550251.0,"upper_bound":1288563244.0,"unit":"ns"},"median_abs_dev":{"estimate":5129799.615427852,"lower_bound":1139762.8144651651,"upper_bound":8699178.325858712,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-1024","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[4891309834.0,4867136450.0,4873120110.0,4853740567.0,4922521625.0,4936533393.0,4889500907.0,4812336791.0,4948796109.0,4860723249.0],"unit":"ns","throughput":[],"typical":{"estimate":4885571903.5,"lower_bound":4861088381.0,"upper_bound":4909926122.37,"unit":"ns"},"mean":{"estimate":4885571903.5,"lower_bound":4861088381.0,"upper_bound":4909926122.37,"unit":"ns"},"median":{"estimate":4881310508.5,"lower_bound":4860438508.5,"upper_bound":4922521625.0,"unit":"ns"},"median_abs_dev":{"estimate":35698932.46751726,"lower_bound":9189792.896148562,"upper_bound":76491867.1740979,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-1024","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-1024","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[2387803177.0,2351740587.0,2373088274.0,2407169599.0,2403047929.0,2371174802.0,2387655954.0,2396911773.0,2370518613.0,2382000316.0],"unit":"ns","throughput":[],"typical":{"estimate":2383111102.4,"lower_bound":2372974110.0,"upper_bound":2392932717.8,"unit":"ns"},"mean":{"estimate":2383111102.4,"lower_bound":2372974110.0,"upper_bound":2392932717.8,"unit":"ns"},"median":{"estimate":2384828135.0,"lower_bound":2371174802.0,"upper_bound":2396911773.0,"unit":"ns"},"median_abs_dev":{"estimate":19078816.263583302,"lower_bound":2391322.562545538,"upper_bound":28821793.155410886,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-2048","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[2592663292.0,2604250654.0,2537895380.0,2554504984.0,2575385290.0,2537529466.0,2565608641.0,2542482533.0,2543736585.0,2569373879.0],"unit":"ns","throughput":[],"typical":{"estimate":2562343070.4,"lower_bound":2549216407.1125,"upper_bound":2576658647.1525,"unit":"ns"},"mean":{"estimate":2562343070.4,"lower_bound":2549216407.1125,"upper_bound":2576658647.1525,"unit":"ns"},"median":{"estimate":2560056812.5,"lower_bound":2540815982.5,"upper_bound":2581018585.5,"unit":"ns"},"median_abs_dev":{"estimate":25125997.593024373,"lower_bound":3942960.545298457,"upper_bound":40599452.444815636,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-2048","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[9793874282.0,9812736156.0,9774774984.0,9806655940.0,9814785847.0,9760039098.0,9782145302.0,9953902298.0,9952670090.0,9743042634.0],"unit":"ns","throughput":[],"typical":{"estimate":9819462663.1,"lower_bound":9780195676.0,"upper_bound":9866739850.905,"unit":"ns"},"mean":{"estimate":9819462663.1,"lower_bound":9780195676.0,"upper_bound":9866739850.905,"unit":"ns"},"median":{"estimate":9800265111.0,"lower_bound":9771092200.0,"upper_bound":9882703123.0,"unit":"ns"},"median_abs_dev":{"estimate":32328044.982862473,"lower_bound":6026699.952104688,"upper_bound":104040459.06961262,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-2048","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-2048","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[4743695773.0,4787874011.0,4769218668.0,4784923539.0,4775180771.0,4775166640.0,4774730516.0,4808915913.0,4775687578.0,4718787459.0],"unit":"ns","throughput":[],"typical":{"estimate":4771418086.8,"lower_bound":4756136408.9,"upper_bound":4784920327.7625,"unit":"ns"},"mean":{"estimate":4771418086.8,"lower_bound":4756136408.9,"upper_bound":4784920327.7625,"unit":"ns"},"median":{"estimate":4775173705.5,"lower_bound":4759213144.5,"upper_bound":4784923539.0,"unit":"ns"},"median_abs_dev":{"estimate":11642020.665612817,"lower_bound":344249.3356883526,"upper_bound":42169301.20304525,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-gen-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-gen-4096","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[5203851628.0,5146312789.0,5074780371.0,5118172672.0,5068301005.0,5134719973.0,5076463895.0,5118995165.0,5140392773.0,5147073455.0],"unit":"ns","throughput":[],"typical":{"estimate":5122906372.6,"lower_bound":5098935651.8275,"upper_bound":5147767270.925,"unit":"ns"},"mean":{"estimate":5122906372.6,"lower_bound":5098935651.8275,"upper_bound":5147767270.925,"unit":"ns"},"median":{"estimate":5126857569.0,"lower_bound":5076463895.0,"upper_bound":5146312789.0,"unit":"ns"},"median_abs_dev":{"estimate":29408190.355700254,"lower_bound":4803153.930526972,"upper_bound":84743199.49110746,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/proof-vfy-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/proof-vfy-4096","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[19475873521.0,19503423382.0,19433330958.0,19536076166.0,19457283593.0,19442172434.0,19552693909.0,19526049470.0,19385589840.0,19641292718.0],"unit":"ns","throughput":[],"typical":{"estimate":19495378599.1,"lower_bound":19454539715.89,"upper_bound":19539592549.7875,"unit":"ns"},"mean":{"estimate":19495378599.1,"lower_bound":19454539715.89,"upper_bound":19539592549.7875,"unit":"ns"},"median":{"estimate":19489648451.5,"lower_bound":19442172434.0,"upper_bound":19539371689.5,"unit":"ns"},"median_abs_dev":{"estimate":69610835.29576063,"lower_bound":17756088.010266423,"upper_bound":124356091.36583805,"unit":"ns"},"slope":null,"change":null} -{"reason":"benchmark-complete","id":"kzg-paillier/decryption-4096","report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier/decryption-4096","iteration_count":[1,1,1,1,1,1,1,1,1,1],"measured_values":[9619629203.0,9607744638.0,9630371825.0,9524445462.0,9551266834.0,9509064337.0,9546800686.0,9578859154.0,9548193833.0,9536202746.0],"unit":"ns","throughput":[],"typical":{"estimate":9565257871.8,"lower_bound":9541682552.4,"upper_bound":9590305961.7325,"unit":"ns"},"mean":{"estimate":9565257871.8,"lower_bound":9541682552.4,"upper_bound":9590305961.7325,"unit":"ns"},"median":{"estimate":9549730333.5,"lower_bound":9535623074.0,"upper_bound":9607744638.0,"unit":"ns"},"median_abs_dev":{"estimate":40336869.16347742,"lower_bound":4343495.306387544,"upper_bound":68882049.93529916,"unit":"ns"},"slope":null,"change":null} -{"reason":"group-complete","group_name":"kzg-paillier","benchmarks":["kzg-paillier/proof-gen-1","kzg-paillier/proof-vfy-1","kzg-paillier/decryption-1","kzg-paillier/proof-gen-2","kzg-paillier/proof-vfy-2","kzg-paillier/decryption-2","kzg-paillier/proof-gen-4","kzg-paillier/proof-vfy-4","kzg-paillier/decryption-4","kzg-paillier/proof-gen-8","kzg-paillier/proof-vfy-8","kzg-paillier/decryption-8","kzg-paillier/proof-gen-16","kzg-paillier/proof-vfy-16","kzg-paillier/decryption-16","kzg-paillier/proof-gen-32","kzg-paillier/proof-vfy-32","kzg-paillier/decryption-32","kzg-paillier/proof-gen-64","kzg-paillier/proof-vfy-64","kzg-paillier/decryption-64","kzg-paillier/proof-gen-128","kzg-paillier/proof-vfy-128","kzg-paillier/decryption-128","kzg-paillier/proof-gen-256","kzg-paillier/proof-vfy-256","kzg-paillier/decryption-256","kzg-paillier/proof-gen-512","kzg-paillier/proof-vfy-512","kzg-paillier/decryption-512","kzg-paillier/proof-gen-1024","kzg-paillier/proof-vfy-1024","kzg-paillier/decryption-1024","kzg-paillier/proof-gen-2048","kzg-paillier/proof-vfy-2048","kzg-paillier/decryption-2048","kzg-paillier/proof-gen-4096","kzg-paillier/proof-vfy-4096","kzg-paillier/decryption-4096"],"report_directory":"/data/codes/rust/fde/target/criterion/reports/kzg-paillier"}