mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-30 04:32:21 +02:00
random: move XoRoShiRo128PlusPlus into random module
This is preparation for making it more generally accessible.
This commit is contained in:
parent
8f5ac0d0b6
commit
8cc2f45065
@ -173,8 +173,7 @@ BITCOIN_TESTS =\
|
|||||||
test/validation_flush_tests.cpp \
|
test/validation_flush_tests.cpp \
|
||||||
test/validation_tests.cpp \
|
test/validation_tests.cpp \
|
||||||
test/validationinterface_tests.cpp \
|
test/validationinterface_tests.cpp \
|
||||||
test/versionbits_tests.cpp \
|
test/versionbits_tests.cpp
|
||||||
test/xoroshiro128plusplus_tests.cpp
|
|
||||||
|
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
BITCOIN_TESTS += \
|
BITCOIN_TESTS += \
|
||||||
|
@ -23,8 +23,7 @@ TEST_UTIL_H = \
|
|||||||
test/util/str.h \
|
test/util/str.h \
|
||||||
test/util/transaction_utils.h \
|
test/util/transaction_utils.h \
|
||||||
test/util/txmempool.h \
|
test/util/txmempool.h \
|
||||||
test/util/validation.h \
|
test/util/validation.h
|
||||||
test/util/xoroshiro128plusplus.h
|
|
||||||
|
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
TEST_UTIL_H += wallet/test/util.h
|
TEST_UTIL_H += wallet/test/util.h
|
||||||
|
51
src/random.h
51
src/random.h
@ -349,6 +349,57 @@ public:
|
|||||||
void fillrand(Span<std::byte> output) noexcept;
|
void fillrand(Span<std::byte> output) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** xoroshiro128++ PRNG. Extremely fast, not appropriate for cryptographic purposes.
|
||||||
|
*
|
||||||
|
* Memory footprint is 128bit, period is 2^128 - 1.
|
||||||
|
* This class is not thread-safe.
|
||||||
|
*
|
||||||
|
* Reference implementation available at https://prng.di.unimi.it/xoroshiro128plusplus.c
|
||||||
|
* See https://prng.di.unimi.it/
|
||||||
|
*/
|
||||||
|
class XoRoShiRo128PlusPlus
|
||||||
|
{
|
||||||
|
uint64_t m_s0;
|
||||||
|
uint64_t m_s1;
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr static uint64_t SplitMix64(uint64_t& seedval) noexcept
|
||||||
|
{
|
||||||
|
uint64_t z = (seedval += 0x9e3779b97f4a7c15);
|
||||||
|
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
||||||
|
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
||||||
|
return z ^ (z >> 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
using result_type = uint64_t;
|
||||||
|
|
||||||
|
constexpr explicit XoRoShiRo128PlusPlus(uint64_t seedval) noexcept
|
||||||
|
: m_s0(SplitMix64(seedval)), m_s1(SplitMix64(seedval)) {}
|
||||||
|
|
||||||
|
// no copy - that is dangerous, we don't want accidentally copy the RNG and then have two streams
|
||||||
|
// with exactly the same results.
|
||||||
|
XoRoShiRo128PlusPlus(const XoRoShiRo128PlusPlus&) = delete;
|
||||||
|
XoRoShiRo128PlusPlus& operator=(const XoRoShiRo128PlusPlus&) = delete;
|
||||||
|
|
||||||
|
// allow moves
|
||||||
|
XoRoShiRo128PlusPlus(XoRoShiRo128PlusPlus&&) = default;
|
||||||
|
XoRoShiRo128PlusPlus& operator=(XoRoShiRo128PlusPlus&&) = default;
|
||||||
|
|
||||||
|
constexpr result_type operator()() noexcept
|
||||||
|
{
|
||||||
|
uint64_t s0 = m_s0, s1 = m_s1;
|
||||||
|
const uint64_t result = std::rotl(s0 + s1, 17) + s0;
|
||||||
|
s1 ^= s0;
|
||||||
|
m_s0 = std::rotl(s0, 49) ^ s1 ^ (s1 << 21);
|
||||||
|
m_s1 = std::rotl(s1, 28);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr result_type min() noexcept { return std::numeric_limits<result_type>::min(); }
|
||||||
|
static constexpr result_type max() noexcept { return std::numeric_limits<result_type>::max(); }
|
||||||
|
static constexpr double entropy() noexcept { return 0.0; }
|
||||||
|
};
|
||||||
|
|
||||||
/** More efficient than using std::shuffle on a FastRandomContext.
|
/** More efficient than using std::shuffle on a FastRandomContext.
|
||||||
*
|
*
|
||||||
* This is more efficient as std::shuffle will consume entropy in groups of
|
* This is more efficient as std::shuffle will consume entropy in groups of
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#include <bip324.h>
|
#include <bip324.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
#include <random.h>
|
||||||
#include <span.h>
|
#include <span.h>
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
#include <test/util/xoroshiro128plusplus.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <random.h>
|
||||||
#include <span.h>
|
#include <span.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
#include <test/util/xoroshiro128plusplus.h>
|
|
||||||
#include <util/bitset.h>
|
#include <util/bitset.h>
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <crypto/chacha20.h>
|
#include <crypto/chacha20.h>
|
||||||
|
#include <random.h>
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
#include <test/util/xoroshiro128plusplus.h>
|
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
#include <test/util/xoroshiro128plusplus.h>
|
|
||||||
#include <util/chaintype.h>
|
#include <util/chaintype.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <random.h>
|
||||||
#include <span.h>
|
#include <span.h>
|
||||||
#include <support/allocators/pool.h>
|
#include <support/allocators/pool.h>
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
#include <test/util/poolresourcetester.h>
|
#include <test/util/poolresourcetester.h>
|
||||||
#include <test/util/xoroshiro128plusplus.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <random.h>
|
||||||
#include <span.h>
|
#include <span.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
#include <test/util/xoroshiro128plusplus.h>
|
|
||||||
#include <util/vecdeque.h>
|
#include <util/vecdeque.h>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
@ -219,4 +219,21 @@ BOOST_AUTO_TEST_CASE(shuffle_stat_test)
|
|||||||
BOOST_CHECK_EQUAL(sum, 12000U);
|
BOOST_CHECK_EQUAL(sum, 12000U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(xoroshiro128plusplus_reference_values)
|
||||||
|
{
|
||||||
|
// numbers generated from reference implementation
|
||||||
|
XoRoShiRo128PlusPlus rng(0);
|
||||||
|
BOOST_TEST(0x6f68e1e7e2646ee1 == rng());
|
||||||
|
BOOST_TEST(0xbf971b7f454094ad == rng());
|
||||||
|
BOOST_TEST(0x48f2de556f30de38 == rng());
|
||||||
|
BOOST_TEST(0x6ea7c59f89bbfc75 == rng());
|
||||||
|
|
||||||
|
// seed with a random number
|
||||||
|
rng = XoRoShiRo128PlusPlus(0x1a26f3fa8546b47a);
|
||||||
|
BOOST_TEST(0xc8dc5e08d844ac7d == rng());
|
||||||
|
BOOST_TEST(0x5b5f1f6d499dad1b == rng());
|
||||||
|
BOOST_TEST(0xbeb0031f93313d6f == rng());
|
||||||
|
BOOST_TEST(0xbfbcf4f43a264497 == rng());
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
// Copyright (c) 2022 The Bitcoin Core developers
|
|
||||||
// Distributed under the MIT software license, see the accompanying
|
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
|
|
||||||
#ifndef BITCOIN_TEST_UTIL_XOROSHIRO128PLUSPLUS_H
|
|
||||||
#define BITCOIN_TEST_UTIL_XOROSHIRO128PLUSPLUS_H
|
|
||||||
|
|
||||||
#include <bit>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
/** xoroshiro128++ PRNG. Extremely fast, not appropriate for cryptographic purposes.
|
|
||||||
*
|
|
||||||
* Memory footprint is 128bit, period is 2^128 - 1.
|
|
||||||
* This class is not thread-safe.
|
|
||||||
*
|
|
||||||
* Reference implementation available at https://prng.di.unimi.it/xoroshiro128plusplus.c
|
|
||||||
* See https://prng.di.unimi.it/
|
|
||||||
*/
|
|
||||||
class XoRoShiRo128PlusPlus
|
|
||||||
{
|
|
||||||
uint64_t m_s0;
|
|
||||||
uint64_t m_s1;
|
|
||||||
|
|
||||||
[[nodiscard]] constexpr static uint64_t SplitMix64(uint64_t& seedval) noexcept
|
|
||||||
{
|
|
||||||
uint64_t z = (seedval += 0x9e3779b97f4a7c15);
|
|
||||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
|
||||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
|
||||||
return z ^ (z >> 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
using result_type = uint64_t;
|
|
||||||
|
|
||||||
constexpr explicit XoRoShiRo128PlusPlus(uint64_t seedval) noexcept
|
|
||||||
: m_s0(SplitMix64(seedval)), m_s1(SplitMix64(seedval)) {}
|
|
||||||
|
|
||||||
// no copy - that is dangerous, we don't want accidentally copy the RNG and then have two streams
|
|
||||||
// with exactly the same results.
|
|
||||||
XoRoShiRo128PlusPlus(const XoRoShiRo128PlusPlus&) = delete;
|
|
||||||
XoRoShiRo128PlusPlus& operator=(const XoRoShiRo128PlusPlus&) = delete;
|
|
||||||
|
|
||||||
// allow moves
|
|
||||||
XoRoShiRo128PlusPlus(XoRoShiRo128PlusPlus&&) = default;
|
|
||||||
XoRoShiRo128PlusPlus& operator=(XoRoShiRo128PlusPlus&&) = default;
|
|
||||||
|
|
||||||
constexpr result_type operator()() noexcept
|
|
||||||
{
|
|
||||||
uint64_t s0 = m_s0, s1 = m_s1;
|
|
||||||
const uint64_t result = std::rotl(s0 + s1, 17) + s0;
|
|
||||||
s1 ^= s0;
|
|
||||||
m_s0 = std::rotl(s0, 49) ^ s1 ^ (s1 << 21);
|
|
||||||
m_s1 = std::rotl(s1, 28);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr result_type min() noexcept { return std::numeric_limits<result_type>::min(); }
|
|
||||||
static constexpr result_type max() noexcept { return std::numeric_limits<result_type>::max(); }
|
|
||||||
static constexpr double entropy() noexcept { return 0.0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BITCOIN_TEST_UTIL_XOROSHIRO128PLUSPLUS_H
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright (c) 2022 The Bitcoin Core developers
|
|
||||||
// Distributed under the MIT software license, see the accompanying
|
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
|
|
||||||
#include <test/util/setup_common.h>
|
|
||||||
#include <test/util/xoroshiro128plusplus.h>
|
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(xoroshiro128plusplus_tests, BasicTestingSetup)
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(reference_values)
|
|
||||||
{
|
|
||||||
// numbers generated from reference implementation
|
|
||||||
XoRoShiRo128PlusPlus rng(0);
|
|
||||||
BOOST_TEST(0x6f68e1e7e2646ee1 == rng());
|
|
||||||
BOOST_TEST(0xbf971b7f454094ad == rng());
|
|
||||||
BOOST_TEST(0x48f2de556f30de38 == rng());
|
|
||||||
BOOST_TEST(0x6ea7c59f89bbfc75 == rng());
|
|
||||||
|
|
||||||
// seed with a random number
|
|
||||||
rng = XoRoShiRo128PlusPlus(0x1a26f3fa8546b47a);
|
|
||||||
BOOST_TEST(0xc8dc5e08d844ac7d == rng());
|
|
||||||
BOOST_TEST(0x5b5f1f6d499dad1b == rng());
|
|
||||||
BOOST_TEST(0xbeb0031f93313d6f == rng());
|
|
||||||
BOOST_TEST(0xbfbcf4f43a264497 == rng());
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -57,7 +57,8 @@ unsigned-integer-overflow:CBlockPolicyEstimator::processBlockTx
|
|||||||
unsigned-integer-overflow:TxConfirmStats::EstimateMedianVal
|
unsigned-integer-overflow:TxConfirmStats::EstimateMedianVal
|
||||||
unsigned-integer-overflow:prevector.h
|
unsigned-integer-overflow:prevector.h
|
||||||
unsigned-integer-overflow:EvalScript
|
unsigned-integer-overflow:EvalScript
|
||||||
unsigned-integer-overflow:xoroshiro128plusplus.h
|
unsigned-integer-overflow:XoRoShiRo128PlusPlus::operator()
|
||||||
|
unsigned-integer-overflow:XoRoShiRo128PlusPlus::SplitMix64
|
||||||
unsigned-integer-overflow:bitset_detail::PopCount
|
unsigned-integer-overflow:bitset_detail::PopCount
|
||||||
implicit-integer-sign-change:CBlockPolicyEstimator::processBlockTx
|
implicit-integer-sign-change:CBlockPolicyEstimator::processBlockTx
|
||||||
implicit-integer-sign-change:SetStdinEcho
|
implicit-integer-sign-change:SetStdinEcho
|
||||||
@ -75,6 +76,6 @@ shift-base:arith_uint256.cpp
|
|||||||
shift-base:crypto/
|
shift-base:crypto/
|
||||||
shift-base:streams.h
|
shift-base:streams.h
|
||||||
shift-base:FormatHDKeypath
|
shift-base:FormatHDKeypath
|
||||||
shift-base:xoroshiro128plusplus.h
|
shift-base:XoRoShiRo128PlusPlus::operator()
|
||||||
shift-base:RandomMixin<*>::randbits
|
shift-base:RandomMixin<*>::randbits
|
||||||
shift-base:RandomMixin<*>::randbits<*>
|
shift-base:RandomMixin<*>::randbits<*>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user