r/cryptography 9d ago

Why cryptographically secure random number generation must be difficult to reverse

CSPRNG algorithms like Blum Blum Shub make use of one way functions to transform one PRNG state into the next. For example, modular squaring of the state (modular square root requires factoring) or modular exponentiation (discrete logarithms are computationally hard).

It seems that the reasoning is, if the random state is compromised (state compromise extension attack), then the attacker would be able to know what the future random numbers will be but not what the previously generated random numbers were. I am not finding any information on why this particular requirement is important. How is it useful to be able to keep past generated random numbers secret when future ones are compromised?

10 Upvotes

37 comments sorted by

16

u/atoponce 9d ago

Imagine just encrypting a counter. If the state is compromised, then the attacker knows the current value of that counter. Run the counter in reverse, and you can calculate prior states of the generator. With that, you could discover previously generated secrets.

-5

u/neuralbeans 9d ago

I know that, but why is it so important for cryptography applications that the previous states remain secret? Is there an application requiring random numbers where this requirement is critical?

11

u/yeboi314159 9d ago

Why would you not want that? Why would you want a system that when state is compromised reveals all previous secrets, when you could have one that when the state is compromised all future and previous secrets still say secure?

Imagine a service that encrypts data constantly. It seems pretty obvious that you would want this property so that the negative effects of the compromised state are minimized.

1

u/neuralbeans 8d ago

I'm not saying it's not a good quality, but why would you use a deterministic random number generator if you didn't want the procedure being compromised? Surely using a non-deterministic one that can neither recover past numbers nor predict future ones would be better?

3

u/atoponce 8d ago

Non-deterministic RNGs meet this requirement, but their hardware designs are usually black-box "trust me bro" or come with NDAs. We're generally skeptical of these implementations and prefer designs we can audit. On top of that, backtracking resistance isn't terribly difficult to get correct.

1

u/neuralbeans 8d ago

Isn't dev/random such an RNG?

2

u/atoponce 8d ago

/dev/{,u}random is a hybrid RNG. I think it's most accurately categorized as a non-deterministic software RNG, as it requires hardware noise to constantly reseed a CSPRNG.

7

u/DeflateAwning 9d ago

Generating 10 private keys for 10 different users...

2

u/neuralbeans 8d ago

Wouldn't you use a true random number generator for those?

3

u/atoponce 8d ago

Cost primarily. Why purchased dedicated HWRNG hardware when your OS already ships a CSPRNG for free?

1

u/neuralbeans 8d ago

Isn't dev/random a true random number generator? I don't think it uses one way functions.

2

u/atoponce 8d ago

No. It's a CSPRNG. Always has been.

3

u/Pharisaeus 9d ago

Is there an application requiring random numbers where this requirement is critical?

Any stream cipher? Stream cipher works like this:

  1. Generate random bytes (keystream)
  2. XOR them with plaintext to produce ciphertext

Now imagine that I know a "crib", some short phrase that I know appears in the plaintext. I can XOR that with ciphertext to recover part of the keystream, and if I can now compute the previous or next random values from that point, then I can decrypt rest of the message.

There are also more obvious reasons related to "forward secrecy" - what if someone was recording all past encrypted data, and now they can decrypt them?

1

u/neuralbeans 8d ago edited 8d ago

So it's to make only half the plain text recoverable? Also, recovering a generated random number from a non-cryptographic PRNG doesn't mean that you've recovered the state that let's you generate past or future numbers.

2

u/Natanael_L 9d ago edited 9d ago

There's plenty, in particular algorithms with single use secrets (a lot of key exchange algorithms, some signature algorithms).

If you can recover secrets that were supposed to be permanently deleted you can break a ton of protocols and steal secrets and impersonate people

1

u/neuralbeans 8d ago

Wouldn't a non-deterministic true random number generator be better for that? That way an attacker cannot predict future random numbers either.

2

u/Natanael_L 8d ago

