# Using a PRNG for a stream cipher instead of a dedicated algorithm

I am aware, that it is possible to build a stream cipher using some deterministic PRNG (like HASH_DRBG or CTR_DRBG) with good key material as the seed.

What are the advantages of using a purpose built stream cipher algorithm (like Salsa20 or RC4 before it became obsolete) over a generic PRNG?

• HASH_DRBG is considerably slower than Salsa20/Chacha20. Also the latter has a block property which would enable you to rebuild the stream from any place you want - that property violates a CSPRNG prerequisite that something like HASH_DRBG has - mainly that recovery of the current state should not betray the past states. That said, you can use HASH_DRBG or some variant of it to construct a stream cipher that is as secure as that hash function provided you don't screw up the implementation, it will just not be used. SSL for example, puts a big strain on the server, no one wants it worse. – user10653 May 1 '17 at 2:01
• @dingrite That comment would be a worthy answer. – mat May 1 '17 at 7:51

I use HMAC-DRBG in my python modules as a backup for when no "real" crypto package is installed. The python 2 standard library offers cryptographic hashes and HMAC, but no encryption primitives.

The advantage of HMAC-DRBG over something like AES-CTR/ChaCha is that is significantly less complicated than implementing a "real" design in pure python, and faster as well. This is because the meat of the crypto calls are performed in C, and just dispatched via python - the two calls to sha512 which are executed in C is much simpler and faster then a running AES + modes of operation in pure python.

Additionally, creating an authenticated scheme with support for authenticated extra data requires only a small modification, if you're already using HMAC-DRBG.

While it is obviously not the most ideal setup, and certainly not ideal for production use, it can be useful as a sort of poor mans encryption algorithm when nothing else is available. As it's not an officially prescribed or proven technique for encrypting data, cryptographers may wag their finger at you if you use this technique, especially if it results in problems someday.

It's also going to be relatively slow. The problem is that hashes are designed to eat lots of input data in a small amount of time. They were not necessarily designed to produce lots of output data in a small amount of time (though with sha-3 and the modes of operation, that's arguably not necessarily true anymore; I'm assuming you don't have sha-3 and the modes of operation it offers, otherwise you'd being using it).

If you have other choices, you should probably use them - using a substitute (HMAC-DRBG stream cipher) instead of the real deal (i.e. AES-CTR) if the latter is available is not really a wise decision.

• Technically I think I have an HMAC-DRBG like construction, rather than the official construction, but that is besides the point and likely to go unnoticed anyways. – Ella Rose Apr 30 '17 at 20:35
• I'll second this answer by noting that I've been forced to do the same. There are numerous development platforms for which the only cryptographic primitive available is a hash function. Usually databases, where SHA2 is "native" but any encryption primitives require complicated extension mechanisms that make deployment a major issue. Getting a bank to enable a bunch of scary-souring flags and load executable libraries onto their database server is a non-starter. So HASH_DRBG plus HMAC gives you at least some way to do authenticated encryption when it cannot be done in the application tier. – rmalayter May 1 '17 at 3:57

Rather than giving the advantages of purpose build stream cipher I'll give the disadvantages of using a PRNG / DRBG (you are using a PRNG for the use case of a stream cipher after all):

• Implementation details (including reseeding) may differ between systems (this is less likely if the DRBG is well defined and tested, but as they have been designed to retrieve random numbers given some entropy, you never know);
• Often deterministic stream ciphers are retrieved from the system. That means that they may be reseeded. You could argue that this is mainly what makes them different from a stream cipher in the first place.
• PRNG's often contain additional counter measures to decouple the state from the input (seeding material) & output, making them slower;
• PRNG's are often more complex than just a stream cipher (code size, number of instructions). They are indeed often created from stream cipher-like constructions (such as CTR_DRBG you mentioned);
• PRNG's are simply not defined for this kind of functionality in mind, making implementation and code maintenance more complex (considering, for instance, the principle of least surprise, which using a PRNG as stream cipher definitely violates);
• PRNG's often do not contain implementation details like buffering, the final XOR operation etc. build into them; you may have to wrap a DRBG to create the same experience of a stream cipher operation encrypt / decrypt (and in e.g. Java you cannot simply add a Cipher without implementing and signing a provider).
• Interesting answer, quite contrary to what my thoughts have been. My reasoning, which brought me to this question, was, that I usually have a hash function primitive available anyway. And since implementing HASH_DRBG is extremely easy, one could spare oneself the (possibly error prone) implementation of a more complicated scheme. – mat Apr 30 '17 at 16:06
• If HASH_DRBG was so advantegeous we would have seen stream cipher implementations based upon a hash construction (and although they are probably defined somewhere, they certainly aren't popular). – Maarten Bodewes Apr 30 '17 at 16:12
• KeccaK/SHA-3 based constructions may change that though. In that case a direct stream cipher construction based on the underlying sponge construction is used though, not a PRNG. – Maarten Bodewes Apr 30 '17 at 16:17
• I know that that is rarely used, and was wondering why, wether there is any security margin with purpose built stream ciphers. – mat Apr 30 '17 at 16:22
• I don't think there is a (significant) difference with regards to the security margin; I think the other properties are more important in this case. But do note that they have slightly different properties; e.g. the seed may not be well distributed, so in general I'd expect some kind of internal randomness extraction during creation of the inital state, which is not required for a well distributed key in a stream cipher. – Maarten Bodewes Apr 30 '17 at 16:25

I think this question's answer becomes much clearer if we refine our terminology/classification of algorithms, to focus on the requirements instead of the mechanics. In particular, cryptographic uses of "random" numbers tend to fall into one of two categories:

1. Applications that need deterministic values that an adversary cannot predict, but which honest parties must be able to.
2. Applications that need nondeterministic values that an adversary cannot predict, but honest parties don't need to predict either.

Category #1 is pseudorandom generators. Category #2 is often not recognized or confusingly labeled—it's a goal that can be fulfilled either by true random generators, by pseudorandom ones, or most often in practice, by algorithms that combine true random sampling and pseudorandom generation. The prime example is the operating systems' random number generators, which collect random event timing data periodically in order to refresh the state of a pseudorandom generator.

Now, the NIST DRBGs are algorithms designed for category #2. Salsa20 and RC4 are designed for #1. And stream cipher encryption is a category #1 application that needs determinism—to decrypt Alice's message, Bob must deterministically reconstruct the same keystream that Alice generated.

You could encrypt with a DRBG, but they just have superfluous steps that are irrelevant to encryption. And the way DRBGs are constructed, if you examine it in detail, bears this—a DRBG generally include some form of stream cipher as a component, along with additional stuff so that an application can nondeterministically perturb its state with true random samples.

• I suspect that "additional stuff" would render a stream cipher more secure in an environment where an attacker can modify the input data and perform a cryptanalysis on the output to attempt to determine the key. – Erik Aronesty May 1 '17 at 17:13