zcashd/src/random.cpp

91 lines
2.1 KiB
C++
Raw Normal View History

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
2014-12-12 20:09:33 -08:00
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#include "random.h"
#include "support/cleanse.h"
#ifdef WIN32
#include "compat.h" // for Windows API
#endif
#include "serialize.h" // for begin_ptr(vec)
#include "util.h" // for LogPrint()
#include "utilstrencodings.h" // for GetTime()
#include <limits>
#ifndef WIN32
#include <sys/time.h>
#endif
#include <librustzcash.h>
static 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;
}
void GetRandBytes(unsigned char* buf, size_t num)
{
librustzcash_getrandom(buf, num);
}
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 {
GetRandBytes((unsigned char*)&nRand, sizeof(nRand));
} while (nRand >= nRange);
return (nRand % nMax);
}
int GetRandInt(int nMax)
{
return GetRand(nMax);
}
uint256 GetRandHash()
{
uint256 hash;
GetRandBytes((unsigned char*)&hash, sizeof(hash));
return hash;
}
Kill insecure_random and associated global state There are only a few uses of `insecure_random` outside the tests. This PR replaces uses of insecure_random (and its accompanying global state) in the core code with an FastRandomContext that is automatically seeded on creation. This is meant to be used for inner loops. The FastRandomContext can be in the outer scope, or the class itself, then rand32() is used inside the loop. Useful e.g. for pushing addresses in CNode or the fee rounding, or randomization for coin selection. As a context is created per purpose, thus it gets rid of cross-thread unprotected shared usage of a single set of globals, this should also get rid of the potential race conditions. - I'd say TxMempool::check is not called enough to warrant using a special fast random context, this is switched to GetRand() (open for discussion...) - The use of `insecure_rand` in ConnectThroughProxy has been replaced by an atomic integer counter. The only goal here is to have a different credentials pair for each connection to go on a different Tor circuit, it does not need to be random nor unpredictable. - To avoid having a FastRandomContext on every CNode, the context is passed into PushAddress as appropriate. There remains an insecure_random for test usage in `test_random.h`. Zcash: Resolved conflicts with the following files src/addrman.cpp src/main.cpp src/net.cpp src/net.h src/policy/fees.cpp src/policy/fees.h src/random.cpp src/test/merkle_tests.cpp src/test/net_tests.cpp src/test/prevector_tests.cpp src/test/sighash_tests.cpp src/test/skiplist_tests.cpp src/test/test_bitcoin.cpp src/test/versionbits_tests.cpp src/wallet/test/crypto_tests.cpp
2016-10-13 07:19:20 -07:00
FastRandomContext::FastRandomContext(bool fDeterministic)
{
// The seed values have some unlikely fixed points which we avoid.
if (fDeterministic) {
Kill insecure_random and associated global state There are only a few uses of `insecure_random` outside the tests. This PR replaces uses of insecure_random (and its accompanying global state) in the core code with an FastRandomContext that is automatically seeded on creation. This is meant to be used for inner loops. The FastRandomContext can be in the outer scope, or the class itself, then rand32() is used inside the loop. Useful e.g. for pushing addresses in CNode or the fee rounding, or randomization for coin selection. As a context is created per purpose, thus it gets rid of cross-thread unprotected shared usage of a single set of globals, this should also get rid of the potential race conditions. - I'd say TxMempool::check is not called enough to warrant using a special fast random context, this is switched to GetRand() (open for discussion...) - The use of `insecure_rand` in ConnectThroughProxy has been replaced by an atomic integer counter. The only goal here is to have a different credentials pair for each connection to go on a different Tor circuit, it does not need to be random nor unpredictable. - To avoid having a FastRandomContext on every CNode, the context is passed into PushAddress as appropriate. There remains an insecure_random for test usage in `test_random.h`. Zcash: Resolved conflicts with the following files src/addrman.cpp src/main.cpp src/net.cpp src/net.h src/policy/fees.cpp src/policy/fees.h src/random.cpp src/test/merkle_tests.cpp src/test/net_tests.cpp src/test/prevector_tests.cpp src/test/sighash_tests.cpp src/test/skiplist_tests.cpp src/test/test_bitcoin.cpp src/test/versionbits_tests.cpp src/wallet/test/crypto_tests.cpp
2016-10-13 07:19:20 -07:00
Rz = Rw = 11;
} else {
uint32_t tmp;
do {
GetRandBytes((unsigned char*)&tmp, 4);
} while (tmp == 0 || tmp == 0x9068ffffU);
Kill insecure_random and associated global state There are only a few uses of `insecure_random` outside the tests. This PR replaces uses of insecure_random (and its accompanying global state) in the core code with an FastRandomContext that is automatically seeded on creation. This is meant to be used for inner loops. The FastRandomContext can be in the outer scope, or the class itself, then rand32() is used inside the loop. Useful e.g. for pushing addresses in CNode or the fee rounding, or randomization for coin selection. As a context is created per purpose, thus it gets rid of cross-thread unprotected shared usage of a single set of globals, this should also get rid of the potential race conditions. - I'd say TxMempool::check is not called enough to warrant using a special fast random context, this is switched to GetRand() (open for discussion...) - The use of `insecure_rand` in ConnectThroughProxy has been replaced by an atomic integer counter. The only goal here is to have a different credentials pair for each connection to go on a different Tor circuit, it does not need to be random nor unpredictable. - To avoid having a FastRandomContext on every CNode, the context is passed into PushAddress as appropriate. There remains an insecure_random for test usage in `test_random.h`. Zcash: Resolved conflicts with the following files src/addrman.cpp src/main.cpp src/net.cpp src/net.h src/policy/fees.cpp src/policy/fees.h src/random.cpp src/test/merkle_tests.cpp src/test/net_tests.cpp src/test/prevector_tests.cpp src/test/sighash_tests.cpp src/test/skiplist_tests.cpp src/test/test_bitcoin.cpp src/test/versionbits_tests.cpp src/wallet/test/crypto_tests.cpp
2016-10-13 07:19:20 -07:00
Rz = tmp;
do {
GetRandBytes((unsigned char*)&tmp, 4);
} while (tmp == 0 || tmp == 0x464fffffU);
Kill insecure_random and associated global state There are only a few uses of `insecure_random` outside the tests. This PR replaces uses of insecure_random (and its accompanying global state) in the core code with an FastRandomContext that is automatically seeded on creation. This is meant to be used for inner loops. The FastRandomContext can be in the outer scope, or the class itself, then rand32() is used inside the loop. Useful e.g. for pushing addresses in CNode or the fee rounding, or randomization for coin selection. As a context is created per purpose, thus it gets rid of cross-thread unprotected shared usage of a single set of globals, this should also get rid of the potential race conditions. - I'd say TxMempool::check is not called enough to warrant using a special fast random context, this is switched to GetRand() (open for discussion...) - The use of `insecure_rand` in ConnectThroughProxy has been replaced by an atomic integer counter. The only goal here is to have a different credentials pair for each connection to go on a different Tor circuit, it does not need to be random nor unpredictable. - To avoid having a FastRandomContext on every CNode, the context is passed into PushAddress as appropriate. There remains an insecure_random for test usage in `test_random.h`. Zcash: Resolved conflicts with the following files src/addrman.cpp src/main.cpp src/net.cpp src/net.h src/policy/fees.cpp src/policy/fees.h src/random.cpp src/test/merkle_tests.cpp src/test/net_tests.cpp src/test/prevector_tests.cpp src/test/sighash_tests.cpp src/test/skiplist_tests.cpp src/test/test_bitcoin.cpp src/test/versionbits_tests.cpp src/wallet/test/crypto_tests.cpp
2016-10-13 07:19:20 -07:00
Rw = tmp;
}
}
int GenIdentity(int n)
{
return n-1;
}