Merge bitcoin/bitcoin#30571: test: [refactor] Use m_rng directly

948238a683 test: Remove FastRandomContext global (Ryan Ofsky)
fa0fe08eca scripted-diff: [test] Use g_rng/m_rng directly (MarcoFalke)
fa54cab473 test: refactor: Accept any RandomNumberGenerator in RandMoney (MarcoFalke)
68f77dd21e test: refactor: Pass rng parameters to test functions (Ryan Ofsky)
fa19af555d test: refactor: Move g_insecure_rand_ctx.Reseed out of the helper that calls MakeRandDeterministicDANGEROUS (MarcoFalke)
3dc527f460 test: refactor: Give unit test functions access to test state (Ryan Ofsky)
fab023e177 test: refactor: Make unsigned promotion explicit (MarcoFalke)
fa2cb654ec test: Add m_rng alias for the global random context (MarcoFalke)
fae7e3791c test: Correct the random seed log on a prevector test failure (MarcoFalke)

Pull request description:

  This is mostly a style-cleanup for the tests' random generation:

  1) `g_insecure_rand_ctx` in the tests is problematic, because the name is a leftover when the generator was indeed insecure. However, now the generator is *deterministic*, because the seed is either passed in or printed (c.f. RANDOM_CTX_SEED). Stating that deterministic randomness is insecure in the tests seems redundant at best. Fix it by just using `m_rng` for the name.

  2) The global random context has many one-line aliases, such as `InsecureRand32`. This is problematic, because the same line of code may use the context directly and through a wrapper at the same time. For example in net_tests (see below). This inconsistency is harmless, but confusing. Fix it by just removing the one-line aliases.

  ```
  src/test/net_tests.cpp:        auto msg_data_1 = g_insecure_rand_ctx.randbytes<uint8_t>(InsecureRandRange(100000));
  ````

  3) The wrapper for randmoney has the same problem that the same unit test uses the context directly and through a wrapper at the same time. Also, it has a single type of Rng hardcoded. Fix it by accepting any type.

ACKs for top commit:
  hodlinator:
    ACK 948238a683
  ryanofsky:
    Code review ACK 948238a683. Only changes since last review were changing a comments a little bit.
  marcofleon:
    Code review ACK 948238a683. Only changes since my last review are the improvements in `prevector_tests`.

Tree-SHA512: 69c6b46a42cb743138ee8c87ff26a588dbe083e3efb3dca49b8a133ba5d3b09e8bf01c590ec7e121a7d77cb1fd7dcacd927a9ca139ac65e1f7c6d1ec46f93b57
This commit is contained in:
merge-script
2024-08-28 16:56:32 +01:00
48 changed files with 514 additions and 459 deletions

View File

@@ -26,10 +26,11 @@
#include <boost/test/unit_test.hpp>
BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
namespace crypto_tests {
struct CryptoTest : BasicTestingSetup {
template<typename Hasher, typename In, typename Out>
static void TestVector(const Hasher &h, const In &in, const Out &out) {
void TestVector(const Hasher &h, const In &in, const Out &out) {
Out hash;
BOOST_CHECK(out.size() == h.OUTPUT_SIZE);
hash.resize(out.size());
@@ -43,7 +44,7 @@ static void TestVector(const Hasher &h, const In &in, const Out &out) {
Hasher hasher(h);
size_t pos = 0;
while (pos < in.size()) {
size_t len = InsecureRandRange((in.size() - pos + 1) / 2 + 1);
size_t len = m_rng.randrange((in.size() - pos + 1) / 2 + 1);
hasher.Write((const uint8_t*)in.data() + pos, len);
pos += len;
if (pos > 0 && pos + 2 * out.size() > in.size() && pos < in.size()) {
@@ -57,22 +58,22 @@ static void TestVector(const Hasher &h, const In &in, const Out &out) {
}
}
static void TestSHA1(const std::string &in, const std::string &hexout) { TestVector(CSHA1(), in, ParseHex(hexout));}
static void TestSHA256(const std::string &in, const std::string &hexout) { TestVector(CSHA256(), in, ParseHex(hexout));}
static void TestSHA512(const std::string &in, const std::string &hexout) { TestVector(CSHA512(), in, ParseHex(hexout));}
static void TestRIPEMD160(const std::string &in, const std::string &hexout) { TestVector(CRIPEMD160(), in, ParseHex(hexout));}
void TestSHA1(const std::string &in, const std::string &hexout) { TestVector(CSHA1(), in, ParseHex(hexout));}
void TestSHA256(const std::string &in, const std::string &hexout) { TestVector(CSHA256(), in, ParseHex(hexout));}
void TestSHA512(const std::string &in, const std::string &hexout) { TestVector(CSHA512(), in, ParseHex(hexout));}
void TestRIPEMD160(const std::string &in, const std::string &hexout) { TestVector(CRIPEMD160(), in, ParseHex(hexout));}
static void TestHMACSHA256(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
void TestHMACSHA256(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
std::vector<unsigned char> key = ParseHex(hexkey);
TestVector(CHMAC_SHA256(key.data(), key.size()), ParseHex(hexin), ParseHex(hexout));
}
static void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
std::vector<unsigned char> key = ParseHex(hexkey);
TestVector(CHMAC_SHA512(key.data(), key.size()), ParseHex(hexin), ParseHex(hexout));
}
static void TestAES256(const std::string &hexkey, const std::string &hexin, const std::string &hexout)
void TestAES256(const std::string &hexkey, const std::string &hexin, const std::string &hexout)
{
std::vector<unsigned char> key = ParseHex(hexkey);
std::vector<unsigned char> in = ParseHex(hexin);
@@ -91,7 +92,7 @@ static void TestAES256(const std::string &hexkey, const std::string &hexin, cons
BOOST_CHECK(buf == in);
}
static void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout)
void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout)
{
std::vector<unsigned char> key = ParseHex(hexkey);
std::vector<unsigned char> iv = ParseHex(hexiv);
@@ -132,7 +133,7 @@ static void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, b
}
}
static void TestChaCha20(const std::string &hex_message, const std::string &hexkey, ChaCha20::Nonce96 nonce, uint32_t seek, const std::string& hexout)
void TestChaCha20(const std::string &hex_message, const std::string &hexkey, ChaCha20::Nonce96 nonce, uint32_t seek, const std::string& hexout)
{
auto key = ParseHex<std::byte>(hexkey);
assert(key.size() == 32);
@@ -164,8 +165,8 @@ static void TestChaCha20(const std::string &hex_message, const std::string &hexk
// Repeat 10x, but fragmented into 3 chunks, to exercise the ChaCha20 class's caching.
for (int i = 0; i < 10; ++i) {
size_t lens[3];
lens[0] = InsecureRandRange(hexout.size() / 2U + 1U);
lens[1] = InsecureRandRange(hexout.size() / 2U + 1U - lens[0]);
lens[0] = m_rng.randrange(hexout.size() / 2U + 1U);
lens[1] = m_rng.randrange(hexout.size() / 2U + 1U - lens[0]);
lens[2] = hexout.size() / 2U - lens[0] - lens[1];
rng.Seek(nonce, seek);
@@ -183,7 +184,7 @@ static void TestChaCha20(const std::string &hex_message, const std::string &hexk
}
}
static void TestFSChaCha20(const std::string& hex_plaintext, const std::string& hexkey, uint32_t rekey_interval, const std::string& ciphertext_after_rotation)
void TestFSChaCha20(const std::string& hex_plaintext, const std::string& hexkey, uint32_t rekey_interval, const std::string& ciphertext_after_rotation)
{
auto key = ParseHex<std::byte>(hexkey);
BOOST_CHECK_EQUAL(FSChaCha20::KEYLEN, key.size());
@@ -223,7 +224,7 @@ static void TestFSChaCha20(const std::string& hex_plaintext, const std::string&
BOOST_CHECK_EQUAL(HexStr(fsc20_output), ciphertext_after_rotation);
}
static void TestPoly1305(const std::string &hexmessage, const std::string &hexkey, const std::string& hextag)
void TestPoly1305(const std::string &hexmessage, const std::string &hexkey, const std::string& hextag)
{
auto key = ParseHex<std::byte>(hexkey);
auto m = ParseHex<std::byte>(hexmessage);
@@ -237,7 +238,7 @@ static void TestPoly1305(const std::string &hexmessage, const std::string &hexke
auto data = Span{m};
Poly1305 poly1305{key};
for (int chunk = 0; chunk < splits; ++chunk) {
size_t now = InsecureRandRange(data.size() + 1);
size_t now = m_rng.randrange(data.size() + 1);
poly1305.Update(data.first(now));
data = data.subspan(now);
}
@@ -248,7 +249,7 @@ static void TestPoly1305(const std::string &hexmessage, const std::string &hexke
}
}
static void TestChaCha20Poly1305(const std::string& plain_hex, const std::string& aad_hex, const std::string& key_hex, ChaCha20::Nonce96 nonce, const std::string& cipher_hex)
void TestChaCha20Poly1305(const std::string& plain_hex, const std::string& aad_hex, const std::string& key_hex, ChaCha20::Nonce96 nonce, const std::string& cipher_hex)
{
auto plain = ParseHex<std::byte>(plain_hex);
auto aad = ParseHex<std::byte>(aad_hex);
@@ -257,7 +258,7 @@ static void TestChaCha20Poly1305(const std::string& plain_hex, const std::string
for (int i = 0; i < 10; ++i) {
// During i=0, use single-plain Encrypt/Decrypt; others use a split at prefix.
size_t prefix = i ? InsecureRandRange(plain.size() + 1) : plain.size();
size_t prefix = i ? m_rng.randrange(plain.size() + 1) : plain.size();
// Encrypt.
std::vector<std::byte> cipher(plain.size() + AEADChaCha20Poly1305::EXPANSION);
AEADChaCha20Poly1305 aead{key};
@@ -289,7 +290,7 @@ static void TestChaCha20Poly1305(const std::string& plain_hex, const std::string
}
}
static void TestFSChaCha20Poly1305(const std::string& plain_hex, const std::string& aad_hex, const std::string& key_hex, uint64_t msg_idx, const std::string& cipher_hex)
void TestFSChaCha20Poly1305(const std::string& plain_hex, const std::string& aad_hex, const std::string& key_hex, uint64_t msg_idx, const std::string& cipher_hex)
{
auto plain = ParseHex<std::byte>(plain_hex);
auto aad = ParseHex<std::byte>(aad_hex);
@@ -299,7 +300,7 @@ static void TestFSChaCha20Poly1305(const std::string& plain_hex, const std::stri
for (int it = 0; it < 10; ++it) {
// During it==0 we use the single-plain Encrypt/Decrypt; others use a split at prefix.
size_t prefix = it ? InsecureRandRange(plain.size() + 1) : plain.size();
size_t prefix = it ? m_rng.randrange(plain.size() + 1) : plain.size();
std::byte dummy_tag[FSChaCha20Poly1305::EXPANSION] = {{}};
// Do msg_idx dummy encryptions to seek to the correct packet.
@@ -335,7 +336,7 @@ static void TestFSChaCha20Poly1305(const std::string& plain_hex, const std::stri
}
}
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) {
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) {
std::vector<unsigned char> initial_key_material = ParseHex(ikm_hex);
std::vector<unsigned char> salt = ParseHex(salt_hex);
std::vector<unsigned char> info = ParseHex(info_hex);
@@ -351,6 +352,10 @@ static void TestHKDF_SHA256_32(const std::string &ikm_hex, const std::string &sa
BOOST_CHECK(HexStr(out) == okm_check_hex);
}
void TestSHA3_256(const std::string& input, const std::string& output);
}; // struct CryptoTests
} // namespace crypto_tests
static std::string LongTestString()
{
std::string ret;
@@ -366,6 +371,8 @@ static std::string LongTestString()
const std::string test1 = LongTestString();
BOOST_FIXTURE_TEST_SUITE(crypto_tests, CryptoTest)
BOOST_AUTO_TEST_CASE(ripemd160_testvectors) {
TestRIPEMD160("", "9c1185a5c5e9fc54612808977ee8f548b2258d31");
TestRIPEMD160("abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
@@ -1067,7 +1074,7 @@ BOOST_AUTO_TEST_CASE(sha256d64)
unsigned char in[64 * 32];
unsigned char out1[32 * 32], out2[32 * 32];
for (int j = 0; j < 64 * i; ++j) {
in[j] = InsecureRandBits(8);
in[j] = m_rng.randbits(8);
}
for (int j = 0; j < i; ++j) {
CHash256().Write({in + 64 * j, 64}).Finalize({out1 + 32 * j, 32});
@@ -1077,7 +1084,7 @@ BOOST_AUTO_TEST_CASE(sha256d64)
}
}
static void TestSHA3_256(const std::string& input, const std::string& output)
void CryptoTest::TestSHA3_256(const std::string& input, const std::string& output)
{
const auto in_bytes = ParseHex(input);
const auto out_bytes = ParseHex(output);
@@ -1091,8 +1098,8 @@ static void TestSHA3_256(const std::string& input, const std::string& output)
// Reset and split randomly in 3
sha.Reset();
int s1 = InsecureRandRange(in_bytes.size() + 1);
int s2 = InsecureRandRange(in_bytes.size() + 1 - s1);
int s1 = m_rng.randrange(in_bytes.size() + 1);
int s2 = m_rng.randrange(in_bytes.size() + 1 - s1);
int s3 = in_bytes.size() - s1 - s2;
sha.Write(Span{in_bytes}.first(s1)).Write(Span{in_bytes}.subspan(s1, s2));
sha.Write(Span{in_bytes}.last(s3)).Finalize(out);
@@ -1196,7 +1203,7 @@ BOOST_AUTO_TEST_CASE(muhash_tests)
uint256 res;
int table[4];
for (int i = 0; i < 4; ++i) {
table[i] = g_insecure_rand_ctx.randbits<3>();
table[i] = m_rng.randbits<3>();
}
for (int order = 0; order < 4; ++order) {
MuHash3072 acc;
@@ -1216,8 +1223,8 @@ BOOST_AUTO_TEST_CASE(muhash_tests)
}
}
MuHash3072 x = FromInt(g_insecure_rand_ctx.randbits<4>()); // x=X
MuHash3072 y = FromInt(g_insecure_rand_ctx.randbits<4>()); // x=X, y=Y
MuHash3072 x = FromInt(m_rng.randbits<4>()); // x=X
MuHash3072 y = FromInt(m_rng.randbits<4>()); // x=X, y=Y
MuHash3072 z; // x=X, y=Y, z=1
z *= x; // x=X, y=Y, z=X
z *= y; // x=X, y=Y, z=X*Y