@@ -13,22 +13,26 @@ use zeroize::{DefaultIsZeroes, Zeroize};
13
13
14
14
use crate :: { frost:: Identifier , Ciphersuite , Error , Field , Group , Scalar , VerifyingKey } ;
15
15
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.
17
21
#[ 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 > ) ;
19
23
20
- impl < C > Secret < C >
24
+ impl < C > SharedSecret < C >
21
25
where
22
26
C : Ciphersuite ,
23
27
{
24
- /// Deserialize [`Secret`] from bytes
28
+ /// Deserialize from bytes
25
29
pub fn from_bytes (
26
30
bytes : <<C :: Group as Group >:: Field as Field >:: Serialization ,
27
31
) -> Result < Self , Error > {
28
32
<<C :: Group as Group >:: Field as Field >:: deserialize ( & bytes) . map ( |scalar| Self ( scalar) )
29
33
}
30
34
31
- /// Serialize [`Secret`] to bytes
35
+ /// Serialize to bytes
32
36
pub fn to_bytes ( & self ) -> <<C :: Group as Group >:: Field as Field >:: Serialization {
33
37
<<C :: Group as Group >:: Field as Field >:: serialize ( & self . 0 )
34
38
}
@@ -45,18 +49,18 @@ where
45
49
}
46
50
}
47
51
48
- impl < C > Debug for Secret < C >
52
+ impl < C > Debug for SharedSecret < C >
49
53
where
50
54
C : Ciphersuite ,
51
55
{
52
56
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
53
- f. debug_tuple ( "Secret " )
57
+ f. debug_tuple ( "SharedSecret " )
54
58
. field ( & hex:: encode ( self . to_bytes ( ) ) )
55
59
. finish ( )
56
60
}
57
61
}
58
62
59
- impl < C > Default for Secret < C >
63
+ impl < C > Default for SharedSecret < C >
60
64
where
61
65
C : Ciphersuite ,
62
66
{
@@ -66,29 +70,79 @@ where
66
70
}
67
71
68
72
// 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 >
81
76
where
82
77
C : Ciphersuite ,
83
78
{
84
- fn from ( secret : & Secret < C > ) -> Self {
79
+ fn from ( secret : & SharedSecret < C > ) -> Self {
85
80
let element = <C :: Group as Group >:: generator ( ) * secret. 0 ;
86
81
87
82
VerifyingKey { element }
88
83
}
89
84
}
90
85
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 >
92
146
where
93
147
C : Ciphersuite ,
94
148
{
@@ -103,13 +157,13 @@ where
103
157
}
104
158
}
105
159
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 .
107
161
#[ 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 )
109
163
where
110
164
C : Ciphersuite ;
111
165
112
- impl < C > Public < C >
166
+ impl < C > VerifyingShare < C >
113
167
where
114
168
C : Ciphersuite ,
115
169
{
@@ -118,33 +172,33 @@ where
118
172
<C :: Group as Group >:: deserialize ( & bytes) . map ( |element| Self ( element) )
119
173
}
120
174
121
- /// Serialize [`Public`] to bytes
175
+ /// Serialize to bytes
122
176
pub fn to_bytes ( & self ) -> <C :: Group as Group >:: Serialization {
123
177
<C :: Group as Group >:: serialize ( & self . 0 )
124
178
}
125
179
}
126
180
127
- impl < C > Debug for Public < C >
181
+ impl < C > Debug for VerifyingShare < C >
128
182
where
129
183
C : Ciphersuite ,
130
184
{
131
185
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
132
- f. debug_tuple ( "Public " )
186
+ f. debug_tuple ( "VerifyingShare " )
133
187
. field ( & hex:: encode ( self . to_bytes ( ) ) )
134
188
. finish ( )
135
189
}
136
190
}
137
191
138
- impl < C > From < Secret < C > > for Public < C >
192
+ impl < C > From < SigningShare < C > > for VerifyingShare < C >
139
193
where
140
194
C : Ciphersuite ,
141
195
{
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 > )
144
198
}
145
199
}
146
200
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.
148
202
///
149
203
/// This is a (public) commitment to one coefficient of a secret polynomial used for performing
150
204
/// verifiable secret sharing for a Shamir secret share.
@@ -180,7 +234,7 @@ pub struct SecretShare<C: Ciphersuite> {
180
234
/// The participant identifier of this [`SecretShare`].
181
235
pub identifier : Identifier < C > ,
182
236
/// Secret Key.
183
- pub value : Secret < C > ,
237
+ pub value : SigningShare < C > ,
184
238
/// The commitments to be distributed among signers.
185
239
pub commitment : VerifiableSecretSharingCommitment < C > ,
186
240
}
@@ -189,8 +243,8 @@ impl<C> SecretShare<C>
189
243
where
190
244
C : Ciphersuite ,
191
245
{
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 > {
194
248
& self . value
195
249
}
196
250
@@ -237,8 +291,8 @@ pub struct SharePackage<C: Ciphersuite> {
237
291
/// This participant's secret share.
238
292
pub secret_share : SecretShare < C > ,
239
293
/// 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.
242
296
pub group_public : VerifyingKey < C > ,
243
297
}
244
298
@@ -262,11 +316,11 @@ pub fn keygen_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
262
316
let mut bytes = [ 0 ; 64 ] ;
263
317
rng. fill_bytes ( & mut bytes) ;
264
318
265
- let secret = Secret :: random ( & mut rng) ;
319
+ let secret = SharedSecret :: random ( & mut rng) ;
266
320
let group_public = VerifyingKey :: from ( & secret) ;
267
321
let secret_shares = generate_secret_shares ( & secret, num_signers, threshold, rng) ?;
268
322
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 > > =
270
324
HashMap :: with_capacity ( num_signers as usize ) ;
271
325
272
326
for secret_share in secret_shares {
@@ -302,9 +356,9 @@ pub struct KeyPackage<C: Ciphersuite> {
302
356
/// Denotes the participant identifier each secret share key package is owned by.
303
357
pub identifier : Identifier < C > ,
304
358
/// This participant's secret share.
305
- pub secret_share : Secret < C > ,
359
+ pub secret_share : SigningShare < C > ,
306
360
/// This participant's public key.
307
- pub public : Public < C > ,
361
+ pub public : VerifyingShare < C > ,
308
362
/// The public signing key that represents the entire group.
309
363
pub group_public : VerifyingKey < C > ,
310
364
}
@@ -318,13 +372,13 @@ where
318
372
& self . identifier
319
373
}
320
374
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 > {
323
377
& self . secret_share
324
378
}
325
379
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 > {
328
382
& self . public
329
383
}
330
384
@@ -369,7 +423,7 @@ pub struct PublicKeyPackage<C: Ciphersuite> {
369
423
/// correct view of participants' public keys to perform verification before
370
424
/// publishing a signature. `signer_pubkeys` represents all signers for a
371
425
/// signing operation.
372
- pub signer_pubkeys : HashMap < Identifier < C > , Public < C > > ,
426
+ pub signer_pubkeys : HashMap < Identifier < C > , VerifyingShare < C > > ,
373
427
/// The joint public key for the entire group.
374
428
pub group_public : VerifyingKey < C > ,
375
429
}
@@ -394,7 +448,7 @@ pub struct PublicKeyPackage<C: Ciphersuite> {
394
448
///
395
449
/// [`secret_key_shard`]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-03.html#appendix-B.1
396
450
pub fn generate_secret_shares < C : Ciphersuite , R : RngCore + CryptoRng > (
397
- secret : & Secret < C > ,
451
+ secret : & SharedSecret < C > ,
398
452
numshares : u8 ,
399
453
threshold : u8 ,
400
454
mut rng : R ,
@@ -456,7 +510,7 @@ pub fn generate_secret_shares<C: Ciphersuite, R: RngCore + CryptoRng>(
456
510
457
511
secret_shares. push ( SecretShare {
458
512
identifier : id,
459
- value : Secret ( value) ,
513
+ value : SigningShare ( value) ,
460
514
commitment : commitment. clone ( ) ,
461
515
} ) ;
462
516
}
@@ -467,7 +521,7 @@ pub fn generate_secret_shares<C: Ciphersuite, R: RngCore + CryptoRng>(
467
521
/// Recompute the secret from t-of-n secret shares using Lagrange interpolation.
468
522
pub fn reconstruct_secret < C : Ciphersuite > (
469
523
secret_shares : Vec < SecretShare < C > > ,
470
- ) -> Result < Secret < C > , & ' static str > {
524
+ ) -> Result < SharedSecret < C > , & ' static str > {
471
525
if secret_shares. is_empty ( ) {
472
526
return Err ( "No secret_shares provided" ) ;
473
527
}
@@ -512,5 +566,8 @@ pub fn reconstruct_secret<C: Ciphersuite>(
512
566
secret = secret + ( lagrange_coefficient * secret_share. value . 0 ) ;
513
567
}
514
568
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
+ )
516
573
}
0 commit comments