Note that that warning in the documentation for :rand is trying to say that the *PRNG algorithms :rand supports* are not cryptographically strong. If you need strong randomness, you have to not only use a high-entropy seed, but also a cryptographically-secure PRNG (CSPRNG), which none of the algorithms in :rand are.
Seeding the :rand PRNG using :crypto is not sufficient to give you a CSPRNG (i.e. a PRNG which can produce an indefinite stream of bytes which cannot be used to recover the original key/seed.) If you need strong randomness, the docs meant to say that you should just use :crypto *directly* as your CSPRNG, because that's what it is: crypto:strong_rand_bytes/1 calls OpenSSL's RAND_bytes, which is a CSPRNG algorithm seeded using system entropy. On Thursday, September 22, 2016 at 7:40:11 AM UTC-7, Dorian Karter wrote: > > Thanks for contributing your thoughts @paul! :) > > I don't think I'm doing anything weird with this code per se. The official > documentation for rand > <http://www.google.com/url?q=http%3A%2F%2Ferlang.org%2Fdoc%2Fman%2Frand.html&sa=D&sntz=1&usg=AFQjCNHTd8QeKm8eRqCrCvYRv3eviNTYUQ> > > says this: > > This random number generator is not cryptographically strong. If a strong > cryptographic random number generator is needed, use one of functions in > the crypto <http://erlang.org/doc/man/crypto.html> module, for example, > crypto:strong_rand_bytes/1 <http://erlang.org/doc/man/crypto.html>. > > And perhaps by extension we should include this type of message in > `Enum.random` which is, as far as I know, the only place using `:rand`. > > I could not find any additional official documentation on the matter and > that's the only way I found to seed rand with `crypto:strong_rand_bytes/1` > as suggested. > > On Wednesday, September 21, 2016 at 9:59:28 PM UTC-5, Paul Schoenfelder > wrote: >> >> This code above just doesn't seem like the spirit of Elixir which focuses >>> on developer productivity and happiness by simplicity. >>> It sends people to learn the intricacies of erlang for something that >>> should be simple and is simple in a lot of other languages. >>> >> >> The first thing that pops out to me about that code is that it's odd that >> you are providing a constant seed, the typical use of the :rand API for me >> is usually just a call like so `:rand.seed(:exsplus)` (or whatever >> algorithm you choose). Basically, your example is complicated because you >> are doing something extra to seed the random number generator in a >> particular way. >> >> I have to add my +1 to disliking wrapping Erlang standard library >> functions when there is no clear benefit to doing so. Adding `Kernel.rand` >> or whatever would still have to expose more or less the same complexity, so >> there is little benefit to wrapping it. Erlang has a rich standard library, >> and if Elixir tried to wrap all of it to avoid making people dip into the >> Erlang APIs, it would be a huge effort, and a wasted one for the most part. >> I don't think one has to learn the intricacies of Erlang to use the vast >> majority of the APIs, they are generally well documented, and if you know >> Elixir, you can use the Erlang APIs with little understanding of Erlang >> itself - in my opinion, if you know Elixir, there isn't much of a leap to >> knowing Erlang anyway, other than learning the syntax. The biggest pain >> point of course is that the Elixir and Erlang documentation is separated, >> and one can't access the Erlang docs in the shell, etc - but I don't think >> the solution to that is wrapping everything. >> >> Just my two cents, >> >> Paul >> >> >> On Wed, Sep 21, 2016 at 9:39 PM, Dorian Karter <[email protected]> wrote: >> >>> Thanks @josevalim, I'll definetly send a PR to the Elixir guide as you >>> suggested. I had no idea this page existed. >>> >>> I tend to agree with @eksperimental. >>> >>> The other point I have (oops had) in favor of implementing Kernel.seed >>> is that @josevalim recently implemented Kernel.rand. >>> Scratch that just saw this commit from 5hrs ago >>> https://github.com/elixir-lang/elixir/commit/8e2a1e58510dbefb5c707071fcba1584ba3b614f >>> >>> Regardless, I think there should be a more idiomatic way to seed rand >>> that does not involve sending the user down the path I've gone down in my >>> blog post. >>> >>> << i1 :: unsigned-integer-32, i2 :: unsigned-integer-32, i3 :: >>> unsigned-integer-32>> = :crypto.strong_rand_bytes(12):rand.seed(:exsplus, >>> {i1, i2, i3}) >>> >>> >>> This code above just doesn't seem like the spirit of Elixir which >>> focuses on developer productivity and happiness by simplicity. >>> It sends people to learn the intricacies of erlang for something that >>> should be simple and is simple in a lot of other languages. >>> >>> I think we can take a hint from Ruby and Java and their SecureRandom >>> libraries: >>> >>> Java: >>> https://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html >>> Ruby: >>> https://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html >>> >>> Particularly I like Ruby's SecureRandom because it provides helpful >>> methods such as `urlsafe_base64`, `uuid`, `random_bytes` and `hex`. I >>> remember this being the first thing I looked for when I was building my >>> first Elixir application (url shortener) and was surprised at how many >>> hoops I had to jump through as a beginner to get something so simple done. >>> >>> On Wednesday, September 21, 2016 at 2:39:13 PM UTC-5, eksperimental >>> wrote: >>>> >>>> there is a single particularity in this proposal, and it could solve >>>> something I have been bitten >>>> by some time ago when improving *.random functions in Elixir core. >>>> I couldn't figure out why all tests related to random functions were >>>> not working, and that's becuase >>>> when creating Integer.random (a function that never made it to core) I >>>> used :random.seed instead >>>> of :rand.seed. >>>> Believe me it took me a while and a lot of head scratches to figure out >>>> what was going on. >>>> >>>> Having two modules so similar it's a source of confusion, and being >>>> this function a critical >>>> function when generating randon values could be a source of security >>>> bugs: so I don't think it >>>> would be a bad idea to have a Kernel.seed funcion >>>> >>>> >>>> On Wed, 21 Sep 2016 21:01:23 +0200 >>>> José Valim <[email protected]> wrote: >>>> >>>> > We typically avoid only wrapping Erlang functions because in the long >>>> term >>>> > we will just end-up duplicating all the efforts already done in the >>>> Erlang >>>> > community. For example, even for a simple case such as Kernel.seed, >>>> we need >>>> > to document the tuple format, the meaning of exsplus, etc. And unless >>>> we >>>> > wrap all the functionality in rand, at some point you will still need >>>> to >>>> > use rand directly. >>>> > >>>> > So I would like to propose other initiatives: >>>> > >>>> > * We should continue to focus on better documenting those entry >>>> points, >>>> > which we already do in places such as the Getting Started guides >>>> > <http://elixir-lang.org/getting-started/erlang-libraries.html>. In >>>> fact, >>>> > your article is a great exploration of the rand module and, if you >>>> send a >>>> > pull request to the guides linking to your article in the rand >>>> section, we >>>> > would love to merge it! >>>> > >>>> > * Send a pull request to Erlang/OTP that improves their >>>> documentation. For >>>> > example, including an example of using the crypto module for a >>>> > cryptographically secure example would probably be very welcome. >>>> > >>>> > * Send a pull request to Erlang/OTP that adds the functionality you >>>> would >>>> > like to see Elixir wrapping. >>>> > >>>> > If you or anyone else need help in contributing to Erlang, please >>>> ping me >>>> > any time, either on IRC or by e-mail and I would love to provide >>>> guidance. >>>> > Improving Erlang is our responsibility too! :D >>>> > >>>> > >>>> > *José Valim* >>>> > www.plataformatec.com.br >>>> > Skype: jv.ptec >>>> > Founder and Director of R&D >>>> > >>>> > On Wed, Sep 21, 2016 at 8:47 PM, Dorian Karter <[email protected]> >>>> wrote: >>>> > >>>> > > I recently wrote a blog post about my explorations into random >>>> number >>>> > > generation from Elixir and Erlang. You can find it here: >>>> > > https://hashrocket.com/blog/posts/the-adventures-of- >>>> > > generating-random-numbers-in-erlang-and-elixir >>>> > > >>>> > > This led me to question why `:rand.seed` is not exposed from Elixir >>>> > > without hitting Erlang directly. I think every time we send a user >>>> to learn >>>> > > something about the intricacies of Erlang we are introducing a >>>> mental >>>> > > overhead. >>>> > > >>>> > > I would be happy to submit a pull request that will attempt to wrap >>>> > > `:rand.seed` but figured I'd check with the core team first. My >>>> questions: >>>> > > >>>> > > 1. Why is `:rand.seed` not exposed from Elixir? is that by design? >>>> > > 2. If it should be exposed by Elixir where do you imagine it >>>> living? >>>> > > `Kernel.seed`? or should we create a new `Random` module. >>>> > > 3. Would it make sense to provide a method that will just securly >>>> seed >>>> > > rand like so >>>> > > >>>> > > << i1 :: unsigned-integer-32, i2 :: unsigned-integer-32, i3 :: >>>> unsigned-integer-32>> >>>> > > = :crypto.strong_rand_bytes(12):rand.seed(:exsplus, {i1, i2, i3}) >>>> > > >>>> > > 4. Anything else I should consider if I submit a pull request other >>>> than >>>> > > obvious testing and documentation >>>> > > >>>> > > >>>> > > Thanks so much for your attention and feedback! >>>> > > >>>> > > Dorian >>>> > > >>>> > > -- >>>> > > You received this message because you are subscribed to the Google >>>> Groups >>>> > > "elixir-lang-core" group. >>>> > > To unsubscribe from this group and stop receiving emails from it, >>>> send an >>>> > > email to [email protected]. >>>> > > To view this discussion on the web visit >>>> https://groups.google.com/d/ >>>> > > msgid/elixir-lang-core/577910ae-2a52-49f4-9e77- >>>> > > 670639106a3c%40googlegroups.com >>>> > > < >>>> https://groups.google.com/d/msgid/elixir-lang-core/577910ae-2a52-49f4-9e77-670639106a3c%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> >>>> >>>> > > . >>>> > > For more options, visit https://groups.google.com/d/optout. >>>> > > >>>> > >>>> >>>> -- >>> You received this message because you are subscribed to the Google >>> Groups "elixir-lang-core" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/elixir-lang-core/5607dd04-eaf2-499e-8182-3789a44ebded%40googlegroups.com >>> >>> <https://groups.google.com/d/msgid/elixir-lang-core/5607dd04-eaf2-499e-8182-3789a44ebded%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/bdd706a9-2d86-4891-b8bc-a6a8806d35d3%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
