// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "random.h"
#include "support/cleanse.h"
-#ifdef WIN32
+#ifdef _WIN32
#include "compat.h" // for Windows API
#endif
#include "serialize.h" // for begin_ptr(vec)
#include <limits>
-#ifndef WIN32
+#ifndef _WIN32
#include <sys/time.h>
#endif
-#include <openssl/err.h>
-#include <openssl/rand.h>
+#include "sodium.h"
static inline int64_t GetPerformanceCounter()
{
int64_t nCounter = 0;
-#ifdef WIN32
+#ifdef _WIN32
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
#else
timeval t;
return nCounter;
}
-void RandAddSeed()
+void GetRandBytes(unsigned char* buf, size_t num)
{
- // Seed with CPU performance counter
- int64_t nCounter = GetPerformanceCounter();
- RAND_add(&nCounter, sizeof(nCounter), 1.5);
- memory_cleanse((void*)&nCounter, sizeof(nCounter));
-}
-
-void RandAddSeedPerfmon()
-{
- RandAddSeed();
-
-#ifdef WIN32
- // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
- // Seed with the entire set of perfmon data
-
- // This can take up to 2 seconds, so only do it every 10 minutes
- static int64_t nLastPerfmon;
- if (GetTime() < nLastPerfmon + 10 * 60)
- return;
- nLastPerfmon = GetTime();
-
- std::vector<unsigned char> vData(250000, 0);
- long ret = 0;
- unsigned long nSize = 0;
- const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
- while (true) {
- nSize = vData.size();
- ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
- if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
- break;
- vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
- }
- RegCloseKey(HKEY_PERFORMANCE_DATA);
- if (ret == ERROR_SUCCESS) {
- RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
- memory_cleanse(begin_ptr(vData), nSize);
- LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
- } else {
- static bool warned = false; // Warn only once
- if (!warned) {
- LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
- warned = true;
- }
- }
-#endif
-}
-
-void GetRandBytes(unsigned char* buf, int num)
-{
- if (RAND_bytes(buf, num) != 1) {
- LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL));
- assert(false);
- }
+ randombytes_buf(buf, num);
}
uint64_t GetRand(uint64_t nMax)