Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions crates/threshold-signatures/benches/advanced_dkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use rand_core::SeedableRng;

mod bench_utils;
use crate::bench_utils::{
MAX_MALICIOUS, PreparedOutputs, SAMPLE_SIZE, analyze_received_sizes, prepare_dkg,
MAX_MALICIOUS, PreparedOutputs, SAMPLE_SIZE, analyze_received_sizes, participant_rng,
prepare_dkg,
};

use threshold_signatures::{
Expand Down Expand Up @@ -48,7 +49,10 @@ where
|b| {
b.iter_batched(
|| prepare_simulated_dkg::<C>(&setup, threshold()),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand Down Expand Up @@ -89,22 +93,26 @@ where
{
let mut rng = MockCryptoRng::seed_from_u64(42);
let preps = prepare_dkg::<C, _>(participants_num(), threshold, &mut rng);
let participants: Vec<_> = preps.iter().map(|(p, _)| *p).collect();
let (_, protocol_snapshot) = run_protocol_and_take_snapshots(preps)
let participants: Vec<_> = preps.protocols.iter().map(|(p, _)| *p).collect();
let seeds = preps.seeds;
let (_, protocol_snapshot) = run_protocol_and_take_snapshots(preps.protocols)
.expect("Running protocol with snapshot should not have issues");

// choose the real_participant at random
let real_participant = *participants
.choose(&mut rng)
.expect("participant list is not empty");

// rebuild the exact rng the real participant used during snapshot capture
let rng_for_protocol = participant_rng(&seeds, real_participant);

let cached_simulator = Simulator::new(real_participant, &protocol_snapshot)
.expect("Simulator should not be empty");

DkgSetup {
participants,
real_participant,
rng_for_protocol: rng,
rng_for_protocol,
cached_simulator,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rand_core::SeedableRng;
mod bench_utils;
use crate::bench_utils::{
MAX_MALICIOUS, PreparedOutputs, RECONSTRUCTION_LOWER_BOUND, SAMPLE_SIZE,
analyze_received_sizes, ed25519_prepare_sign_v1,
analyze_received_sizes, ed25519_prepare_sign_v1, participant_rng,
};
use threshold_signatures::{
ReconstructionThreshold,
Expand Down Expand Up @@ -35,7 +35,10 @@ fn bench_sign(c: &mut Criterion) {
|b| {
b.iter_batched(
|| prepare_simulated_sign(&setup, *RECONSTRUCTION_LOWER_BOUND),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand Down Expand Up @@ -71,6 +74,9 @@ fn setup_sign_snapshot(threshold: ReconstructionThreshold) -> SignSetup {
// choose the real_participant being the coordinator
let (real_participant, keygen_out) = preps.key_packages[preps.index].clone();

// rebuild the exact rng the real participant used during snapshot capture
let rng_for_protocol = participant_rng(&preps.seeds, real_participant);

let cached_simulator = Simulator::new(real_participant, &protocol_snapshot)
.expect("Simulator should not be empty");

Expand All @@ -79,7 +85,7 @@ fn setup_sign_snapshot(threshold: ReconstructionThreshold) -> SignSetup {
real_participant,
keygen_out,
message: preps.message,
rng_for_protocol: rng,
rng_for_protocol,
cached_simulator,
}
}
Expand Down
26 changes: 12 additions & 14 deletions crates/threshold-signatures/benches/advanced_eddsa_frost_sign_v2.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#![allow(clippy::indexing_slicing)]

use criterion::{Criterion, criterion_group, criterion_main};
use rand::{Rng, RngCore};
use rand::Rng;
use rand_core::SeedableRng;

mod bench_utils;
use crate::bench_utils::{
MAX_MALICIOUS, PreparedOutputs, RECONSTRUCTION_LOWER_BOUND, SAMPLE_SIZE,
analyze_received_sizes, ed25519_prepare_presign, ed25519_prepare_sign_v2,
analyze_received_sizes, ed25519_prepare_presign, ed25519_prepare_sign_v2, participant_rng,
};
use threshold_signatures::{
ReconstructionThreshold,
Expand Down Expand Up @@ -40,7 +40,10 @@ fn bench_presign(c: &mut Criterion) {
|b| {
b.iter_batched(
|| prepare_simulate_presign(&setup),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand All @@ -63,7 +66,10 @@ fn bench_sign(c: &mut Criterion) {
|b| {
b.iter_batched(
|| prepare_simulated_sign(&setup, *RECONSTRUCTION_LOWER_BOUND),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand Down Expand Up @@ -95,16 +101,8 @@ fn setup_presign_snapshot(num_participants: usize) -> PresignSetup {
let index_real_participant = rng.gen_range(0..num_participants);
let (real_participant, keygen_out) = preps.key_packages[index_real_participant].clone();

// recreate rng using by real_participant to generate presignatures
let mut real_participant_rng = MockCryptoRng::seed_from_u64(42);
for (i, _) in preps.key_packages.iter().enumerate() {
let seed = real_participant_rng.next_u64();

if i == index_real_participant {
real_participant_rng = MockCryptoRng::seed_from_u64(seed);
break;
}
}
// rebuild the exact rng the real participant used during snapshot capture
let real_participant_rng = participant_rng(&preps.seeds, real_participant);

let cached_simulator = Simulator::new(real_participant, &protocol_snapshot)
.expect("Simulator should not be empty");
Expand Down
30 changes: 16 additions & 14 deletions crates/threshold-signatures/benches/advanced_ot_based_ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

use criterion::{Criterion, criterion_group, criterion_main};
use frost_secp256k1::VerifyingKey;
use rand::{Rng, RngCore, seq::SliceRandom as _};
use rand::{Rng, seq::SliceRandom as _};
use rand_core::SeedableRng;

mod bench_utils;
use crate::bench_utils::{
MAX_MALICIOUS, PreparedOutputs, RECONSTRUCTION_LOWER_BOUND, SAMPLE_SIZE,
analyze_received_sizes, ot_ecdsa_prepare_presign, ot_ecdsa_prepare_sign,
ot_ecdsa_prepare_triples,
ot_ecdsa_prepare_triples, participant_rng,
};

use threshold_signatures::{
Expand Down Expand Up @@ -58,7 +58,10 @@ fn bench_triples(c: &mut Criterion) {
|b| {
b.iter_batched(
|| prepare_simulated_triples(&setup),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand Down Expand Up @@ -86,7 +89,10 @@ fn bench_presign(c: &mut Criterion) {
|b| {
b.iter_batched(
|| prepare_simulated_presign(&setup),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand Down Expand Up @@ -117,7 +123,10 @@ fn bench_sign(c: &mut Criterion) {
|b| {
b.iter_batched(
|| prepare_simulated_sign(&setup, *RECONSTRUCTION_LOWER_BOUND),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand Down Expand Up @@ -149,15 +158,8 @@ fn setup_triples_snapshot(participant_num: usize) -> TriplesSetup {
.choose(&mut rng)
.expect("participant list is not empty");

// recreate rng using by real_participant to generate triples
let mut rng_copy = MockCryptoRng::seed_from_u64(42);
for p in &preps.participants {
if *p == real_participant {
break;
}
rng_copy.next_u64();
}
let real_participant_rng = MockCryptoRng::seed_from_u64(rng_copy.next_u64());
// rebuild the exact rng the real participant used during snapshot capture
let real_participant_rng = participant_rng(&preps.seeds, real_participant);

let cached_simulator = Simulator::new(real_participant, &protocol_snapshot)
.expect("Simulator should not be empty");
Expand Down
25 changes: 12 additions & 13 deletions crates/threshold-signatures/benches/advanced_robust_ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

use criterion::{Criterion, criterion_group, criterion_main};
use frost_secp256k1::VerifyingKey;
use rand::{RngCore, seq::SliceRandom as _};
use rand::seq::SliceRandom as _;
use rand_core::SeedableRng;

mod bench_utils;
use crate::bench_utils::{
MAX_MALICIOUS, PreparedOutputs, SAMPLE_SIZE, analyze_received_sizes,
MAX_MALICIOUS, PreparedOutputs, SAMPLE_SIZE, analyze_received_sizes, participant_rng,
robust_ecdsa_prepare_presign, robust_ecdsa_prepare_sign,
};
use threshold_signatures::{
Expand Down Expand Up @@ -51,7 +51,10 @@ fn bench_presign(c: &mut Criterion) {
|b| {
b.iter_batched(
|| prepare_simulate_presign(&setup),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand Down Expand Up @@ -79,7 +82,10 @@ fn bench_sign(c: &mut Criterion) {
|b| {
b.iter_batched(
|| prepare_simulated_sign(&setup, max_malicious),
|preps| run_simulated_protocol(preps.participant, preps.protocol, preps.simulator),
|preps| {
run_simulated_protocol(preps.participant, preps.protocol, preps.simulator)
.expect("simulated replay should complete")
},
criterion::BatchSize::SmallInput,
);
},
Expand Down Expand Up @@ -114,15 +120,8 @@ fn setup_presign_snapshot(num_participants: usize) -> PresignSetup {
.expect("participant list is not empty")
.clone();

// recreate rng using by real_participant to generate presignatures
let mut rng_copy = MockCryptoRng::seed_from_u64(42);
for p in &preps.participants {
if *p == real_participant {
break;
}
rng_copy.next_u64();
}
let real_participant_rng = MockCryptoRng::seed_from_u64(rng_copy.next_u64());
// rebuild the exact rng the real participant used during snapshot capture
let real_participant_rng = participant_rng(&preps.seeds, real_participant);

let cached_simulator = Simulator::new(real_participant, &protocol_snapshot)
.expect("Simulator should not be empty");
Expand Down
20 changes: 18 additions & 2 deletions crates/threshold-signatures/benches/bench_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,29 @@ pub use robust_ecdsa::*;

use average::{Estimate, Quantile, Variance};
use k256::AffinePoint;
use std::{env, sync::LazyLock};
use std::{collections::HashMap, env, sync::LazyLock};

use rand_core::SeedableRng;
use threshold_signatures::{
ReconstructionThreshold,
ecdsa::{self, Scalar},
participants::Participant,
protocol::Protocol,
test_utils::Simulator,
test_utils::{MockCryptoRng, Simulator},
};

/// Rebuilds the RNG a participant's protocol was seeded with during snapshot
/// capture, so the simulated replay reproduces the exact recorded run.
pub fn participant_rng<S: std::hash::BuildHasher>(
seeds: &HashMap<Participant, u64, S>,
participant: Participant,
) -> MockCryptoRng {
let seed = *seeds
.get(&participant)
.expect("participant must have a recorded seed");
MockCryptoRng::seed_from_u64(seed)
}

// fix malicious number of participants
pub static MAX_MALICIOUS: LazyLock<usize> = std::sync::LazyLock::new(|| {
env::var("MAX_MALICIOUS")
Expand Down Expand Up @@ -63,6 +76,9 @@ pub struct PreparedPresig<PresignOutput, KeygenOutput> {
pub protocols: Vec<(Participant, Box<dyn Protocol<Output = PresignOutput>>)>,
pub key_packages: Vec<(Participant, KeygenOutput)>,
pub participants: Vec<Participant>,
/// Per-participant RNG seed used to build each presign protocol; empty when
/// the protocol is built from deterministic inputs.
pub seeds: HashMap<Participant, u64>,
}

pub struct PreparedSig<RerandomizedPresignOutput> {
Expand Down
9 changes: 8 additions & 1 deletion crates/threshold-signatures/benches/bench_utils/ckd.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use rand::Rng;
use rand_core::{CryptoRngCore, SeedableRng};

Expand Down Expand Up @@ -28,6 +30,7 @@ pub fn prepare_ckd<R: CryptoRngCore + SeedableRng + Send + 'static>(
let coordinator = participants[coordinator_index];

let mut protocols = Vec::with_capacity(participants.len());
let mut seeds = HashMap::with_capacity(participants.len());

let mut app_id: [u8; 32] = [0u8; 32];
rng.fill_bytes(&mut app_id);
Expand All @@ -38,7 +41,8 @@ pub fn prepare_ckd<R: CryptoRngCore + SeedableRng + Send + 'static>(
let app_pk = ckd::ElementG1::generator() * app_sk;

for (p, keygen_out) in &key_packages {
let rng_p = MockCryptoRng::seed_from_u64(rng.next_u64());
let seed = rng.next_u64();
let rng_p = MockCryptoRng::seed_from_u64(seed);
let protocol = ckd::protocol::ckd(
&participants,
coordinator,
Expand All @@ -51,6 +55,7 @@ pub fn prepare_ckd<R: CryptoRngCore + SeedableRng + Send + 'static>(
.map(|ckd| Box::new(ckd) as Box<dyn Protocol<Output = ckd::CKDOutputOption>>)
.expect("Ckd should succeed");
protocols.push((*p, protocol));
seeds.insert(*p, seed);
}

PreparedCkdPackage {
Expand All @@ -59,6 +64,7 @@ pub fn prepare_ckd<R: CryptoRngCore + SeedableRng + Send + 'static>(
key_packages,
app_id,
app_pk,
seeds,
}
}

Expand All @@ -71,4 +77,5 @@ pub struct PreparedCkdPackage {
pub key_packages: Vec<(Participant, ckd::KeygenOutput)>,
pub app_id: ckd::AppId,
pub app_pk: ckd::ElementG1,
pub seeds: HashMap<Participant, u64>,
}
Loading
Loading