Skip to content

Commit 1183783

Browse files
authored
Merge of #106
2 parents 6de0e09 + 7607139 commit 1183783

File tree

11 files changed

+131
-80
lines changed

11 files changed

+131
-80
lines changed

frost-core/README.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,3 @@ scratch. End-users should not use `frost-core` if they want to sign and verify s
1717
should use the crate specific to their ciphersuite/curve parameters that uses `frost-core` as a
1818
dependency, such as `frost-ristretto255`.
1919

20-
## Example
21-
22-
```rust
23-
24-
```
25-
26-

frost-core/src/frost/keys.rs

Lines changed: 107 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,26 @@ use zeroize::{DefaultIsZeroes, Zeroize};
1313

1414
use crate::{frost::Identifier, Ciphersuite, Error, Field, Group, Scalar, VerifyingKey};
1515

16-
/// A secret scalar value representing a signer's secret key.
16+
/// A group secret to be split between participants.
17+
///
18+
/// This is similar to a [`crate::SigningKey`], but this secret is not intended to be used
19+
/// on its own for signing, but split into shares that a threshold number of signers will use to
20+
/// sign.
1721
#[derive(Clone, Copy, PartialEq, Eq)]
18-
pub struct Secret<C: Ciphersuite>(pub(crate) Scalar<C>);
22+
pub struct SharedSecret<C: Ciphersuite>(pub(crate) Scalar<C>);
1923

20-
impl<C> Secret<C>
24+
impl<C> SharedSecret<C>
2125
where
2226
C: Ciphersuite,
2327
{
24-
/// Deserialize [`Secret`] from bytes
28+
/// Deserialize from bytes
2529
pub fn from_bytes(
2630
bytes: <<C::Group as Group>::Field as Field>::Serialization,
2731
) -> Result<Self, Error> {
2832
<<C::Group as Group>::Field as Field>::deserialize(&bytes).map(|scalar| Self(scalar))
2933
}
3034

31-
/// Serialize [`Secret`] to bytes
35+
/// Serialize to bytes
3236
pub fn to_bytes(&self) -> <<C::Group as Group>::Field as Field>::Serialization {
3337
<<C::Group as Group>::Field as Field>::serialize(&self.0)
3438
}
@@ -45,18 +49,18 @@ where
4549
}
4650
}
4751

48-
impl<C> Debug for Secret<C>
52+
impl<C> Debug for SharedSecret<C>
4953
where
5054
C: Ciphersuite,
5155
{
5256
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
53-
f.debug_tuple("Secret")
57+
f.debug_tuple("SharedSecret")
5458
.field(&hex::encode(self.to_bytes()))
5559
.finish()
5660
}
5761
}
5862

59-
impl<C> Default for Secret<C>
63+
impl<C> Default for SharedSecret<C>
6064
where
6165
C: Ciphersuite,
6266
{
@@ -66,29 +70,79 @@ where
6670
}
6771

