Move rand functions from util to new random.h/.cpp
authorsvost <ya.nowa@yandex.ru>
Sun, 13 Feb 2022 11:33:15 +0000 (14:33 +0300)
committersvost <ya.nowa@yandex.ru>
Sun, 13 Feb 2022 11:33:15 +0000 (14:33 +0300)
16 files changed:
CMakeLists.txt
src/CMakeLists.txt
src/addrman.cpp
src/addrman.h
src/bitcoinrpc.cpp
src/db.cpp
src/net.cpp
src/net.h
src/random.cpp [new file with mode: 0644]
src/random.h [new file with mode: 0644]
src/script.cpp
src/uint256.cpp
src/uint256.h
src/util.cpp
src/util.h
src/wallet.cpp

index 45ba823..4167062 100644 (file)
@@ -125,6 +125,7 @@ set(generic_sources
     ${CMAKE_CURRENT_SOURCE_DIR}/src/streams.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/src/miner.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/random.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/src/init.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/src/net.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/src/stun.cpp
index 230defa..183d941 100644 (file)
@@ -100,6 +100,7 @@ set(generic_sources
     ${CMAKE_CURRENT_SOURCE_DIR}/noui.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/ntp.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/protocol.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/random.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/rpcblockchain.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/rpcdump.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/rpcmining.cpp
index a754926..6c3f394 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "addrman.h"
 #include "hash.h"
+#include "random.h"
 #include "streams.h"
 
 using namespace std;
@@ -538,3 +539,13 @@ void CAddrMan::Connected_(const CService &addr, int64_t nTime)
     if (nTime - info.nTime > nUpdateInterval)
         info.nTime = nTime;
 }
+
+CAddrMan::CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>())
+{
+    nKey.resize(32);
+    GetRandBytes(&nKey[0], 32);
+
+    nIdCount = 0;
+    nTried = 0;
+    nNew = 0;
+}
index 69a1271..80ef713 100644 (file)
 #include "util.h"
 #include "sync.h"
 
-
 #include <map>
 #include <vector>
 
-#include <openssl/rand.h>
-
 
 /** Extended statistics about a CAddress */
 class CAddrInfo : public CAddress
@@ -421,15 +418,7 @@ public:
             )
 
 
-    CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>())
-    {
-         nKey.resize(32);
-         RAND_bytes(&nKey[0], 32);
-
-         nIdCount = 0;
-         nTried = 0;
-         nNew = 0;
-    }
+    CAddrMan();
 
     // Return the number of (unique) addresses in all tables.
     int size()
