-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Export and document cryptographically secure random numbers #32954
Comments
On the other hand, putting it in a package makes releasing bug fixes or improvements much faster. |
To start with, it should certainly be a package. As it gains more widespread usage, we can figure out if it should live in stdlib. Given that we are more likely to move things out of stdlib rather than into it, having an external package seems better. |
I disagree. Security is still the toxic wastedump of computer science. People are rightfully reluctant of adding external dependencies. Many people are naive with respect to crypto and security. People lack the resources to properly vet packages that provide secure random. We want to support a culture of "when in doubt, then be secure". We absolutely do not want to force people to make ill-informed trade-offs whether they "can get away" with using insecure At the very least, I want the If we do not want to implement a CSPRNG, then we could export a wrapper around one of the mbedtls CSPRNGs. mbedtls is already a binary dependency of julia. We could also fix up the random wrapper in We could also point people at the CC @hustf @essenciary @sbromberger for a user perspective. |
Question: is this intended to produce truly unpredictable random data like /dev/random or a reproducible stream of pseudo-random data? |
I might have more to say later, but I want to address @JeffBezanson 's comment here from a different perspective: while "releasing bug fixes or improvements" might be a valid reason to move non-secure code out to a 3rd-party package, I'm not sure this is a great strategy for things like CSPRNGs. There are a couple of reasons for my belief:
Finally, and possibly a distraction: extraordinary claims require extraordinary evidence. I am unconvinced that moving code out to third-party libraries has actually resulted in more frequent releases than what we see in Julia Base/stdlib. Just in 2019, we've had 3 releases of Julia, with two more imminent. I don't know that third-party packages have seen that sort of iteration: picking some popular packages, I see that in the same timeframe,
I'm certainly not arguing that these should be moved (back) into Base. (Actually, for a few of them perhaps I am, but that's a different discussion.) To reiterate my point more simply, and to wrap it up: TL/DR MHO, YMMV, etc.: Crypto functionality should be primitive and stable, and should be important enough to be versioned as part of the language itself. |
As the person merging the releases, I can assure you that DiffEq* has had a lot more than 2 releases. Doing Suppose that Gadfly were made into a standard library. Does that mean any more work would have been done on it? No. It would get the same amount of maintenance as it does now. Even if it would have technically been included in 3 different Julia releases, if the actual code was unchanged, it's hard to argue that this is really a release. |
Again, I'd like to ask about the P part of CSPRNG is significant. Because if people just want a good reliable stream of random data, that's a pretty simple, stable API that I'd be happy to commit to. If people don't want reproducibility, then we can change algorithms at any time and not worry about breaking people's programs. If people want reproducibility, then that's a whole different story because then we need to pick and commit to maintaining and supporting a given algorithm. The original suggestion of using |
I also think looking at the release schedules of other existing packages is not relevant. The point was just that it's possible to release new versions independent of julia/stdlib. If you want to make a new release, you can at any time. Even if it were true that packages have on average fewer releases than julia, there is no causal relationship. Is it really so crazy to consider a compiler and a crypto library separate projects? Long term, the structure I'd like to have is everything in But, if we can make the existing |
Yup, as I feared, that last point became a distraction. However, as mentioned (perhaps ad nauseam) elsewhere,
will kill practical use of Julia in many environments. If this is indeed the direction The Project is headed, confirmation now will allow me to start looking at alternatives in my organization. This preference has been repeated often enough by enough people that it is now, in my mind, a Thing To Be Taken Seriously. I'll follow up off github. |
Does the rest of that sentence
help? I simply don't understand how a language and libraries being separate packages is some perverse and awful new idea that we invented. Isn't that how everything works? How many useful libraries are bundled with gcc? And there is not that much in our |
Coming back to the discussion at hand:
From my perspective, this should be sufficient. That is, I can use a PRNG in testing and development to ensure that my code is doing what it should using reproducible inputs, and then I can easily switch out to a CSRNG for production. |
For Rust, you linked to an external crate https://crates.io/crates/rand, developed in a separate repo https://github.com/rust-random/rand. |
Sorry for being unclear in the initial feature request and inadvertently derailing the discussion. In this specific issue, I am simply asking for an idiot-proof way of generating secure random (which is documented in an idiot-proof way). Making |
Ok that's a pretty straightforward ask. We have also talked about making MbedTLS a standard library (the current situation is quite bad where you end up having multiple different copies of it) and HTTP as well, using MbedTLS for secure web connections. |
Given that all you need to generate a secure random array is |
It might be too breaking/inconvenient a change, but I'd like to get folks' takes as to whether there's any reason not to make secure randomness the default. I think this would obviate most of the issues @chethega found in his initial post. |
If called in a loop on unix-like systems, then you will run out of file descriptors. Correct use is to initialize a module-level global But yes, documentation that includes copy-pastable examples of correct use can be an appropriate solution. |
Just as a data-point: Primes.jl. It's sometimes practical to use the default RNG, have the possiblity to use |
I don't understand either of these points. Packages are not inconvenient at all — presumably a CSPRNG would also live in a package, not I am not sure that an ecosystem of competing CSPRNG libraries is such a bad thing (competition has its advantages), but in any case, is it a practical concern? The only CSPRNG I could find for Julia is |
fwiw (/dev/random vs /dev/urandom) https://www.2uo.de/myths-about-urandom/ |
The term CSPRNG has been misused in this thread: what's actually wanted is a secure source of genuine randomness, regardless of how it's generated—usually partially from random events, partly from using a CSPRNG to enhance the amount of bits you can get from those random events. |
I think it makes sense to have a good, fast CSPRNG in base alongside the default non-CS PRNG. Additional RNGs can always live in packages, but we should bless a good default. |
I cannot resist adding stdlib/uuid to the list of mersenne twister users that MAY WISH TO use a better random source by default, per rfc4122/uuid and rfc6919 / further requirement levels. |
Using a secure RNG for uuids is a good idea 👍 |
There seem to be two major things to do here:
For (1), if we can open For (2), I would propose that we provide |
|
As far as I understood, your random/pseudo-random terminology difference is that pseudo-random additionally exposes a
If the kernel fails to offer /dev/urandom then we can give up and should panic or throw. The OS failing to provide secure random is mostly a non-issue. Even if we believed that the current kernel RNG state is compromised (e.g. we are on a VM that just was migrated, we have been informed of this but suspect that the kernel did not get the message) then we could just write some entropy to /dev/urandom and reopen it. Once we make RandomDevice usable (open once on startup, thread-safe, fix precompilation woes) the remaining main advantages of a different implementation are performance (plus the windows story that is SystemFunction036; we could check whether we are running a non-ancient OS and use a more modern API). Performance is kinda important, though! If we plan to make the default use a secure algorithm, then we must have
rfc6919#10 perfectly describes the kind of security considerations and requirement level that uuid generation recommends in rfc4122#4.5. I you haven't already, crack open a can of beer and read that. "a BETTER solution" my ass. |
I really don't think this is a viable option. This will lead to hundreds of posts on discourse—that I will be answering for years to come—with people comparing Julia's In short, the default RNG can stay as is, and the secure RNG needs to be:
To satisfy this, I think that my proposal to export |
Mostly true, but the applications I have do suck secure randomness at a very large rate, so reading from |
FWIW I have wrapped the Maybe the easiest thing to do is to spin off this little wrapper into a tiny package that can be called on demand. |
Would it be possible to optionally pass RandomDevice a buffer size? I have an application where I must use a CSPRNG (urandom) for any and all random elements in a project. Latency becomes a problem and I had to hack together a buffer containing normally distributed random values of all things. Doesn't help that urandom is a single threaded process. edit: urandom is usually 200+ mb/sec on a decent cpu |
This is now exported and documented. |
Various applications need a source of cryptographically secure random numbers. We currently do not provide a CSPRNG.
Secure random is a very basic primitive, and imo as widely important as secure hash (which we do provide). Further, we have a very nice AbstractRNG interface. In other words, there are very few API decisions (mainly: whether to define
Random.seed!
for the CSPRNG). Secure random could live in packages, but this has lots of disadvantages: First, it is inconvenient, which will lead to people misusing the default random generator. Second, a central place for maintaining such basic functionality is preferable to many competing implementations, both security-wise and in terms of simplified audits of packages.There was some discussion here that inspired me to grep through a lot of packages to gauge how they use randomness. I'll link all of the individual issues here, to make the point that this is important functionality, and that there is confusion about secure random in the package ecosystem. Considerations about the default RNG are separate.
A sensible solution could be to use
RandomDevice()
. In this case, we would simply update the docs.The text was updated successfully, but these errors were encountered: