Skip to content

Commit 3dcb3ea

Browse files
committed
Merge branch 'gdemay/CRP-1471-idkg-bench-reshare' into 'master'
test(crypto): CRP-1471 benchmark IDKG operations for reshare and product transcripts Follow-up on [MR-12252](https://gitlab.com/dfinity-lab/public/ic/-/merge_requests/12252) that focussed on benchmarking IDKG crypto operations in the case where `IDkgTranscript` corresponds to the sharing of a random value with masking commitments (`IDkgTranscriptOperation::Random`). This MR adds benchmarks for those operations for the other two types of transcripts: 1. where a `IDkgTranscript` corresponds to the resharing of masked value to an unmasked one (`IDkgTranscriptOperation::ReshareOfMasked`) 2. where a `IDkgTranscript` corresponds to the resharing of an unmasked value to an unmasked one (`IDkgTranscriptOperation::ReshareOfUnmasked`) 3. where a `IDkgTranscript` corresponds to the product of a masked value with an unmasked one (`IDkgTranscriptOperation::UnmaskedTimesMasked`) See merge request dfinity-lab/public/ic!12533
2 parents ae1e555 + 6a4cf5d commit 3dcb3ea

File tree

1 file changed

+111
-32
lines changed

1 file changed

+111
-32
lines changed

rs/crypto/benches/idkg.rs

Lines changed: 111 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use rand::prelude::IteratorRandom;
1919
use rand::thread_rng;
2020
use std::collections::{BTreeMap, HashSet};
2121
use std::fmt::{Display, Formatter};
22+
use strum::IntoEnumIterator;
23+
use strum_macros::EnumIter;
2224

2325
criterion_main!(benches);
2426
criterion_group!(benches, crypto_idkg_benchmarks);
@@ -45,22 +47,29 @@ fn crypto_idkg_benchmarks(criterion: &mut Criterion) {
4547
.sample_size(test_case.sample_size)
4648
.sampling_mode(test_case.sampling_mode);
4749

48-
bench_create_dealing(group, &test_case);
49-
bench_verify_dealing_public(group, &test_case);
50-
bench_verify_dealing_private(group, &test_case);
50+
IDkgMode::iter().for_each(|mode| bench_create_dealing(group, &test_case, &mode));
51+
IDkgMode::iter().for_each(|mode| bench_verify_dealing_public(group, &test_case, &mode));
52+
IDkgMode::iter().for_each(|mode| bench_verify_dealing_private(group, &test_case, &mode));
53+
5154
bench_verify_initial_dealings(group, &test_case);
52-
bench_create_transcript(group, &test_case);
53-
bench_verify_transcript(group, &test_case);
54-
bench_load_transcript(group, &test_case);
55+
56+
IDkgMode::iter().for_each(|mode| bench_create_transcript(group, &test_case, &mode));
57+
IDkgMode::iter().for_each(|mode| bench_verify_transcript(group, &test_case, &mode));
58+
IDkgMode::iter().for_each(|mode| bench_load_transcript(group, &test_case, &mode));
59+
5560
bench_retain_active_transcripts(group, &test_case, 1);
5661
}
5762
}
5863

