From 2f92a3742df64ea90e8e0ced29e15c23ce7977f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=BA=C3=B1ez?= Date: Tue, 21 May 2024 11:32:29 +0200 Subject: [PATCH] Fix test_dkg_simple_tdec_share_refreshing test! --- ferveo/src/dkg.rs | 2 +- ferveo/src/lib.rs | 112 +++++++++++++++++++++------------------------- 2 files changed, 52 insertions(+), 62 deletions(-) diff --git a/ferveo/src/dkg.rs b/ferveo/src/dkg.rs index 9fcbe831..9388e3c5 100644 --- a/ferveo/src/dkg.rs +++ b/ferveo/src/dkg.rs @@ -185,7 +185,7 @@ impl PubliclyVerifiableDkg { .values() .map(|v| { let domain_point = map.get(&v.share_index).unwrap(); - // TODO: Use PublicKey directly + // TODO: Use PublicKey directly. See same problem in lib.rs::test_dkg_simple_tdec_share_refreshing ( v.share_index, (*domain_point, E::G2::from(v.public_key.encryption_key)), diff --git a/ferveo/src/lib.rs b/ferveo/src/lib.rs index 8e352d71..2db0243b 100644 --- a/ferveo/src/lib.rs +++ b/ferveo/src/lib.rs @@ -131,6 +131,8 @@ mod test_dkg_full { use super::*; use crate::test_common::*; + type G2 = ::G2; + pub fn create_shared_secret_simple_tdec( dkg: &PubliclyVerifiableDkg, aad: &[u8], @@ -623,12 +625,17 @@ mod test_dkg_full { .take(shares_num as usize) .map(|m| m.1.clone()) .collect::>(); + + // Initially, each participant creates a transcript, which is + // combined into a joint AggregateTranscript. let local_aggregate = AggregatedTranscript::from_transcripts(&transcripts).unwrap(); assert!(local_aggregate .aggregate .verify_aggregation(&dkg, &transcripts) .unwrap()); + + // Ciphertext created from the aggregate public key let ciphertext = ferveo_tdec::encrypt::( SecretBox::new(MSG.to_vec()), AAD, @@ -637,7 +644,8 @@ mod test_dkg_full { ) .unwrap(); - // Create an initial shared secret + // The set of transcripts (or equivalently, the AggregateTranscript), + // represents a (blinded) shared secret. let (_, _, old_shared_secret) = create_shared_secret_simple_tdec( &dkg, AAD, @@ -646,74 +654,56 @@ mod test_dkg_full { &transcripts, ); - // Each participant prepares an update for each other participant - let share_updates = dkg - .validators - .keys() - .map(|v_addr| { - let deltas_i = UpdateTranscript::create_refresh_updates( - &dkg.domain_and_key_map(), - dkg.dkg_params.security_threshold(), - rng, - ) - .updates; - (v_addr.clone(), deltas_i) - }) - .collect::>(); - - // Participants share updates and update their shares + // When the share refresh protocol is necessary, each participant + // prepares an UpdateTranscript, containing updates for each other. + let mut update_transcripts: HashMap> = + HashMap::new(); + let mut validator_map: HashMap = HashMap::new(); - // Now, every participant separately: - let updated_private_key_shares: Vec<_> = dkg - .validators - .values() - .map(|validator| { - // Current participant receives updates from other participants - let updates_for_participant: Vec<_> = share_updates - .values() - .map(|updates| { - updates.get(&validator.share_index).cloned().unwrap() - }) - .collect(); + for validator in dkg.validators.values() { + update_transcripts.insert( + validator.share_index, + dkg.generate_refresh_transcript(rng).unwrap(), + ); + validator_map.insert( + validator.share_index, + // TODO: Probably should consume public keys. See domain_and_key_map() in dkg.rs + G2::from( + validator_keypairs + .get(validator.share_index as usize) + .unwrap() + .public_key() + .encryption_key, + ), + ); + } - // Each validator uses their decryption key to update their share - let validator_keypair = validator_keypairs - .get(validator.share_index as usize) - .unwrap(); + // Participants distribute UpdateTranscripts and update their shares + // accordingly. The result is a new, joint AggregatedTranscript. + let new_aggregate = local_aggregate + .aggregate + .refresh(&update_transcripts, &validator_map) + .unwrap(); - // Creates updated private key shares - AggregatedTranscript::from_transcripts(&transcripts) - .unwrap() - .aggregate - .create_updated_private_key_share( - validator_keypair, - validator.share_index, - updates_for_participant.as_slice(), - ) - .unwrap() - }) - .collect(); + // TODO: Assert new aggregate is different than original + // TODO: Show that all participants obtain the same new aggregate transcript. - // Get decryption shares, now with refreshed private shares: + // Get decryption shares, now with the refreshed aggregate transcript: let decryption_shares: Vec> = validator_keypairs .iter() - .enumerate() - .map(|(share_index, validator_keypair)| { - // In order to proceed with the decryption, we need to convert the updated private key shares - let private_key_share = &updated_private_key_shares - .get(share_index) + .map(|validator_keypair| { + let validator = dkg + .get_validator(&validator_keypair.public_key()) + .unwrap(); + new_aggregate + .create_decryption_share_simple( + &ciphertext.header().unwrap(), + AAD, + validator_keypair, + validator.share_index, + ) .unwrap() - .inner() - .0; - DecryptionShareSimple::create( - &validator_keypair.decryption_key, - private_key_share, - &ciphertext.header().unwrap(), - AAD, - &dkg.pvss_params.g_inv(), - ) - .unwrap() }) // We take only the first `security_threshold` decryption shares .take(dkg.dkg_params.security_threshold() as usize)