This is called reseeding / key erasure, or in some scenarios recovery security. Every major OS RNG periodically refills the system RNG seed with fresh secret randomness.

A hardware based generator isn't going to be fast enough while simultaneously guaranteeing perfect debiasing

1

u/paulstelian97 8d ago

If you can reverse a generator, then for example you can have someone generate a key pair followed by some public value; your ability to reverse the RNG would extract the private key from the key pair.

1

u/neuralbeans 8d ago

You can't recover the state from knowing a generated random number. You can't do that with a non-secure PRNG if it has good randomness.

3

u/paulstelian97 8d ago

If you have enough random bits, you can reproduce the internal state of a bad/insecure RNG and then can even reverse it. Good RNGs challenge _both_ the reproduction of the internal state, _and_ the ability to reverse it shall you end up getting such an internal state.

1

u/neuralbeans 8d ago

So if you use an invertible PRNG, but use a large seed and state space and emit just the last significant bit from each generated number, would you be able to recover the state or seed from a few recovered generated bits?

3

u/paulstelian97 8d ago

If it’s a _good_ one, not really, but some may allow enough information to be obtained that way in a not very long interval. The good ones just make it so you need a LOT lot of info, like more than you could practically collect.

The best RNGs combine the PRNG aspect with reseeding, adding small amounts of potentially truly random information in the state. That makes it non-reversible.

1

u/ottawadeveloper 8d ago

Password generation is random. If you then obtained one randomly generated password, you could run it in reverse to discover previously randomly generated passwords

5

u/doggydestroyer 9d ago

Let's suppose you generate ssl keys and random primes for that... Let's suppose for RSA... Then getting prior state of RNG will compromise previous keys...

1

u/neuralbeans 8d ago

Shouldn't you be using non deterministic true random numbers for those?

3

u/doggydestroyer 8d ago

Typically the rate of RNG must be very high especially for servers... AES-CTR for example mode is a very high quality RNG that can produce GB/s... Also debiasing true random observation needs some kind of hash function as well... So pipeline is unpredictable data -> hash conditioner -> AES-CTR mode...

1

u/neuralbeans 8d ago

CSPRNGs are slow as well, no?

2

u/atoponce 8d ago edited 8d ago

They don't have to be, no. A simple CSPRNG is AES in fast-key-erasure mode. If you have AES-NI, then you can produce an extremely fast random bitstream. On the order of gigabits per second.

On my Intel Core i7-8650U CPU @ 1.90GHz, I get just shy of 800 MBps with a 16-byte block and 6 GBps with a 16k byte block with AES-128-ECB:

$ openssl speed -evp aes-128-ecb ...(snip)... type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes AES-128-ECB 792189.37k 3070270.93k 5008869.29k 5758503.59k 6132162.56k 6176565.93k

Compared to ChaCha20, which is not hardware accelerated, it's about half as good:

$ openssl speed -evp chacha20 ...(snip)... type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes ChaCha20 342175.45k 711233.66k 1477347.32k 3090790.74k 3314854.57k 3210231.81k

Sure, there will be some overhead for the re-keying logic, but not enough to significantly impact the performance of the CSPRNG. It's one call of the primitive, the rest is insignificant overhead. It is still considerably faster than any off-the-shelf HWRNG, even those from ID Quantique.

Edit: typo

3

u/WE_THINK_IS_COOL 9d ago edited 9d ago

Suppose you compromise a web server that generates its API authentication tokens using a CSPRNG and stores their hashes for validation. If you could run that web server's CSPRNG backwards, you could recover all of the previously-emitted authentication tokens, whereas if you can't, you're stuck trying to crack the hashes.

Or perhaps a web server and client use a CSPRNG to generate their TLS session keys in modes with forward secrecy. If you could run their CSPRNGs backwards in time, you could get those keys and decrypt past TLS sessions.

