You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

random.h 3.7KB

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