@@ -10,7 +10,7 @@ use multisig::Committee;
10
10
use rayon:: prelude:: * ;
11
11
use serde:: { Deserialize , Serialize } ;
12
12
use serde_with:: serde_as;
13
- use std:: { iter:: successors, num:: NonZeroUsize } ;
13
+ use std:: { iter:: successors, num:: NonZeroUsize , ops :: Add } ;
14
14
15
15
use crate :: {
16
16
interpolation:: { interpolate, interpolate_in_exponent} ,
@@ -158,27 +158,26 @@ impl<C: CurveGroup> VerifiableSecretSharing for FeldmanVss<C> {
158
158
159
159
fn reconstruct (
160
160
pp : & Self :: PublicParam ,
161
- shares : impl Iterator < Item = ( usize , Self :: SecretShare ) > ,
161
+ shares : impl ExactSizeIterator < Item = ( usize , Self :: SecretShare ) > + Clone ,
162
162
) -> Result < Self :: Secret , VssError > {
163
- let shares = shares. collect :: < Vec < _ > > ( ) ;
164
163
let n = pp. n . get ( ) ;
165
164
let t = pp. t . get ( ) ;
166
165
// input validation
167
166
if shares. len ( ) != t {
168
167
return Err ( VssError :: MismatchedSharesCount ( t, shares. len ( ) ) ) ;
169
168
}
170
- for ( idx, _) in shares. iter ( ) {
171
- if * idx >= n {
172
- return Err ( VssError :: IndexOutOfBound ( n - 1 , * idx) ) ;
169
+ for ( idx, _) in shares. clone ( ) {
170
+ if idx >= n {
171
+ return Err ( VssError :: IndexOutOfBound ( n - 1 , idx) ) ;
173
172
}
174
173
}
175
174
176
175
// Lagrange interpolate to get back the secret
177
176
let eval_points: Vec < _ > = shares
178
- . iter ( )
179
- . map ( |& ( idx, _) | C :: ScalarField :: from ( idx as u64 + 1 ) )
177
+ . clone ( )
178
+ . map ( |( idx, _) | C :: ScalarField :: from ( idx as u64 + 1 ) )
180
179
. collect ( ) ;
181
- let evals: Vec < _ > = shares. iter ( ) . map ( |& ( _, share) | share) . collect ( ) ;
180
+ let evals: Vec < _ > = shares. map ( |( _, share) | share) . collect ( ) ;
182
181
interpolate :: < C > ( & eval_points, & evals)
183
182
. map_err ( |e| VssError :: FailedReconstruction ( e. to_string ( ) ) )
184
183
}
@@ -217,6 +216,36 @@ impl<C: CurveGroup> FeldmanCommitment<C> {
217
216
}
218
217
}
219
218
219
+ impl < C : CurveGroup > Add < FeldmanCommitment < C > > for FeldmanCommitment < C > {
220
+ type Output = FeldmanCommitment < C > ;
221
+
222
+ fn add ( self , other : FeldmanCommitment < C > ) -> Self :: Output {
223
+ & self + & other
224
+ }
225
+ }
226
+
227
+ impl < C : CurveGroup > Add < & FeldmanCommitment < C > > for FeldmanCommitment < C > {
228
+ type Output = FeldmanCommitment < C > ;
229
+
230
+ fn add ( self , other : & FeldmanCommitment < C > ) -> Self :: Output {
231
+ & self + other
232
+ }
233
+ }
234
+
235
+ impl < C : CurveGroup > Add < & FeldmanCommitment < C > > for & FeldmanCommitment < C > {
236
+ type Output = FeldmanCommitment < C > ;
237
+
238
+ fn add ( self , other : & FeldmanCommitment < C > ) -> Self :: Output {
239
+ let combined: Vec < C > = self
240
+ . comm
241
+ . iter ( )
242
+ . zip ( other. comm . iter ( ) )
243
+ . map ( |( x, y) | * x + y)
244
+ . collect ( ) ;
245
+ C :: normalize_batch ( & combined) . into ( )
246
+ }
247
+ }
248
+
220
249
impl < C : CurveGroup > KeyResharing < Self > for FeldmanVss < C > {
221
250
fn reshare < R : Rng > (
222
251
new_pp : & FeldmanVssPublicParam ,
@@ -252,19 +281,17 @@ impl<C: CurveGroup> KeyResharing<Self> for FeldmanVss<C> {
252
281
fn combine (
253
282
old_pp : & FeldmanVssPublicParam ,
254
283
new_pp : & FeldmanVssPublicParam ,
255
- send_node_indices : & [ usize ] ,
256
- row_commitments : & [ FeldmanCommitment < C > ] ,
257
284
recv_node_idx : usize ,
258
- recv_reshares : & [ C :: ScalarField ] ,
285
+ reshares : impl ExactSizeIterator < Item = ( usize , C :: ScalarField , FeldmanCommitment < C > ) > + Clone ,
259
286
) -> Result < ( C :: ScalarField , FeldmanCommitment < C > ) , VssError > {
260
287
// input validation
261
288
let n = old_pp. n . get ( ) ;
262
- if send_node_indices . is_empty ( ) || row_commitments . is_empty ( ) || recv_reshares . is_empty ( ) {
289
+ if reshares . len ( ) == 0 {
263
290
return Err ( VssError :: EmptyReshare ) ;
264
291
}
265
- for idx in send_node_indices . iter ( ) {
266
- if * idx >= n {
267
- return Err ( VssError :: IndexOutOfBound ( n - 1 , * idx) ) ;
292
+ for ( idx, _ , _ ) in reshares . clone ( ) {
293
+ if idx >= n {
294
+ return Err ( VssError :: IndexOutOfBound ( n - 1 , idx) ) ;
268
295
}
269
296
}
270
297
@@ -273,24 +300,23 @@ impl<C: CurveGroup> KeyResharing<Self> for FeldmanVss<C> {
273
300
if recv_node_idx >= new_n {
274
301
return Err ( VssError :: IndexOutOfBound ( new_n - 1 , recv_node_idx) ) ;
275
302
}
276
- if row_commitments. iter ( ) . any ( |cm| cm. len ( ) != new_t) {
277
- return Err ( VssError :: InvalidCommitment ) ;
278
- }
279
-
280
- let subset_size = recv_reshares. len ( ) ;
281
- if send_node_indices. len ( ) != subset_size || row_commitments. len ( ) != subset_size {
282
- return Err ( VssError :: MismatchedInputLength ) ;
303
+ for ( _, _, row_commitment) in reshares. clone ( ) {
304
+ if row_commitment. len ( ) != new_t {
305
+ return Err ( VssError :: InvalidCommitment ) ;
306
+ }
283
307
}
284
308
285
309
// interpolate reshares to get new secret share
286
- let eval_points: Vec < _ > = send_node_indices
287
- . iter ( )
288
- . map ( |& idx| C :: ScalarField :: from ( idx as u64 + 1 ) )
310
+ let eval_points: Vec < _ > = reshares
311
+ . clone ( )
312
+ . map ( |( idx, _ , _ ) | C :: ScalarField :: from ( idx as u64 + 1 ) )
289
313
. collect ( ) ;
290
- let new_secret = interpolate :: < C > ( & eval_points, recv_reshares)
314
+ let recv_reshares: Vec < _ > = reshares. clone ( ) . map ( |( _, share, _) | share) . collect ( ) ;
315
+ let new_secret = interpolate :: < C > ( & eval_points, & recv_reshares)
291
316
. map_err ( |e| VssError :: FailedCombine ( e. to_string ( ) ) ) ?;
292
317
293
318
// interpolate in the exponent to get new Feldman commitment
319
+ let row_commitments: Vec < _ > = reshares. map ( |( _, _, commitment) | commitment) . collect ( ) ;
294
320
let new_commitment = ( 0 ..new_t)
295
321
. into_par_iter ( )
296
322
. map ( |j| {
@@ -461,15 +487,10 @@ mod tests {
461
487
let selected_row_commitments: Vec < FeldmanCommitment < _ > > =
462
488
( 0 ..old_t) . map ( |i| row_commitments[ i] . clone ( ) ) . collect ( ) ;
463
489
464
- let ( new_secret_share, new_commitment) = FeldmanVss :: < G1Projective > :: combine (
465
- & old_pp,
466
- & new_pp,
467
- & ( 0 ..old_t) . collect :: < Vec < _ > > ( ) ,
468
- & selected_row_commitments,
469
- j,
470
- & recv_reshares,
471
- )
472
- . unwrap ( ) ;
490
+ let reshares_iter =
491
+ ( 0 ..old_t) . map ( |i| ( i, recv_reshares[ i] , selected_row_commitments[ i] . clone ( ) ) ) ;
492
+ let ( new_secret_share, new_commitment) =
493
+ FeldmanVss :: < G1Projective > :: combine ( & old_pp, & new_pp, j, reshares_iter) . unwrap ( ) ;
473
494
474
495
new_shares. push ( new_secret_share) ;
475
496
new_commitments. push ( new_commitment) ;
0 commit comments