Josh Datko writes: > On Fri, 2016-08-26 at 14:59 -0500, Christopher Allan Webber wrote: >> Hello!So, as some of you know, I'm working on a federation >> implementation in Guile.This needs a few things: >> >> - Random tokens which won't collide, for various purposes > > There's a function in libgcrypt, gcry_create_nonce. Perhaps this would > provide better performance in this use-case. From the libgcrypt 1.6.4 > manual: > > void gcry_create_nonce (unsigned char *buffer, size t length) > > Fill buffer with length unpredictable bytes. This is commonly called a > nonce and may also be used for initialization vectors and padding. This > is an extra function nearly independent of the other random function > for 3 reasons: It better protects the regular random generator’s > internal state, provides better performance and does not drain the > precious entropy pool
That seems to fill 300k 50-length bytevectors with random data per second, which is quite good. At that point, it's really the base64 encoding in guile which is slowing things down, which I suspect might be much faster in Guile 2.1.X (but I haven't tested it yet). >> - The ability to generate a solid random key, which is used for... > > Well, besides this unfortunate recent bug/cve (http://formal.iti.kit.ed > u/~klebanov/pubs/libgcrypt-cve-2016-6313.pdf), I would take > cryptographic PRNG over a non-one, with no offense to the guile > developers. I think you're right. I did a bit more research (full caveat: I know nearly nothing about these things, or this section of the codebase, aside from what I looked into yesterday) and it looks like Guile is using the same Multiply With Carry RNG that was installed in 1999: /* * The prepackaged RNG * * This is the MWC (Multiply With Carry) random number generator * described by George Marsaglia at the Department of Statistics and * Supercomputer Computations Research Institute, The Florida State * University (http://stat.fsu.edu/~geo). * * It uses 64 bits, has a period of 4578426017172946943 (4.6e18), and * passes all tests in the DIEHARD test suite * (http://stat.fsu.edu/~geo/diehard.html) */ As it turns out, Multiply With Carry was the same PRNG used in V8, in the article I previously linked to where troubles were described: https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.a7q1tgev9 It looks like most other languages are using the Mersenne Twister, though I don't know if that is necessarily better, or if V8's implementation was just not really good, or really anything about it. But yes, I think trusting a crypto library's PRNG for security-critical stuff is probably the right move. The recent CVE sorta sucks, but also, it's good that it's getting that much review to run into those kinds of problems. >> - The ability to generate an HMAC (for signed cooke based sessions) > > HMAC is deterministic, so once you have your key generated, there is no > random input into HMAC (besides the key of course). Right, I just need an initial good value... and even if that were on the longer end of generation, it would only need to be done once. >> So!Does someone much better informed than I am have any insights? >> :) >> > > Seeding one RNG (/dev/random) from another (libgcrypt) doesn't sit well > with me. The problem you need to seed a PRNG from ideally, real random. > How did you generate *that* random? Well, you quickly have a Rube > Goldberg machine. Well, and here I was going to throw all my energy into a new random number generating device scavenged from an old Boggle dice dome, some original red-box D20s, and a webcam... oh well. In all seriousness, good point. :) Anyway, I'll trust in libgcrypt to do the right thing for now. Thanks for the input! - Chris