index dafacef..a0342c0 100644 (file)
@@ -473,7 +473,7 @@ void StartRPCServer()
     if (mapArgs["-rpcpassword"].empty())
     {
         unsigned char rand_pwd[32];
-        RAND_bytes(rand_pwd, 32);
+        GetRandBytes(rand_pwd, 32);
         std::string strWhatAmI = "To use novacoind";
         if (mapArgs.count("-server"))
             strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
index 946454d..78e2495 100644 (file)
@@ -497,7 +497,7 @@ bool CAddrDB::Write(const CAddrMan& addr)
 {
     // Generate random temporary filename
     unsigned short randv = 0;
-    RAND_bytes((unsigned char *)&randv, sizeof(randv));
+    GetRandBytes((unsigned char *)&randv, sizeof(randv));
     std::string tmpfn = strprintf("peers.dat.%04x", randv);
 
     // serialize addresses, checksum data up to that point, then append csum
index 28f40b8..cd89567 100644 (file)
@@ -528,7 +528,7 @@ void CNode::PushVersion()
         addrMe = GetLocalAddress(&addr);
     }
 
-    RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
+    GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
     printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
index 11963b0..fd8174b 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -10,8 +10,7 @@
 #include "addrman.h"
 #include "hash.h"
 #include "streams.h"
-
-#include <openssl/rand.h>
+#include "random.h"
 
 #ifndef WIN32
 #include <arpa/inet.h>
@@ -477,7 +476,7 @@ public:
                      void (*fn)(void*, CDataStream&), void* param1)
     {
         uint256 hashReply;
-        RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
+        GetRandBytes((unsigned char*)&hashReply, sizeof(hashReply));
 
         {
             LOCK(cs_mapRequests);
@@ -492,7 +491,7 @@ public:
                      void (*fn)(void*, CDataStream&), void* param1)
     {
         uint256 hashReply;
-        RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
+        GetRandBytes((unsigned char*)&hashReply, sizeof(hashReply));
 
         {
             LOCK(cs_mapRequests);
@@ -507,7 +506,7 @@ public:
                      void (*fn)(void*, CDataStream&), void* param1)
     {
         uint256 hashReply;
-        RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
+        GetRandBytes((unsigned char*)&hashReply, sizeof(hashReply));
 
         {
             LOCK(cs_mapRequests);
diff --git a/src/random.cpp b/src/random.cpp
new file mode 100644 (file)
index 0000000..00af04f
--- /dev/null
@@ -0,0 +1,106 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "random.h"
+#include "uint256.h"
+#include "util.h" // for printf()
+
+#ifdef WIN32
+#include "compat.h" // for Windows API
+#endif
+
+#ifndef WIN32
+#include <sys/time.h>
+#endif
+
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#include <cstring>
+
+
+static inline int64_t GetPerformanceCounter()
+{
+    int64_t nCounter = 0;
+#ifdef WIN32
+    QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
+#else
+    timeval t{};
+    gettimeofday(&t, nullptr);
+    nCounter = (int64_t) t.tv_sec * 1000000 + t.tv_usec;
+#endif
+    return nCounter;
+}
+
+void RandAddSeed()
+{
+    // Seed with CPU performance counter
+    int64_t nCounter = GetPerformanceCounter();
+    RAND_add(&nCounter, sizeof(nCounter), 1.5);
+    memset(&nCounter, 0, sizeof(nCounter));
+}
+
+void RandAddSeedPerfmon()
+{
+    RandAddSeed();
+
+#ifdef WIN32
+    // 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();
+
+    // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
+    // Seed with the entire set of perfmon data
+    unsigned char pdata[250000];
+    memset(pdata, 0, sizeof(pdata));
+    unsigned long nSize = sizeof(pdata);
+    long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
+    RegCloseKey(HKEY_PERFORMANCE_DATA);
+    if (ret == ERROR_SUCCESS)
+    {
+        RAND_add(pdata, nSize, nSize/100.0);
+        OPENSSL_cleanse(pdata, nSize);
+        printf("RandAddSeed() %lu bytes\n", nSize);
+    }
+#endif
+}
+
+void GetRandBytes(unsigned char *buf, int num)
+{
+    if (RAND_bytes(buf, num) != 1) {
+        printf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), nullptr));
+        assert(false);
+    }
+}
+
+uint64_t GetRand(uint64_t nMax)
+{
+    if (nMax == 0)
+        return 0;
+
+    // The range of the random source must be a multiple of the modulus
+    // to give every possible output value an equal possibility
+    uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
+    uint64_t nRand = 0;
+    do
+        RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
+    while (nRand >= nRange);
+    return (nRand % nMax);
+}
+
+int GetRandInt(int nMax)
+{
+    return static_cast<int>(GetRand(nMax));
+}
+
+uint256 GetRandHash()
+{
+    uint256 hash;
+    RAND_bytes(hash.begin(), hash.size());
+    return hash;
+}
diff --git a/src/random.h b/src/random.h
new file mode 100644 (file)
index 0000000..41c2d34
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_RANDOM_H
+#define BITCOIN_RANDOM_H
+
+#include <cstdint>
+
+class uint256;
+
+/**
+ * Seed OpenSSL PRNG with additional entropy data
+ */
+void RandAddSeed();
+void RandAddSeedPerfmon();
+
+/**
+ * Functions to gather random data via the OpenSSL PRNG
+ */
+void GetRandBytes(unsigned char *buf, int num);
+uint64_t GetRand(uint64_t nMax);
+int GetRandInt(int nMax);
+uint256 GetRandHash();
+
+#endif // BITCOIN_RANDOM_H
index a72868a..aa3fe8c 100644 (file)
@@ -7,6 +7,7 @@
 #include "keystore.h"
 #include "key.h"
 #include "main.h"
+#include "random.h"
 #include "sync.h"
 #include "util.h"
 #include "base58.h"
index 2d65072..8faf052 100644 (file)
@@ -3,11 +3,8 @@
 // Distributed under the MIT/X11 software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
-
 #include "uint256.h"
 
-#include <openssl/rand.h>
-
 #include <cassert>
 #include <cstdio>
 #include <cstring>
@@ -216,10 +213,3 @@ uint256::uint256(const std::vector<unsigned char>& vch)
     else
         *this = 0;
 }
