@@ -255,20 +255,37 @@ static void TestChaCha20Poly1305(const std::string& plain_hex, const std::string
255
255
auto key = ParseHex<std::byte>(key_hex);
256
256
auto expected_cipher = ParseHex<std::byte>(cipher_hex);
257
257
258
- std::vector<std::byte> cipher (plain.size () + AEADChaCha20Poly1305::EXPANSION);
259
- AEADChaCha20Poly1305 aead{key};
260
- aead.Encrypt (plain, aad, nonce, cipher);
261
- BOOST_CHECK (cipher == expected_cipher);
258
+ for (int i = 0 ; i < 10 ; ++i) {
259
+ // During i=0, use single-plain Encrypt/Decrypt; others use a split at prefix.
260
+ size_t prefix = i ? InsecureRandRange (plain.size () + 1 ) : plain.size ();
261
+ // Encrypt.
262
+ std::vector<std::byte> cipher (plain.size () + AEADChaCha20Poly1305::EXPANSION);
263
+ AEADChaCha20Poly1305 aead{key};
264
+ if (i == 0 ) {
265
+ aead.Encrypt (plain, aad, nonce, cipher);
266
+ } else {
267
+ aead.Encrypt (Span{plain}.first (prefix), Span{plain}.subspan (prefix), aad, nonce, cipher);
268
+ }
269
+ BOOST_CHECK (cipher == expected_cipher);
262
270
263
- std::vector<std::byte> decipher (cipher.size () - AEADChaCha20Poly1305::EXPANSION);
264
- bool ret = aead.Decrypt (cipher, aad, nonce, decipher);
265
- BOOST_CHECK (ret);
266
- BOOST_CHECK (decipher == plain);
271
+ // Decrypt.
272
+ std::vector<std::byte> decipher (cipher.size () - AEADChaCha20Poly1305::EXPANSION);
273
+ bool ret{false };
274
+ if (i == 0 ) {
275
+ ret = aead.Decrypt (cipher, aad, nonce, decipher);
276
+ } else {
277
+ ret = aead.Decrypt (cipher, aad, nonce, Span{decipher}.first (prefix), Span{decipher}.subspan (prefix));
278
+ }
279
+ BOOST_CHECK (ret);
280
+ BOOST_CHECK (decipher == plain);
281
+ }
267
282
283
+ // Test Keystream output.
268
284
std::vector<std::byte> keystream (plain.size ());
285
+ AEADChaCha20Poly1305 aead{key};
269
286
aead.Keystream (nonce, keystream);
270
287
for (size_t i = 0 ; i < plain.size (); ++i) {
271
- BOOST_CHECK_EQUAL (plain[i] ^ keystream[i], cipher [i]);
288
+ BOOST_CHECK_EQUAL (plain[i] ^ keystream[i], expected_cipher [i]);
272
289
}
273
290
}
274
291
@@ -280,25 +297,43 @@ static void TestFSChaCha20Poly1305(const std::string& plain_hex, const std::stri
280
297
auto expected_cipher = ParseHex<std::byte>(cipher_hex);
281
298
std::vector<std::byte> cipher (plain.size () + FSChaCha20Poly1305::EXPANSION);
282
299
283
- FSChaCha20Poly1305 enc_aead{key, 224 };
284
- for (uint64_t i = 0 ; i < msg_idx; ++i) {
285
- std::byte dummy_tag[FSChaCha20Poly1305::EXPANSION] = {{}};
286
- enc_aead.Encrypt (Span{dummy_tag}.first (0 ), Span{dummy_tag}.first (0 ), dummy_tag);
287
- }
300
+ for (int it = 0 ; it < 10 ; ++it) {
301
+ // During it==0 we use the single-plain Encrypt/Decrypt; others use a split at prefix.
302
+ size_t prefix = it ? InsecureRandRange (plain.size () + 1 ) : plain.size ();
288
303
289
- enc_aead.Encrypt (plain, aad, cipher);
290
- BOOST_CHECK (cipher == expected_cipher);
304
+ // Do msg_idx dummy encryptions to seek to the correct packet.
305
+ FSChaCha20Poly1305 enc_aead{key, 224 };
306
+ for (uint64_t i = 0 ; i < msg_idx; ++i) {
307
+ std::byte dummy_tag[FSChaCha20Poly1305::EXPANSION] = {{}};
308
+ enc_aead.Encrypt (Span{dummy_tag}.first (0 ), Span{dummy_tag}.first (0 ), dummy_tag);
309
+ }
291
310
292
- FSChaCha20Poly1305 dec_aead{key, 224 };
293
- for (uint64_t i = 0 ; i < msg_idx; ++i) {
294
- std::byte dummy_tag[FSChaCha20Poly1305::EXPANSION] = {{}};
295
- dec_aead.Decrypt (dummy_tag, Span{dummy_tag}.first (0 ), Span{dummy_tag}.first (0 ));
296
- }
311
+ // Invoke single-plain or plain1/plain2 Encrypt.
312
+ if (it == 0 ) {
313
+ enc_aead.Encrypt (plain, aad, cipher);
314
+ } else {
315
+ enc_aead.Encrypt (Span{plain}.first (prefix), Span{plain}.subspan (prefix), aad, cipher);
316
+ }
317
+ BOOST_CHECK (cipher == expected_cipher);
297
318
298
- std::vector<std::byte> decipher (cipher.size () - AEADChaCha20Poly1305::EXPANSION);
299
- bool ret = dec_aead.Decrypt (cipher, aad, decipher);
300
- BOOST_CHECK (ret);
301
- BOOST_CHECK (decipher == plain);
319
+ // Do msg_idx dummy decryptions to seek to the correct packet.
320
+ FSChaCha20Poly1305 dec_aead{key, 224 };
321
+ for (uint64_t i = 0 ; i < msg_idx; ++i) {
322
+ std::byte dummy_tag[FSChaCha20Poly1305::EXPANSION] = {{}};
323
+ dec_aead.Decrypt (dummy_tag, Span{dummy_tag}.first (0 ), Span{dummy_tag}.first (0 ));
324
+ }
325
+
326
+ // Invoke single-plain or plain1/plain2 Decrypt.
327
+ std::vector<std::byte> decipher (cipher.size () - AEADChaCha20Poly1305::EXPANSION);
328
+ bool ret{false };
329
+ if (it == 0 ) {
330
+ ret = dec_aead.Decrypt (cipher, aad, decipher);
331
+ } else {
332
+ ret = dec_aead.Decrypt (cipher, aad, Span{decipher}.first (prefix), Span{decipher}.subspan (prefix));
333
+ }
334
+ BOOST_CHECK (ret);
335
+ BOOST_CHECK (decipher == plain);
336
+ }
302
337
}
303
338
304
339
static void TestHKDF_SHA256_32 (const std::string &ikm_hex, const std::string &salt_hex, const std::string &info_hex, const std::string &okm_check_hex) {
0 commit comments