6872
// Implements [`Zeroize`] by overwriting a value with the [`Default::default()`] value
69-
impl<C> DefaultIsZeroes for Secret<C> where C: Ciphersuite {}
70-
71-
// impl<C> Drop for Secret<C>
72-
// where
73-
// C: Ciphersuite,
74-
// {
75-
// fn drop(&mut self) {
76-
// self.zeroize()
77-
// }
78-
// }
79-
80-
impl<C> From<&Secret<C>> for VerifyingKey<C>
73+
impl<C> DefaultIsZeroes for SharedSecret<C> where C: Ciphersuite {}
74+
75+
impl<C> From<&SharedSecret<C>> for VerifyingKey<C>
8176
where
8277
C: Ciphersuite,
8378
{
84-
fn from(secret: &Secret<C>) -> Self {
79+
fn from(secret: &SharedSecret<C>) -> Self {
8580
let element = <C::Group as Group>::generator() * secret.0;
8681

8782
VerifyingKey { element }
8883
}
8984
}
9085

91-
impl<C> FromHex for Secret<C>
86+
impl<C> FromHex for SharedSecret<C>
87+
where
88+
C: Ciphersuite,
89+
{
90+
type Error = &'static str;
91+
92+
fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
93+
let v: Vec<u8> = FromHex::from_hex(hex).map_err(|_| "invalid hex")?;
94+
match v.try_into() {
95+
Ok(bytes) => Self::from_bytes(bytes).map_err(|_| "malformed secret encoding"),
96+
Err(_) => Err("malformed secret encoding"),
97+
}
98+
}
99+
}
100+
101+
/// A secret scalar value representing a signer's share of the group secret.
102+
#[derive(Clone, Copy, PartialEq, Eq)]
103+
pub struct SigningShare<C: Ciphersuite>(pub(crate) Scalar<C>);
104+
105+
impl<C> SigningShare<C>
106+
where
107+
C: Ciphersuite,
108+
{
109+
/// Deserialize from bytes
110+
pub fn from_bytes(
111+
bytes: <<C::Group as Group>::Field as Field>::Serialization,
112+
) -> Result<Self, Error> {
113+
<<C::Group as Group>::Field as Field>::deserialize(&bytes).map(|scalar| Self(scalar))
114+
}
115+
116+
/// Serialize to bytes
117+
pub fn to_bytes(&self) -> <<C::Group as Group>::Field as Field>::Serialization {
118+
<<C::Group as Group>::Field as Field>::serialize(&self.0)
119+
}
120+
}
121+
122+
impl<C> Debug for SigningShare<C>
123+
where
124+
C: Ciphersuite,
125+
{
126+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
127+
f.debug_tuple("SigningShare")
128+
.field(&hex::encode(self.to_bytes()))
129+
.finish()
130+
}
131+
}
132+
133+
impl<C> Default for SigningShare<C>
134+
where
135+
C: Ciphersuite,
136+
{
137+
fn default() -> Self {
138+
Self(<<C::Group as Group>::Field as Field>::zero())
139+
}
140+
}
141+
142+
// Implements [`Zeroize`] by overwriting a value with the [`Default::default()`] value
143+
impl<C> DefaultIsZeroes for SigningShare<C> where C: Ciphersuite {}
144+
145+
impl<C> FromHex for SigningShare<C>
92146
where
93147
C: Ciphersuite,
94148
{
@@ -103,13 +157,13 @@ where
103157
}
104158
}
105159

106-
/// A public group element that represents a single signer's public key.
160+
/// A public group element that represents a single signer's public verification share.
107161
#[derive(Copy, Clone, PartialEq, Eq)]
108-
pub struct Public<C>(pub(super) <C::Group as Group>::Element)
162+
pub struct VerifyingShare<C>(pub(super) <C::Group as Group>::Element)
109163
where
110164
C: Ciphersuite;
111165

112-
impl<C> Public<C>
166+
impl<C> VerifyingShare<C>
113167
where
114168
C: Ciphersuite,
115169
{
@@ -118,33 +172,33 @@ where
118172
<C::Group as Group>::deserialize(&bytes).map(|element| Self(element))
119173
}
120174

121-
/// Serialize [`Public`] to bytes
175+
/// Serialize to bytes
122176
pub fn to_bytes(&self) -> <C::Group as Group>::Serialization {
123177
<C::Group as Group>::serialize(&self.0)
124178
}
125179
}
126180

127-
impl<C> Debug for Public<C>
181+
impl<C> Debug for VerifyingShare<C>
128182
where
129183
C: Ciphersuite,
130184
{
131185
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
132-
f.debug_tuple("Public")
186+
f.debug_tuple("VerifyingShare")
133187
.field(&hex::encode(self.to_bytes()))
134188
.finish()
135189
}
136190
}
137191

