Merge #12062: Increment MIT Licence copyright header year on files modified in 2017
[bitcoinplatinum.git] / src / random.h
blobea88670a37305c1bae933a26c220d8ed2d1871e6
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2017 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #ifndef BITCOIN_RANDOM_H
7 #define BITCOIN_RANDOM_H
9 #include <crypto/chacha20.h>
10 #include <crypto/common.h>
11 #include <uint256.h>
13 #include <stdint.h>
15 /* Seed OpenSSL PRNG with additional entropy data */
16 void RandAddSeed();
18 /**
19 * Functions to gather random data via the OpenSSL PRNG
21 void GetRandBytes(unsigned char* buf, int num);
22 uint64_t GetRand(uint64_t nMax);
23 int GetRandInt(int nMax);
24 uint256 GetRandHash();
26 /**
27 * Add a little bit of randomness to the output of GetStrongRangBytes.
28 * This sleeps for a millisecond, so should only be called when there is
29 * no other work to be done.
31 void RandAddSeedSleep();
33 /**
34 * Function to gather random data from multiple sources, failing whenever any
35 * of those source fail to provide a result.
37 void GetStrongRandBytes(unsigned char* buf, int num);
39 /**
40 * Fast randomness source. This is seeded once with secure random data, but
41 * is completely deterministic and insecure after that.
42 * This class is not thread-safe.
44 class FastRandomContext {
45 private:
46 bool requires_seed;
47 ChaCha20 rng;
49 unsigned char bytebuf[64];
50 int bytebuf_size;
52 uint64_t bitbuf;
53 int bitbuf_size;
55 void RandomSeed();
57 void FillByteBuffer()
59 if (requires_seed) {
60 RandomSeed();
62 rng.Output(bytebuf, sizeof(bytebuf));
63 bytebuf_size = sizeof(bytebuf);
66 void FillBitBuffer()
68 bitbuf = rand64();
69 bitbuf_size = 64;
72 public:
73 explicit FastRandomContext(bool fDeterministic = false);
75 /** Initialize with explicit seed (only for testing) */
76 explicit FastRandomContext(const uint256& seed);
78 /** Generate a random 64-bit integer. */
79 uint64_t rand64()
81 if (bytebuf_size < 8) FillByteBuffer();
82 uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
83 bytebuf_size -= 8;
84 return ret;
87 /** Generate a random (bits)-bit integer. */
88 uint64_t randbits(int bits) {
89 if (bits == 0) {
90 return 0;
91 } else if (bits > 32) {
92 return rand64() >> (64 - bits);
93 } else {
94 if (bitbuf_size < bits) FillBitBuffer();
95 uint64_t ret = bitbuf & (~(uint64_t)0 >> (64 - bits));
96 bitbuf >>= bits;
97 bitbuf_size -= bits;
98 return ret;
102 /** Generate a random integer in the range [0..range). */
103 uint64_t randrange(uint64_t range)
105 --range;
106 int bits = CountBits(range);
107 while (true) {
108 uint64_t ret = randbits(bits);
109 if (ret <= range) return ret;
113 /** Generate random bytes. */
114 std::vector<unsigned char> randbytes(size_t len);
116 /** Generate a random 32-bit integer. */
117 uint32_t rand32() { return randbits(32); }
119 /** generate a random uint256. */
120 uint256 rand256();
122 /** Generate a random boolean. */
123 bool randbool() { return randbits(1); }
126 /* Number of random bytes returned by GetOSRand.
127 * When changing this constant make sure to change all call sites, and make
128 * sure that the underlying OS APIs for all platforms support the number.
129 * (many cap out at 256 bytes).
131 static const int NUM_OS_RANDOM_BYTES = 32;
133 /** Get 32 bytes of system entropy. Do not use this in application code: use
134 * GetStrongRandBytes instead.
136 void GetOSRand(unsigned char *ent32);
138 /** Check that OS randomness is available and returning the requested number
139 * of bytes.
141 bool Random_SanityCheck();
143 /** Initialize the RNG. */
144 void RandomInit();
146 #endif // BITCOIN_RANDOM_H