Changeset View
Changeset View
Standalone View
Standalone View
src/random.h
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#ifndef BITCOIN_RANDOM_H | #ifndef BITCOIN_RANDOM_H | ||||
#define BITCOIN_RANDOM_H | #define BITCOIN_RANDOM_H | ||||
#include <crypto/chacha20.h> | #include <crypto/chacha20.h> | ||||
#include <crypto/common.h> | #include <crypto/common.h> | ||||
#include <uint256.h> | #include <uint256.h> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <limits> | #include <limits> | ||||
/** | /** | ||||
* Overall design of the RNG and entropy sources. | |||||
* | |||||
* We maintain a single global 256-bit RNG state for all high-quality | |||||
* randomness. The following (classes of) functions interact with that state by | |||||
* mixing in new entropy, and optionally extracting random output from it: | |||||
* | |||||
* - The GetRand*() class of functions, as well as construction of | |||||
* FastRandomContext objects, perform 'fast' seeding, consisting of mixing in: | |||||
* - A stack pointer (indirectly committing to calling thread and call stack) | |||||
* - A high-precision timestamp (rdtsc when available, c++ | |||||
* high_resolution_clock otherwise) | |||||
* - Hardware RNG (rdrand) when available. | |||||
* These entropy sources are very fast, and only designed to protect against | |||||
* situations where a VM state restore/copy results in multiple systems with the | |||||
* same randomness. FastRandomContext on the other hand does not protect against | |||||
* this once created, but is even faster (and acceptable to use inside tight | |||||
* loops). | |||||
* | |||||
* - The GetStrongRand*() class of function perform 'slow' seeding, including | |||||
* everything that fast seeding includes, but additionally: | |||||
* - OS entropy (/dev/urandom, getrandom(), ...). The application will | |||||
* terminate if this entropy source fails. | |||||
* - Bytes from OpenSSL's RNG (which itself may be seeded from various | |||||
* sources) | |||||
* - Another high-precision timestamp (indirectly committing to a benchmark of | |||||
* all the previous sources). These entropy sources are slower, but designed to | |||||
* make sure the RNG state contains fresh data that is unpredictable to | |||||
* attackers. | |||||
* | |||||
* - RandAddSeedSleep() seeds everything that fast seeding includes, but | |||||
* additionally: | |||||
* - A high-precision timestamp before and after sleeping 1ms. | |||||
* - (On Windows) Once every 10 minutes, performance monitoring data from the | |||||
* OS. These just exploit the fact the system is idle to improve the quality of | |||||
* the RNG slightly. | |||||
* | |||||
* On first use of the RNG (regardless of what function is called first), all | |||||
* entropy sources used in the 'slow' seeder are included, but also: | |||||
* - (On Windows) Performance monitoring data from the OS. | |||||
* - (On Windows) Through OpenSSL, the screen contents. | |||||
* | |||||
* When mixing in new entropy, H = SHA512(entropy || old_rng_state) is computed, | |||||
* and (up to) the first 32 bytes of H are produced as output, while the last 32 | |||||
* bytes become the new RNG state. | |||||
*/ | |||||
/** | |||||
* Generate random data via the internal PRNG. | * Generate random data via the internal PRNG. | ||||
* | * | ||||
* These functions are designed to be fast (sub microsecond), but do not | * These functions are designed to be fast (sub microsecond), but do not | ||||
* necessarily meaningfully add entropy to the PRNG state. | * necessarily meaningfully add entropy to the PRNG state. | ||||
* | * | ||||
* Thread-safe. | * Thread-safe. | ||||
*/ | */ | ||||
void GetRandBytes(uint8_t *buf, int num) noexcept; | void GetRandBytes(uint8_t *buf, int num) noexcept; | ||||
▲ Show 20 Lines • Show All 183 Lines • Show Last 20 Lines |