-
-uint256 GetRandHash()
-{
-    uint256 hash;
-    RAND_bytes(hash.begin(), hash.size());
-    return hash;
-}
index 4d60835..d6cd23f 100644 (file)
@@ -584,6 +584,4 @@ inline const uint256 operator|(const uint256& a, const uint256& b)      { return
 inline const uint256 operator+(const uint256& a, const uint256& b)      { return (base_uint256)a +  (base_uint256)b; }
 inline const uint256 operator-(const uint256& a, const uint256& b)      { return (base_uint256)a -  (base_uint256)b; }
 
-uint256 GetRandHash();
-
 #endif
index 2c5ec84..cd750ab 100644 (file)
@@ -6,6 +6,7 @@
 #include "util.h"
 #include "allocators.h"
 #include "interface.h"
+#include "random.h"
 #include "sync.h"
 #include "version.h"
 
@@ -114,67 +115,6 @@ public:
 instance_of_cinit;
 
 
-
-
-
-
-
-
-void RandAddSeed()
-{
-    // Seed with CPU performance counter
-    int64_t nCounter = GetPerformanceCounter();
-    RAND_add(&nCounter, sizeof(nCounter), 1.5);
-    memset(&nCounter, 0, sizeof(nCounter));
-}
-
-void RandAddSeedPerfmon()
-{
-    RandAddSeed();
-
-    // 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();
-
-#ifdef WIN32
-    // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
-    // Seed with the entire set of perfmon data
-    unsigned char pdata[250000];
-    memset(pdata, 0, sizeof(pdata));
-    unsigned long nSize = sizeof(pdata);
-    long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
-    RegCloseKey(HKEY_PERFORMANCE_DATA);
-    if (ret == ERROR_SUCCESS)
-    {
-        RAND_add(pdata, nSize, nSize/100.0);
-        OPENSSL_cleanse(pdata, nSize);
-        printf("RandAddSeed() %lu bytes\n", nSize);
-    }
-#endif
-}
-
-uint64_t GetRand(uint64_t nMax)
-{
-    if (nMax == 0)
-        return 0;
-
-    // The range of the random source must be a multiple of the modulus
-    // to give every possible output value an equal possibility
-    uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
-    uint64_t nRand = 0;
-    do
-        RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
-    while (nRand >= nRange);
-    return (nRand % nMax);
-}
-
-int GetRandInt(int nMax)
-{
-    return static_cast<int>(GetRand(nMax));
-}
-
 static FILE* fileout = NULL;
 
 inline int OutputDebugStringF(const char* pszFormat, ...)
index d350ed4..8a37c03 100644 (file)
@@ -142,12 +142,6 @@ inline void Sleep(int64_t n)
 #endif
 
 
-
-
-
-
-
-
 extern std::map<std::string, std::string> mapArgs;
 extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
 extern bool fDebug;
@@ -165,8 +159,6 @@ extern bool fNoListen;
 extern bool fLogTimestamps;
 extern bool fReopenDebugLog;
 
-void RandAddSeed();
-void RandAddSeedPerfmon();
 int ATTR_WARN_PRINTF(1,2) OutputDebugStringF(const char* pszFormat, ...);
 
 /*
@@ -235,8 +227,6 @@ void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map
 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
 #endif
 void ShrinkDebugFile();
-int GetRandInt(int nMax);
-uint64_t GetRand(uint64_t nMax);
 int64_t GetTime();
 int64_t GetTimeMillis();
 int64_t GetTimeMicros();
@@ -245,13 +235,6 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const
 void runCommand(std::string strCommand);
 
 
-
-
-
-
-
-
-
 inline std::string i64tostr(int64_t n)
 {
     return strprintf("%" PRId64, n);
@@ -365,19 +348,6 @@ inline void PrintHex(const std::vector<unsigned char>& vch, const char* pszForma
     printf(pszFormat, HexStr(vch, fSpaces).c_str());
 }
 
-inline int64_t GetPerformanceCounter()
-{
-    int64_t nCounter = 0;
-#ifdef WIN32
-    QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
-#else
-    timeval t;
-    gettimeofday(&t, NULL);
-    nCounter = (int64_t) t.tv_sec * 1000000 + t.tv_usec;
-#endif
-    return nCounter;
-}
-
 inline int64_t GetTimeMillis()
 {
     return (boost::posix_time::microsec_clock::universal_time() -
index 75c9f31..1602479 100644 (file)
@@ -379,13 +379,13 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
     RandAddSeedPerfmon();
 
     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
-    RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
+    GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
 
     CMasterKey kMasterKey;
 
     RandAddSeedPerfmon();
     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
-    RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
+    GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
 
     CCrypter crypter;
     int64_t nStartTime = GetTimeMillis();