Random Number Generator: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
m Fixed a minor spelling mistake.
m Bot: Replace deprecated source tag with syntaxhighlight
Line 35:
Newer x86 and x86-64 processors have the instruction RDSEED for generating random numbers.
To use RDSEED you will first need to check if the instruction is available.
<sourcesyntaxhighlight lang="asm">
mov eax, 7 ; set EAX to request function 7
mov ecx, 0 ; set ECX to request subfunction 0
Line 41:
shr ebx, 18 ; the result we want is in EBX...
and ebx, 1 ; ...test for the flag of interest...
</syntaxhighlight>
</source>
 
If EBX is set to 1 (or ZF is unset), the instruction is available. Then it can be used to generate a 16/32/64 bit random number (depending on the register size used as an argument). If a random number was generated, the Carry flag is set.
 
<sourcesyntaxhighlight lang="asm">
mov ecx, 100 ; number of retries
.retry:
Line 55:
.done:
; random number is in EAX
</syntaxhighlight>
</source>
 
It is up to you and your users to trust RDSEED. Because it is implemented in hardware, it effectively is a black box that may contain all sorts of bugs, or worse, backdoors.
Line 87:
RDRAND is slightly older than RDSEED, and provides ([https://software.intel.com/content/www/us/en/develop/blogs/the-difference-between-rdrand-and-rdseed.html what Intel claims to be]) a CSPRNG.
Its presence is indicated by CPUID leaf 1, ECX bit 30:
<sourcesyntaxhighlight lang="asm">
mov eax, 1 ; set EAX to request function 1
mov ecx, 0 ; set ECX to request subfunction 0
Line 93:
shr ecx, 30 ; the result we want is in ECX...
and ecx, 1 ; ...test for the flag of interest...
</syntaxhighlight>
</source>
 
If ECX is set to 1 (or ZF is unset), the instruction is available. Usage is identical to RDSEED:
 
<sourcesyntaxhighlight lang="asm">
mov ecx, 100 ; number of retries
.retry:
Line 107:
.done:
; random number is in EAX
</syntaxhighlight>
</source>
 
It is automatically seeded by the same entropy source that RDSEED reads from, and cannot be seeded manually. It therefore is subject to the same caveats as RDSEED.
Line 125:
Taken directly from the [http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf C standard document (p. 347)]:
 
<sourcesyntaxhighlight lang="c">
// The following functions define a portable implementation of rand and srand.
 
Line 140:
next = seed;
}
</syntaxhighlight>
</source>
 
This is a fairly standard but mediocre [https://en.wikipedia.org/wiki/Linear_congruential_generator Linear Congruential Generator] (LCG). It returns 15 random bits.
Line 175:
In 1982, Brian Wichmann and David Hill [https://doi.org/10.2307/2347988 proposed] to combine three linear congruential generators, then normalizing and summing the results to get a number uniformly distributed between 0 and 1. A common instance is:
 
<sourcesyntaxhighlight lang="c">
static uint16_t seed[3]; /* seed with numbers between 1 and 30000 */
float wichmann_hill(void) {
Line 183:
return fmod(seed[0] / 30269.0 + seed[1] / 30307.0 + seed[2] / 30323.0, 1.0);
}
</syntaxhighlight>
</source>
 
This version is known to have a period of just shy of of seven trillion (the least common multiple of 30268, 30306, and 30322).