GNOME Bugzilla – Bug 129636
Seeding by array, and other seeding issues in GRand
Last modified: 2011-02-18 16:07:08 UTC
GRand lacks the init_by_array from the reference implementation from http://www.math.keio.ac.jp/~matumoto/MT2002/emt19937ar.html . Also seeding during g_rand_new (and thus for g_random*) wastes some entropy if /dev/urandom is not available. Seeding with an array in this case gets the maximum possible entropy. Also it would make sense to use more then 1 word for the default seeding as reading 1 word or 4 words from /dev/urandom really makes no difference due to how /dev/urandom works and we get 128 bits of entropy that way. Also there is no way to copy the state of the random number generator to 'replay' the values later, that is, take a snapshot of the generator. The attached patch solves all these issues by adding a g_rand_set_seed_array, g_rand_new_with_seed_array and g_rand_copy, and modifying the g_rand_new function to squeeze out all possible entropy it can.
Created attachment 22550 [details] [review] patch to add specified functionality
Created attachment 22573 [details] [review] Updated patch
Note: the changelog in the updated patch doesn't reflext the EINTR handling in g_rand_new, I've updated that here but I don't suppose that requires to send a new patch :)
Also obviously another DOH! mistake is that the errno = 0 should be inside the loop. Attaching a new patch
Created attachment 22574 [details] [review] De-DOH!-ified patch
Commited to CVS by Tim. Fri Dec 19 11:49:21 2003 George Lebl <jirka@5z.com> * glib/grand.c glib/grand.h (g_rand_new) (g_rand_new_with_seed) (g_rand_new_with_seed_array) (g_rand_set_seed_array): Add the init_by_array functionality from the reference implementation of the mersenne twister (mt19937ar.c) and change the naming to fit with the rest of the grand API. New functions are g_rand_new_with_seed_array, g_rand_set_seed_array. This is only reliable/tested for the 2.2 version of the seeding as that's what the reference implementation uses. Also modify g_rand_new to get 4 longs from /dev/urandom since that will always be available anyway and we get more entropy and if /dev/urandom is unavailable use also 4 longs for seeding using secs, usecs, getpid and getppid. For version 2.0 use only a simple seed again but be more careful about seeding with secs/usecs in this case. * glib/grand.c glib/grand.h (g_rand_copy): Add g_rand_copy function to copy the current state of the random number generator. * glib/grand.c (g_rand_new): Add testing for EINTR when reading from /dev/urandom * tests/rand-test.c: add testing of the array seeding stuff against the reference implementation, plus add statistical sanity check to see that the values outputted are truly kind of random. And check that g_rand_copy truly copies the state by checking a few terms.