Crate bitcoin_random

source ·
Expand description

| 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) | | - 64 bits from the 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. | | - 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. | | - RandAddPeriodic() seeds everything that fast | seeding includes, but additionally: | | - A high-precision timestamp | | - Dynamic environment data (performance | monitoring, …) | | - Strengthen the entropy for 10 ms using | repeated SHA512. | | This is run once every minute. | | 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: | | - 256 bits from the hardware RNG | (rdseed or rdrand) when available. | | - Dynamic environment data (performance | monitoring, …) | | - Static environment data | | - Strengthen the entropy for 100 ms using | repeated SHA512. | | 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.

Structs

  • | Fast randomness source. This is seeded | once with secure random data, but is | completely deterministic and does | not gather more entropy after that. | | This class is not thread-safe. |
  • | The RNG state consists of 256 bits of | entropy, taken from the output of one | operation’s SHA512 output, and fed | as input to the next one. | | Carrying 256 bits of entropy should | be sufficient to guarantee unpredictability | as long as any entropy source was ever | unpredictable to an attacker. To protect | against situations where an attacker | might observe the RNG’s state, fresh | entropy is always mixed when | | GetStrongRandBytes is called. |

Enums

Constants

Traits

Functions

  • | Fallback: get 32 bytes of system entropy | from /dev/urandom. The most compatible | way to get cryptographic randomness | on UNIX-ish platforms. |
  • | Fall back to /dev/urandom if there is | no specific method implemented to get | system entropy for this OS. |
  • | Fall back to using C++11 clock (usually | microsecond or nanosecond precision) |
  • | Generate a uniform random integer in | the range [0..range). Precondition: | range > 0 |
  • | Generate random data via the internal | PRNG. | | These functions are designed to be fast | (sub microsecond), but do not necessarily | meaningfully add entropy to the PRNG | state. | | Thread-safe. |
  • | Generate a uniform random duration | in the range [0..max). Precondition: | max.count() > 0 |
  • | Read 64 bits of entropy using rdrand. | | Must only be called when RdRand is supported. |
  • | Read 64 bits of entropy using rdseed. | | Must only be called when RdSeed is supported. |
  • | Gather entropy from various sources, | feed it into the internal PRNG, and generate | random data using it. | | This function will cause failure whenever | the OS RNG fails. | | Thread-safe. |

  • | Gather non-cryptographic environment | data that changes over time. |
  • | Gathers entropy from the low bits of | the time at which events occur. Should | be called with a uint32_t describing | the event at the time an event occurs. | | Thread-safe. |
  • | Gather entropy from various expensive | sources, and feed them to the PRNG state. | | Thread-safe. |
  • | Gather non-cryptographic environment | data that does not change over time. |
  • | Initialize global RNG state and log | any CPU features that are used. | | Calling this function is optional. | RNG state will be initialized when first | needed if it is not called. |
  • | Check that OS randomness is available | and returning the requested number | of bytes. |

  • | Add 64 bits of entropy gathered from | hardware to hasher. Do nothing if not | supported. |
  • | Add 256 bits of entropy gathered from | hardware to hasher. Do nothing if not | supported. |
  • | Extract entropy from rng, strengthen | it, and feed it into hasher. |
  • | A note on the use of in the seeding functions | below: | | None of the RNG code should ever throw | any exception. |
  • | More efficient than using std::shuffle | on a FastRandomContext. | | This is more efficient as std::shuffle | will consume entropy in groups of 64 | bits at the time and throw away most. | | This also works around a bug in libstdc++ | std::shuffle that may cause type::operator=(type&&) | to be invoked on itself, which the library’s | debug mode detects and panics on. This | is a known issue, see https://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle |
  • | Use repeated SHA512 to strengthen the | randomness in seed32, and feed into | hasher. |

Type Definitions