Switch FastRandomContext to ChaCha20

This commit is contained in:
Pieter Wuille
2017-02-15 17:45:22 -08:00
parent e04326fe66
commit 16329224e7
10 changed files with 126 additions and 43 deletions

View File

@@ -6,6 +6,7 @@
#ifndef BITCOIN_RANDOM_H
#define BITCOIN_RANDOM_H
#include "crypto/chacha20.h"
#include "uint256.h"
#include <stdint.h>
@@ -33,21 +34,68 @@ void GetStrongRandBytes(unsigned char* buf, int num);
* This class is not thread-safe.
*/
class FastRandomContext {
private:
bool requires_seed;
ChaCha20 rng;
unsigned char bytebuf[64];
int bytebuf_size;
uint64_t bitbuf;
int bitbuf_size;
void RandomSeed();
void FillByteBuffer()
{
if (requires_seed) {
RandomSeed();
}
rng.Output(bytebuf, sizeof(bytebuf));
bytebuf_size = sizeof(bytebuf);
}
void FillBitBuffer()
{
bitbuf = rand64();
bitbuf_size = 64;
}
public:
explicit FastRandomContext(bool fDeterministic=false);
explicit FastRandomContext(bool fDeterministic = false);
uint32_t rand32() {
Rz = 36969 * (Rz & 65535) + (Rz >> 16);
Rw = 18000 * (Rw & 65535) + (Rw >> 16);
return (Rw << 16) + Rz;
/** Initialize with explicit seed (only for testing) */
explicit FastRandomContext(const uint256& seed);
/** Generate a random 64-bit integer. */
uint64_t rand64()
{
if (bytebuf_size < 8) FillByteBuffer();
uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
bytebuf_size -= 8;
return ret;
}
bool randbool() {
return rand32() & 1;
/** Generate a random (bits)-bit integer. */
uint64_t randbits(int bits) {
if (bits == 0) {
return 0;
} else if (bits > 32) {
return rand64() >> (64 - bits);
} else {
if (bitbuf_size < bits) FillBitBuffer();
uint64_t ret = bitbuf & (~(uint64_t)0 >> (64 - bits));
bitbuf >>= bits;
bitbuf_size -= bits;
return ret;
}
}
uint32_t Rz;
uint32_t Rw;
/** Generate a random 32-bit integer. */
uint32_t rand32() { return randbits(32); }
/** Generate a random boolean. */
bool randbool() { return randbits(1); }
};
/* Number of random bytes returned by GetOSRand.