Skip to content

Commit 95fe283

Browse files
committed
embed public and private shares into DkgPrivateBegin and DkgEndBegin messages
make embedding of public and private shares configurable reenable start_private_shares test now that embedding is configurable inc major semver for backwards incompatible API changes test modules do not need to be public unless someone is using them externally allow a static mut ref to an atomic variable used for test log initialization; allow many arguments to Signer::new allow many arguments to setup_with_timeouts fmt and code change for rng PR rebase rebase fixes add TryFromInt to signer and coordinator errors so we can remove more unwrap calls remove unwrap in signer state machine
1 parent e3ab997 commit 95fe283

6 files changed

Lines changed: 259 additions & 35 deletions

File tree

src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ pub mod test_helpers {
321321

322322
#[cfg(test)]
323323
/// Test module for common functionality
324-
pub mod test {
324+
mod test {
325325
use super::*;
326326
use crate::util::create_rng;
327327

src/net.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ pub struct DkgPrivateBegin {
168168
pub signer_ids: Vec<u32>,
169169
/// Key IDs who responded in time for this DKG round
170170
pub key_ids: Vec<u32>,
171+
/// Include DkgPublicShares to avoid p2p related message delivery
172+
/// order issues when signers communicate directly with each other
173+
pub dkg_public_shares: HashMap<u32, DkgPublicShares>,
171174
}
172175

173176
impl Signable for DkgPrivateBegin {
@@ -179,6 +182,9 @@ impl Signable for DkgPrivateBegin {
179182
}
180183
for signer_id in &self.signer_ids {
181184
hasher.update(signer_id.to_be_bytes());
185+
if let Some(shares) = self.dkg_public_shares.get(signer_id) {
186+
shares.hash(hasher);
187+
}
182188
}
183189
}
184190
}
@@ -228,6 +234,9 @@ pub struct DkgEndBegin {
228234
pub signer_ids: Vec<u32>,
229235
/// Key IDs who responded in time for this DKG round
230236
pub key_ids: Vec<u32>,
237+
/// Include DkgPrivateShares to avoid p2p related message delivery
238+
/// order issues when signers communicate directly with each other
239+
pub dkg_private_shares: HashMap<u32, DkgPrivateShares>,
231240
}
232241

233242
impl Signable for DkgEndBegin {
@@ -239,6 +248,9 @@ impl Signable for DkgEndBegin {
239248
}
240249
for signer_id in &self.signer_ids {
241250
hasher.update(signer_id.to_be_bytes());
251+
if let Some(shares) = self.dkg_private_shares.get(signer_id) {
252+
shares.hash(hasher);
253+
}
242254
}
243255
}
244256
}
@@ -660,6 +672,7 @@ mod test {
660672
dkg_id: 0,
661673
key_ids: Default::default(),
662674
signer_ids: Default::default(),
675+
dkg_public_shares: Default::default(),
663676
};
664677
let msg = Message::DkgBegin(dkg_begin.clone());
665678
let coordinator_packet_dkg_begin = Packet {

src/state_machine/coordinator/fire.rs

Lines changed: 119 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -424,11 +424,19 @@ impl<Aggregator: AggregatorTrait> Coordinator<Aggregator> {
424424
.keys()
425425
.flat_map(|signer_id| self.config.signer_key_ids[signer_id].clone())
426426
.collect::<Vec<u32>>();
427-
427+
let dkg_public_shares = if self.config.embed_public_private_shares {
428+
self.dkg_public_shares
429+
.iter()
430+
.map(|(id, share)| (*id, share.clone()))
431+
.collect()
432+
} else {
433+
Default::default()
434+
};
428435
let dkg_begin = DkgPrivateBegin {
429436
dkg_id: self.current_dkg_id,
430437
key_ids: active_key_ids,
431438
signer_ids: self.dkg_public_shares.keys().cloned().collect(),
439+
dkg_public_shares,
432440
};
433441
let dkg_private_begin_msg = Packet {
434442
sig: dkg_begin
@@ -458,11 +466,20 @@ impl<Aggregator: AggregatorTrait> Coordinator<Aggregator> {
458466
.keys()
459467
.flat_map(|signer_id| self.config.signer_key_ids[signer_id].clone())
460468
.collect::<Vec<u32>>();
469+
let dkg_private_shares = if self.config.embed_public_private_shares {
470+
self.dkg_private_shares
471+
.iter()
472+
.map(|(id, share)| (*id, share.clone()))
473+
.collect()
474+
} else {
475+
Default::default()
476+
};
461477

462478
let dkg_end_begin = DkgEndBegin {
463479
dkg_id: self.current_dkg_id,
464480
key_ids: active_key_ids,
465481
signer_ids: self.dkg_private_shares.keys().cloned().collect(),
482+
dkg_private_shares,
466483
};
467484
let dkg_end_begin_msg = Packet {
468485
sig: dkg_end_begin
@@ -1270,7 +1287,7 @@ impl<Aggregator: AggregatorTrait> CoordinatorTrait for Coordinator<Aggregator> {
12701287

12711288
#[cfg(test)]
12721289
/// Test module for coordinator functionality
1273-
pub mod test {
1290+
mod test {
12741291
use crate::{
12751292
curve::{point::Point, scalar::Scalar},
12761293
net::{
@@ -1524,17 +1541,27 @@ pub mod test {
15241541

15251542
#[test]
15261543
fn missing_public_keys_dkg_v1() {
1527-
missing_public_keys_dkg::<v1::Aggregator, v1::Signer>(10, 1);
1544+
missing_public_keys_dkg::<v1::Aggregator, v1::Signer>(10, 1, false);
1545+
}
1546+
#[test]
1547+
fn missing_public_keys_dkg_v1_embed() {
1548+
missing_public_keys_dkg::<v1::Aggregator, v1::Signer>(10, 1, true);
15281549
}
15291550

15301551
#[test]
15311552
fn missing_public_keys_dkg_v2() {
1532-
missing_public_keys_dkg::<v2::Aggregator, v2::Signer>(10, 1);
1553+
missing_public_keys_dkg::<v2::Aggregator, v2::Signer>(10, 1, false);
1554+
}
1555+
1556+
#[test]
1557+
fn missing_public_keys_dkg_v2_embed() {
1558+
missing_public_keys_dkg::<v2::Aggregator, v2::Signer>(10, 1, true);
15331559
}
15341560

15351561
fn missing_public_keys_dkg<Aggregator: AggregatorTrait, SignerType: SignerTrait>(
15361562
num_signers: u32,
15371563
keys_per_signer: u32,
1564+
embed_public_private_shares: bool,
15381565
) -> (Vec<FireCoordinator<Aggregator>>, Vec<Signer<SignerType>>) {
15391566
let timeout = Duration::from_millis(1024);
15401567
let expire = Duration::from_millis(1280);
@@ -1547,6 +1574,7 @@ pub mod test {
15471574
Some(timeout),
15481575
Some(timeout),
15491576
Some(timeout),
1577+
embed_public_private_shares,
15501578
);
15511579

15521580
// Start a DKG round where we will not allow all signers to recv DkgBegin, so they will not respond with DkgPublicShares
@@ -1605,17 +1633,28 @@ pub mod test {
16051633

16061634
#[test]
16071635
fn minimum_signers_dkg_v1() {
1608-
minimum_signers_dkg::<v1::Aggregator, v1::Signer>(10, 2);
1636+
minimum_signers_dkg::<v1::Aggregator, v1::Signer>(10, 2, false);
16091637
}
16101638

16111639
#[test]
16121640
fn minimum_signers_dkg_v2() {
1613-
minimum_signers_dkg::<v2::Aggregator, v2::Signer>(10, 2);
1641+
minimum_signers_dkg::<v2::Aggregator, v2::Signer>(10, 2, false);
1642+
}
1643+
1644+
#[test]
1645+
fn minimum_signers_dkg_v1_embed() {
1646+
minimum_signers_dkg::<v1::Aggregator, v1::Signer>(10, 2, true);
1647+
}
1648+
1649+
#[test]
1650+
fn minimum_signers_dkg_v2_embed() {
1651+
minimum_signers_dkg::<v2::Aggregator, v2::Signer>(10, 2, true);
16141652
}
16151653

16161654
fn minimum_signers_dkg<Aggregator: AggregatorTrait, SignerType: SignerTrait>(
16171655
num_signers: u32,
16181656
keys_per_signer: u32,
1657+
embed_public_private_shares: bool,
16191658
) -> (Vec<FireCoordinator<Aggregator>>, Vec<Signer<SignerType>>) {
16201659
let timeout = Duration::from_millis(1024);
16211660
let expire = Duration::from_millis(1280);
@@ -1628,6 +1667,7 @@ pub mod test {
16281667
Some(timeout),
16291668
Some(timeout),
16301669
Some(timeout),
1670+
embed_public_private_shares,
16311671
);
16321672

16331673
// Start a DKG round where we will not allow all signers to recv DkgBegin, so they will not respond with DkgPublicShares
@@ -1760,15 +1800,27 @@ pub mod test {
17601800

17611801
#[test]
17621802
fn insufficient_signers_dkg_v1() {
1763-
insufficient_signers_dkg::<v1::Aggregator, v1::Signer>();
1803+
insufficient_signers_dkg::<v1::Aggregator, v1::Signer>(false);
17641804
}
17651805

17661806
#[test]
17671807
fn insufficient_signers_dkg_v2() {
1768-
insufficient_signers_dkg::<v2::Aggregator, v2::Signer>();
1808+
insufficient_signers_dkg::<v2::Aggregator, v2::Signer>(false);
1809+
}
1810+
1811+
#[test]
1812+
fn insufficient_signers_dkg_v1_embed() {
1813+
insufficient_signers_dkg::<v1::Aggregator, v1::Signer>(true);
1814+
}
1815+
1816+
#[test]
1817+
fn insufficient_signers_dkg_v2_embed() {
1818+
insufficient_signers_dkg::<v2::Aggregator, v2::Signer>(true);
17691819
}
17701820

1771-
fn insufficient_signers_dkg<Aggregator: AggregatorTrait, Signer: SignerTrait>() {
1821+
fn insufficient_signers_dkg<Aggregator: AggregatorTrait, Signer: SignerTrait>(
1822+
embed_public_private_shares: bool,
1823+
) {
17721824
let timeout = Duration::from_millis(1024);
17731825
let expire = Duration::from_millis(1280);
17741826
let num_signers = 10;
@@ -1781,6 +1833,7 @@ pub mod test {
17811833
Some(timeout),
17821834
Some(timeout),
17831835
Some(timeout),
1836+
embed_public_private_shares,
17841837
);
17851838

17861839
// Start a DKG round where we will not allow all signers to recv DkgBegin, so they will not respond with DkgPublicShares
@@ -2209,20 +2262,35 @@ pub mod test {
22092262

22102263
#[test]
22112264
fn minimum_signers_sign_v1() {
2212-
minimum_signers_sign::<v1::Aggregator, v1::Signer>();
2265+
minimum_signers_sign::<v1::Aggregator, v1::Signer>(false);
22132266
}
22142267

22152268
#[test]
22162269
fn minimum_signers_sign_v2() {
2217-
minimum_signers_sign::<v2::Aggregator, v2::Signer>();
2270+
minimum_signers_sign::<v2::Aggregator, v2::Signer>(false);
22182271
}
22192272

2220-
fn minimum_signers_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>() {
2273+
#[test]
2274+
fn minimum_signers_sign_v1_embed() {
2275+
minimum_signers_sign::<v1::Aggregator, v1::Signer>(true);
2276+
}
2277+
2278+
#[test]
2279+
fn minimum_signers_sign_v2_embed() {
2280+
minimum_signers_sign::<v2::Aggregator, v2::Signer>(true);
2281+
}
2282+
2283+
fn minimum_signers_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>(
2284+
embed_public_private_shares: bool,
2285+
) {
22212286
let num_signers = 10;
22222287
let keys_per_signer = 2;
22232288

2224-
let (mut coordinators, mut signers) =
2225-
minimum_signers_dkg::<Aggregator, Signer>(num_signers, keys_per_signer);
2289+
let (mut coordinators, mut signers) = minimum_signers_dkg::<Aggregator, Signer>(
2290+
num_signers,
2291+
keys_per_signer,
2292+
embed_public_private_shares,
2293+
);
22262294
let config = coordinators.first().unwrap().get_config();
22272295

22282296
// Figure out how many signers we can remove and still be above the threshold
@@ -2293,20 +2361,35 @@ pub mod test {
22932361

22942362
#[test]
22952363
fn missing_public_keys_sign_v1() {
2296-
missing_public_keys_sign::<v1::Aggregator, v1::Signer>();
2364+
missing_public_keys_sign::<v1::Aggregator, v1::Signer>(false);
2365+
}
2366+
2367+
#[test]
2368+
fn missing_public_keys_sign_v2() {
2369+
missing_public_keys_sign::<v2::Aggregator, v2::Signer>(false);
22972370
}
22982371

22992372
#[test]
2300-
fn minimum_missing_public_keys_sign_v2() {
2301-
missing_public_keys_sign::<v2::Aggregator, v2::Signer>();
2373+
fn missing_public_keys_sign_v1_embed() {
2374+
missing_public_keys_sign::<v1::Aggregator, v1::Signer>(true);
23022375
}
23032376

2304-
fn missing_public_keys_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>() {
2377+
#[test]
2378+
fn missing_public_keys_sign_v2_embed() {
2379+
missing_public_keys_sign::<v2::Aggregator, v2::Signer>(true);
2380+
}
2381+
2382+
fn missing_public_keys_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>(
2383+
embed_public_private_shares: bool,
2384+
) {
23052385
let num_signers = 10;
23062386
let keys_per_signer = 2;
23072387

2308-
let (mut coordinators, mut signers) =
2309-
minimum_signers_dkg::<Aggregator, Signer>(num_signers, keys_per_signer);
2388+
let (mut coordinators, mut signers) = minimum_signers_dkg::<Aggregator, Signer>(
2389+
num_signers,
2390+
keys_per_signer,
2391+
embed_public_private_shares,
2392+
);
23102393

23112394
// Let us also remove that signers public key from the config including all of its key ids
23122395
let mut removed_signer = signers.pop().expect("Failed to pop signer");
@@ -2380,15 +2463,27 @@ pub mod test {
23802463

23812464
#[test]
23822465
fn insufficient_signers_sign_v1() {
2383-
insufficient_signers_sign::<v1::Aggregator, v1::Signer>();
2466+
insufficient_signers_sign::<v1::Aggregator, v1::Signer>(false);
23842467
}
23852468

23862469
#[test]
23872470
fn insufficient_signers_sign_v2() {
2388-
insufficient_signers_sign::<v2::Aggregator, v2::Signer>();
2471+
insufficient_signers_sign::<v2::Aggregator, v2::Signer>(false);
2472+
}
2473+
2474+
#[test]
2475+
fn insufficient_signers_sign_v1_embed() {
2476+
insufficient_signers_sign::<v1::Aggregator, v1::Signer>(true);
2477+
}
2478+
2479+
#[test]
2480+
fn insufficient_signers_sign_v2_embed() {
2481+
insufficient_signers_sign::<v2::Aggregator, v2::Signer>(true);
23892482
}
23902483

2391-
fn insufficient_signers_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>() {
2484+
fn insufficient_signers_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>(
2485+
embed_public_private_shares: bool,
2486+
) {
23922487
let num_signers = 5;
23932488
let keys_per_signer = 2;
23942489
let (mut coordinators, mut signers) =
@@ -2400,6 +2495,7 @@ pub mod test {
24002495
None,
24012496
Some(Duration::from_millis(128)),
24022497
Some(Duration::from_millis(128)),
2498+
embed_public_private_shares,
24032499
);
24042500
let config = coordinators.first().unwrap().get_config();
24052501

src/state_machine/coordinator/frost.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,18 @@ impl<Aggregator: AggregatorTrait> Coordinator<Aggregator> {
229229
dkg_id = %self.current_dkg_id,
230230
"Starting Private Share Distribution"
231231
);
232+
let dkg_public_shares = if self.config.embed_public_private_shares {
233+
(0..self.config.num_signers)
234+
.map(|id| (id, self.dkg_public_shares[&id].clone()))
235+
.collect()
236+
} else {
237+
Default::default()
238+
};
232239
let dkg_begin = DkgPrivateBegin {
233240
dkg_id: self.current_dkg_id,
234241
key_ids: (1..self.config.num_keys + 1).collect(),
235242
signer_ids: (0..self.config.num_signers).collect(),
243+
dkg_public_shares,
236244
};
237245
let dkg_private_begin_msg = Packet {
238246
sig: dkg_begin
@@ -251,10 +259,18 @@ impl<Aggregator: AggregatorTrait> Coordinator<Aggregator> {
251259
dkg_id = %self.current_dkg_id,
252260
"Starting DKG End Distribution"
253261
);
262+
let dkg_private_shares = if self.config.embed_public_private_shares {
263+
(0..self.config.num_signers)
264+
.map(|id| (id, self.dkg_private_shares[&id].clone()))
265+
.collect()
266+
} else {
267+
Default::default()
268+
};
254269
let dkg_begin = DkgEndBegin {
255270
dkg_id: self.current_dkg_id,
256271
key_ids: (0..self.config.num_keys).collect(),
257272
signer_ids: (0..self.config.num_signers).collect(),
273+
dkg_private_shares,
258274
};
259275
let dkg_end_begin_msg = Packet {
260276
sig: dkg_begin.sign(&self.config.message_private_key).expect(""),
@@ -787,7 +803,7 @@ impl<Aggregator: AggregatorTrait> CoordinatorTrait for Coordinator<Aggregator> {
787803

788804
#[cfg(test)]
789805
/// Test module for coordinator functionality
790-
pub mod test {
806+
mod test {
791807
use crate::{
792808
curve::scalar::Scalar,
793809
net::{DkgBegin, Message, NonceRequest, Packet, SignatureType},

0 commit comments

Comments
 (0)