Skip to content

Commit 8f60e6d

Browse files
authored
core: add more serialization roundtrips to tests (#952)
1 parent 5a27016 commit 8f60e6d

File tree

2 files changed

+106
-11
lines changed

2 files changed

+106
-11
lines changed

frost-core/src/tests/ciphersuite_generic.rs

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use rand_core::{CryptoRng, RngCore};
66

77
use crate as frost;
88
use crate::keys::dkg::{round1, round2};
9-
use crate::keys::SigningShare;
9+
use crate::keys::{SecretShare, SigningShare};
10+
use crate::round1::SigningNonces;
1011
use crate::round2::SignatureShare;
1112
use crate::{
1213
keys::PublicKeyPackage, Error, Field, Group, Identifier, Signature, SigningKey, SigningPackage,
@@ -26,6 +27,8 @@ pub fn check_zero_key_fails<C: Ciphersuite>() {
2627
/// Test share generation with a Ciphersuite
2728
pub fn check_share_generation<C: Ciphersuite, R: RngCore + CryptoRng>(mut rng: R) {
2829
let secret = crate::SigningKey::<C>::new(&mut rng);
30+
// Simulate serialization / deserialization to ensure it works
31+
let secret = SigningKey::deserialize(&secret.serialize()).unwrap();
2932

3033
let max_signers = 5;
3134
let min_signers = 3;
@@ -110,20 +113,30 @@ pub fn check_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
110113

111114
let max_signers = 5;
112115
let min_signers = 3;
113-
let (shares, pubkeys) = frost::keys::generate_with_dealer(
116+
let (shares, pub_key_package) = frost::keys::generate_with_dealer(
114117
max_signers,
115118
min_signers,
116119
frost::keys::IdentifierList::Default,
117120
&mut rng,
118121
)
119122
.unwrap();
123+
// Simulate serialization / deserialization to ensure it works
124+
let pub_key_package =
125+
PublicKeyPackage::deserialize(&pub_key_package.serialize().unwrap()).unwrap();
120126

121127
// Verifies the secret shares from the dealer
122-
let key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> = shares
123-
.into_iter()
124-
.map(|(k, v)| (k, frost::keys::KeyPackage::try_from(v).unwrap()))
125-
.collect();
128+
let mut key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
129+
BTreeMap::new();
126130

131+
for (k, v) in shares {
132+
// Simulate serialization / deserialization to ensure it works
133+
let v = SecretShare::<C>::deserialize(&v.serialize().unwrap()).unwrap();
134+
let key_package = frost::keys::KeyPackage::try_from(v).unwrap();
135+
// Simulate serialization / deserialization to ensure it works
136+
let key_package =
137+
frost::keys::KeyPackage::deserialize(&key_package.serialize().unwrap()).unwrap();
138+
key_packages.insert(k, key_package);
139+
}
127140
// Check if it fails with not enough signers. Usually this would return an
128141
// error before even running the signing procedure, because `KeyPackage`
129142
// contains the correct `min_signers` value and the signing procedure checks
@@ -144,11 +157,11 @@ pub fn check_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
144157
})
145158
.collect(),
146159
&mut rng,
147-
pubkeys.clone(),
160+
pub_key_package.clone(),
148161
);
149162
assert_eq!(r, Err(Error::InvalidSignature));
150163

151-
check_sign(min_signers, key_packages, rng, pubkeys).unwrap()
164+
check_sign(min_signers, key_packages, rng, pub_key_package).unwrap()
152165
}
153166

154167
/// Test FROST signing with trusted dealer fails with invalid numbers of signers.
@@ -203,7 +216,10 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
203216
// Round 1: generating nonces and signing commitments for each participant
204217
////////////////////////////////////////////////////////////////////////////
205218

206-
for participant_identifier in key_packages.keys().take(min_signers as usize).cloned() {
219+
for participant_identifier in key_packages.keys().take(min_signers as usize) {
220+
// Simulate serialization / deserialization to ensure it works
221+
let participant_identifier =
222+
Identifier::deserialize(&participant_identifier.serialize()).unwrap();
207223
// Generate one (1) nonce and one SigningCommitments instance for each
208224
// participant, up to _min_signers_.
209225
let (nonces, commitments) = frost::round1::commit(
@@ -213,6 +229,11 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
213229
.signing_share(),
214230
&mut rng,
215231
);
232+
// Simulate serialization / deserialization to ensure it works
233+
let nonces = SigningNonces::deserialize(&nonces.serialize().unwrap()).unwrap();
234+
let commitments =
235+
frost::round1::SigningCommitments::deserialize(&commitments.serialize().unwrap())
236+
.unwrap();
216237
nonces_map.insert(participant_identifier, nonces);
217238
commitments_map.insert(participant_identifier, commitments);
218239
}
@@ -223,6 +244,9 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
223244
let mut signature_shares = BTreeMap::new();
224245
let message = "message to sign".as_bytes();
225246
let signing_package = SigningPackage::new(commitments_map, message);
247+
// Simulate serialization / deserialization to ensure it works
248+
let signing_package =
249+
SigningPackage::deserialize(&signing_package.serialize().unwrap()).unwrap();
226250

227251
////////////////////////////////////////////////////////////////////////////
228252
// Round 2: each participant generates their signature share
@@ -241,6 +265,8 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
241265

242266
// Each participant generates their signature share.
243267
let signature_share = frost::round2::sign(&signing_package, nonces_to_use, key_package)?;
268+
// Simulate serialization / deserialization to ensure it works
269+
let signature_share = SignatureShare::deserialize(&signature_share.serialize()).unwrap();
244270
signature_shares.insert(*participant_identifier, signature_share);
245271
}
246272

@@ -265,6 +291,8 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
265291

266292
// Aggregate (also verifies the signature shares)
267293
let group_signature = frost::aggregate(&signing_package, &signature_shares, &pubkey_package)?;
294+
// Simulate serialization / deserialization to ensure it works
295+
let group_signature = Signature::deserialize(&group_signature.serialize().unwrap()).unwrap();
268296

269297
// Check that the threshold signature can be verified by the group public
270298
// key (the verification key).
@@ -451,6 +479,16 @@ where
451479
frost::keys::dkg::part1(participant_identifier, max_signers, min_signers, &mut rng)
452480
.unwrap();
453481

482+
// Simulate serialization / deserialization to ensure it works
483+
let round1_secret_package = frost::keys::dkg::round1::SecretPackage::<C>::deserialize(
484+
&round1_secret_package.serialize().unwrap(),
485+
)
486+
.unwrap();
487+
let round1_package = frost::keys::dkg::round1::Package::<C>::deserialize(
488+
&round1_package.serialize().unwrap(),
489+
)
490+
.unwrap();
491+
454492
// Store the participant's secret package for later use.
455493
// In practice each participant will store it in their own environment.
456494
round1_secret_packages.insert(
@@ -507,6 +545,12 @@ where
507545
let (round2_secret_package, round2_packages) =
508546
frost::keys::dkg::part2(round1_secret_package, round1_packages).expect("should work");
509547

548+
// Simulate serialization / deserialization to ensure it works
549+
let round2_secret_package = frost::keys::dkg::round2::SecretPackage::<C>::deserialize(
550+
&round2_secret_package.serialize().unwrap(),
551+
)
552+
.unwrap();
553+
510554
// Store the participant's secret package for later use.
511555
// In practice each participant will store it in their own environment.
512556
round2_secret_packages.insert(
@@ -522,6 +566,11 @@ where
522566
// Note that, in contrast to the previous part, here each other participant
523567
// gets its own specific package.
524568
for (receiver_identifier, round2_package) in round2_packages {
569+
// Simulate serialization / deserialization to ensure it works
570+
let round2_package = frost::keys::dkg::round2::Package::<C>::deserialize(
571+
&round2_package.serialize().unwrap(),
572+
)
573+
.unwrap();
525574
received_round2_packages
526575
.entry(receiver_identifier)
527576
.or_insert_with(BTreeMap::new)
@@ -572,6 +621,13 @@ where
572621
&received_round2_packages[&participant_identifier],
573622
)
574623
.unwrap();
624+
// Simulate serialization / deserialization to ensure it works
625+
let key_package =
626+
frost::keys::KeyPackage::deserialize(&key_package.serialize().unwrap()).unwrap();
627+
let pubkey_package_for_participant = frost::keys::PublicKeyPackage::deserialize(
628+
&pubkey_package_for_participant.serialize().unwrap(),
629+
)
630+
.unwrap();
575631
verifying_shares.insert(participant_identifier, key_package.verifying_share);
576632
// Test if all verifying_key are equal
577633
if let Some(previous_verifying_key) = verifying_key {
@@ -593,6 +649,9 @@ where
593649
.unwrap()
594650
.1
595651
.clone();
652+
// Simulate serialization / deserialization to ensure it works
653+
let pubkeys =
654+
frost::keys::PublicKeyPackage::deserialize(&pubkeys.serialize().unwrap()).unwrap();
596655

597656
// Proceed with the signing test.
598657
check_sign(min_signers, key_packages, rng, pubkeys).unwrap()

frost-core/src/tests/refresh.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ pub fn check_refresh_shares_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
6969
&mut rng,
7070
)
7171
.unwrap();
72+
// Simulate serialization / deserialization to ensure it works
73+
let new_pub_key_package =
74+
frost::keys::PublicKeyPackage::deserialize(&new_pub_key_package.serialize().unwrap())
75+
.unwrap();
7276

7377
// Each participant refreshes their share
7478

@@ -79,14 +83,16 @@ pub fn check_refresh_shares_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
7983
let current_share = &old_key_packages[&identifier];
8084
// Do a serialization roundtrip to simulate real usage
8185
let zero_share = SecretShare::deserialize(&zero_shares[i].serialize().unwrap()).unwrap();
82-
let new_share = refresh_share(zero_share, current_share);
86+
let new_share = refresh_share(zero_share, current_share).unwrap();
8387
new_shares.insert(identifier, new_share);
8488
}
8589

8690
let mut key_packages: BTreeMap<frost::Identifier<C>, KeyPackage<C>> = BTreeMap::new();
8791

8892
for (k, v) in new_shares {
89-
key_packages.insert(k, v.unwrap());
93+
// Simulate serialization / deserialization to ensure it works
94+
let v = KeyPackage::<C>::deserialize(&v.serialize().unwrap()).unwrap();
95+
key_packages.insert(k, v);
9096
}
9197
check_sign(MIN_SIGNERS, key_packages, rng, new_pub_key_package).unwrap();
9298
}
@@ -371,6 +377,16 @@ where
371377
let (round1_secret_package, round1_package) =
372378
refresh_dkg_part1(participant_identifier, max_signers, min_signers, &mut rng).unwrap();
373379

380+
// Simulate serialization / deserialization to ensure it works
381+
let round1_secret_package = frost::keys::dkg::round1::SecretPackage::<C>::deserialize(
382+
&round1_secret_package.serialize().unwrap(),
383+
)
384+
.unwrap();
385+
let round1_package = frost::keys::dkg::round1::Package::<C>::deserialize(
386+
&round1_package.serialize().unwrap(),
387+
)
388+
.unwrap();
389+
374390
// Store the participant's secret package for later use.
375391
// In practice each participant will store it in their own environment.
376392
round1_secret_packages.insert(
@@ -421,6 +437,12 @@ where
421437
let (round2_secret_package, round2_packages) =
422438
refresh_dkg_part2(round1_secret_package, round1_packages).expect("should work");
423439

440+
// Simulate serialization / deserialization to ensure it works
441+
let round2_secret_package = frost::keys::dkg::round2::SecretPackage::<C>::deserialize(
442+
&round2_secret_package.serialize().unwrap(),
443+
)
444+
.unwrap();
445+
424446
// Store the participant's secret package for later use.
425447
// In practice each participant will store it in their own environment.
426448
round2_secret_packages.insert(
@@ -436,6 +458,11 @@ where
436458
// Note that, in contrast to the previous part, here each other participant
437459
// gets its own specific package.
438460
for (receiver_identifier, round2_package) in round2_packages {
461+
// Simulate serialization / deserialization to ensure it works
462+
let round2_package = frost::keys::dkg::round2::Package::<C>::deserialize(
463+
&round2_package.serialize().unwrap(),
464+
)
465+
.unwrap();
439466
received_round2_packages
440467
.entry(receiver_identifier)
441468
.or_insert_with(BTreeMap::new)
@@ -488,6 +515,12 @@ where
488515
old_key_packages[&participant_identifier].clone(),
489516
)
490517
.unwrap();
518+
// Simulate serialization / deserialization to ensure it works
519+
let key_package = KeyPackage::deserialize(&key_package.serialize().unwrap()).unwrap();
520+
let pubkey_package_for_participant = frost::keys::PublicKeyPackage::deserialize(
521+
&pubkey_package_for_participant.serialize().unwrap(),
522+
)
523+
.unwrap();
491524
verifying_shares.insert(participant_identifier, key_package.verifying_share);
492525
// Test if all verifying_key are equal
493526
if let Some(previous_verifying_key) = verifying_key {
@@ -509,6 +542,9 @@ where
509542
.unwrap()
510543
.1
511544
.clone();
545+
// Simulate serialization / deserialization to ensure it works
546+
let pubkeys =
547+
frost::keys::PublicKeyPackage::deserialize(&pubkeys.serialize().unwrap()).unwrap();
512548

513549
// Proceed with the signing test.
514550
check_sign(min_signers, key_packages, rng, pubkeys).unwrap()

0 commit comments

Comments
 (0)