# How can I be sure the RNGCryptoServiceProvider is able to produce 12 bytes that can have 2^96 values?

I am writing code that needs to produce a truly random number of 96 bits. The requirements are:

• The code must be able to produce all $2^{96}$ values.
• The likelihood for any value to come up must be the same for all values.
• It must be impossible to predict the next $96$-bit number that will come up.

So, using RNGCryptoServiceProvider, I have the following implementation:

  Public Function GetRandom96BitNumber() As BigInteger
Dim random96BitNumber As BigInteger
'We need 12 bytes, but take 13 in order to ensure a positive number.
Dim bytesFor96BitNumber(12) As Byte
Dim cryptoProvider = New RNGCryptoServiceProvider
cryptoProvider.GetBytes(bytesFor96BitNumber)
'Set the thirteenth byte to zero to ensure that we get a positive BigInteger.
bytesFor96BitNumber(12) = 0
random96BitNumber = New BigInteger(bytesFor96BitNumber)

Return random96BitNumber
End Function


Question:

This code (assuming it employs the RNGCryptoServiceProvider correctly) is only as good as the quality of randomness of the RNGCryptoServiceProvider. How can I convince myself and my clients that the three criteria stated above are met? I found this document that compares cryptographic random number generation between Windows and Linux and I think I read there that the entropy used to seed the RNGCryptoServiceProvider is at least 256 bits.

Does this mean that the three requirements stated above are met? If yes: why? If not: why not?

Any further guidance for getting enlightenment are very much appreciated.

• 96-bit is such an odd number... Are you trying to generate nonces here? Commented Jul 4, 2016 at 22:10
• @MaartenBodewes I will not deny that if the code included has a flaw I hope to get a comment that points that out. But the question is very much about the RNGCryptoServiceProvider itself: will it meet the three criteria stated in the question when I ask it to provide 12 bytes? Commented Jul 5, 2016 at 5:37
• Your criteria are targeted at the actual RNG itself, while RNGCryptoServiceProvider is just defined as "use the OS functionality". On the other hand, your criteria are too vague on one hand, and too specific in an unrealistic manner: The first is covered by the second. But what does "be the same" mean?E.g. iIf there is a difference in the likelihood of $2^{-10000}$, is that good enough or not? And the third is worded quite vague: Based on which knowledge does it have to be unpredictable?
– tylo
Commented Jul 5, 2016 at 16:31

RNGCryptoServiceProvider - according to many sites including the following Wikipedia link itself - uses the CryptGenRandom functionality of the operating system. You therefore need to convince your clients that the OS functionality is sufficient.

The Wikipedia article contains references to FIPS and Common Criteria EAL4 evaluations of the operating systems containing the RNG. That should normally be sufficient - although I must admit that I cannot find the actual FIPS validation certificate of the RNG.

The best reference is probably the documentation of BCryptGenRandom which states:

The default random number provider implements an algorithm for generating random numbers that complies with the NIST SP800-90 standard, specifically the CTR_DRBG portion of that standard.

This is for Windows versions after Windows Vista. Before that an RC4 based algorithm seems to have been used.

I'm not really sure if you're asking a VB.net api question, or if you're worried about the effectiveness of RNGCryptoServiceProvider.

If it's the latter, then you're effectively asking whether Microsoft's crypto provision function is truly random. You could research the underlying mechanism that RNGCryptoServiceProvider uses. Your paper is a good start. Since this standard api is used the world over, and you're using it correctly in the code (your assumption), it follows that the generated bytes are good. There is a mountain of literature on this api that you can google. I personally am not convinced that RNGCryptoServiceProvider or the /dev/random equivalent is truly random, but this is your simplest option for (quasi true) random numbers.

• This question is very much about the effectiveness of RNGCryptoServiceProvider. The code included is just an illustration. Commented Jul 5, 2016 at 5:34