From 6e3369d11cfd4ec751775e1eee82f8192b51943e Mon Sep 17 00:00:00 2001
From: Piotr Roslaniec
Date: Wed, 13 Mar 2024 09:56:44 +0100
Subject: [PATCH] feature!: remove fast variant
---
ferveo-tdec/benches/tpke.rs | 157 +-----------------------------
ferveo-tdec/src/ciphertext.rs | 5 +-
ferveo-tdec/src/combine.rs | 87 +----------------
ferveo-tdec/src/context.rs | 38 +-------
ferveo-tdec/src/decryption.rs | 155 +-----------------------------
ferveo-tdec/src/lib.rs | 175 +---------------------------------
ferveo/src/lib.rs | 2 +-
7 files changed, 18 insertions(+), 601 deletions(-)
diff --git a/ferveo-tdec/benches/tpke.rs b/ferveo-tdec/benches/tpke.rs
index 03711289..25672b70 100644
--- a/ferveo-tdec/benches/tpke.rs
+++ b/ferveo-tdec/benches/tpke.rs
@@ -1,14 +1,10 @@
#![allow(clippy::redundant_closure)]
use ark_bls12_381::{Bls12_381, Fr};
-use ark_ec::pairing::Pairing;
use criterion::{
black_box, criterion_group, criterion_main, BenchmarkId, Criterion,
};
-use ferveo_tdec::{
- test_common::{setup_fast, setup_simple},
- *,
-};
+use ferveo_tdec::{test_common::setup_simple, *};
use rand::prelude::StdRng;
use rand_core::{RngCore, SeedableRng};
@@ -16,7 +12,6 @@ const NUM_SHARES_CASES: [usize; 5] = [4, 8, 16, 32, 64];
const MSG_SIZE_CASES: [usize; 7] = [256, 512, 1024, 2048, 4096, 8192, 16384];
type E = Bls12_381;
-type G2Prepared = ::G2Prepared;
#[allow(dead_code)]
#[derive(Clone)]
@@ -31,63 +26,6 @@ struct SetupShared {
shared_secret: SharedSecret,
}
-#[derive(Clone)]
-struct SetupFast {
- shared: SetupShared,
- contexts: Vec>,
- pub_contexts: Vec>,
- decryption_shares: Vec>,
- prepared_key_shares: Vec,
-}
-
-impl SetupFast {
- pub fn new(shares_num: usize, msg_size: usize, rng: &mut StdRng) -> Self {
- let threshold = shares_num * 2 / 3;
- let mut msg: Vec = vec![0u8; msg_size];
- rng.fill_bytes(&mut msg[..]);
- let aad: &[u8] = "my-aad".as_bytes();
-
- let (pubkey, privkey, contexts) =
- setup_fast::(threshold, shares_num, rng);
- let ciphertext =
- encrypt::(SecretBox::new(msg.clone()), aad, &pubkey, rng)
- .unwrap();
-
- let mut decryption_shares: Vec> = vec![];
- for context in contexts.iter() {
- decryption_shares
- .push(context.create_share(&ciphertext, aad).unwrap());
- }
-
- let pub_contexts = contexts[0].clone().public_decryption_contexts;
- let prepared_key_shares =
- prepare_combine_fast(&pub_contexts, &decryption_shares);
-
- let shared_secret = share_combine_fast_unchecked(
- &decryption_shares,
- &prepared_key_shares,
- );
-
- let shared = SetupShared {
- threshold,
- shares_num,
- msg: msg.to_vec(),
- aad: aad.to_vec(),
- pubkey,
- privkey,
- ciphertext,
- shared_secret,
- };
- Self {
- shared,
- contexts,
- pub_contexts,
- decryption_shares,
- prepared_key_shares,
- }
- }
-}
-
#[derive(Clone)]
struct SetupSimple {
shared: SetupShared,
@@ -158,25 +96,6 @@ pub fn bench_create_decryption_share(c: &mut Criterion) {
let msg_size = MSG_SIZE_CASES[0];
for shares_num in NUM_SHARES_CASES {
- let fast = {
- let setup = SetupFast::new(shares_num, msg_size, rng);
- move || {
- black_box({
- // TODO: Consider running benchmarks for a single iteration and not for all iterations.
- // This way we could test the performance of this method for a single participant.
- setup
- .contexts
- .iter()
- .map(|ctx| {
- ctx.create_share(
- &setup.shared.ciphertext,
- &setup.shared.aad,
- )
- })
- .collect::>()
- })
- }
- };
let simple = {
let setup = SetupSimple::new(shares_num, msg_size, rng);
move || {
@@ -218,11 +137,6 @@ pub fn bench_create_decryption_share(c: &mut Criterion) {
);
}
};
-
- group.bench_function(
- BenchmarkId::new("share_create_fast", shares_num),
- |b| b.iter(|| fast()),
- );
group.bench_function(
BenchmarkId::new("share_create_simple", shares_num),
|b| b.iter(|| simple()),
@@ -242,26 +156,12 @@ pub fn bench_share_prepare(c: &mut Criterion) {
let msg_size = MSG_SIZE_CASES[0];
for shares_num in NUM_SHARES_CASES {
- let fast = {
- let setup = SetupFast::new(shares_num, msg_size, rng);
- move || {
- black_box(prepare_combine_fast(
- &setup.pub_contexts,
- &setup.decryption_shares,
- ))
- }
- };
let simple = {
let setup = SetupSimple::new(shares_num, msg_size, rng);
let domain: Vec =
setup.pub_contexts.iter().map(|c| c.domain).collect();
move || black_box(prepare_combine_simple::(&domain))
};
-
- group.bench_function(
- BenchmarkId::new("share_prepare_fast", shares_num),
- |b| b.iter(|| fast()),
- );
group.bench_function(
BenchmarkId::new("share_prepare_simple", shares_num),
|b| b.iter(|| simple()),
@@ -278,15 +178,6 @@ pub fn bench_share_combine(c: &mut Criterion) {
let msg_size = MSG_SIZE_CASES[0];
for shares_num in NUM_SHARES_CASES {
- let fast = {
- let setup = SetupFast::new(shares_num, msg_size, rng);
- move || {
- black_box(share_combine_fast_unchecked(
- &setup.decryption_shares,
- &setup.prepared_key_shares,
- ));
- }
- };
let simple = {
let setup = SetupSimple::new(shares_num, msg_size, rng);
move || {
@@ -320,10 +211,6 @@ pub fn bench_share_combine(c: &mut Criterion) {
}
};
- group.bench_function(
- BenchmarkId::new("share_combine_fast", shares_num),
- |b| b.iter(|| fast()),
- );
group.bench_function(
BenchmarkId::new("share_combine_simple", shares_num),
|b| b.iter(|| simple()),
@@ -345,7 +232,7 @@ pub fn bench_share_encrypt_decrypt(c: &mut Criterion) {
for msg_size in MSG_SIZE_CASES {
let mut encrypt = {
let mut rng = rng.clone();
- let setup = SetupFast::new(shares_num, msg_size, &mut rng);
+ let setup = SetupSimple::new(shares_num, msg_size, &mut rng);
move || {
let setup = setup.clone();
black_box(
@@ -393,7 +280,7 @@ pub fn bench_ciphertext_validity_checks(c: &mut Criterion) {
for msg_size in MSG_SIZE_CASES {
let ciphertext_verification = {
let mut rng = rng.clone();
- let setup = SetupFast::new(shares_num, msg_size, &mut rng);
+ let setup = SetupSimple::new(shares_num, msg_size, &mut rng);
move || {
black_box(setup.shared.ciphertext.check(
&setup.shared.aad,
@@ -417,44 +304,6 @@ pub fn bench_decryption_share_validity_checks(c: &mut Criterion) {
let msg_size = MSG_SIZE_CASES[0];
for shares_num in NUM_SHARES_CASES {
- let share_fast_verification = {
- let mut rng = rng.clone();
- let setup = SetupFast::new(shares_num, msg_size, &mut rng);
- move || {
- black_box(verify_decryption_shares_fast(
- &setup.pub_contexts,
- &setup.shared.ciphertext,
- &setup.decryption_shares,
- ))
- }
- };
- group.bench_function(
- BenchmarkId::new("share_fast_verification", shares_num),
- |b| b.iter(|| share_fast_verification()),
- );
-
- let mut share_fast_batch_verification = {
- let mut rng = rng.clone();
- let setup = SetupFast::new(shares_num, msg_size, &mut rng);
- // We need to repackage a bunch of variables here to avoid borrowing issues:
- let ciphertext = setup.shared.ciphertext.clone();
- let ciphertexts = vec![ciphertext];
- let decryption_shares = setup.decryption_shares.clone();
- let decryption_shares = vec![decryption_shares];
- move || {
- black_box(batch_verify_decryption_shares(
- &setup.pub_contexts,
- &ciphertexts,
- &decryption_shares,
- &mut rng,
- ))
- }
- };
- group.bench_function(
- BenchmarkId::new("share_fast_batch_verification", shares_num),
- |b| b.iter(|| share_fast_batch_verification()),
- );
-
let share_simple_verification = {
let mut rng = rng.clone();
let setup = SetupSimple::new(shares_num, msg_size, &mut rng);
diff --git a/ferveo-tdec/src/ciphertext.rs b/ferveo-tdec/src/ciphertext.rs
index 57b6ca13..6d33946c 100644
--- a/ferveo-tdec/src/ciphertext.rs
+++ b/ferveo-tdec/src/ciphertext.rs
@@ -261,7 +261,7 @@ mod tests {
let aad: &[u8] = "my-aad".as_bytes();
let (pubkey, privkey, contexts) =
- setup_fast::(threshold, shares_num, rng);
+ setup_simple::(threshold, shares_num, rng);
let g_inv = &contexts[0].setup_params.g_inv;
let ciphertext =
@@ -285,7 +285,8 @@ mod tests {
let threshold = shares_num * 2 / 3;
let msg = "my-msg".as_bytes().to_vec();
let aad: &[u8] = "my-aad".as_bytes();
- let (pubkey, _, contexts) = setup_fast::(threshold, shares_num, rng);
+ let (pubkey, _, contexts) =
+ setup_simple::(threshold, shares_num, rng);
let g_inv = contexts[0].setup_params.g_inv.clone();
let mut ciphertext =
encrypt::(SecretBox::new(msg), aad, &pubkey, rng).unwrap();
diff --git a/ferveo-tdec/src/combine.rs b/ferveo-tdec/src/combine.rs
index a46477fb..d04bc55f 100644
--- a/ferveo-tdec/src/combine.rs
+++ b/ferveo-tdec/src/combine.rs
@@ -1,14 +1,11 @@
#![allow(non_snake_case)]
-use std::ops::Mul;
-
-use ark_ec::{pairing::Pairing, CurveGroup};
+use ark_ec::pairing::Pairing;
use ark_ff::{Field, One, PrimeField, Zero};
use ferveo_common::serialization;
use itertools::izip;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
-use subproductdomain::SubproductDomain;
use zeroize::{Zeroize, ZeroizeOnDrop};
#[serde_as]
@@ -19,42 +16,7 @@ pub struct SharedSecret(
#[serde_as(as = "serialization::SerdeAs")] pub(crate) E::TargetField,
);
-use crate::{
- verify_decryption_shares_fast, Ciphertext, DecryptionShareFast,
- DecryptionSharePrecomputed, DecryptionShareSimple, Error,
- PublicDecryptionContextFast, Result,
-};
-
-pub fn prepare_combine_fast(
- public_decryption_contexts: &[PublicDecryptionContextFast],
- shares: &[DecryptionShareFast],
-) -> Vec {
- let mut domain = vec![]; // omega_i, vector of domain points
- let mut n_0 = E::ScalarField::one();
- for d_i in shares.iter() {
- domain.push(public_decryption_contexts[d_i.decrypter_index].domain);
- // n_0_i = 1 * t^1 * t^2 ...
- n_0 *= public_decryption_contexts[d_i.decrypter_index].lagrange_n_0;
- }
- let s = SubproductDomain::::new(domain);
- let mut lagrange = s.inverse_lagrange_coefficients(); // 1/L_i
-
- // Given a vector of field elements {v_i}, compute the vector {coeff * v_i^(-1)}
- ark_ff::batch_inversion_and_mul(&mut lagrange, &n_0); // n_0 * L_i
-
- // L_i * [b]Z_i
- izip!(shares.iter(), lagrange.iter())
- .map(|(d_i, lambda)| {
- let decrypter = &public_decryption_contexts[d_i.decrypter_index];
- let blinded_key_share =
- decrypter.blinded_key_share.blinded_key_share;
- E::G2Prepared::from(
- // [b]Z_i * L_i
- blinded_key_share.mul(*lambda).into_affine(),
- )
- })
- .collect::>()
-}
+use crate::{DecryptionSharePrecomputed, DecryptionShareSimple};
pub fn prepare_combine_simple(
domain: &[E::ScalarField],
@@ -82,51 +44,6 @@ pub fn lagrange_basis_at(
lagrange_coeffs
}
-// TODO: Hide this from external users. Currently blocked by usage in benchmarks.
-pub fn share_combine_fast_unchecked(
- shares: &[DecryptionShareFast],
- prepared_key_shares: &[E::G2Prepared],
-) -> SharedSecret {
- let mut pairing_a = vec![];
- let mut pairing_b = vec![];
-
- for (d_i, prepared_key_share) in izip!(shares, prepared_key_shares.iter()) {
- pairing_a.push(
- // D_i
- E::G1Prepared::from(d_i.decryption_share),
- );
- pairing_b.push(
- // Z_{i,omega_i}) = [dk_{i}^{-1}]*\hat{Y}_{i_omega_j}]
- // Reference: https://nikkolasg.github.io/ferveo/pvss.html#validator-decryption-of-private-key-shares
- // Prepared key share is a sum of L_i * [b]Z_i
- prepared_key_share.clone(),
- );
- }
- // e(D_i, [b*omega_i^-1] Z_{i,omega_i})
- let shared_secret = E::multi_pairing(pairing_a, pairing_b).0;
- SharedSecret(shared_secret)
-}
-
-pub fn share_combine_fast(
- pub_contexts: &[PublicDecryptionContextFast],
- ciphertext: &Ciphertext,
- decryption_shares: &[DecryptionShareFast],
- prepared_key_shares: &[E::G2Prepared],
-) -> Result> {
- let is_valid_shares = verify_decryption_shares_fast(
- pub_contexts,
- ciphertext,
- decryption_shares,
- );
- if !is_valid_shares {
- return Err(Error::DecryptionShareVerificationFailed);
- }
- Ok(share_combine_fast_unchecked(
- decryption_shares,
- prepared_key_shares,
- ))
-}
-
pub fn share_combine_simple(
decryption_shares: &[DecryptionShareSimple],
lagrange_coeffs: &[E::ScalarField],
diff --git a/ferveo-tdec/src/context.rs b/ferveo-tdec/src/context.rs
index ba697917..4bfb81fb 100644
--- a/ferveo-tdec/src/context.rs
+++ b/ferveo-tdec/src/context.rs
@@ -1,11 +1,9 @@
-use std::ops::Mul;
-
-use ark_ec::{pairing::Pairing, CurveGroup};
+use ark_ec::pairing::Pairing;
use crate::{
- prepare_combine_simple, BlindedKeyShare, Ciphertext, CiphertextHeader,
- DecryptionShareFast, DecryptionSharePrecomputed, DecryptionShareSimple,
- PrivateKeyShare, PublicKey, Result,
+ prepare_combine_simple, BlindedKeyShare, CiphertextHeader,
+ DecryptionSharePrecomputed, DecryptionShareSimple, PrivateKeyShare,
+ PublicKey, Result,
};
#[derive(Clone, Debug)]
@@ -37,34 +35,6 @@ pub struct SetupParams {
pub h: E::G2Affine,
}
-#[derive(Clone, Debug)]
-pub struct PrivateDecryptionContextFast {
- pub index: usize,
- pub setup_params: SetupParams,
- pub private_key_share: PrivateKeyShare,
- pub public_decryption_contexts: Vec>,
-}
-
-impl PrivateDecryptionContextFast {
- pub fn create_share(
- &self,
- ciphertext: &Ciphertext,
- aad: &[u8],
- ) -> Result> {
- ciphertext.check(aad, &self.setup_params.g_inv)?;
-
- let decryption_share = ciphertext
- .commitment
- .mul(self.setup_params.b_inv)
- .into_affine();
-
- Ok(DecryptionShareFast {
- decrypter_index: self.index,
- decryption_share,
- })
- }
-}
-
#[derive(Clone, Debug)]
pub struct PrivateDecryptionContextSimple {
pub index: usize,
diff --git a/ferveo-tdec/src/decryption.rs b/ferveo-tdec/src/decryption.rs
index dec3ed78..7c199fde 100644
--- a/ferveo-tdec/src/decryption.rs
+++ b/ferveo-tdec/src/decryption.rs
@@ -1,27 +1,17 @@
use std::ops::Mul;
use ark_ec::{pairing::Pairing, CurveGroup};
-use ark_ff::{Field, One, Zero};
-use ark_std::UniformRand;
+use ark_ff::Field;
use ferveo_common::serialization;
-use itertools::{izip, zip_eq};
-use rand_core::RngCore;
+use itertools::izip;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_with::serde_as;
use crate::{
- Ciphertext, CiphertextHeader, PrivateKeyShare, PublicDecryptionContextFast,
+ Ciphertext, CiphertextHeader, PrivateKeyShare,
PublicDecryptionContextSimple, Result,
};
-#[serde_as]
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct DecryptionShareFast {
- pub decrypter_index: usize,
- #[serde_as(as = "serialization::SerdeAs")]
- pub decryption_share: E::G1Affine,
-}
-
#[serde_as]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ValidatorShareChecksum {
@@ -230,122 +220,6 @@ impl DecryptionSharePrecomputed {
}
}
-pub fn generate_random_scalars(
- n: usize,
- rng: &mut R,
-) -> Vec {
- (0..n)
- .map(|_| E::ScalarField::rand(rng))
- .collect::>()
-}
-
-// TODO: Remove this code? Currently only used in benchmarks. Move to benchmark suite?
-pub fn batch_verify_decryption_shares(
- pub_contexts: &[PublicDecryptionContextFast],
- ciphertexts: &[Ciphertext],
- decryption_shares: &[Vec>],
- rng: &mut R,
-) -> bool {
- let num_ciphertexts = ciphertexts.len();
- let num_shares = decryption_shares[0].len();
-
- // Get [b_i] H for each of the decryption shares
- let blinding_keys = decryption_shares[0]
- .iter()
- .map(|d| {
- E::G2Prepared::from(
- pub_contexts[d.decrypter_index]
- .blinded_key_share
- .blinding_key,
- )
- })
- .collect::>();
-
- // For each ciphertext, generate num_shares random scalars
- let alpha_ij = (0..num_ciphertexts)
- .map(|_| generate_random_scalars::<_, E>(num_shares, rng))
- .collect::>();
-
- let mut pairings_a = Vec::with_capacity(num_shares + 1);
- let mut pairings_b = Vec::with_capacity(num_shares + 1);
-
- // Compute \sum_j \alpha_{i,j} for each ciphertext i
- let sum_alpha_i = alpha_ij
- .iter()
- .map(|alpha_j| alpha_j.iter().sum::())
- .collect::>();
-
- // Compute \sum_i [ \sum_j \alpha_{i,j} ] U_i
- let sum_u_i = E::G1Prepared::from(
- izip!(ciphertexts.iter(), sum_alpha_i.iter())
- .map(|(c, alpha_j)| c.commitment.mul(*alpha_j))
- .sum::()
- .into_affine(),
- );
-
- // e(\sum_i [ \sum_j \alpha_{i,j} ] U_i, -H)
- pairings_a.push(sum_u_i);
- pairings_b.push(pub_contexts[0].h_inv.clone());
-
- let mut sum_d_i = vec![E::G1::zero(); num_shares];
-
- // sum_D_i = { [\sum_i \alpha_{i,j} ] D_i }
- for (d, alpha_j) in izip!(decryption_shares.iter(), alpha_ij.iter()) {
- for (sum_alpha_d_i, d_ij, alpha) in
- izip!(sum_d_i.iter_mut(), d.iter(), alpha_j.iter())
- {
- *sum_alpha_d_i += d_ij.decryption_share.mul(*alpha);
- }
- }
-
- // e([\sum_i \alpha_{i,j} ] D_i, B_i)
- for (d_i, b_i) in izip!(sum_d_i.iter(), blinding_keys.iter()) {
- pairings_a.push(E::G1Prepared::from(d_i.into_affine()));
- pairings_b.push(b_i.clone());
- }
-
- E::multi_pairing(pairings_a, pairings_b).0 == E::TargetField::one()
-}
-
-pub fn verify_decryption_shares_fast(
- pub_contexts: &[PublicDecryptionContextFast],
- ciphertext: &Ciphertext,
- decryption_shares: &[DecryptionShareFast],
-) -> bool {
- // [b_i] H
- let blinding_keys = decryption_shares
- .iter()
- .map(|d| {
- E::G2Prepared::from(
- pub_contexts[d.decrypter_index]
- .blinded_key_share
- .blinding_key,
- )
- })
- .collect::>();
-
- let mut pairing_a: Vec = vec![];
- let mut pairing_b = vec![];
-
- // e(U, -H)
- pairing_a.push(ciphertext.commitment.into());
- pairing_b.push(pub_contexts[0].h_inv.clone());
-
- for (d_i, p_i) in zip_eq(decryption_shares, blinding_keys) {
- let mut pairing_a_i = pairing_a.clone();
- let mut pairing_b_i = pairing_b.clone();
- // e(D_i, B_i)
- pairing_a_i.push(d_i.decryption_share.into());
- pairing_b_i.push(p_i.clone());
- if E::multi_pairing(pairing_a_i, pairing_b_i).0 != E::TargetField::one()
- {
- return false;
- }
- }
-
- true
-}
-
pub fn verify_decryption_shares_simple(
pub_contexts: &Vec>,
ciphertext: &Ciphertext,
@@ -370,26 +244,3 @@ pub fn verify_decryption_shares_simple(
}
true
}
-
-#[cfg(test)]
-mod tests {
- use ark_ec::AffineRepr;
- use ferveo_common::{FromBytes, ToBytes};
-
- use crate::*;
-
- type E = ark_bls12_381::Bls12_381;
-
- #[test]
- fn decryption_share_serialization() {
- let decryption_share = DecryptionShareFast:: {
- decrypter_index: 1,
- decryption_share: ark_bls12_381::G1Affine::generator(),
- };
-
- let serialized = decryption_share.to_bytes().unwrap();
- let deserialized: DecryptionShareFast =
- DecryptionShareFast::from_bytes(&serialized).unwrap();
- assert_eq!(serialized, deserialized.to_bytes().unwrap())
- }
-}
diff --git a/ferveo-tdec/src/lib.rs b/ferveo-tdec/src/lib.rs
index e0086dbf..e41ff704 100644
--- a/ferveo-tdec/src/lib.rs
+++ b/ferveo-tdec/src/lib.rs
@@ -61,119 +61,16 @@ pub mod test_common {
pub use ark_bls12_381::Bls12_381 as EllipticCurve;
use ark_ec::{pairing::Pairing, AffineRepr};
pub use ark_ff::UniformRand;
- use ark_ff::{Field, One, Zero};
+ use ark_ff::{Field, Zero};
use ark_poly::{
univariate::DensePolynomial, DenseUVPolynomial, EvaluationDomain,
Polynomial,
};
use itertools::izip;
- use rand_core::RngCore;
use subproductdomain::fast_multiexp;
pub use super::*;
- pub fn setup_fast(
- threshold: usize,
- shares_num: usize,
- rng: &mut impl RngCore,
- ) -> (
- PublicKey,
- PrivateKeyShare,
- Vec>,
- ) {
- assert!(shares_num >= threshold);
-
- // Generators G∈G1, H∈G2
- let g = E::G1Affine::generator();
- let h = E::G2Affine::generator();
-
- // The dealer chooses a uniformly random polynomial f of degree t-1
- let threshold_poly =
- DensePolynomial::::rand(threshold - 1, rng);
- // Domain, or omega Ω
- let fft_domain =
- ark_poly::GeneralEvaluationDomain::::new(
- shares_num,
- )
- .unwrap();
- // `evals` are evaluations of the polynomial f over the domain, omega: f(ω_j) for ω_j in Ω
- let evals = threshold_poly.evaluate_over_domain_by_ref(fft_domain);
-
- // A - public key shares of participants
- let pubkey_shares = fast_multiexp(&evals.evals, g.into_group());
- let pubkey_share = g.mul(evals.evals[0]);
- debug_assert!(pubkey_shares[0] == E::G1Affine::from(pubkey_share));
-
- // Y, but only when b = 1 - private key shares of participants
- let privkey_shares = fast_multiexp(&evals.evals, h.into_group());
-
- // a_0
- let x = threshold_poly.coeffs[0];
-
- // F_0 - The commitment to the constant term, and is the public key output Y from PVDKG
- let pubkey = g.mul(x);
- let privkey = h.mul(x);
-
- let mut domain_points = Vec::with_capacity(shares_num);
- let mut point = E::ScalarField::one();
- let mut domain_points_inv = Vec::with_capacity(shares_num);
- let mut point_inv = E::ScalarField::one();
-
- for _ in 0..shares_num {
- domain_points.push(point); // 1, t, t^2, t^3, ...; where t is a scalar generator fft_domain.group_gen
- point *= fft_domain.group_gen();
- domain_points_inv.push(point_inv);
- point_inv *= fft_domain.group_gen_inv();
- }
-
- let mut private_contexts = vec![];
- let mut public_contexts = vec![];
-
- // (domain, domain_inv, A, Y)
- for (index, (domain, domain_inv, public, private)) in izip!(
- domain_points.iter(),
- domain_points_inv.iter(),
- pubkey_shares.iter(),
- privkey_shares.iter()
- )
- .enumerate()
- {
- let private_key_share = PrivateKeyShare(*private);
- let b = E::ScalarField::rand(rng);
- let mut blinded_key_shares = private_key_share.blind(b);
- blinded_key_shares.multiply_by_omega_inv(domain_inv);
- private_contexts.push(PrivateDecryptionContextFast:: {
- index,
- setup_params: SetupParams {
- b,
- b_inv: b.inverse().unwrap(),
- g,
- h_inv: E::G2Prepared::from(-h.into_group()),
- g_inv: E::G1Prepared::from(-g.into_group()),
- h,
- },
- private_key_share,
- public_decryption_contexts: vec![],
- });
- public_contexts.push(PublicDecryptionContextFast:: {
- domain: *domain,
- public_key: PublicKey::(*public),
- blinded_key_share: blinded_key_shares,
- lagrange_n_0: *domain,
- h_inv: E::G2Prepared::from(-h.into_group()),
- });
- }
- for private in private_contexts.iter_mut() {
- private.public_decryption_contexts = public_contexts.clone();
- }
-
- (
- PublicKey(pubkey.into()),
- PrivateKeyShare(privkey.into()),
- private_contexts,
- )
- }
-
pub fn setup_simple(
shares_num: usize,
threshold: usize,
@@ -183,8 +80,6 @@ pub mod test_common {
PrivateKeyShare,
Vec>,
) {
- assert!(shares_num >= threshold);
-
let g = E::G1Affine::generator();
let h = E::G2Affine::generator();
@@ -310,7 +205,7 @@ mod tests {
let msg = "my-msg".as_bytes().to_vec();
let aad: &[u8] = "my-aad".as_bytes();
- let (pubkey, _, _) = setup_fast::(threshold, shares_num, rng);
+ let (pubkey, _, _) = setup_simple::(threshold, shares_num, rng);
let ciphertext =
encrypt::(SecretBox::new(msg), aad, &pubkey, rng).unwrap();
@@ -357,22 +252,6 @@ mod tests {
.is_err());
}
- #[test]
- fn tdec_fast_variant_share_validation() {
- let rng = &mut test_rng();
- let shares_num = 16;
- let threshold = shares_num * 2 / 3;
- let msg = "my-msg".as_bytes().to_vec();
- let aad: &[u8] = "my-aad".as_bytes();
-
- let (pubkey, _, contexts) = setup_fast::(threshold, shares_num, rng);
- let ciphertext =
- encrypt::(SecretBox::new(msg), aad, &pubkey, rng).unwrap();
-
- let bad_aad = "bad aad".as_bytes();
- assert!(contexts[0].create_share(&ciphertext, bad_aad).is_err());
- }
-
#[test]
fn tdec_simple_variant_share_validation() {
let rng = &mut test_rng();
@@ -392,56 +271,6 @@ mod tests {
.is_err());
}
- #[test]
- fn tdec_fast_variant_e2e() {
- let mut rng = &mut test_rng();
- let shares_num = 16;
- let threshold = shares_num * 2 / 3;
- let msg = "my-msg".as_bytes().to_vec();
- let aad: &[u8] = "my-aad".as_bytes();
-
- let (pubkey, _, contexts) =
- setup_fast::(threshold, shares_num, &mut rng);
- let ciphertext =
- encrypt::(SecretBox::new(msg.clone()), aad, &pubkey, rng)
- .unwrap();
- let g_inv = &contexts[0].setup_params.g_inv;
-
- let mut decryption_shares: Vec> = vec![];
- for context in contexts.iter() {
- decryption_shares
- .push(context.create_share(&ciphertext, aad).unwrap());
- }
-
- // TODO: Verify and enable this check
- /*for pub_context in contexts[0].public_decryption_contexts.iter() {
- assert!(pub_context
- .blinded_key_shares
- .verify_blinding(&pub_context.public_key_shares, rng));
- }*/
-
- let prepared_blinded_key_shares = prepare_combine_fast(
- &contexts[0].public_decryption_contexts,
- &decryption_shares,
- );
-
- let shared_secret = share_combine_fast(
- &contexts[0].public_decryption_contexts,
- &ciphertext,
- &decryption_shares,
- &prepared_blinded_key_shares,
- )
- .unwrap();
-
- test_ciphertext_validation_fails(
- &msg,
- aad,
- &ciphertext,
- &shared_secret,
- g_inv,
- );
- }
-
#[test]
fn tdec_simple_variant_e2e() {
let mut rng = &mut test_rng();
diff --git a/ferveo/src/lib.rs b/ferveo/src/lib.rs
index e3638fe6..8ee00941 100644
--- a/ferveo/src/lib.rs
+++ b/ferveo/src/lib.rs
@@ -72,7 +72,7 @@ pub enum Error {
#[error("Invalid variant: {0}")]
InvalidVariant(String),
- /// DKG parameters validaiton failed
+ /// DKG parameters validation failed
#[error("Invalid DKG parameters: number of shares {0}, threshold {1}")]
InvalidDkgParameters(u32, u32),