Skip to content

Commit 8cc2f45

Browse files
committed
random: move XoRoShiRo128PlusPlus into random module
This is preparation for making it more generally accessible.
1 parent 8f5ac0d commit 8cc2f45

13 files changed

+78
-104
lines changed

src/Makefile.test.include

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,7 @@ BITCOIN_TESTS =\
173173
test/validation_flush_tests.cpp \
174174
test/validation_tests.cpp \
175175
test/validationinterface_tests.cpp \
176-
test/versionbits_tests.cpp \
177-
test/xoroshiro128plusplus_tests.cpp
176+
test/versionbits_tests.cpp
178177

179178
if ENABLE_WALLET
180179
BITCOIN_TESTS += \

src/Makefile.test_util.include

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ TEST_UTIL_H = \
2323
test/util/str.h \
2424
test/util/transaction_utils.h \
2525
test/util/txmempool.h \
26-
test/util/validation.h \
27-
test/util/xoroshiro128plusplus.h
26+
test/util/validation.h
2827

2928
if ENABLE_WALLET
3029
TEST_UTIL_H += wallet/test/util.h

src/random.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,57 @@ class FastRandomContext : public RandomMixin<FastRandomContext>
349349
void fillrand(Span<std::byte> output) noexcept;
350350
};
351351

352+
/** xoroshiro128++ PRNG. Extremely fast, not appropriate for cryptographic purposes.
353+
*
354+
* Memory footprint is 128bit, period is 2^128 - 1.
355+
* This class is not thread-safe.
356+
*
357+
* Reference implementation available at https://prng.di.unimi.it/xoroshiro128plusplus.c
358+
* See https://prng.di.unimi.it/
359+
*/
360+
class XoRoShiRo128PlusPlus
361+
{
362+
uint64_t m_s0;
363+
uint64_t m_s1;
364+
365+
[[nodiscard]] constexpr static uint64_t SplitMix64(uint64_t& seedval) noexcept
366+
{
367+
uint64_t z = (seedval += 0x9e3779b97f4a7c15);
368+
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
369+
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
370+
return z ^ (z >> 31);
371+
}
372+
373+
public:
374+
using result_type = uint64_t;
375+
376+
constexpr explicit XoRoShiRo128PlusPlus(uint64_t seedval) noexcept
377+
: m_s0(SplitMix64(seedval)), m_s1(SplitMix64(seedval)) {}
378+
379+
// no copy - that is dangerous, we don't want accidentally copy the RNG and then have two streams
380+
// with exactly the same results.
381+
XoRoShiRo128PlusPlus(const XoRoShiRo128PlusPlus&) = delete;
382+
XoRoShiRo128PlusPlus& operator=(const XoRoShiRo128PlusPlus&) = delete;
383+
384+
// allow moves
385+
XoRoShiRo128PlusPlus(XoRoShiRo128PlusPlus&&) = default;
386+
XoRoShiRo128PlusPlus& operator=(XoRoShiRo128PlusPlus&&) = default;
387+
388+
constexpr result_type operator()() noexcept
389+
{
390+
uint64_t s0 = m_s0, s1 = m_s1;
391+
const uint64_t result = std::rotl(s0 + s1, 17) + s0;
392+
s1 ^= s0;
393+
m_s0 = std::rotl(s0, 49) ^ s1 ^ (s1 << 21);
394+
m_s1 = std::rotl(s1, 28);
395+
return result;
396+
}
397+
398+
static constexpr result_type min() noexcept { return std::numeric_limits<result_type>::min(); }
399+
static constexpr result_type max() noexcept { return std::numeric_limits<result_type>::max(); }
400+
static constexpr double entropy() noexcept { return 0.0; }
401+
};
402+
352403
/** More efficient than using std::shuffle on a FastRandomContext.
353404
*
354405
* This is more efficient as std::shuffle will consume entropy in groups of

src/test/fuzz/bip324.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
#include <bip324.h>
66
#include <chainparams.h>
7+
#include <random.h>
78
#include <span.h>
89
#include <test/fuzz/FuzzedDataProvider.h>
910
#include <test/fuzz/fuzz.h>
1011
#include <test/fuzz/util.h>
11-
#include <test/util/xoroshiro128plusplus.h>
1212

1313
#include <cstdint>
1414
#include <vector>

src/test/fuzz/bitset.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <random.h>
56
#include <span.h>
67
#include <test/fuzz/util.h>
7-
#include <test/util/xoroshiro128plusplus.h>
88
#include <util/bitset.h>
99

1010
#include <bitset>

src/test/fuzz/crypto_chacha20.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <crypto/chacha20.h>
6+
#include <random.h>
67
#include <test/fuzz/FuzzedDataProvider.h>
78
#include <test/fuzz/fuzz.h>
89
#include <test/fuzz/util.h>
9-
#include <test/util/xoroshiro128plusplus.h>
1010

1111
#include <array>
1212
#include <cstddef>

src/test/fuzz/p2p_transport_serialization.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <test/fuzz/FuzzedDataProvider.h>
1111
#include <test/fuzz/fuzz.h>
1212
#include <test/fuzz/util.h>
13-
#include <test/util/xoroshiro128plusplus.h>
1413
#include <util/chaintype.h>
1514

1615
#include <cassert>

src/test/fuzz/poolresource.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <random.h>
56
#include <span.h>
67
#include <support/allocators/pool.h>
78
#include <test/fuzz/FuzzedDataProvider.h>
89
#include <test/fuzz/fuzz.h>
910
#include <test/fuzz/util.h>
1011
#include <test/util/poolresourcetester.h>
11-
#include <test/util/xoroshiro128plusplus.h>
1212

1313
#include <cstdint>
1414
#include <tuple>

src/test/fuzz/vecdeque.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <random.h>
56
#include <span.h>
67
#include <test/fuzz/util.h>
7-
#include <test/util/xoroshiro128plusplus.h>
88
#include <util/vecdeque.h>
99

1010
#include <deque>

src/test/random_tests.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,21 @@ BOOST_AUTO_TEST_CASE(shuffle_stat_test)
219219
BOOST_CHECK_EQUAL(sum, 12000U);
220220
}
221221

222+
BOOST_AUTO_TEST_CASE(xoroshiro128plusplus_reference_values)
223+
{
224+
// numbers generated from reference implementation
225+
XoRoShiRo128PlusPlus rng(0);
226+
BOOST_TEST(0x6f68e1e7e2646ee1 == rng());
227+
BOOST_TEST(0xbf971b7f454094ad == rng());
228+
BOOST_TEST(0x48f2de556f30de38 == rng());
229+
BOOST_TEST(0x6ea7c59f89bbfc75 == rng());
230+
231+
// seed with a random number
232+
rng = XoRoShiRo128PlusPlus(0x1a26f3fa8546b47a);
233+
BOOST_TEST(0xc8dc5e08d844ac7d == rng());
234+
BOOST_TEST(0x5b5f1f6d499dad1b == rng());
235+
BOOST_TEST(0xbeb0031f93313d6f == rng());
236+
BOOST_TEST(0xbfbcf4f43a264497 == rng());
237+
}
238+
222239
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)