3
3
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
4
5
5
use crate :: checksum:: Checksum ;
6
-
7
6
use crate :: checksum:: ChecksumError ;
8
7
use crate :: checksum:: ChecksumHasher ;
9
8
use crate :: checksum:: CHECKSUM_LEN ;
@@ -30,7 +29,6 @@ use crate::serde::write_variable_length_bytes;
30
29
use rand_core:: CryptoRng ;
31
30
use rand_core:: RngCore ;
32
31
use std:: borrow:: Borrow ;
33
-
34
32
use std:: collections:: BTreeMap ;
35
33
use std:: hash:: Hasher ;
36
34
use std:: io;
@@ -229,15 +227,25 @@ impl PublicPackage {
229
227
230
228
pub fn serialize_into < W : io:: Write > ( & self , mut writer : W ) -> io:: Result < ( ) > {
231
229
self . sender_identity . serialize_into ( & mut writer) ?;
230
+ self . serialize_without_sender_into ( writer)
231
+ }
232
+
233
+ fn serialize_without_sender_into < W : io:: Write > ( & self , mut writer : W ) -> io:: Result < ( ) > {
232
234
self . recipient_identity . serialize_into ( & mut writer) ?;
233
235
let frost_package = self . frost_package . serialize ( ) . map_err ( io:: Error :: other) ?;
234
236
write_variable_length_bytes ( & mut writer, & frost_package) ?;
235
- writer. write_all ( & self . checksum . to_le_bytes ( ) ) ?;
236
- Ok ( ( ) )
237
+ writer. write_all ( & self . checksum . to_le_bytes ( ) )
237
238
}
238
239
239
240
pub fn deserialize_from < R : io:: Read > ( mut reader : R ) -> io:: Result < Self > {
240
241
let sender_identity = Identity :: deserialize_from ( & mut reader) ?;
242
+ Self :: deserialize_without_sender_from ( reader, sender_identity)
243
+ }
244
+
245
+ fn deserialize_without_sender_from < R : io:: Read > (
246
+ mut reader : R ,
247
+ sender_identity : Identity ,
248
+ ) -> io:: Result < Self > {
241
249
let recipient_identity = Identity :: deserialize_from ( & mut reader) ?;
242
250
243
251
let frost_package = read_variable_length_bytes ( & mut reader) ?;
@@ -256,12 +264,85 @@ impl PublicPackage {
256
264
}
257
265
}
258
266
267
+ /// A collection of [`PublicPackage`] structs, all from the same sender.
268
+ #[ derive( Default , Clone , PartialEq , Eq , Debug ) ]
269
+ pub struct CombinedPublicPackage {
270
+ packages : Vec < PublicPackage > ,
271
+ }
272
+
273
+ impl CombinedPublicPackage {
274
+ // This struct should not be constructed directly, hence `new` does not need to be `pub`.
275
+ // Keeping `new` private has the advantage that the implementation does not need to strictly
276
+ // enforce the same `sender_identity`, but it can omit this check (here we still check in debug
277
+ // builds just to catch bugs).
278
+ fn new ( packages : Vec < PublicPackage > ) -> Self {
279
+ // The serialization expects at least 1 package to be present
280
+ debug_assert ! ( !packages. is_empty( ) ) ;
281
+
282
+ let first_identity = & packages[ 0 ] . sender_identity ;
283
+ for pkg in & packages {
284
+ debug_assert_eq ! ( & pkg. sender_identity, first_identity) ;
285
+ }
286
+
287
+ Self { packages }
288
+ }
289
+
290
+ #[ inline]
291
+ #[ must_use]
292
+ pub fn packages ( & self ) -> & [ PublicPackage ] {
293
+ & self . packages
294
+ }
295
+
296
+ #[ inline]
297
+ pub fn packages_for < ' a > (
298
+ & ' a self ,
299
+ recipient_identity : & ' a Identity ,
300
+ ) -> impl Iterator < Item = & ' a PublicPackage > + ' a {
301
+ self . packages
302
+ . iter ( )
303
+ . filter ( move |pkg| & pkg. recipient_identity == recipient_identity)
304
+ }
305
+
306
+ pub fn serialize ( & self ) -> Vec < u8 > {
307
+ let mut buf = Vec :: new ( ) ;
308
+ self . serialize_into ( & mut buf) . expect ( "serialization failed" ) ;
309
+ buf
310
+ }
311
+
312
+ pub fn serialize_into < W : io:: Write > ( & self , mut writer : W ) -> io:: Result < ( ) > {
313
+ let sender_identity = & self . packages [ 0 ] . sender_identity ;
314
+ sender_identity. serialize_into ( & mut writer) ?;
315
+ write_variable_length ( writer, & self . packages , |writer, pkg| {
316
+ pkg. serialize_without_sender_into ( writer)
317
+ } )
318
+ }
319
+
320
+ pub fn deserialize_from < R : io:: Read > ( mut reader : R ) -> io:: Result < Self > {
321
+ let sender_identity = Identity :: deserialize_from ( & mut reader) ?;
322
+
323
+ let packages = read_variable_length ( reader, move |reader| {
324
+ PublicPackage :: deserialize_without_sender_from ( reader, sender_identity. clone ( ) )
325
+ } ) ?;
326
+
327
+ Ok ( Self { packages } )
328
+ }
329
+ }
330
+
331
+ impl IntoIterator for CombinedPublicPackage {
332
+ type Item = PublicPackage ;
333
+ type IntoIter = <Vec < PublicPackage > as IntoIterator >:: IntoIter ;
334
+
335
+ fn into_iter ( self ) -> Self :: IntoIter {
336
+ self . packages . into_iter ( )
337
+ }
338
+ }
339
+
259
340
pub fn round2 < ' a , P , R > (
260
341
secret : & participant:: Secret ,
261
342
round1_secret_package : & [ u8 ] ,
262
343
round1_public_packages : P ,
263
344
mut csrng : R ,
264
- ) -> Result < ( Vec < u8 > , Vec < PublicPackage > ) , Error >
345
+ ) -> Result < ( Vec < u8 > , CombinedPublicPackage ) , Error >
265
346
where
266
347
P : IntoIterator < Item = & ' a round1:: PublicPackage > ,
267
348
R : RngCore + CryptoRng ,
@@ -354,7 +435,10 @@ where
354
435
round2_public_packages. push ( public_package) ;
355
436
}
356
437
357
- Ok ( ( encrypted_secret_package, round2_public_packages) )
438
+ Ok ( (
439
+ encrypted_secret_package,
440
+ CombinedPublicPackage :: new ( round2_public_packages) ,
441
+ ) )
358
442
}
359
443
360
444
#[ cfg( test) ]
@@ -558,12 +642,12 @@ mod tests {
558
642
. expect ( "round 2 secret package import failed" ) ;
559
643
560
644
round2_public_packages
561
- . iter ( )
562
- . find ( | & p| p . recipient_identity ( ) == & identity2 )
645
+ . packages_for ( & identity2 )
646
+ . next ( )
563
647
. expect ( "round 2 public packages missing package for identity2" ) ;
564
648
round2_public_packages
565
- . iter ( )
566
- . find ( | & p| p . recipient_identity ( ) == & identity3 )
649
+ . packages_for ( & identity3 )
650
+ . next ( )
567
651
. expect ( "round 2 public packages missing package for identity3" ) ;
568
652
}
569
653
0 commit comments