@@ -81,7 +81,7 @@ impl ThresholdKey {
81
81
dealings : I ,
82
82
) -> anyhow:: Result < Self >
83
83
where
84
- I : ExactSizeIterator < Item = ( usize , VssShare , VssCommitment ) > + Clone ,
84
+ I : Iterator < Item = ( usize , VssShare , VssCommitment ) > ,
85
85
{
86
86
let old_pp = FeldmanVssPublicParam :: from ( old_committee) ;
87
87
let new_pp = FeldmanVssPublicParam :: from ( new_committee) ;
@@ -131,10 +131,15 @@ impl ThresholdKey {
131
131
132
132
/// `DecryptionKeyCell` is a thread-safe container for an optional `DecryptionKey`
133
133
/// that allows asynchronous notification when the key is set.
134
- #[ derive( Debug , Clone , Default ) ]
134
+ #[ derive( Clone , Debug , Default ) ]
135
135
pub struct ThresholdKeyCell {
136
- key : Arc < RwLock < Option < ThresholdKey > > > ,
137
- notify : Arc < Notify > ,
136
+ inner : Arc < ThresholdKeyCellInner > ,
137
+ }
138
+
139
+ #[ derive( Debug , Default ) ]
140
+ struct ThresholdKeyCellInner {
141
+ key : RwLock < Option < ThresholdKey > > ,
142
+ notify : Notify ,
138
143
}
139
144
140
145
impl ThresholdKeyCell {
@@ -143,25 +148,25 @@ impl ThresholdKeyCell {
143
148
}
144
149
145
150
pub fn set ( & self , key : ThresholdKey ) {
146
- * self . key . write ( ) = Some ( key) ;
147
- self . notify . notify_waiters ( ) ;
151
+ * self . inner . key . write ( ) = Some ( key) ;
152
+ self . inner . notify . notify_waiters ( ) ;
148
153
}
149
154
150
155
pub fn get ( & self ) -> Option < ThresholdKey > {
151
- ( * self . key . read ( ) ) . clone ( )
156
+ ( * self . inner . key . read ( ) ) . clone ( )
152
157
}
153
158
154
159
pub fn enc_key ( & self ) -> Option < ThresholdEncKey > {
155
160
self . get ( ) . map ( |sk| sk. pubkey )
156
161
}
157
162
158
163
pub fn get_ref ( & self ) -> impl Deref < Target = Option < ThresholdKey > > {
159
- self . key . read ( )
164
+ self . inner . key . read ( )
160
165
}
161
166
162
167
pub async fn read ( & self ) -> ThresholdKey {
163
168
loop {
164
- let fut = self . notify . notified ( ) ;
169
+ let fut = self . inner . notify . notified ( ) ;
165
170
if let Some ( k) = self . get ( ) {
166
171
return k;
167
172
}
@@ -280,10 +285,10 @@ impl<const N: usize> From<KeyStore> for KeyStoreVec<N> {
280
285
281
286
/// A `KeyStore` with committee information and public keys used in the DKG or key resharing
282
287
#[ derive( Debug , Clone ) ]
283
- pub struct KeyStore ( Arc < Inner > ) ;
288
+ pub struct KeyStore ( Arc < KeyStoreInner > ) ;
284
289
285
290
#[ derive( Debug ) ]
286
- struct Inner {
291
+ struct KeyStoreInner {
287
292
committee : Committee ,
288
293
keys : BTreeMap < KeyId , DkgEncKey > ,
289
294
}
@@ -294,7 +299,7 @@ impl KeyStore {
294
299
I : IntoIterator < Item = ( T , DkgEncKey ) > ,
295
300
T : Into < KeyId > ,
296
301
{
297
- let this = Self ( Arc :: new ( Inner {
302
+ let this = Self ( Arc :: new ( KeyStoreInner {
298
303
committee : c,
299
304
keys : keys. into_iter ( ) . map ( |( i, k) | ( i. into ( ) , k) ) . collect ( ) ,
300
305
} ) ) ;
@@ -446,20 +451,19 @@ impl DkgAccumulator {
446
451
}
447
452
448
453
/// Try to finalize the accumulator into a subset if enough bundles are collected.
449
- pub fn try_finalize ( & mut self ) -> Option < DkgSubset > {
454
+ /// Returns a reference to the internal data to avoid cloning the bundles.
455
+ pub fn try_finalize ( & self ) -> Option < DkgSubsetRef < ' _ > > {
450
456
if self . complete {
451
457
let combkey = match & self . mode {
452
458
AccumulatorMode :: Dkg => None ,
453
459
AccumulatorMode :: Resharing ( combkey) => Some ( combkey. clone ( ) ) ,
454
460
} ;
455
461
456
- let subset = DkgSubset {
462
+ Some ( DkgSubsetRef {
457
463
committee_id : self . committee ( ) . id ( ) ,
458
- bundles : self . bundles . clone ( ) ,
464
+ bundles : & self . bundles ,
459
465
combkey,
460
- } ;
461
-
462
- Some ( subset)
466
+ } )
463
467
} else {
464
468
None
465
469
}
@@ -488,6 +492,14 @@ pub struct DkgSubset {
488
492
combkey : Option < ThresholdCombKey > ,
489
493
}
490
494
495
+ /// A reference-based version of DkgSubset to avoid cloning bundles.
496
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
497
+ pub struct DkgSubsetRef < ' a > {
498
+ committee_id : CommitteeId ,
499
+ bundles : & ' a [ DkgBundle ] ,
500
+ combkey : Option < ThresholdCombKey > ,
501
+ }
502
+
491
503
impl DkgSubset {
492
504
/// Create a new subset with DKG bundles.
493
505
pub fn new_dkg ( committee_id : CommitteeId , bundles : Vec < DkgBundle > ) -> Self {
@@ -536,6 +548,27 @@ impl DkgSubset {
536
548
self . combkey . is_some ( )
537
549
}
538
550
551
+ /// Convert this DkgSubset to a DkgSubsetRef.
552
+ pub fn as_ref ( & self ) -> DkgSubsetRef < ' _ > {
553
+ DkgSubsetRef {
554
+ committee_id : self . committee_id ,
555
+ bundles : & self . bundles ,
556
+ combkey : self . combkey . as_ref ( ) . cloned ( ) ,
557
+ }
558
+ }
559
+
560
+ /// Extract the new threshold decryption key from the subset.
561
+ pub fn extract_key (
562
+ & self ,
563
+ curr : & KeyStore ,
564
+ dkg_sk : & LabeledDkgDecKey ,
565
+ prev : Option < & KeyStore > ,
566
+ ) -> anyhow:: Result < ThresholdKey > {
567
+ self . as_ref ( ) . extract_key ( curr, dkg_sk, prev)
568
+ }
569
+ }
570
+
571
+ impl < ' a > DkgSubsetRef < ' a > {
539
572
/// Extract the new threshold decryption key from the subset.
540
573
pub fn extract_key (
541
574
& self ,
@@ -547,7 +580,7 @@ impl DkgSubset {
547
580
548
581
match & self . combkey {
549
582
None => {
550
- let mut dealings_iter = ResultIter :: new ( self . bundles ( ) . iter ( ) . map ( |b| {
583
+ let mut dealings_iter = ResultIter :: new ( self . bundles . iter ( ) . map ( |b| {
551
584
vess. decrypt_share ( curr. committee ( ) , dkg_sk, b. vess_ct ( ) , DKG_AAD )
552
585
. map ( |s| ( s, b. comm ( ) . clone ( ) ) )
553
586
} ) ) ;
@@ -559,38 +592,28 @@ impl DkgSubset {
559
592
) ?;
560
593
561
594
dealings_iter. result ( ) ?;
562
-
563
595
Ok ( dec_key)
564
596
}
565
597
Some ( combkey) => {
566
- let Some ( prev) = prev else {
567
- return Err ( anyhow ! ( "previous key store missing" ) ) ;
568
- } ;
598
+ let prev = prev. ok_or_else ( || anyhow ! ( "previous key store missing" ) ) ?;
599
+ let mut dealings_iter = ResultIter :: new ( self . bundles . iter ( ) . map ( |b| {
600
+ let node_idx = b. origin ( ) . 0 . into ( ) ;
601
+ let pub_share = combkey
602
+ . get_pub_share ( node_idx)
603
+ . ok_or ( VessError :: FailedVerification ) ?;
604
+ vess. decrypt_reshare ( curr. committee ( ) , dkg_sk, b. vess_ct ( ) , DKG_AAD , * pub_share)
605
+ . map ( |s| ( node_idx, s, b. comm ( ) . clone ( ) ) )
606
+ } ) ) ;
569
607
570
- let dealings: Vec < _ > = self
571
- . bundles ( )
572
- . iter ( )
573
- . map ( |b| {
574
- let node_idx = b. origin ( ) . 0 . into ( ) ;
575
- let pub_share = combkey
576
- . get_pub_share ( node_idx)
577
- . ok_or ( VessError :: FailedVerification ) ?;
578
- let s = vess. decrypt_reshare (
579
- curr. committee ( ) ,
580
- dkg_sk,
581
- b. vess_ct ( ) ,
582
- DKG_AAD ,
583
- * pub_share,
584
- ) ?;
585
- Ok ( ( node_idx, s, b. comm ( ) . clone ( ) ) )
586
- } )
587
- . collect :: < Result < Vec < _ > , VessError > > ( ) ?;
588
- ThresholdKey :: from_resharing (
608
+ let dec_key = ThresholdKey :: from_resharing (
589
609
prev. committee ( ) ,
590
610
curr. committee ( ) ,
591
611
dkg_sk. node_idx ( ) ,
592
- dealings. into_iter ( ) ,
593
- )
612
+ & mut dealings_iter,
613
+ ) ?;
614
+
615
+ dealings_iter. result ( ) ?;
616
+ Ok ( dec_key)
594
617
}
595
618
}
596
619
}
0 commit comments