Skip to content

Commit 5a27016

Browse files
authored
fix function name and ciphersuite refresh modules (#922)
* fix function name and ciphersuite refresh modules * core: add min_signers to PublicKeyPackage (#912) * core: add min_signers to PublicKeyPackage * fix JSON deserialization when min_signers is missing * fix warnings, restore wrongly commented out line
1 parent 94cef54 commit 5a27016

File tree

55 files changed

+785
-114
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+785
-114
lines changed

frost-core/CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Entries are listed in reverse chronological order.
44

5-
## Unreleases
5+
## Unreleased
66

77
### Breaking Changes
88

@@ -12,6 +12,13 @@ Entries are listed in reverse chronological order.
1212
the default behaviour is now as if `cheater-detection` was enabled. If you
1313
explicitly *did not enable* it, you can avoid cheater detection by calling
1414
`aggregate_custom()` with `CheaterDetection::Disabled`.
15+
* The `std` and `nightly` features were removed from all crates
16+
* Renamed `frost_core::keys::refresh::refresh_dkg_part_1` to `refresh_dkg_part1`.
17+
* Fixed the crate-specific versions of the `refresh` module to be non-generic.
18+
19+
### Additional changes
20+
21+
* Added DKG refresh functions to the crate-specific `refresh` modules.
1522

1623
## 2.2.0
1724

frost-core/src/keys.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,11 @@ where
381381
pub(crate) fn coefficients(&self) -> &[CoefficientCommitment<C>] {
382382
&self.0
383383
}
384+
385+
/// Return the threshold associated with this commitment.
386+
pub(crate) fn min_signers(&self) -> u16 {
387+
self.0.len() as u16
388+
}
384389
}
385390

386391
/// A secret share generated by performing a (t-out-of-n) secret sharing scheme,
@@ -563,6 +568,7 @@ pub fn split<C: Ciphersuite, R: RngCore + CryptoRng>(
563568
header: Header::default(),
564569
verifying_shares,
565570
verifying_key,
571+
min_signers: Some(min_signers),
566572
};
567573

568574
// Apply post-processing
@@ -706,7 +712,7 @@ where
706712
signing_share: secret_share.signing_share,
707713
verifying_share,
708714
verifying_key,
709-
min_signers: secret_share.commitment.0.len() as u16,
715+
min_signers: secret_share.commitment.min_signers(),
710716
})
711717
}
712718
}
@@ -716,7 +722,7 @@ where
716722
///
717723
/// Used for verification purposes before publishing a signature.
718724
#[derive(Clone, Debug, PartialEq, Eq, Getters)]
719-
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
725+
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
720726
#[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))]
721727
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
722728
pub struct PublicKeyPackage<C: Ciphersuite> {
@@ -728,6 +734,12 @@ pub struct PublicKeyPackage<C: Ciphersuite> {
728734
pub(crate) verifying_shares: BTreeMap<Identifier<C>, VerifyingShare<C>>,
729735
/// The joint public key for the entire group.
730736
pub(crate) verifying_key: VerifyingKey<C>,
737+
/// The minimum number of signers (threshold) required for the group.
738+
/// This can be None in packages created with `frost_core` prior to 3.0.0.
739+
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
740+
#[cfg_attr(feature = "serde", serde(default))]
741+
#[getter(copy)]
742+
pub(crate) min_signers: Option<u16>,
731743
}
732744

733745
impl<C> PublicKeyPackage<C>
@@ -738,11 +750,26 @@ where
738750
pub fn new(
739751
verifying_shares: BTreeMap<Identifier<C>, VerifyingShare<C>>,
740752
verifying_key: VerifyingKey<C>,
753+
min_signers: u16,
754+
) -> Self {
755+
Self::new_internal(verifying_shares, verifying_key, Some(min_signers))
756+
}
757+
758+
/// Create a new [`PublicKeyPackage`] instance, allowing not specifying the
759+
/// number of signers. This is used internally, in particular for testing
760+
/// old [`PublicKeyPackage`]s that do not encode the `min_signers`.
761+
#[cfg_attr(feature = "internals", visibility::make(pub))]
762+
#[cfg_attr(docsrs, doc(cfg(feature = "internals")))]
763+
pub(crate) fn new_internal(
764+
verifying_shares: BTreeMap<Identifier<C>, VerifyingShare<C>>,
765+
verifying_key: VerifyingKey<C>,
766+
min_signers: Option<u16>,
741767
) -> Self {
742768
Self {
743769
header: Header::default(),
744770
verifying_shares,
745771
verifying_key,
772+
min_signers,
746773
}
747774
}
748775

@@ -761,6 +788,7 @@ where
761788
Ok(PublicKeyPackage::new(
762789
verifying_keys,
763790
VerifyingKey::from_commitment(commitment)?,
791+
commitment.min_signers(),
764792
))
765793
}
766794

