1 /** @file
2  *
3  * Random number generation
4  *
5  */
6 
7 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
8 
9 #include <stdlib.h>
10 #include <ipxe/timer.h>
11 
12 static int32_t rnd_seed = 0;
13 
14 /**
15  * Seed the pseudo-random number generator
16  *
17  * @v seed		Seed value
18  */
srandom(unsigned int seed)19 void srandom ( unsigned int seed ) {
20 	rnd_seed = seed;
21 	if ( ! rnd_seed )
22 		rnd_seed = 4; /* Chosen by fair dice roll */
23 }
24 
25 /**
26  * Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
27  *
28  * @ret rand		Pseudo-random number
29  */
random(void)30 long int random ( void ) {
31 	int32_t q;
32 
33 	if ( ! rnd_seed ) /* Initialize linear congruential generator */
34 		srandom ( currticks() );
35 
36 	/* simplified version of the LCG given in Bruce Schneier's
37 	   "Applied Cryptography" */
38 	q = ( rnd_seed / 53668 );
39 	rnd_seed = ( 40014 * ( rnd_seed - 53668 * q ) - 12211 * q );
40 	if ( rnd_seed < 0 )
41 		rnd_seed += 2147483563L;
42 	return rnd_seed;
43 }
44