mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-01 16:53:52 +02:00
crypto: refactor ChaCha20 classes to use Span<std::byte> interface
This commit is contained in:
@@ -20,17 +20,17 @@ FUZZ_TARGET(crypto_chacha20)
|
||||
ChaCha20 chacha20;
|
||||
if (fuzzed_data_provider.ConsumeBool()) {
|
||||
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
|
||||
chacha20 = ChaCha20{key.data()};
|
||||
chacha20 = ChaCha20{MakeByteSpan(key)};
|
||||
}
|
||||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
|
||||
CallOneOf(
|
||||
fuzzed_data_provider,
|
||||
[&] {
|
||||
std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
|
||||
chacha20.SetKey32(key.data());
|
||||
chacha20.SetKey(MakeByteSpan(key));
|
||||
},
|
||||
[&] {
|
||||
chacha20.Seek64(
|
||||
chacha20.Seek(
|
||||
{
|
||||
fuzzed_data_provider.ConsumeIntegral<uint32_t>(),
|
||||
fuzzed_data_provider.ConsumeIntegral<uint64_t>()
|
||||
@@ -38,12 +38,12 @@ FUZZ_TARGET(crypto_chacha20)
|
||||
},
|
||||
[&] {
|
||||
std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
|
||||
chacha20.Keystream(output.data(), output.size());
|
||||
chacha20.Keystream(MakeWritableByteSpan(output));
|
||||
},
|
||||
[&] {
|
||||
std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
|
||||
const std::vector<uint8_t> input = ConsumeFixedLengthByteVector(fuzzed_data_provider, output.size());
|
||||
chacha20.Crypt(input.data(), output.data(), input.size());
|
||||
chacha20.Crypt(MakeByteSpan(input), MakeWritableByteSpan(output));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -62,9 +62,8 @@ template<bool UseCrypt>
|
||||
void ChaCha20SplitFuzz(FuzzedDataProvider& provider)
|
||||
{
|
||||
// Determine key, iv, start position, length.
|
||||
unsigned char key[32] = {0};
|
||||
auto key_bytes = provider.ConsumeBytes<unsigned char>(32);
|
||||
std::copy(key_bytes.begin(), key_bytes.end(), key);
|
||||
auto key_bytes = provider.ConsumeBytes<std::byte>(ChaCha20::KEYLEN);
|
||||
key_bytes.resize(ChaCha20::KEYLEN);
|
||||
uint64_t iv = provider.ConsumeIntegral<uint64_t>();
|
||||
uint32_t iv_prefix = provider.ConsumeIntegral<uint32_t>();
|
||||
uint64_t total_bytes = provider.ConsumeIntegralInRange<uint64_t>(0, 1000000);
|
||||
@@ -72,13 +71,13 @@ void ChaCha20SplitFuzz(FuzzedDataProvider& provider)
|
||||
uint32_t seek = provider.ConsumeIntegralInRange<uint32_t>(0, ~(uint32_t)(total_bytes >> 6));
|
||||
|
||||
// Initialize two ChaCha20 ciphers, with the same key/iv/position.
|
||||
ChaCha20 crypt1(key);
|
||||
ChaCha20 crypt2(key);
|
||||
crypt1.Seek64({iv_prefix, iv}, seek);
|
||||
crypt2.Seek64({iv_prefix, iv}, seek);
|
||||
ChaCha20 crypt1(key_bytes);
|
||||
ChaCha20 crypt2(key_bytes);
|
||||
crypt1.Seek({iv_prefix, iv}, seek);
|
||||
crypt2.Seek({iv_prefix, iv}, seek);
|
||||
|
||||
// Construct vectors with data.
|
||||
std::vector<unsigned char> data1, data2;
|
||||
std::vector<std::byte> data1, data2;
|
||||
data1.resize(total_bytes);
|
||||
data2.resize(total_bytes);
|
||||
|
||||
@@ -90,14 +89,14 @@ void ChaCha20SplitFuzz(FuzzedDataProvider& provider)
|
||||
uint64_t bytes = 0;
|
||||
while (bytes < (total_bytes & ~uint64_t{7})) {
|
||||
uint64_t val = rng();
|
||||
WriteLE64(data1.data() + bytes, val);
|
||||
WriteLE64(data2.data() + bytes, val);
|
||||
WriteLE64(UCharCast(data1.data() + bytes), val);
|
||||
WriteLE64(UCharCast(data2.data() + bytes), val);
|
||||
bytes += 8;
|
||||
}
|
||||
if (bytes < total_bytes) {
|
||||
unsigned char valbytes[8];
|
||||
std::byte valbytes[8];
|
||||
uint64_t val = rng();
|
||||
WriteLE64(valbytes, val);
|
||||
WriteLE64(UCharCast(valbytes), val);
|
||||
std::copy(valbytes, valbytes + (total_bytes - bytes), data1.data() + bytes);
|
||||
std::copy(valbytes, valbytes + (total_bytes - bytes), data2.data() + bytes);
|
||||
}
|
||||
@@ -108,9 +107,9 @@ void ChaCha20SplitFuzz(FuzzedDataProvider& provider)
|
||||
|
||||
// Encrypt data1, the whole array at once.
|
||||
if constexpr (UseCrypt) {
|
||||
crypt1.Crypt(data1.data(), data1.data(), total_bytes);
|
||||
crypt1.Crypt(data1, data1);
|
||||
} else {
|
||||
crypt1.Keystream(data1.data(), total_bytes);
|
||||
crypt1.Keystream(data1);
|
||||
}
|
||||
|
||||
// Encrypt data2, in at most 256 chunks.
|
||||
@@ -127,9 +126,9 @@ void ChaCha20SplitFuzz(FuzzedDataProvider& provider)
|
||||
// This tests that Keystream() has the same behavior as Crypt() applied
|
||||
// to 0x00 input bytes.
|
||||
if (UseCrypt || provider.ConsumeBool()) {
|
||||
crypt2.Crypt(data2.data() + bytes2, data2.data() + bytes2, now);
|
||||
crypt2.Crypt(Span{data2}.subspan(bytes2, now), Span{data2}.subspan(bytes2, now));
|
||||
} else {
|
||||
crypt2.Keystream(data2.data() + bytes2, now);
|
||||
crypt2.Keystream(Span{data2}.subspan(bytes2, now));
|
||||
}
|
||||
bytes2 += now;
|
||||
if (is_last) break;
|
||||
|
||||
@@ -275,14 +275,14 @@ FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
||||
|
||||
if (fuzzed_data_provider.ConsumeBool()) {
|
||||
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
|
||||
chacha20 = ChaCha20{key.data()};
|
||||
chacha20 = ChaCha20{MakeByteSpan(key)};
|
||||
ECRYPT_keysetup(&ctx, key.data(), key.size() * 8, 0);
|
||||
} else {
|
||||
// The default ChaCha20 constructor is equivalent to using the all-0 key.
|
||||
ECRYPT_keysetup(&ctx, ZEROKEY, 256, 0);
|
||||
}
|
||||
|
||||
// ECRYPT_keysetup() doesn't set the counter and nonce to 0 while SetKey32() does
|
||||
// ECRYPT_keysetup() doesn't set the counter and nonce to 0 while SetKey() does
|
||||
static const uint8_t iv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
ChaCha20::Nonce96 nonce{0, 0};
|
||||
uint32_t counter{0};
|
||||
@@ -293,11 +293,11 @@ FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
||||
fuzzed_data_provider,
|
||||
[&] {
|
||||
const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
|
||||
chacha20.SetKey32(key.data());
|
||||
chacha20.SetKey(MakeByteSpan(key));
|
||||
nonce = {0, 0};
|
||||
counter = 0;
|
||||
ECRYPT_keysetup(&ctx, key.data(), key.size() * 8, 0);
|
||||
// ECRYPT_keysetup() doesn't set the counter and nonce to 0 while SetKey32() does
|
||||
// ECRYPT_keysetup() doesn't set the counter and nonce to 0 while SetKey() does
|
||||
uint8_t iv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
ECRYPT_ivsetup(&ctx, iv);
|
||||
},
|
||||
@@ -306,7 +306,7 @@ FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
||||
uint64_t iv = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
|
||||
nonce = {iv_prefix, iv};
|
||||
counter = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
|
||||
chacha20.Seek64(nonce, counter);
|
||||
chacha20.Seek(nonce, counter);
|
||||
ctx.input[12] = counter;
|
||||
ctx.input[13] = iv_prefix;
|
||||
ctx.input[14] = iv;
|
||||
@@ -315,7 +315,7 @@ FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
||||
[&] {
|
||||
uint32_t integralInRange = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096);
|
||||
std::vector<uint8_t> output(integralInRange);
|
||||
chacha20.Keystream(output.data(), output.size());
|
||||
chacha20.Keystream(MakeWritableByteSpan(output));
|
||||
std::vector<uint8_t> djb_output(integralInRange);
|
||||
ECRYPT_keystream_bytes(&ctx, djb_output.data(), djb_output.size());
|
||||
assert(output == djb_output);
|
||||
@@ -324,7 +324,7 @@ FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
||||
counter += (integralInRange + 63) >> 6;
|
||||
if (counter < old_counter) ++nonce.first;
|
||||
if (integralInRange & 63) {
|
||||
chacha20.Seek64(nonce, counter);
|
||||
chacha20.Seek(nonce, counter);
|
||||
}
|
||||
assert(counter == ctx.input[12]);
|
||||
},
|
||||
@@ -332,7 +332,7 @@ FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
||||
uint32_t integralInRange = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096);
|
||||
std::vector<uint8_t> output(integralInRange);
|
||||
const std::vector<uint8_t> input = ConsumeFixedLengthByteVector(fuzzed_data_provider, output.size());
|
||||
chacha20.Crypt(input.data(), output.data(), input.size());
|
||||
chacha20.Crypt(MakeByteSpan(input), MakeWritableByteSpan(output));
|
||||
std::vector<uint8_t> djb_output(integralInRange);
|
||||
ECRYPT_encrypt_bytes(&ctx, input.data(), djb_output.data(), input.size());
|
||||
assert(output == djb_output);
|
||||
@@ -341,7 +341,7 @@ FUZZ_TARGET(crypto_diff_fuzz_chacha20)
|
||||
counter += (integralInRange + 63) >> 6;
|
||||
if (counter < old_counter) ++nonce.first;
|
||||
if (integralInRange & 63) {
|
||||
chacha20.Seek64(nonce, counter);
|
||||
chacha20.Seek(nonce, counter);
|
||||
}
|
||||
assert(counter == ctx.input[12]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user