Use ChaCha20 caching in FastRandomContext

This commit is contained in:
Pieter Wuille 2022-09-21 17:31:54 -04:00
parent 38eaece67b
commit 5d16f75763
2 changed files with 8 additions and 26 deletions

View file

@ -605,12 +605,9 @@ void FastRandomContext::RandomSeed()
uint256 FastRandomContext::rand256() noexcept uint256 FastRandomContext::rand256() noexcept
{ {
if (bytebuf_size < 32) { if (requires_seed) RandomSeed();
FillByteBuffer();
}
uint256 ret; uint256 ret;
memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 32); rng.Keystream(ret.data(), ret.size());
bytebuf_size -= 32;
return ret; return ret;
} }
@ -624,7 +621,7 @@ std::vector<unsigned char> FastRandomContext::randbytes(size_t len)
return ret; return ret;
} }
FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), bytebuf_size(0), bitbuf_size(0) FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), bitbuf_size(0)
{ {
rng.SetKey(seed.begin(), 32); rng.SetKey(seed.begin(), 32);
} }
@ -675,7 +672,7 @@ bool Random_SanityCheck()
return true; return true;
} }
FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0) FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), bitbuf_size(0)
{ {
if (!fDeterministic) { if (!fDeterministic) {
return; return;
@ -688,12 +685,9 @@ FastRandomContext& FastRandomContext::operator=(FastRandomContext&& from) noexce
{ {
requires_seed = from.requires_seed; requires_seed = from.requires_seed;
rng = from.rng; rng = from.rng;
std::copy(std::begin(from.bytebuf), std::end(from.bytebuf), std::begin(bytebuf));
bytebuf_size = from.bytebuf_size;
bitbuf = from.bitbuf; bitbuf = from.bitbuf;
bitbuf_size = from.bitbuf_size; bitbuf_size = from.bitbuf_size;
from.requires_seed = true; from.requires_seed = true;
from.bytebuf_size = 0;
from.bitbuf_size = 0; from.bitbuf_size = 0;
return *this; return *this;
} }

View file

@ -145,23 +145,11 @@ private:
bool requires_seed; bool requires_seed;
ChaCha20 rng; ChaCha20 rng;
unsigned char bytebuf[64];
int bytebuf_size;
uint64_t bitbuf; uint64_t bitbuf;
int bitbuf_size; int bitbuf_size;
void RandomSeed(); void RandomSeed();
void FillByteBuffer()
{
if (requires_seed) {
RandomSeed();
}
rng.Keystream(bytebuf, sizeof(bytebuf));
bytebuf_size = sizeof(bytebuf);
}
void FillBitBuffer() void FillBitBuffer()
{ {
bitbuf = rand64(); bitbuf = rand64();
@ -185,10 +173,10 @@ public:
/** Generate a random 64-bit integer. */ /** Generate a random 64-bit integer. */
uint64_t rand64() noexcept uint64_t rand64() noexcept
{ {
if (bytebuf_size < 8) FillByteBuffer(); if (requires_seed) RandomSeed();
uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size); unsigned char buf[8];
bytebuf_size -= 8; rng.Keystream(buf, 8);
return ret; return ReadLE64(buf);
} }
/** Generate a random (bits)-bit integer. */ /** Generate a random (bits)-bit integer. */