Cryptography
random-number-generator randomness pseudo-random-generator
Updated Fri, 07 Oct 2022 00:31:36 GMT

# Should we really rely on "Cryptographically Secure Pseudo-Random Number Generators" (CSPRNG) alone to guarantee secure random output?

Would it be over-engineering to for example hash the random numbers a random amount of times too, for instance when using the CSPRNG in client-side JavaScript? (assuming this is not the strongest CSPRNG)

Edit: Or would it instead be wise/necessary to rely on more devices of randomness (like mixing/hashing a Client Secure Random + Server Secure Random) when security is extremely important in case of using client-side JavaScript, because the security of the web clients/browsers/agents are unknown?

## Solution

Should we really rely on "Cryptographically Secure Pseudo-Random Number Generators" (CSPRNG) alone to guarantee secure random output?

No, we should not rely on CSPRNGs alone for secure random output. For this task, a CSPRNGs requires a truly (not pseudo) random input (the seed). Lacking that, different instances of the same CSPRNG that reuse the same seed will generate the same output when reset (e.g. the program is run again, the device is reset). Using CSPRNGs seeded with no or insufficient randomness is a most classical source of security compromise; see e.g. Mining Your Ps and Qs: Detection of Widespread Weak Keys in Network Devices.

Would it be over-engineering to, for example, hash the random numbers a random amount of times too, for instance when using the CSPRNG in client-side JavaScript?

Yes, what's proposed is poorly-thought over-engineering.

"Pseudo" (the P in CSPRNG and PRNG) means providing repeatable results from run to run, absent variable input. If we use a (CS)PRNG to decide how many times itself is run, it remains a (CS)PRNG. The problem discussed above is not solved, or even meaningfully mitigated. We get a false impression of extra security.

What works to a better degree is mixing several sources of randomness at the input of a CSPRNG, and using that CSPRNG. In client-side JavaScript, the sources could be a system-supplied hopefully-true RNG (possibly `Math.random()` if nothing better is known to be available), cursor location and system time sampled at various instants determined by network or user-interface events (keypresses), a server-supplied nonce, and as a last resort keyboard input. The CSPRNG could be built from a hash function.

Whether that's over-engineering or not depends on security goal, threat model, and runtime environment. The later is often not known when writing the code. Many browsers at some point in their history had insecure `Math.random()` and supplied no secure alternative, making IMHO such precaution sound.

Update following comment

using a hash ( CSPRNG output, available client data, available server data ) would provide more security than just using the CSPRNG?

Yes, if these three conditions hold:

• The hash is secure for modern definition of that (assimilable to a PRF).
• And the apparent entropy in "CSPRNG output" (for one not knowing it's secret seed) is at least the width of the hash; e.g. if this output is $$n$$ decimal digit, $$n\log_2(10)$$ bits.
• And at least about 1 bit worth of the extra data inputs is unpredictable to the adversary. Without that condition, the entropy in the output can be reduced by 0.83 bit (see this), which may be a (usually very minor) issue.

This is valid for hash too narrow for collision-resistance or preimage-resistance (e.g. SHA-256 truncated to 80 bit), and remains valid if we replace "CSPRNG" with whatever available RNG. There are slightly better ways to combine extra entropy, but that one is already a worthwhile improvement.

• +0 – Interesting! So basically, for example, using a hash ( CSPRNG output, available client data, available server data ) would (almost always?) provide more security than just using the CSPRNG? — Sep 06, 2022 at 11:34
• +2 – Very interesting article: "We are able to obtain RSA private keys for 0.50% of TLS hosts and 0.03% of SSH hosts, because their public keys shared nontrivial common factors due to entropy problems" — Sep 06, 2022 at 11:36
• +0 – @NeilYogaCrypto I don't think "almost always" factors into any cryptography discussion in the positive sense... at least not without a tremendous amount of precise math behind it. If you can assume the hash algorithm is secure, then you can show that predicting the output of the hash is at least as hard as predicting the output of the CSPRNG. In theory, including the client and server data introduces additional entropy (see fgrieu's three conditions that must hold). In casual situations, this is reasonable. — Sep 07, 2022 at 15:45
• +1 – Another option would be to use a well known and studied CSPRNG, feeding the best entropy you can acquire to seed it. The advantage they have is that the attack vectors that have been studied against them are directly tied to the way you intend to use them. — Sep 07, 2022 at 15:46