From 935be2dc056a8d295fff8c2e937fc23f8fa80f7e Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 25 Jan 2024 14:26:19 +0100 Subject: [PATCH] refactor(validator): replace dkg validator with validator --- ferveo/examples/bench_primitives_size.rs | 5 +- ferveo/src/api.rs | 7 +- ferveo/src/dkg.rs | 87 +++++++++--------------- ferveo/src/lib.rs | 20 +++--- ferveo/src/pvss.rs | 22 ++---- ferveo/src/test_common.rs | 2 +- 6 files changed, 56 insertions(+), 87 deletions(-) diff --git a/ferveo/examples/bench_primitives_size.rs b/ferveo/examples/bench_primitives_size.rs index 8f993c36..d44d394c 100644 --- a/ferveo/examples/bench_primitives_size.rs +++ b/ferveo/examples/bench_primitives_size.rs @@ -96,14 +96,13 @@ fn setup( for i in 0..shares_num { let mut dkg = setup_dkg(i as usize, shares_num, security_threshold); let message = dkg.share(rng).expect("Test failed"); - let sender = dkg.get_validator(&dkg.me.validator.public_key).unwrap(); + let sender = dkg.get_validator(&dkg.me.public_key).unwrap(); transcripts.push((sender.clone(), message.clone())); } let mut dkg = setup_dkg(0, shares_num, security_threshold); for (sender, pvss) in transcripts.into_iter() { - dkg.apply_message(&sender.validator, &pvss) - .expect("Setup failed"); + dkg.apply_message(&sender, &pvss).expect("Setup failed"); } dkg } diff --git a/ferveo/src/api.rs b/ferveo/src/api.rs index b8c0febf..26da8c57 100644 --- a/ferveo/src/api.rs +++ b/ferveo/src/api.rs @@ -327,7 +327,7 @@ impl AggregatedTranscript { &ciphertext_header.0, aad, &validator_keypair.decryption_key, - dkg.0.me.share_index, + dkg.0.me.share_index as usize, &domain_points, &dkg.0.pvss_params.g_inv(), ) @@ -344,12 +344,13 @@ impl AggregatedTranscript { &ciphertext_header.0, aad, &validator_keypair.decryption_key, - dkg.0.me.share_index, + dkg.0.me.share_index as usize, &dkg.0.pvss_params.g_inv(), )?; + let domain_point = dkg.0.domain.element(dkg.0.me.share_index as usize); Ok(DecryptionShareSimple { share, - domain_point: dkg.0.domain.element(dkg.0.me.share_index), + domain_point, }) } } diff --git a/ferveo/src/dkg.rs b/ferveo/src/dkg.rs index e5615d05..f3c0dc15 100644 --- a/ferveo/src/dkg.rs +++ b/ferveo/src/dkg.rs @@ -1,6 +1,6 @@ -use std::{cmp::Ordering, collections::BTreeMap}; +use std::collections::BTreeMap; -use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup, Group}; +use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup}; use ark_poly::EvaluationDomain; use ferveo_common::PublicKey; use measure_time::print_time; @@ -62,35 +62,27 @@ impl DkgParams { } } -#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] -pub struct DkgValidator { - pub validator: Validator, - pub share_index: usize, -} - -impl PartialOrd for DkgValidator { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for DkgValidator { - fn cmp(&self, other: &Self) -> Ordering { - self.share_index.cmp(&other.share_index) - } -} - -pub type ValidatorsMap = BTreeMap>; +pub type ValidatorsMap = BTreeMap>; pub type PVSSMap = BTreeMap>; #[derive(Debug, Clone)] pub enum DkgState { + // TODO: Do we need to keep track of the block number? Sharing { accumulated_shares: u32, block: u32 }, Dealt, Success { public_key: E::G1Affine }, Invalid, } +impl DkgState { + fn new() -> Self { + DkgState::Sharing { + accumulated_shares: 0, + block: 0, + } + } +} + /// The DKG context that holds all of the local state for participating in the DKG // TODO: Consider removing Clone to avoid accidentally NOT-mutating state. // Currently, we're assuming that the DKG is only mutated by the owner of the instance. @@ -102,7 +94,7 @@ pub struct PubliclyVerifiableDkg { pub validators: ValidatorsMap, pub vss: PVSSMap, pub domain: ark_poly::GeneralEvaluationDomain, - pub me: DkgValidator, + pub me: Validator, pub state: DkgState, } @@ -128,20 +120,14 @@ impl PubliclyVerifiableDkg { let validators: ValidatorsMap = validators .iter() .enumerate() - .map(|(validator_index, validator)| { - ( - validator.address.clone(), - DkgValidator { - validator: validator.clone(), - share_index: validator_index, - }, - ) + .map(|(_validator_index, validator)| { + (validator.address.clone(), validator.clone()) }) .collect(); // Make sure that `me` is a known validator if let Some(my_validator) = validators.get(&me.address) { - if my_validator.validator.public_key != me.public_key { + if my_validator.public_key != me.public_key { return Err(Error::ValidatorPublicKeyMismatch); } } else { @@ -150,32 +136,22 @@ impl PubliclyVerifiableDkg { Ok(Self { dkg_params: *dkg_params, - pvss_params: PubliclyVerifiableParams:: { - g: E::G1::generator(), - h: E::G2::generator(), - }, - vss: BTreeMap::new(), + pvss_params: PubliclyVerifiableParams::::default(), + vss: PVSSMap::::new(), domain, - me: DkgValidator { - validator: me.clone(), - share_index: validators[&me.address].share_index, - }, + me: me.clone(), validators, - state: DkgState::Sharing { - accumulated_shares: 0, - // TODO: Do we need to keep track of the block number? - block: 0, - }, + state: DkgState::new(), }) } pub fn get_validator( &self, public_key: &PublicKey, - ) -> Option<&DkgValidator> { + ) -> Option<&Validator> { self.validators .values() - .find(|validator| &validator.validator.public_key == public_key) + .find(|validator| &validator.public_key == public_key) } /// Create a new PVSS instance within this DKG session, contributing to the final key @@ -414,7 +390,7 @@ mod test_dealing { for i in 0..dkg.dkg_params.shares_num() { let (mut dkg, _) = setup_dkg(i as usize); let message = dkg.share(rng).unwrap(); - let sender = dkg.me.validator.clone(); + let sender = dkg.me.clone(); messages.push((sender, message)); } @@ -497,7 +473,7 @@ mod test_dealing { let pvss = dkg.share(rng).unwrap(); // This validator has already sent a PVSS - let sender = dkg.me.validator.clone(); + let sender = dkg.me.clone(); // First PVSS is accepted assert!(dkg.verify_message(&sender, &pvss).is_ok()); @@ -540,7 +516,7 @@ mod test_dealing { } )); - let sender = dkg.me.validator.clone(); + let sender = dkg.me.clone(); // Sender verifies it's own PVSS transcript assert!(dkg.verify_message(&sender, &pvss).is_ok()); @@ -594,8 +570,7 @@ mod test_dealing { } )); - let sender = dkg.me.validator.clone(); - + let sender = dkg.me.clone(); dkg.state = DkgState::Success { public_key: G1::zero(), }; @@ -623,7 +598,7 @@ mod test_aggregation { fn test_aggregate() { let (mut dkg, _) = setup_dealt_dkg(); let aggregate = dkg.aggregate().unwrap(); - let sender = dkg.me.validator.clone(); + let sender = dkg.me.clone(); assert!(dkg.verify_message(&sender, &aggregate).is_ok()); assert!(dkg.apply_message(&sender, &aggregate).is_ok()); assert!(matches!(dkg.state, DkgState::Success { .. })); @@ -652,7 +627,7 @@ mod test_aggregation { fn test_aggregate_message_state_guards() { let (mut dkg, _) = setup_dealt_dkg(); let aggregate = dkg.aggregate().unwrap(); - let sender = dkg.me.validator.clone(); + let sender = dkg.me.clone(); dkg.state = DkgState::Sharing { accumulated_shares: 0, @@ -675,7 +650,7 @@ mod test_aggregation { let (mut dkg, _) = setup_dealt_dkg(); dkg.dkg_params.shares_num = 10; let aggregate = dkg.aggregate().unwrap(); - let sender = dkg.me.validator.clone(); + let sender = dkg.me.clone(); assert!(dkg.verify_message(&sender, &aggregate).is_err()); } @@ -693,7 +668,7 @@ mod test_aggregation { { *public_key = G1::zero(); } - let sender = dkg.me.validator.clone(); + let sender = dkg.me.clone(); assert!(dkg.verify_message(&sender, &aggregate).is_err()); } } diff --git a/ferveo/src/lib.rs b/ferveo/src/lib.rs index 0db10105..0ca9252e 100644 --- a/ferveo/src/lib.rs +++ b/ferveo/src/lib.rs @@ -177,7 +177,7 @@ mod test_dkg_full { ciphertext_header, aad, &validator_keypair.decryption_key, - validator.share_index, + validator.share_index as usize, &dkg.pvss_params.g_inv(), ) .unwrap() @@ -277,7 +277,7 @@ mod test_dkg_full { &ciphertext.header().unwrap(), AAD, &validator_keypair.decryption_key, - validator.share_index, + validator.share_index as usize, &domain_points, &dkg.pvss_params.g_inv(), ) @@ -431,12 +431,14 @@ mod test_dkg_full { // Current participant receives updates from other participants let updates_for_participant: Vec<_> = share_updates .values() - .map(|updates| *updates.get(validator.share_index).unwrap()) + .map(|updates| { + *updates.get(validator.share_index as usize).unwrap() + }) .collect(); // Each validator uses their decryption key to update their share let decryption_key = validator_keypairs - .get(validator.share_index) + .get(validator.share_index as usize) .unwrap() .decryption_key; @@ -446,7 +448,7 @@ mod test_dkg_full { pvss_aggregated .update_private_key_share_for_recovery( &decryption_key, - validator.share_index, + validator.share_index as usize, updates_for_participant.as_slice(), ) .unwrap() @@ -572,12 +574,14 @@ mod test_dkg_full { // Current participant receives updates from other participants let updates_for_participant: Vec<_> = share_updates .values() - .map(|updates| *updates.get(validator.share_index).unwrap()) + .map(|updates| { + *updates.get(validator.share_index as usize).unwrap() + }) .collect(); // Each validator uses their decryption key to update their share let decryption_key = validator_keypairs - .get(validator.share_index) + .get(validator.share_index as usize) .unwrap() .decryption_key; @@ -587,7 +591,7 @@ mod test_dkg_full { pvss_aggregated .update_private_key_share_for_recovery( &decryption_key, - validator.share_index, + validator.share_index as usize, updates_for_participant.as_slice(), ) .unwrap() diff --git a/ferveo/src/pvss.rs b/ferveo/src/pvss.rs index c2b075b4..af83aa81 100644 --- a/ferveo/src/pvss.rs +++ b/ferveo/src/pvss.rs @@ -150,8 +150,8 @@ impl PubliclyVerifiableSS { // ek_{i}^{eval_i}, i = validator index fast_multiexp( // &evals.evals[i..i] = &evals.evals[i] - &[evals.evals[validator.share_index]], // one share per validator - validator.validator.public_key.encryption_key.into_group(), + &[evals.evals[validator.share_index as usize]], // one share per validator + validator.public_key.encryption_key.into_group(), )[0] }) .collect::>>(); @@ -198,17 +198,12 @@ impl PubliclyVerifiableSS { /// transcript was at fault so that the can issue a new one. This /// function may also be used for that purpose. pub fn verify_full(&self, dkg: &PubliclyVerifiableDkg) -> bool { - let validators = dkg - .validators - .values() - .map(|v| v.validator.clone()) - .collect::>(); - let validators = validators.as_slice(); + let validators = dkg.validators.values().cloned().collect::>(); do_verify_full( &self.coeffs, &self.shares, &dkg.pvss_params, - validators, + &validators, &dkg.domain, ) } @@ -287,17 +282,12 @@ impl PubliclyVerifiableSS { &self, dkg: &PubliclyVerifiableDkg, ) -> Result { - let validators = dkg - .validators - .values() - .map(|v| v.validator.clone()) - .collect::>(); - let validators = validators.as_slice(); + let validators = dkg.validators.values().cloned().collect::>(); do_verify_aggregation( &self.coeffs, &self.shares, &dkg.pvss_params, - validators, + &validators, &dkg.domain, &dkg.vss, ) diff --git a/ferveo/src/test_common.rs b/ferveo/src/test_common.rs index 21739c7e..4faae733 100644 --- a/ferveo/src/test_common.rs +++ b/ferveo/src/test_common.rs @@ -91,7 +91,7 @@ pub fn setup_dealt_dkg_with( shares_num, my_index as usize, ); - let me = dkg.me.validator.clone(); + let me = dkg.me.clone(); let message = dkg.share(rng).unwrap(); (me, message) })