I've read Intel's The Difference Between RDRAND and RDSEED and Intel Digital Random Number Generator (DRNG) Software Implementation Guide, but I have some open questions that are specific to usage in an application. I work with Wei Dai's Crypto++, which is a C++ class library of crypto algorithms and schemes. The library provides access to Intel's RDRAND and RDSEED instructions.
The Crypto++ library applies Maurer's randomness test for TRNGs to the output of both RDRAND and RDSEED. RDSEED consistently provides a value at or near 1.00000, while RDRAND often provides a value at 0.997 or above (1.00000 on occasion, but not consistently).
My first question is, why do the numbers produced by RDSEED appear to be of better quality then the numbers provided by RDRAND with the Maurer test?
The Crypto++ library provides two additional tests. First, the library attempts to fetch 10,000 bytes. Second, the reads and discard bytes (which is really just the first test over again). Both attempt to ensure the generator can produce a steady stream.
Now, in the two tests above, the library retries a failed operation 8 times. A failed operation means a random number was not produced by the generator, and it is signaled by the Carry Flag (CF). If RDRAND or RDSEED reaches the failure limit of 8, then the API call fails. RDRAND always fulfills the request (I've never seen it fail), but RDSEED fails on occasions (because the maximum number of retries were reached).
My second question is, why does RDSEED suffer depletion when it appears RDRAND does not (it also appears RDSEED is a simpler generator than RDRAND)?
I realize the Maurer test is a statistical test, and future runs a years from now might turn the results on their head. But I also feel I should not be seeing these trends in repeated random samplings over days and weeks.
I also understand there's little difference between 1.00000 and 0.99700 in practice since I can grab extra bytes and run it through an HKDF to extract the entropy. Its more a morbid curiosity to me.
The Crypto++ source files are available at rdrand.cpp. The C++ file calls into routines provided for Microsoft Assembler (MASM/ML). We found we could get greater throughput by providing hand tuned assembly for bulk requests (i.e., avoid intrinsics).
The RDRAND routine can be found around line 185 of rdrand.asm, while the RDSEED routine can be found around line 430 of rdrand.asm
An example of tests applied to generators (including RDRAND and RDSEED) under Windows is shown below: