Branch: Tag:

2015-09-29

2015-09-29 02:03:35 by Martin Nilsson <nilsson@fastmail.com>

Replace PRNG with Bob Jenkins small noncryptographic PRNG. Smaller and uses less state, 20% slower and gives a slightly better grade by dieharder.

102:    return 1<<(my_log2(x-1)+1);   }    - static unsigned INT32 RandSeed1 = 0x5c2582a4; - static unsigned INT32 RandSeed2 = 0x64dff8ca; -  - static unsigned INT32 slow_rand(void) - { -  RandSeed1 = ((RandSeed1 * 13 + 1) ^ (RandSeed1 >> 9)) + RandSeed2; -  RandSeed2 = (RandSeed2 * RandSeed1 + 13) ^ (RandSeed2 >> 13); -  return RandSeed1; - } -  - static void slow_srand(INT32 seed) - { -  RandSeed1 = (seed - 1) ^ 0xA5B96384UL; -  RandSeed2 = (seed + 1) ^ 0x56F04021UL; - } -  - #define RNDBUF 250 - #define RNDSTEP 7 - #define RNDJUMP 103 -  - static unsigned INT32 rndbuf[ RNDBUF ]; - static unsigned int rnd_index; -  +    #if HAS___BUILTIN_IA32_RDRAND32_STEP   static int use_rdrnd; -  + static unsigned int rnd_index;   static unsigned long long rnd_index64;   #define bit_RDRND_2 (1<<30)   #endif    -  + /* Bob Jenkins small noncryptographic PRNG */ +  + typedef unsigned long int u4; + static u4 rnd_a; + static u4 rnd_b; + static u4 rnd_c; + static u4 rnd_d; +  + #define rot(x,k) (((x)<<(k))|((x)>>(32-(k)))) + static u4 ranval(void) { +  u4 e = rnd_a - rot(rnd_b, 27); +  rnd_a = rnd_b ^ rot(rnd_c, 17); +  rnd_b = rnd_c + rnd_d; +  rnd_c = rnd_d + e; +  rnd_d = e + rnd_a; +  return rnd_d; + } +  + static void raninit( u4 seed ) { +  u4 i; +  rnd_a = 0xf1ea5eed, rnd_b = rnd_c = rnd_d = seed; +  for (i=0; i<20; ++i) { +  (void)ranval(); +  } + } +    PMOD_EXPORT void my_srand(INT32 seed)   {   #if HAS___BUILTIN_IA32_RDRAND32_STEP
155: Inside #if HAS___BUILTIN_IA32_RDRAND32_STEP
   http://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide    */   #endif -  { -  int e; -  unsigned INT32 mask; +     -  slow_srand(seed); -  -  rnd_index = 0; -  for (e=0;e < RNDBUF; e++) rndbuf[e]=slow_rand(); -  -  mask = (unsigned INT32) -1; -  -  for (e=0;e< (int)sizeof(INT32)*8 ;e++) -  { -  int d = RNDSTEP * e + 3; -  rndbuf[d % RNDBUF] &= mask; -  mask>>=1; -  rndbuf[d % RNDBUF] |= (mask+1); +  raninit(seed);   } -  } - } +       PMOD_EXPORT unsigned INT32 my_rand(void)   {
189: Inside #if HAS___BUILTIN_IA32_RDRAND32_STEP
      /* hardware random unit most likely not healthy.    Switch to software random. */ -  rnd_index = 0; +     use_rdrnd = 0;    }   #endif -  if(++rnd_index == RNDBUF) rnd_index=0; -  return rndbuf[rnd_index] += rndbuf[rnd_index+RNDJUMP-(rnd_index<RNDBUF-RNDJUMP?0:RNDBUF)]; +  return ranval();   }      PMOD_EXPORT unsigned INT64 my_rand64(void)
212: Inside #if HAS___BUILTIN_IA32_RDRAND32_STEP
      /* hardware random unit most likely not healthy.    Switch to software random. */ -  rnd_index = 0; +     use_rdrnd = 0;    }   #endif -  return ((INT64)my_rand()<<32) | my_rand(); +  return ((INT64)ranval()<<32) | ranval();   }