On 11/04/17 18:40, Peter Dimov via Boost wrote:
Andrey Semashev wrote:
The proposal to make Boost.Random header-only was rejected by Steven.
This sounds like essential context that might have been worth mentioning. :-)
Steven is right that we're still dependent on Boost.System, this needs to be solved somehow.
I think, Steven was more opposed to the whole idea of header-only code, regardless of implementation.
To get back to Uuid. The whole seed_rng file needs to be retired. It's only an implementation detail of a primitive operation that returns N random bytes. At the time seed_rng was written, there was no good way of obtaining high quality randomness from the OS, but this is not the case today.
What the Uuid library needs, when generating a random UUID, is just an array of random bytes; there's no need to create a random number generator, then seed it. None at all. This is historical baggage.
Well, not exactly. I agree that some code in seed_rng.hpp is unneccessary and outdated. But certainly not all of it. Boost.UUID needs a good PRNG, preferably a fast one. An RNG that blocks if there's not enough entropy is not suitable. If OS provides such PRNG then great, we can use it. I'm not sure every platform does, though. In particular, I'm not sure Windows APIs guarantee the non-blocking behavior. Another point to consider is whether we want to deplete system entropy pool when generating lots of UUIDs. The primary property we need from random numbers is uniqueness; we don't require cryprographical randomness for every byte of an UUID or maybe even every generated UUID.
And in my opinion, all the conceptification and templatization in James's PR is completely unnecessary and just adds complexity. What we need is this:
namespace boost { int get_random_bytes( void * buffer, size_t size ); // returns errno }
This happens to match the Linux function with the same name but this is coincidental.
The implementation of this function needs to
- read from /dev/urandom on POSIX
There are also Linux-specific getrandom and BSD-specific getentropy.
- use RtlGenRandom on Windows desktop
IIRC, it's only available since Vista or 7? I forget.
- use Bcrypt on Windows non-desktop
The devil is in the details, as usually. The function is not the proper interface for such a tool because, e.g. in case of /dev/urandom-based implementation, it will have to open/close a file on every call. This is an additional source of failure and an attack vector. The standard interface for system RNG is std::random_device, which you can create and use multiple times. Boost.UUID also rightfully implements random_generator as an object to accommodate this usage pattern.
Switching topics back to Boost.Random, I consider the use of the token to select a cryptographic provider a bad practice. Even the POSIX path should ignore the token. get_random_bytes is the way to go. But that's a separate story.
I'm not sure I understand what you mean here. I agree that APIs like getrandom and getentropy are superior to reading from /dev/urandom, but those are not available universally. I'm not sure how that relates to Windows though.