138-
impl<C> From<Secret<C>> for Public<C>
192+
impl<C> From<SigningShare<C>> for VerifyingShare<C>
139193
where
140194
C: Ciphersuite,
141195
{
142-
fn from(secret: Secret<C>) -> Public<C> {
143-
Public(<C::Group as Group>::generator() * secret.0 as Scalar<C>)
196+
fn from(secret: SigningShare<C>) -> VerifyingShare<C> {
197+
VerifyingShare(<C::Group as Group>::generator() * secret.0 as Scalar<C>)
144198
}
145199
}
146200

147-
/// A [`Group::Element`] that is a commitment to one coefficient of our secret polynomial.
201+
/// A [`Group::Element`] newtype that is a commitment to one coefficient of our secret polynomial.
148202
///
149203
/// This is a (public) commitment to one coefficient of a secret polynomial used for performing
150204
/// verifiable secret sharing for a Shamir secret share.
@@ -180,7 +234,7 @@ pub struct SecretShare<C: Ciphersuite> {
180234
/// The participant identifier of this [`SecretShare`].
181235
pub identifier: Identifier<C>,
182236
/// Secret Key.
183-
pub value: Secret<C>,
237+
pub value: SigningShare<C>,
184238
/// The commitments to be distributed among signers.
185239
pub commitment: VerifiableSecretSharingCommitment<C>,
186240
}
@@ -189,8 +243,8 @@ impl<C> SecretShare<C>
189243
where
190244
C: Ciphersuite,
191245
{
192-
/// Gets the inner [`Secret`] share value.
193-
pub fn secret(&self) -> &Secret<C> {
246+
/// Gets the inner [`SigningShare`] value.
247+
pub fn secret(&self) -> &SigningShare<C> {
194248
&self.value
195249
}
196250

@@ -237,8 +291,8 @@ pub struct SharePackage<C: Ciphersuite> {
237291
/// This participant's secret share.
238292
pub secret_share: SecretShare<C>,
239293
/// This participant's public key.
240-
pub public: Public<C>,
241-
/// The public signing key that represents the entire group.
294+
pub public: VerifyingShare<C>,
295+
/// The public verifying key that represents the entire group.
242296
pub group_public: VerifyingKey<C>,
243297
}
244298

@@ -262,11 +316,11 @@ pub fn keygen_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
262316
let mut bytes = [0; 64];
263317
rng.fill_bytes(&mut bytes);
264318

265-
let secret = Secret::random(&mut rng);
319+
let secret = SharedSecret::random(&mut rng);
266320
let group_public = VerifyingKey::from(&secret);
267321
let secret_shares = generate_secret_shares(&secret, num_signers, threshold, rng)?;
268322
let mut share_packages: Vec<SharePackage<C>> = Vec::with_capacity(num_signers as usize);
269-
let mut signer_pubkeys: HashMap<Identifier<C>, Public<C>> =
323+
let mut signer_pubkeys: HashMap<Identifier<C>, VerifyingShare<C>> =
270324
HashMap::with_capacity(num_signers as usize);
271325

272326
for secret_share in secret_shares {
@@ -302,9 +356,9 @@ pub struct KeyPackage<C: Ciphersuite> {
302356
/// Denotes the participant identifier each secret share key package is owned by.
303357
pub identifier: Identifier<C>,
304358
/// This participant's secret share.
305-
pub secret_share: Secret<C>,
359+
pub secret_share: SigningShare<C>,
306360
/// This participant's public key.
307-
pub public: Public<C>,
361+
pub public: VerifyingShare<C>,
308362
/// The public signing key that represents the entire group.
309363
pub group_public: VerifyingKey<C>,
310364
}
@@ -318,13 +372,13 @@ where
318372
&self.identifier
319373
}
320374

321-
/// Gets the participant's [`Secret`] share associated with this [`KeyPackage`].
322-
pub fn secret_share(&self) -> &Secret<C> {
375+
/// Gets the participant's [`SigningShare`] associated with this [`KeyPackage`].
376+
pub fn secret_share(&self) -> &SigningShare<C> {
323377
&self.secret_share
324378
}
325379

326-
/// Gets the participant's [`Public`] key associated with this [`Secret`] share in this [`KeyPackage`].
327-
pub fn public(&self) -> &Public<C> {
380+
/// Gets the participant's [`VerifyingShare`] associated with the [`SigningShare`] in this [`KeyPackage`].
381+
pub fn public(&self) -> &VerifyingShare<C> {
328382
&self.public
329383
}
330384

@@ -369,7 +423,7 @@ pub struct PublicKeyPackage<C: Ciphersuite> {
369423
/// correct view of participants' public keys to perform verification before
370424
/// publishing a signature. `signer_pubkeys` represents all signers for a
371425
/// signing operation.
372-
pub signer_pubkeys: HashMap<Identifier<C>, Public<C>>,
426+
pub signer_pubkeys: HashMap<Identifier<C>, VerifyingShare<C>>,
373427
/// The joint public key for the entire group.
374428
pub group_public: VerifyingKey<C>,
375429
}
@@ -394,7 +448,7 @@ pub struct PublicKeyPackage<C: Ciphersuite> {
394448
///
395449
/// [`secret_key_shard`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-03.html#appendix-B.1
396450
pub fn generate_secret_shares<C: Ciphersuite, R: RngCore + CryptoRng>(
397-
secret: &Secret<C>,
451+
secret: &SharedSecret<C>,
398452
numshares: u8,
399453
threshold: u8,
400454
mut rng: R,
@@ -456,7 +510,7 @@ pub fn generate_secret_shares<C: Ciphersuite, R: RngCore + CryptoRng>(
456510

457511
secret_shares.push(SecretShare {
458512
identifier: id,
459-
value: Secret(value),
513+
value: SigningShare(value),
460514
commitment: commitment.clone(),
461515
});
462516
}
@@ -467,7 +521,7 @@ pub fn generate_secret_shares<C: Ciphersuite, R: RngCore + CryptoRng>(
467521
/// Recompute the secret from t-of-n secret shares using Lagrange interpolation.
468522
pub fn reconstruct_secret<C: Ciphersuite>(
469523
secret_shares: Vec<SecretShare<C>>,
470-
) -> Result<Secret<C>, &'static str> {
524+
) -> Result<SharedSecret<C>, &'static str> {
471525
if secret_shares.is_empty() {
472526
return Err("No secret_shares provided");
473527
}
@@ -512,5 +566,8 @@ pub fn reconstruct_secret<C: Ciphersuite>(
512566
secret = secret + (lagrange_coefficient * secret_share.value.0);
513567
}
514568

515-
Ok(Secret::from_bytes(<<C::Group as Group>::Field as Field>::serialize(&secret)).unwrap())
569+
Ok(
570+
SharedSecret::from_bytes(<<C::Group as Group>::Field as Field>::serialize(&secret))
571+
.unwrap(),
572+
)
516573
}

frost-core/src/frost/round1.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use zeroize::Zeroize;
88

99
use crate::{frost, Ciphersuite, Error, Field, Group};
1010

11-
use super::{keys::Secret, Identifier};
11+
use super::{keys::SigningShare, Identifier};
1212

1313
/// A scalar that is a signing nonce.
1414
#[derive(Clone, PartialEq, Eq, Zeroize)]
@@ -18,17 +18,16 @@ impl<C> Nonce<C>
1818
where
1919
C: Ciphersuite,
2020
{
21-
/// Generates a new uniformly random signing nonce by sourcing fresh
22-
/// randomness and combining with the secret key, to hedge against a bad
23-
/// RNG.
21+
/// Generates a new uniformly random signing nonce by sourcing fresh randomness and combining
22+
/// with the secret signing share, to hedge against a bad RNG.
2423
///
2524
/// Each participant generates signing nonces before performing a signing
2625
/// operation.
2726
///
2827
/// An implementation of `nonce_generate(secret)` from the [spec].
2928
///
3029
/// [spec]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-05.html#name-nonce-generation
31-
pub fn new<R>(secret: &Secret<C>, rng: &mut R) -> Self
30+
pub fn new<R>(secret: &SigningShare<C>, rng: &mut R) -> Self
3231
where
3332
R: CryptoRng + RngCore,
3433
{
@@ -167,7 +166,7 @@ where
167166
///
168167
/// Each participant generates signing nonces before performing a signing
169168
/// operation.
170-
pub fn new<R>(secret: &Secret<C>, rng: &mut R) -> Self
169+
pub fn new<R>(secret: &SigningShare<C>, rng: &mut R) -> Self
171170
where
172171
R: CryptoRng + RngCore,
173172
{
@@ -301,7 +300,7 @@ pub(super) fn encode_group_commitments<C: Ciphersuite>(
301300
pub fn preprocess<C, R>(
302301
num_nonces: u8,
303302
participant_identifier: Identifier<C>,
304-
secret: &Secret<C>,
303+
secret: &SigningShare<C>,
305304
rng: &mut R,
306305
) -> (Vec<SigningNonces<C>>, Vec<SigningCommitments<C>>)
307306
where
@@ -331,7 +330,7 @@ where
331330
/// [`commit`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-05.html#section-5.1
332331
pub fn commit<C, R>(
333332
participant_identifier: Identifier<C>,
334-
secret: &Secret<C>,
333+
secret: &SigningShare<C>,
335334
rng: &mut R,
336335
) -> (SigningNonces<C>, SigningCommitments<C>)
337336
where

0 commit comments

Comments
 (0)