Background: Implementing online casino, I would like to use a number of PRNGs with high throughput, like MersenneTwisterFast. I know it is not cryptographically strong, but quite unpredictable when used with a proper seed value (is it?), let's say, AES-CTR.

Question: How secure would be the PRNG, initialized by a generated value from another PRNG, that was initialized by a cryptographically strong seed (taken from /dev/random per se)?

As to my mind, good PRNG algorithm can't be predicted when seed is unknown (and which is securely random), so the seeds for the second level PRNGs are also securely random, and their sequence is also unpredictable. Am I right?

UPDATE: I think this article is highly related to my question: /dev/urandom is actually a properly seeded CSPRNG seeding other CSPRNGs.

  • Tough question (at least to me), but interesting nonetheless. I have what is possibly a dumb question: why cant you use the CSPRNG throughout the application?
    – Gray
    Commented Feb 26, 2014 at 15:09
  • @Gray, I forgot to mention it here, as I first asked this question in another form on Stack Overflow: it's just the performance is really not good enough.
    – shpikachu
    Commented Feb 26, 2014 at 15:53
  • Out of curiosity (feel free to decline to answer), what is the performance difference? Are we talking ms being shaved off or a real time difference?
    – Gray
    Commented Feb 26, 2014 at 18:34
  • Check out this question: Does (online) poker require cryptographically secure randomness?. Not exactly the same, but it covers some interesting points. Commented Feb 27, 2014 at 10:59
  • I'd focus on using a fast CSPRNG. AES-CTR will be able to emit gigabytes per second. Commented Feb 27, 2014 at 11:23

3 Answers 3


First of all there is nothing wrong with seeding a CSPRNG with the output from another CSPRNG, as far as the source has been properly seeded in the first place.

As others have stated, Mersenne Twister is not a cryptographic algorithm, so you should not use it for a casino.

/dev/random and /dev/urandom is built using a solid CSPRNG on pretty much every modern UNIX, save for any possible incidents with improper seed you can use either for anything, and in many systems neither will ever block once they have been properly seeded.

The exception is Linux where an old home-grown slurry function is used in place of modern cryptography. /dev/random blocks because that theoretically under certain assumptions makes the output cryptographically secure, even if the slurry function is not of cryptographic strength. And /dev/urandom throws that away because then one can actually get some work done.

Linux random has not been truly broken, it is just in the zone of some partial exploits being possible under controlled conditions: https://www.schneier.com/blog/archives/2013/10/insecurities_in.html

Combined with the difficulties of only getting incomplete and permuted outputs I don't think it is likely that an attacker could exploit Linux /dev/urandom through your site. But why risk it? You can safely use /dev/random to generate a seed for a proper CSPRNG. As long as you don't otherwise expose output from /dev/random it doesn't matter if the slurry function is cryptographically strong or not, an isolated piece of the output is still sufficiently unpredictable.


This certainly looks like premature optimization.

A fast CSPRNG on a modern Intel CPU will output between 500 MB and 2 GB per second. Even if you have a quite random game which requires 100 random bytes per second per player (I can't think of a typical casino game anywhere near that) a single core will be able to generate random numbers for ten million simultaneous users.

Other operations, such as database access, the webserver etc. will be much more expensive than generating good random numbers. I recommend seeding a good stream cipher like ChaCha or AES-CTR from the system random generator instead of downgrading to an insecure PRNG. It's possible that the system random generator by itself is already fast enough.

Check eBACS for benchmarks of stream ciphers.

Using non crypto PRNGs like Mersenne-Twister for an online casino is a really bad idea. These generators don't aim an unpredictability. They only try to look random enough that their flaws don't cause any deviation from actual random data that breaks the using code by accident.

For example if you ran a scientific simulation with MT and with perfect random numbers and it gave different results, that'd be considered a flaw in MT. But it doesn't try to resist somebody who deliberately tries to predict the output.

As @CL. already said, MT is easily predictable once you've seen a few hundred outputs. Compare that with a CSPRNG which will be indistinguishable for true random numbers even after observing petabytes of data.

  • It's a post-mortem optimization actually. In the current implementation the bottleneck appeared to be the waiting for the entropy from /dev/random for MT initialization. That initiated me to search for several solutions. One was to use different RNG, another--to optimize the current schema. From both answers I understand that the main flaw is MT usage--fine, is it the reason my idea is bad? If I replace just MT with AES-CTR in my question, will the answer be: 'yes'?
    – shpikachu
    Commented Mar 1, 2014 at 10:41
  • You need to replenish /dev/random faster than you use it. Commented Mar 3, 2014 at 21:53
  • @theGreenCabbage, well, yeah: 'Do what you should do, and don't do what you shouldn't' - but that still doesn't answer my question
    – shpikachu
    Commented Mar 4, 2014 at 5:25
  • Or just use /dev/urandom. Commented Mar 4, 2014 at 8:20
  • @CodesInChaos, still doesn't answer the question 'Is seeding CSPRNG with a sequence from another CSPRNG secure enough', does it?
    – shpikachu
    Commented Mar 4, 2014 at 9:45

Wikipedia says:

The algorithm in its native form is not suitable for cryptography (ie it's not a CSPRNG). Observing a sufficient number of iterations (624 in the case of MT19937, since this is the size of the state vector from which future iterations are produced) allows one to predict all future iterations.

In other words, even with a strong seed, you get only a few unpredictable output values. The difference between the Mersenne Twister and a CSPRNG is that the latter stays unpredictable for much longer.

You need to reseed the PRNG regularly. Alternatively, use a CSPRNG in the first place, and concentrate on optimizing that one for speed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .