18 for (
int i = 0; i < rekey_interval; ++i) {
49 unsigned mode = provider.ConsumeIntegral<uint8_t>();
50 bool use_splits = mode & 1;
51 bool damage = mode & 4;
52 unsigned aad_length_bits = 3 * ((mode >> 3) & 3);
53 unsigned aad_length = provider.ConsumeIntegralInRange<
unsigned>(0, (1 << aad_length_bits) - 1);
54 unsigned length_bits = 2 * ((mode >> 5) & 7);
55 unsigned length = provider.ConsumeIntegralInRange<
unsigned>(0, (1 << length_bits) - 1);
57 auto aad = rng.
randbytes<std::byte>(aad_length);
58 auto plain = rng.
randbytes<std::byte>(length);
63 if (use_splits && length > 0) {
64 size_t split_index = provider.ConsumeIntegralInRange<
size_t>(1, length);
71 std::vector<std::byte> keystream(length);
73 for (
size_t i = 0; i < length; ++i) {
74 assert((plain[i] ^ keystream[i]) == cipher[i]);
77 std::vector<std::byte> decrypted_contents(length);
81 unsigned key_position = provider.ConsumeIntegralInRange<
unsigned>(0, 31);
82 std::byte damage_val{(uint8_t)(1U << (key_position & 7))};
83 std::vector<std::byte> bad_key = key;
84 bad_key[key_position] ^= damage_val;
87 ok = bad_aead.
Decrypt(cipher, aad,
nonce, decrypted_contents);
93 unsigned damage_bit = provider.ConsumeIntegralInRange<
unsigned>(0, (cipher.size() + aad.size()) * 8U - 1U);
94 unsigned damage_pos = damage_bit >> 3;
95 std::byte damage_val{(uint8_t)(1U << (damage_bit & 7))};
96 if (damage_pos >= cipher.size()) {
97 aad[damage_pos - cipher.size()] ^= damage_val;
99 cipher[damage_pos] ^= damage_val;
103 if (use_splits && length > 0) {
104 size_t split_index = provider.ConsumeIntegralInRange<
size_t>(1, length);
107 ok = aead.
Decrypt(cipher, aad,
nonce, decrypted_contents);
113 assert(decrypted_contents == plain);
122 auto key = provider.ConsumeBytes<std::byte>(32);
140 unsigned mode = provider.ConsumeIntegral<uint8_t>();
141 bool use_splits = mode & 1;
142 bool damage = mode & 4;
143 unsigned aad_length_bits = 3 * ((mode >> 3) & 3);
144 unsigned aad_length = provider.ConsumeIntegralInRange<
unsigned>(0, (1 << aad_length_bits) - 1);
145 unsigned length_bits = 2 * ((mode >> 5) & 7);
146 unsigned length = provider.ConsumeIntegralInRange<
unsigned>(0, (1 << length_bits) - 1);
148 auto aad = rng.
randbytes<std::byte>(aad_length);
149 auto plain = rng.
randbytes<std::byte>(length);
153 if (use_splits && length > 0) {
154 size_t split_index = provider.ConsumeIntegralInRange<
size_t>(1, length);
157 enc_aead.
Encrypt(plain, aad, cipher);
160 std::vector<std::byte> decrypted_contents(length);
164 unsigned key_position = provider.ConsumeIntegralInRange<
unsigned>(0, 31);
165 std::byte damage_val{(uint8_t)(1U << (key_position & 7))};
166 std::vector<std::byte> bad_key = key;
167 bad_key[key_position] ^= damage_val;
171 ok = bad_fs_aead.
Decrypt(cipher, aad, decrypted_contents);
177 unsigned damage_bit = provider.ConsumeIntegralInRange<
unsigned>(0, (cipher.size() + aad.size()) * 8U - 1U);
178 unsigned damage_pos = damage_bit >> 3;
179 std::byte damage_val{(uint8_t)(1U << (damage_bit & 7))};
180 if (damage_pos >= cipher.size()) {
181 aad[damage_pos - cipher.size()] ^= damage_val;
183 cipher[damage_pos] ^= damage_val;
188 if (use_splits && length > 0) {
189 size_t split_index = provider.ConsumeIntegralInRange<
size_t>(1, length);
192 ok = dec_aead.
Decrypt(cipher, aad, decrypted_contents);
198 assert(decrypted_contents == plain);
The AEAD_CHACHA20_POLY1305 authenticated encryption algorithm from RFC8439 section 2....
ChaCha20::Nonce96 Nonce96
96-bit nonce type.
void Encrypt(Span< const std::byte > plain, Span< const std::byte > aad, Nonce96 nonce, Span< std::byte > cipher) noexcept
Encrypt a message with a specified 96-bit nonce and aad.
static constexpr unsigned EXPANSION
Expansion when encrypting.
bool Decrypt(Span< const std::byte > cipher, Span< const std::byte > aad, Nonce96 nonce, Span< std::byte > plain) noexcept
Decrypt a message with a specified 96-bit nonce and aad.
void Keystream(Nonce96 nonce, Span< std::byte > keystream) noexcept
Get a number of keystream bytes from the underlying stream cipher.
Forward-secure wrapper around AEADChaCha20Poly1305.
bool Decrypt(Span< const std::byte > cipher, Span< const std::byte > aad, Span< std::byte > plain) noexcept
Decrypt a message with a specified aad.
static constexpr auto EXPANSION
Expansion when encrypting.
void Encrypt(Span< const std::byte > plain, Span< const std::byte > aad, Span< std::byte > cipher) noexcept
Encrypt a message with a specified aad.
std::vector< T > ConsumeBytes(size_t num_bytes)
T ConsumeIntegralInRange(T min, T max)
std::vector< B > randbytes(size_t len) noexcept
Generate random bytes.
A Span is an object that can refer to a contiguous sequence of objects.
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
static constexpr void crypt_till_rekey(FSChaCha20Poly1305 &aead, int rekey_interval, bool encrypt)
FUZZ_TARGET(crypto_aeadchacha20poly1305)
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.