33#ifdef HAVE_SYS_GETRANDOM
34#include <linux/random.h>
35#include <sys/syscall.h>
37#if defined(HAVE_GETENTROPY) || \
38 (defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX))
41#if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
42#include <sys/random.h>
44#ifdef HAVE_SYSCTL_ARND
45#include <sys/sysctl.h>
49 LogPrintf(
"Failed to read randomness, aborting\n");
56#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
58#elif !defined(_MSC_VER) && defined(__i386__)
61 __asm__ volatile(
"rdtsc" :
"=A"(r));
63#elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
67 return (
r2 << 32) |
r1;
71 return std::chrono::high_resolution_clock::now().time_since_epoch().count();
82 "Unexpected value for bit_RDRND");
86 "Unexpected value for bit_RDSEED");
106 LogPrintf(
"Using RdSeed as additional entropy source\n");
109 LogPrintf(
"Using RdRand as an additional entropy source\n");
127 for (
int i = 0; i < 10; ++i) {
129 __asm__ volatile(
".byte 0x0f, 0xc7, 0xf0; setc %1"
130 :
"=a"(
r1),
"=q"(
ok)::
"cc");
135 for (
int i = 0; i < 10; ++i) {
137 __asm__ volatile(
".byte 0x0f, 0xc7, 0xf0; setc %1"
138 :
"=a"(
r2),
"=q"(
ok)::
"cc");
144#elif defined(__x86_64__) || defined(__amd64__)
147 for (
int i = 0; i < 10; ++i) {
149 __asm__ volatile(
".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1"
150 :
"=a"(
r1),
"=q"(
ok)::
"cc");
157#error "RdRand is only supported on x86 and x86_64"
174 __asm__ volatile(
".byte 0x0f, 0xc7, 0xf8; setc %1"
175 :
"=a"(
r1),
"=q"(
ok)::
"cc");
183 __asm__ volatile(
".byte 0x0f, 0xc7, 0xf8; setc %1"
184 :
"=a"(
r2),
"=q"(
ok)::
"cc");
191#elif defined(__x86_64__) || defined(__amd64__)
196 __asm__ volatile(
".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1"
197 :
"=a"(
r1),
"=q"(
ok)::
"cc");
205#error "RdSeed is only supported on x86 and x86_64"
225#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
228 hasher.Write((
const uint8_t *)&out,
sizeof(out));
239#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
243 for (
int i = 0; i < 4; ++i) {
245 hasher.Write((
const uint8_t *)&out,
sizeof(out));
252 for (
int i = 0; i < 4; ++i) {
254 for (
int j = 0;
j < 1024; ++
j) {
257 hasher.Write((
const uint8_t *)&out,
sizeof(out));
277 for (
int i = 0; i < 1000; ++i) {
332#elif defined(HAVE_SYS_GETRANDOM)
351#elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
364#elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
373#elif defined(HAVE_SYSCTL_ARND)
416 Mutex m_events_mutex;
426 LOCK(m_events_mutex);
444 LOCK(m_events_mutex);
468 "Buffer needs to have hasher's output size");
474 hasher.Write(m_state, 32);
479 hasher.Finalize(buf);
481 memcpy(m_state, buf + 32, 32);
500 static std::vector<RNGState, secure_allocator<RNGState>>
g_rng(1);
521 hasher.Write((
const uint8_t *)&ptr,
sizeof(ptr));
541 rng.SeedEvents(hasher);
571 rng.SeedEvents(hasher);
577 "Feeding %i bytes of dynamic environment data into RNG\n",
631 if (!rng.MixExtract(out,
num, std::move(hasher),
false)) {
694 std::vector<uint8_t>
ret(
len);
702 : requires_seed(
false), bytebuf_size(0), bitbuf_size(0) {
703 rng.SetKey(seed.begin(), 32);
747 std::this_thread::sleep_for(std::chrono::milliseconds(1));
763 : requires_seed(!
fDeterministic), bytebuf_size(0), bitbuf_size(0) {
768 rng.SetKey(seed.
begin(), 32);
775 std::copy(std::begin(
from.bytebuf), std::end(
from.bytebuf),
776 std::begin(bytebuf));
777 bytebuf_size =
from.bytebuf_size;
778 bitbuf =
from.bitbuf;
779 bitbuf_size =
from.bitbuf_size;
780 from.requires_seed =
true;
781 from.bytebuf_size = 0;
782 from.bitbuf_size = 0;
793std::chrono::microseconds
797 -0.0000000000000035527136788 );
798 return now + std::chrono::duration_cast<std::chrono::microseconds>(
A hasher class for SHA-256.
A hasher class for SHA-512.
CSHA512 & Write(const uint8_t *data, size_t len)
static constexpr size_t OUTPUT_SIZE
void SetKey(const uint8_t *key, size_t keylen)
set key with flexible keylength; 256bit recommended
void Keystream(uint8_t *c, size_t bytes)
outputs the keystream of size <bytes> into
uint160 rand160() noexcept
generate a random uint160.
std::vector< uint8_t > randbytes(size_t len)
Generate random bytes.
FastRandomContext(bool fDeterministic=false) noexcept
uint256 rand256() noexcept
generate a random uint256.
FastRandomContext & operator=(const FastRandomContext &)=delete
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
A Span is an object that can refer to a contiguous sequence of objects.
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
#define LogPrint(category,...)
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future sampled from an exponential distribution (https://en....
static void ReportHardwareRand()
void GetRandBytes(Span< uint8_t > bytes) noexcept
Overall design of the RNG and entropy sources.
static void SeedStrengthen(CSHA512 &hasher, RNGState &rng, int microseconds) noexcept
Extract entropy from rng, strengthen it, and feed it into hasher.
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
bool g_mock_deterministic_tests
static void SeedFast(CSHA512 &hasher) noexcept
static void GetDevURandom(uint8_t *ent32)
Fallback: get 32 bytes of system entropy from /dev/urandom.
static void InitHardwareRand()
Access to other hardware random number generators could be added here later, assuming it is sufficien...
static void SeedHardwareFast(CSHA512 &hasher) noexcept
Add 64 bits of entropy gathered from hardware to hasher.
uint64_t GetRandInternal(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
void GetOSRand(uint8_t *ent32)
Get 32 bytes of system entropy.
static void SeedTimestamp(CSHA512 &hasher) noexcept
A note on the use of noexcept in the seeding functions below:
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
static void Strengthen(const uint8_t(&seed)[32], int microseconds, CSHA512 &hasher) noexcept
Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher.
uint256 GetRandHash() noexcept
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept
static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
static void RandFailure()
@ SLOW
Automatically called by GetStrongRandBytes.
@ PERIODIC
Called by RandAddPeriodic()
@ FAST
Automatically called by GetRandBytes.
static void SeedHardwareSlow(CSHA512 &hasher) noexcept
Add 256 bits of entropy gathered from hardware to hasher.
static int64_t GetPerformanceCounter() noexcept
void GetStrongRandBytes(Span< uint8_t > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept
uint256 GetRandHash() noexcept
static const int NUM_OS_RANDOM_BYTES
Number of random bytes returned by GetOSRand.
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int64_t GetTimeMicros()
Returns the system time (not mockable)