random: replace construct/assign with explicit Reseed()

This commit is contained in:
Pieter Wuille 2024-05-31 10:39:23 -04:00
parent 2ae392d561
commit ce8094246e
7 changed files with 32 additions and 47 deletions

View file

@ -704,6 +704,13 @@ void FastRandomContext::fillrand(Span<std::byte> output) noexcept
FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), rng(MakeByteSpan(seed)) {}
void FastRandomContext::Reseed(const uint256& seed) noexcept
{
FlushCache();
requires_seed = false;
rng = {MakeByteSpan(seed)};
}
bool Random_SanityCheck()
{
uint64_t start = GetPerformanceCounter();
@ -759,15 +766,6 @@ FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_se
// use.
}
FastRandomContext& FastRandomContext::operator=(FastRandomContext&& from) noexcept
{
requires_seed = from.requires_seed;
rng = from.rng;
from.requires_seed = true;
static_cast<RandomMixin<FastRandomContext>&>(*this) = std::move(from);
return *this;
}
void RandomInit()
{
// Invoke RNG code to trigger initialization (if not already performed)

View file

@ -184,27 +184,21 @@ private:
*/
RandomNumberGenerator auto& Impl() noexcept { return static_cast<T&>(*this); }
public:
RandomMixin() noexcept = default;
protected:
constexpr void FlushCache() noexcept
{
bitbuf = 0;
bitbuf_size = 0;
}
// Do not permit copying an RNG.
public:
constexpr RandomMixin() noexcept = default;
// Do not permit copying or moving an RNG.
RandomMixin(const RandomMixin&) = delete;
RandomMixin& operator=(const RandomMixin&) = delete;
RandomMixin(RandomMixin&& other) noexcept : bitbuf(other.bitbuf), bitbuf_size(other.bitbuf_size)
{
other.bitbuf = 0;
other.bitbuf_size = 0;
}
RandomMixin& operator=(RandomMixin&& other) noexcept
{
bitbuf = other.bitbuf;
bitbuf_size = other.bitbuf_size;
other.bitbuf = 0;
other.bitbuf_size = 0;
return *this;
}
RandomMixin(RandomMixin&&) = delete;
RandomMixin& operator=(RandomMixin&&) = delete;
/** Generate a random (bits)-bit integer. */
uint64_t randbits(int bits) noexcept
@ -394,13 +388,8 @@ public:
/** Initialize with explicit seed (only for testing) */
explicit FastRandomContext(const uint256& seed) noexcept;
// Do not permit copying a FastRandomContext (move it, or create a new one to get reseeded).
FastRandomContext(const FastRandomContext&) = delete;
FastRandomContext(FastRandomContext&&) = delete;
FastRandomContext& operator=(const FastRandomContext&) = delete;
/** Move a FastRandomContext. If the original one is used again, it will be reseeded. */
FastRandomContext& operator=(FastRandomContext&& from) noexcept;
/** Reseed with explicit seed (only for testing). */
void Reseed(const uint256& seed) noexcept;
/** Generate a random 64-bit integer. */
uint64_t rand64() noexcept
@ -440,14 +429,12 @@ public:
constexpr explicit InsecureRandomContext(uint64_t seedval) noexcept
: m_s0(SplitMix64(seedval)), m_s1(SplitMix64(seedval)) {}
// no copy - that is dangerous, we don't want accidentally copy the RNG and then have two streams
// with exactly the same results.
InsecureRandomContext(const InsecureRandomContext&) = delete;
InsecureRandomContext& operator=(const InsecureRandomContext&) = delete;
// allow moves
InsecureRandomContext(InsecureRandomContext&&) = default;
InsecureRandomContext& operator=(InsecureRandomContext&&) = default;
constexpr void Reseed(uint64_t seedval) noexcept
{
FlushCache();
m_s0 = SplitMix64(seedval);
m_s1 = SplitMix64(seedval);
}
constexpr uint64_t rand64() noexcept
{

View file

@ -124,7 +124,7 @@ public:
explicit AddrManDeterministic(const NetGroupManager& netgroupman, FuzzedDataProvider& fuzzed_data_provider)
: AddrMan(netgroupman, /*deterministic=*/true, GetCheckRatio())
{
WITH_LOCK(m_impl->cs, m_impl->insecure_rand = FastRandomContext{ConsumeUInt256(fuzzed_data_provider)});
WITH_LOCK(m_impl->cs, m_impl->insecure_rand.Reseed(ConsumeUInt256(fuzzed_data_provider)));
}
/**

View file

@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
// ecdsa_signature_parse_der_lax are executed during this test.
// Specifically branches that run only when an ECDSA
// signature's R and S values have leading zeros.
g_insecure_rand_ctx = FastRandomContext{uint256{33}};
g_insecure_rand_ctx.Reseed(uint256{33});
TxOrphanageTest orphanage;
CKey key;

View file

@ -212,7 +212,7 @@ public:
prevector_tester() {
SeedRandomForTest();
rand_seed = InsecureRand256();
rand_cache = FastRandomContext(rand_seed);
rand_cache.Reseed(rand_seed);
}
};

View file

@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(xoroshiro128plusplus_reference_values)
BOOST_TEST(0x6ea7c59f89bbfc75 == rng());
// seed with a random number
rng = InsecureRandomContext(0x1a26f3fa8546b47a);
rng.Reseed(0x1a26f3fa8546b47a);
BOOST_TEST(0xc8dc5e08d844ac7d == rng());
BOOST_TEST(0x5b5f1f6d499dad1b == rng());
BOOST_TEST(0xbeb0031f93313d6f == rng());

View file

@ -34,5 +34,5 @@ void SeedRandomForTest(SeedRand seedtype)
const uint256& seed{seedtype == SeedRand::SEED ? ctx_seed : uint256::ZERO};
LogPrintf("%s: Setting random seed for current tests to %s=%s\n", __func__, RANDOM_CTX_SEED, seed.GetHex());
MakeRandDeterministicDANGEROUS(seed);
g_insecure_rand_ctx = FastRandomContext(GetRandHash());
g_insecure_rand_ctx.Reseed(GetRandHash());
}