How can a block cipher in counter mode be a reasonable PRNG when it's a PRP? Wikipedia claims:


  A secure block cipher can be converted into a CSPRNG by running it in counter mode. This is done by choosing a random key and encrypting a 0, then encrypting a 1, then encrypting a 2, etc. The counter can also be started at an arbitrary number other than zero. Obviously, the period will be 2^n for an n-bit block cipher; equally obviously, the initial values (i.e., key and "plaintext") must not become known to an attacker, however good this CSPRNG construction might be. Otherwise, all security will be lost.


Here's a trivial counter-example:

Say I'm interested in generating psuedo-random 128 bit numbers. I'm using this method with a 128bit block cipher, but since the block cipher is giving out essentially a psuedo-random permutation of the counter - all the numbers I get are different! They are obviously not going to pass any basic randomness tests?!

Is this a mistake in Wikipedia (or just a misleading explanation?) or there's something I got wrong here?

If the answer is that it simply wouldn't work for values equal or larger than 128 bits, I would still doubt it would give out good quality output for 64 bits, since it has a very predictable pattern that the concatenation of any two consecutive 64 bit values is unique pattern that would never repeat (if that's a not a "real concern" mathematically, could you explain why? and what about 96 bit numbers?).

And if this is actually the case, are there any alternative examples of CSPRNG constructions that generate quality values for arbitrarily large amount of bits? are secure hashes any better (it seems reasonable I guess..)?

[Note: I've found this answer that very shortly addresses this issue but I didn't find it satisfying enough]



Update: Wikipedia seems to be updated now as a result of this discussion! Many thanks for @CodesInChaos who improved the article. This is useful knowledge for myself and many other people.
For a random function you'd expect all outputs to be different if you generate fewer than $2^{n/2}$ blocks (birthday problem). Thus PRPs and PRFs are indistinguishable unless you observe about $2^{n/2}$, at which point you'd expect collisions using the PRF but not using the PRP.

For a 128 bit cipher this is a lot of data, so we generally don't care about this. But using a 64 bit cipher, you shouldn't encrypt more than a few gigabytes of data using the same key.


  are there any alternative examples of CSPRNG constructions that generate quality values for arbitrarily large amount of bits?


In principle yes. I think using a variant of CTR mode which uses a secret IV and xors the counter+IV into the output might work. It'd get rid of the trivial "no duplicates" pattern, but it might be distinguishable in other ways.

128 bit blocks should be good enough as a stream cipher/CSPRNG. But if it's a bit too low for your taste (Generating $2^{64}$ blocks is feasible with sufficient effort), you can simply use larger blocks. Typically hash functions (like SHA-2), which want to avoid collisions, use 256 or 512 bit block ciphers.



I've changed the paragraph on wikipedia to


  A secure block cipher can be converted into a CSPRNG by running it in counter mode. This is done by choosing a random key and encrypting a 0, then encrypting a 1, then encrypting a 2, etc. The counter can also be started at an arbitrary number other than zero. Assuming an n-bit block cipher the output can be distinguished from random data after around $2^{n/2}$ blocks since, following the birthday problem, colliding blocks should become likely at that point, whereas a block cipher in CTR mode will never output identical blocks. For 64 bit block ciphers this limits the safe output size to a few gigabytes, with 128 bit blocks the limitation is large enough not to impact typical applications.


I mention the $2^{n/2}$ birthday bound limitation. Removed the part about the period, since it doesn't matter in practice (it's far above both practical output size and safe output size). I also removed the part about keeping key and plaintext (what plaintext? It's a CSRPNG, not a cipher) secret. I'm not really happy with the formulation, so feel free to improve it.