A reversible CSPRNG's outputs are vulnerable to theft from a compromise occurring indefinitely in the future. So making the CSPRNG non-reversible limits the window of exposure of outputs that are generated but not stored on the system (since if they were stored, the attacker could just get them from wherever they were stored instead of running the CSPRNG backwards).

You also want to make sure it's impossible to recover the CSPRNG's state from the outputs, which is another reason one-way functions are used. And continually injecting randomness or re-seeding prevents an attacker from learning future outputs as well (e.g. if their attack was limited to just being able to make a copy of the system's state, like they can't persist malware on the machine or whatever).

1

u/neuralbeans 8d ago

I guess my question is why use a deterministic CSPRNG that would compromise future generated numbers when you can use a non-deterministic true RNG that would keep both past and future generated numbers secret.

3

u/WE_THINK_IS_COOL 8d ago

Mainly for speed. True hardware RNGs can only produce bits at a limited rate, and the application might need more bits per second than the hardware can produce, so in practice (e.g. in the Linux kernel's /dev/urandom) a CSPRNG is used for generating the output, which periodically has true randomness from the hardware RNG injected into its state to prevent forward/backward-looking attacks.

Older CPUs also do not have a hardware RNG built in, so in that case the OS is limited to collecting "true" randomness from the precise timing of interrupts, network and disk I/O, and so forth, which is extremely slow at gathering entropy.

In that case the entropy needs to be estimated and "pooled" to be injected all at once in large batches, using the CSPRNG for generating output in between. If small amounts of entropy were just injected immediately instead of in large batches, then an application could continually read the CSPRNG's output and brute-force each injected value "Hollywood style", i.e. brute-forcing the 10 unknown bits of the precise timing 100 times (100 * 2^10 operations) by asking for the next CSPRNG output after each 10-bit injection, instead of having to brute-force the whole batch of entropy (2^(10 * 100) operations) when it's pooled and injected all at once.

3

u/Honest-Finish3596 8d ago

Knowing any part of the plaintext of a stream cipher gives you knowledge of the keystream at that point automatically, then you can just rewind to get the rest of it. For this reason it should not only not be possible to reverse, but also impossible to predict forwards.

Known plaintext attacks are always a concern because the attacker can always guess parts of your plaintext, unless you are encrypting uniformly random numbers.

Blum blum shub is insecure for all practical parameter sizes and you should use a symmetric key stream cipher instead.

2

u/Intelligent_Law_5614 9d ago

Consider a system in which a server is using such a generator to create cryptographic keys or nonces, which it uses to create encrypted session connections with a bunch of different clients.

Consider what would happen if one client of such a server was a bad actor.

If it could ask the server to create an encrypted connection, and could use the key it negotiated with the server to discover the RNG's internal state and reverse-compute the earlier states, it would then be able to deduce the session keys which the server had generated previously for other connections. If it has been able to eavesdrop on the earlier connections it could then decrypt the content of those connections. This is one instance of a "record now, decrypt later" attack.

Because this is s reverse attack, the server could not mitigate it after the fact by discarding and renewing the internal state of the RNG using fresh entropy, even if it did this immediately after giving a key to the bad actor.

2

u/dittybopper_05H 5d ago

How is it useful to be able to keep past generated random numbers secret when future ones are compromised?

This should be obvious, but to keep your past traffic secure.

If you're using encryption it's because you want to keep the information being exchanged a secret. You can learn a lot about current events by reading past traffic. This is why signals intelligence organizations keep traffic that they can't break pretty much indefinitely, because they might one day be able to actually break it.

1

u/esteindividu0 9d ago

any inversion algorithm gives immediately a distinguisher from random: to distinguish you can just check if the inverter succeeded.

1

u/neuralbeans 8d ago

If you can predict future numbers then you can still confirm that they are not true random, no?

2

u/esteindividu0 8d ago

yes, that is the idea. a successful inverter can be used to predict accurately, whereas no true random string allows it.