diff --git a/src/ripple/basics/random.h b/src/ripple/basics/random.h index 8b55d29d1..516eeefa7 100644 --- a/src/ripple/basics/random.h +++ b/src/ripple/basics/random.h @@ -21,13 +21,13 @@ #define RIPPLE_BASICS_RANDOM_H_INCLUDED #include -#include #include #include #include #include #include #include +#include #include // namespace ripple { @@ -67,27 +67,30 @@ inline beast::xor_shift_engine& default_prng () { - static - boost::thread_specific_ptr engine; - - if (!engine.get()) + // This is used to seed the thread-specific PRNGs on demand + static beast::xor_shift_engine seeder = [] { std::random_device rng; + std::uniform_int_distribution distribution{1}; + return beast::xor_shift_engine(distribution(rng)); + }(); - std::uint64_t seed = rng(); + // This protects the seeder + static std::mutex m; - for (int i = 0; i < 6; ++i) + // The thread-specific PRNGs: + thread_local beast::xor_shift_engine engine = [] + { + std::uint64_t seed; { - if (seed == 0) - seed = rng(); - - seed ^= (seed << (7 - i)) * rng(); + std::lock_guard lk(m); + std::uniform_int_distribution distribution{1}; + seed = distribution(seeder); } + return beast::xor_shift_engine{seed}; + }(); - engine.reset (new beast::xor_shift_engine (seed)); - } - - return *engine; + return engine; } /** Return a uniformly distributed random integer. @@ -100,8 +103,8 @@ default_prng () The randomness is generated by the specified engine (or the default engine if one is not specified). The result - is only cryptographicallys secure if the PRNG engine is - cryptographically secure. + is cryptographically secure only when the engine passed + into the function is cryptographically secure. @note The range is always a closed interval, so calling rand_int(-5, 15) can return any integer in the