@@ -777,6 +805,11 @@ where
777805
let group_commitment = sum_commitments(&commitments)?;
778806
Self::from_commitment(&identifiers, &group_commitment)
779807
}
808+
809+
/// Return the maximum number of signers.
810+
pub fn max_signers(&self) -> u16 {
811+
self.verifying_shares.len() as u16
812+
}
780813
}
781814

782815
#[cfg(feature = "serialization")]

frost-core/src/keys/dkg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ pub fn part2<C: Ciphersuite>(
491491
}
492492

493493
for package in round1_packages.values() {
494-
if package.commitment.0.len() != secret_package.min_signers as usize {
494+
if package.commitment.min_signers() != secret_package.min_signers {
495495
return Err(Error::IncorrectNumberOfCommitments);
496496
}
497497
}

frost-core/src/keys/refresh.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//!
1919
//! For the DKG approach, the flow is very similar to [DKG
2020
//! itself](`https://frost.zfnd.org/tutorial/dkg.html`). Each participant calls
21-
//! [`refresh_dkg_part_1()`], keeps the returned secret package and sends the
21+
//! [`refresh_dkg_part1()`], keeps the returned secret package and sends the
2222
//! returned package to other participants. Then each participants calls
2323
//! [`refresh_dkg_part2()`] and sends the returned packages to the other
2424
//! participants. Finally each participant calls [`refresh_dkg_shares()`].
@@ -61,6 +61,14 @@ pub fn compute_refreshing_shares<C: Ciphersuite, R: RngCore + CryptoRng>(
6161
identifiers: &[Identifier<C>],
6262
rng: &mut R,
6363
) -> Result<(Vec<SecretShare<C>>, PublicKeyPackage<C>), Error<C>> {
64+
// Validate min_signers. It's OK if the min_signers is missing, because
65+
// we validate it again in `refresh_share()`.
66+
if let Some(package_min_signers) = pub_key_package.min_signers {
67+
if min_signers != package_min_signers {
68+
return Err(Error::InvalidMinSigners);
69+
}
70+
}
71+
6472
// Validate inputs
6573
if identifiers.len() != max_signers as usize {
6674
return Err(Error::IncorrectNumberOfIdentifiers);
@@ -110,6 +118,7 @@ pub fn compute_refreshing_shares<C: Ciphersuite, R: RngCore + CryptoRng>(
110118
header: pub_key_package.header,
111119
verifying_shares: refreshed_verifying_shares,
112120
verifying_key: pub_key_package.verifying_key,
121+
min_signers: Some(pub_key_package.min_signers.unwrap_or(min_signers)),
113122
};
114123

115124
Ok((refreshing_shares_minus_identity, refreshed_pub_key_package))
@@ -168,7 +177,7 @@ pub fn refresh_share<C: Ciphersuite>(
168177
/// It returns the [`round1::SecretPackage`] that must be kept in memory
169178
/// by the participant for the other steps, and the [`round1::Package`] that
170179
/// must be sent to each other participant in the refresh run.
171-
pub fn refresh_dkg_part_1<C: Ciphersuite, R: RngCore + CryptoRng>(
180+
pub fn refresh_dkg_part1<C: Ciphersuite, R: RngCore + CryptoRng>(
172181
identifier: Identifier<C>,
173182
max_signers: u16,
174183
min_signers: u16,
@@ -460,6 +469,7 @@ pub fn refresh_dkg_shares<C: Ciphersuite>(
460469
header: old_pub_key_package.header,
461470
verifying_shares: new_verifying_shares,
462471
verifying_key: old_pub_key_package.verifying_key,
472+
min_signers: Some(round2_secret_package.min_signers),
463473
};
464474

465475
let key_package = KeyPackage {

frost-core/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,15 @@ pub fn verify_signature_share<C: Ciphersuite>(
758758
// In order to reuse `pre_aggregate()`, we need to create some "dummy" containers
759759
let signature_shares = BTreeMap::from([(identifier, *signature_share)]);
760760
let verifying_shares = BTreeMap::from([(identifier, *verifying_share)]);
761-
let public_key_package = PublicKeyPackage::new(verifying_shares, *verifying_key);
761+
let public_key_package = PublicKeyPackage {
762+
verifying_shares,
763+
verifying_key: *verifying_key,
764+
// Use None since we don't have the min_signers value here. This
765+
// can only cause problems if the `pre_aggregate` function relies on it.
766+
// This has been documented in `pre_aggregate()`.
767+
min_signers: None,
768+
header: Header::default(),
769+
};
762770

763771
let (signing_package, signature_shares, pubkeys) =
764772
<C>::pre_aggregate(signing_package, &signature_shares, &public_key_package)?;

0 commit comments

Comments
 (0)