1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
8 #include "util.h" // for printf()
11 #include "compat.h" // for Windows API
18 #include <openssl/crypto.h>
19 #include <openssl/err.h>
20 #include <openssl/rand.h>
25 static inline int64_t GetPerformanceCounter()
29 QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
32 gettimeofday(&t, nullptr);
33 nCounter = (int64_t) t.tv_sec * 1000000 + t.tv_usec;
40 // Seed with CPU performance counter
41 int64_t nCounter = GetPerformanceCounter();
42 RAND_add(&nCounter, sizeof(nCounter), 1.5);
43 memset(&nCounter, 0, sizeof(nCounter));
46 void RandAddSeedPerfmon()
51 // This can take up to 2 seconds, so only do it every 10 minutes
52 static int64_t nLastPerfmon;
53 if (GetTime() < nLastPerfmon + 10 * 60)
55 nLastPerfmon = GetTime();
57 // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
58 // Seed with the entire set of perfmon data
59 unsigned char pdata[250000];
60 memset(pdata, 0, sizeof(pdata));
61 unsigned long nSize = sizeof(pdata);
62 long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
63 RegCloseKey(HKEY_PERFORMANCE_DATA);
64 if (ret == ERROR_SUCCESS)
66 RAND_add(pdata, nSize, nSize/100.0);
67 OPENSSL_cleanse(pdata, nSize);
68 printf("RandAddSeed() %lu bytes\n", nSize);
73 void GetRandBytes(unsigned char *buf, int num)
75 if (RAND_bytes(buf, num) != 1) {
76 printf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), nullptr));
81 uint64_t GetRand(uint64_t nMax)
86 // The range of the random source must be a multiple of the modulus
87 // to give every possible output value an equal possibility
88 uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
91 RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
92 while (nRand >= nRange);
93 return (nRand % nMax);
96 int GetRandInt(int nMax)
98 return static_cast<int>(GetRand(nMax));
101 uint256 GetRandHash()
104 RAND_bytes(hash.begin(), hash.size());