# Simple CSRNG design based on hash function

I was researching designs for cryptographically secure random number generators based on hash function. I know that there is Hash_DRGB but I can not understand why such a complicated design is required or if a simpler design would also work.

My Idea for a simple design would be a follows: Let $$S$$ be the 512 bit internal state:

1. For initialization with entropy data $$E$$ do $$S \leftarrow \text{SHA512}(E)$$
2. To add entropy $$E$$ to the state do $$S \leftarrow \text{SHA512}(S || E)$$
3. To get 512 bits of entropy from the pool do $$output \leftarrow \text{SHA512}(S || someArbitraryConstant) \\ S \leftarrow \text{SHA512}(S)$$

To get more entropy than 512 bits, just repeat the last call until enough is generated and truncate if the required amount is not divisible by 512 bits.

Can you tell me if this design is secure. And does anyone know literature which studied a design like this (or something equivalently similar). If this is not secure why is this the case and what can be done to fix the issue? Or is NISTs Hash_DRBG really to easiest secure design?

If this is indeed a secure solution, will this also work for other Hash functions from the SHA2 and SHA3 family?

This design is fairly similar to one found in a version of the DSA standard analysed by Kelsey et.al. in this paper [link], and the original PRNG specification can be found here [link].

One possible security risk highlighted there that also exists in this design is that if the internal state $$S$$ is compromised, all following values of $$S$$ are also compromised until the next addition of new entropy $$E$$. If $$E$$ is not big enough to resist a brute-force guessing attack then even after adding the new $$E$$ the resulting $$S$$ is still compromised.

This design also requires $$someArbitraryConstant$$ to exist. If the spec or implementation allows for an empty string then $$S$$ becomes public to everyone which means the construction loses all security properties.

Another consideration is that in this design, an extra call to the hash function to update $$S$$ is required each time output is generated. The Hash_DRBG construction on the other hand uses an internal counter instead and avoids this, which should make it twice as performant for heavy loads.

• isn't any CSPRNG compromised if the internal state is compromised? Commented May 18 at 23:31

The arbitrary constant of step 3 should be 1 to 119 bytes (or 1 to 959 bits). If it was empty, a trivial attack would predict 512-bit outputs following the first one after a reseeding. If it was larger, there would be extra SHA-512 rounds making the generator slower, and as an aside there would be even so slightly less entropy in each 512-bit output block.

With such parameter, and if initialized with enough entropy at step 1, and if it's internal state does not leak or become corrupted, then there is no known attack on this (hybrid) random number generator.

Even under these hypothesis, it has a number of theoretical drawbacks:

• When generating many consecutive outputs, the $$S \leftarrow \text{SHA512}(S)$$ steps tends to reduce the entropy in $$S$$, like to about $$512-\ln(2+k)$$ bit of entropy after $$k$$ previous iterated hashes (see Entropy when iterating cryptographic hash functions). While this is not a practical issue at all, this can be viewed as unfortunate. A common way to fix that non-issue, and make the generator twice faster in step 3, is to reduce step 3 to: $$\mathsf{output} \leftarrow \operatorname{SHA-512}(S\mathbin\|\underline k)$$ where $$k$$ is an incremental counter of output blocks since the last reseeding (or just since step 1), and $$\underline k$$ is a representation of $$k$$ as bytestring per some convention (like, big-endian binary over 64 bits). A similar technique is used in MGF1 (with 4 bytes, but 8 is more natural in the context of SHA-512).
• We are using SHA-512 outside of it's initial stated design goals of resistance to collision and (first and second) preimage. These goals do not imply that for random input, the output is indistinguishable from random, which we assume. While there is no known attack against that property of SHA-512, we may have better assurance if we use $$\operatorname{HMAC-SHA-512}(S,X)$$ (where the first input is the key parameter of HMAC) instead of $$\operatorname{SHA-512}(S\mathbin\|X)$$ at steps 2 and 3. PBKDF2 essentially does that.

Importantly, this is lacking at least one most critical feature: something giving assurance that the generator is effectively seeded with actual entropy at step 1 (including but not limited to: step 1 is actually performed before any successful execution of step 3). Such failures do occur! Sometime that's because the amount of actual entropy has been overestimated (causing things ranging from output occasionally identical across reboots or different instances of the same generator on different machines, real or virtual; to keys that can be found by enumeration by an attacker aware of the generator and how it's entropy source works). That can be an accidental hardware defect. Or perhaps an adversary deliberately blows a liquefied gas to literally freeze what gathers entropy.

As a relatively minor aside, there is nothing stated to insure timely reseeding. OTOH, if a reseeding is necessary, we are next to disaster, and there is no assurance that reseeding will advert it.

Also: risk of disclosure by some side channel are not considered. Not that it's particularly likely with SHA-512.

And of course, this ignores more complex and occasionally overkill prescriptions in NIST 800-90 or AIS31. Which can be a problem when it comes to get rubber-stamped.

• "The arbitrary constant of step 3 should be 1 to 119 bytes (or 1 to 959 bits)." Would it not need to be at least 100 bits or so to deter brute-force attempts? edit: maybe not, I think I mixed it up. Commented May 17 at 15:49
• @n-l-i: yes, if that arbitrary constant is secret. But that is not required for security of the method (under the proper assumptions for the rest). And in cryptography, constants are assumed public unless stated otherwise (contrary to keys, which are assumed secret unless explicitly public).
– fgrieu
Commented May 17 at 16:18