Skip to content

Commit b564bca

Browse files
committed
fix: indexed aad during encryption for security
1 parent 58cc102 commit b564bca

File tree

1 file changed

+28
-9
lines changed

1 file changed

+28
-9
lines changed

timeboost-crypto/src/vess.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,21 @@ impl<C: CurveGroup> ShoupVess<C> {
171171
subset
172172
}
173173

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
175185
// each dealing contains (Shamir poly + Feldman commitment + MRE ciphertext)
176186
fn new_dealing(
177187
&self,
188+
ith: usize,
178189
seed: &[u8; 32],
179190
recipients: &[mre::EncryptionKey<C>],
180191
aad: &[u8],
@@ -194,9 +205,12 @@ impl<C: CurveGroup> ShoupVess<C> {
194205
let serialized_shares: Vec<Vec<u8>> =
195206
FeldmanVss::<C>::compute_serialized_shares(&self.vss_pp, &poly).collect();
196207

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+
)?;
200214
Ok((poly, comm, mre_ct))
201215
}
202216

@@ -252,7 +266,8 @@ impl<C: CurveGroup> ShoupVess<C> {
252266
MultiRecvCiphertext<C, sha2::Sha256>,
253267
)> = seeds
254268
.par_iter()
255-
.map(|r| self.new_dealing(r, recipients, aad))
269+
.enumerate()
270+
.map(|(i, r)| self.new_dealing(i, r, recipients, aad))
256271
.collect::<Result<_, VessError>>()?;
257272

258273
// compute h:= H_compress(aad, dealings)
@@ -409,7 +424,7 @@ impl<C: CurveGroup> ShoupVess<C> {
409424
let seed = seeds
410425
.pop_front()
411426
.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)?;
413428

414429
hasher.update(serialize_to_vec![cm]?);
415430
hasher.update(mre_ct.to_bytes());
@@ -435,14 +450,18 @@ impl<C: CurveGroup> ShoupVess<C> {
435450
let mut verifier_state = self.io_pattern(aad).to_verifier_state(&ct.transcript);
436451

437452
// 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) =
439454
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());
440457

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+
{
442461
let recv_ct = mre_ct
443462
.get_recipient_ct(node_idx)
444463
.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))?;
446465
// mu'_kj in paper
447466
let unshifted_eval: C::ScalarField =
448467
CanonicalDeserialize::deserialize_compressed(&*pt)?;

0 commit comments

Comments
 (0)