# Using ChaCha20 as a PRNG with a variable-length seed

As far as I understand, the key stream of the ChaCha20 cipher may be used as a seeded PRNG, where the seed is used to set the key and the nonce. As described in RFC7539, ChaCha20 can be used with a 256-bit (32-byte) key and a 96-bit (12-byte) nonce, allowing a seed of maximum 352 bits (44 bytes), thus limiting the counter to 32 bits (4 bytes).

My problem is, how can I use this PRNG if I want to provide a larger seed? Say, I seed the PRNG from an entropy source where I a can guarantee a minimum of about 4 bits of entropy per byte, and want to seed the PRNG with 64 bytes or more to be confident that it has been provided about 256 bits of entropy.

I reckon a cryptographic hash function, such as SHA256 or SHA512, could be used to compress the collected entropy bytes to be used as a seed, but it would be desirable if this could be solved by only using the available ChaCha20 primitive.

Another possibility seems to be to use ChaCha20 to construct a Davies–Meyer one-way compression function, treating a variable-length seed as blocks of 44 bytes (to input as key and nonce for the next block), taking the final 44 byte output as input seed to the PRNG.

It seems that Davies–Meyer was designed to be used with block ciphers, but ChaCha20 is a stream cipher.

My questions are:

1. Are there any obvious problems with using Davis-Meyer like this?
2. Are there any obviously better approaches to feed this PRNG with a variable-length seed?

ChaCha20 is a PRF, so you can use it as an extractor. k0 and k1 being two random 256-bit keys, compute E(k0,E(k1,0)), and use half the output as a key. Remaining bits can be used for the nonce, but in case (k0,k1) repeats, you may want to use a different source for the nonce, even a simple timestamp.
• Here you mean $E(k, n)$ where $k$ is the 256-bit key and $n$ is the...128-bit input? So you truncate $E(k_1, 0)$ to a 128-bit chaining value to feed it into $n \mapsto E(k_0, n)$? – Squeamish Ossifrage Dec 19 '17 at 23:21