From a4e5d35b7f5a3f58222d8a453ad03e4e9575b41a Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 31 Oct 2024 00:54:58 +0000 Subject: [PATCH 01/30] feat(crypto): CRP-2597 make NiDkgTag non-Copy --- rs/consensus/src/consensus/dkg_key_manager.rs | 13 ++-- .../src/consensus/share_aggregator.rs | 4 +- rs/consensus/src/consensus/validator.rs | 8 +-- rs/consensus/src/dkg.rs | 16 +++-- rs/consensus/src/dkg/payload_builder.rs | 38 +++++----- rs/consensus/src/dkg/payload_validator.rs | 2 +- rs/consensus/src/dkg/utils.rs | 8 ++- rs/consensus/utils/src/crypto.rs | 4 +- rs/consensus/utils/src/lib.rs | 6 +- rs/crypto/benches/ni_dkg.rs | 12 ++-- rs/crypto/benches/threshold_sig.rs | 49 ++++++++----- .../src/threshold/ni_dkg/tests/fixtures.rs | 8 +-- .../ni_dkg/tests/test_create_dealing.rs | 6 +- .../src/vault/test_utils/ni_dkg/fixtures.rs | 4 +- rs/crypto/src/sign/mod.rs | 10 ++- rs/crypto/src/sign/threshold_sig.rs | 37 +++++----- .../sign/threshold_sig/ni_dkg/transcript.rs | 7 +- .../threshold_sig/ni_dkg/transcript/tests.rs | 2 +- rs/crypto/src/sign/threshold_sig/store.rs | 27 +++++--- .../src/sign/threshold_sig/store/tests.rs | 42 +++++------ rs/crypto/src/sign/threshold_sig/tests.rs | 69 ++++++++++--------- .../ni-dkg/src/initial_config/tests.rs | 20 ++++-- rs/crypto/test_utils/ni-dkg/src/lib.rs | 16 ++--- rs/crypto/tests/threshold_sigs_with_ni_dkg.rs | 64 +++++++++++------ .../artifact_pool/src/consensus_pool.rs | 2 +- rs/test_utilities/consensus/src/lib.rs | 4 +- rs/test_utilities/src/crypto.rs | 4 +- rs/types/types/src/consensus.rs | 4 +- rs/types/types/src/consensus/catchup.rs | 2 +- rs/types/types/src/consensus/dkg.rs | 9 ++- .../types/src/crypto/threshold_sig/ni_dkg.rs | 8 ++- .../src/crypto/threshold_sig/ni_dkg/config.rs | 7 +- .../src/crypto/threshold_sig/ni_dkg/id.rs | 2 +- 33 files changed, 305 insertions(+), 209 deletions(-) diff --git a/rs/consensus/src/consensus/dkg_key_manager.rs b/rs/consensus/src/consensus/dkg_key_manager.rs index f0bc4893c2a..bb3e10aa4b4 100644 --- a/rs/consensus/src/consensus/dkg_key_manager.rs +++ b/rs/consensus/src/consensus/dkg_key_manager.rs @@ -312,14 +312,14 @@ impl DkgKeyManager { .current_transcripts() .iter() .filter(|(_, t)| !self.pending_transcript_loads.contains_key(&t.dkg_id)) - .map(|(_, t)| (current_interval_start, t.dkg_id)); + .map(|(_, t)| (current_interval_start, t.dkg_id.clone())); // For next transcripts, we take the start of the next interval as a deadline. let next_transcripts_with_load_deadlines = summary .next_transcripts() .iter() .filter(|(_, t)| !self.pending_transcript_loads.contains_key(&t.dkg_id)) - .map(|(_, t)| (next_interval_start, t.dkg_id)); + .map(|(_, t)| (next_interval_start, t.dkg_id.clone())); current_transcripts_with_load_deadlines .chain(next_transcripts_with_load_deadlines) @@ -333,7 +333,8 @@ impl DkgKeyManager { let logger = self.logger.clone(); let summary = summary.clone(); let (tx, rx) = sync_channel(0); - self.pending_transcript_loads.insert(dkg_id, (deadline, rx)); + self.pending_transcript_loads + .insert(dkg_id.clone(), (deadline, rx)); std::thread::spawn(move || { let transcript = summary @@ -596,7 +597,7 @@ mod tests { .current_transcripts() .values() .chain(dkg_summary.next_transcripts().values()) - .map(|t| t.dkg_id) + .map(|t| t.dkg_id.clone()) .collect::>(); // We expect the genesis summary to contain exactly 2 current transcripts. assert_eq!(summary_0_transcripts.len(), 2); @@ -629,7 +630,7 @@ mod tests { .current_transcripts() .values() .chain(dkg_summary.next_transcripts().values()) - .map(|t| t.dkg_id) + .map(|t| t.dkg_id.clone()) .collect::>(); // For the 3rd summary we expect 2 current and 2 next transcripts. assert_eq!(summary_2_transcripts.len(), 4); @@ -659,7 +660,7 @@ mod tests { .current_transcripts() .values() .chain(dkg_summary.next_transcripts().values()) - .map(|t| t.dkg_id) + .map(|t| t.dkg_id.clone()) .collect::>(); // For the 3rd summary we expect 2 current and 2 next transcripts. assert_eq!(summary_3_transcripts.len(), 4); diff --git a/rs/consensus/src/consensus/share_aggregator.rs b/rs/consensus/src/consensus/share_aggregator.rs index 5b464f7e165..67787b98619 100644 --- a/rs/consensus/src/consensus/share_aggregator.rs +++ b/rs/consensus/src/consensus/share_aggregator.rs @@ -66,7 +66,7 @@ impl ShareAggregator { &self.log, self.membership.as_ref(), self.crypto.as_aggregate(), - Box::new(|_| dkg_id), + Box::new(|_| dkg_id.clone()), shares, )) } @@ -153,7 +153,7 @@ impl ShareAggregator { &self.log, self.membership.as_ref(), self.crypto.as_aggregate(), - Box::new(|_| dkg_id), + Box::new(|_| dkg_id.clone()), shares, ); if !result.is_empty() { diff --git a/rs/consensus/src/consensus/validator.rs b/rs/consensus/src/consensus/validator.rs index a86348788b9..e00196bf12a 100644 --- a/rs/consensus/src/consensus/validator.rs +++ b/rs/consensus/src/consensus/validator.rs @@ -203,10 +203,10 @@ impl SignatureVerify for RandomTape { let dkg_id = active_low_threshold_nidkg_id(pool.as_cache(), self.height()) .ok_or_else(|| ValidationFailure::DkgSummaryNotFound(self.height()))?; if self.signature.signer == dkg_id { - crypto.verify_aggregate(self, self.signature.signer)?; + crypto.verify_aggregate(self, self.signature.signer.clone())?; Ok(()) } else { - Err(InvalidArtifactReason::InappropriateDkgId(self.signature.signer).into()) + Err(InvalidArtifactReason::InappropriateDkgId(self.signature.signer.clone()).into()) } } } @@ -244,10 +244,10 @@ impl SignatureVerify for RandomBeacon { let dkg_id = active_low_threshold_nidkg_id(pool.as_cache(), self.height()) .ok_or_else(|| ValidationFailure::DkgSummaryNotFound(self.height()))?; if self.signature.signer == dkg_id { - crypto.verify_aggregate(self, self.signature.signer)?; + crypto.verify_aggregate(self, self.signature.signer.clone())?; Ok(()) } else { - Err(InvalidArtifactReason::InappropriateDkgId(self.signature.signer).into()) + Err(InvalidArtifactReason::InappropriateDkgId(self.signature.signer.clone()).into()) } } } diff --git a/rs/consensus/src/dkg.rs b/rs/consensus/src/dkg.rs index 46cbbc067d2..66ce04c0b1d 100644 --- a/rs/consensus/src/dkg.rs +++ b/rs/consensus/src/dkg.rs @@ -216,7 +216,7 @@ impl DkgImpl { return Mutations::from(ChangeAction::RemoveFromUnvalidated((*message).clone())); } - let message_dkg_id = message.content.dkg_id; + let message_dkg_id = &message.content.dkg_id; // If the dealing refers to a DKG interval starting at a different height, // we skip it. @@ -226,7 +226,7 @@ impl DkgImpl { // If the dealing refers a config which is not among the ongoing DKGs, // we reject it. - let config = match configs.get(&message_dkg_id) { + let config = match configs.get(message_dkg_id) { Some(config) => config, None => { return get_handle_invalid_change_action( @@ -348,7 +348,7 @@ impl PoolMutationsProducer for DkgImpl { .get_unvalidated() // Group all unvalidated dealings by dealer. .fold(BTreeMap::new(), |mut map, dealing| { - let key = (dealing.signature.signer, dealing.content.dkg_id); + let key = (dealing.signature.signer, dealing.content.dkg_id.clone()); let dealings: &mut Vec<_> = map.entry(key).or_default(); dealings.push(dealing); processed += 1; @@ -499,10 +499,12 @@ pub fn make_registry_cup_from_cup_contents( let low_dkg_id = dkg_summary .current_transcript(&NiDkgTag::LowThreshold) - .dkg_id; + .dkg_id + .clone(); let high_dkg_id = dkg_summary .current_transcript(&NiDkgTag::HighThreshold) - .dkg_id; + .dkg_id + .clone(); // In a NNS subnet recovery case the block validation context needs to reference a registry // version of the NNS to be recovered. Otherwise the validation context points to a registry @@ -1247,7 +1249,7 @@ mod tests { // Now we create a message with an unknown Dkg id and verify // that it gets rejected. - let mut invalid_dkg_id = valid_dealing_message.content.dkg_id; + let mut invalid_dkg_id = valid_dealing_message.content.dkg_id.clone(); invalid_dkg_id.dealer_subnet = subnet_test_id(444); let mut invalid_dealing_message = valid_dealing_message.clone(); invalid_dealing_message.content.dkg_id = invalid_dkg_id; @@ -1325,7 +1327,7 @@ mod tests { let dkg_id_from_future = NiDkgId { start_block_height: ic_types::Height::from(1000), dealer_subnet: valid_dealing_message.content.dkg_id.dealer_subnet, - dkg_tag: valid_dealing_message.content.dkg_id.dkg_tag, + dkg_tag: valid_dealing_message.content.dkg_id.dkg_tag.clone(), target_subnet: NiDkgTargetSubnet::Local, }; let mut dealing_message_from_future = valid_dealing_message; diff --git a/rs/consensus/src/dkg/payload_builder.rs b/rs/consensus/src/dkg/payload_builder.rs index feae6b40146..742d010faf7 100644 --- a/rs/consensus/src/dkg/payload_builder.rs +++ b/rs/consensus/src/dkg/payload_builder.rs @@ -102,7 +102,7 @@ pub fn create_payload( // Make sure the message relates to one of the ongoing DKGs and it's from a unique // dealer. last_dkg_summary.configs.contains_key(&msg.content.dkg_id) - && !dealers_from_chain.contains(&(msg.content.dkg_id, msg.signature.signer)) + && !dealers_from_chain.contains(&(msg.content.dkg_id.clone(), msg.signature.signer)) }) .take(max_dealings_per_block) .cloned() @@ -160,11 +160,11 @@ pub(super) fn create_summary_payload( Ok(transcript) => { let previous_value_found = if dkg_id.target_subnet == NiDkgTargetSubnet::Local { next_transcripts - .insert(dkg_id.dkg_tag, transcript) + .insert(dkg_id.dkg_tag.clone(), transcript) .is_some() } else { transcripts_for_remote_subnets - .insert(*dkg_id, Ok(transcript)) + .insert(dkg_id.clone(), Ok(transcript)) .is_some() }; if previous_value_found { @@ -199,7 +199,7 @@ pub(super) fn create_summary_payload( &last_summary .transcripts_for_remote_subnets .iter() - .map(|(id, _, result)| (*id, result.clone())) + .map(|(id, _, result)| (id.clone(), result.clone())) .collect(), &last_summary.initial_dkg_attempts, &logger, @@ -314,7 +314,7 @@ fn compute_remote_dkg_data( .iter() .find(|(id, _)| eq_sans_height(id, &dkg_id)) { - new_transcripts.insert(*id, transcript.clone()); + new_transcripts.insert(id.clone(), transcript.clone()); } // If not, we check if we computed a transcript for this config in the last round. And // if not, we move the config into the new summary so that we try again in @@ -493,7 +493,7 @@ pub(crate) fn get_configs_for_local_transcripts( let dkg_id = NiDkgId { start_block_height, dealer_subnet: subnet_id, - dkg_tag: *tag, + dkg_tag: tag.clone(), target_subnet: NiDkgTargetSubnet::Local, }; let (dealers, resharing_transcript) = match tag { @@ -701,9 +701,13 @@ fn create_remote_dkg_configs( }; let low_thr_config = - do_create_remote_dkg_config(&low_thr_dkg_id, dealers, receivers, registry_version); - let high_thr_config = - do_create_remote_dkg_config(&high_thr_dkg_id, dealers, receivers, registry_version); + do_create_remote_dkg_config(low_thr_dkg_id.clone(), dealers, receivers, registry_version); + let high_thr_config = do_create_remote_dkg_config( + high_thr_dkg_id.clone(), + dealers, + receivers, + registry_version, + ); let sibl_err = String::from("Failed to create the sibling config"); match (low_thr_config, high_thr_config) { (Ok(config0), Ok(config1)) => Ok((config0, config1)), @@ -733,20 +737,20 @@ fn create_remote_dkg_configs( } fn do_create_remote_dkg_config( - dkg_id: &NiDkgId, + dkg_id: NiDkgId, dealers: &BTreeSet, receivers: &BTreeSet, registry_version: &RegistryVersion, ) -> Result { NiDkgConfig::new(NiDkgConfigData { - dkg_id: *dkg_id, + threshold: NumberOfNodes::from( + dkg_id.dkg_tag.threshold_for_subnet_of_size(receivers.len()) as u32, + ), + dkg_id, max_corrupt_dealers: NumberOfNodes::from(get_faults_tolerated(dealers.len()) as u32), max_corrupt_receivers: NumberOfNodes::from(get_faults_tolerated(receivers.len()) as u32), dealers: dealers.clone(), receivers: receivers.clone(), - threshold: NumberOfNodes::from( - dkg_id.dkg_tag.threshold_for_subnet_of_size(receivers.len()) as u32, - ), registry_version: *registry_version, resharing_transcript: None, }) @@ -845,7 +849,7 @@ mod tests { NiDkgId { start_block_height, dealer_subnet: subnet_id, - dkg_tag: *tag, + dkg_tag: tag.clone(), target_subnet: NiDkgTargetSubnet::Local, } ); @@ -1180,7 +1184,7 @@ mod tests { &NiDkgId { start_block_height: Height::from(0), dealer_subnet: subnet_id, - dkg_tag: *tag, + dkg_tag: tag.clone(), target_subnet: NiDkgTargetSubnet::Local, } ); @@ -1285,7 +1289,7 @@ mod tests { &NiDkgId { start_block_height: Height::from(expected_height), dealer_subnet: subnet_id, - dkg_tag: *tag, + dkg_tag: tag.clone(), target_subnet: NiDkgTargetSubnet::Local, } ); diff --git a/rs/consensus/src/dkg/payload_validator.rs b/rs/consensus/src/dkg/payload_validator.rs index 6ee59e5d9b4..cbf52f1078a 100644 --- a/rs/consensus/src/dkg/payload_validator.rs +++ b/rs/consensus/src/dkg/payload_validator.rs @@ -226,7 +226,7 @@ fn validate_dealings_payload( let dealers_from_payload: HashSet<_> = dealings .messages .iter() - .map(|message| (message.content.dkg_id, message.signature.signer)) + .map(|message| (message.content.dkg_id.clone(), message.signature.signer)) .collect(); if dealers_from_payload.len() != dealings.messages.len() { diff --git a/rs/consensus/src/dkg/utils.rs b/rs/consensus/src/dkg/utils.rs index 8fcad081bab..a04517548c5 100644 --- a/rs/consensus/src/dkg/utils.rs +++ b/rs/consensus/src/dkg/utils.rs @@ -12,7 +12,11 @@ pub(super) fn get_dealers_from_chain( ) -> HashSet<(NiDkgId, NodeId)> { get_dkg_dealings(pool_reader, block) .into_iter() - .flat_map(|(dkg_id, dealings)| dealings.into_keys().map(move |node_id| (dkg_id, node_id))) + .flat_map(|(dkg_id, dealings)| { + dealings + .into_keys() + .map(move |node_id| (dkg_id.clone(), node_id)) + }) .collect() } @@ -35,7 +39,7 @@ pub(super) fn get_dkg_dealings( .messages .iter() .for_each(|msg| { - let collected_dealings = acc.entry(msg.content.dkg_id).or_default(); + let collected_dealings = acc.entry(msg.content.dkg_id.clone()).or_default(); assert!( collected_dealings .insert(msg.signature.signer, msg.content.dealing.clone()) diff --git a/rs/consensus/utils/src/crypto.rs b/rs/consensus/utils/src/crypto.rs index 1e4d12f98f3..7a8bccf2407 100644 --- a/rs/consensus/utils/src/crypto.rs +++ b/rs/consensus/utils/src/crypto.rs @@ -406,7 +406,7 @@ impl + ThresholdSigVerifier + ThresholdSigVerifier>, >( @@ -267,7 +267,7 @@ pub fn active_low_threshold_nidkg_id( ) -> Option { get_active_data_at(reader, height, |block, height| { get_transcript_data_at_given_summary(block, height, NiDkgTag::LowThreshold, |transcript| { - transcript.dkg_id + transcript.dkg_id.clone() }) }) } @@ -279,7 +279,7 @@ pub fn active_high_threshold_nidkg_id( ) -> Option { get_active_data_at(reader, height, |block, height| { get_transcript_data_at_given_summary(block, height, NiDkgTag::HighThreshold, |transcript| { - transcript.dkg_id + transcript.dkg_id.clone() }) }) } diff --git a/rs/crypto/benches/ni_dkg.rs b/rs/crypto/benches/ni_dkg.rs index 5ee0ab88d4e..f0625f7ee80 100644 --- a/rs/crypto/benches/ni_dkg.rs +++ b/rs/crypto/benches/ni_dkg.rs @@ -295,7 +295,7 @@ fn prepare_create_reshare_dealing_test_vectors( ) -> (NiDkgTestEnvironment, RandomNiDkgConfig) { let config0 = RandomNiDkgConfig::builder() .subnet_size(test_case.num_of_nodes) - .dkg_tag(test_case.dkg_tag) + .dkg_tag(test_case.dkg_tag.clone()) .dealer_count(test_case.num_of_dealers) .max_corrupt_dealers(get_faults_tolerated(test_case.num_of_dealers)) .build(rng); @@ -325,7 +325,7 @@ fn prepare_create_initial_dealing_test_vectors( ) -> (NiDkgTestEnvironment, RandomNiDkgConfig) { let config = RandomNiDkgConfig::builder() .subnet_size(test_case.num_of_nodes) - .dkg_tag(test_case.dkg_tag) + .dkg_tag(test_case.dkg_tag.clone()) .dealer_count(test_case.num_of_dealers) .max_corrupt_dealers(get_faults_tolerated(test_case.num_of_dealers)) .build(rng); @@ -343,7 +343,7 @@ fn prepare_verify_dealing_test_vectors( ) { let config = RandomNiDkgConfig::builder() .subnet_size(test_case.num_of_nodes) - .dkg_tag(test_case.dkg_tag) + .dkg_tag(test_case.dkg_tag.clone()) .dealer_count(test_case.num_of_dealers) .max_corrupt_dealers(get_faults_tolerated(test_case.num_of_dealers)) .build(rng); @@ -376,7 +376,7 @@ fn prepare_create_transcript_test_vectors( ) { let config = RandomNiDkgConfig::builder() .subnet_size(test_case.num_of_nodes) - .dkg_tag(test_case.dkg_tag) + .dkg_tag(test_case.dkg_tag.clone()) .dealer_count(test_case.num_of_dealers) .max_corrupt_dealers(get_faults_tolerated(test_case.num_of_dealers)) .build(rng); @@ -394,7 +394,7 @@ fn prepare_load_transcript_test_vectors( ) -> (NiDkgTestEnvironment, RandomNiDkgConfig, NiDkgTranscript) { let config = RandomNiDkgConfig::builder() .subnet_size(test_case.num_of_nodes) - .dkg_tag(test_case.dkg_tag) + .dkg_tag(test_case.dkg_tag.clone()) .dealer_count(test_case.num_of_dealers) .max_corrupt_dealers(get_faults_tolerated(test_case.num_of_dealers)) .build(rng); @@ -417,7 +417,7 @@ fn prepare_retain_keys_test_vectors( // tag/threshold). let config0 = RandomNiDkgConfig::builder() .subnet_size(test_case.num_of_nodes) - .dkg_tag(test_case.dkg_tag) + .dkg_tag(test_case.dkg_tag.clone()) .dealer_count(test_case.num_of_dealers) .registry_version(ic_base_types::RegistryVersion::from(1)) .max_corrupt_dealers(get_faults_tolerated(test_case.num_of_dealers)) diff --git a/rs/crypto/benches/threshold_sig.rs b/rs/crypto/benches/threshold_sig.rs index 7b3f160ecc2..2f7dc9b4b55 100644 --- a/rs/crypto/benches/threshold_sig.rs +++ b/rs/crypto/benches/threshold_sig.rs @@ -109,13 +109,13 @@ fn bench_threshold_sig_n_nodes( for &node_id in &nodes_in_subnet { load_transcript(&transcript, &env.crypto_components, node_id); } - let dkg_id = transcript.dkg_id; + let dkg_id = transcript.dkg_id.clone(); bench_threshold_sign( group, &nodes_in_subnet, &env.crypto_components, - dkg_id, + dkg_id.clone(), message_size, rng, ); @@ -125,7 +125,7 @@ fn bench_threshold_sig_n_nodes( group, &nodes_in_subnet, &env.crypto_components, - dkg_id, + dkg_id.clone(), message_size, rng, ); @@ -133,7 +133,7 @@ fn bench_threshold_sig_n_nodes( group, &nodes_in_subnet, &env.crypto_components, - dkg_id, + dkg_id.clone(), &transcript, message_size, rng, @@ -143,7 +143,7 @@ fn bench_threshold_sig_n_nodes( group, &threshold_many_random_subnet_nodes, &env.crypto_components, - dkg_id, + dkg_id.clone(), message_size, rng, ); @@ -174,7 +174,7 @@ fn bench_threshold_sign( (message, signer) }, |(message, signer)| { - assert!(signer.sign_threshold(&message, dkg_id).is_ok()); + assert!(signer.sign_threshold(&message, dkg_id.clone()).is_ok()); }, SmallInput, ) @@ -202,7 +202,7 @@ fn bench_verify_threshold_sig_share_incl_loading_pubkey( || { let message = signable_with_random_bytes(message_size, rng); let sig_shares = - sign_threshold_for_each(nodes, &message, dkg_id, crypto_components); + sign_threshold_for_each(nodes, &message, dkg_id.clone(), crypto_components); let combiner = crypto_for(random_node(nodes, rng), crypto_components); (sig_shares, combiner) }, |(sig_shares, combiner)| { assert!(combiner - .combine_threshold_sig_shares(sig_shares, dkg_id) + .combine_threshold_sig_shares(sig_shares, dkg_id.clone()) .is_ok()); }, SmallInput, @@ -321,16 +336,16 @@ fn bench_verify_threshold_sig_combined( || { let message = signable_with_random_bytes(message_size, rng); let sig_shares = - sign_threshold_for_each(nodes, &message, dkg_id, crypto_components); + sign_threshold_for_each(nodes, &message, dkg_id.clone(), crypto_components); let threshold_sig = crypto_for(random_node(nodes, rng), crypto_components) - .combine_threshold_sig_shares(sig_shares, dkg_id) + .combine_threshold_sig_shares(sig_shares, dkg_id.clone()) .expect("failed to combine threshold signature shares"); let verifier = crypto_for(random_node(nodes, rng), crypto_components); (threshold_sig, message, verifier) }, |(threshold_sig, message, verifier)| { assert!(verifier - .verify_threshold_sig_combined(&threshold_sig, &message, dkg_id) + .verify_threshold_sig_combined(&threshold_sig, &message, dkg_id.clone()) .is_ok()); }, SmallInput, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs index 0e5a8ec88da..d953f8b73be 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs @@ -272,7 +272,7 @@ impl StateWithDealings { .expect("Could not find dealer in nodes"); let dealing = node.create_dealing( config.algorithm_id, - config.dkg_id, + config.dkg_id.clone(), config .dealers .position(node.node_id) @@ -319,7 +319,7 @@ impl StateWithVerifiedDealings { let test_result = if let Some(transcript) = &config.resharing_transcript { static_api::verify_resharing_dealing( config.algorithm_id, - config.dkg_id, + config.dkg_id.clone(), dealer_index, config.threshold.get(), config.epoch, @@ -330,7 +330,7 @@ impl StateWithVerifiedDealings { } else { static_api::verify_dealing( config.algorithm_id, - config.dkg_id, + config.dkg_id.clone(), dealer_index, config.threshold.get(), config.epoch, @@ -438,7 +438,7 @@ impl StateWithTranscript { node.csp .load_threshold_signing_key( self.config.algorithm_id, - self.config.dkg_id, + self.config.dkg_id.clone(), self.config.epoch, self.transcript.clone(), node_index, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/test_create_dealing.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/test_create_dealing.rs index caa2600d5c9..58cb4e592b3 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/test_create_dealing.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/test_create_dealing.rs @@ -72,7 +72,7 @@ impl StateWithConfig { let dealing = dealer_node.create_dealing( incorrect_algorithm_id, - self.config.dkg_id, + self.config.dkg_id.clone(), self.config .dealers .position(dealer_node.node_id) @@ -122,7 +122,7 @@ impl StateWithConfig { for incorrect_threshold in &[0, num_receivers + 1, num_receivers + 2] { let dealing = dealer_node.create_dealing( self.config.algorithm_id, - self.config.dkg_id, + self.config.dkg_id.clone(), self.config .dealers .position(dealer_node.node_id) @@ -168,7 +168,7 @@ impl StateWithConfig { let dealing = dealer_node.create_dealing( self.config.algorithm_id, - self.config.dkg_id, + self.config.dkg_id.clone(), self.config .dealers .position(dealer_node.node_id) diff --git a/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs index 4ad4044a3ed..f23ba873edf 100644 --- a/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs @@ -341,7 +341,7 @@ impl StateWithVerifiedDealings { let test_result = if let Some(transcript) = &config.resharing_transcript { ni_dkg_static_api::verify_resharing_dealing( config.algorithm_id, - config.dkg_id, + config.dkg_id.clone(), dealer_index, config.threshold.get(), config.epoch, @@ -352,7 +352,7 @@ impl StateWithVerifiedDealings { } else { ni_dkg_static_api::verify_dealing( config.algorithm_id, - config.dkg_id, + config.dkg_id.clone(), dealer_index, config.threshold.get(), config.epoch, diff --git a/rs/crypto/src/sign/mod.rs b/rs/crypto/src/sign/mod.rs index fce2d215cb8..81cf75c271c 100644 --- a/rs/crypto/src/sign/mod.rs +++ b/rs/crypto/src/sign/mod.rs @@ -524,6 +524,9 @@ impl ThresholdSigVerifier for CryptoCo result } + ////////////////////////////////////////////// + // TODO: dkg_id as reference + ////////////////////////////////////////////// fn combine_threshold_sig_shares( &self, shares: BTreeMap>, @@ -545,7 +548,7 @@ impl ThresholdSigVerifier for CryptoCo &self.lockable_threshold_sig_data_store, &self.csp, shares, - dkg_id, + &dkg_id, ); self.metrics.observe_duration_seconds( MetricsDomain::ThresholdSignature, @@ -563,6 +566,9 @@ impl ThresholdSigVerifier for CryptoCo result } + ////////////////////////////////////////////// + // TODO: dkg_id as reference + ////////////////////////////////////////////// fn verify_threshold_sig_combined( &self, signature: &CombinedThresholdSigOf, @@ -587,7 +593,7 @@ impl ThresholdSigVerifier for CryptoCo &self.csp, signature, message, - dkg_id, + &dkg_id, ); self.metrics.observe_duration_seconds( MetricsDomain::ThresholdSignature, diff --git a/rs/crypto/src/sign/threshold_sig.rs b/rs/crypto/src/sign/threshold_sig.rs index 2e519f882c2..017a5f14937 100644 --- a/rs/crypto/src/sign/threshold_sig.rs +++ b/rs/crypto/src/sign/threshold_sig.rs @@ -22,13 +22,16 @@ mod tests; pub struct ThresholdSignerInternal {} impl ThresholdSignerInternal { + ////////////////////////////////////////////// + // TODO: dkg_id as reference (assuming error is unlikely) + ////////////////////////////////////////////// pub fn sign_threshold( lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, threshold_sig_csp_client: &C, message: &H, dkg_id: NiDkgId, ) -> Result, ThresholdSignError> { - let pub_coeffs = pub_coeffs_from_store(dkg_id, lockable_threshold_sig_data_store)?; + let pub_coeffs = pub_coeffs_from_store(&dkg_id, lockable_threshold_sig_data_store)?; let csp_signature = threshold_sig_csp_client .threshold_sign( AlgorithmId::from(&pub_coeffs), @@ -43,25 +46,27 @@ impl ThresholdSignerInternal { // Use this if only the pub coeffs are needed from the store. If also indices // are required, use transcript_data_from_store instead. fn pub_coeffs_from_store( - dkg_id: NiDkgId, + dkg_id: &NiDkgId, lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, ) -> Result { let maybe_coeffs = lockable_threshold_sig_data_store .read() .transcript_data(dkg_id) .map(|data| data.public_coefficients().clone()); - maybe_coeffs.ok_or(ThresholdSigDataNotFoundError::ThresholdSigDataNotFound { dkg_id }) + maybe_coeffs.ok_or(ThresholdSigDataNotFoundError::ThresholdSigDataNotFound { + dkg_id: dkg_id.clone(), + }) } fn transcript_data_from_store( - dkg_id: NiDkgId, + dkg_id: &NiDkgId, lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, ) -> Result { let maybe_transcript_data = lockable_threshold_sig_data_store .read() .transcript_data(dkg_id) .cloned(); - maybe_transcript_data.ok_or_else(|| sig_data_not_found_error(dkg_id)) + maybe_transcript_data.ok_or_else(|| sig_data_not_found_error(dkg_id.clone())) } fn sig_data_not_found_error(dkg_id: NiDkgId) -> ThresholdSigDataNotFoundError { @@ -192,7 +197,7 @@ fn lazily_calculated_public_key_from_store( dkg_id: NiDkgId, node_id: NodeId, ) -> CryptoResult { - match public_key_from_store(lockable_threshold_sig_data_store, dkg_id, node_id) { + match public_key_from_store(lockable_threshold_sig_data_store, &dkg_id, node_id) { Some(public_key) => Ok(public_key), None => calculate_and_store_public_key_or_panic( lockable_threshold_sig_data_store, @@ -205,7 +210,7 @@ fn lazily_calculated_public_key_from_store( fn public_key_from_store( lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, ) -> Option { lockable_threshold_sig_data_store @@ -220,8 +225,8 @@ fn calculate_and_store_public_key_or_panic( dkg_id: NiDkgId, node_id: NodeId, ) -> CryptoResult { - let transcript_data = transcript_data_from_store(dkg_id, lockable_threshold_sig_data_store)?; - let (public_coeffs, node_index) = coeffs_and_index(transcript_data, dkg_id, node_id)?; + let transcript_data = transcript_data_from_store(&dkg_id, lockable_threshold_sig_data_store)?; + let (public_coeffs, node_index) = coeffs_and_index(transcript_data, &dkg_id, node_id)?; let public_key = threshold_sig_csp_client .threshold_individual_public_key( AlgorithmId::from(&public_coeffs), @@ -244,7 +249,7 @@ fn calculate_and_store_public_key_or_panic( fn coeffs_and_index( transcript_data: TranscriptData, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, ) -> CryptoResult<(CspPublicCoefficients, NodeIndex)> { let public_coeffs = transcript_data.public_coefficients().clone(); @@ -279,7 +284,7 @@ impl ThresholdSigVerifierInternal { lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, threshold_sig_csp_client: &C, shares: BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult> { error_if_shares_empty(&shares)?; let transcript_data = @@ -299,7 +304,7 @@ impl ThresholdSigVerifierInternal { fn shares_to_vector( transcript_data: &TranscriptData, shares: BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult>> { let max_node_index = maximum_node_index(transcript_data, &shares, dkg_id)?; let array_size = ::try_from(max_node_index).expect("usize overflow") + 1; @@ -318,7 +323,7 @@ fn shares_to_vector( fn maximum_node_index( transcript_data: &TranscriptData, shares: &BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult { shares.iter().try_fold(0, |cur_max, (node_id, _share)| { index_for_node_id(transcript_data, *node_id, dkg_id).map(|index| cmp::max(cur_max, index)) @@ -339,7 +344,7 @@ fn error_if_shares_empty( fn index_for_node_id( transcript_data: &TranscriptData, node_id: NodeId, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult { transcript_data .index(node_id) @@ -373,7 +378,7 @@ fn map_csp_combine_sigs_error(error: CryptoError) -> CryptoError { } } -fn node_id_missing_error(node_id: NodeId, dkg_id: NiDkgId) -> CryptoError { +fn node_id_missing_error(node_id: NodeId, dkg_id: &NiDkgId) -> CryptoError { CryptoError::InvalidArgument { message: format!( "There is no node index for dkg id \"{:?}\" and node id \"{}\" in the transcript data.", @@ -388,7 +393,7 @@ impl ThresholdSigVerifierInternal { threshold_sig_csp_client: &C, signature: &CombinedThresholdSigOf, message: &H, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult<()> { let pub_coeffs = pub_coeffs_from_store(dkg_id, lockable_threshold_sig_data_store)?; let csp_signature = CspSignature::try_from(signature)?; diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs index e4fb70028a1..0258c812d87 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs @@ -239,7 +239,7 @@ mod loading { insert_transcript_data_into_store( lockable_threshold_sig_data_store, &csp_transcript, - transcript.dkg_id, + transcript.dkg_id.clone(), &transcript.committee, ); let epoch = epoch(transcript.registry_version); @@ -311,7 +311,10 @@ mod loading { ) -> Result<(), CspDkgLoadPrivateKeyError> { ni_dkg_csp_client.load_threshold_signing_key( AlgorithmId::NiDkg_Groth20_Bls12_381, - transcript.dkg_id, + /////////////////////////////////////// + // TODO: this param is actually not needed/used + /////////////////////////////////////// + transcript.dkg_id.clone(), epoch(transcript.registry_version), csp_transcript.clone(), self_index_in_committee, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript/tests.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript/tests.rs index bd3999c5363..30f7eabf809 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript/tests.rs @@ -726,7 +726,7 @@ mod load_transcript { ) -> Option { lockable_threshold_sig_data_store .read() - .transcript_data(dkg_id) + .transcript_data(&dkg_id) .cloned() } diff --git a/rs/crypto/src/sign/threshold_sig/store.rs b/rs/crypto/src/sign/threshold_sig/store.rs index 926c8989652..060eb41d9c9 100644 --- a/rs/crypto/src/sign/threshold_sig/store.rs +++ b/rs/crypto/src/sign/threshold_sig/store.rs @@ -41,13 +41,13 @@ pub trait ThresholdSigDataStore { ); /// Returns the transcript data for the node_id if it has been loaded. - fn transcript_data(&self, dkg_id: NiDkgId) -> Option<&TranscriptData>; + fn transcript_data(&self, dkg_id: &NiDkgId) -> Option<&TranscriptData>; /// Returns a reference to the individual public key of the node with ID /// `node_id` for the given `dkg_id`. fn individual_public_key( &self, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, ) -> Option<&CspThresholdSigPublicKey>; } @@ -135,13 +135,16 @@ impl ThresholdSigDataStoreImpl { #[allow(clippy::map_entry)] fn entry_for(&mut self, dkg_id: NiDkgId) -> &mut ThresholdSigData { if !self.store.contains_key(&dkg_id) { - self.store.insert(dkg_id, ThresholdSigData::default()); + self.store + .insert(dkg_id.clone(), ThresholdSigData::default()); match dkg_id.dkg_tag { NiDkgTag::LowThreshold => { - self.low_threshold_dkg_id_insertion_order.push_back(dkg_id); + self.low_threshold_dkg_id_insertion_order + .push_back(dkg_id.clone()); } NiDkgTag::HighThreshold => { - self.high_threshold_dkg_id_insertion_order.push_back(dkg_id); + self.high_threshold_dkg_id_insertion_order + .push_back(dkg_id.clone()); } } } @@ -181,13 +184,14 @@ impl ThresholdSigDataStore for ThresholdSigDataStoreImpl { public_coefficients: CspPublicCoefficients, indices: BTreeMap, ) { + let dkg_tag = dkg_id.dkg_tag.clone(); let data = self.entry_for(dkg_id); data.transcript_data = Some(TranscriptData { public_coeffs: public_coefficients, indices, }); - self.purge_entry_for_oldest_dkg_id_if_necessary(dkg_id.dkg_tag); + self.purge_entry_for_oldest_dkg_id_if_necessary(dkg_tag); self.assert_length_invariant(); } @@ -197,27 +201,28 @@ impl ThresholdSigDataStore for ThresholdSigDataStoreImpl { node_id: NodeId, public_key: CspThresholdSigPublicKey, ) { + let dkg_tag = dkg_id.dkg_tag.clone(); self.entry_for(dkg_id) .public_keys .get_or_insert_with(BTreeMap::new) .insert(node_id, public_key); - self.purge_entry_for_oldest_dkg_id_if_necessary(dkg_id.dkg_tag); + self.purge_entry_for_oldest_dkg_id_if_necessary(dkg_tag); self.assert_length_invariant(); } - fn transcript_data(&self, dkg_id: NiDkgId) -> Option<&TranscriptData> { + fn transcript_data(&self, dkg_id: &NiDkgId) -> Option<&TranscriptData> { self.store - .get(&dkg_id) + .get(dkg_id) .and_then(|data| data.transcript_data.as_ref()) } fn individual_public_key( &self, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, ) -> Option<&CspThresholdSigPublicKey> { - self.store.get(&dkg_id).and_then(|data| { + self.store.get(dkg_id).and_then(|data| { data.public_keys .as_ref() .and_then(|public_key_map| public_key_map.get(&node_id)) diff --git a/rs/crypto/src/sign/threshold_sig/store/tests.rs b/rs/crypto/src/sign/threshold_sig/store/tests.rs index dc4d14908ba..a4fff5dbe3a 100644 --- a/rs/crypto/src/sign/threshold_sig/store/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/store/tests.rs @@ -25,9 +25,9 @@ fn should_contain_transcript_data_after_insertion_with_dkg_id(dkg_id: NiDkgId) { ]); let public_coeffs = public_coeffs(); - store.insert_transcript_data(dkg_id, public_coeffs.clone(), indices); + store.insert_transcript_data(dkg_id.clone(), public_coeffs.clone(), indices); - let transcript_data = store.transcript_data(dkg_id).unwrap(); + let transcript_data = store.transcript_data(&dkg_id).unwrap(); assert_eq!(transcript_data.public_coefficients(), &public_coeffs); assert_eq!( transcript_data.index(node_test_id(NODE_1)), @@ -43,7 +43,7 @@ fn should_contain_transcript_data_after_insertion_with_dkg_id(dkg_id: NiDkgId) { fn should_not_contain_nonexistent_transcript_data() { let store = ThresholdSigDataStoreImpl::new(); - assert!(store.transcript_data(NI_DKG_ID_1).is_none()); + assert!(store.transcript_data(&NI_DKG_ID_1).is_none()); } #[test] @@ -52,10 +52,10 @@ fn should_contain_individual_public_keys_after_insertion_with_nidkg_id() { let mut store = ThresholdSigDataStoreImpl::new(); let csp_pubkey = csp_public_key(); - store.insert_individual_public_key(dkg_id, node_test_id(NODE_1), csp_pubkey); + store.insert_individual_public_key(dkg_id.clone(), node_test_id(NODE_1), csp_pubkey); assert_eq!( - store.individual_public_key(dkg_id, node_test_id(NODE_1)), + store.individual_public_key(&dkg_id, node_test_id(NODE_1)), Some(&csp_pubkey) ); } @@ -72,15 +72,15 @@ fn should_insert_multiple_individual_public_keys() { store.insert_individual_public_key(NI_DKG_ID_2, node_test_id(NODE_1), csp_pubkey_2); assert_eq!( - store.individual_public_key(NI_DKG_ID_1, node_test_id(NODE_1)), + store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1)), Some(&csp_pubkey_1) ); assert_eq!( - store.individual_public_key(NI_DKG_ID_1, node_test_id(NODE_2)), + store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_2)), Some(&csp_pubkey_2) ); assert_eq!( - store.individual_public_key(NI_DKG_ID_2, node_test_id(NODE_1)), + store.individual_public_key(&NI_DKG_ID_2, node_test_id(NODE_1)), Some(&csp_pubkey_2) ); } @@ -90,7 +90,7 @@ fn should_not_contain_nonexistent_individual_public_key() { let store = ThresholdSigDataStoreImpl::new(); assert_eq!( - store.individual_public_key(NI_DKG_ID_1, node_test_id(NODE_1)), + store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1)), None ); } @@ -104,7 +104,7 @@ fn should_overwrite_existing_public_coefficients() { store.insert_transcript_data(NI_DKG_ID_1, public_coeffs_1, BTreeMap::new()); store.insert_transcript_data(NI_DKG_ID_1, public_coeffs_2.clone(), BTreeMap::new()); - let transcript_data = store.transcript_data(NI_DKG_ID_1).unwrap(); + let transcript_data = store.transcript_data(&NI_DKG_ID_1).unwrap(); assert_eq!(transcript_data.public_coefficients(), &public_coeffs_2); } @@ -118,7 +118,7 @@ fn should_overwrite_existing_indices() { store.insert_transcript_data(NI_DKG_ID_1, public_coeffs.clone(), indices_1); store.insert_transcript_data(NI_DKG_ID_1, public_coeffs, indices_2); - let transcript_data = store.transcript_data(NI_DKG_ID_1).unwrap(); + let transcript_data = store.transcript_data(&NI_DKG_ID_1).unwrap(); assert_eq!(transcript_data.index(node_test_id(NODE_1)), None); assert_eq!( transcript_data.index(node_test_id(NODE_2)), @@ -137,7 +137,7 @@ fn should_overwrite_existing_individual_public_keys() { store.insert_individual_public_key(NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_2); assert_eq!( - store.individual_public_key(NI_DKG_ID_1, node_test_id(NODE_1)), + store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1)), Some(&csp_pubkey_2) ); } @@ -188,7 +188,7 @@ fn should_purge_data_on_inserting_coeffs_and_indices_if_capacity_exceeded() { store.store.len(), ThresholdSigDataStoreImpl::CAPACITY_PER_TAG ); - assert!(store.transcript_data(ni_dkg_id(1)).is_none()); + assert!(store.transcript_data(&ni_dkg_id(1)).is_none()); for i in 2..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { assert_eq!(pub_coeffs_from_store(&store, ni_dkg_id(i)), pub_coeffs); } @@ -211,7 +211,7 @@ fn should_purge_data_in_insertion_order_on_inserting_coeffs_and_indices_if_capac assert_eq!(pub_coeffs_from_store(&store, ni_dkg_id(i)), pub_coeffs); } assert!(store - .transcript_data(ni_dkg_id(ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1)) + .transcript_data(&ni_dkg_id(ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1)) .is_none()); } @@ -223,13 +223,13 @@ fn should_not_purge_all_transcripts_of_certain_threshold_if_capacity_exceeded( let pub_coeffs = public_coeffs(); store.insert_transcript_data( - ni_dkg_id_with_tag(single_transcript_threshold, 1), + ni_dkg_id_with_tag(single_transcript_threshold.clone(), 1), pub_coeffs.clone(), BTreeMap::new(), ); for i in 0..ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { store.insert_transcript_data( - ni_dkg_id_with_tag(other_transcripts_threshold, i), + ni_dkg_id_with_tag(other_transcripts_threshold.clone(), i), pub_coeffs.clone(), BTreeMap::new(), ); @@ -294,11 +294,11 @@ fn should_purge_data_on_inserting_pubkeys_if_capacity_exceeded() { ); for i in 2..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { assert_eq!( - store.individual_public_key(ni_dkg_id(i), node_id), + store.individual_public_key(&ni_dkg_id(i), node_id), Some(&csp_pubkey) ); } - assert_eq!(store.individual_public_key(ni_dkg_id(1), node_id), None); + assert_eq!(store.individual_public_key(&ni_dkg_id(1), node_id), None); } #[test] @@ -317,13 +317,13 @@ fn should_purge_data_in_insertion_order_on_inserting_pubkeys_if_max_size_exceede ); for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { assert_eq!( - store.individual_public_key(ni_dkg_id(i), node_id), + store.individual_public_key(&ni_dkg_id(i), node_id), Some(&csp_pubkey) ); } assert_eq!( store.individual_public_key( - ni_dkg_id(ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1), + &ni_dkg_id(ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1), node_id ), None @@ -426,7 +426,7 @@ fn pub_coeffs_from_store( dkg_id: NiDkgId, ) -> CspPublicCoefficients { store - .transcript_data(dkg_id) + .transcript_data(&dkg_id) .expect("Expecting transcript data to be present for dkg id") .public_coefficients() .clone() diff --git a/rs/crypto/src/sign/threshold_sig/tests.rs b/rs/crypto/src/sign/threshold_sig/tests.rs index 679c5ece494..51cc8bec047 100644 --- a/rs/crypto/src/sign/threshold_sig/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/tests.rs @@ -60,7 +60,8 @@ mod sign_threshold { .return_const(Ok(individual_csp_threshold_sig( [42; IndividualSignatureBytes::SIZE], ))); - let threshold_sig_data_store = threshold_sig_data_store_with_coeffs(pub_coeffs, dkg_id); + let threshold_sig_data_store = + threshold_sig_data_store_with_coeffs(pub_coeffs, dkg_id.clone()); let _ = ThresholdSignerInternal::sign_threshold( &threshold_sig_data_store, @@ -241,8 +242,11 @@ mod verify_threshold_sig_share { fn should_call_csp_with_correct_params_if_public_key_in_store() { let dkg_id = NI_DKG_ID_1; let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); - let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs_and_pubkey(dkg_id, NODE_ID, csp_public_key); + let threshold_sig_data_store = threshold_sig_data_store_with_coeffs_and_pubkey( + dkg_id.clone(), + NODE_ID, + csp_public_key, + ); let mut csp = MockAllCryptoServiceProvider::new(); let (expected_msg, expected_sig) = (message.clone(), sig_share.clone()); csp.expect_threshold_verify_individual_signature() @@ -424,7 +428,9 @@ mod verify_threshold_sig_share { fn should_have_correct_public_key_in_store_after_sig_verification_if_not_in_store_before() { let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id(NI_DKG_ID_1); + threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id( + NI_DKG_ID_1.clone(), + ); let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_threshold_individual_public_key() .times(1) @@ -438,14 +444,14 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + NI_DKG_ID_1.clone(), NODE_ID, ); assert_eq!( threshold_sig_data_store .read() - .individual_public_key(NI_DKG_ID_1, NODE_ID), + .individual_public_key(&NI_DKG_ID_1.clone(), NODE_ID), Some(&csp_public_key) ); } @@ -675,13 +681,14 @@ mod combine_threshold_sig_shares { .return_const(Ok(combined_csp_threshold_sig( [42; CombinedSignatureBytes::SIZE], ))); - let threshold_sig_data_store = threshold_sig_data_store_with(dkg_id, pub_coeffs, indices); + let threshold_sig_data_store = + threshold_sig_data_store_with(dkg_id.clone(), pub_coeffs, indices); let _ = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, &csp, shares, - dkg_id, + &dkg_id, ); } @@ -701,7 +708,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!( @@ -727,7 +734,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); } @@ -768,7 +775,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); } @@ -784,7 +791,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!( @@ -808,7 +815,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!( @@ -834,7 +841,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!( @@ -867,7 +874,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); } @@ -887,7 +894,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert!(result.unwrap_err().is_malformed_signature()); @@ -908,7 +915,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert!(result.unwrap_err().is_malformed_signature()); @@ -929,7 +936,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!(result.unwrap_err(), invalid_argument()); @@ -950,7 +957,7 @@ mod combine_threshold_sig_shares { &threshold_sig_data_store, &csp, shares, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); let expected_error = CryptoError::InternalError { @@ -1015,11 +1022,11 @@ mod verify_threshold_sig_combined { ); let _ = ThresholdSigVerifierInternal::verify_threshold_sig_combined( - &threshold_sig_data_store_with_coeffs(pub_coeffs, dkg_id), + &threshold_sig_data_store_with_coeffs(pub_coeffs, dkg_id.clone()), &csp, &combined_sig, &message, - dkg_id, + &dkg_id, ); } @@ -1033,7 +1040,7 @@ mod verify_threshold_sig_combined { &csp, &combined_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert!(result.is_ok()); @@ -1050,7 +1057,7 @@ mod verify_threshold_sig_combined { &csp, &combined_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!( @@ -1072,7 +1079,7 @@ mod verify_threshold_sig_combined { &csp, &invalid_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert!(result.unwrap_err().is_malformed_signature()); @@ -1089,7 +1096,7 @@ mod verify_threshold_sig_combined { &csp, &combined_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!(result.unwrap_err(), verification_error); @@ -1106,7 +1113,7 @@ mod verify_threshold_sig_combined { &csp, &combined_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!(result.unwrap_err(), malformed_sig_error); @@ -1122,7 +1129,7 @@ mod verify_threshold_sig_combined { &csp, &combined_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!(result.unwrap_err(), invalid_argument()); } @@ -1137,7 +1144,7 @@ mod verify_threshold_sig_combined { &csp, &combined_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!(result.unwrap_err(), malformed_public_key()); } @@ -1152,7 +1159,7 @@ mod verify_threshold_sig_combined { &csp, &combined_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); let expected_error = CryptoError::InternalError { @@ -1247,7 +1254,7 @@ mod verify_combined_threshold_sig_by_public_key { &csp_2, &combined_sig, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, ); } @@ -1640,7 +1647,7 @@ fn threshold_sig_data_store_with_coeffs_and_pubkey( let threshold_sig_data_store = LockableThresholdSigDataStore::new(); { let mut locked_store = threshold_sig_data_store.write(); - locked_store.insert_transcript_data(dkg_id, pub_coeffs(), BTreeMap::new()); + locked_store.insert_transcript_data(dkg_id.clone(), pub_coeffs(), BTreeMap::new()); locked_store.insert_individual_public_key(dkg_id, node_id, public_key); } threshold_sig_data_store diff --git a/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs b/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs index 3ee75200de7..548bc1172d6 100644 --- a/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs +++ b/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs @@ -41,7 +41,13 @@ fn should_correctly_create_initial_dkg_config_for_single_node() { let dkg_tag = NiDkgTag::LowThreshold; let target_id = target_id(); - let config = InitialNiDkgConfig::new(&nodes_set, dealer_subnet, dkg_tag, target_id, REG_V1); + let config = InitialNiDkgConfig::new( + &nodes_set, + dealer_subnet, + dkg_tag.clone(), + target_id, + REG_V1, + ); assert_eq!( config.get().dkg_id(), @@ -74,7 +80,13 @@ fn should_correctly_create_initial_dkg_config() { let dkg_tag = NiDkgTag::LowThreshold; let target_id = target_id(); - let config = InitialNiDkgConfig::new(&nodes_set, dealer_subnet, dkg_tag, target_id, REG_V1); + let config = InitialNiDkgConfig::new( + &nodes_set, + dealer_subnet, + dkg_tag.clone(), + target_id, + REG_V1, + ); assert_eq!( config.get().dkg_id(), @@ -131,7 +143,7 @@ fn should_have_stable_internal_csp_transcript_cbor_serialization() { fn should_correctly_retrieve_initial_low_threshold_ni_dkg_transcript_from_registry() { let mut transcript = transcript(); let dkg_tag = NiDkgTag::LowThreshold; - transcript.dkg_id.dkg_tag = dkg_tag; + transcript.dkg_id.dkg_tag = dkg_tag.clone(); let registry = registry_with_ni_dkg_transcript( InitialNiDkgTranscriptRecord::from(transcript.clone()), dkg_tag, @@ -154,7 +166,7 @@ fn should_correctly_retrieve_initial_low_threshold_ni_dkg_transcript_from_regist fn should_correctly_retrieve_initial_high_threshold_ni_dkg_transcript_from_registry() { let mut transcript = transcript(); let dkg_tag = NiDkgTag::HighThreshold; - transcript.dkg_id.dkg_tag = dkg_tag; + transcript.dkg_id.dkg_tag = dkg_tag.clone(); let registry = registry_with_ni_dkg_transcript( InitialNiDkgTranscriptRecord::from(transcript.clone()), dkg_tag, diff --git a/rs/crypto/test_utils/ni-dkg/src/lib.rs b/rs/crypto/test_utils/ni-dkg/src/lib.rs index fc81be00512..61e9816343f 100644 --- a/rs/crypto/test_utils/ni-dkg/src/lib.rs +++ b/rs/crypto/test_utils/ni-dkg/src/lib.rs @@ -181,7 +181,7 @@ pub fn sign_threshold_for_each( .iter() .map(|signer| { let sig_share = crypto_for(*signer, crypto_components) - .sign_threshold(msg, dkg_id) + .sign_threshold(msg, dkg_id.clone()) .unwrap_or_else(|_| panic!("signing by node {:?} failed", signer)); (*signer, sig_share) }) @@ -566,8 +566,11 @@ impl RandomNiDkgConfig { receivers } }; - let dkg_tag = transcript.dkg_id.dkg_tag; + let dkg_tag = transcript.dkg_id.dkg_tag.clone(); let config_data = NiDkgConfigData { + threshold: Self::number_of_nodes_from_usize( + dkg_tag.threshold_for_subnet_of_size(new_subnet_size), + ), dkg_id: NiDkgId { start_block_height: Height::new(transcript.dkg_id.start_block_height.get() + 1), // Theoretically the subnet ID should change on the _first_ DKG in the new @@ -584,9 +587,6 @@ impl RandomNiDkgConfig { Self::number_of_nodes_from_usize(get_faults_tolerated(new_subnet_size)) }, receivers, - threshold: Self::number_of_nodes_from_usize( - dkg_tag.threshold_for_subnet_of_size(new_subnet_size), - ), registry_version, resharing_transcript: Some(transcript), }; @@ -607,6 +607,9 @@ impl RandomNiDkgConfig { let receivers = transcript.committee.get().clone(); let dkg_tag = transcript.dkg_id.dkg_tag; let config_data = NiDkgConfigData { + threshold: Self::number_of_nodes_from_usize( + dkg_tag.threshold_for_subnet_of_size(subnet_size), + ), dkg_id: NiDkgId { start_block_height: Height::new(transcript.dkg_id.start_block_height.get() + 1), // Theoretically the subnet ID should change on the _first_ DKG in the new @@ -623,9 +626,6 @@ impl RandomNiDkgConfig { Self::number_of_nodes_from_usize(get_faults_tolerated(subnet_size)) }, receivers, - threshold: Self::number_of_nodes_from_usize( - dkg_tag.threshold_for_subnet_of_size(subnet_size), - ), registry_version, resharing_transcript: None, }; diff --git a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs index 691c8c9b09c..64275e142ec 100644 --- a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs +++ b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs @@ -43,7 +43,7 @@ fn should_threshold_sign_if_sufficient_shares() { combiner: random_combiner, }, &msg, - dkg_id, + dkg_id.clone(), &crypto_components, ); let random_verifier = random_node_in(config.receivers().get(), rng); @@ -66,15 +66,19 @@ fn should_produce_valid_signature_shares() { let sig_shares = sign_threshold_for_each( &config.receivers().get().iter().copied().collect::>(), &msg, - dkg_id, + dkg_id.clone(), &crypto_components, ); let verifier = random_node_in(config.receivers().get(), rng); sig_shares.iter().for_each(|(signer, sig_share)| { assert_eq!( - crypto_for(verifier, &crypto_components) - .verify_threshold_sig_share(sig_share, &msg, dkg_id, *signer), + crypto_for(verifier, &crypto_components).verify_threshold_sig_share( + sig_share, + &msg, + dkg_id.clone(), + *signer + ), Ok(()), "node {:?} failed to verify threshold sig share of signer {:?}", verifier, @@ -113,7 +117,7 @@ fn should_load_transcript_and_validate_signature_shares_as_non_receiver_without_ let sig_shares = sign_threshold_for_each( &config.receivers().get().iter().copied().collect::>(), &msg, - dkg_id, + dkg_id.clone(), &crypto_components, ); @@ -133,7 +137,12 @@ fn should_load_transcript_and_validate_signature_shares_as_non_receiver_without_ // Verify the signature shares with the node that is not a receiver. sig_shares.iter().for_each(|(signer, sig_share)| { assert_eq!( - other_crypto_component.verify_threshold_sig_share(sig_share, &msg, dkg_id, *signer), + other_crypto_component.verify_threshold_sig_share( + sig_share, + &msg, + dkg_id.clone(), + *signer + ), Ok(()), "node {:?} failed to verify threshold sig share of signer {:?}", other_node_id, @@ -179,7 +188,7 @@ fn should_fail_to_combine_insufficient_shares() { let sig_shares = sign_threshold_for_each( &n_random_nodes_in(config.receivers().get(), num_of_shares_to_combine, rng), &message(), - dkg_id, + dkg_id.clone(), &crypto_components, ); let combination_result = crypto_for( @@ -278,7 +287,7 @@ fn threshold_sign_and_combine( let sig_shares = sign_threshold_for_each( &signers_and_combiner.signers, msg, - dkg_id, + dkg_id.clone(), crypto_components, ); crypto_for(signers_and_combiner.combiner, crypto_components) @@ -296,7 +305,7 @@ fn sign_threshold_for_each( .iter() .map(|signer| { let sig_share = crypto_for(*signer, crypto_components) - .sign_threshold(msg, dkg_id) + .sign_threshold(msg, dkg_id.clone()) .unwrap_or_else(|e| panic!("signing by node {:?} failed: {}", signer, e)); (*signer, sig_share) }) @@ -537,29 +546,41 @@ mod non_interactive_distributed_key_generation { assert_eq!(epoch1_nodes.difference(&epoch2_nodes).count(), 0); // Test that all nodes can sign in their own epoch - assert!(nodes_can_sign_in_epoch(&epoch0_nodes, dkg_id0, &env)); - assert!(nodes_can_sign_in_epoch(&epoch1_nodes, dkg_id1, &env)); - assert!(nodes_can_sign_in_epoch(&epoch2_nodes, dkg_id2, &env)); + assert!(nodes_can_sign_in_epoch( + &epoch0_nodes, + dkg_id0.clone(), + &env + )); + assert!(nodes_can_sign_in_epoch( + &epoch1_nodes, + dkg_id1.clone(), + &env + )); + assert!(nodes_can_sign_in_epoch( + &epoch2_nodes, + dkg_id2.clone(), + &env + )); // Test that nodes added later cannot sign in old epochs assert!( nodes_cannot_sign_in_epoch_due_to_missing_threshold_sig_data( &new_in_epoch1, - dkg_id0, + dkg_id0.clone(), &env ) ); assert!( nodes_cannot_sign_in_epoch_due_to_missing_threshold_sig_data( &new_in_epoch2, - dkg_id0, + dkg_id0.clone(), &env ) ); assert!( nodes_cannot_sign_in_epoch_due_to_missing_threshold_sig_data( &new_in_epoch2, - dkg_id1, + dkg_id1.clone(), &env ) ); @@ -581,7 +602,7 @@ mod non_interactive_distributed_key_generation { // Now nobody can sign in epoch0 since the keys have been removed assert!(nodes_cannot_sign_in_epoch_due_to_missing_secret_key( &epoch0_nodes, - dkg_id0, + dkg_id0.clone(), &env )); @@ -762,7 +783,7 @@ mod non_interactive_distributed_key_generation { rng, subnet_size, dealer_count, - threshold, + threshold.clone(), ); let overhead = (record_len as f64) / (expected_size as f64); @@ -809,7 +830,8 @@ mod non_interactive_distributed_key_generation { let msg = message(); for node in nodes { - let sig = crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id); + let sig = + crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id.clone()); if sig.is_err() { return false; } @@ -826,7 +848,8 @@ mod non_interactive_distributed_key_generation { let msg = message(); for node in nodes { - let sig = crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id); + let sig = + crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id.clone()); match sig { Ok(_) => return false, Err(CryptoError::SecretKeyNotFound { @@ -850,7 +873,8 @@ mod non_interactive_distributed_key_generation { let msg = message(); for node in nodes { - let sig = crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id); + let sig = + crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id.clone()); match sig { Ok(_) => return false, Err(CryptoError::ThresholdSigDataNotFound { diff --git a/rs/test_utilities/artifact_pool/src/consensus_pool.rs b/rs/test_utilities/artifact_pool/src/consensus_pool.rs index 3f4790dc8af..4345a5b16ec 100644 --- a/rs/test_utilities/artifact_pool/src/consensus_pool.rs +++ b/rs/test_utilities/artifact_pool/src/consensus_pool.rs @@ -584,7 +584,7 @@ impl TestConsensusPool { let content = RandomBeaconContent::new(height, ic_types::crypto::crypto_hash(&beacon)); let share = RandomBeaconShare { signature: crypto - .sign_threshold(&content, dkg_id) + .sign_threshold(&content, dkg_id.clone()) .map(|signature| ThresholdSignatureShare { signature, signer: node_id, diff --git a/rs/test_utilities/consensus/src/lib.rs b/rs/test_utilities/consensus/src/lib.rs index 286fe4921b7..1b2de4ce925 100755 --- a/rs/test_utilities/consensus/src/lib.rs +++ b/rs/test_utilities/consensus/src/lib.rs @@ -138,8 +138,8 @@ pub fn make_genesis(summary: dkg::Summary) -> CatchUpPackage { // created. let registry_version = summary.registry_version; let height = summary.height; - let low_dkg_id = summary.current_transcript(&NiDkgTag::LowThreshold).dkg_id; - let high_dkg_id = summary.current_transcript(&NiDkgTag::HighThreshold).dkg_id; + let low_dkg_id = summary.current_transcript(&NiDkgTag::LowThreshold).dkg_id.clone(); + let high_dkg_id = summary.current_transcript(&NiDkgTag::HighThreshold).dkg_id.clone(); let block = Block::new( Id::from(CryptoHash(Vec::new())), Payload::new( diff --git a/rs/test_utilities/src/crypto.rs b/rs/test_utilities/src/crypto.rs index 2489f476541..4a4ad00dec3 100644 --- a/rs/test_utilities/src/crypto.rs +++ b/rs/test_utilities/src/crypto.rs @@ -270,7 +270,7 @@ impl NiDkgAlgorithm for CryptoReturningOk { self.loaded_transcripts .write() .unwrap() - .insert(transcript.dkg_id); + .insert(transcript.dkg_id.clone()); Ok(LoadTranscriptResult::SigningKeyAvailable) } @@ -281,7 +281,7 @@ impl NiDkgAlgorithm for CryptoReturningOk { self.retained_transcripts .write() .unwrap() - .push(transcripts.iter().map(|t| t.dkg_id).collect()); + .push(transcripts.into_iter().map(|t| t.dkg_id).collect()); Ok(()) } } diff --git a/rs/types/types/src/consensus.rs b/rs/types/types/src/consensus.rs index 76adeb928fc..43025304270 100644 --- a/rs/types/types/src/consensus.rs +++ b/rs/types/types/src/consensus.rs @@ -654,7 +654,7 @@ impl From<&RandomBeacon> for pb::RandomBeacon { height: random_beacon.content.height.get(), parent: random_beacon.content.parent.clone().get().0, signature: random_beacon.signature.signature.clone().get().0, - signer: Some(pb::NiDkgId::from(random_beacon.signature.signer)), + signer: Some(pb::NiDkgId::from(random_beacon.signature.signer.clone())), } } } @@ -749,7 +749,7 @@ impl From<&RandomTape> for pb::RandomTape { version: random_tape.content.version.to_string(), height: random_tape.content.height.get(), signature: random_tape.signature.signature.clone().get().0, - signer: Some(pb::NiDkgId::from(random_tape.signature.signer)), + signer: Some(pb::NiDkgId::from(random_tape.signature.signer.clone())), } } } diff --git a/rs/types/types/src/consensus/catchup.rs b/rs/types/types/src/consensus/catchup.rs index a9f8a3db2fe..a7a58f961a2 100644 --- a/rs/types/types/src/consensus/catchup.rs +++ b/rs/types/types/src/consensus/catchup.rs @@ -207,7 +207,7 @@ pub type CatchUpContentHash = CryptoHashOf; impl From<&CatchUpPackage> for pb::CatchUpPackage { fn from(cup: &CatchUpPackage) -> Self { Self { - signer: Some(pb::NiDkgId::from(cup.signature.signer)), + signer: Some(pb::NiDkgId::from(cup.signature.signer.clone())), signature: cup.signature.signature.clone().get().0, content: pb::CatchUpContent::from(&cup.content).as_protobuf_vec(), } diff --git a/rs/types/types/src/consensus/dkg.rs b/rs/types/types/src/consensus/dkg.rs index 2706d5a2a6e..61e3bf209b4 100644 --- a/rs/types/types/src/consensus/dkg.rs +++ b/rs/types/types/src/consensus/dkg.rs @@ -247,7 +247,10 @@ impl Summary { let mut next_transcripts = self.next_transcripts; self.current_transcripts .into_iter() - .map(|(tag, current)| (tag, next_transcripts.remove(&tag).unwrap_or(current))) + .map(|(tag, current)| { + let new_next_transcripts = next_transcripts.remove(&tag).unwrap_or(current); + (tag, new_next_transcripts) + }) .collect() } @@ -308,7 +311,7 @@ fn build_callback_ided_transcripts_vec( .iter() .map( |(id, callback_id, transcript_result)| pb::CallbackIdedNiDkgTranscript { - dkg_id: Some(pb::NiDkgId::from(*id)), + dkg_id: Some(pb::NiDkgId::from(id.clone())), transcript_result: match transcript_result { Ok(transcript) => Some(pb::NiDkgTranscriptResult { val: Some(pb::ni_dkg_transcript_result::Val::Transcript( @@ -452,7 +455,7 @@ impl TryFrom for Summary { configs: summary .configs .into_iter() - .map(|config| NiDkgConfig::try_from(config).map(|c| (c.dkg_id, c))) + .map(|config| NiDkgConfig::try_from(config).map(|c| (c.dkg_id.clone(), c))) .collect::, _>>() .map_err(ProxyDecodeError::Other)?, current_transcripts: build_tagged_transcripts_map(&summary.current_transcripts)?, diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs index 7fa2dddd134..8387ebd803d 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs @@ -9,6 +9,7 @@ use core::fmt; use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::{CspNiDkgDealing, CspNiDkgTranscript}; #[cfg(test)] use ic_exhaustive_derive::ExhaustiveSet; +// use ic_management_canister_types::MasterPublicKeyId; use ic_protobuf::types::v1 as pb; use ic_protobuf::types::v1::NiDkgId as NiDkgIdProto; use serde::{Deserialize, Serialize}; @@ -31,13 +32,14 @@ mod tests; /// Allows to distinguish protocol executions in high and low threshold /// settings. -#[derive( - Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, EnumIter, Serialize, +#[derive( + Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, EnumIter, Serialize, )] #[cfg_attr(test, derive(ExhaustiveSet))] pub enum NiDkgTag { LowThreshold = 1, HighThreshold = 2, + // HighThresholdForKey(MasterPublicKeyId) = 3, } impl From<&NiDkgTag> for pb::NiDkgTag { @@ -174,7 +176,7 @@ impl From<&NiDkgTranscript> for CspPublicCoefficients { impl From<&NiDkgTranscript> for pb::NiDkgTranscript { fn from(transcript: &NiDkgTranscript) -> Self { Self { - dkg_id: Some(pb::NiDkgId::from(transcript.dkg_id)), + dkg_id: Some(pb::NiDkgId::from(transcript.dkg_id.clone())), threshold: transcript.threshold.get().get(), committee: transcript .committee diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/config.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/config.rs index 953889170c1..4fd2fc5dafc 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/config.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/config.rs @@ -37,7 +37,7 @@ pub struct NiDkgConfig { impl From<&NiDkgConfig> for pb::NiDkgConfig { fn from(config: &NiDkgConfig) -> Self { Self { - dkg_id: Some(pb::NiDkgId::from(config.dkg_id)), + dkg_id: Some(pb::NiDkgId::from(config.dkg_id.clone())), max_corrupt_dealers: config.max_corrupt_dealers.get(), dealers: config .dealers @@ -169,7 +169,10 @@ impl NiDkgConfig { } pub fn dkg_id(&self) -> NiDkgId { - self.dkg_id + //////////////////////////// + // TODO: ideally now a reference is returned, but there are many callers... + //////////////////////////// + self.dkg_id.clone() } pub fn max_corrupt_dealers(&self) -> NumberOfNodes { diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs index 99c97478849..66985cd50a4 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs @@ -8,7 +8,7 @@ use ic_protobuf::types::v1 as pb; mod tests; /// The ID for non-interactive DKG. Identifies a DKG epoch. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, Serialize)] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, Serialize)] #[cfg_attr(test, derive(ExhaustiveSet))] pub struct NiDkgId { /// This field refers to the height of the block denoting the start of the From 808aa1d203337259f4c8b68da6bd3ff750dca43b Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 31 Oct 2024 09:24:04 +0000 Subject: [PATCH 02/30] More fixes --- rs/orchestrator/src/upgrade.rs | 2 +- rs/test_utilities/consensus/src/lib.rs | 10 ++++++++-- rs/types/types/src/crypto/threshold_sig/ni_dkg.rs | 4 +--- .../src/crypto/threshold_sig/ni_dkg/config/tests.rs | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/rs/orchestrator/src/upgrade.rs b/rs/orchestrator/src/upgrade.rs index cf01f282602..c497d84d13b 100644 --- a/rs/orchestrator/src/upgrade.rs +++ b/rs/orchestrator/src/upgrade.rs @@ -561,7 +561,7 @@ fn get_subnet_id(registry: &dyn RegistryClient, cup: &CatchUpPackage) -> Result< // Note that although sometimes CUPs have no signatures (e.g. genesis and // recovery CUPs) they always have the signer id (the DKG id), which is taken // from the high-threshold transcript when we build a genesis/recovery CUP. - let dkg_id = cup.signature.signer; + let dkg_id = cup.signature.signer.clone(); // If the DKG key material was signed by the subnet itself — use it, if not, get // the subnet id from the registry. match dkg_id.target_subnet { diff --git a/rs/test_utilities/consensus/src/lib.rs b/rs/test_utilities/consensus/src/lib.rs index 1b2de4ce925..6888ff6205d 100755 --- a/rs/test_utilities/consensus/src/lib.rs +++ b/rs/test_utilities/consensus/src/lib.rs @@ -138,8 +138,14 @@ pub fn make_genesis(summary: dkg::Summary) -> CatchUpPackage { // created. let registry_version = summary.registry_version; let height = summary.height; - let low_dkg_id = summary.current_transcript(&NiDkgTag::LowThreshold).dkg_id.clone(); - let high_dkg_id = summary.current_transcript(&NiDkgTag::HighThreshold).dkg_id.clone(); + let low_dkg_id = summary + .current_transcript(&NiDkgTag::LowThreshold) + .dkg_id + .clone(); + let high_dkg_id = summary + .current_transcript(&NiDkgTag::HighThreshold) + .dkg_id + .clone(); let block = Block::new( Id::from(CryptoHash(Vec::new())), Payload::new( diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs index 8387ebd803d..d2db020d82f 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs @@ -32,9 +32,7 @@ mod tests; /// Allows to distinguish protocol executions in high and low threshold /// settings. -#[derive( - Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, EnumIter, Serialize, -)] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, EnumIter, Serialize)] #[cfg_attr(test, derive(ExhaustiveSet))] pub enum NiDkgTag { LowThreshold = 1, diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/config/tests.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/config/tests.rs index bd0f6e12afe..502836b05e6 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/config/tests.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/config/tests.rs @@ -203,7 +203,7 @@ fn should_return_correct_config_values() { let resharing_transcript = Some(transcript()); let config_data = NiDkgConfigData { - dkg_id, + dkg_id: dkg_id.clone(), max_corrupt_dealers, dealers: dealers.clone(), max_corrupt_receivers, From 9cb80e81006eddf5ac7c183075fb45ca0ab879df Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 04:51:57 +0000 Subject: [PATCH 03/30] Take NiDkgId as ref in combine_threshold_sig_shares --- rs/consensus/utils/src/crypto.rs | 2 +- rs/crypto/benches/threshold_sig.rs | 4 ++-- rs/crypto/src/sign/mod.rs | 7 ++----- rs/crypto/temp_crypto/src/lib.rs | 2 +- rs/crypto/tests/threshold_sigs_with_ni_dkg.rs | 4 ++-- rs/interfaces/src/crypto/sign/threshold_sig.rs | 2 +- rs/test_utilities/src/crypto.rs | 2 +- 7 files changed, 10 insertions(+), 13 deletions(-) diff --git a/rs/consensus/utils/src/crypto.rs b/rs/consensus/utils/src/crypto.rs index 7a8bccf2407..1a9d473f841 100644 --- a/rs/consensus/utils/src/crypto.rs +++ b/rs/consensus/utils/src/crypto.rs @@ -406,7 +406,7 @@ impl + ThresholdSigVerifier( }, |(sig_shares, combiner)| { assert!(combiner - .combine_threshold_sig_shares(sig_shares, dkg_id.clone()) + .combine_threshold_sig_shares(sig_shares, &dkg_id) .is_ok()); }, SmallInput, @@ -338,7 +338,7 @@ fn bench_verify_threshold_sig_combined( let sig_shares = sign_threshold_for_each(nodes, &message, dkg_id.clone(), crypto_components); let threshold_sig = crypto_for(random_node(nodes, rng), crypto_components) - .combine_threshold_sig_shares(sig_shares, dkg_id.clone()) + .combine_threshold_sig_shares(sig_shares, &dkg_id) .expect("failed to combine threshold signature shares"); let verifier = crypto_for(random_node(nodes, rng), crypto_components); (threshold_sig, message, verifier) diff --git a/rs/crypto/src/sign/mod.rs b/rs/crypto/src/sign/mod.rs index 81cf75c271c..b8479e9dac7 100644 --- a/rs/crypto/src/sign/mod.rs +++ b/rs/crypto/src/sign/mod.rs @@ -524,13 +524,10 @@ impl ThresholdSigVerifier for CryptoCo result } - ////////////////////////////////////////////// - // TODO: dkg_id as reference - ////////////////////////////////////////////// fn combine_threshold_sig_shares( &self, shares: BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult> { let log_id = get_log_id(&self.logger); let logger = new_logger!(&self.logger; @@ -548,7 +545,7 @@ impl ThresholdSigVerifier for CryptoCo &self.lockable_threshold_sig_data_store, &self.csp, shares, - &dkg_id, + dkg_id, ); self.metrics.observe_duration_seconds( MetricsDomain::ThresholdSignature, diff --git a/rs/crypto/temp_crypto/src/lib.rs b/rs/crypto/temp_crypto/src/lib.rs index 7013dcf7f69..ed6977a2451 100644 --- a/rs/crypto/temp_crypto/src/lib.rs +++ b/rs/crypto/temp_crypto/src/lib.rs @@ -860,7 +860,7 @@ pub mod internal { fn combine_threshold_sig_shares( &self, shares: BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult> { self.crypto_component .combine_threshold_sig_shares(shares, dkg_id) diff --git a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs index 64275e142ec..d1fb3fa8d5d 100644 --- a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs +++ b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs @@ -195,7 +195,7 @@ fn should_fail_to_combine_insufficient_shares() { random_node_in(config.receivers().get(), rng), &crypto_components, ) - .combine_threshold_sig_shares(sig_shares, dkg_id); + .combine_threshold_sig_shares(sig_shares, &dkg_id); assert_eq!( combination_result.unwrap_err(), @@ -291,7 +291,7 @@ fn threshold_sign_and_combine( crypto_components, ); crypto_for(signers_and_combiner.combiner, crypto_components) - .combine_threshold_sig_shares(sig_shares, dkg_id) + .combine_threshold_sig_shares(sig_shares, &dkg_id) .expect("failed to combine signature shares") } diff --git a/rs/interfaces/src/crypto/sign/threshold_sig.rs b/rs/interfaces/src/crypto/sign/threshold_sig.rs index e6feb27dff0..e49dea91e44 100644 --- a/rs/interfaces/src/crypto/sign/threshold_sig.rs +++ b/rs/interfaces/src/crypto/sign/threshold_sig.rs @@ -89,7 +89,7 @@ pub trait ThresholdSigVerifier { fn combine_threshold_sig_shares( &self, shares: BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult>; /// Verifies a combined threshold signature. diff --git a/rs/test_utilities/src/crypto.rs b/rs/test_utilities/src/crypto.rs index 4a4ad00dec3..64ebdc4c834 100644 --- a/rs/test_utilities/src/crypto.rs +++ b/rs/test_utilities/src/crypto.rs @@ -195,7 +195,7 @@ impl ThresholdSigVerifier for CryptoReturningOk { fn combine_threshold_sig_shares( &self, _shares: BTreeMap>, - _dkg_id: NiDkgId, + _dkg_id: &NiDkgId, ) -> CryptoResult> { Ok(CombinedThresholdSigOf::new(CombinedThresholdSig(vec![]))) } From 4461616b32cca63f431942dbcff20c6b88bcc8d4 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 05:00:06 +0000 Subject: [PATCH 04/30] Take NiDkgId as ref in verify_threshold_sig_combined --- rs/consensus/utils/src/crypto.rs | 2 +- rs/crypto/benches/threshold_sig.rs | 2 +- rs/crypto/src/sign/mod.rs | 7 ++----- rs/crypto/temp_crypto/src/lib.rs | 2 +- rs/crypto/tests/threshold_sigs_with_ni_dkg.rs | 2 +- rs/interfaces/src/crypto/sign/threshold_sig.rs | 2 +- rs/test_utilities/src/crypto.rs | 2 +- 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/rs/consensus/utils/src/crypto.rs b/rs/consensus/utils/src/crypto.rs index 1a9d473f841..a63cf4c0d27 100644 --- a/rs/consensus/utils/src/crypto.rs +++ b/rs/consensus/utils/src/crypto.rs @@ -422,7 +422,7 @@ impl + ThresholdSigVerifier( }, |(threshold_sig, message, verifier)| { assert!(verifier - .verify_threshold_sig_combined(&threshold_sig, &message, dkg_id.clone()) + .verify_threshold_sig_combined(&threshold_sig, &message, &dkg_id) .is_ok()); }, SmallInput, diff --git a/rs/crypto/src/sign/mod.rs b/rs/crypto/src/sign/mod.rs index b8479e9dac7..62bc99f4260 100644 --- a/rs/crypto/src/sign/mod.rs +++ b/rs/crypto/src/sign/mod.rs @@ -563,14 +563,11 @@ impl ThresholdSigVerifier for CryptoCo result } - ////////////////////////////////////////////// - // TODO: dkg_id as reference - ////////////////////////////////////////////// fn verify_threshold_sig_combined( &self, signature: &CombinedThresholdSigOf, message: &T, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult<()> { let log_id = get_log_id(&self.logger); let logger = new_logger!(&self.logger; @@ -590,7 +587,7 @@ impl ThresholdSigVerifier for CryptoCo &self.csp, signature, message, - &dkg_id, + dkg_id, ); self.metrics.observe_duration_seconds( MetricsDomain::ThresholdSignature, diff --git a/rs/crypto/temp_crypto/src/lib.rs b/rs/crypto/temp_crypto/src/lib.rs index ed6977a2451..98048131dde 100644 --- a/rs/crypto/temp_crypto/src/lib.rs +++ b/rs/crypto/temp_crypto/src/lib.rs @@ -870,7 +870,7 @@ pub mod internal { &self, signature: &CombinedThresholdSigOf, message: &T, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult<()> { self.crypto_component .verify_threshold_sig_combined(signature, message, dkg_id) diff --git a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs index d1fb3fa8d5d..7e7dd83ff73 100644 --- a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs +++ b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs @@ -48,7 +48,7 @@ fn should_threshold_sign_if_sufficient_shares() { ); let random_verifier = random_node_in(config.receivers().get(), rng); let verify_combined_result = crypto_for(random_verifier, &crypto_components) - .verify_threshold_sig_combined(&combined_sig, &msg, dkg_id); + .verify_threshold_sig_combined(&combined_sig, &msg, &dkg_id); assert_eq!(verify_combined_result, Ok(())); } diff --git a/rs/interfaces/src/crypto/sign/threshold_sig.rs b/rs/interfaces/src/crypto/sign/threshold_sig.rs index e49dea91e44..d2788a50eba 100644 --- a/rs/interfaces/src/crypto/sign/threshold_sig.rs +++ b/rs/interfaces/src/crypto/sign/threshold_sig.rs @@ -111,7 +111,7 @@ pub trait ThresholdSigVerifier { &self, signature: &CombinedThresholdSigOf, message: &T, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult<()>; } diff --git a/rs/test_utilities/src/crypto.rs b/rs/test_utilities/src/crypto.rs index 64ebdc4c834..8022eb44936 100644 --- a/rs/test_utilities/src/crypto.rs +++ b/rs/test_utilities/src/crypto.rs @@ -204,7 +204,7 @@ impl ThresholdSigVerifier for CryptoReturningOk { &self, _signature: &CombinedThresholdSigOf, _message: &T, - _dkg_id: NiDkgId, + _dkg_id: &NiDkgId, ) -> CryptoResult<()> { Ok(()) } From 0ae9cdc6ff5f9dd47eee7665dee3e9cb2a329785 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 10:06:38 +0000 Subject: [PATCH 05/30] Take NiDkgId as ref at more places --- rs/consensus/utils/src/crypto.rs | 4 +- rs/crypto/benches/threshold_sig.rs | 63 +++----- rs/crypto/src/sign/mod.rs | 8 +- rs/crypto/src/sign/threshold_sig.rs | 21 ++- .../sign/threshold_sig/ni_dkg/transcript.rs | 4 +- rs/crypto/src/sign/threshold_sig/store.rs | 22 ++- .../src/sign/threshold_sig/store/tests.rs | 52 +++---- rs/crypto/src/sign/threshold_sig/tests.rs | 141 +++++++++--------- rs/crypto/temp_crypto/src/lib.rs | 4 +- rs/crypto/test_utils/ni-dkg/src/lib.rs | 4 +- rs/crypto/tests/threshold_sigs_with_ni_dkg.rs | 78 ++++------ .../src/crypto/sign/threshold_sig.rs | 4 +- .../artifact_pool/src/consensus_pool.rs | 2 +- rs/test_utilities/src/crypto.rs | 4 +- 14 files changed, 182 insertions(+), 229 deletions(-) diff --git a/rs/consensus/utils/src/crypto.rs b/rs/consensus/utils/src/crypto.rs index a63cf4c0d27..2729a06c9f8 100644 --- a/rs/consensus/utils/src/crypto.rs +++ b/rs/consensus/utils/src/crypto.rs @@ -199,7 +199,7 @@ impl + ThresholdSigVerifier CryptoResult> { - self.sign_threshold(message, dkg_id) + self.sign_threshold(message, &dkg_id) .map(|signature| ThresholdSignatureShare { signature, signer }) } @@ -212,7 +212,7 @@ where { self.verify_threshold_sig_share( &message.signature.signature, &message.content, - dkg_id, + &dkg_id, message.signature.signer, ) } diff --git a/rs/crypto/benches/threshold_sig.rs b/rs/crypto/benches/threshold_sig.rs index 530ead54673..a06c450b25d 100644 --- a/rs/crypto/benches/threshold_sig.rs +++ b/rs/crypto/benches/threshold_sig.rs @@ -115,7 +115,7 @@ fn bench_threshold_sig_n_nodes( group, &nodes_in_subnet, &env.crypto_components, - dkg_id.clone(), + &dkg_id, message_size, rng, ); @@ -125,7 +125,7 @@ fn bench_threshold_sig_n_nodes( group, &nodes_in_subnet, &env.crypto_components, - dkg_id.clone(), + &dkg_id, message_size, rng, ); @@ -133,7 +133,7 @@ fn bench_threshold_sig_n_nodes( group, &nodes_in_subnet, &env.crypto_components, - dkg_id.clone(), + &dkg_id, &transcript, message_size, rng, @@ -143,7 +143,7 @@ fn bench_threshold_sig_n_nodes( group, &threshold_many_random_subnet_nodes, &env.crypto_components, - dkg_id.clone(), + &dkg_id, message_size, rng, ); @@ -151,7 +151,7 @@ fn bench_threshold_sig_n_nodes( group, &threshold_many_random_subnet_nodes, &env.crypto_components, - dkg_id, + &dkg_id, message_size, rng, ); @@ -162,7 +162,7 @@ fn bench_threshold_sign( group: &mut BenchmarkGroup<'_, M>, nodes_in_subnet: &[NodeId], crypto_components: &BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, message_size: usize, rng: &mut R, ) { @@ -174,7 +174,7 @@ fn bench_threshold_sign( (message, signer) }, |(message, signer)| { - assert!(signer.sign_threshold(&message, dkg_id.clone()).is_ok()); + assert!(signer.sign_threshold(&message, dkg_id).is_ok()); }, SmallInput, ) @@ -185,7 +185,7 @@ fn bench_verify_threshold_sig_share_incl_loading_pubkey, nodes_in_subnet: &[NodeId], crypto_components: &BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, transcript: &NiDkgTranscript, message_size: usize, rng: &mut R, @@ -202,7 +202,7 @@ fn bench_verify_threshold_sig_share_incl_loading_pubkey, nodes_in_subnet: &[NodeId], crypto_components: &BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, message_size: usize, rng: &mut R, ) { @@ -255,7 +250,7 @@ fn bench_verify_threshold_sig_share_excl_loading_pubkey( group: &mut BenchmarkGroup<'_, M>, nodes: &[NodeId], crypto_components: &BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, message_size: usize, rng: &mut R, ) { @@ -306,13 +291,13 @@ fn bench_combine_threshold_sig_shares( || { let message = signable_with_random_bytes(message_size, rng); let sig_shares = - sign_threshold_for_each(nodes, &message, dkg_id.clone(), crypto_components); + sign_threshold_for_each(nodes, &message, dkg_id, crypto_components); let combiner = crypto_for(random_node(nodes, rng), crypto_components); (sig_shares, combiner) }, |(sig_shares, combiner)| { assert!(combiner - .combine_threshold_sig_shares(sig_shares, &dkg_id) + .combine_threshold_sig_shares(sig_shares, dkg_id) .is_ok()); }, SmallInput, @@ -325,7 +310,7 @@ fn bench_verify_threshold_sig_combined( group: &mut BenchmarkGroup<'_, M>, nodes: &[NodeId], crypto_components: &BTreeMap>, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, message_size: usize, rng: &mut R, ) { @@ -336,16 +321,16 @@ fn bench_verify_threshold_sig_combined( || { let message = signable_with_random_bytes(message_size, rng); let sig_shares = - sign_threshold_for_each(nodes, &message, dkg_id.clone(), crypto_components); + sign_threshold_for_each(nodes, &message, dkg_id, crypto_components); let threshold_sig = crypto_for(random_node(nodes, rng), crypto_components) - .combine_threshold_sig_shares(sig_shares, &dkg_id) + .combine_threshold_sig_shares(sig_shares, dkg_id) .expect("failed to combine threshold signature shares"); let verifier = crypto_for(random_node(nodes, rng), crypto_components); (threshold_sig, message, verifier) }, |(threshold_sig, message, verifier)| { assert!(verifier - .verify_threshold_sig_combined(&threshold_sig, &message, &dkg_id) + .verify_threshold_sig_combined(&threshold_sig, &message, dkg_id) .is_ok()); }, SmallInput, @@ -370,7 +355,7 @@ fn random_nodes(nodes: &[NodeId], n: usize, rng: &mut R) -> /// dummy transcripts derived from `transcript` until the maximum storage /// capacity is reached. fn purge_dkg_id_from_data_store( - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node: &TempCryptoComponentGeneric, transcript: &NiDkgTranscript, ) { @@ -383,7 +368,7 @@ fn purge_dkg_id_from_data_store( .expect("overflow") { dummy_transcript.dkg_id.start_block_height += Height::from(1); - assert_ne!(dummy_transcript.dkg_id, dkg_id); + assert_ne!(&dummy_transcript.dkg_id, dkg_id); assert!(node.load_transcript(&dummy_transcript).is_ok()); } diff --git a/rs/crypto/src/sign/mod.rs b/rs/crypto/src/sign/mod.rs index 62bc99f4260..668e462383e 100644 --- a/rs/crypto/src/sign/mod.rs +++ b/rs/crypto/src/sign/mod.rs @@ -443,7 +443,11 @@ impl MultiSigVerifier for CryptoCompon impl ThresholdSigner for CryptoComponentImpl { // TODO (CRP-479): switch to Result, // ThresholdSigDataNotFoundError> - fn sign_threshold(&self, message: &T, dkg_id: NiDkgId) -> CryptoResult> { + fn sign_threshold( + &self, + message: &T, + dkg_id: &NiDkgId, + ) -> CryptoResult> { let log_id = get_log_id(&self.logger); let logger = new_logger!(&self.logger; crypto.log_id => log_id, @@ -484,7 +488,7 @@ impl ThresholdSigVerifier for CryptoCo &self, signature: &ThresholdSigShareOf, message: &T, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, signer: NodeId, ) -> CryptoResult<()> { let log_id = get_log_id(&self.logger); diff --git a/rs/crypto/src/sign/threshold_sig.rs b/rs/crypto/src/sign/threshold_sig.rs index 017a5f14937..689f493de1e 100644 --- a/rs/crypto/src/sign/threshold_sig.rs +++ b/rs/crypto/src/sign/threshold_sig.rs @@ -22,23 +22,20 @@ mod tests; pub struct ThresholdSignerInternal {} impl ThresholdSignerInternal { - ////////////////////////////////////////////// - // TODO: dkg_id as reference (assuming error is unlikely) - ////////////////////////////////////////////// pub fn sign_threshold( lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, threshold_sig_csp_client: &C, message: &H, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> Result, ThresholdSignError> { - let pub_coeffs = pub_coeffs_from_store(&dkg_id, lockable_threshold_sig_data_store)?; + let pub_coeffs = pub_coeffs_from_store(dkg_id, lockable_threshold_sig_data_store)?; let csp_signature = threshold_sig_csp_client .threshold_sign( AlgorithmId::from(&pub_coeffs), message.as_signed_bytes(), pub_coeffs, ) - .map_err(|error| map_threshold_sign_error_or_panic(error, dkg_id))?; + .map_err(|error| map_threshold_sign_error_or_panic(error, dkg_id.clone()))?; threshold_sig_share_or_panic(csp_signature) } } @@ -143,7 +140,7 @@ impl ThresholdSigVerifierInternal { threshold_sig_csp_client: &C, signature: &ThresholdSigShareOf, message: &H, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, signer: NodeId, ) -> CryptoResult<()> { let csp_signature = CspSignature::try_from(signature)?; @@ -194,10 +191,10 @@ impl ThresholdSigVerifierInternal { fn lazily_calculated_public_key_from_store( lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, threshold_sig_csp_client: &C, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, ) -> CryptoResult { - match public_key_from_store(lockable_threshold_sig_data_store, &dkg_id, node_id) { + match public_key_from_store(lockable_threshold_sig_data_store, dkg_id, node_id) { Some(public_key) => Ok(public_key), None => calculate_and_store_public_key_or_panic( lockable_threshold_sig_data_store, @@ -222,11 +219,11 @@ fn public_key_from_store( fn calculate_and_store_public_key_or_panic( lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, threshold_sig_csp_client: &C, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, ) -> CryptoResult { - let transcript_data = transcript_data_from_store(&dkg_id, lockable_threshold_sig_data_store)?; - let (public_coeffs, node_index) = coeffs_and_index(transcript_data, &dkg_id, node_id)?; + let transcript_data = transcript_data_from_store(dkg_id, lockable_threshold_sig_data_store)?; + let (public_coeffs, node_index) = coeffs_and_index(transcript_data, dkg_id, node_id)?; let public_key = threshold_sig_csp_client .threshold_individual_public_key( AlgorithmId::from(&public_coeffs), diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs index 0258c812d87..3972dcdf525 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs @@ -239,7 +239,7 @@ mod loading { insert_transcript_data_into_store( lockable_threshold_sig_data_store, &csp_transcript, - transcript.dkg_id.clone(), + &transcript.dkg_id, &transcript.committee, ); let epoch = epoch(transcript.registry_version); @@ -324,7 +324,7 @@ mod loading { fn insert_transcript_data_into_store( lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, csp_transcript: &CspNiDkgTranscript, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, committee: &NiDkgReceivers, ) { lockable_threshold_sig_data_store diff --git a/rs/crypto/src/sign/threshold_sig/store.rs b/rs/crypto/src/sign/threshold_sig/store.rs index 060eb41d9c9..3a78f843d4a 100644 --- a/rs/crypto/src/sign/threshold_sig/store.rs +++ b/rs/crypto/src/sign/threshold_sig/store.rs @@ -23,7 +23,7 @@ pub trait ThresholdSigDataStore { /// before. fn insert_transcript_data( &mut self, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, public_coefficients: CspPublicCoefficients, indices: BTreeMap, ); @@ -35,7 +35,7 @@ pub trait ThresholdSigDataStore { /// with the given `dkg_id`, this key will be overwritten. fn insert_individual_public_key( &mut self, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, individual_public_key: CspThresholdSigPublicKey, ); @@ -133,8 +133,8 @@ impl ThresholdSigDataStoreImpl { } #[allow(clippy::map_entry)] - fn entry_for(&mut self, dkg_id: NiDkgId) -> &mut ThresholdSigData { - if !self.store.contains_key(&dkg_id) { + fn entry_for(&mut self, dkg_id: &NiDkgId) -> &mut ThresholdSigData { + if !self.store.contains_key(dkg_id) { self.store .insert(dkg_id.clone(), ThresholdSigData::default()); match dkg_id.dkg_tag { @@ -149,11 +149,11 @@ impl ThresholdSigDataStoreImpl { } } self.store - .get_mut(&dkg_id) + .get_mut(dkg_id) .expect("Missing dkg id from store") } - fn purge_entry_for_oldest_dkg_id_if_necessary(&mut self, tag: NiDkgTag) { + fn purge_entry_for_oldest_dkg_id_if_necessary(&mut self, tag: &NiDkgTag) { let dkg_id_insertion_order = match tag { NiDkgTag::LowThreshold => &mut self.low_threshold_dkg_id_insertion_order, NiDkgTag::HighThreshold => &mut self.high_threshold_dkg_id_insertion_order, @@ -180,34 +180,32 @@ impl ThresholdSigDataStoreImpl { impl ThresholdSigDataStore for ThresholdSigDataStoreImpl { fn insert_transcript_data( &mut self, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, public_coefficients: CspPublicCoefficients, indices: BTreeMap, ) { - let dkg_tag = dkg_id.dkg_tag.clone(); let data = self.entry_for(dkg_id); data.transcript_data = Some(TranscriptData { public_coeffs: public_coefficients, indices, }); - self.purge_entry_for_oldest_dkg_id_if_necessary(dkg_tag); + self.purge_entry_for_oldest_dkg_id_if_necessary(&dkg_id.dkg_tag); self.assert_length_invariant(); } fn insert_individual_public_key( &mut self, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, public_key: CspThresholdSigPublicKey, ) { - let dkg_tag = dkg_id.dkg_tag.clone(); self.entry_for(dkg_id) .public_keys .get_or_insert_with(BTreeMap::new) .insert(node_id, public_key); - self.purge_entry_for_oldest_dkg_id_if_necessary(dkg_tag); + self.purge_entry_for_oldest_dkg_id_if_necessary(&dkg_id.dkg_tag); self.assert_length_invariant(); } diff --git a/rs/crypto/src/sign/threshold_sig/store/tests.rs b/rs/crypto/src/sign/threshold_sig/store/tests.rs index a4fff5dbe3a..542543e426a 100644 --- a/rs/crypto/src/sign/threshold_sig/store/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/store/tests.rs @@ -14,10 +14,10 @@ const NODE_2_INDEX: NodeIndex = 2; #[test] fn should_contain_transcript_data_after_insertion_with_nidkg_id() { - should_contain_transcript_data_after_insertion_with_dkg_id(NI_DKG_ID_1); + should_contain_transcript_data_after_insertion_with_dkg_id(&NI_DKG_ID_1); } -fn should_contain_transcript_data_after_insertion_with_dkg_id(dkg_id: NiDkgId) { +fn should_contain_transcript_data_after_insertion_with_dkg_id(dkg_id: &NiDkgId) { let mut store = ThresholdSigDataStoreImpl::new(); let indices = indices_with(vec![ (node_test_id(NODE_1), NODE_1_INDEX), @@ -25,9 +25,9 @@ fn should_contain_transcript_data_after_insertion_with_dkg_id(dkg_id: NiDkgId) { ]); let public_coeffs = public_coeffs(); - store.insert_transcript_data(dkg_id.clone(), public_coeffs.clone(), indices); + store.insert_transcript_data(dkg_id, public_coeffs.clone(), indices); - let transcript_data = store.transcript_data(&dkg_id).unwrap(); + let transcript_data = store.transcript_data(dkg_id).unwrap(); assert_eq!(transcript_data.public_coefficients(), &public_coeffs); assert_eq!( transcript_data.index(node_test_id(NODE_1)), @@ -52,7 +52,7 @@ fn should_contain_individual_public_keys_after_insertion_with_nidkg_id() { let mut store = ThresholdSigDataStoreImpl::new(); let csp_pubkey = csp_public_key(); - store.insert_individual_public_key(dkg_id.clone(), node_test_id(NODE_1), csp_pubkey); + store.insert_individual_public_key(&dkg_id, node_test_id(NODE_1), csp_pubkey); assert_eq!( store.individual_public_key(&dkg_id, node_test_id(NODE_1)), @@ -67,9 +67,9 @@ fn should_insert_multiple_individual_public_keys() { let csp_pubkey_2 = csp_public_key(); assert_ne!(NI_DKG_ID_1, NI_DKG_ID_2); - store.insert_individual_public_key(NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_1); - store.insert_individual_public_key(NI_DKG_ID_1, node_test_id(NODE_2), csp_pubkey_2); - store.insert_individual_public_key(NI_DKG_ID_2, node_test_id(NODE_1), csp_pubkey_2); + store.insert_individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_1); + store.insert_individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_2), csp_pubkey_2); + store.insert_individual_public_key(&NI_DKG_ID_2, node_test_id(NODE_1), csp_pubkey_2); assert_eq!( store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1)), @@ -101,8 +101,8 @@ fn should_overwrite_existing_public_coefficients() { let (public_coeffs_1, public_coeffs_2) = (public_coeffs_1(), public_coeffs_2()); assert_ne!(public_coeffs_1, public_coeffs_2); - store.insert_transcript_data(NI_DKG_ID_1, public_coeffs_1, BTreeMap::new()); - store.insert_transcript_data(NI_DKG_ID_1, public_coeffs_2.clone(), BTreeMap::new()); + store.insert_transcript_data(&NI_DKG_ID_1, public_coeffs_1, BTreeMap::new()); + store.insert_transcript_data(&NI_DKG_ID_1, public_coeffs_2.clone(), BTreeMap::new()); let transcript_data = store.transcript_data(&NI_DKG_ID_1).unwrap(); assert_eq!(transcript_data.public_coefficients(), &public_coeffs_2); @@ -115,8 +115,8 @@ fn should_overwrite_existing_indices() { let indices_2 = indices_with(vec![(node_test_id(NODE_2), NODE_2_INDEX)]); let public_coeffs = public_coeffs(); - store.insert_transcript_data(NI_DKG_ID_1, public_coeffs.clone(), indices_1); - store.insert_transcript_data(NI_DKG_ID_1, public_coeffs, indices_2); + store.insert_transcript_data(&NI_DKG_ID_1, public_coeffs.clone(), indices_1); + store.insert_transcript_data(&NI_DKG_ID_1, public_coeffs, indices_2); let transcript_data = store.transcript_data(&NI_DKG_ID_1).unwrap(); assert_eq!(transcript_data.index(node_test_id(NODE_1)), None); @@ -133,8 +133,8 @@ fn should_overwrite_existing_individual_public_keys() { let csp_pubkey_2 = other_csp_public_key(); assert_ne!(csp_pubkey_1, csp_pubkey_2); - store.insert_individual_public_key(NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_1); - store.insert_individual_public_key(NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_2); + store.insert_individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_1); + store.insert_individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_2); assert_eq!( store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1)), @@ -152,7 +152,7 @@ fn should_not_purge_data_on_inserting_coeffs_and_indices_if_capacity_not_exceede let mut store = ThresholdSigDataStoreImpl::new(); for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { - store.insert_transcript_data(ni_dkg_id(i), public_coeffs(), BTreeMap::new()); + store.insert_transcript_data(&ni_dkg_id(i), public_coeffs(), BTreeMap::new()); } assert_eq!( @@ -166,7 +166,7 @@ fn should_not_purge_data_on_inserting_pubkeys_if_capacity_not_exceeded() { let mut store = ThresholdSigDataStoreImpl::new(); for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { - store.insert_individual_public_key(ni_dkg_id(i), node_test_id(NODE_1), csp_public_key()); + store.insert_individual_public_key(&ni_dkg_id(i), node_test_id(NODE_1), csp_public_key()); } assert_eq!( @@ -181,7 +181,7 @@ fn should_purge_data_on_inserting_coeffs_and_indices_if_capacity_exceeded() { let pub_coeffs = public_coeffs(); for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { - store.insert_transcript_data(ni_dkg_id(i), pub_coeffs.clone(), BTreeMap::new()); + store.insert_transcript_data(&ni_dkg_id(i), pub_coeffs.clone(), BTreeMap::new()); } assert_eq!( @@ -200,7 +200,7 @@ fn should_purge_data_in_insertion_order_on_inserting_coeffs_and_indices_if_capac let pub_coeffs = public_coeffs(); for i in (1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1).rev() { - store.insert_transcript_data(ni_dkg_id(i), pub_coeffs.clone(), BTreeMap::new()); + store.insert_transcript_data(&ni_dkg_id(i), pub_coeffs.clone(), BTreeMap::new()); } assert_eq!( @@ -223,13 +223,13 @@ fn should_not_purge_all_transcripts_of_certain_threshold_if_capacity_exceeded( let pub_coeffs = public_coeffs(); store.insert_transcript_data( - ni_dkg_id_with_tag(single_transcript_threshold.clone(), 1), + &ni_dkg_id_with_tag(single_transcript_threshold.clone(), 1), pub_coeffs.clone(), BTreeMap::new(), ); for i in 0..ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { store.insert_transcript_data( - ni_dkg_id_with_tag(other_transcripts_threshold.clone(), i), + &ni_dkg_id_with_tag(other_transcripts_threshold.clone(), i), pub_coeffs.clone(), BTreeMap::new(), ); @@ -285,7 +285,7 @@ fn should_purge_data_on_inserting_pubkeys_if_capacity_exceeded() { let node_id = node_test_id(NODE_1); for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { - store.insert_individual_public_key(ni_dkg_id(i), node_id, csp_pubkey); + store.insert_individual_public_key(&ni_dkg_id(i), node_id, csp_pubkey); } assert_eq!( @@ -308,7 +308,7 @@ fn should_purge_data_in_insertion_order_on_inserting_pubkeys_if_max_size_exceede let node_id = node_test_id(NODE_1); for i in (1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1).rev() { - store.insert_individual_public_key(ni_dkg_id(i), node_id, csp_pubkey); + store.insert_individual_public_key(&ni_dkg_id(i), node_id, csp_pubkey); } assert_eq!( @@ -337,12 +337,12 @@ fn should_store_up_to_capacity_per_tag_for_both_tags() { for i in 0..ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { store.insert_transcript_data( - ni_dkg_id_with_tag(NiDkgTag::LowThreshold, i), + &ni_dkg_id_with_tag(NiDkgTag::LowThreshold, i), pub_coeffs.clone(), BTreeMap::new(), ); store.insert_transcript_data( - ni_dkg_id_with_tag(NiDkgTag::HighThreshold, i), + &ni_dkg_id_with_tag(NiDkgTag::HighThreshold, i), pub_coeffs.clone(), BTreeMap::new(), ); @@ -361,7 +361,7 @@ fn should_store_up_to_capacity_per_tag_for_both_tags() { // Insert one more transcript per tag store.insert_transcript_data( - ni_dkg_id_with_tag( + &ni_dkg_id_with_tag( NiDkgTag::LowThreshold, ThresholdSigDataStoreImpl::CAPACITY_PER_TAG, ), @@ -369,7 +369,7 @@ fn should_store_up_to_capacity_per_tag_for_both_tags() { BTreeMap::new(), ); store.insert_transcript_data( - ni_dkg_id_with_tag( + &ni_dkg_id_with_tag( NiDkgTag::HighThreshold, ThresholdSigDataStoreImpl::CAPACITY_PER_TAG, ), diff --git a/rs/crypto/src/sign/threshold_sig/tests.rs b/rs/crypto/src/sign/threshold_sig/tests.rs index 51cc8bec047..10d3f8126ba 100644 --- a/rs/crypto/src/sign/threshold_sig/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/tests.rs @@ -60,14 +60,13 @@ mod sign_threshold { .return_const(Ok(individual_csp_threshold_sig( [42; IndividualSignatureBytes::SIZE], ))); - let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs(pub_coeffs, dkg_id.clone()); + let threshold_sig_data_store = threshold_sig_data_store_with_coeffs(pub_coeffs, &dkg_id); let _ = ThresholdSignerInternal::sign_threshold( &threshold_sig_data_store, &csp, &message, - dkg_id, + &dkg_id, ); } @@ -76,13 +75,13 @@ mod sign_threshold { let csp_sig = individual_csp_threshold_sig([42; IndividualSignatureBytes::SIZE]); let csp = csp_with_sign_returning_once(Ok(csp_sig.clone())); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs(pub_coeffs(), NI_DKG_ID_1); + threshold_sig_data_store_with_coeffs(pub_coeffs(), &NI_DKG_ID_1); let sig_share_result = ThresholdSignerInternal::sign_threshold( &threshold_sig_data_store, &csp, &signable_mock(), - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert!(sig_share_result.is_ok()); @@ -99,13 +98,13 @@ mod sign_threshold { fn should_panic_with_correct_message_if_csp_returns_unsupported_algorithm_error() { let csp = csp_with_sign_returning_once(Err(unsupported_algorithm())); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs(pub_coeffs(), NI_DKG_ID_1); + threshold_sig_data_store_with_coeffs(pub_coeffs(), &NI_DKG_ID_1); let _panic = ThresholdSignerInternal::sign_threshold( &threshold_sig_data_store, &csp, &signable_mock(), - NI_DKG_ID_1, + &NI_DKG_ID_1, ); } @@ -114,13 +113,13 @@ mod sign_threshold { fn should_panic_if_csp_returns_wrong_secret_key_type_error() { let csp = csp_with_sign_returning_once(Err(wrong_secret_key_type())); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs(pub_coeffs(), NI_DKG_ID_1); + threshold_sig_data_store_with_coeffs(pub_coeffs(), &NI_DKG_ID_1); let _panic = ThresholdSignerInternal::sign_threshold( &threshold_sig_data_store, &csp, &signable_mock(), - NI_DKG_ID_1, + &NI_DKG_ID_1, ); } @@ -131,13 +130,13 @@ mod sign_threshold { fn should_panic_if_csp_returns_malformed_secret_key_error() { let csp = csp_with_sign_returning_once(Err(malformed_secret_key())); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs(pub_coeffs(), NI_DKG_ID_1); + threshold_sig_data_store_with_coeffs(pub_coeffs(), &NI_DKG_ID_1); let _panic = ThresholdSignerInternal::sign_threshold( &threshold_sig_data_store, &csp, &signable_mock(), - NI_DKG_ID_1, + &NI_DKG_ID_1, ); } @@ -145,13 +144,13 @@ mod sign_threshold { fn should_return_secret_key_not_found_error_if_csp_returns_secret_key_not_found_error() { let csp = csp_with_sign_returning_once(Err(secret_key_not_found())); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs(pub_coeffs(), NI_DKG_ID_1); + threshold_sig_data_store_with_coeffs(pub_coeffs(), &NI_DKG_ID_1); let sig_share_result = ThresholdSignerInternal::sign_threshold( &threshold_sig_data_store, &csp, &signable_mock(), - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!( @@ -173,7 +172,7 @@ mod sign_threshold { &threshold_sig_data_store, &csp, &signable_mock(), - NI_DKG_ID_1, + &NI_DKG_ID_1, ); assert_eq!( @@ -193,13 +192,13 @@ mod sign_threshold { combined_csp_threshold_sig([42; CombinedSignatureBytes::SIZE]); let csp = csp_with_sign_returning_once(Ok(csp_sig_with_wrong_type)); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs(pub_coeffs(), NI_DKG_ID_1); + threshold_sig_data_store_with_coeffs(pub_coeffs(), &NI_DKG_ID_1); let _panic = ThresholdSignerInternal::sign_threshold( &threshold_sig_data_store, &csp, &signable_mock(), - NI_DKG_ID_1, + &NI_DKG_ID_1, ); } @@ -242,11 +241,8 @@ mod verify_threshold_sig_share { fn should_call_csp_with_correct_params_if_public_key_in_store() { let dkg_id = NI_DKG_ID_1; let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); - let threshold_sig_data_store = threshold_sig_data_store_with_coeffs_and_pubkey( - dkg_id.clone(), - NODE_ID, - csp_public_key, - ); + let threshold_sig_data_store = + threshold_sig_data_store_with_coeffs_and_pubkey(&dkg_id, NODE_ID, csp_public_key); let mut csp = MockAllCryptoServiceProvider::new(); let (expected_msg, expected_sig) = (message.clone(), sig_share.clone()); csp.expect_threshold_verify_individual_signature() @@ -264,7 +260,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - dkg_id, + &dkg_id, NODE_ID, ); } @@ -274,7 +270,7 @@ mod verify_threshold_sig_share { let (sig_share, message, csp_public_key, pub_coeffs) = (sig_share(), signable_mock(), csp_public_key(), pub_coeffs()); let threshold_sig_data_store = threshold_sig_data_store_with( - NI_DKG_ID_1, + &NI_DKG_ID_1, pub_coeffs.clone(), indices(vec![(NODE_ID, 3)]), ); @@ -295,7 +291,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); } @@ -305,7 +301,7 @@ mod verify_threshold_sig_share { let (sig_share, message, csp_public_key, public_coeffs) = (sig_share(), signable_mock(), csp_public_key(), pub_coeffs()); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, public_coeffs, indices(vec![(NODE_ID, 3)])); + threshold_sig_data_store_with(&NI_DKG_ID_1, public_coeffs, indices(vec![(NODE_ID, 3)])); let mut csp = MockAllCryptoServiceProvider::new(); let (expected_msg, expected_sig, expected_pk) = (message.clone(), sig_share.clone(), csp_public_key); @@ -327,7 +323,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); } @@ -336,7 +332,7 @@ mod verify_threshold_sig_share { fn should_return_ok_if_sig_verification_ok_and_public_key_in_store() { let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs_and_pubkey(NI_DKG_ID_1, NODE_ID, csp_public_key); + threshold_sig_data_store_with_coeffs_and_pubkey(&NI_DKG_ID_1, NODE_ID, csp_public_key); let csp = csp_with_verify_indiv_sig_returning_once(Ok(())); let verification_result = ThresholdSigVerifierInternal::verify_threshold_sig_share( @@ -344,7 +340,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); @@ -355,7 +351,7 @@ mod verify_threshold_sig_share { fn should_return_ok_if_sig_verification_ok_and_public_key_not_in_store() { let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id(NI_DKG_ID_1); + threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id(&NI_DKG_ID_1); let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_threshold_individual_public_key() .times(1) @@ -369,7 +365,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); @@ -381,7 +377,7 @@ mod verify_threshold_sig_share { let verification_error = sig_verification_error(); let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs_and_pubkey(NI_DKG_ID_1, NODE_ID, csp_public_key); + threshold_sig_data_store_with_coeffs_and_pubkey(&NI_DKG_ID_1, NODE_ID, csp_public_key); let csp = csp_with_verify_indiv_sig_returning_once(Err(verification_error.clone())); let verification_result = ThresholdSigVerifierInternal::verify_threshold_sig_share( @@ -389,7 +385,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); @@ -402,7 +398,7 @@ mod verify_threshold_sig_share { let verification_error = sig_verification_error(); let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id(NI_DKG_ID_1); + threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id(&NI_DKG_ID_1); let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_threshold_individual_public_key() .times(1) @@ -416,7 +412,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); @@ -428,9 +424,7 @@ mod verify_threshold_sig_share { fn should_have_correct_public_key_in_store_after_sig_verification_if_not_in_store_before() { let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id( - NI_DKG_ID_1.clone(), - ); + threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id(&NI_DKG_ID_1); let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_threshold_individual_public_key() .times(1) @@ -444,7 +438,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1.clone(), + &NI_DKG_ID_1, NODE_ID, ); @@ -460,7 +454,7 @@ mod verify_threshold_sig_share { fn should_not_regenerate_public_key_if_in_store_already() { let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs_and_pubkey(NI_DKG_ID_1, NODE_ID, csp_public_key); + threshold_sig_data_store_with_coeffs_and_pubkey(&NI_DKG_ID_1, NODE_ID, csp_public_key); let mut csp = csp_with_verify_indiv_sig_returning_once(Ok(())); csp.expect_threshold_individual_public_key().times(0); @@ -469,7 +463,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); } @@ -487,7 +481,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); @@ -504,7 +498,7 @@ mod verify_threshold_sig_share { fn should_fail_with_invalid_argument_if_index_missing_upon_key_generation() { let (sig_share, message) = (sig_share(), signable_mock()); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices(vec![])); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices(vec![])); let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_threshold_individual_public_key().times(0); csp.expect_threshold_verify_individual_signature().times(0); @@ -514,7 +508,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); @@ -534,7 +528,7 @@ mod verify_threshold_sig_share { fn should_fail_with_malformed_signature_if_signature_has_invalid_length() { let (sig_share, message) = (invalid_threshold_sig_share(), signable_mock()); let threshold_sig_data_store = - threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id(NI_DKG_ID_1); + threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id(&NI_DKG_ID_1); let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_threshold_individual_public_key().times(0); csp.expect_threshold_verify_individual_signature().times(0); @@ -544,7 +538,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); @@ -556,7 +550,7 @@ mod verify_threshold_sig_share { fn should_panic_if_calculating_individual_public_key_fails() { let (sig_share, message) = (sig_share(), signable_mock()); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices(vec![(NODE_ID, 3)])); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices(vec![(NODE_ID, 3)])); let mut csp = csp_with_indiv_pk_returning_once(Err(invalid_argument())); csp.expect_threshold_verify_individual_signature().times(0); @@ -565,7 +559,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); } @@ -579,7 +573,7 @@ mod verify_threshold_sig_share { fn should_panic_if_csp_returns_invalid_argument_error() { let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs_and_pubkey(NI_DKG_ID_1, NODE_ID, csp_public_key); + threshold_sig_data_store_with_coeffs_and_pubkey(&NI_DKG_ID_1, NODE_ID, csp_public_key); let csp = csp_with_verify_indiv_sig_returning_once(Err(invalid_argument())); let _panic = ThresholdSigVerifierInternal::verify_threshold_sig_share( @@ -587,7 +581,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); } @@ -601,7 +595,7 @@ mod verify_threshold_sig_share { fn should_panic_if_csp_returns_malformed_public_key_error() { let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs_and_pubkey(NI_DKG_ID_1, NODE_ID, csp_public_key); + threshold_sig_data_store_with_coeffs_and_pubkey(&NI_DKG_ID_1, NODE_ID, csp_public_key); let csp = csp_with_verify_indiv_sig_returning_once(Err(malformed_public_key())); let _panic = ThresholdSigVerifierInternal::verify_threshold_sig_share( @@ -609,7 +603,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); } @@ -619,7 +613,7 @@ mod verify_threshold_sig_share { fn should_panic_if_csp_returns_malformed_signature_error() { let (sig_share, message, csp_public_key) = (sig_share(), signable_mock(), csp_public_key()); let threshold_sig_data_store = - threshold_sig_data_store_with_coeffs_and_pubkey(NI_DKG_ID_1, NODE_ID, csp_public_key); + threshold_sig_data_store_with_coeffs_and_pubkey(&NI_DKG_ID_1, NODE_ID, csp_public_key); let csp = csp_with_verify_indiv_sig_returning_once(Err(malformed_signature())); let _panic = ThresholdSigVerifierInternal::verify_threshold_sig_share( @@ -627,7 +621,7 @@ mod verify_threshold_sig_share { &csp, &sig_share, &message, - NI_DKG_ID_1, + &NI_DKG_ID_1, NODE_ID, ); } @@ -681,8 +675,7 @@ mod combine_threshold_sig_shares { .return_const(Ok(combined_csp_threshold_sig( [42; CombinedSignatureBytes::SIZE], ))); - let threshold_sig_data_store = - threshold_sig_data_store_with(dkg_id.clone(), pub_coeffs, indices); + let threshold_sig_data_store = threshold_sig_data_store_with(&dkg_id, pub_coeffs, indices); let _ = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -702,7 +695,7 @@ mod combine_threshold_sig_shares { let indices = indices(vec![(NODE_1, 0)]); let csp = csp_with_combine_sigs_returning_once(Ok(csp_combined_sig.clone())); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let result = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -728,7 +721,7 @@ mod combine_threshold_sig_shares { [1; IndividualSignatureBytes::SIZE], ))]); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let _ = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -769,7 +762,7 @@ mod combine_threshold_sig_shares { )), ]); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let _ = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -785,7 +778,7 @@ mod combine_threshold_sig_shares { let indices = indices(vec![]); let csp = MockAllCryptoServiceProvider::new(); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let result = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -835,7 +828,7 @@ mod combine_threshold_sig_shares { let indices = indices(vec![(NODE_2, 0)]); let csp = MockAllCryptoServiceProvider::new(); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let result = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -868,7 +861,7 @@ mod combine_threshold_sig_shares { [42; CombinedSignatureBytes::SIZE], ))); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let _panic = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -888,7 +881,7 @@ mod combine_threshold_sig_shares { let indices = indices(vec![(NODE_1, 0)]); let csp = MockAllCryptoServiceProvider::new(); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let result = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -909,7 +902,7 @@ mod combine_threshold_sig_shares { )]); let csp = csp_with_combine_sigs_returning_once(Err(malformed_signature())); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let result = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -930,7 +923,7 @@ mod combine_threshold_sig_shares { )]); let csp = csp_with_combine_sigs_returning_once(Err(invalid_argument())); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let result = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -951,7 +944,7 @@ mod combine_threshold_sig_shares { )]); let csp = csp_with_combine_sigs_returning_once(Err(sig_verification_error())); let threshold_sig_data_store = - threshold_sig_data_store_with(NI_DKG_ID_1, pub_coeffs(), indices); + threshold_sig_data_store_with(&NI_DKG_ID_1, pub_coeffs(), indices); let result = ThresholdSigVerifierInternal::combine_threshold_sig_shares( &threshold_sig_data_store, @@ -1022,7 +1015,7 @@ mod verify_threshold_sig_combined { ); let _ = ThresholdSigVerifierInternal::verify_threshold_sig_combined( - &threshold_sig_data_store_with_coeffs(pub_coeffs, dkg_id.clone()), + &threshold_sig_data_store_with_coeffs(pub_coeffs, &dkg_id), &csp, &combined_sig, &message, @@ -1036,7 +1029,7 @@ mod verify_threshold_sig_combined { let csp = csp_with_verify_combined_returning_once(Ok(())); let result = ThresholdSigVerifierInternal::verify_threshold_sig_combined( - &threshold_sig_data_store_with_coeffs(pub_coeffs, NI_DKG_ID_1), + &threshold_sig_data_store_with_coeffs(pub_coeffs, &NI_DKG_ID_1), &csp, &combined_sig, &message, @@ -1250,7 +1243,7 @@ mod verify_combined_threshold_sig_by_public_key { REG_V1, ); let _ = ThresholdSigVerifierInternal::verify_threshold_sig_combined( - &threshold_sig_data_store_with_coeffs(pub_coeffs, NI_DKG_ID_1), + &threshold_sig_data_store_with_coeffs(pub_coeffs, &NI_DKG_ID_1), &csp_2, &combined_sig, &message, @@ -1605,7 +1598,7 @@ fn invalid_combined_threshold_sig() -> CombinedThresholdSigOf { } fn threshold_sig_data_store_with( - dkg_id: NiDkgId, + dkg_id: &NiDkgId, public_coeffs: CspPublicCoefficients, indices: BTreeMap, ) -> LockableThresholdSigDataStore { @@ -1617,7 +1610,7 @@ fn threshold_sig_data_store_with( } fn threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id( - ni_dkg_id: NiDkgId, + ni_dkg_id: &NiDkgId, ) -> LockableThresholdSigDataStore { let store = LockableThresholdSigDataStore::new(); store @@ -1628,7 +1621,7 @@ fn threshold_sig_data_store_with_non_empty_coeffs_and_indices_for_dkg_id( fn threshold_sig_data_store_with_coeffs( csp_public_coefficients: CspPublicCoefficients, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> LockableThresholdSigDataStore { let threshold_sig_data_store = LockableThresholdSigDataStore::new(); threshold_sig_data_store.write().insert_transcript_data( @@ -1640,14 +1633,14 @@ fn threshold_sig_data_store_with_coeffs( } fn threshold_sig_data_store_with_coeffs_and_pubkey( - dkg_id: NiDkgId, + dkg_id: &NiDkgId, node_id: NodeId, public_key: CspThresholdSigPublicKey, ) -> LockableThresholdSigDataStore { let threshold_sig_data_store = LockableThresholdSigDataStore::new(); { let mut locked_store = threshold_sig_data_store.write(); - locked_store.insert_transcript_data(dkg_id.clone(), pub_coeffs(), BTreeMap::new()); + locked_store.insert_transcript_data(dkg_id, pub_coeffs(), BTreeMap::new()); locked_store.insert_individual_public_key(dkg_id, node_id, public_key); } threshold_sig_data_store @@ -1666,7 +1659,7 @@ fn btree_map(entries: Vec<(NodeId, H)>) -> BTreeMap { } fn default_threshold_sig_data_store() -> LockableThresholdSigDataStore { - threshold_sig_data_store_with_coeffs(pub_coeffs(), NI_DKG_ID_1) + threshold_sig_data_store_with_coeffs(pub_coeffs(), &NI_DKG_ID_1) } fn csp_with_threshold_verify_combined_signature_expecting_once( diff --git a/rs/crypto/temp_crypto/src/lib.rs b/rs/crypto/temp_crypto/src/lib.rs index 98048131dde..b021a461743 100644 --- a/rs/crypto/temp_crypto/src/lib.rs +++ b/rs/crypto/temp_crypto/src/lib.rs @@ -850,7 +850,7 @@ pub mod internal { &self, signature: &ThresholdSigShareOf, message: &T, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, signer: NodeId, ) -> CryptoResult<()> { self.crypto_component @@ -972,7 +972,7 @@ pub mod internal { fn sign_threshold( &self, message: &T, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, ) -> CryptoResult> { self.crypto_component.sign_threshold(message, dkg_id) } diff --git a/rs/crypto/test_utils/ni-dkg/src/lib.rs b/rs/crypto/test_utils/ni-dkg/src/lib.rs index 61e9816343f..52aa8754cbf 100644 --- a/rs/crypto/test_utils/ni-dkg/src/lib.rs +++ b/rs/crypto/test_utils/ni-dkg/src/lib.rs @@ -174,14 +174,14 @@ pub fn retain_only_active_keys( pub fn sign_threshold_for_each( signers: &[NodeId], msg: &H, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, crypto_components: &BTreeMap>, ) -> BTreeMap> { signers .iter() .map(|signer| { let sig_share = crypto_for(*signer, crypto_components) - .sign_threshold(msg, dkg_id.clone()) + .sign_threshold(msg, dkg_id) .unwrap_or_else(|_| panic!("signing by node {:?} failed", signer)); (*signer, sig_share) }) diff --git a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs index 7e7dd83ff73..322cd3ad2ac 100644 --- a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs +++ b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs @@ -66,19 +66,15 @@ fn should_produce_valid_signature_shares() { let sig_shares = sign_threshold_for_each( &config.receivers().get().iter().copied().collect::>(), &msg, - dkg_id.clone(), + &dkg_id, &crypto_components, ); let verifier = random_node_in(config.receivers().get(), rng); sig_shares.iter().for_each(|(signer, sig_share)| { assert_eq!( - crypto_for(verifier, &crypto_components).verify_threshold_sig_share( - sig_share, - &msg, - dkg_id.clone(), - *signer - ), + crypto_for(verifier, &crypto_components) + .verify_threshold_sig_share(sig_share, &msg, &dkg_id, *signer), Ok(()), "node {:?} failed to verify threshold sig share of signer {:?}", verifier, @@ -117,7 +113,7 @@ fn should_load_transcript_and_validate_signature_shares_as_non_receiver_without_ let sig_shares = sign_threshold_for_each( &config.receivers().get().iter().copied().collect::>(), &msg, - dkg_id.clone(), + &dkg_id, &crypto_components, ); @@ -137,12 +133,7 @@ fn should_load_transcript_and_validate_signature_shares_as_non_receiver_without_ // Verify the signature shares with the node that is not a receiver. sig_shares.iter().for_each(|(signer, sig_share)| { assert_eq!( - other_crypto_component.verify_threshold_sig_share( - sig_share, - &msg, - dkg_id.clone(), - *signer - ), + other_crypto_component.verify_threshold_sig_share(sig_share, &msg, &dkg_id, *signer), Ok(()), "node {:?} failed to verify threshold sig share of signer {:?}", other_node_id, @@ -188,7 +179,7 @@ fn should_fail_to_combine_insufficient_shares() { let sig_shares = sign_threshold_for_each( &n_random_nodes_in(config.receivers().get(), num_of_shares_to_combine, rng), &message(), - dkg_id.clone(), + &dkg_id, &crypto_components, ); let combination_result = crypto_for( @@ -287,7 +278,7 @@ fn threshold_sign_and_combine( let sig_shares = sign_threshold_for_each( &signers_and_combiner.signers, msg, - dkg_id.clone(), + &dkg_id, crypto_components, ); crypto_for(signers_and_combiner.combiner, crypto_components) @@ -298,14 +289,14 @@ fn threshold_sign_and_combine( fn sign_threshold_for_each( signers: &[NodeId], msg: &H, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, crypto_components: &BTreeMap>, ) -> BTreeMap> { signers .iter() .map(|signer| { let sig_share = crypto_for(*signer, crypto_components) - .sign_threshold(msg, dkg_id.clone()) + .sign_threshold(msg, dkg_id) .unwrap_or_else(|e| panic!("signing by node {:?} failed: {}", signer, e)); (*signer, sig_share) }) @@ -546,41 +537,29 @@ mod non_interactive_distributed_key_generation { assert_eq!(epoch1_nodes.difference(&epoch2_nodes).count(), 0); // Test that all nodes can sign in their own epoch - assert!(nodes_can_sign_in_epoch( - &epoch0_nodes, - dkg_id0.clone(), - &env - )); - assert!(nodes_can_sign_in_epoch( - &epoch1_nodes, - dkg_id1.clone(), - &env - )); - assert!(nodes_can_sign_in_epoch( - &epoch2_nodes, - dkg_id2.clone(), - &env - )); + assert!(nodes_can_sign_in_epoch(&epoch0_nodes, &dkg_id0, &env)); + assert!(nodes_can_sign_in_epoch(&epoch1_nodes, &dkg_id1, &env)); + assert!(nodes_can_sign_in_epoch(&epoch2_nodes, &dkg_id2, &env)); // Test that nodes added later cannot sign in old epochs assert!( nodes_cannot_sign_in_epoch_due_to_missing_threshold_sig_data( &new_in_epoch1, - dkg_id0.clone(), + &dkg_id0, &env ) ); assert!( nodes_cannot_sign_in_epoch_due_to_missing_threshold_sig_data( &new_in_epoch2, - dkg_id0.clone(), + &dkg_id0, &env ) ); assert!( nodes_cannot_sign_in_epoch_due_to_missing_threshold_sig_data( &new_in_epoch2, - dkg_id1.clone(), + &dkg_id1, &env ) ); @@ -602,13 +581,13 @@ mod non_interactive_distributed_key_generation { // Now nobody can sign in epoch0 since the keys have been removed assert!(nodes_cannot_sign_in_epoch_due_to_missing_secret_key( &epoch0_nodes, - dkg_id0.clone(), + &dkg_id0, &env )); // But the newer epochs can still be used by all nodes - assert!(nodes_can_sign_in_epoch(&epoch1_nodes, dkg_id1, &env)); - assert!(nodes_can_sign_in_epoch(&epoch2_nodes, dkg_id2, &env)); + assert!(nodes_can_sign_in_epoch(&epoch1_nodes, &dkg_id1, &env)); + assert!(nodes_can_sign_in_epoch(&epoch2_nodes, &dkg_id2, &env)); // And all nodes can still load the old transcript (but not decrypt it) load_transcript_for_receivers(config3.get(), &transcript0, &env.crypto_components); @@ -616,7 +595,7 @@ mod non_interactive_distributed_key_generation { // Even after the transcript is loaded again, key is not available assert!(nodes_cannot_sign_in_epoch_due_to_missing_secret_key( &epoch3_nodes, - dkg_id0, + &dkg_id0, &env )); @@ -624,7 +603,7 @@ mod non_interactive_distributed_key_generation { let config4 = RandomNiDkgConfig::reshare(transcript3, 1..=2, max_subnet_size, rng); let (_transcript4, dkg_id4, epoch4_nodes) = run_dkg_and_load_transcripts(&config4, &mut env, rng); - assert!(nodes_can_sign_in_epoch(&epoch4_nodes, dkg_id4, &env)); + assert!(nodes_can_sign_in_epoch(&epoch4_nodes, &dkg_id4, &env)); } #[test] @@ -824,14 +803,13 @@ mod non_interactive_distributed_key_generation { fn nodes_can_sign_in_epoch( nodes: &HashSet, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, env: &NiDkgTestEnvironment, ) -> bool { let msg = message(); for node in nodes { - let sig = - crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id.clone()); + let sig = crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id); if sig.is_err() { return false; } @@ -842,14 +820,13 @@ mod non_interactive_distributed_key_generation { fn nodes_cannot_sign_in_epoch_due_to_missing_secret_key( nodes: &HashSet, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, env: &NiDkgTestEnvironment, ) -> bool { let msg = message(); for node in nodes { - let sig = - crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id.clone()); + let sig = crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id); match sig { Ok(_) => return false, Err(CryptoError::SecretKeyNotFound { @@ -867,20 +844,19 @@ mod non_interactive_distributed_key_generation { fn nodes_cannot_sign_in_epoch_due_to_missing_threshold_sig_data( nodes: &HashSet, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, env: &NiDkgTestEnvironment, ) -> bool { let msg = message(); for node in nodes { - let sig = - crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id.clone()); + let sig = crypto_for(*node, &env.crypto_components).sign_threshold(&msg, dkg_id); match sig { Ok(_) => return false, Err(CryptoError::ThresholdSigDataNotFound { dkg_id: missing_dkg_id, }) => { - assert_eq!(dkg_id, missing_dkg_id); + assert_eq!(dkg_id, &missing_dkg_id); } Err(e) => { panic!("Unexpected error {}", e); diff --git a/rs/interfaces/src/crypto/sign/threshold_sig.rs b/rs/interfaces/src/crypto/sign/threshold_sig.rs index d2788a50eba..dce70d51313 100644 --- a/rs/interfaces/src/crypto/sign/threshold_sig.rs +++ b/rs/interfaces/src/crypto/sign/threshold_sig.rs @@ -28,7 +28,7 @@ pub trait ThresholdSigner { /// internal error, e.g., an RPC error when calling the CSP vault. // TODO (CRP-479): switch to Result, // ThresholdSigDataNotFoundError> - fn sign_threshold(&self, message: &T, dkg_id: NiDkgId) -> CryptoResult>; + fn sign_threshold(&self, message: &T, dkg_id: &NiDkgId) -> CryptoResult>; } /// A Crypto Component interface to verify threshold signatures. @@ -67,7 +67,7 @@ pub trait ThresholdSigVerifier { &self, signature: &ThresholdSigShareOf, message: &T, - dkg_id: NiDkgId, + dkg_id: &NiDkgId, signer: NodeId, ) -> CryptoResult<()>; diff --git a/rs/test_utilities/artifact_pool/src/consensus_pool.rs b/rs/test_utilities/artifact_pool/src/consensus_pool.rs index 4345a5b16ec..d5491d948a2 100644 --- a/rs/test_utilities/artifact_pool/src/consensus_pool.rs +++ b/rs/test_utilities/artifact_pool/src/consensus_pool.rs @@ -584,7 +584,7 @@ impl TestConsensusPool { let content = RandomBeaconContent::new(height, ic_types::crypto::crypto_hash(&beacon)); let share = RandomBeaconShare { signature: crypto - .sign_threshold(&content, dkg_id.clone()) + .sign_threshold(&content, &dkg_id) .map(|signature| ThresholdSignatureShare { signature, signer: node_id, diff --git a/rs/test_utilities/src/crypto.rs b/rs/test_utilities/src/crypto.rs index 8022eb44936..7cb5978364e 100644 --- a/rs/test_utilities/src/crypto.rs +++ b/rs/test_utilities/src/crypto.rs @@ -175,7 +175,7 @@ impl ThresholdSigner for CryptoReturningOk { fn sign_threshold( &self, _message: &T, - _dkg_id: NiDkgId, + _dkg_id: &NiDkgId, ) -> CryptoResult> { Ok(ThresholdSigShareOf::new(ThresholdSigShare(vec![]))) } @@ -186,7 +186,7 @@ impl ThresholdSigVerifier for CryptoReturningOk { &self, _signature: &ThresholdSigShareOf, _message: &T, - _dkg_id: NiDkgId, + _dkg_id: &NiDkgId, _signer: NodeId, ) -> CryptoResult<()> { Ok(()) From 3a8675b165cd6bca0e150f0bbac04be7b9b2a4c8 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 12:59:18 +0000 Subject: [PATCH 06/30] Fmt --- rs/interfaces/src/crypto/sign/threshold_sig.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rs/interfaces/src/crypto/sign/threshold_sig.rs b/rs/interfaces/src/crypto/sign/threshold_sig.rs index dce70d51313..402aad9b1b7 100644 --- a/rs/interfaces/src/crypto/sign/threshold_sig.rs +++ b/rs/interfaces/src/crypto/sign/threshold_sig.rs @@ -28,7 +28,8 @@ pub trait ThresholdSigner { /// internal error, e.g., an RPC error when calling the CSP vault. // TODO (CRP-479): switch to Result, // ThresholdSigDataNotFoundError> - fn sign_threshold(&self, message: &T, dkg_id: &NiDkgId) -> CryptoResult>; + fn sign_threshold(&self, message: &T, dkg_id: &NiDkgId) + -> CryptoResult>; } /// A Crypto Component interface to verify threshold signatures. From 5e466decc3b52c68d396d6171a0d796f6808fdc9 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 13:16:20 +0000 Subject: [PATCH 07/30] Remove unused dkg_id param of NiDkgCspClient::load_threshold_signing_key --- .../src/api/threshold.rs | 1 - .../src/threshold/ni_dkg/mod.rs | 1 - .../src/threshold/ni_dkg/tests/fixtures.rs | 1 - .../src/sign/threshold_sig/ni_dkg/transcript.rs | 4 ---- .../threshold_sig/ni_dkg/transcript/tests.rs | 17 +++++++---------- rs/crypto/test_utils/csp/src/lib.rs | 1 - 6 files changed, 7 insertions(+), 18 deletions(-) diff --git a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs index d73e4e89170..26e3e04e743 100644 --- a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs +++ b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs @@ -474,7 +474,6 @@ pub trait NiDkgCspClient { fn load_threshold_signing_key( &self, algorithm_id: AlgorithmId, - dkg_id: NiDkgId, epoch: Epoch, csp_transcript: CspNiDkgTranscript, receiver_index: NodeIndex, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs index 20b240a704a..4c6a6662b42 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs @@ -213,7 +213,6 @@ impl NiDkgCspClient for Csp { fn load_threshold_signing_key( &self, algorithm_id: AlgorithmId, - _dkg_id: NiDkgId, epoch: Epoch, csp_transcript: CspNiDkgTranscript, receiver_index: NodeIndex, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs index d953f8b73be..9ee51d9184c 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs @@ -438,7 +438,6 @@ impl StateWithTranscript { node.csp .load_threshold_signing_key( self.config.algorithm_id, - self.config.dkg_id.clone(), self.config.epoch, self.transcript.clone(), node_index, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs index 3972dcdf525..84f08b50907 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs @@ -311,10 +311,6 @@ mod loading { ) -> Result<(), CspDkgLoadPrivateKeyError> { ni_dkg_csp_client.load_threshold_signing_key( AlgorithmId::NiDkg_Groth20_Bls12_381, - /////////////////////////////////////// - // TODO: this param is actually not needed/used - /////////////////////////////////////// - transcript.dkg_id.clone(), epoch(transcript.registry_version), csp_transcript.clone(), self_index_in_committee, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript/tests.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript/tests.rs index 30f7eabf809..d66d166b2a6 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript/tests.rs @@ -568,16 +568,13 @@ mod load_transcript { }; let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_load_threshold_signing_key() - .withf( - move |algorithm_id, dkg_id, epoch_, transcript, receiver_index| { - *algorithm_id == AlgorithmId::NiDkg_Groth20_Bls12_381 - && *dkg_id == NI_DKG_ID_1 - && *epoch_ == epoch(REG_V1) - && *transcript == csp_transcript - && *receiver_index == 2 // index of NODE_3 in (sorted) - // resharing committee - }, - ) + .withf(move |algorithm_id, epoch_, transcript, receiver_index| { + *algorithm_id == AlgorithmId::NiDkg_Groth20_Bls12_381 + && *epoch_ == epoch(REG_V1) + && *transcript == csp_transcript + && *receiver_index == 2 // index of NODE_3 in (sorted) + // resharing committee + }) .times(1) .return_const(Ok(())); csp.expect_observe_epoch_in_loaded_transcript() diff --git a/rs/crypto/test_utils/csp/src/lib.rs b/rs/crypto/test_utils/csp/src/lib.rs index 07a193f45d2..f4a4c6b04b7 100644 --- a/rs/crypto/test_utils/csp/src/lib.rs +++ b/rs/crypto/test_utils/csp/src/lib.rs @@ -171,7 +171,6 @@ mock! { fn load_threshold_signing_key( &self, algorithm_id: AlgorithmId, - dkg_id: NiDkgId, epoch: Epoch, csp_transcript: CspNiDkgTranscript, receiver_index: u32, From b5343d66f292874989840c3585250c0f1f057c60 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 13:29:59 +0000 Subject: [PATCH 08/30] Cleanup benches --- rs/crypto/benches/threshold_sig.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rs/crypto/benches/threshold_sig.rs b/rs/crypto/benches/threshold_sig.rs index a06c450b25d..ddb46b0e38c 100644 --- a/rs/crypto/benches/threshold_sig.rs +++ b/rs/crypto/benches/threshold_sig.rs @@ -109,13 +109,13 @@ fn bench_threshold_sig_n_nodes( for &node_id in &nodes_in_subnet { load_transcript(&transcript, &env.crypto_components, node_id); } - let dkg_id = transcript.dkg_id.clone(); + let dkg_id = &transcript.dkg_id; bench_threshold_sign( group, &nodes_in_subnet, &env.crypto_components, - &dkg_id, + dkg_id, message_size, rng, ); @@ -125,7 +125,7 @@ fn bench_threshold_sig_n_nodes( group, &nodes_in_subnet, &env.crypto_components, - &dkg_id, + dkg_id, message_size, rng, ); @@ -133,7 +133,7 @@ fn bench_threshold_sig_n_nodes( group, &nodes_in_subnet, &env.crypto_components, - &dkg_id, + dkg_id, &transcript, message_size, rng, @@ -143,7 +143,7 @@ fn bench_threshold_sig_n_nodes( group, &threshold_many_random_subnet_nodes, &env.crypto_components, - &dkg_id, + dkg_id, message_size, rng, ); @@ -151,7 +151,7 @@ fn bench_threshold_sig_n_nodes( group, &threshold_many_random_subnet_nodes, &env.crypto_components, - &dkg_id, + dkg_id, message_size, rng, ); From 64a7b7bbe225c077a4ed00775332ce040036a895 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 15:51:31 +0000 Subject: [PATCH 09/30] NiDkgConfig::dkg_id now returns ref --- rs/consensus/src/dkg.rs | 4 ++-- rs/consensus/src/dkg/payload_builder.rs | 14 +++++++------- .../crypto_service_provider/src/api/threshold.rs | 9 +++++++++ rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs | 6 +++--- .../src/sign/threshold_sig/ni_dkg/transcript.rs | 2 +- .../test_utils/ni-dkg/src/initial_config/tests.rs | 4 ++-- rs/crypto/tests/threshold_sigs_with_ni_dkg.rs | 4 ++-- rs/test_utilities/src/crypto.rs | 4 ++-- rs/types/types/src/consensus/dkg.rs | 2 +- .../src/crypto/threshold_sig/ni_dkg/config.rs | 7 ++----- .../crypto/threshold_sig/ni_dkg/config/tests.rs | 2 +- rs/types/types/src/exhaustive.rs | 2 +- 12 files changed, 33 insertions(+), 27 deletions(-) diff --git a/rs/consensus/src/dkg.rs b/rs/consensus/src/dkg.rs index 66ce04c0b1d..98de550cd72 100644 --- a/rs/consensus/src/dkg.rs +++ b/rs/consensus/src/dkg.rs @@ -148,7 +148,7 @@ impl DkgImpl { let content = match ic_interfaces::crypto::NiDkgAlgorithm::create_dealing(&*self.crypto, config) { - Ok(dealing) => DealingContent::new(dealing, config.dkg_id()), + Ok(dealing) => DealingContent::new(dealing, config.dkg_id().clone()), Err(err) => { match config.dkg_id().target_subnet { NiDkgTargetSubnet::Local => error!( @@ -311,7 +311,7 @@ impl DkgImpl { fn contains_dkg_messages(dkg_pool: &dyn DkgPool, config: &NiDkgConfig, replica_id: NodeId) -> bool { dkg_pool.get_validated().any(|message| { - message.content.dkg_id == config.dkg_id() && message.signature.signer == replica_id + &message.content.dkg_id == config.dkg_id() && message.signature.signer == replica_id }) } diff --git a/rs/consensus/src/dkg/payload_builder.rs b/rs/consensus/src/dkg/payload_builder.rs index 742d010faf7..55dd17c790e 100644 --- a/rs/consensus/src/dkg/payload_builder.rs +++ b/rs/consensus/src/dkg/payload_builder.rs @@ -261,7 +261,7 @@ fn create_transcript( _logger: &ReplicaLogger, ) -> Result { let no_dealings = BTreeMap::new(); - let dealings = all_dealings.get(&config.dkg_id()).unwrap_or(&no_dealings); + let dealings = all_dealings.get(config.dkg_id()).unwrap_or(&no_dealings); ic_interfaces::crypto::NiDkgAlgorithm::create_transcript(crypto, config, dealings) } @@ -312,7 +312,7 @@ fn compute_remote_dkg_data( // if we do, move it to the new summary. if let Some((id, transcript)) = previous_transcripts .iter() - .find(|(id, _)| eq_sans_height(id, &dkg_id)) + .find(|(id, _)| eq_sans_height(id, dkg_id)) { new_transcripts.insert(id.clone(), transcript.clone()); } @@ -321,7 +321,7 @@ fn compute_remote_dkg_data( // the next round. else if !new_transcripts .iter() - .any(|(id, _)| eq_sans_height(id, &dkg_id)) + .any(|(id, _)| eq_sans_height(id, dkg_id)) { expected_configs.push(config) } @@ -364,7 +364,7 @@ fn compute_remote_dkg_data( if failed_target_ids.contains(&id) { for config in config_group.iter() { new_transcripts.insert( - config.dkg_id(), + config.dkg_id().clone(), Err(REMOTE_DKG_REPEATED_FAILURE_ERROR.to_string()), ); } @@ -846,7 +846,7 @@ mod tests { let config = configs[index].clone(); assert_eq!( config.dkg_id(), - NiDkgId { + &NiDkgId { start_block_height, dealer_subnet: subnet_id, dkg_tag: tag.clone(), @@ -1189,7 +1189,7 @@ mod tests { } ); - assert_eq!(&conf.dkg_id(), id); + assert_eq!(conf.dkg_id(), id); assert_eq!( conf.registry_version(), RegistryVersion::from(initial_registry_version) @@ -1294,7 +1294,7 @@ mod tests { } ); - assert_eq!(&conf.dkg_id(), id); + assert_eq!(conf.dkg_id(), id); assert_eq!( conf.registry_version(), RegistryVersion::from(initial_registry_version) diff --git a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs index 26e3e04e743..80c8037ff2e 100644 --- a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs +++ b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs @@ -203,6 +203,9 @@ pub trait NiDkgCspClient { fn create_dealing( &self, algorithm_id: AlgorithmId, + /////////////////////////////////////// + // TODO: dkg_id as ref + /////////////////////////////////////// dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, @@ -298,6 +301,9 @@ pub trait NiDkgCspClient { fn verify_dealing( &self, algorithm_id: AlgorithmId, + /////////////////////////////////////// + // TODO: dkg_id as ref + /////////////////////////////////////// dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, @@ -353,6 +359,9 @@ pub trait NiDkgCspClient { fn verify_resharing_dealing( &self, algorithm_id: AlgorithmId, + /////////////////////////////////////// + // TODO: dkg_id as ref + /////////////////////////////////////// dkg_id: NiDkgId, dealer_resharing_index: NodeIndex, threshold: NumberOfNodes, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs index f029dcff818..53e27259bb5 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs @@ -104,7 +104,7 @@ mod creation { ) -> Result { Ok(ni_dkg_csp_client.create_dealing( AlgorithmId::NiDkg_Groth20_Bls12_381, - config.dkg_id(), + config.dkg_id().clone(), dealer_index_in_dealers_or_panic(config.dealers(), *self_node_id), config.threshold().get(), epoch(config.registry_version()), @@ -162,7 +162,7 @@ mod verification { if let Some(transcript) = config.resharing_transcript() { Ok(ni_dkg_csp_client.verify_resharing_dealing( AlgorithmId::NiDkg_Groth20_Bls12_381, - config.dkg_id(), + config.dkg_id().clone(), index_in_resharing_committee_or_panic(dealer, &transcript.committee), config.threshold().get(), epoch, @@ -173,7 +173,7 @@ mod verification { } else { Ok(ni_dkg_csp_client.verify_dealing( AlgorithmId::NiDkg_Groth20_Bls12_381, - config.dkg_id(), + config.dkg_id().clone(), dealer_index_in_dealers_or_panic(config.dealers(), *dealer), config.threshold().get(), epoch, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs index 84f08b50907..911dd1f2e19 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/transcript.rs @@ -30,7 +30,7 @@ mod creation { ensure_dealing_node_ids_in_dealers(config.dealers(), &verified_dealings); let csp_transcript = create_csp_transcript(ni_dkg_csp_client, config, &verified_dealings)?; Ok(NiDkgTranscript { - dkg_id: config.dkg_id(), + dkg_id: config.dkg_id().clone(), threshold: config.threshold(), committee: config.receivers().clone(), registry_version: config.registry_version(), diff --git a/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs b/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs index 548bc1172d6..2c48e47db8c 100644 --- a/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs +++ b/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs @@ -51,7 +51,7 @@ fn should_correctly_create_initial_dkg_config_for_single_node() { assert_eq!( config.get().dkg_id(), - NiDkgId { + &NiDkgId { start_block_height: Height::new(0), dealer_subnet, dkg_tag, @@ -90,7 +90,7 @@ fn should_correctly_create_initial_dkg_config() { assert_eq!( config.get().dkg_id(), - NiDkgId { + &NiDkgId { start_block_height: Height::new(0), dealer_subnet, dkg_tag, diff --git a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs index 322cd3ad2ac..29857dfdbb1 100644 --- a/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs +++ b/rs/crypto/tests/threshold_sigs_with_ni_dkg.rs @@ -212,7 +212,7 @@ fn setup_with_random_ni_dkg_config( .subnet_size(subnet_size) .build(rng) .into_config(); - let dkg_id = config.dkg_id(); + let dkg_id = config.dkg_id().clone(); let crypto_components = NiDkgTestEnvironment::new_for_config(&config, rng).crypto_components; (config, dkg_id, crypto_components) } @@ -795,7 +795,7 @@ mod non_interactive_distributed_key_generation { load_transcript_for_receivers(config.get(), &transcript, &env.crypto_components); - let dkg_id = config.get().dkg_id(); + let dkg_id = config.get().dkg_id().clone(); let nodes = config.receiver_ids(); (transcript, dkg_id, nodes) diff --git a/rs/test_utilities/src/crypto.rs b/rs/test_utilities/src/crypto.rs index 7cb5978364e..be398809cb7 100644 --- a/rs/test_utilities/src/crypto.rs +++ b/rs/test_utilities/src/crypto.rs @@ -255,11 +255,11 @@ impl NiDkgAlgorithm for CryptoReturningOk { ) -> Result { let mut transcript = dummy_transcript_for_tests_with_params( config.receivers().get().clone().into_iter().collect(), - config.dkg_id().dkg_tag, + config.dkg_id().dkg_tag.clone(), config.threshold().get().get(), config.registry_version().get(), ); - transcript.dkg_id = config.dkg_id(); + transcript.dkg_id = config.dkg_id().clone(); Ok(transcript) } diff --git a/rs/types/types/src/consensus/dkg.rs b/rs/types/types/src/consensus/dkg.rs index 61e3bf209b4..cb32c6c7aa4 100644 --- a/rs/types/types/src/consensus/dkg.rs +++ b/rs/types/types/src/consensus/dkg.rs @@ -182,7 +182,7 @@ impl Summary { Self { configs: configs .into_iter() - .map(|config| (config.dkg_id(), config)) + .map(|config| (config.dkg_id().clone(), config)) .collect(), current_transcripts, next_transcripts, diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/config.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/config.rs index 4fd2fc5dafc..539a4b335be 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/config.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/config.rs @@ -168,11 +168,8 @@ impl NiDkgConfig { }) } - pub fn dkg_id(&self) -> NiDkgId { - //////////////////////////// - // TODO: ideally now a reference is returned, but there are many callers... - //////////////////////////// - self.dkg_id.clone() + pub fn dkg_id(&self) -> &NiDkgId { + &self.dkg_id } pub fn max_corrupt_dealers(&self) -> NumberOfNodes { diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/config/tests.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/config/tests.rs index 502836b05e6..1c4a76e857f 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/config/tests.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/config/tests.rs @@ -215,7 +215,7 @@ fn should_return_correct_config_values() { let config = NiDkgConfig::new(config_data).unwrap(); - assert_eq!(config.dkg_id(), dkg_id); + assert_eq!(config.dkg_id(), &dkg_id); assert_eq!(config.max_corrupt_dealers(), max_corrupt_dealers); assert_eq!(config.dealers().get(), &dealers); assert_eq!(config.max_corrupt_receivers(), max_corrupt_receivers); diff --git a/rs/types/types/src/exhaustive.rs b/rs/types/types/src/exhaustive.rs index bdcc4cb2ef1..d494659d24b 100644 --- a/rs/types/types/src/exhaustive.rs +++ b/rs/types/types/src/exhaustive.rs @@ -918,7 +918,7 @@ trait HasId { impl HasId for NiDkgConfig { fn get_id(&self) -> Option { - Some(self.dkg_id()) + Some(self.dkg_id().clone()) } } impl HasId for IDkgTranscript { From e0e60b9f9bf99cbb2b7dd1dd39325cf64f0789ee Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 16:11:19 +0000 Subject: [PATCH 10/30] Remove obsolete dkg_id param in NiDkgCspClient::create_dealing --- .../crypto_service_provider/src/api/threshold.rs | 5 ----- .../src/threshold/ni_dkg/mod.rs | 1 - .../src/threshold/ni_dkg/tests/fixtures.rs | 11 +---------- .../src/threshold/ni_dkg/tests/test_create_dealing.rs | 3 --- rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs | 1 - .../src/sign/threshold_sig/ni_dkg/dealing/tests.rs | 10 ++++------ rs/crypto/test_utils/csp/src/lib.rs | 1 - 7 files changed, 5 insertions(+), 27 deletions(-) diff --git a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs index 80c8037ff2e..7559dc4686f 100644 --- a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs +++ b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs @@ -179,7 +179,6 @@ pub trait NiDkgCspClient { /// /// # Arguments /// * `algorithm_id` selects the algorithm suite to use for the scheme. - /// * `dkg_id` is the identifier for the distributed key being generated. /// * `dealer_index` the index associated with the dealer. /// * `threshold` is the minimum number of nodes required to generate a /// valid threshold signature. @@ -203,10 +202,6 @@ pub trait NiDkgCspClient { fn create_dealing( &self, algorithm_id: AlgorithmId, - /////////////////////////////////////// - // TODO: dkg_id as ref - /////////////////////////////////////// - dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs index 4c6a6662b42..b078724349e 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs @@ -81,7 +81,6 @@ impl NiDkgCspClient for Csp { fn create_dealing( &self, algorithm_id: AlgorithmId, - _dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs index 9ee51d9184c..db432b64198 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs @@ -67,7 +67,6 @@ impl MockNode { pub fn create_dealing( &self, algorithm_id: AlgorithmId, - dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, @@ -85,14 +84,7 @@ impl MockNode { ) } else { self.csp - .create_dealing( - algorithm_id, - dkg_id, - dealer_index, - threshold, - epoch, - receiver_keys, - ) + .create_dealing(algorithm_id, dealer_index, threshold, epoch, receiver_keys) .map_err(ni_dkg_errors::CspDkgCreateReshareDealingError::from) } } @@ -272,7 +264,6 @@ impl StateWithDealings { .expect("Could not find dealer in nodes"); let dealing = node.create_dealing( config.algorithm_id, - config.dkg_id.clone(), config .dealers .position(node.node_id) diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/test_create_dealing.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/test_create_dealing.rs index 58cb4e592b3..e9a4f1725ad 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/test_create_dealing.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/test_create_dealing.rs @@ -72,7 +72,6 @@ impl StateWithConfig { let dealing = dealer_node.create_dealing( incorrect_algorithm_id, - self.config.dkg_id.clone(), self.config .dealers .position(dealer_node.node_id) @@ -122,7 +121,6 @@ impl StateWithConfig { for incorrect_threshold in &[0, num_receivers + 1, num_receivers + 2] { let dealing = dealer_node.create_dealing( self.config.algorithm_id, - self.config.dkg_id.clone(), self.config .dealers .position(dealer_node.node_id) @@ -168,7 +166,6 @@ impl StateWithConfig { let dealing = dealer_node.create_dealing( self.config.algorithm_id, - self.config.dkg_id.clone(), self.config .dealers .position(dealer_node.node_id) diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs index 53e27259bb5..9e24dc8f918 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs @@ -104,7 +104,6 @@ mod creation { ) -> Result { Ok(ni_dkg_csp_client.create_dealing( AlgorithmId::NiDkg_Groth20_Bls12_381, - config.dkg_id().clone(), dealer_index_in_dealers_or_panic(config.dealers(), *self_node_id), config.threshold().get(), epoch(config.registry_version()), diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs index 3602d9e15f7..df73e24e96e 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs @@ -47,9 +47,8 @@ mod create_dealing { let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_create_dealing() .withf( - move |algorithm_id, dkg_id, dealer_index, threshold, epoch_, receiver_keys| { - *dkg_id == DKG_ID - && *dealer_index == 0 + move |algorithm_id, dealer_index, threshold, epoch_, receiver_keys| { + *dealer_index == 0 && *algorithm_id == AlgorithmId::NiDkg_Groth20_Bls12_381 && *threshold == THRESHOLD && *epoch_ == epoch(REG_V2) @@ -305,9 +304,8 @@ mod create_dealing { let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_create_dealing() .withf( - move |algorithm_id, dkg_id, dealer_index, threshold, epoch_, receiver_keys| { - *dkg_id == DKG_ID - && *dealer_index == expected_index + move |algorithm_id, dealer_index, threshold, epoch_, receiver_keys| { + *dealer_index == expected_index && *algorithm_id == AlgorithmId::NiDkg_Groth20_Bls12_381 && *threshold == THRESHOLD && *epoch_ == epoch(REG_V2) diff --git a/rs/crypto/test_utils/csp/src/lib.rs b/rs/crypto/test_utils/csp/src/lib.rs index f4a4c6b04b7..f5234643a63 100644 --- a/rs/crypto/test_utils/csp/src/lib.rs +++ b/rs/crypto/test_utils/csp/src/lib.rs @@ -110,7 +110,6 @@ mock! { fn create_dealing( &self, algorithm_id: AlgorithmId, - dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, From 26e2b6ad1fd9352ac59a9380e76b52f28647e1cc Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 16:20:16 +0000 Subject: [PATCH 11/30] Remove obsolete dkg_id param in NiDkgCspClient::verify_dealing --- .../src/api/threshold.rs | 6 ------ .../src/threshold/ni_dkg/mod.rs | 3 --- .../src/threshold/ni_dkg/tests/fixtures.rs | 1 - .../src/vault/test_utils/ni_dkg/fixtures.rs | 1 - .../src/sign/threshold_sig/ni_dkg/dealing.rs | 1 - .../threshold_sig/ni_dkg/dealing/tests.rs | 19 +++---------------- rs/crypto/test_utils/csp/src/lib.rs | 1 - 7 files changed, 3 insertions(+), 29 deletions(-) diff --git a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs index 7559dc4686f..979bf9fd4f9 100644 --- a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs +++ b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs @@ -292,14 +292,9 @@ pub trait NiDkgCspClient { /// error. (`InvalidDealingError`) /// * the number of receiver keys is unsupported by this machine. /// (`SizeError`) - #[allow(clippy::too_many_arguments)] fn verify_dealing( &self, algorithm_id: AlgorithmId, - /////////////////////////////////////// - // TODO: dkg_id as ref - /////////////////////////////////////// - dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, @@ -350,7 +345,6 @@ pub trait NiDkgCspClient { /// (`InvalidDealingError`) /// * the number of receiver keys is unsupported by this machine. /// (`SizeError`) - #[allow(clippy::too_many_arguments)] // The arguments are per the spec. fn verify_resharing_dealing( &self, algorithm_id: AlgorithmId, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs index b078724349e..9ae2320ef94 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs @@ -129,7 +129,6 @@ impl NiDkgCspClient for Csp { fn verify_dealing( &self, algorithm_id: AlgorithmId, - dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, @@ -138,7 +137,6 @@ impl NiDkgCspClient for Csp { ) -> Result<(), ni_dkg_errors::CspDkgVerifyDealingError> { static_api::verify_dealing( algorithm_id, - dkg_id, dealer_index, threshold, epoch, @@ -335,7 +333,6 @@ pub mod static_api { /// Verifies a CSP dealing pub fn verify_dealing( algorithm_id: AlgorithmId, - _dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs index db432b64198..9391e2c69d2 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs @@ -321,7 +321,6 @@ impl StateWithVerifiedDealings { } else { static_api::verify_dealing( config.algorithm_id, - config.dkg_id.clone(), dealer_index, config.threshold.get(), config.epoch, diff --git a/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs index f23ba873edf..aa0316b304e 100644 --- a/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs @@ -352,7 +352,6 @@ impl StateWithVerifiedDealings { } else { ni_dkg_static_api::verify_dealing( config.algorithm_id, - config.dkg_id.clone(), dealer_index, config.threshold.get(), config.epoch, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs index 9e24dc8f918..b41262e7792 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs @@ -172,7 +172,6 @@ mod verification { } else { Ok(ni_dkg_csp_client.verify_dealing( AlgorithmId::NiDkg_Groth20_Bls12_381, - config.dkg_id().clone(), dealer_index_in_dealers_or_panic(config.dealers(), *dealer), config.threshold().get(), epoch, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs index df73e24e96e..c895acac297 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs @@ -483,15 +483,8 @@ mod verify_dealing { let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_verify_dealing() .withf( - move |algorithm_id, - dkg_id, - dealer_index, - threshold, - epoch_, - receiver_keys, - dealing| { - *dkg_id == DKG_ID - && *dealer_index == 0 + move |algorithm_id, dealer_index, threshold, epoch_, receiver_keys, dealing| { + *dealer_index == 0 && *algorithm_id == AlgorithmId::NiDkg_Groth20_Bls12_381 && *threshold == THRESHOLD && *epoch_ == epoch(REG_V2) @@ -714,13 +707,7 @@ mod verify_dealing { let mut csp = MockAllCryptoServiceProvider::new(); csp.expect_verify_dealing() .withf( - move |_algorithm_id, - _dkg_id, - _dealer_index, - _threshold, - _epoch, - receiver_keys, - _dealing| { + move |_algorithm_id, _dealer_index, _threshold, _epoch, receiver_keys, _dealing| { println!("{:?}", receiver_keys); *receiver_keys == expected_receiver_keys }, diff --git a/rs/crypto/test_utils/csp/src/lib.rs b/rs/crypto/test_utils/csp/src/lib.rs index f5234643a63..59bc666c70b 100644 --- a/rs/crypto/test_utils/csp/src/lib.rs +++ b/rs/crypto/test_utils/csp/src/lib.rs @@ -129,7 +129,6 @@ mock! { fn verify_dealing( &self, algorithm_id: AlgorithmId, - dkg_id: NiDkgId, dealer_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, From 14fec1da3f9d723a560923c9c67e506c3ea71e58 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 16:32:22 +0000 Subject: [PATCH 12/30] Remove obsolete dkg_id param in NiDkgCspClient::verify_resharing_dealing --- .../src/api/threshold.rs | 5 --- .../src/threshold/ni_dkg/mod.rs | 4 --- .../src/threshold/ni_dkg/tests/fixtures.rs | 31 ++----------------- .../src/vault/test_utils/ni_dkg/fixtures.rs | 1 - .../src/sign/threshold_sig/ni_dkg/dealing.rs | 1 - .../threshold_sig/ni_dkg/dealing/tests.rs | 4 +-- rs/crypto/test_utils/csp/src/lib.rs | 2 -- 7 files changed, 3 insertions(+), 45 deletions(-) diff --git a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs index 979bf9fd4f9..d67b6f92cca 100644 --- a/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs +++ b/rs/crypto/internal/crypto_service_provider/src/api/threshold.rs @@ -7,7 +7,6 @@ use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::{ CspFsEncryptionPublicKey, CspNiDkgDealing, CspNiDkgTranscript, Epoch, }; use ic_crypto_internal_types::sign::threshold_sig::public_key::CspThresholdSigPublicKey; -use ic_types::crypto::threshold_sig::ni_dkg::NiDkgId; use ic_types::crypto::{AlgorithmId, CryptoResult}; use ic_types::{NodeIndex, NumberOfNodes}; use serde::{Deserialize, Serialize}; @@ -348,10 +347,6 @@ pub trait NiDkgCspClient { fn verify_resharing_dealing( &self, algorithm_id: AlgorithmId, - /////////////////////////////////////// - // TODO: dkg_id as ref - /////////////////////////////////////// - dkg_id: NiDkgId, dealer_resharing_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs index 9ae2320ef94..a1a47bc5a86 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/mod.rs @@ -26,7 +26,6 @@ use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::{ }; use ic_logger::debug; use ic_types::crypto::error::{KeyNotFoundError, MalformedDataError}; -use ic_types::crypto::threshold_sig::ni_dkg::NiDkgId; use ic_types::crypto::AlgorithmId; use ic_types::{NodeIndex, NumberOfNodes}; use std::collections::{BTreeMap, BTreeSet}; @@ -149,7 +148,6 @@ impl NiDkgCspClient for Csp { fn verify_resharing_dealing( &self, algorithm_id: AlgorithmId, - dkg_id: NiDkgId, dealer_resharing_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, @@ -159,7 +157,6 @@ impl NiDkgCspClient for Csp { ) -> Result<(), ni_dkg_errors::CspDkgVerifyReshareDealingError> { static_api::verify_resharing_dealing( algorithm_id, - dkg_id, dealer_resharing_index, threshold, epoch, @@ -363,7 +360,6 @@ pub mod static_api { #[allow(clippy::too_many_arguments)] pub fn verify_resharing_dealing( algorithm_id: AlgorithmId, - _dkg_id: NiDkgId, dealer_resharing_index: NodeIndex, threshold: NumberOfNodes, epoch: Epoch, diff --git a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs index 9391e2c69d2..a077538ab56 100644 --- a/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/threshold/ni_dkg/tests/fixtures.rs @@ -7,37 +7,14 @@ use ic_crypto_internal_types::sign::threshold_sig::public_key::CspThresholdSigPu use ic_types::crypto::threshold_sig::ni_dkg::config::dealers::NiDkgDealers; use ic_types::crypto::threshold_sig::ni_dkg::config::receivers::NiDkgReceivers; use ic_types::crypto::threshold_sig::ni_dkg::config::NiDkgThreshold; -use ic_types::crypto::threshold_sig::ni_dkg::{NiDkgTag, NiDkgTargetSubnet}; use ic_types::crypto::AlgorithmId; -use ic_types::{Height, NodeId, SubnetId}; -use ic_types_test_utils::ids::{node_test_id, subnet_test_id}; +use ic_types::NodeId; +use ic_types_test_utils::ids::node_test_id; use rand::seq::IteratorRandom; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; use strum::IntoEnumIterator; -// Generate random data structures: -// Alternatively we could implement Distribution for all of these types. -// Deriving Rand may be enough for many. See: https://stackoverflow.com/questions/48490049/how-do-i-choose-a-random-value-from-an-enum -pub fn random_height(rng: &mut ChaCha20Rng) -> Height { - Height::from(rng.gen::()) -} -pub fn random_subnet_id(rng: &mut ChaCha20Rng) -> SubnetId { - subnet_test_id(rng.gen::()) -} -pub fn random_ni_dkg_tag(rng: &mut ChaCha20Rng) -> NiDkgTag { - NiDkgTag::iter() - .choose(rng) - .expect("Could not choose a NiDkgTag") -} -pub fn random_ni_dkg_id(rng: &mut ChaCha20Rng) -> NiDkgId { - NiDkgId { - start_block_height: random_height(rng), - dealer_subnet: random_subnet_id(rng), - target_subnet: NiDkgTargetSubnet::Local, - dkg_tag: random_ni_dkg_tag(rng), - } -} pub fn random_algorithm_id(rng: &mut ChaCha20Rng) -> AlgorithmId { AlgorithmId::iter() .choose(rng) @@ -142,7 +119,6 @@ impl MockNetwork { #[derive(Clone, Debug)] pub struct MockDkgConfig { pub algorithm_id: AlgorithmId, - pub dkg_id: NiDkgId, pub dealers: NiDkgDealers, pub receivers: NiDkgReceivers, pub receiver_keys: BTreeMap, @@ -202,7 +178,6 @@ impl MockDkgConfig { // Config values let algorithm_id = AlgorithmId::NiDkg_Groth20_Bls12_381; - let dkg_id = random_ni_dkg_id(rng); let max_corrupt_dealers = rng.gen_range(0..num_dealers); // Need at least one honest dealer. let threshold = rng.gen_range(min_threshold..=num_receivers); // threshold <= num_receivers let epoch = Epoch::from(rng.gen::()); @@ -215,7 +190,6 @@ impl MockDkgConfig { let resharing_transcript = last_dkg.map(|(_last_config, last_transcript)| last_transcript); MockDkgConfig { algorithm_id, - dkg_id, dealers, receivers, receiver_keys, @@ -310,7 +284,6 @@ impl StateWithVerifiedDealings { let test_result = if let Some(transcript) = &config.resharing_transcript { static_api::verify_resharing_dealing( config.algorithm_id, - config.dkg_id.clone(), dealer_index, config.threshold.get(), config.epoch, diff --git a/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs index aa0316b304e..ac5d81840e7 100644 --- a/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs @@ -341,7 +341,6 @@ impl StateWithVerifiedDealings { let test_result = if let Some(transcript) = &config.resharing_transcript { ni_dkg_static_api::verify_resharing_dealing( config.algorithm_id, - config.dkg_id.clone(), dealer_index, config.threshold.get(), config.epoch, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs index b41262e7792..ce10cc1c71d 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing.rs @@ -161,7 +161,6 @@ mod verification { if let Some(transcript) = config.resharing_transcript() { Ok(ni_dkg_csp_client.verify_resharing_dealing( AlgorithmId::NiDkg_Groth20_Bls12_381, - config.dkg_id().clone(), index_in_resharing_committee_or_panic(dealer, &transcript.committee), config.threshold().get(), epoch, diff --git a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs index c895acac297..40ddbe216e8 100644 --- a/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/ni_dkg/dealing/tests.rs @@ -758,15 +758,13 @@ mod verify_dealing_with_resharing_transcript { csp.expect_verify_resharing_dealing() .withf( move |algorithm_id, - dkg_id, dealer_resharing_index, threshold, epoch_, receiver_keys, dealing, resharing_pub_coeffs| { - *dkg_id == DKG_ID - && *algorithm_id == AlgorithmId::NiDkg_Groth20_Bls12_381 + *algorithm_id == AlgorithmId::NiDkg_Groth20_Bls12_381 && *threshold == THRESHOLD && *epoch_ == epoch(REG_V2) && *receiver_keys == map_of(vec![(0u32, csp_fs_enc_pk(PK_VALUE_1))]) diff --git a/rs/crypto/test_utils/csp/src/lib.rs b/rs/crypto/test_utils/csp/src/lib.rs index 59bc666c70b..61aa2523e1c 100644 --- a/rs/crypto/test_utils/csp/src/lib.rs +++ b/rs/crypto/test_utils/csp/src/lib.rs @@ -12,7 +12,6 @@ use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::{ CspFsEncryptionPublicKey, CspNiDkgDealing, CspNiDkgTranscript, Epoch, }; use ic_crypto_internal_types::sign::threshold_sig::public_key::CspThresholdSigPublicKey; -use ic_types::crypto::threshold_sig::ni_dkg::NiDkgId; use ic_types::crypto::{AlgorithmId, CryptoResult}; use ic_types::{NodeIndex, NumberOfNodes}; use mockall::predicate::*; @@ -139,7 +138,6 @@ mock! { fn verify_resharing_dealing( &self, algorithm_id: AlgorithmId, - dkg_id: NiDkgId, dealer_resharing_index: u32, threshold: NumberOfNodes, epoch: Epoch, From 7339b903e08addc28e24ead92cbb2cdcd53d8de8 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 1 Nov 2024 20:57:03 +0000 Subject: [PATCH 13/30] Cleanup --- rs/types/types/src/crypto/threshold_sig/ni_dkg.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs index d2db020d82f..05c6831af45 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs @@ -9,7 +9,6 @@ use core::fmt; use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::{CspNiDkgDealing, CspNiDkgTranscript}; #[cfg(test)] use ic_exhaustive_derive::ExhaustiveSet; -// use ic_management_canister_types::MasterPublicKeyId; use ic_protobuf::types::v1 as pb; use ic_protobuf::types::v1::NiDkgId as NiDkgIdProto; use serde::{Deserialize, Serialize}; @@ -37,7 +36,6 @@ mod tests; pub enum NiDkgTag { LowThreshold = 1, HighThreshold = 2, - // HighThresholdForKey(MasterPublicKeyId) = 3, } impl From<&NiDkgTag> for pb::NiDkgTag { From dbaf13a52baeff138d1b2bd8d625ad0030d1e1ad Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Tue, 5 Nov 2024 13:33:28 +0000 Subject: [PATCH 14/30] feat(crypto): CRP-2597-extend-nidkg-tag-with-high-threshold-for-keyid-variant --- Cargo.lock | 2 + rs/consensus/src/consensus/batch_delivery.rs | 8 +- rs/consensus/src/consensus/dkg_key_manager.rs | 9 +- rs/consensus/src/dkg/payload_builder.rs | 27 +++++- rs/crypto/BUILD.bazel | 1 + rs/crypto/Cargo.toml | 1 + rs/crypto/benches/ni_dkg.rs | 5 ++ .../crypto_service_provider/BUILD.bazel | 1 + .../crypto_service_provider/Cargo.toml | 1 + .../src/vault/test_utils/ni_dkg/fixtures.rs | 47 +++++++++- rs/crypto/src/sign/threshold_sig.rs | 22 +++-- rs/crypto/src/sign/threshold_sig/store.rs | 39 +++++++-- .../ni-dkg/src/initial_config/tests.rs | 3 + rs/crypto/test_utils/ni-dkg/src/lib.rs | 6 +- rs/protobuf/def/types/v1/dkg.proto | 1 + rs/protobuf/def/types/v1/types.proto | 2 + rs/protobuf/generator/src/lib.rs | 5 +- rs/protobuf/src/gen/crypto/types.v1.rs | 5 ++ rs/protobuf/src/gen/messaging/types.v1.rs | 5 ++ rs/protobuf/src/gen/registry/types.v1.rs | 5 ++ rs/protobuf/src/gen/state/types.v1.rs | 5 ++ rs/protobuf/src/gen/types/types.v1.rs | 24 ++++-- rs/types/management_canister_types/src/lib.rs | 14 ++- rs/types/types/src/consensus/dkg.rs | 86 +++++++++++++++++-- .../types/src/crypto/threshold_sig/ni_dkg.rs | 38 ++++++-- .../src/crypto/threshold_sig/ni_dkg/id.rs | 33 ++++++- .../crypto/threshold_sig/ni_dkg/id/tests.rs | 36 +++++++- .../src/crypto/threshold_sig/ni_dkg/tests.rs | 46 +++++++--- 28 files changed, 408 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e4b048748d..4b77905d8b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6832,6 +6832,7 @@ dependencies = [ "ic-interfaces-registry", "ic-interfaces-registry-mocks", "ic-logger", + "ic-management-canister-types", "ic-metrics", "ic-protobuf", "ic-registry-client", @@ -7173,6 +7174,7 @@ dependencies = [ "ic-crypto-utils-basic-sig", "ic-interfaces", "ic-logger", + "ic-management-canister-types", "ic-metrics", "ic-protobuf", "ic-sys", diff --git a/rs/consensus/src/consensus/batch_delivery.rs b/rs/consensus/src/consensus/batch_delivery.rs index bf88a935c69..5bb79ad829b 100644 --- a/rs/consensus/src/consensus/batch_delivery.rs +++ b/rs/consensus/src/consensus/batch_delivery.rs @@ -308,7 +308,7 @@ pub fn generate_responses_to_setup_initial_dkg_calls( for (id, callback_id, transcript) in transcripts_for_remote_subnets.iter() { let add_transcript = |transcript_results: &mut TranscriptResults| { let value = Some(transcript.clone()); - match id.dkg_tag { + match &id.dkg_tag { NiDkgTag::LowThreshold => { if transcript_results.low_threshold.is_some() { error!( @@ -327,6 +327,12 @@ pub fn generate_responses_to_setup_initial_dkg_calls( } transcript_results.high_threshold = value; } + NiDkgTag::HighThresholdForKey(master_public_key_id) => { + error!( + log, + "Implementation error: NiDkgTag::HighThresholdForKey({master_public_key_id}) used in SetupInitialDKG for callback ID {callback_id}", + ); + } } }; match transcripts.get_mut(callback_id) { diff --git a/rs/consensus/src/consensus/dkg_key_manager.rs b/rs/consensus/src/consensus/dkg_key_manager.rs index bb3e10aa4b4..4d95ead7b60 100644 --- a/rs/consensus/src/consensus/dkg_key_manager.rs +++ b/rs/consensus/src/consensus/dkg_key_manager.rs @@ -535,9 +535,12 @@ impl Drop for DkgKeyManager { /// Print the information about a [`NiDkgId`] in a concise way for logging fn dkg_id_log_msg(id: &NiDkgId) -> String { - let tag = match id.dkg_tag { - NiDkgTag::LowThreshold => "low", - NiDkgTag::HighThreshold => "high", + let tag = match &id.dkg_tag { + NiDkgTag::LowThreshold => "low".to_string(), + NiDkgTag::HighThreshold => "high".to_string(), + NiDkgTag::HighThresholdForKey(master_public_key_id) => { + format!("highForKey({master_public_key_id})") + } }; // If the target is local (which it is usually), we don't log the target diff --git a/rs/consensus/src/dkg/payload_builder.rs b/rs/consensus/src/dkg/payload_builder.rs index 55dd17c790e..f04f875717b 100644 --- a/rs/consensus/src/dkg/payload_builder.rs +++ b/rs/consensus/src/dkg/payload_builder.rs @@ -507,6 +507,21 @@ pub(crate) fn get_configs_for_local_transcripts( resharing_transcript.cloned(), ) } + //////////////////////////////////////////////////////////////////////////////// + // TODO: how to behave here? The code below is copied+adapted from the HighThreshold case. However, + // this code currently won't be executed because we iterate over TAGS, which is a const that does not + // and cannot contain an NiDkgTag::HighThresholdForKey entry + /////////////////////////////////////////////////////////////////////////////// + NiDkgTag::HighThresholdForKey(master_public_key_id) => { + let resharing_transcript = reshared_transcripts + .get(&NiDkgTag::HighThresholdForKey(master_public_key_id.clone())); + ( + resharing_transcript + .map(|transcript| transcript.committee.get().clone()) + .unwrap_or_else(|| node_ids.clone()), + resharing_transcript.cloned(), + ) + } }; let threshold = NumberOfNodes::from(tag.threshold_for_subnet_of_size(node_ids.len()) as u32); @@ -1206,9 +1221,13 @@ mod tests { assert_eq!(conf.max_corrupt_dealers().get(), 2); assert_eq!( conf.threshold().get().get(), - match *tag { + match tag { NiDkgTag::LowThreshold => 3, NiDkgTag::HighThreshold => 5, + ///////////////////////////////////////// + // TODO: check with Consensus team + NiDkgTag::HighThresholdForKey(_) => panic!("not applicable"), + ///////////////////////////////////////// } ); } @@ -1311,9 +1330,13 @@ mod tests { assert_eq!(conf.max_corrupt_dealers().get(), 2); assert_eq!( conf.threshold().get().get(), - match *tag { + match tag { NiDkgTag::LowThreshold => 3, NiDkgTag::HighThreshold => 5, + ///////////////////////////////////////// + // TODO: check with Consensus team + NiDkgTag::HighThresholdForKey(_) => panic!("not applicable"), + ///////////////////////////////////////// } ); diff --git a/rs/crypto/BUILD.bazel b/rs/crypto/BUILD.bazel index db9188c218f..411812b64ae 100644 --- a/rs/crypto/BUILD.bazel +++ b/rs/crypto/BUILD.bazel @@ -37,6 +37,7 @@ DEPENDENCIES = [ "//rs/registry/helpers", "//rs/registry/keys", "//rs/types/base_types", + "//rs/types/management_canister_types", "//rs/types/types", "@crate_index//:bincode", "@crate_index//:hex", diff --git a/rs/crypto/Cargo.toml b/rs/crypto/Cargo.toml index c7cec3750f3..17f94fb40ff 100644 --- a/rs/crypto/Cargo.toml +++ b/rs/crypto/Cargo.toml @@ -81,6 +81,7 @@ ic-crypto-test-utils-tls = { path = "test_utils/tls" } ic-crypto-tree-hash = { path = "tree_hash" } ic-crypto-utils-canister-threshold-sig = { path = "utils/canister_threshold_sig" } ic-interfaces-registry-mocks = { path = "../interfaces/registry/mocks" } +ic-management-canister-types = { path = "../types/management_canister_types" } ic-registry-client = { path = "../registry/client" } ic-registry-client-fake = { path = "../registry/fake" } ic-registry-proto-data-provider = { path = "../registry/proto_data_provider" } diff --git a/rs/crypto/benches/ni_dkg.rs b/rs/crypto/benches/ni_dkg.rs index f0625f7ee80..2b71a1cd84c 100644 --- a/rs/crypto/benches/ni_dkg.rs +++ b/rs/crypto/benches/ni_dkg.rs @@ -48,6 +48,9 @@ fn test_cases(num_dealers: &[usize]) -> Vec { for n in num_dealers { cases.push(TestCase::new(*n, NiDkgTag::LowThreshold)); cases.push(TestCase::new(*n, NiDkgTag::HighThreshold)); + /////////////////////////////////////////////////////// + // TODO: I assume we don't benchmark the NiDkgTag::HighThresholdForKey case here, right? + /////////////////////////////////////////////////////// } cases } @@ -258,6 +261,7 @@ impl TestCase { let tag_name = match self.dkg_tag { NiDkgTag::LowThreshold => "low", NiDkgTag::HighThreshold => "high", + NiDkgTag::HighThresholdForKey(_) => unimplemented!(), }; format!( "crypto_nidkg_{}_nodes_{}_dealers_{}", @@ -281,6 +285,7 @@ impl TestCase { num_of_dealers: num_of_nodes, dkg_tag, }, + NiDkgTag::HighThresholdForKey(_) => unimplemented!(), } } } diff --git a/rs/crypto/internal/crypto_service_provider/BUILD.bazel b/rs/crypto/internal/crypto_service_provider/BUILD.bazel index 18f657f8daf..8272c5460bd 100644 --- a/rs/crypto/internal/crypto_service_provider/BUILD.bazel +++ b/rs/crypto/internal/crypto_service_provider/BUILD.bazel @@ -80,6 +80,7 @@ DEV_DEPENDENCIES = [ "//rs/crypto/utils/basic_sig", "//rs/test_utilities/in_memory_logger", "//rs/test_utilities/time", + "//rs/types/management_canister_types", "//rs/types/types_test_utils", "@crate_index//:assert_matches", "@crate_index//:lazy_static", diff --git a/rs/crypto/internal/crypto_service_provider/Cargo.toml b/rs/crypto/internal/crypto_service_provider/Cargo.toml index 7d1a9c71db7..0b5f2b1e1f4 100644 --- a/rs/crypto/internal/crypto_service_provider/Cargo.toml +++ b/rs/crypto/internal/crypto_service_provider/Cargo.toml @@ -76,6 +76,7 @@ ic-crypto-test-utils-local-csp-vault = { path = "../../../crypto/test_utils/loca ic-crypto-test-utils-metrics = { path = "../../../crypto/test_utils/metrics" } ic-crypto-test-utils-reproducible-rng = { path = "../../../crypto/test_utils/reproducible_rng" } ic-crypto-utils-basic-sig = { path = "../../utils/basic_sig" } +ic-management-canister-types = { path = "../../../types/management_canister_types" } ic-test-utilities-compare-dirs = { path = "../../../test_utilities/compare_dirs" } ic-test-utilities-in-memory-logger = { path = "../../../test_utilities/in_memory_logger" } ic-test-utilities-time = { path = "../../../test_utilities/time" } diff --git a/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs b/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs index ac5d81840e7..290130b7110 100644 --- a/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs +++ b/rs/crypto/internal/crypto_service_provider/src/vault/test_utils/ni_dkg/fixtures.rs @@ -10,6 +10,10 @@ use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::{ CspNiDkgDealing, CspNiDkgTranscript, Epoch, }; use ic_crypto_internal_types::sign::threshold_sig::public_key::CspThresholdSigPublicKey; +use ic_management_canister_types::{ + EcdsaCurve, EcdsaKeyId, MasterPublicKeyId, SchnorrAlgorithm, SchnorrKeyId, VetKdCurve, + VetKdKeyId, +}; use ic_types::crypto::threshold_sig::ni_dkg::config::dealers::NiDkgDealers; use ic_types::crypto::threshold_sig::ni_dkg::config::receivers::NiDkgReceivers; use ic_types::crypto::threshold_sig::ni_dkg::config::NiDkgThreshold; @@ -22,7 +26,7 @@ use rand::Rng; use rand_chacha::ChaCha20Rng; use std::collections::BTreeMap; use std::sync::Arc; -use strum::IntoEnumIterator; +use strum::{EnumCount, IntoEnumIterator}; // Generate random data structures: // Alternatively we could implement Distribution for all of these types. @@ -33,10 +37,45 @@ pub fn random_height(rng: &mut ChaCha20Rng) -> Height { pub fn random_subnet_id(rng: &mut ChaCha20Rng) -> SubnetId { subnet_test_id(rng.gen::()) } +pub fn random_master_public_key_id(rng: &mut ChaCha20Rng) -> MasterPublicKeyId { + assert_eq!(MasterPublicKeyId::COUNT, 3); + assert_eq!(EcdsaCurve::iter().count(), 1); + assert_eq!(SchnorrAlgorithm::iter().count(), 2); + assert_eq!(VetKdCurve::iter().count(), 1); + + use rand::prelude::SliceRandom; + [ + MasterPublicKeyId::Ecdsa(EcdsaKeyId { + curve: EcdsaCurve::Secp256k1, + name: "some key".to_string(), + }), + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Bip340Secp256k1, + name: "some key".to_string(), + }), + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Ed25519, + name: "some key".to_string(), + }), + MasterPublicKeyId::VetKd(VetKdKeyId { + curve: VetKdCurve::Bls12_381_G2, + name: "some key".to_string(), + }), + ] + .choose(rng) + .cloned() + .expect("Could not choose a MasterPublicKeyId") +} pub fn random_ni_dkg_tag(rng: &mut ChaCha20Rng) -> NiDkgTag { - NiDkgTag::iter() - .choose(rng) - .expect("Could not choose a NiDkgTag") + use rand::prelude::SliceRandom; + [ + NiDkgTag::LowThreshold, + NiDkgTag::HighThreshold, + NiDkgTag::HighThresholdForKey(random_master_public_key_id(rng)), + ] + .choose(rng) + .cloned() + .expect("Could not choose a NiDkgTag") } pub fn random_ni_dkg_id(rng: &mut ChaCha20Rng) -> NiDkgId { NiDkgId { diff --git a/rs/crypto/src/sign/threshold_sig.rs b/rs/crypto/src/sign/threshold_sig.rs index 689f493de1e..47225cc1e63 100644 --- a/rs/crypto/src/sign/threshold_sig.rs +++ b/rs/crypto/src/sign/threshold_sig.rs @@ -22,6 +22,9 @@ mod tests; pub struct ThresholdSignerInternal {} impl ThresholdSignerInternal { + //////////////////////////////////////// + #[allow(clippy::result_large_err)] + //////////////////////////////////////// pub fn sign_threshold( lockable_threshold_sig_data_store: &LockableThresholdSigDataStore, threshold_sig_csp_client: &C, @@ -70,6 +73,9 @@ fn sig_data_not_found_error(dkg_id: NiDkgId) -> ThresholdSigDataNotFoundError { ThresholdSigDataNotFoundError::ThresholdSigDataNotFound { dkg_id } } +//////////////////////////////////////// +#[allow(clippy::result_large_err)] +//////////////////////////////////////// fn threshold_sig_share_or_panic( csp_signature: CspSignature, ) -> Result, ThresholdSignError> { @@ -441,12 +447,8 @@ impl ThresholdSigVerifierInternal { H: Signable, { let csp_signature = CspSignature::try_from(signature)?; - let transcript = initial_ni_dkg_transcript_from_registry( - registry, - subnet_id, - version, - NiDkgTag::HighThreshold, - )?; + let transcript = + initial_high_threshold_ni_dkg_transcript_from_registry(registry, subnet_id, version)?; let csp_pub_coeffs = CspPublicCoefficients::from(&transcript); threshold_sig_csp_client .threshold_verify_combined_signature( @@ -459,20 +461,16 @@ impl ThresholdSigVerifierInternal { } } -fn initial_ni_dkg_transcript_from_registry( +fn initial_high_threshold_ni_dkg_transcript_from_registry( registry: &dyn RegistryClient, subnet_id: SubnetId, registry_version: RegistryVersion, - dkg_tag: NiDkgTag, ) -> CryptoResult { let maybe_transcripts = registry .get_initial_dkg_transcripts(subnet_id, registry_version) .map_err(CryptoError::RegistryClient)?; match maybe_transcripts.value { - Some(transcripts) => Ok(match dkg_tag { - NiDkgTag::LowThreshold => transcripts.low_threshold, - NiDkgTag::HighThreshold => transcripts.high_threshold, - }), + Some(transcripts) => Ok(transcripts.high_threshold), None => Err(CryptoError::DkgTranscriptNotFound { subnet_id, registry_version, diff --git a/rs/crypto/src/sign/threshold_sig/store.rs b/rs/crypto/src/sign/threshold_sig/store.rs index 3a78f843d4a..f9127f61b8f 100644 --- a/rs/crypto/src/sign/threshold_sig/store.rs +++ b/rs/crypto/src/sign/threshold_sig/store.rs @@ -1,4 +1,5 @@ use super::*; +use ic_management_canister_types::MasterPublicKeyId; use ic_types::crypto::threshold_sig::ni_dkg::NiDkgId; use std::collections::VecDeque; @@ -88,6 +89,8 @@ pub struct ThresholdSigDataStoreImpl { // VecDeque used as queue: `push_back` to add, `pop_front` to remove low_threshold_dkg_id_insertion_order: VecDeque, high_threshold_dkg_id_insertion_order: VecDeque, + high_threshold_for_key_id_dkg_id_insertion_order: + BTreeMap>, } #[derive(Default)] @@ -129,6 +132,7 @@ impl ThresholdSigDataStoreImpl { high_threshold_dkg_id_insertion_order: VecDeque::with_capacity( max_num_of_dkg_ids_per_tag, ), + high_threshold_for_key_id_dkg_id_insertion_order: BTreeMap::new(), } } @@ -137,7 +141,7 @@ impl ThresholdSigDataStoreImpl { if !self.store.contains_key(dkg_id) { self.store .insert(dkg_id.clone(), ThresholdSigData::default()); - match dkg_id.dkg_tag { + match &dkg_id.dkg_tag { NiDkgTag::LowThreshold => { self.low_threshold_dkg_id_insertion_order .push_back(dkg_id.clone()); @@ -146,6 +150,20 @@ impl ThresholdSigDataStoreImpl { self.high_threshold_dkg_id_insertion_order .push_back(dkg_id.clone()); } + NiDkgTag::HighThresholdForKey(master_public_key_id) => { + match self + .high_threshold_for_key_id_dkg_id_insertion_order + .get_mut(master_public_key_id) + { + Some(insertion_order) => insertion_order.push_back(dkg_id.clone()), + None => { + let mut buf = VecDeque::with_capacity(self.max_num_of_dkg_ids_per_tag); + buf.push_back(dkg_id.clone()); + self.high_threshold_for_key_id_dkg_id_insertion_order + .insert(master_public_key_id.clone(), buf); + } + } + } } } self.store @@ -155,14 +173,19 @@ impl ThresholdSigDataStoreImpl { fn purge_entry_for_oldest_dkg_id_if_necessary(&mut self, tag: &NiDkgTag) { let dkg_id_insertion_order = match tag { - NiDkgTag::LowThreshold => &mut self.low_threshold_dkg_id_insertion_order, - NiDkgTag::HighThreshold => &mut self.high_threshold_dkg_id_insertion_order, + NiDkgTag::LowThreshold => Some(&mut self.low_threshold_dkg_id_insertion_order), + NiDkgTag::HighThreshold => Some(&mut self.high_threshold_dkg_id_insertion_order), + NiDkgTag::HighThresholdForKey(master_public_key_id) => self + .high_threshold_for_key_id_dkg_id_insertion_order + .get_mut(master_public_key_id), }; - if dkg_id_insertion_order.len() > self.max_num_of_dkg_ids_per_tag { - let oldest_dkg_id = dkg_id_insertion_order - .pop_front() - .expect("dkg store unexpectedly empty"); - self.store.remove(&oldest_dkg_id); + if let Some(insertion_order) = dkg_id_insertion_order { + if insertion_order.len() > self.max_num_of_dkg_ids_per_tag { + let oldest_dkg_id = insertion_order + .pop_front() + .expect("dkg store unexpectedly empty"); + self.store.remove(&oldest_dkg_id); + } } } diff --git a/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs b/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs index 2c48e47db8c..85d1e1e5454 100644 --- a/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs +++ b/rs/crypto/test_utils/ni-dkg/src/initial_config/tests.rs @@ -294,6 +294,9 @@ fn registry_with_ni_dkg_transcript( cup_contents.initial_ni_dkg_transcript_low_threshold = Some(InitialNiDkgTranscriptRecord::from(transcript())); } + NiDkgTag::HighThresholdForKey(_master_public_key_id) => { + unimplemented!("not supported currently") + } } let registry_data = ProtoRegistryDataProvider::new(); registry_data diff --git a/rs/crypto/test_utils/ni-dkg/src/lib.rs b/rs/crypto/test_utils/ni-dkg/src/lib.rs index 52aa8754cbf..be3c2ae15fa 100644 --- a/rs/crypto/test_utils/ni-dkg/src/lib.rs +++ b/rs/crypto/test_utils/ni-dkg/src/lib.rs @@ -461,9 +461,13 @@ impl RandomNiDkgConfig { /// is possible to perform tests where a single subnet has both /// high and low threshold transcripts pub fn new_with_inverted_threshold(&self, rng: &mut R) -> Self { - let dkg_tag = match self.0.dkg_id().dkg_tag { + let dkg_tag = match &self.0.dkg_id().dkg_tag { NiDkgTag::LowThreshold => NiDkgTag::HighThreshold, NiDkgTag::HighThreshold => NiDkgTag::LowThreshold, + //////////////////////// + // TODO: how to behave here? + //////////////////////// + NiDkgTag::HighThresholdForKey(_master_public_key_id) => NiDkgTag::LowThreshold, }; let subnet_size = self.0.receivers().get().len(); diff --git a/rs/protobuf/def/types/v1/dkg.proto b/rs/protobuf/def/types/v1/dkg.proto index 5f44eae6bae..c6279bfd114 100644 --- a/rs/protobuf/def/types/v1/dkg.proto +++ b/rs/protobuf/def/types/v1/dkg.proto @@ -41,6 +41,7 @@ message Summary { message TaggedNiDkgTranscript { NiDkgTranscript transcript = 1; NiDkgTag tag = 2; + optional MasterPublicKeyId key_id = 3; } message CallbackIdedNiDkgTranscript { diff --git a/rs/protobuf/def/types/v1/types.proto b/rs/protobuf/def/types/v1/types.proto index c90b4c6da99..e6ec885e72c 100644 --- a/rs/protobuf/def/types/v1/types.proto +++ b/rs/protobuf/def/types/v1/types.proto @@ -32,6 +32,7 @@ message NiDkgId { bytes dealer_subnet = 2; NiDkgTag dkg_tag = 4; google.protobuf.BytesValue remote_target_id = 5; + optional MasterPublicKeyId key_id = 6; } // A non-interactive distributed key generation (NI-DKG) tag. @@ -39,6 +40,7 @@ enum NiDkgTag { NI_DKG_TAG_UNSPECIFIED = 0; NI_DKG_TAG_LOW_THRESHOLD = 1; NI_DKG_TAG_HIGH_THRESHOLD = 2; + NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY = 3; } message NominalCycles { diff --git a/rs/protobuf/generator/src/lib.rs b/rs/protobuf/generator/src/lib.rs index cb752ed8930..6fa62fa3b2a 100644 --- a/rs/protobuf/generator/src/lib.rs +++ b/rs/protobuf/generator/src/lib.rs @@ -351,7 +351,10 @@ fn build_types_proto(def: &Path, out: &Path) { config.type_attribute(".types.v1.SubnetId", "#[derive(Eq, Hash)]"); config.type_attribute(".types.v1.NiDkgId", "#[derive(Eq, Hash)]"); config.type_attribute(".types.v1.PrincipalId", "#[derive(Eq, Hash)]"); - config.type_attribute(".types.v1.EcdsaKeyId", "#[derive(Eq)]"); + config.type_attribute(".types.v1.MasterPublicKeyId", "#[derive(Eq, Hash)]"); + config.type_attribute(".types.v1.EcdsaKeyId", "#[derive(Eq, Hash)]"); + config.type_attribute(".types.v1.SchnorrKeyId", "#[derive(Eq, Hash)]"); + config.type_attribute(".types.v1.VetKdKeyId", "#[derive(Eq, Hash)]"); config.type_attribute(".types.v1.EcdsaCurve", "#[derive(candid::CandidType)]"); config.type_attribute(".types.v1.EcdsaKeyId", "#[derive(candid::CandidType)]"); config.type_attribute( diff --git a/rs/protobuf/src/gen/crypto/types.v1.rs b/rs/protobuf/src/gen/crypto/types.v1.rs index 19efff53939..89a98b27763 100644 --- a/rs/protobuf/src/gen/crypto/types.v1.rs +++ b/rs/protobuf/src/gen/crypto/types.v1.rs @@ -35,6 +35,8 @@ pub struct NiDkgId { pub dkg_tag: i32, #[prost(message, optional, tag = "5")] pub remote_target_id: ::core::option::Option<::prost::alloc::vec::Vec>, + #[prost(message, optional, tag = "6")] + pub key_id: ::core::option::Option, } #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] pub struct NominalCycles { @@ -100,6 +102,7 @@ pub enum NiDkgTag { Unspecified = 0, LowThreshold = 1, HighThreshold = 2, + HighThresholdForKey = 3, } impl NiDkgTag { /// String value of the enum field names used in the ProtoBuf definition. @@ -111,6 +114,7 @@ impl NiDkgTag { Self::Unspecified => "NI_DKG_TAG_UNSPECIFIED", Self::LowThreshold => "NI_DKG_TAG_LOW_THRESHOLD", Self::HighThreshold => "NI_DKG_TAG_HIGH_THRESHOLD", + Self::HighThresholdForKey => "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -119,6 +123,7 @@ impl NiDkgTag { "NI_DKG_TAG_UNSPECIFIED" => Some(Self::Unspecified), "NI_DKG_TAG_LOW_THRESHOLD" => Some(Self::LowThreshold), "NI_DKG_TAG_HIGH_THRESHOLD" => Some(Self::HighThreshold), + "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY" => Some(Self::HighThresholdForKey), _ => None, } } diff --git a/rs/protobuf/src/gen/messaging/types.v1.rs b/rs/protobuf/src/gen/messaging/types.v1.rs index a49c3e2e36f..59f003f321c 100644 --- a/rs/protobuf/src/gen/messaging/types.v1.rs +++ b/rs/protobuf/src/gen/messaging/types.v1.rs @@ -35,6 +35,8 @@ pub struct NiDkgId { pub dkg_tag: i32, #[prost(message, optional, tag = "5")] pub remote_target_id: ::core::option::Option<::prost::alloc::vec::Vec>, + #[prost(message, optional, tag = "6")] + pub key_id: ::core::option::Option, } #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] pub struct NominalCycles { @@ -100,6 +102,7 @@ pub enum NiDkgTag { Unspecified = 0, LowThreshold = 1, HighThreshold = 2, + HighThresholdForKey = 3, } impl NiDkgTag { /// String value of the enum field names used in the ProtoBuf definition. @@ -111,6 +114,7 @@ impl NiDkgTag { Self::Unspecified => "NI_DKG_TAG_UNSPECIFIED", Self::LowThreshold => "NI_DKG_TAG_LOW_THRESHOLD", Self::HighThreshold => "NI_DKG_TAG_HIGH_THRESHOLD", + Self::HighThresholdForKey => "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -119,6 +123,7 @@ impl NiDkgTag { "NI_DKG_TAG_UNSPECIFIED" => Some(Self::Unspecified), "NI_DKG_TAG_LOW_THRESHOLD" => Some(Self::LowThreshold), "NI_DKG_TAG_HIGH_THRESHOLD" => Some(Self::HighThreshold), + "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY" => Some(Self::HighThresholdForKey), _ => None, } } diff --git a/rs/protobuf/src/gen/registry/types.v1.rs b/rs/protobuf/src/gen/registry/types.v1.rs index a4772d33102..69525148912 100644 --- a/rs/protobuf/src/gen/registry/types.v1.rs +++ b/rs/protobuf/src/gen/registry/types.v1.rs @@ -35,6 +35,8 @@ pub struct NiDkgId { pub dkg_tag: i32, #[prost(message, optional, tag = "5")] pub remote_target_id: ::core::option::Option<::prost::alloc::vec::Vec>, + #[prost(message, optional, tag = "6")] + pub key_id: ::core::option::Option, } #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NominalCycles { @@ -88,6 +90,7 @@ pub enum NiDkgTag { Unspecified = 0, LowThreshold = 1, HighThreshold = 2, + HighThresholdForKey = 3, } impl NiDkgTag { /// String value of the enum field names used in the ProtoBuf definition. @@ -99,6 +102,7 @@ impl NiDkgTag { Self::Unspecified => "NI_DKG_TAG_UNSPECIFIED", Self::LowThreshold => "NI_DKG_TAG_LOW_THRESHOLD", Self::HighThreshold => "NI_DKG_TAG_HIGH_THRESHOLD", + Self::HighThresholdForKey => "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -107,6 +111,7 @@ impl NiDkgTag { "NI_DKG_TAG_UNSPECIFIED" => Some(Self::Unspecified), "NI_DKG_TAG_LOW_THRESHOLD" => Some(Self::LowThreshold), "NI_DKG_TAG_HIGH_THRESHOLD" => Some(Self::HighThreshold), + "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY" => Some(Self::HighThresholdForKey), _ => None, } } diff --git a/rs/protobuf/src/gen/state/types.v1.rs b/rs/protobuf/src/gen/state/types.v1.rs index 24d72856531..7ed42c11b5e 100644 --- a/rs/protobuf/src/gen/state/types.v1.rs +++ b/rs/protobuf/src/gen/state/types.v1.rs @@ -35,6 +35,8 @@ pub struct NiDkgId { pub dkg_tag: i32, #[prost(message, optional, tag = "5")] pub remote_target_id: ::core::option::Option<::prost::alloc::vec::Vec>, + #[prost(message, optional, tag = "6")] + pub key_id: ::core::option::Option, } #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NominalCycles { @@ -88,6 +90,7 @@ pub enum NiDkgTag { Unspecified = 0, LowThreshold = 1, HighThreshold = 2, + HighThresholdForKey = 3, } impl NiDkgTag { /// String value of the enum field names used in the ProtoBuf definition. @@ -99,6 +102,7 @@ impl NiDkgTag { Self::Unspecified => "NI_DKG_TAG_UNSPECIFIED", Self::LowThreshold => "NI_DKG_TAG_LOW_THRESHOLD", Self::HighThreshold => "NI_DKG_TAG_HIGH_THRESHOLD", + Self::HighThresholdForKey => "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -107,6 +111,7 @@ impl NiDkgTag { "NI_DKG_TAG_UNSPECIFIED" => Some(Self::Unspecified), "NI_DKG_TAG_LOW_THRESHOLD" => Some(Self::LowThreshold), "NI_DKG_TAG_HIGH_THRESHOLD" => Some(Self::HighThreshold), + "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY" => Some(Self::HighThresholdForKey), _ => None, } } diff --git a/rs/protobuf/src/gen/types/types.v1.rs b/rs/protobuf/src/gen/types/types.v1.rs index 70b5c346d04..c6b224d0946 100644 --- a/rs/protobuf/src/gen/types/types.v1.rs +++ b/rs/protobuf/src/gen/types/types.v1.rs @@ -122,6 +122,8 @@ pub struct NiDkgId { pub dkg_tag: i32, #[prost(message, optional, tag = "5")] pub remote_target_id: ::core::option::Option<::prost::alloc::vec::Vec>, + #[prost(message, optional, tag = "6")] + pub key_id: ::core::option::Option, } #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct NominalCycles { @@ -131,7 +133,14 @@ pub struct NominalCycles { pub low: u64, } #[derive( - serde::Serialize, serde::Deserialize, Eq, candid::CandidType, Clone, PartialEq, ::prost::Message, + serde::Serialize, + serde::Deserialize, + Eq, + Hash, + candid::CandidType, + Clone, + PartialEq, + ::prost::Message, )] pub struct EcdsaKeyId { #[prost(enumeration = "EcdsaCurve", tag = "1")] @@ -139,28 +148,28 @@ pub struct EcdsaKeyId { #[prost(string, tag = "2")] pub name: ::prost::alloc::string::String, } -#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +#[derive(serde::Serialize, serde::Deserialize, Eq, Hash, Clone, PartialEq, ::prost::Message)] pub struct SchnorrKeyId { #[prost(enumeration = "SchnorrAlgorithm", tag = "1")] pub algorithm: i32, #[prost(string, tag = "2")] pub name: ::prost::alloc::string::String, } -#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +#[derive(serde::Serialize, serde::Deserialize, Eq, Hash, Clone, PartialEq, ::prost::Message)] pub struct VetKdKeyId { #[prost(enumeration = "VetKdCurve", tag = "1")] pub curve: i32, #[prost(string, tag = "2")] pub name: ::prost::alloc::string::String, } -#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] +#[derive(serde::Serialize, serde::Deserialize, Eq, Hash, Clone, PartialEq, ::prost::Message)] pub struct MasterPublicKeyId { #[prost(oneof = "master_public_key_id::KeyId", tags = "1, 2, 3")] pub key_id: ::core::option::Option, } /// Nested message and enum types in `MasterPublicKeyId`. pub mod master_public_key_id { - #[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Oneof)] + #[derive(serde::Serialize, serde::Deserialize, Eq, Hash, Clone, PartialEq, ::prost::Oneof)] pub enum KeyId { #[prost(message, tag = "1")] Ecdsa(super::EcdsaKeyId), @@ -177,6 +186,7 @@ pub enum NiDkgTag { Unspecified = 0, LowThreshold = 1, HighThreshold = 2, + HighThresholdForKey = 3, } impl NiDkgTag { /// String value of the enum field names used in the ProtoBuf definition. @@ -188,6 +198,7 @@ impl NiDkgTag { Self::Unspecified => "NI_DKG_TAG_UNSPECIFIED", Self::LowThreshold => "NI_DKG_TAG_LOW_THRESHOLD", Self::HighThreshold => "NI_DKG_TAG_HIGH_THRESHOLD", + Self::HighThresholdForKey => "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -196,6 +207,7 @@ impl NiDkgTag { "NI_DKG_TAG_UNSPECIFIED" => Some(Self::Unspecified), "NI_DKG_TAG_LOW_THRESHOLD" => Some(Self::LowThreshold), "NI_DKG_TAG_HIGH_THRESHOLD" => Some(Self::HighThreshold), + "NI_DKG_TAG_HIGH_THRESHOLD_FOR_KEY" => Some(Self::HighThresholdForKey), _ => None, } } @@ -382,6 +394,8 @@ pub struct TaggedNiDkgTranscript { pub transcript: ::core::option::Option, #[prost(enumeration = "NiDkgTag", tag = "2")] pub tag: i32, + #[prost(message, optional, tag = "3")] + pub key_id: ::core::option::Option, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct CallbackIdedNiDkgTranscript { diff --git a/rs/types/management_canister_types/src/lib.rs b/rs/types/management_canister_types/src/lib.rs index 3f026ec6bd6..cdeaa8aedfc 100644 --- a/rs/types/management_canister_types/src/lib.rs +++ b/rs/types/management_canister_types/src/lib.rs @@ -35,7 +35,7 @@ use serde::Serialize; use serde_bytes::ByteBuf; use std::mem::size_of; use std::{collections::BTreeSet, convert::TryFrom, error::Error, fmt, slice::Iter, str::FromStr}; -use strum_macros::{Display, EnumIter, EnumString}; +use strum_macros::{Display, EnumCount, EnumIter, EnumString}; /// The id of the management canister. pub const IC_00: CanisterId = CanisterId::ic_00(); @@ -2370,7 +2370,17 @@ impl FromStr for VetKdKeyId { /// (variant { EcdsaKeyId; SchnorrKeyId }) /// ``` #[derive( - Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, CandidType, Deserialize, Serialize, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug, + CandidType, + Deserialize, + EnumCount, + Serialize, )] pub enum MasterPublicKeyId { Ecdsa(EcdsaKeyId), diff --git a/rs/types/types/src/consensus/dkg.rs b/rs/types/types/src/consensus/dkg.rs index cb32c6c7aa4..ffefbd0b8de 100644 --- a/rs/types/types/src/consensus/dkg.rs +++ b/rs/types/types/src/consensus/dkg.rs @@ -9,6 +9,7 @@ use crate::{ messages::CallbackId, ReplicaVersion, }; +use ic_management_canister_types::MasterPublicKeyId; use ic_protobuf::types::v1 as pb; use serde_with::serde_as; use std::collections::BTreeMap; @@ -300,6 +301,10 @@ fn build_tagged_transcripts_vec( .map(|(tag, transcript)| pb::TaggedNiDkgTranscript { tag: pb::NiDkgTag::from(tag) as i32, transcript: Some(pb::NiDkgTranscript::from(transcript)), + key_id: match tag { + NiDkgTag::HighThresholdForKey(k) => Some(pb::MasterPublicKeyId::from(k)), + _ => None, + }, }) .collect() } @@ -375,12 +380,33 @@ fn build_tagged_transcripts_map( .ok_or_else(|| ProxyDecodeError::MissingField("TaggedNiDkgTranscript::transcript")) .and_then(|t| { Ok(( - NiDkgTag::try_from(tagged_transcript.tag).map_err(|e| { - ProxyDecodeError::Other(format!( - "Failed to convert NiDkgTag of transcript: {:?}", - e - )) - })?, + // TODO: test all cases!? + match tagged_transcript.tag { + 1 => Ok(NiDkgTag::LowThreshold), + 2 => Ok(NiDkgTag::HighThreshold), + 3 => { + let mpkid_proto = + tagged_transcript.key_id.as_ref().ok_or_else(|| { + ProxyDecodeError::Other( + "Failed to convert NiDkgTag of transcript: \ + Invalid DkgTag: missing key ID" + .to_string(), + ) + })?; + let mpkid = MasterPublicKeyId::try_from(mpkid_proto.clone()) + .map_err(|e| { + ProxyDecodeError::Other(format!( + "Failed to convert NiDkgTag of transcript: \ + Invalid MasterPublicKeyId: {e}" + )) + })?; + Ok(NiDkgTag::HighThresholdForKey(mpkid)) + } + _ => Err(ProxyDecodeError::Other( + "Failed to convert NiDkgTag of transcript: Invalid DKG tag" + .to_string(), + )), + }?, NiDkgTranscript::try_from(t).map_err(ProxyDecodeError::Other)?, )) }) @@ -535,7 +561,7 @@ impl NiDkgTag { let f = crate::consensus::get_faults_tolerated(committee_size); match self { NiDkgTag::LowThreshold => f + 1, - NiDkgTag::HighThreshold => committee_size - f, + NiDkgTag::HighThreshold | NiDkgTag::HighThresholdForKey(_) => committee_size - f, } } } @@ -585,7 +611,14 @@ impl TryFrom for Payload { #[cfg(test)] mod tests { + use super::*; + use ic_management_canister_types::{ + EcdsaCurve, EcdsaKeyId, MasterPublicKeyId, SchnorrAlgorithm, SchnorrKeyId, VetKdCurve, + VetKdKeyId, + }; + use strum::EnumCount; + use strum::IntoEnumIterator; #[test] fn should_correctly_calculate_threshold_for_ni_dkg_tag_low_threshold() { @@ -600,6 +633,7 @@ mod tests { assert_eq!(low_threshold_tag.threshold_for_subnet_of_size(28), 10); assert_eq!(low_threshold_tag.threshold_for_subnet_of_size(64), 22); } + #[test] fn should_correctly_calculate_threshold_for_ni_dkg_tag_high_threshold() { let high_threshold_tag = NiDkgTag::HighThreshold; @@ -614,6 +648,44 @@ mod tests { assert_eq!(high_threshold_tag.threshold_for_subnet_of_size(64), 43); } + #[test] + fn should_correctly_calculate_threshold_for_ni_dkg_tag_high_threshold_for_key() { + for master_public_key_id in [ + MasterPublicKeyId::Ecdsa(EcdsaKeyId { + curve: EcdsaCurve::Secp256k1, + name: "some key".to_string(), + }), + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Bip340Secp256k1, + name: "some key".to_string(), + }), + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Ed25519, + name: "some key".to_string(), + }), + MasterPublicKeyId::VetKd(VetKdKeyId { + curve: VetKdCurve::Bls12_381_G2, + name: "some key".to_string(), + }), + ] { + let tag = NiDkgTag::HighThresholdForKey(master_public_key_id); + + assert_eq!(tag.threshold_for_subnet_of_size(0), 1); + assert_eq!(tag.threshold_for_subnet_of_size(1), 1); + assert_eq!(tag.threshold_for_subnet_of_size(2), 1); + assert_eq!(tag.threshold_for_subnet_of_size(3), 1); + assert_eq!(tag.threshold_for_subnet_of_size(4), 3); + assert_eq!(tag.threshold_for_subnet_of_size(5), 3); + assert_eq!(tag.threshold_for_subnet_of_size(6), 3); + assert_eq!(tag.threshold_for_subnet_of_size(28), 19); + assert_eq!(tag.threshold_for_subnet_of_size(64), 43); + } + assert_eq!(MasterPublicKeyId::COUNT, 3); + assert_eq!(EcdsaCurve::iter().count(), 1); + assert_eq!(SchnorrAlgorithm::iter().count(), 2); + assert_eq!(VetKdCurve::iter().count(), 1); + } + #[test] fn should_correctly_calculate_faults_tolerated_for_committee_of_size() { use crate::consensus::get_faults_tolerated; diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs index 05c6831af45..96140ab8362 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs @@ -9,12 +9,13 @@ use core::fmt; use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::{CspNiDkgDealing, CspNiDkgTranscript}; #[cfg(test)] use ic_exhaustive_derive::ExhaustiveSet; +use ic_management_canister_types::MasterPublicKeyId; use ic_protobuf::types::v1 as pb; use ic_protobuf::types::v1::NiDkgId as NiDkgIdProto; use serde::{Deserialize, Serialize}; use std::collections::BTreeSet; use std::convert::TryFrom; -use strum_macros::EnumIter; +use strum_macros::EnumCount; use thiserror::Error; pub mod config; @@ -31,11 +32,13 @@ mod tests; /// Allows to distinguish protocol executions in high and low threshold /// settings. -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, EnumIter, Serialize)] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, EnumCount, Serialize)] #[cfg_attr(test, derive(ExhaustiveSet))] +#[repr(isize)] pub enum NiDkgTag { LowThreshold = 1, HighThreshold = 2, + HighThresholdForKey(MasterPublicKeyId) = 3, } impl From<&NiDkgTag> for pb::NiDkgTag { @@ -43,6 +46,9 @@ impl From<&NiDkgTag> for pb::NiDkgTag { match tag { NiDkgTag::LowThreshold => pb::NiDkgTag::LowThreshold, NiDkgTag::HighThreshold => pb::NiDkgTag::HighThreshold, + NiDkgTag::HighThresholdForKey(_master_public_key_id) => { + pb::NiDkgTag::HighThresholdForKey + } } } } @@ -100,14 +106,30 @@ impl fmt::Display for NiDkgTargetSubnet { } } -impl TryFrom for NiDkgTag { - type Error = (); +// No longer possible; +// this must be used in conversion of NiDkgId to pb::NiDkgId; +// implement directly there +// impl TryFrom for NiDkgTag { +// type Error = (); - fn try_from(ni_dkg_tag: i32) -> Result { +// fn try_from(ni_dkg_tag: i32) -> Result { +// match ni_dkg_tag { +// 1 => Ok(NiDkgTag::LowThreshold), +// 2 => Ok(NiDkgTag::HighThreshold), +// _ => Err(()), +// } +// } +// } + +//////////////////// +// TODO: check if we still need this +//////////////////////// +impl From<&NiDkgTag> for i32 { + fn from(ni_dkg_tag: &NiDkgTag) -> Self { match ni_dkg_tag { - 1 => Ok(NiDkgTag::LowThreshold), - 2 => Ok(NiDkgTag::HighThreshold), - _ => Err(()), + NiDkgTag::LowThreshold => 1, + NiDkgTag::HighThreshold => 2, + NiDkgTag::HighThresholdForKey(_) => 3, } } } diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs index 66985cd50a4..20bc996b9de 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs @@ -47,11 +47,15 @@ impl From for NiDkgIdProto { NiDkgIdProto { start_block_height: ni_dkg_id.start_block_height.get(), dealer_subnet: ni_dkg_id.dealer_subnet.get().into_vec(), - dkg_tag: ni_dkg_id.dkg_tag as i32, + dkg_tag: pb::NiDkgTag::from(&ni_dkg_id.dkg_tag) as i32, // i32::from(&ni_dkg_id.dkg_tag), // TODO: delete i32::from conversion ? remote_target_id: match ni_dkg_id.target_subnet { NiDkgTargetSubnet::Remote(target_id) => Some(target_id.0.to_vec()), NiDkgTargetSubnet::Local => None, }, + key_id: match ni_dkg_id.dkg_tag { + NiDkgTag::HighThresholdForKey(k) => Some(pb::MasterPublicKeyId::from(&k)), + _ => None, + }, } } } @@ -66,8 +70,23 @@ impl TryFrom for NiDkgId { PrincipalId::try_from(ni_dkg_id_proto.dealer_subnet.as_slice()) .map_err(NiDkgIdFromProtoError::InvalidPrincipalId)?, ), - dkg_tag: NiDkgTag::try_from(ni_dkg_id_proto.dkg_tag) - .map_err(|_| NiDkgIdFromProtoError::InvalidDkgTag)?, + dkg_tag: { + match ni_dkg_id_proto.dkg_tag { + 1 => Ok(NiDkgTag::LowThreshold), + 2 => Ok(NiDkgTag::HighThreshold), + 3 => { + let mpkid_proto = ni_dkg_id_proto + .key_id + .ok_or(NiDkgIdFromProtoError::InvalidDkgTagMissingKeyId)?; + let mpkid = MasterPublicKeyId::try_from(mpkid_proto).map_err(|e| { + NiDkgIdFromProtoError::InvalidMasterPublicKeyId(format!("{e}")) + // TODO: test this case + })?; + Ok(NiDkgTag::HighThresholdForKey(mpkid)) + } + _ => Err(NiDkgIdFromProtoError::InvalidDkgTag), + }? + }, target_subnet: match ni_dkg_id_proto.remote_target_id { None => NiDkgTargetSubnet::Local, // Note that empty bytes (which are different from None) will lead to an error. @@ -103,7 +122,9 @@ pub fn ni_dkg_target_id(data: &[u8]) -> Result for ic_protobuf::proxy::ProxyDecodeError { @@ -112,9 +133,15 @@ impl From for ic_protobuf::proxy::ProxyDecodeError { match error { InvalidPrincipalId(err) => Self::InvalidPrincipalId(Box::new(err)), InvalidDkgTag => Self::Other("Invalid DKG tag.".to_string()), + InvalidDkgTagMissingKeyId => { + Self::Other("Invalid DKG tag: missing the mandatory key ID.".to_string()) + } InvalidRemoteTargetIdSize(_) => { Self::Other("Invalid remote target Id size.".to_string()) } + InvalidMasterPublicKeyId(e) => { + Self::Other(format!("Invalid master public key for NiDkgTag: {e}.")) + } } } } diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs index 1541705abe3..c895502e6f8 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs @@ -21,10 +21,16 @@ fn should_convert_ni_dkg_id_to_proto() { dealer_subnet: principal_id.into_vec(), remote_target_id: Some(target_id.to_vec()), dkg_tag: 2, + key_id: None, } ) } +#[test] +fn should_convert_ni_dkg_id_with_key_id_to_proto() { + todo!() +} + #[test] fn should_parse_valid_proto_as_ni_dkg_id() { let principal_id_blob = vec![42; PrincipalId::MAX_LENGTH_IN_BYTES]; @@ -37,6 +43,7 @@ fn should_parse_valid_proto_as_ni_dkg_id() { dealer_subnet: principal_id_blob.clone(), remote_target_id: val.clone(), dkg_tag: 2, + key_id: None, }; let id = NiDkgId::try_from(proto).unwrap(); @@ -58,6 +65,11 @@ fn should_parse_valid_proto_as_ni_dkg_id() { } } +#[test] +fn should_parse_valid_proto_as_ni_dkg_id_with_key_id() { + todo!() +} + #[test] fn should_return_error_if_remote_target_id_invalid_when_parsing_proto() { let target_id_size = NiDkgTargetId::SIZE - 2; @@ -66,6 +78,7 @@ fn should_return_error_if_remote_target_id_invalid_when_parsing_proto() { dealer_subnet: vec![42; PrincipalId::MAX_LENGTH_IN_BYTES], remote_target_id: Some(vec![42; target_id_size]), dkg_tag: 1, + key_id: None, }; let result = NiDkgId::try_from(proto); @@ -77,13 +90,33 @@ fn should_return_error_if_remote_target_id_invalid_when_parsing_proto() { } #[test] -fn should_return_error_if_ni_dkg_tag_invalid_when_parsing_proto() { +fn should_return_error_if_ni_dkg_tag_invalid_with_missing_keyid_when_parsing_proto() { let invalid_dkg_tag = 3; let proto = NiDkgIdProto { start_block_height: 7, dealer_subnet: vec![42; PrincipalId::MAX_LENGTH_IN_BYTES], remote_target_id: Some(vec![42; NiDkgTargetId::SIZE]), dkg_tag: invalid_dkg_tag, + key_id: None, + }; + + let result = NiDkgId::try_from(proto); + + assert_eq!( + result.unwrap_err(), + NiDkgIdFromProtoError::InvalidDkgTagMissingKeyId + ); +} + +#[test] +fn should_return_error_if_ni_dkg_tag_invalid_when_parsing_proto() { + let invalid_dkg_tag = 4; + let proto = NiDkgIdProto { + start_block_height: 7, + dealer_subnet: vec![42; PrincipalId::MAX_LENGTH_IN_BYTES], + remote_target_id: Some(vec![42; NiDkgTargetId::SIZE]), + dkg_tag: invalid_dkg_tag, + key_id: None, }; let result = NiDkgId::try_from(proto); @@ -99,6 +132,7 @@ fn should_return_error_if_dealer_subnet_id_invalid_when_parsing_proto() { dealer_subnet: vec![42; invalid_principal_length], remote_target_id: Some(vec![42; NiDkgTargetId::SIZE]), dkg_tag: 2, + key_id: None, }; let result = NiDkgId::try_from(proto); diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/tests.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/tests.rs index e2508479f3d..129e0c207d1 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/tests.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/tests.rs @@ -7,6 +7,11 @@ use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::ni_dkg_groth20_bls12_ Dealing, EncryptedShares, PublicCoefficientsBytes, ZKProofDec, ZKProofShare, NUM_CHUNKS, NUM_ZK_REPETITIONS, }; +use ic_management_canister_types::{ + EcdsaCurve, EcdsaKeyId, SchnorrAlgorithm, SchnorrKeyId, VetKdCurve, VetKdKeyId, +}; +use strum::EnumCount; +use strum::IntoEnumIterator; #[test] fn should_correctly_convert_csp_dkg_dealing_to_dkg_dealing() { @@ -302,17 +307,36 @@ fn empty_ni_csp_dkg_transcript() -> CspNiDkgTranscript { }) } -#[test] -fn should_correctly_convert_i32_to_ni_dkg_tag() { - assert!(NiDkgTag::try_from(-1).is_err()); - assert!(NiDkgTag::try_from(0).is_err()); - assert_eq!(NiDkgTag::try_from(1), Ok(NiDkgTag::LowThreshold)); - assert_eq!(NiDkgTag::try_from(2), Ok(NiDkgTag::HighThreshold)); - assert!(NiDkgTag::try_from(3).is_err()); -} - #[test] fn should_correctly_convert_ni_dkg_tag_to_i32() { - assert_eq!(NiDkgTag::LowThreshold as i32, 1); - assert_eq!(NiDkgTag::HighThreshold as i32, 2); + assert_eq!(i32::from(&NiDkgTag::LowThreshold), 1); + assert_eq!(i32::from(&NiDkgTag::HighThreshold), 2); + + for master_public_key_id in [ + MasterPublicKeyId::Ecdsa(EcdsaKeyId { + curve: EcdsaCurve::Secp256k1, + name: "some key".to_string(), + }), + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Bip340Secp256k1, + name: "some key".to_string(), + }), + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Ed25519, + name: "some key".to_string(), + }), + MasterPublicKeyId::VetKd(VetKdKeyId { + curve: VetKdCurve::Bls12_381_G2, + name: "some key".to_string(), + }), + ] { + assert_eq!( + i32::from(&NiDkgTag::HighThresholdForKey(master_public_key_id)), + 3 + ); + } + assert_eq!(MasterPublicKeyId::COUNT, 3); + assert_eq!(EcdsaCurve::iter().count(), 1); + assert_eq!(SchnorrAlgorithm::iter().count(), 2); + assert_eq!(VetKdCurve::iter().count(), 1); } From c51dc23ebf670e288d0dbf1ab2194886f72a874a Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Tue, 5 Nov 2024 13:51:56 +0000 Subject: [PATCH 15/30] Fix deps --- rs/crypto/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/crypto/Cargo.toml b/rs/crypto/Cargo.toml index 17f94fb40ff..a28c51b347b 100644 --- a/rs/crypto/Cargo.toml +++ b/rs/crypto/Cargo.toml @@ -31,6 +31,7 @@ ic-crypto-tls-cert-validation = { path = "node_key_validation/tls_cert_validatio ic-crypto-tls-interfaces = { path = "tls_interfaces" } ic-crypto-utils-basic-sig = { path = "utils/basic_sig" } ic-crypto-utils-tls = { path = "utils/tls" } +ic-management-canister-types = { path = "../types/management_canister_types" } ic-interfaces = { path = "../interfaces" } ic-interfaces-registry = { path = "../interfaces/registry" } ic-logger = { path = "../monitoring/logger" } @@ -81,7 +82,6 @@ ic-crypto-test-utils-tls = { path = "test_utils/tls" } ic-crypto-tree-hash = { path = "tree_hash" } ic-crypto-utils-canister-threshold-sig = { path = "utils/canister_threshold_sig" } ic-interfaces-registry-mocks = { path = "../interfaces/registry/mocks" } -ic-management-canister-types = { path = "../types/management_canister_types" } ic-registry-client = { path = "../registry/client" } ic-registry-client-fake = { path = "../registry/fake" } ic-registry-proto-data-provider = { path = "../registry/proto_data_provider" } From fce1c6359156c744aba1baf23105b06b20bbc6c4 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Tue, 5 Nov 2024 13:53:50 +0000 Subject: [PATCH 16/30] Remove obsolete conversion i32->NiDkgTag --- .../types/src/crypto/threshold_sig/ni_dkg.rs | 13 ------- .../src/crypto/threshold_sig/ni_dkg/tests.rs | 39 ------------------- 2 files changed, 52 deletions(-) diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs index 96140ab8362..23e4a53b39c 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs @@ -121,19 +121,6 @@ impl fmt::Display for NiDkgTargetSubnet { // } // } -//////////////////// -// TODO: check if we still need this -//////////////////////// -impl From<&NiDkgTag> for i32 { - fn from(ni_dkg_tag: &NiDkgTag) -> Self { - match ni_dkg_tag { - NiDkgTag::LowThreshold => 1, - NiDkgTag::HighThreshold => 2, - NiDkgTag::HighThresholdForKey(_) => 3, - } - } -} - /// A dealer's contribution (called dealing) to distributed key generation. #[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)] pub struct NiDkgDealing { diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/tests.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/tests.rs index 129e0c207d1..48953e59d3c 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/tests.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/tests.rs @@ -7,11 +7,6 @@ use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::ni_dkg_groth20_bls12_ Dealing, EncryptedShares, PublicCoefficientsBytes, ZKProofDec, ZKProofShare, NUM_CHUNKS, NUM_ZK_REPETITIONS, }; -use ic_management_canister_types::{ - EcdsaCurve, EcdsaKeyId, SchnorrAlgorithm, SchnorrKeyId, VetKdCurve, VetKdKeyId, -}; -use strum::EnumCount; -use strum::IntoEnumIterator; #[test] fn should_correctly_convert_csp_dkg_dealing_to_dkg_dealing() { @@ -306,37 +301,3 @@ fn empty_ni_csp_dkg_transcript() -> CspNiDkgTranscript { receiver_data: Default::default(), }) } - -#[test] -fn should_correctly_convert_ni_dkg_tag_to_i32() { - assert_eq!(i32::from(&NiDkgTag::LowThreshold), 1); - assert_eq!(i32::from(&NiDkgTag::HighThreshold), 2); - - for master_public_key_id in [ - MasterPublicKeyId::Ecdsa(EcdsaKeyId { - curve: EcdsaCurve::Secp256k1, - name: "some key".to_string(), - }), - MasterPublicKeyId::Schnorr(SchnorrKeyId { - algorithm: SchnorrAlgorithm::Bip340Secp256k1, - name: "some key".to_string(), - }), - MasterPublicKeyId::Schnorr(SchnorrKeyId { - algorithm: SchnorrAlgorithm::Ed25519, - name: "some key".to_string(), - }), - MasterPublicKeyId::VetKd(VetKdKeyId { - curve: VetKdCurve::Bls12_381_G2, - name: "some key".to_string(), - }), - ] { - assert_eq!( - i32::from(&NiDkgTag::HighThresholdForKey(master_public_key_id)), - 3 - ); - } - assert_eq!(MasterPublicKeyId::COUNT, 3); - assert_eq!(EcdsaCurve::iter().count(), 1); - assert_eq!(SchnorrAlgorithm::iter().count(), 2); - assert_eq!(VetKdCurve::iter().count(), 1); -} From 6a5a57890c28d9b39f825356c11b2a07b7af022e Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Wed, 6 Nov 2024 14:26:24 +0000 Subject: [PATCH 17/30] Cleanup --- rs/types/types/src/crypto/threshold_sig/ni_dkg.rs | 15 --------------- .../types/src/crypto/threshold_sig/ni_dkg/id.rs | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs index 23e4a53b39c..156e5bef517 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs @@ -106,21 +106,6 @@ impl fmt::Display for NiDkgTargetSubnet { } } -// No longer possible; -// this must be used in conversion of NiDkgId to pb::NiDkgId; -// implement directly there -// impl TryFrom for NiDkgTag { -// type Error = (); - -// fn try_from(ni_dkg_tag: i32) -> Result { -// match ni_dkg_tag { -// 1 => Ok(NiDkgTag::LowThreshold), -// 2 => Ok(NiDkgTag::HighThreshold), -// _ => Err(()), -// } -// } -// } - /// A dealer's contribution (called dealing) to distributed key generation. #[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)] pub struct NiDkgDealing { diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs index 20bc996b9de..80032eb8403 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs @@ -47,7 +47,7 @@ impl From for NiDkgIdProto { NiDkgIdProto { start_block_height: ni_dkg_id.start_block_height.get(), dealer_subnet: ni_dkg_id.dealer_subnet.get().into_vec(), - dkg_tag: pb::NiDkgTag::from(&ni_dkg_id.dkg_tag) as i32, // i32::from(&ni_dkg_id.dkg_tag), // TODO: delete i32::from conversion ? + dkg_tag: pb::NiDkgTag::from(&ni_dkg_id.dkg_tag) as i32, remote_target_id: match ni_dkg_id.target_subnet { NiDkgTargetSubnet::Remote(target_id) => Some(target_id.0.to_vec()), NiDkgTargetSubnet::Local => None, From 07fb339f4bd02e13a9e0b7d3e6d0417447f7ec3d Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Wed, 6 Nov 2024 15:11:32 +0000 Subject: [PATCH 18/30] Tests --- .../crypto/threshold_sig/ni_dkg/id/tests.rs | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs index c895502e6f8..3717d6c96b3 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs @@ -1,3 +1,5 @@ +use ic_management_canister_types::{EcdsaCurve, EcdsaKeyId}; + use super::*; #[test] @@ -28,7 +30,32 @@ fn should_convert_ni_dkg_id_to_proto() { #[test] fn should_convert_ni_dkg_id_with_key_id_to_proto() { - todo!() + let principal_id = PrincipalId::new_subnet_test_id(42); + let target_id = [42; NiDkgTargetId::SIZE]; + let height = 7; + let master_public_key_id = MasterPublicKeyId::Ecdsa(EcdsaKeyId { + curve: EcdsaCurve::Secp256k1, + name: "key".to_string(), + }); + let id = NiDkgId { + start_block_height: Height::new(7), + dealer_subnet: SubnetId::from(principal_id), + dkg_tag: NiDkgTag::HighThresholdForKey(master_public_key_id.clone()), + target_subnet: NiDkgTargetSubnet::Remote(NiDkgTargetId::new(target_id)), + }; + + let proto = NiDkgIdProto::from(id); + + assert_eq!( + proto, + NiDkgIdProto { + start_block_height: height, + dealer_subnet: principal_id.into_vec(), + remote_target_id: Some(target_id.to_vec()), + dkg_tag: pb::NiDkgTag::HighThresholdForKey as i32, + key_id: Some(pb::MasterPublicKeyId::from(&master_public_key_id)), + } + ) } #[test] @@ -67,7 +94,40 @@ fn should_parse_valid_proto_as_ni_dkg_id() { #[test] fn should_parse_valid_proto_as_ni_dkg_id_with_key_id() { - todo!() + let principal_id_blob = vec![42; PrincipalId::MAX_LENGTH_IN_BYTES]; + let target_id = [42; NiDkgTargetId::SIZE]; + let height = 7; + let master_public_key_id = MasterPublicKeyId::Ecdsa(EcdsaKeyId { + curve: EcdsaCurve::Secp256k1, + name: "key".to_string(), + }); + + for val in [None, Some(target_id.to_vec())].iter() { + let proto = NiDkgIdProto { + start_block_height: height, + dealer_subnet: principal_id_blob.clone(), + remote_target_id: val.clone(), + dkg_tag: pb::NiDkgTag::HighThresholdForKey as i32, + key_id: Some(pb::MasterPublicKeyId::from(&master_public_key_id)), + }; + + let id = NiDkgId::try_from(proto).unwrap(); + + assert_eq!( + id, + NiDkgId { + start_block_height: Height::new(height), + dealer_subnet: SubnetId::from( + PrincipalId::try_from(principal_id_blob.as_slice()).unwrap() + ), + dkg_tag: NiDkgTag::HighThresholdForKey(master_public_key_id.clone()), + target_subnet: match val { + None => NiDkgTargetSubnet::Local, + Some(_) => NiDkgTargetSubnet::Remote(NiDkgTargetId::new(target_id)), + }, + } + ); + } } #[test] From 0c1c7a7f0c69fcddb732668bf994f82fcab0f83b Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Wed, 6 Nov 2024 15:27:04 +0000 Subject: [PATCH 19/30] Do not benchmark NiDkgTag::HighThresholdForKey for now --- rs/crypto/benches/ni_dkg.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/rs/crypto/benches/ni_dkg.rs b/rs/crypto/benches/ni_dkg.rs index 2b71a1cd84c..52fabed5d8d 100644 --- a/rs/crypto/benches/ni_dkg.rs +++ b/rs/crypto/benches/ni_dkg.rs @@ -48,9 +48,6 @@ fn test_cases(num_dealers: &[usize]) -> Vec { for n in num_dealers { cases.push(TestCase::new(*n, NiDkgTag::LowThreshold)); cases.push(TestCase::new(*n, NiDkgTag::HighThreshold)); - /////////////////////////////////////////////////////// - // TODO: I assume we don't benchmark the NiDkgTag::HighThresholdForKey case here, right? - /////////////////////////////////////////////////////// } cases } From b17d8f96374b173f310ee5d80ad125aa2e93ea5a Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Wed, 6 Nov 2024 15:29:31 +0000 Subject: [PATCH 20/30] Do not support new tag in new_with_inverted_threshold --- rs/crypto/test_utils/ni-dkg/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/rs/crypto/test_utils/ni-dkg/src/lib.rs b/rs/crypto/test_utils/ni-dkg/src/lib.rs index be3c2ae15fa..4cb89c34c68 100644 --- a/rs/crypto/test_utils/ni-dkg/src/lib.rs +++ b/rs/crypto/test_utils/ni-dkg/src/lib.rs @@ -464,10 +464,7 @@ impl RandomNiDkgConfig { let dkg_tag = match &self.0.dkg_id().dkg_tag { NiDkgTag::LowThreshold => NiDkgTag::HighThreshold, NiDkgTag::HighThreshold => NiDkgTag::LowThreshold, - //////////////////////// - // TODO: how to behave here? - //////////////////////// - NiDkgTag::HighThresholdForKey(_master_public_key_id) => NiDkgTag::LowThreshold, + NiDkgTag::HighThresholdForKey(_) => unimplemented!("not supported/needed currently"), }; let subnet_size = self.0.receivers().get().len(); From ac3769759c0cb8c3ec6c300666ee9ba6818a877b Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Wed, 6 Nov 2024 16:02:34 +0000 Subject: [PATCH 21/30] Add test should_return_error_if_ni_dkg_tag_invalid_with_invalid_master_public_key_when_parsing_proto --- .../src/crypto/threshold_sig/ni_dkg/id.rs | 1 - .../crypto/threshold_sig/ni_dkg/id/tests.rs | 28 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs index 80032eb8403..1248c9e9227 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id.rs @@ -80,7 +80,6 @@ impl TryFrom for NiDkgId { .ok_or(NiDkgIdFromProtoError::InvalidDkgTagMissingKeyId)?; let mpkid = MasterPublicKeyId::try_from(mpkid_proto).map_err(|e| { NiDkgIdFromProtoError::InvalidMasterPublicKeyId(format!("{e}")) - // TODO: test this case })?; Ok(NiDkgTag::HighThresholdForKey(mpkid)) } diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs index 3717d6c96b3..3fa606c9ddd 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg/id/tests.rs @@ -1,3 +1,4 @@ +use assert_matches::assert_matches; use ic_management_canister_types::{EcdsaCurve, EcdsaKeyId}; use super::*; @@ -151,12 +152,12 @@ fn should_return_error_if_remote_target_id_invalid_when_parsing_proto() { #[test] fn should_return_error_if_ni_dkg_tag_invalid_with_missing_keyid_when_parsing_proto() { - let invalid_dkg_tag = 3; + let dkg_tag_requiring_some_key_id = 3; let proto = NiDkgIdProto { start_block_height: 7, dealer_subnet: vec![42; PrincipalId::MAX_LENGTH_IN_BYTES], remote_target_id: Some(vec![42; NiDkgTargetId::SIZE]), - dkg_tag: invalid_dkg_tag, + dkg_tag: dkg_tag_requiring_some_key_id, key_id: None, }; @@ -168,6 +169,29 @@ fn should_return_error_if_ni_dkg_tag_invalid_with_missing_keyid_when_parsing_pro ); } +#[test] +fn should_return_error_if_ni_dkg_tag_invalid_with_invalid_master_public_key_when_parsing_proto() { + let proto = NiDkgIdProto { + start_block_height: 7, + dealer_subnet: vec![42; PrincipalId::MAX_LENGTH_IN_BYTES], + remote_target_id: Some(vec![42; NiDkgTargetId::SIZE]), + dkg_tag: pb::NiDkgTag::HighThresholdForKey as i32, + key_id: Some(pb::MasterPublicKeyId { + key_id: Some(pb::master_public_key_id::KeyId::Ecdsa(pb::EcdsaKeyId { + curve: 99, + name: "invalid_curve".to_string(), + })), + }), + }; + + let result = NiDkgId::try_from(proto); + + assert_matches!( + result.unwrap_err(), + NiDkgIdFromProtoError::InvalidMasterPublicKeyId(_) + ); +} + #[test] fn should_return_error_if_ni_dkg_tag_invalid_when_parsing_proto() { let invalid_dkg_tag = 4; From 7cfe2f7e853556d5abe6b64269b17daf81d5c71f Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Wed, 6 Nov 2024 16:21:49 +0000 Subject: [PATCH 22/30] Extend TODO description --- rs/types/types/src/consensus/dkg.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rs/types/types/src/consensus/dkg.rs b/rs/types/types/src/consensus/dkg.rs index ffefbd0b8de..02f3dd1b258 100644 --- a/rs/types/types/src/consensus/dkg.rs +++ b/rs/types/types/src/consensus/dkg.rs @@ -380,7 +380,12 @@ fn build_tagged_transcripts_map( .ok_or_else(|| ProxyDecodeError::MissingField("TaggedNiDkgTranscript::transcript")) .and_then(|t| { Ok(( - // TODO: test all cases!? + ///////////////////////////////////////////////// + // TODO: ideally we extend existing tests where build_tagged_transcripts_map + // is used (e.g., tests for `impl TryFrom for Summary`) to test + // this new behavior, but I cannot find such tests: are there no such tests + // currently, or am I overlooking them? + ///////////////////////////////////////////////// match tagged_transcript.tag { 1 => Ok(NiDkgTag::LowThreshold), 2 => Ok(NiDkgTag::HighThreshold), From 14cfb312a51edf356ce4e3a90b4f40f334350142 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 7 Nov 2024 00:06:45 +0000 Subject: [PATCH 23/30] Add comment --- rs/types/types/src/consensus/dkg.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/rs/types/types/src/consensus/dkg.rs b/rs/types/types/src/consensus/dkg.rs index 02f3dd1b258..49db861e46b 100644 --- a/rs/types/types/src/consensus/dkg.rs +++ b/rs/types/types/src/consensus/dkg.rs @@ -398,6 +398,23 @@ fn build_tagged_transcripts_map( .to_string(), ) })?; + //////////////////////////////////////////////////////// + // TODO: Consensus team to decide if we should rather + // not extend the TaggedNiDkgTranscript with a key ID and + // instead use the key ID from the tagged_transcript's + // transcripts's NIDkgId as follows: + // let mpkid_proto = tagged_transcript + // .transcript + // .as_ref() + // .ok_or_else(|| ProxyDecodeError::Other("TODO".to_string()))? + // .dkg_id + // .as_ref() + // .ok_or_else(|| ProxyDecodeError::Other("TODO".to_string()))? + // .key_id + // .as_ref() + // .ok_or_else(|| ProxyDecodeError::Other("TODO".to_string()))?; + //////////////////////////////////////////////////////// + let mpkid = MasterPublicKeyId::try_from(mpkid_proto.clone()) .map_err(|e| { ProxyDecodeError::Other(format!( From 4fadc021072e7651667335d07d3d2d7ff39b6170 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 7 Nov 2024 00:50:16 +0000 Subject: [PATCH 24/30] Store: rename capacity and improve docu --- rs/crypto/src/sign/threshold_sig/store.rs | 31 +++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/rs/crypto/src/sign/threshold_sig/store.rs b/rs/crypto/src/sign/threshold_sig/store.rs index f9127f61b8f..a880f247e6c 100644 --- a/rs/crypto/src/sign/threshold_sig/store.rs +++ b/rs/crypto/src/sign/threshold_sig/store.rs @@ -80,12 +80,20 @@ impl TranscriptData { /// data was inserted _first_ is removed, that is, DKG IDs are purged in /// insertion order. /// -/// The maximum number of threshold signature data stored per tag is defined by -/// `CAPACITY_PER_TAG`. For the moment there are two tags, `LowThreshold` and `HighThreshold`, -/// meaning that the total capacity of the threshold signature data store is `2 * CAPACITY_PER_TAG`. +/// The maximum number of threshold signature data stored per tag or key is defined by +/// `CAPACITY_PER_TAG_OR_KEY`. For the moment there are three tags: +/// * `LowThreshold` +/// * `HighThreshold` +/// * `HighThresholdForKey(MasterPublicKeyId)` +/// +/// and that the total capacity of the threshold signature data store is +/// `2*CAPACITY_PER_TAG_OR_KEY + K*CAPACITY_PER_TAG_OR_KEY` where `K` is +/// the number of different `MasterPublicKeyId`s that are stored on the +/// subnet. In production, currently at most 3 keys are stored pe subnet +/// (1 ECDSA key, 2 Schnorr keys). pub struct ThresholdSigDataStoreImpl { store: BTreeMap, - max_num_of_dkg_ids_per_tag: usize, + max_num_of_dkg_ids_per_tag_or_key: usize, // VecDeque used as queue: `push_back` to add, `pop_front` to remove low_threshold_dkg_id_insertion_order: VecDeque, high_threshold_dkg_id_insertion_order: VecDeque, @@ -118,19 +126,19 @@ impl ThresholdSigDataStoreImpl { /// /// # Panics /// If `max_num_of_dkg_ids_per_tag` is smaller than 1. - fn new_with_max_size(max_num_of_dkg_ids_per_tag: usize) -> Self { + fn new_with_max_size(max_num_of_dkg_ids_per_tag_or_key: usize) -> Self { assert!( - max_num_of_dkg_ids_per_tag >= 1, + max_num_of_dkg_ids_per_tag_or_key >= 1, "The maximum size per tag must be at least 1" ); ThresholdSigDataStoreImpl { store: BTreeMap::new(), - max_num_of_dkg_ids_per_tag, + max_num_of_dkg_ids_per_tag_or_key, low_threshold_dkg_id_insertion_order: VecDeque::with_capacity( - max_num_of_dkg_ids_per_tag, + max_num_of_dkg_ids_per_tag_or_key, ), high_threshold_dkg_id_insertion_order: VecDeque::with_capacity( - max_num_of_dkg_ids_per_tag, + max_num_of_dkg_ids_per_tag_or_key, ), high_threshold_for_key_id_dkg_id_insertion_order: BTreeMap::new(), } @@ -157,7 +165,8 @@ impl ThresholdSigDataStoreImpl { { Some(insertion_order) => insertion_order.push_back(dkg_id.clone()), None => { - let mut buf = VecDeque::with_capacity(self.max_num_of_dkg_ids_per_tag); + let mut buf = + VecDeque::with_capacity(self.max_num_of_dkg_ids_per_tag_or_key); buf.push_back(dkg_id.clone()); self.high_threshold_for_key_id_dkg_id_insertion_order .insert(master_public_key_id.clone(), buf); @@ -180,7 +189,7 @@ impl ThresholdSigDataStoreImpl { .get_mut(master_public_key_id), }; if let Some(insertion_order) = dkg_id_insertion_order { - if insertion_order.len() > self.max_num_of_dkg_ids_per_tag { + if insertion_order.len() > self.max_num_of_dkg_ids_per_tag_or_key { let oldest_dkg_id = insertion_order .pop_front() .expect("dkg store unexpectedly empty"); From 3ad52e42beb6242e20dd3165ecf2b57473bca735 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 7 Nov 2024 00:51:35 +0000 Subject: [PATCH 25/30] Typo in docu --- rs/crypto/src/sign/threshold_sig/store.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/crypto/src/sign/threshold_sig/store.rs b/rs/crypto/src/sign/threshold_sig/store.rs index a880f247e6c..a5e4f392e5c 100644 --- a/rs/crypto/src/sign/threshold_sig/store.rs +++ b/rs/crypto/src/sign/threshold_sig/store.rs @@ -86,7 +86,7 @@ impl TranscriptData { /// * `HighThreshold` /// * `HighThresholdForKey(MasterPublicKeyId)` /// -/// and that the total capacity of the threshold signature data store is +/// and the total capacity of the threshold signature data store is /// `2*CAPACITY_PER_TAG_OR_KEY + K*CAPACITY_PER_TAG_OR_KEY` where `K` is /// the number of different `MasterPublicKeyId`s that are stored on the /// subnet. In production, currently at most 3 keys are stored pe subnet From 770c4e4c20f273920a855089e4975fb3eebe83ab Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 7 Nov 2024 00:52:42 +0000 Subject: [PATCH 26/30] Typo --- rs/crypto/src/sign/threshold_sig/store.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/crypto/src/sign/threshold_sig/store.rs b/rs/crypto/src/sign/threshold_sig/store.rs index a5e4f392e5c..fead1d752d4 100644 --- a/rs/crypto/src/sign/threshold_sig/store.rs +++ b/rs/crypto/src/sign/threshold_sig/store.rs @@ -89,7 +89,7 @@ impl TranscriptData { /// and the total capacity of the threshold signature data store is /// `2*CAPACITY_PER_TAG_OR_KEY + K*CAPACITY_PER_TAG_OR_KEY` where `K` is /// the number of different `MasterPublicKeyId`s that are stored on the -/// subnet. In production, currently at most 3 keys are stored pe subnet +/// subnet. In production, currently at most 3 keys are stored per subnet /// (1 ECDSA key, 2 Schnorr keys). pub struct ThresholdSigDataStoreImpl { store: BTreeMap, From cd99051c01967880232931f0f49029a811c63af0 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 7 Nov 2024 11:29:48 +0000 Subject: [PATCH 27/30] Custom ExhaustiveSet impl for NiDkgTag --- rs/types/types/src/crypto/threshold_sig/ni_dkg.rs | 1 - rs/types/types/src/exhaustive.rs | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs index 156e5bef517..1170844574c 100644 --- a/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs +++ b/rs/types/types/src/crypto/threshold_sig/ni_dkg.rs @@ -33,7 +33,6 @@ mod tests; /// Allows to distinguish protocol executions in high and low threshold /// settings. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, EnumCount, Serialize)] -#[cfg_attr(test, derive(ExhaustiveSet))] #[repr(isize)] pub enum NiDkgTag { LowThreshold = 1, diff --git a/rs/types/types/src/exhaustive.rs b/rs/types/types/src/exhaustive.rs index d494659d24b..0b2abb4eeb9 100644 --- a/rs/types/types/src/exhaustive.rs +++ b/rs/types/types/src/exhaustive.rs @@ -631,6 +631,13 @@ impl ExhaustiveSet for Signed> { } } +// TODO(CON-1433): Remove once NiDkgTag::HighThresholdForKey variant is supported by the mainnet version +impl ExhaustiveSet for NiDkgTag { + fn exhaustive_set(_: &mut R) -> Vec { + vec![NiDkgTag::LowThreshold, NiDkgTag::HighThreshold] + } +} + impl ExhaustiveSet for NiDkgConfig { fn exhaustive_set(_: &mut R) -> Vec { vec![NiDkgConfig::new(valid_dkg_config_data()).unwrap()] From df71d3a72a4ac5d4d9ae79ea396b10880c22fe6b Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 7 Nov 2024 12:18:14 +0000 Subject: [PATCH 28/30] Rename to high_threshold_for_key_dkg_id_insertion_order --- rs/crypto/src/sign/threshold_sig/store.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/rs/crypto/src/sign/threshold_sig/store.rs b/rs/crypto/src/sign/threshold_sig/store.rs index fead1d752d4..a2303554da9 100644 --- a/rs/crypto/src/sign/threshold_sig/store.rs +++ b/rs/crypto/src/sign/threshold_sig/store.rs @@ -97,8 +97,7 @@ pub struct ThresholdSigDataStoreImpl { // VecDeque used as queue: `push_back` to add, `pop_front` to remove low_threshold_dkg_id_insertion_order: VecDeque, high_threshold_dkg_id_insertion_order: VecDeque, - high_threshold_for_key_id_dkg_id_insertion_order: - BTreeMap>, + high_threshold_for_key_dkg_id_insertion_order: BTreeMap>, } #[derive(Default)] @@ -140,7 +139,7 @@ impl ThresholdSigDataStoreImpl { high_threshold_dkg_id_insertion_order: VecDeque::with_capacity( max_num_of_dkg_ids_per_tag_or_key, ), - high_threshold_for_key_id_dkg_id_insertion_order: BTreeMap::new(), + high_threshold_for_key_dkg_id_insertion_order: BTreeMap::new(), } } @@ -160,7 +159,7 @@ impl ThresholdSigDataStoreImpl { } NiDkgTag::HighThresholdForKey(master_public_key_id) => { match self - .high_threshold_for_key_id_dkg_id_insertion_order + .high_threshold_for_key_dkg_id_insertion_order .get_mut(master_public_key_id) { Some(insertion_order) => insertion_order.push_back(dkg_id.clone()), @@ -168,7 +167,7 @@ impl ThresholdSigDataStoreImpl { let mut buf = VecDeque::with_capacity(self.max_num_of_dkg_ids_per_tag_or_key); buf.push_back(dkg_id.clone()); - self.high_threshold_for_key_id_dkg_id_insertion_order + self.high_threshold_for_key_dkg_id_insertion_order .insert(master_public_key_id.clone(), buf); } } @@ -185,7 +184,7 @@ impl ThresholdSigDataStoreImpl { NiDkgTag::LowThreshold => Some(&mut self.low_threshold_dkg_id_insertion_order), NiDkgTag::HighThreshold => Some(&mut self.high_threshold_dkg_id_insertion_order), NiDkgTag::HighThresholdForKey(master_public_key_id) => self - .high_threshold_for_key_id_dkg_id_insertion_order + .high_threshold_for_key_dkg_id_insertion_order .get_mut(master_public_key_id), }; if let Some(insertion_order) = dkg_id_insertion_order { From caccc5572853c7434f49e234c538111bd3e85126 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 7 Nov 2024 12:19:47 +0000 Subject: [PATCH 29/30] Fix store invariant --- rs/crypto/src/sign/threshold_sig/store.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/rs/crypto/src/sign/threshold_sig/store.rs b/rs/crypto/src/sign/threshold_sig/store.rs index a2303554da9..7d51813a37b 100644 --- a/rs/crypto/src/sign/threshold_sig/store.rs +++ b/rs/crypto/src/sign/threshold_sig/store.rs @@ -198,12 +198,17 @@ impl ThresholdSigDataStoreImpl { } fn assert_length_invariant(&self) { + let high_threshold_for_key_id_dkg_id_insertion_order_len: usize = self + .high_threshold_for_key_dkg_id_insertion_order + .values() + .map(|v| v.len()) + .sum(); assert_eq!( self.store.len(), self.low_threshold_dkg_id_insertion_order.len() - + self.high_threshold_dkg_id_insertion_order.len(), - "The combined length of the queues maintaining DKG ID insertion order must be the \ - same as that of the map containing the DKG ID data." + + self.high_threshold_dkg_id_insertion_order.len() + + high_threshold_for_key_id_dkg_id_insertion_order_len, + "ThresholdSigDataStore length invariant violated" ); } } From 4d167a80b9f3b460996d6b0066c4905488c0ad5b Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Thu, 7 Nov 2024 13:48:35 +0000 Subject: [PATCH 30/30] Update ThresholdSigDataStore tests --- .../src/sign/threshold_sig/store/tests.rs | 567 +++++++++++------- rs/crypto/src/sign/threshold_sig/tests.rs | 9 +- 2 files changed, 344 insertions(+), 232 deletions(-) diff --git a/rs/crypto/src/sign/threshold_sig/store/tests.rs b/rs/crypto/src/sign/threshold_sig/store/tests.rs index 542543e426a..2e063813c15 100644 --- a/rs/crypto/src/sign/threshold_sig/store/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/store/tests.rs @@ -1,42 +1,62 @@ use super::*; -use crate::sign::threshold_sig::tests::{NI_DKG_ID_1, NI_DKG_ID_2}; use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::ni_dkg_groth20_bls12_381::PublicCoefficientsBytes; use ic_crypto_internal_types::sign::threshold_sig::public_key::bls12_381::PublicKeyBytes; use ic_crypto_internal_types::sign::threshold_sig::public_key::CspThresholdSigPublicKey; -use ic_types::crypto::threshold_sig::ni_dkg::NiDkgId; +use ic_management_canister_types::{ + EcdsaCurve, EcdsaKeyId, SchnorrAlgorithm, SchnorrKeyId, VetKdCurve, VetKdKeyId, +}; +use ic_types::crypto::threshold_sig::ni_dkg::{NiDkgId, NiDkgTargetId, NiDkgTargetSubnet}; use ic_types::Height; use ic_types_test_utils::ids::{node_test_id, SUBNET_1}; +use strum::{EnumCount, IntoEnumIterator}; const NODE_1: u64 = 1; const NODE_2: u64 = 2; const NODE_1_INDEX: NodeIndex = 1; const NODE_2_INDEX: NodeIndex = 2; +pub const NI_DKG_ID_HIGH_T: NiDkgId = NiDkgId { + start_block_height: Height::new(3), + dealer_subnet: SUBNET_1, + dkg_tag: NiDkgTag::HighThreshold, + target_subnet: NiDkgTargetSubnet::Remote(NiDkgTargetId::new([42; 32])), +}; + +pub const NI_DKG_ID_LOW_T: NiDkgId = NiDkgId { + start_block_height: Height::new(3), + dealer_subnet: SUBNET_1, + dkg_tag: NiDkgTag::LowThreshold, + target_subnet: NiDkgTargetSubnet::Remote(NiDkgTargetId::new([42; 32])), +}; + +pub const NI_DKG_ID_1: NiDkgId = NI_DKG_ID_HIGH_T; +pub const NI_DKG_ID_2: NiDkgId = NI_DKG_ID_LOW_T; + #[test] fn should_contain_transcript_data_after_insertion_with_nidkg_id() { - should_contain_transcript_data_after_insertion_with_dkg_id(&NI_DKG_ID_1); -} + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let indices = indices_with(vec![ + (node_test_id(NODE_1), NODE_1_INDEX), + (node_test_id(NODE_2), NODE_2_INDEX), + ]); + let public_coeffs = public_coeffs(); -fn should_contain_transcript_data_after_insertion_with_dkg_id(dkg_id: &NiDkgId) { - let mut store = ThresholdSigDataStoreImpl::new(); - let indices = indices_with(vec![ - (node_test_id(NODE_1), NODE_1_INDEX), - (node_test_id(NODE_2), NODE_2_INDEX), - ]); - let public_coeffs = public_coeffs(); + let dkg_id = ni_dkg_id_with_tag(tag.clone(), 42); - store.insert_transcript_data(dkg_id, public_coeffs.clone(), indices); + store.insert_transcript_data(&dkg_id, public_coeffs.clone(), indices); - let transcript_data = store.transcript_data(dkg_id).unwrap(); - assert_eq!(transcript_data.public_coefficients(), &public_coeffs); - assert_eq!( - transcript_data.index(node_test_id(NODE_1)), - Some(&NODE_1_INDEX) - ); - assert_eq!( - transcript_data.index(node_test_id(NODE_2)), - Some(&NODE_2_INDEX) - ); + let transcript_data = store.transcript_data(&dkg_id).unwrap(); + assert_eq!(transcript_data.public_coefficients(), &public_coeffs); + assert_eq!( + transcript_data.index(node_test_id(NODE_1)), + Some(&NODE_1_INDEX) + ); + assert_eq!( + transcript_data.index(node_test_id(NODE_2)), + Some(&NODE_2_INDEX) + ); + } } #[test] @@ -48,41 +68,47 @@ fn should_not_contain_nonexistent_transcript_data() { #[test] fn should_contain_individual_public_keys_after_insertion_with_nidkg_id() { - let dkg_id = NI_DKG_ID_1; - let mut store = ThresholdSigDataStoreImpl::new(); - let csp_pubkey = csp_public_key(); + for tag in all_tags() { + let dkg_id = ni_dkg_id_with_tag(tag.clone(), 1); + let mut store = ThresholdSigDataStoreImpl::new(); + let csp_pubkey = csp_public_key(); - store.insert_individual_public_key(&dkg_id, node_test_id(NODE_1), csp_pubkey); + store.insert_individual_public_key(&dkg_id, node_test_id(NODE_1), csp_pubkey); - assert_eq!( - store.individual_public_key(&dkg_id, node_test_id(NODE_1)), - Some(&csp_pubkey) - ); + assert_eq!( + store.individual_public_key(&dkg_id, node_test_id(NODE_1)), + Some(&csp_pubkey) + ); + } } #[test] fn should_insert_multiple_individual_public_keys() { - let mut store = ThresholdSigDataStoreImpl::new(); - let csp_pubkey_1 = csp_public_key(); - let csp_pubkey_2 = csp_public_key(); + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let csp_pubkey_1 = csp_public_key(); + let csp_pubkey_2 = other_csp_public_key(); + let ni_dkg_id_1 = ni_dkg_id_with_tag(tag.clone(), 1); + let ni_dkg_id_2 = ni_dkg_id_with_tag(tag.clone(), 2); + + assert_ne!(ni_dkg_id_1, NI_DKG_ID_2); + store.insert_individual_public_key(&ni_dkg_id_1, node_test_id(NODE_1), csp_pubkey_1); + store.insert_individual_public_key(&ni_dkg_id_1, node_test_id(NODE_2), csp_pubkey_2); + store.insert_individual_public_key(&ni_dkg_id_2, node_test_id(NODE_1), csp_pubkey_2); - assert_ne!(NI_DKG_ID_1, NI_DKG_ID_2); - store.insert_individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_1); - store.insert_individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_2), csp_pubkey_2); - store.insert_individual_public_key(&NI_DKG_ID_2, node_test_id(NODE_1), csp_pubkey_2); - - assert_eq!( - store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1)), - Some(&csp_pubkey_1) - ); - assert_eq!( - store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_2)), - Some(&csp_pubkey_2) - ); - assert_eq!( - store.individual_public_key(&NI_DKG_ID_2, node_test_id(NODE_1)), - Some(&csp_pubkey_2) - ); + assert_eq!( + store.individual_public_key(&ni_dkg_id_1, node_test_id(NODE_1)), + Some(&csp_pubkey_1) + ); + assert_eq!( + store.individual_public_key(&ni_dkg_id_1, node_test_id(NODE_2)), + Some(&csp_pubkey_2) + ); + assert_eq!( + store.individual_public_key(&ni_dkg_id_2, node_test_id(NODE_1)), + Some(&csp_pubkey_2) + ); + } } #[test] @@ -97,49 +123,58 @@ fn should_not_contain_nonexistent_individual_public_key() { #[test] fn should_overwrite_existing_public_coefficients() { - let mut store = ThresholdSigDataStoreImpl::new(); - let (public_coeffs_1, public_coeffs_2) = (public_coeffs_1(), public_coeffs_2()); - assert_ne!(public_coeffs_1, public_coeffs_2); + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let (public_coeffs_1, public_coeffs_2) = (public_coeffs_1(), public_coeffs_2()); + assert_ne!(public_coeffs_1, public_coeffs_2); + let ni_dkg_id = ni_dkg_id_with_tag(tag.clone(), 1); - store.insert_transcript_data(&NI_DKG_ID_1, public_coeffs_1, BTreeMap::new()); - store.insert_transcript_data(&NI_DKG_ID_1, public_coeffs_2.clone(), BTreeMap::new()); + store.insert_transcript_data(&ni_dkg_id, public_coeffs_1, BTreeMap::new()); + store.insert_transcript_data(&ni_dkg_id, public_coeffs_2.clone(), BTreeMap::new()); - let transcript_data = store.transcript_data(&NI_DKG_ID_1).unwrap(); - assert_eq!(transcript_data.public_coefficients(), &public_coeffs_2); + let transcript_data = store.transcript_data(&ni_dkg_id).unwrap(); + assert_eq!(transcript_data.public_coefficients(), &public_coeffs_2); + } } #[test] fn should_overwrite_existing_indices() { - let mut store = ThresholdSigDataStoreImpl::new(); - let indices_1 = indices_with(vec![(node_test_id(NODE_1), NODE_1_INDEX)]); - let indices_2 = indices_with(vec![(node_test_id(NODE_2), NODE_2_INDEX)]); - let public_coeffs = public_coeffs(); - - store.insert_transcript_data(&NI_DKG_ID_1, public_coeffs.clone(), indices_1); - store.insert_transcript_data(&NI_DKG_ID_1, public_coeffs, indices_2); - - let transcript_data = store.transcript_data(&NI_DKG_ID_1).unwrap(); - assert_eq!(transcript_data.index(node_test_id(NODE_1)), None); - assert_eq!( - transcript_data.index(node_test_id(NODE_2)), - Some(&NODE_2_INDEX) - ); + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let indices_1 = indices_with(vec![(node_test_id(NODE_1), NODE_1_INDEX)]); + let indices_2 = indices_with(vec![(node_test_id(NODE_2), NODE_2_INDEX)]); + let public_coeffs = public_coeffs(); + let ni_dkg_id = ni_dkg_id_with_tag(tag.clone(), 1); + + store.insert_transcript_data(&ni_dkg_id, public_coeffs.clone(), indices_1); + store.insert_transcript_data(&ni_dkg_id, public_coeffs, indices_2); + + let transcript_data = store.transcript_data(&ni_dkg_id).unwrap(); + assert_eq!(transcript_data.index(node_test_id(NODE_1)), None); + assert_eq!( + transcript_data.index(node_test_id(NODE_2)), + Some(&NODE_2_INDEX) + ); + } } #[test] fn should_overwrite_existing_individual_public_keys() { - let mut store = ThresholdSigDataStoreImpl::new(); - let csp_pubkey_1 = csp_public_key(); - let csp_pubkey_2 = other_csp_public_key(); - assert_ne!(csp_pubkey_1, csp_pubkey_2); + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let csp_pubkey_1 = csp_public_key(); + let csp_pubkey_2 = other_csp_public_key(); + assert_ne!(csp_pubkey_1, csp_pubkey_2); + let ni_dkg_id = ni_dkg_id_with_tag(tag.clone(), 1); - store.insert_individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_1); - store.insert_individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1), csp_pubkey_2); + store.insert_individual_public_key(&ni_dkg_id, node_test_id(NODE_1), csp_pubkey_1); + store.insert_individual_public_key(&ni_dkg_id, node_test_id(NODE_1), csp_pubkey_2); - assert_eq!( - store.individual_public_key(&NI_DKG_ID_1, node_test_id(NODE_1)), - Some(&csp_pubkey_2) - ); + assert_eq!( + store.individual_public_key(&ni_dkg_id, node_test_id(NODE_1)), + Some(&csp_pubkey_2) + ); + } } #[test] @@ -149,70 +184,105 @@ fn should_have_capacity_per_tag_of_9() { #[test] fn should_not_purge_data_on_inserting_coeffs_and_indices_if_capacity_not_exceeded() { - let mut store = ThresholdSigDataStoreImpl::new(); + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + + for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { + store.insert_transcript_data( + &ni_dkg_id_with_tag(tag.clone(), i), + public_coeffs(), + BTreeMap::new(), + ); + } - for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { - store.insert_transcript_data(&ni_dkg_id(i), public_coeffs(), BTreeMap::new()); + assert_eq!( + store.store.len(), + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + ); } - - assert_eq!( - store.store.len(), - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG - ); } #[test] fn should_not_purge_data_on_inserting_pubkeys_if_capacity_not_exceeded() { - let mut store = ThresholdSigDataStoreImpl::new(); + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + + for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { + store.insert_individual_public_key( + &ni_dkg_id_with_tag(tag.clone(), i), + node_test_id(NODE_1), + csp_public_key(), + ); + } - for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { - store.insert_individual_public_key(&ni_dkg_id(i), node_test_id(NODE_1), csp_public_key()); + assert_eq!( + store.store.len(), + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + ); } - - assert_eq!( - store.store.len(), - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG - ); } #[test] fn should_purge_data_on_inserting_coeffs_and_indices_if_capacity_exceeded() { - let mut store = ThresholdSigDataStoreImpl::new(); - let pub_coeffs = public_coeffs(); - - for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { - store.insert_transcript_data(&ni_dkg_id(i), pub_coeffs.clone(), BTreeMap::new()); - } + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let pub_coeffs = public_coeffs(); + + for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { + store.insert_transcript_data( + &ni_dkg_id_with_tag(tag.clone(), i), + pub_coeffs.clone(), + BTreeMap::new(), + ); + } - assert_eq!( - store.store.len(), - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG - ); - assert!(store.transcript_data(&ni_dkg_id(1)).is_none()); - for i in 2..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { - assert_eq!(pub_coeffs_from_store(&store, ni_dkg_id(i)), pub_coeffs); + assert_eq!( + store.store.len(), + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + ); + assert!(store + .transcript_data(&ni_dkg_id_with_tag(tag.clone(), 1)) + .is_none()); + for i in 2..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { + assert_eq!( + pub_coeffs_from_store(&store, ni_dkg_id_with_tag(tag.clone(), i)), + pub_coeffs + ); + } } } #[test] fn should_purge_data_in_insertion_order_on_inserting_coeffs_and_indices_if_capacity_exceeded() { - let mut store = ThresholdSigDataStoreImpl::new(); - let pub_coeffs = public_coeffs(); - - for i in (1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1).rev() { - store.insert_transcript_data(&ni_dkg_id(i), pub_coeffs.clone(), BTreeMap::new()); - } + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let pub_coeffs = public_coeffs(); + + for i in (1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1).rev() { + store.insert_transcript_data( + &ni_dkg_id_with_tag(tag.clone(), i), + pub_coeffs.clone(), + BTreeMap::new(), + ); + } - assert_eq!( - store.store.len(), - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG - ); - for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { - assert_eq!(pub_coeffs_from_store(&store, ni_dkg_id(i)), pub_coeffs); + assert_eq!( + store.store.len(), + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + ); + for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { + assert_eq!( + pub_coeffs_from_store(&store, ni_dkg_id_with_tag(tag.clone(), i)), + pub_coeffs + ); + } + assert!(store + .transcript_data(&ni_dkg_id_with_tag( + tag.clone(), + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 + )) + .is_none()); } - assert!(store - .transcript_data(&ni_dkg_id(ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1)) - .is_none()); } fn should_not_purge_all_transcripts_of_certain_threshold_if_capacity_exceeded( @@ -239,11 +309,7 @@ fn should_not_purge_all_transcripts_of_certain_threshold_if_capacity_exceeded( store.store.len(), ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 ); - assert_eq!( - store.store.len(), - store.low_threshold_dkg_id_insertion_order.len() - + store.high_threshold_dkg_id_insertion_order.len(), - ); + assert_store_length_invariant(&store); // verify there is at least one high threshold transcript and at least one low threshold transcript let mut found_single_threshold = false; @@ -263,130 +329,117 @@ fn should_not_purge_all_transcripts_of_certain_threshold_if_capacity_exceeded( } #[test] -fn should_not_purge_only_low_threshold_transcript_if_capacity_exceeded() { - should_not_purge_all_transcripts_of_certain_threshold_if_capacity_exceeded( - NiDkgTag::LowThreshold, - NiDkgTag::HighThreshold, - ); -} - -#[test] -fn should_not_purge_only_high_threshold_transcript_if_capacity_exceeded() { - should_not_purge_all_transcripts_of_certain_threshold_if_capacity_exceeded( - NiDkgTag::HighThreshold, - NiDkgTag::LowThreshold, - ); +fn should_not_purge_only_transcripts_for_some_tag_if_capacity_exceeded() { + for tag in all_tags() { + for other_tag in all_tags() { + if tag != other_tag { + should_not_purge_all_transcripts_of_certain_threshold_if_capacity_exceeded( + tag.clone(), + other_tag, + ) + } + } + } } #[test] fn should_purge_data_on_inserting_pubkeys_if_capacity_exceeded() { - let mut store = ThresholdSigDataStoreImpl::new(); - let csp_pubkey = csp_public_key(); - let node_id = node_test_id(NODE_1); - - for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { - store.insert_individual_public_key(&ni_dkg_id(i), node_id, csp_pubkey); - } + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let csp_pubkey = csp_public_key(); + let node_id = node_test_id(NODE_1); + + for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { + store.insert_individual_public_key( + &ni_dkg_id_with_tag(tag.clone(), i), + node_id, + csp_pubkey, + ); + } - assert_eq!( - store.store.len(), - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG - ); - for i in 2..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { assert_eq!( - store.individual_public_key(&ni_dkg_id(i), node_id), - Some(&csp_pubkey) + store.store.len(), + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + ); + for i in 2..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1 { + assert_eq!( + store.individual_public_key(&ni_dkg_id_with_tag(tag.clone(), i), node_id), + Some(&csp_pubkey) + ); + } + assert_eq!( + store.individual_public_key(&ni_dkg_id_with_tag(tag.clone(), 1), node_id), + None ); } - assert_eq!(store.individual_public_key(&ni_dkg_id(1), node_id), None); } #[test] fn should_purge_data_in_insertion_order_on_inserting_pubkeys_if_max_size_exceeded() { - let mut store = ThresholdSigDataStoreImpl::new(); - let csp_pubkey = csp_public_key(); - let node_id = node_test_id(NODE_1); - - for i in (1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1).rev() { - store.insert_individual_public_key(&ni_dkg_id(i), node_id, csp_pubkey); - } + for tag in all_tags() { + let mut store = ThresholdSigDataStoreImpl::new(); + let csp_pubkey = csp_public_key(); + let node_id = node_test_id(NODE_1); + + for i in (1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1).rev() { + store.insert_individual_public_key( + &ni_dkg_id_with_tag(tag.clone(), i), + node_id, + csp_pubkey, + ); + } - assert_eq!( - store.store.len(), - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG - ); - for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { assert_eq!( - store.individual_public_key(&ni_dkg_id(i), node_id), - Some(&csp_pubkey) + store.store.len(), + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + ); + for i in 1..=ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { + assert_eq!( + store.individual_public_key(&ni_dkg_id_with_tag(tag.clone(), i), node_id), + Some(&csp_pubkey) + ); + } + assert_eq!( + store.individual_public_key( + &ni_dkg_id_with_tag(tag.clone(), ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1), + node_id + ), + None ); } - assert_eq!( - store.individual_public_key( - &ni_dkg_id(ThresholdSigDataStoreImpl::CAPACITY_PER_TAG + 1), - node_id - ), - None - ); } #[test] -fn should_store_up_to_capacity_per_tag_for_both_tags() { +fn should_store_up_to_capacity_per_tag_for_all_tags() { let mut store = ThresholdSigDataStoreImpl::new(); let pub_coeffs = public_coeffs(); for i in 0..ThresholdSigDataStoreImpl::CAPACITY_PER_TAG { - store.insert_transcript_data( - &ni_dkg_id_with_tag(NiDkgTag::LowThreshold, i), - pub_coeffs.clone(), - BTreeMap::new(), - ); - store.insert_transcript_data( - &ni_dkg_id_with_tag(NiDkgTag::HighThreshold, i), - pub_coeffs.clone(), - BTreeMap::new(), - ); + for tag in all_tags() { + store.insert_transcript_data( + &ni_dkg_id_with_tag(tag.clone(), i), + pub_coeffs.clone(), + BTreeMap::new(), + ); + } } // Verify we have exactly the max capacity stored - assert_eq!( - store.store.len(), - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG * 2 - ); - assert_eq!( - store.store.len(), - store.low_threshold_dkg_id_insertion_order.len() - + store.high_threshold_dkg_id_insertion_order.len(), - ); + assert_max_store_capacity(&store); + assert_store_length_invariant(&store); // Insert one more transcript per tag - store.insert_transcript_data( - &ni_dkg_id_with_tag( - NiDkgTag::LowThreshold, - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG, - ), - pub_coeffs.clone(), - BTreeMap::new(), - ); - store.insert_transcript_data( - &ni_dkg_id_with_tag( - NiDkgTag::HighThreshold, - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG, - ), - pub_coeffs.clone(), - BTreeMap::new(), - ); + for tag in all_tags() { + store.insert_transcript_data( + &ni_dkg_id_with_tag(tag, ThresholdSigDataStoreImpl::CAPACITY_PER_TAG), + pub_coeffs.clone(), + BTreeMap::new(), + ); + } // Verify that we still have exactly the max capacity stored (since one of each tag was purged) - assert_eq!( - store.store.len(), - ThresholdSigDataStoreImpl::CAPACITY_PER_TAG * 2 - ); - assert_eq!( - store.store.len(), - store.low_threshold_dkg_id_insertion_order.len() - + store.high_threshold_dkg_id_insertion_order.len(), - ); + assert_max_store_capacity(&store); + assert_store_length_invariant(&store); } fn indices_with(mappings: Vec<(NodeId, NodeIndex)>) -> BTreeMap { @@ -447,3 +500,69 @@ fn ni_dkg_id_with_tag(ni_dkg_tag: NiDkgTag, height: usize) -> NiDkgId { ..ni_dkg_id(height) } } + +fn all_tags() -> Vec { + assert_eq!(MasterPublicKeyId::COUNT, 3); + assert_eq!(EcdsaCurve::iter().count(), 1); + assert_eq!(SchnorrAlgorithm::iter().count(), 2); + assert_eq!(VetKdCurve::iter().count(), 1); + vec![ + NiDkgTag::LowThreshold, + NiDkgTag::HighThreshold, + NiDkgTag::HighThresholdForKey(ecdsa_secp256k1_master_public_key_id()), + NiDkgTag::HighThresholdForKey(schnorr_bip340_master_public_key_id()), + NiDkgTag::HighThresholdForKey(schnorr_ed25519_master_public_key_id()), + NiDkgTag::HighThresholdForKey(vetkd_master_public_key_id()), + ] +} + +fn ecdsa_secp256k1_master_public_key_id() -> MasterPublicKeyId { + MasterPublicKeyId::Ecdsa(EcdsaKeyId { + curve: EcdsaCurve::Secp256k1, + name: "ecdsa_secp256k1_key".to_string(), + }) +} + +fn schnorr_bip340_master_public_key_id() -> MasterPublicKeyId { + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Bip340Secp256k1, + name: "schnorr_bip340_secp256k1_key".to_string(), + }) +} + +fn schnorr_ed25519_master_public_key_id() -> MasterPublicKeyId { + MasterPublicKeyId::Schnorr(SchnorrKeyId { + algorithm: SchnorrAlgorithm::Ed25519, + name: "schnorr_ed25519_key".to_string(), + }) +} + +fn vetkd_master_public_key_id() -> MasterPublicKeyId { + MasterPublicKeyId::VetKd(VetKdKeyId { + curve: VetKdCurve::Bls12_381_G2, + name: "vetkd_bls12_381_g2_key".to_string(), + }) +} + +fn assert_max_store_capacity(store: &ThresholdSigDataStoreImpl) { + assert_eq!( + store.store.len(), + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG * 2 + + ThresholdSigDataStoreImpl::CAPACITY_PER_TAG * (all_tags().len() - 2) + ); +} + +fn assert_store_length_invariant(store: &ThresholdSigDataStoreImpl) { + let high_threshold_for_key_id_dkg_id_insertion_order_len: usize = store + .high_threshold_for_key_dkg_id_insertion_order + .values() + .map(|v| v.len()) + .sum(); + assert_eq!( + store.store.len(), + store.low_threshold_dkg_id_insertion_order.len() + + store.high_threshold_dkg_id_insertion_order.len() + + high_threshold_for_key_id_dkg_id_insertion_order_len, + "ThresholdSigDataStore length invariant violated" + ); +} diff --git a/rs/crypto/src/sign/threshold_sig/tests.rs b/rs/crypto/src/sign/threshold_sig/tests.rs index 10d3f8126ba..a0a5d52d37b 100644 --- a/rs/crypto/src/sign/threshold_sig/tests.rs +++ b/rs/crypto/src/sign/threshold_sig/tests.rs @@ -21,7 +21,7 @@ use ic_types::crypto::threshold_sig::ni_dkg::{ use ic_types::crypto::{CombinedThresholdSig, SignableMock, ThresholdSigShare}; use ic_types::Height; use ic_types::SubnetId; -use ic_types_test_utils::ids::{NODE_1, SUBNET_0, SUBNET_1}; +use ic_types_test_utils::ids::{NODE_1, SUBNET_1}; pub const NODE_ID: NodeId = NODE_1; @@ -32,13 +32,6 @@ pub const NI_DKG_ID_1: NiDkgId = NiDkgId { target_subnet: NiDkgTargetSubnet::Remote(NiDkgTargetId::new([42; 32])), }; -pub const NI_DKG_ID_2: NiDkgId = NiDkgId { - start_block_height: Height::new(2), - dealer_subnet: SUBNET_0, - dkg_tag: NiDkgTag::HighThreshold, - target_subnet: NiDkgTargetSubnet::Remote(NiDkgTargetId::new([23; 32])), -}; - mod sign_threshold { use super::*; use ic_crypto_internal_csp::key_id::KeyId;