This is the mail archive of the
gsl-discuss@sources.redhat.com
mailing list for the GSL project.
Re: Random Number Seed
- From: "Robert G. Brown" <rgb at phy dot duke dot edu>
- To: Olaf Lenz <olenz at Physik dot Uni-Bielefeld dot DE>
- Cc: Przemyslaw Sliwa <przemyslaw dot sliwa at db dot com>,gsl-discuss at sources dot redhat dot com
- Date: Mon, 21 Feb 2005 07:46:42 -0500 (EST)
- Subject: Re: Random Number Seed
- References: <Pine.LNX.4.44.0403011221340.20444-100000@ganesh><4219CC24.90200@physik.uni-bielefeld.de>
On Mon, 21 Feb 2005, Olaf Lenz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hello!
>
> A few months ago, you suggested the following code snippet for seeding
> the RNG from /dev/random:
>
> - -------------------------------------------------
> #include <stdio.h>
> #include <sys/time.h>
>
> unsigned long int random_seed()
> {
>
> ~ unsigned int seed;
> ~ struct timeval tv;
> ~ FILE *devrandom;
>
> ~ if ((devrandom = fopen("/dev/random","r")) == NULL) {
> ~ gettimeofday(&tv,0);
> ~ seed = tv.tv_sec + tv.tv_usec;
> ~ if(verbose == D_SEED) printf("Got seed %u from gettimeofday()\n",seed);
> ~ } else {
> ~ fread(&seed,sizeof(seed),1,devrandom);
> ~ if(verbose == D_SEED) printf("Got seed %u from /dev/random\n",seed);
> ~ fclose(devrandom);
> ~ }
>
> ~ return(seed);
> }
> - -------------------------------------------------
>
> I've used the code for quite a while now and only today I noticed a big
> problem with it. The code tests, if /dev/random can be opened, but it
> does NOT test if the fread has actually read any number.
>
> In my case, this resulted in the fact that the seed was not seeded at
> all and all processes used the same seed.... P-(
>
> So to all who have been using the code, I would recommend to check their
> results. For the future, I would recommend to use the following code:
My bad, sorry. I was assuming that the system itself wasn't broken
here, so that /dev/random might be absent but wouldn't be broken. In
the man page (and to my experience):
When read, the /dev/random device will only return random bytes
within the estimated number of bits of noise in the entropy pool.
/dev/random should be suitable for uses that need very high
quality randomness such as one-time pad or key generation. When
the entropy pool is empty, reads from /dev/random will block
until additional environmental noise is gathered.
So if you can open and try to read /dev/random the device blocks the
read until it successfully returns an integer (which can actually take a
long time if you are asking for a lot of rands as it has to generate
sufficient entropy).
So either this behavior is somehow implementation dependent on systems
with /dev/random, or your system has a broken /dev/random in the kernel,
or the system has a regular null file called "/dev/random" in the /dev
directory instead of the kernel-linked device. In this latter case
(which I did not anticipate but yes, which is possible) you'd get the
behavior you describe, but I would consider the system "broken" and I'd
think that you want to know it instead of continuing. Especially since
putting a file in place of /dev/random would make a system vulnerable to
various cryptographic attacks, one would think. So much so that I'd
"suspect" an attack if I found a regular file there on a system properly
installed from a well-supported linux distribution.
So one might want to replace the "else" for fread with an error message
and punt unless your system has a different man page than mine and
doesn't state that /dev/random (unlike /dev/urandom) should block until
it returns.
rgb
>
> - -------------------------------------------------
> #include <stdio.h>
> #include <sys/time.h>
>
> unsigned long int random_seed()
> {
>
> ~ unsigned int seed;
> ~ struct timeval tv;
> ~ FILE *devrandom;
>
> ~ if ((devrandom = fopen("/dev/random","r")) == NULL) {
> ~ gettimeofday(&tv,0);
> ~ seed = tv.tv_sec + tv.tv_usec;
> ~ if(verbose == D_SEED) printf("Got seed %u from gettimeofday()\n",seed);
> ~ } else {
> ~ if (fread(&seed,sizeof(seed),1,devrandom) == 1) {
> ~ if(verbose == D_SEED) printf("Got seed %u from /dev/random\n",seed);
> ~ fclose(devrandom);
> ~ } else {
> ~ gettimeofday(&tv,0);
> ~ seed = tv.tv_sec + tv.tv_usec;
> ~ if(verbose == D_SEED) printf("Got seed %u from
> gettimeofday()\n",seed);
>
> ~ }
> ~ }
>
> ~ return(seed);
>
> }
> - -------------------------------------------------
>
> Cheers
> Olaf
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.4 (GNU/Linux)
> Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
>
> iD8DBQFCGcwjtQ3riQ3oo/oRAsjeAKC3CIz3kxxt/ZJUiuYzemIU1IqVdgCffoYW
> vXr8SEcXH69ulMzTfBwWuHw=
> =2RKb
> -----END PGP SIGNATURE-----
>
--
Robert G. Brown http://www.phy.duke.edu/~rgb/
Duke University Dept. of Physics, Box 90305
Durham, N.C. 27708-0305
Phone: 1-919-660-2567 Fax: 919-660-2525 email:rgb@phy.duke.edu