@@ -171,10 +171,21 @@ impl<C: CurveGroup> ShoupVess<C> {
171
171
subset
172
172
}
173
173
174
- // deterministically generate a dealing from a random seed
174
+ /// append `aad` with index value `ith`, returns aad' = aad | ith
175
+ fn indexed_aad ( & self , aad : & [ u8 ] , ith : usize ) -> Vec < u8 > {
176
+ let sample_idx = if self . num_repetition < u8:: MAX as usize {
177
+ ( ith as u8 ) . to_be_bytes ( ) . to_vec ( )
178
+ } else {
179
+ ith. to_be_bytes ( ) . to_vec ( )
180
+ } ;
181
+ [ aad, sample_idx. as_ref ( ) ] . concat ( )
182
+ }
183
+
184
+ // deterministically generate the `i`-th dealing from a random seed
175
185
// each dealing contains (Shamir poly + Feldman commitment + MRE ciphertext)
176
186
fn new_dealing (
177
187
& self ,
188
+ ith : usize ,
178
189
seed : & [ u8 ; 32 ] ,
179
190
recipients : & [ mre:: EncryptionKey < C > ] ,
180
191
aad : & [ u8 ] ,
@@ -194,9 +205,12 @@ impl<C: CurveGroup> ShoupVess<C> {
194
205
let serialized_shares: Vec < Vec < u8 > > =
195
206
FeldmanVss :: < C > :: compute_serialized_shares ( & self . vss_pp , & poly) . collect ( ) ;
196
207
197
- // TODO: use aad'= aad | k instead?
198
- let mre_ct =
199
- mre:: encrypt :: < C , sha2:: Sha256 , _ > ( recipients, & serialized_shares, aad, & mut rng) ?;
208
+ let mre_ct = mre:: encrypt :: < C , sha2:: Sha256 , _ > (
209
+ recipients,
210
+ & serialized_shares,
211
+ & self . indexed_aad ( aad, ith) ,
212
+ & mut rng,
213
+ ) ?;
200
214
Ok ( ( poly, comm, mre_ct) )
201
215
}
202
216
@@ -252,7 +266,8 @@ impl<C: CurveGroup> ShoupVess<C> {
252
266
MultiRecvCiphertext < C , sha2:: Sha256 > ,
253
267
) > = seeds
254
268
. par_iter ( )
255
- . map ( |r| self . new_dealing ( r, recipients, aad) )
269
+ . enumerate ( )
270
+ . map ( |( i, r) | self . new_dealing ( i, r, recipients, aad) )
256
271
. collect :: < Result < _ , VessError > > ( ) ?;
257
272
258
273
// compute h:= H_compress(aad, dealings)
@@ -409,7 +424,7 @@ impl<C: CurveGroup> ShoupVess<C> {
409
424
let seed = seeds
410
425
. pop_front ( )
411
426
. expect ( "subset_size < num_repetitions, so seeds.len() > 0" ) ;
412
- let ( _poly, cm, mre_ct) = self . new_dealing ( & seed, recipients, aad) ?;
427
+ let ( _poly, cm, mre_ct) = self . new_dealing ( i , & seed, recipients, aad) ?;
413
428
414
429
hasher. update ( serialize_to_vec ! [ cm] ?) ;
415
430
hasher. update ( mre_ct. to_bytes ( ) ) ;
@@ -435,14 +450,18 @@ impl<C: CurveGroup> ShoupVess<C> {
435
450
let mut verifier_state = self . io_pattern ( aad) . to_verifier_state ( & ct. transcript ) ;
436
451
437
452
// verifier logic until Step 4b
438
- let ( comm, _h, _subset_seed , shifted_polys, mre_cts) =
453
+ let ( comm, _h, subset_seed , shifted_polys, mre_cts) =
439
454
self . verify_internal ( & mut verifier_state) ?;
455
+ let subset_indices = self . map_subset_seed ( subset_seed) ;
456
+ debug_assert_eq ! ( subset_indices. len( ) , shifted_polys. len( ) ) ;
440
457
441
- for ( shifted_coeffs, mre_ct) in shifted_polys. iter ( ) . zip ( mre_cts. iter ( ) ) {
458
+ for ( ( shifted_coeffs, mre_ct) , ith) in
459
+ shifted_polys. iter ( ) . zip ( mre_cts. iter ( ) ) . zip ( subset_indices)
460
+ {
442
461
let recv_ct = mre_ct
443
462
. get_recipient_ct ( node_idx)
444
463
. ok_or ( VessError :: IndexOutOfBound ( n, node_idx) ) ?;
445
- let pt = recv_sk. decrypt ( & recv_ct, aad) ?;
464
+ let pt = recv_sk. decrypt ( & recv_ct, & self . indexed_aad ( aad, ith ) ) ?;
446
465
// mu'_kj in paper
447
466
let unshifted_eval: C :: ScalarField =
448
467
CanonicalDeserialize :: deserialize_compressed ( & * pt) ?;
0 commit comments