# Can I combine two PRNGs to make use of more seed data?

I have 320 bits of seed data (actually 512 bits of data with 320 bits of entropy, derived from a Diffie-Hellman shared secret and nonces). The PRNG I am using at the moment is the android version of SHA1PRNG. As far as I can tell, it has 160 bits of internal state, and so any entropy over 160 bits would be wasted. Could I create two instances, seeding each with half the data, and combine them somehow? The obvious possibilities would be to alternate which PRNG I pull each byte from, or to XOR the two streams together, but I don't know how that would affect the total entropy.

-
How large is the finite field/elliptic curve you ran you DH on? – CodesInChaos Mar 1 '13 at 8:30
I'm not sure. It's Curve25519, using NaCl. – klkblake Mar 1 '13 at 9:35
In that case you have a ~128 bit security level, so a 160 bit PRNG is fine. Or you can hash your seed data, and use it as key for Salsa20. – CodesInChaos Mar 1 '13 at 9:41
I should add, in case it makes a difference, that the purpose of the PRNG is to detect MitM attacks by generating a random word list based on the session key that the users can compare. (if it doesn't make a difference, post your comment as an answer and I'll accept it). – klkblake Mar 1 '13 at 10:28
There are some tricky points here, but they're not related to entropy or the PRNG. It might be possible that the side that needs to commit later, can generate many public keys, until the random wordlist has some desired properties(such as being similar to the original wordlist). Check out how ZRTP attacked this problem. – CodesInChaos Mar 1 '13 at 10:40

Why are you afraid of "overseeding" the PRNG? The Java SecureRandom class specifies the setSeed function as:

public void setSeed(byte[] seed)


So just feed the 320 bits (40 bytes) data to the setSeed function and it will supplement the existing seed. Leave the compression into the state to the underlying SecureRandom implementation.

[EDIT1]

Note that the SHA1PRNG implementation simply uses the new seed in a message digest update, and that message digest is SHA-1, hence the 160 bit state.

[EDIT2]

Note that it may depend on the entropy source if the entropy represents 320 bits of true random data. The initial compression of the seed data will make sure that any random entropy from the entropy source is used.

Another reason to combine to PRNG's is when the PRNG algorithm is not fully trusted. In that case it is much better to switch to another PRNG. If one is vulnerable the other one will be vulnerable as well.

It is better to re-seed the PRNG more often if there is entropy to spare.

-
My concern was that some of the seed data would be wasted, and so there would be $2^{160}$ possible random streams instead of $2^{320}$. – klkblake Mar 3 '13 at 2:45
There are by definition only $2^{160}$ possible streams because the state is 160 bits... And 160 bits is a lot. – Maarten Bodewes Mar 3 '13 at 11:33
@MaartenBodewes 160 bits is only enough to randomly sort a 40 item list! A 41-item list cannot be randomly sorted into all possible results using only 160 bits. – ErikE Oct 14 at 20:40
@ErikE 160 bits is the size of the internal state, not the output size of the PRNG – Maarten Bodewes Oct 14 at 21:00
@MaartenBodewes I wasn't confused on that point, but I see now that my statement only holds true for the Fisher-Yates Shuffle. Other methods of producing randomly sorted lists of items may not have the same limitation. In any case, it's important for people to be aware of this aspect of the issue. – ErikE Oct 14 at 21:29

If your PRNG expects a 160-bit seed, and you have 320 bits of seed data, you can hash the seed data, then use the result as your seed for the PRNG.

-
Good answer, but in this case the PRNG does not really expect a 160 bit seed at all. The SecureRandom implementation already compresses the seed. – Maarten Bodewes Mar 3 '13 at 1:09