-
Notifications
You must be signed in to change notification settings - Fork 73
Refactoring of random provider #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #53 +/- ##
===========================================
- Coverage 97.41% 97.19% -0.22%
===========================================
Files 11 13 +2
Lines 619 607 -12
===========================================
- Hits 603 590 -13
- Misses 16 17 +1
Continue to review full report at Codecov.
|
| template<class Iter> | ||
| void generate(Iter first, Iter last) | ||
| { | ||
| BOOST_STATIC_ASSERT(sizeof(Iter) >= sizeof(unsigned int)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This checks the iterator size, which is irrelevant. It should check
- whether the
value_typeof the iterator is integral; - whether the
value_typeof the iterator is unsigned; - whether
numeric_limits<value_type>::max()is >= 2^32-1, but this can only be tested at compile time on C++11, so - whether
sizeof(value_type) * CHAR_BIT >= 32.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will update this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this but it didn't work - I'll keep on it.
typedef Iter::value_type iter_value_type;
BOOST_STATIC_ASSERT(is_integral<iter_value_type>::value == true_type);
BOOST_STATIC_ASSERT(is_unsigned<iter_value_type>::value == true_type);
BOOST_STATIC_ASSERT(sizeof(iter_value_type) * CHAR_BIT >= 32);
In reading SeedSeq documentation, Iter can be a class with a value_type type definition of an unsigned integral and an operator*, or it can be a pointer to an unsigned integral, correct? I'm not certain (yet) how I would test for both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typedef std::iterator_traits<Iter>::value_type value_type;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then just BOOST_STATIC_ASSERT( boost::is_integral<value_type>::value );, comparing to the type true_type doesn't make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will work in C++11 because true_type has a constexpr conversion to true but is still nonsensical. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to support C++03, will it still work?
I don't think I have ever used std::iterator_traits before.
I'm learning a ton of new tricks, thanks!
| for (; first != last; ++first) | ||
| { | ||
| get_random_bytes(&*first, sizeof(*first)); | ||
| *first &= (std::numeric_limits<unsigned int>::max)(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not correct. generate is required to produce numbers in [0..2^32-1], regardless of the size of unsigned int.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, I will update this.
| #include <boost/uuid/entropy_error.hpp> | ||
|
|
||
| #include <boost/uuid/detail/random_provider_detect_platform.hpp> | ||
| #include BOOST_UUID_RANDOM_PROVIDER_BASE_INCLUDE() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to just include the appropriate platform header from random_provider_detect_platform.hpp, renaming it into random_provider_base.hpp in the process, because the above confuses dependency scanners; they can't see through the macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed platform detection separate from loading the implementation to make the mocking work properly. I can expand that out so the macro isn't there and put additional preprocessor branches based on the BOOST_UUID_RANDOM_PROVIDER_* definitions made by the detection logic in that header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's better to spell it out with #ifdefs instead of a macro include.
doc/uuid.html
Outdated
| <ul> | ||
| <li> | ||
| <tt>BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX</tt>: on Unix this will force the | ||
| selection of <tt>/dev/*random</tt> over getentropy(3). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer to not provide this. By all means give people a macro to override behavior when they ask for it, no need to to it preemptively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm leveraging this to get coverage and a (mostly) common sad path test. I'll look at testing against the posix.ipp implementation directly when running on linux.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I hadn't yet gotten to the testing part. Keep those macros. I was looking at them from the user side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That'll save a bunch of additional work... thanks.
| </li> | ||
| <li> | ||
| <tt>BOOST_UUID_RANDOM_PROVIDER_FORCE_WINCRYPT</tt>: on Windows this will force the | ||
| selection of Wincrypt over BCrypt. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto. No need to ever prefer the older API. If someone asks for it, fine; until then, no need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm leveraging this to get coverage and a (mostly) common sad path test. This test is more complex as I have to build a DLL and link against it, but I can make another test file that's specific to the wincrypt.ipp file and loads the mock library.
doc/uuid.html
Outdated
| </li> | ||
| <li> | ||
| <tt>BOOST_UUID_RANDOM_PROVIDER_POSIX_BLOCKING</tt>: when using <tt>/dev/*random</tt>, | ||
| if this is defined, skip attempting to open <tt>/dev/urandom</tt> first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. Not only should /dev/random not be configurable to be used as a preference, it should never be used, anywhere, for anything, as the OpenBSD docs say.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Easy to remove. Thanks. Less options too and it simplifies the code and the sad test path that has to account for two open()s in the failure case.
| boost::winapi::NTSTATUS_ status = | ||
| boost::winapi::BCryptGenRandom( | ||
| hProv_, | ||
| reinterpret_cast<boost::winapi::PUCHAR_>(buf), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static_cast is better, when it works, which it does here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, I'll change it. I usually try static_cast first and let the compiler force me the other way.
|
|
||
| #include <boost/predef/library/c/gnu.h> | ||
| #include <boost/predef/platform/cloudabi.h> | ||
| // #include <boost/predef/os/bsd/open.h> re-enable when Boost.Predef #66 clears |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to wait for Predef. The functions we need are available on OpenBSD 2.5 and above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to know, I was planning on getentropy() there so... (on to the next comment)
| #elif BOOST_LIB_C_GNU >= BOOST_VERSION_NUMBER(2, 25, 0) \ | ||
| && !defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX) | ||
| /* when Boost.Prefef #6 merges, allow this based on OpenBSD documentation: | ||
| BOOST_OS_BSD_OPEN >= BOOST_VERSION_NUMBER(5, 6, 0)) */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"getentropy() is not intended for regular code; please use the arc4random(3) family of functions instead."
https://man.openbsd.org/getentropy.2
Heed what the OpenBSD people say. They know their stuff. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and there you go.
| #include <boost/throw_exception.hpp> | ||
| #include <string> | ||
|
|
||
| #if !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BOOST_ALL_NO_LIB, as I already said.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I missed that! Isn't each library capable of having its own preprocessor macros in this area, like BOOST_SYSTEM_NO_LIB, BOOST_CONFIG_NO_LIB, BOOST_PYTHON_NO_LIB...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, but you have to check the global macro as well and not autolink if it's set. It's a global user switch that requests all autolinking to be disabled, anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my builds on Windows with msvc-14.1, BOOST_ALL_NO_LIB is set to 1 by default. This seems odd - why would it be set on the way in? Boost.Uuid does not set it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. No idea why it's set; you'll need to investigate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is defined for all builds of boost, it's in boost.jam. I will add BOOST_UUID_SOURCE and make it conditional on that as well. This pattern is found elsewhere.
| #if defined(BOOST_NO_ANSI_APIS) | ||
| boost::winapi::CryptAcquireContextW | ||
| #else | ||
| boost::winapi::CryptAcquireContextA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason to ever use the A function here, if you ask me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you may be right now that the provider string / enumeration stuff is gone. If so I'll simplify and remove the additional test for this macro.
|
Ah. It now occurs to me that you need the configuration macros in order to force-test a provider when it wouldn't be selected otherwise. Makes sense. |
|
That's what I was using them for, however I could write one test per provider implementation instead I suppose. I just wanted it to be as uniform as possible since they all follow the same pattern. |
|
Yes, you could include the implementation header directly and test that, which is still not a bad idea, but the other way is good too, as it can test the component integrated into the rest of the code. So, either way is fine with me, I suppose. |
|
As an aside, we need to get this level of CI integration into every project. |
|
It still seems to me that RtlGenRandom is quite a convenient choice on Windows as it requires no setup and is quite likely a bit faster than firing up a bcrypt/wincrypt provider. I'm not entirely clear on why you dislike it so. :-) |
|
I believe it would still have a setup cost insofar as needing to perhaps statically initialize the address of the API call through LoadLibrary and GetProcAddress, and in a previous PR I was told to avoid using statics. I agree those two calls are probably much lighter than wincrypt. I can give it a try. |
|
There's no need for works for me. |
|
You are assuming that advapi32.dll has already been loaded, and I think that's an unsafe assumption to make. |
|
It works for me in a sample program. Not sure how I could be assuming anything if the program links. |
|
|
You are still relying on the fact that ADVAPI32.DLL was loaded. While it is in the default library list for most build systems, that can be overridden. ADVAPI32.DLL is not available on Windows CE. Pretty much everyone will be using bcrypt at this point with wincrypt left to cover older platforms. Since that code has worked for a very long time here and in Boost.Random, and seeing as to how it's out of the normal code path, doesn't it make sense to leave it as is? |
|
@pdimov The |
|
Okay that actually wasn't too bad, I'm doing some testing... |
|
It's impossible for a library to not be loaded if you link to it. If that's unsafe, your code is at least 20 times as unsafe. |
| , distribution_type | ||
| ( (std::numeric_limits<unsigned long>::min)() | ||
| , (std::numeric_limits<unsigned long>::max)() | ||
| ( (std::numeric_limits<unsigned int>::min)() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not clear why these changes from ulong to uint are needed. Would probably be better to keep the original to cut down on the delta unless there's a good reason to switch.
test/Jamfile.v2
Outdated
| <define>BOOST_UUID_SOURCE=1 | ||
|
|
||
| # BOOST_AUTO_LINK does not work outside of MSVC on Windows so this makes cygwin, mingw-w64 work: | ||
| <toolset>gcc,<target-os>windows:<linkflags>-lbcrypt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could link here regardless of whether the toolset is gcc (there's also clang btw), and this will fix the lack of autolink when using Boost.Build. But the problem is that we don't necessarily know what to link to.
<linkflags>-lbcrypt isn't correct though, I think that we need lib bcrypt ; and then <library>bcrypt here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try that and see what it does to the mocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any way to negate this (<target-os>windows:<library>bcrypt), so that I can set it in project requirements so everything links against it by default, but then in a specific mock based test negate it so it does NOT link against bcrypt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I vaguely recall that one could use <x>y:-<library>bcrypt to remove it, but I won't be surprised if it doesn't work and I'm imagining things. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out I'm not, in this case. http://www.boost.org/build/doc/html/bbv2/overview/targets.html#bbv2.overview.targets.requirements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Odd, test_serialization passed the second time. Mystery.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of not testing anything, it might be better to disable just test_serialization on mingw and keep testing the rest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cygwin, on the other hand, passes with flying colors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am unable to use the syntax: <target-os>windows:-<library>bcrypt, or <target-os>windows:-<define>BOOST_ALL_NO_LIB - both fail in bjam as an invalid target-os. I'm going back to the logic I had.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If only there existed a simple function in advapi32 that we could just call and avoid all that hassle.
test/Jamfile.v2
Outdated
| [ run test_detail_random_provider.cpp | ||
| : : : | ||
| <define>BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX # will force POSIX over getentropy | ||
| <define>BOOST_UUID_RANDOM_PROVIDER_POSIX_BLOCKING # will force /dev/random over /dev/urandom |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer necessary.
test/test_entropy_error.cpp
Outdated
|
|
||
| entropy_error err(6, "foo"); | ||
| BOOST_TEST_EQ(6, err.errcode()); | ||
| BOOST_TEST_EQ(std::string("foo"), std::string(err.what())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use BOOST_TEST_CSTR_EQ here.
|
AMDG
On 11/08/2017 07:29 PM, James E. King, III wrote:
jeking3 commented on this pull request.
> @@ -7,10 +7,18 @@
project libs/uuid/test
: requirements
- # boost::random requires this setting for a warning free build:
+ # define BOOST_UUID_SOURCE to defeat the default BOOST_ALL_NO_LIB in boost.jam
+ <define>BOOST_UUID_SOURCE=1
+
+ # BOOST_AUTO_LINK does not work outside of MSVC on Windows so this makes cygwin, mingw-w64 work:
+ <toolset>gcc,<target-os>windows:<linkflags>-lbcrypt
I am unable to use the syntax: `<target-os>windows:-<library>bcrypt`, or `<target-os>windows:-<define>BOOST_ALL_NO_LIB` - both fail in bjam as an invalid target-os. I'm going back to the logic I had.
The '-property' syntax is not very user-friendly. Basically,
the property that you remove must be exactly the same as the
property that was added:
-<toolset>gcc,<target-os>windows:<linkflags>-lbcrypt
In Christ,
Steven Watanabe
|
|
I have some changes to support building for CloudABI compatibility since it's in this pull request, now that I was able to build the Boost.Uuid tests under CloudABI. These depend on boostorg/predef#68 so I won't push them until that merges. |
|
One of the developers from CloudABI pointed me to arc4random in cloudlibc so I'm going to remove the cloudabi specific implementation and have it use arc4random. |
|
I'm curious what you think about the scope of this change relative to the upcoming release. I have it marked as a milestone for 1.67.0 and not 1.66.0 right now because it is a lot of change, however it's well tested on every platform, both happy and sad paths. |
|
1.66.0 is closed for beta now so I'd say we missed that boat. |
appveyor.yml
Outdated
| - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||
| ADDPATH: C:\mingw\bin; | ||
| TOOLSET: gcc | ||
| CXXFLAGS: cxxflags=-std=c++03 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new way is cxxstd=03 instead of using cxxflags, which allows testing cxxstd=03,11 or even cxxstd=03,11,14,1z in one go instead of using multiple jobs (slow on Appveyor as they're serialized).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I just re-enabled an old stanza here. The other ones should be using that. If not, I'll adjust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the jobs at https://ci.appveyor.com/project/jeking3/uuid-gaamf/build/1.0.73-develop seem to be using cxxflags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about Travis CI, I'll get this fixed; it's queued up behind boostorg/predef#68 right now.
| # define BOOST_LIB_NAME "advapi32" | ||
| # endif | ||
| # define BOOST_AUTO_LINK_NOMANGLE | ||
| # include <boost/config/auto_link.hpp> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've a strong suspicion that these autolinks are unnecessary. Can't imagine "coredll" not being linked on CE, and "advapi32" is on desktop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, nope, a plain cl doesn't link advapi32 by default, so we do need it, unless Winapi autolinks it for us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly, Cygwin/Mingw g++/clang++ do autolink advapi32 though.
|
This looks good. I however still think that it's way more complex than it would have been with RtlGenRandom on desktop. It's even available by default on Cygwin/Mingw, so things automatically work there even though autolink's not available. |
operating-system provided entropy as it is more secure and faster for the typical use case of generating one uuid at a time. This is a breaking change for anyone passing a mt19937 into one of the explicit constructors of random_generator, which would be quite rare. Changed the default random provider on Windows to use BCrypt where available, falling back to Wincrypt when necessary or when explicitly requested through a macro. Provide a new random_generator_mt19937 type definition for use cases where a large number of uuids need to be created with high performance. This is equivalent to the previous definition of random_generator. Provide a random generation benchmark test showing the cutoff where the mt19937-based generator will outperform the standard generator based on wall time. Removed template specialization for boost::random::random_device so that any UniformRandomNumberGenerator can be used properly with random_generator. Replaced the seed_rng detail implementation (which had a number of flaws) with a replacement header-only random_provider implementation. Note: entropy generation errors will cause an entropy_error to be thrown from random_generator. The previous implementation ignored errors and silently failed. Added internal support for entropy generation on cloudabi platform leveraging the new random_device implementation. Added internal support for Universal Windows Platform (UWP) development leveraging the new random_device implementation. Added internal support for getentropy() on Linux and OpenBSD if certain requirements are met.
|
This (hopyfully last) refresh adds changes to support actually running the test suite on cloudabi in a FreeBSD VM. I switched CloudABI to using arc4random as well. |
|
@swatanabe with one more turn of the crank I think this would be something useful to consider moving into Boost.Random as a replacement for the existing random_device implementation. Given that the random_device inside Boost.Random today is the only piece of code referencing Boost.System, if we did this then Boost.Random would no longer depend on Boost.System. I don't know if that would free up Boost.Random from all library based dependencies though. A fairly simple random_device implementation based on this would be (incomplete...): This would improve the platform coverage of random_device to include UWP and CloudABI, and use more optimal calls on newer versions of Linux. The implementation is also fully tested (happy and sad paths), although the OpenBSD and CloudABI paths are tested manually unless I turn the build into a docker based build. (I have extensive work doing in the Apache Thrift project, so I know this would be possible). |
|
Should I complete the implementation as a random_device replacement and submit it to Boost.Random? |
|
Now that 1.66.0 is closing out, I want to revisit this, but I need an answer, so please reply: Should I complete the implementation as a random_device replacement and submit it to Boost.Random instead? The benefits are:
Thanks - Jim |
|
I thought we've been over this and Boost.Random submission failed, haven't we? My opinion has not changed. You can do it however you like in implementation details of Boost.UUID. A fully compliant implementation of |
|
The right place to ask this question is the list. |
|
I submitted a PR into Boost.Random: boostorg/random#34 - I hadn't heard back from Steven and didn't want to drag the issue up on the mailing list again. |
|
@jeking3 Would you mind sharing the details of the "flaws" you mentioned in "Replaced the seed_rng detail implementation (which had a number of flaws) with a replacement header-only random_provider implementation."? Another implementation difference between seed_rng in 1.66 and the random_provider_base in 1.67 is that seed_rng uses std::fread while the random_provider_base uses ::read. With a synthetic testing it seems the latter is slower when siz is 4 although this only affects seeding. |
|
In particular the code was:
If you have evidence that shows ::read is slower than std::fread then I suggest opening an issue or a pull request with the evidence and the fix. Thanks! |
Changed the default random_generator implementation to use
operating-system provided entropy as it is more secure and
faster for the typical use case of generating one uuid at
a time.
This is a breaking change for anyone passing a mt19937
into one of the explicit constructors of random_generator,
which would be quite rare.
Changed the default random provider on Windows to use BCrypt
where available, falling back to Wincrypt when necessary or
when explicitly requested through a macro.
Provide a new random_generator_mt19937 type definition for
use cases where a large number of uuids need to be created
with high performance. This is equivalent to the previous
definition of random_generator.
Provide a random generation benchmark test showing the
cutoff where the mt19937-based generator will outperform the
standard generator based on wall time.
Removed template specialization for boost::random::random_device
so that any UniformRandomNumberGenerator can be used properly
with random_generator.
Replaced the seed_rng detail implementation (which had a number
of flaws) with a replacement header-only random_provider
implementation.
Note: entropy generation errors will cause an entropy_error
to be thrown from random_generator. The previous implementation
ignored errors and silently failed.
Added internal support for entropy generation on cloudabi
platform leveraging the new random_device implementation.
Added internal support for Universal Windows Platform (UWP)
development leveraging the new random_device implementation.
Added internal support for getentropy() on Linux and OpenBSD
if certain requirements are met.
This is an evolution of #52
This fixes #24