59-
fn bench_create_dealing<M: Measurement>(group: &mut BenchmarkGroup<'_, M>, test_case: &TestCase) {
64+
fn bench_create_dealing<M: Measurement>(
65+
group: &mut BenchmarkGroup<'_, M>,
66+
test_case: &TestCase,
67+
mode: &IDkgMode,
68+
) {
6069
let env = test_case.new_test_environment();
61-
let params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
70+
let params = mode.setup_params(&env);
6271

63-
group.bench_function("create_dealing", |bench| {
72+
group.bench_function(format!("create_dealing_{mode}"), |bench| {
6473
bench.iter_batched(
6574
|| crypto_for(random_dealer_id(&params), &env.crypto_components),
6675
|dealer| create_dealing(dealer, &params),
@@ -72,11 +81,12 @@ fn bench_create_dealing<M: Measurement>(group: &mut BenchmarkGroup<'_, M>, test_
7281
fn bench_verify_dealing_public<M: Measurement>(
7382
group: &mut BenchmarkGroup<'_, M>,
7483
test_case: &TestCase,
84+
mode: &IDkgMode,
7585
) {
7686
let env = test_case.new_test_environment();
77-
let params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
87+
let params = mode.setup_params(&env);
7888

79-
group.bench_function("verify_dealing_public", |bench| {
89+
group.bench_function(format!("verify_dealing_public_{mode}"), |bench| {
8090
bench.iter_batched(
8191
|| {
8292
let receiver = crypto_for(random_receiver_id(&params), &env.crypto_components);
@@ -93,11 +103,12 @@ fn bench_verify_dealing_public<M: Measurement>(
93103
fn bench_verify_dealing_private<M: Measurement>(
94104
group: &mut BenchmarkGroup<'_, M>,
95105
test_case: &TestCase,
106+
mode: &IDkgMode,
96107
) {
97108
let env = test_case.new_test_environment();
98-
let params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
109+
let params = mode.setup_params(&env);
99110

100-
group.bench_function("verify_dealing_private", |bench| {
111+
group.bench_function(format!("verify_dealing_private_{mode}"), |bench| {
101112
bench.iter_batched(
102113
|| {
103114
let receiver = crypto_for(random_receiver_id(&params), &env.crypto_components);
@@ -164,11 +175,12 @@ fn bench_verify_initial_dealings<M: Measurement>(
164175
fn bench_create_transcript<M: Measurement>(
165176
group: &mut BenchmarkGroup<'_, M>,
166177
test_case: &TestCase,
178+
mode: &IDkgMode,
167179
) {
168180
let env = test_case.new_test_environment();
169-
let params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
181+
let params = mode.setup_params(&env);
170182

171-
group.bench_function("create_transcript", |bench| {
183+
group.bench_function(format!("create_transcript_{mode}"), |bench| {
172184
bench.iter_batched(
173185
|| {
174186
let receiver = crypto_for(random_receiver_id(&params), &env.crypto_components);
@@ -186,11 +198,12 @@ fn bench_create_transcript<M: Measurement>(
186198
fn bench_verify_transcript<M: Measurement>(
187199
group: &mut BenchmarkGroup<'_, M>,
188200
test_case: &TestCase,
201+
mode: &IDkgMode,
189202
) {
190203
let env = test_case.new_test_environment();
191-
let params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
204+
let params = mode.setup_params(&env);
192205

193-
group.bench_function("verify_transcript", |bench| {
206+
group.bench_function(format!("verify_transcript_{mode}"), |bench| {
194207
bench.iter_batched(
195208
|| {
196209
let dealings = create_dealings(&params, &env.crypto_components);
@@ -211,11 +224,15 @@ fn bench_verify_transcript<M: Measurement>(
211224
});
212225
}
213226

214-
fn bench_load_transcript<M: Measurement>(group: &mut BenchmarkGroup<'_, M>, test_case: &TestCase) {
227+
fn bench_load_transcript<M: Measurement>(
228+
group: &mut BenchmarkGroup<'_, M>,
229+
test_case: &TestCase,
230+
mode: &IDkgMode,
231+
) {
215232
let env = test_case.new_test_environment();
216-
let params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
233+
let params = mode.setup_params(&env);
217234

218-
group.bench_function("load_transcript", |bench| {
235+
group.bench_function(format!("load_transcript_{mode}"), |bench| {
219236
bench.iter_batched(
220237
|| {
221238
let dealings = create_dealings(&params, &env.crypto_components);
@@ -239,7 +256,7 @@ fn bench_load_transcript<M: Measurement>(group: &mut BenchmarkGroup<'_, M>, test
239256
fn bench_retain_active_transcripts<M: Measurement>(
240257
group: &mut BenchmarkGroup<'_, M>,
241258
test_case: &TestCase,
242-
num_pre_sig_quadruples: usize,
259+
num_pre_sig_quadruples: i32,
243260
) {
244261
let env = test_case.new_test_environment();
245262
let key_transcript = generate_key_transcript(&env);
@@ -545,11 +562,64 @@ fn generate_pre_sig_quadruple(
545562
.unwrap_or_else(|error| panic!("failed to create pre-signature quadruple: {:?}", error))
546563
}
547564

565+
fn setup_reshare_of_masked_params(
566+
env: &CanisterThresholdSigTestEnvironment,
567+
) -> IDkgTranscriptParams {
568+
let params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
569+
let masked_transcript = run_idkg_without_complaint(&params, &env.crypto_components);
570+
let reshare_params = build_params_from_previous(
571+
params,
572+
IDkgTranscriptOperation::ReshareOfMasked(masked_transcript),
573+
);
574+
load_previous_transcripts_for_all_dealers(&reshare_params, &env.crypto_components);
575+
reshare_params
576+
}
577+
578+
fn setup_reshare_of_unmasked_params(
579+
env: &CanisterThresholdSigTestEnvironment,
580+
) -> IDkgTranscriptParams {
581+
let params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
582+
let masked_transcript = run_idkg_without_complaint(&params, &env.crypto_components);
583+
let unmasked_params = build_params_from_previous(
584+
params,
585+
IDkgTranscriptOperation::ReshareOfMasked(masked_transcript),
586+
);
587+
load_previous_transcripts_for_all_dealers(&unmasked_params, &env.crypto_components);
588+
let unmasked_transcript = run_idkg_without_complaint(&unmasked_params, &env.crypto_components);
589+
let unmasked_reshare_params = build_params_from_previous(
590+
unmasked_params,
591+
IDkgTranscriptOperation::ReshareOfUnmasked(unmasked_transcript),
592+
);
593+
load_previous_transcripts_for_all_dealers(&unmasked_reshare_params, &env.crypto_components);
594+
unmasked_reshare_params
595+
}
596+
597+
fn setup_unmasked_times_masked_params(
598+
env: &CanisterThresholdSigTestEnvironment,
599+
) -> IDkgTranscriptParams {
600+
let masked_params = env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1);
601+
let masked_random_transcript =
602+
run_idkg_without_complaint(&masked_params, &env.crypto_components);
603+
604+
let unmasked_params = build_params_from_previous(
605+
masked_params,
606+
IDkgTranscriptOperation::ReshareOfMasked(masked_random_transcript.clone()),
607+
);
608+
load_previous_transcripts_for_all_dealers(&unmasked_params, &env.crypto_components);
609+
let unmasked_transcript = run_idkg_without_complaint(&unmasked_params, &env.crypto_components);
610+
611+
let product_params = build_params_from_previous(
612+
unmasked_params,
613+
IDkgTranscriptOperation::UnmaskedTimesMasked(unmasked_transcript, masked_random_transcript),
614+
);
615+
load_previous_transcripts_for_all_dealers(&product_params, &env.crypto_components);
616+
product_params
617+
}
618+
548619
struct TestCase {
549620
sample_size: usize,
550621
sampling_mode: SamplingMode,
551622
num_of_nodes: usize,
552-
operation_type: IDkgMode,
553623
}
554624

555625
impl Default for TestCase {
@@ -558,7 +628,6 @@ impl Default for TestCase {
558628
sample_size: 100,
559629
sampling_mode: SamplingMode::Auto,
560630
num_of_nodes: 0,
561-
operation_type: IDkgMode::Random,
562631
}
563632
}
564633
}
@@ -570,8 +639,7 @@ impl TestCase {
570639

571640
fn name(&self) -> String {
572641
format!(
573-
"crypto_idkg_{}_{}_nodes_{}_dealers_{}_receivers",
574-
self.operation_type,
642+
"crypto_idkg_{}_nodes_{}_dealers_{}_receivers",
575643
self.num_of_nodes,
576644
self.num_of_dealers(),
577645
self.num_of_receivers()
@@ -587,12 +655,23 @@ impl TestCase {
587655
}
588656
}
589657

590-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
658+
#[derive(Clone, Debug, PartialEq, Eq, Hash, EnumIter)]
591659
enum IDkgMode {
592660
Random,
593-
// TODO CRP-1471: add benchmarks for resharing and product
594-
// ReshareOfMasked,
595-
// UnmaskedTimesMasked,
661+
ReshareOfMasked,
662+
ReshareOfUnmasked,
663+
UnmaskedTimesMasked,
664+
}
665+
666+
impl IDkgMode {
667+
fn setup_params(&self, env: &CanisterThresholdSigTestEnvironment) -> IDkgTranscriptParams {
668+
match self {
669+
IDkgMode::Random => env.params_for_random_sharing(AlgorithmId::ThresholdEcdsaSecp256k1),
670+
IDkgMode::ReshareOfMasked => setup_reshare_of_masked_params(env),
671+
IDkgMode::ReshareOfUnmasked => setup_reshare_of_unmasked_params(env),
672+
IDkgMode::UnmaskedTimesMasked => setup_unmasked_times_masked_params(env),
673+
}
674+
}
596675
}
597676

598677
impl Display for IDkgMode {
@@ -602,9 +681,9 @@ impl Display for IDkgMode {
602681
"{}",
603682
match self {
604683
IDkgMode::Random => "random",
605-
// TODO CRP-1471: add benchmarks for resharing and product
606-
// IDkgMode::ReshareOfMasked => "reshare",
607-
// IDkgMode::UnmaskedTimesMasked => "product",
684+
IDkgMode::ReshareOfMasked => "reshare_of_masked",
685+
IDkgMode::ReshareOfUnmasked => "reshare_of_unmasked",
686+
IDkgMode::UnmaskedTimesMasked => "product",
608687
}
609688
)
610689
}

0 commit comments

Comments
 (0)