1

Say I have Math.random() (which supposedly generates ~32 bits of entropy.) If I use Math.random() + Math.random(), both of them generate ~32 bits of entropy.

I will use the solution of Math.random() + Math.random() to seed another PRNG, so is using Math.random() + Math.random() to seed the PRNG 'better' (as in total entropy input into the system) than using Math.random() by itself?

schroeder
  • 123,438
  • 55
  • 284
  • 319
  • 1
    Related, but not duplicate question: [Why is `Math.random()` not designed to be cryptographically secure?](https://security.stackexchange.com/q/181580/163495) –  Aug 27 '19 at 10:15
  • Math.random() isn't nearly as bad as it used to be a few years ago, when the output was very predictable, as "both" browsers have since improved their algo, but it's still not a CSPRNG. – dandavis Aug 27 '19 at 20:12
  • What are you trying to make it more secure for? The biggest use for cryptography is going to be communication with the server, which is going to be handled "natively" by the actual connection. – Clockwork-Muse Aug 28 '19 at 15:41

3 Answers3

2

The Math.random() function in a browser's Javascript engine is not cryptographically secure.

That is, it does not draw from a truly random source of bytes, and it follows a predictable pattern, even if most people would be unable to recognize that pattern.

Simply using one semi-predictable sequences of numbers to set up a different semi-predictable sequence of numbers is not enough to meaningfully increase security.

Rather, if you need security, use window.crypto.getRandomValues() instead.

Ghedipunk
  • 5,766
  • 2
  • 23
  • 34
2

Math.random() (which supposedly generates ~32 bits of entropy

No, it doesn't. Math.random is not a cryptographically secure random generator, so what it returns does not have any entropy. Entropy is a measure of how unguessable the output is. Since the output of Math.random is guessable in many circumstances (most easily, by having observed previous outputs, or by observing subsequent outputs), it has zero guaranteed entropy.

If I use Math.random() + Math.random(), both of them generate ~32 bits of entropy.

No, they don't. Even if Math.random was seeded by a cryptographically secure pseudorandom generator, the first call could have 32 bits of entropy, but the second would be reusing the same entropy, so the entropy would not add up. The second output is correlated to the first, so using it does not increase security.

Furthermore, since Math.random returns a number, you're adding two numbers together, not concatenating strings, so the addition loses information. With floating point numbers, the information loss is mainly through rounding; with integers, it would be through wrapping. (Thanks to benrg for pointing this out.)

There is simply no way to generate random numbers securely using Math.random. You can't make a secure random generator from a non-secure one. Use Crypto.getRandomValues instead.

Gilles 'SO- stop being evil'
  • 50,912
  • 13
  • 120
  • 179
1

Other answers have already pointed out that Math.random doesn't generate secure random numbers. But even if you did have a source of secure random numbers, adding them together is not a good way to use them, because you lose most of the entropy.

Suppose you have two high quality random integers a and b in the range 0 to 232−1 inclusive. Each one has 32 bits of entropy, and the two of them in total have 64 bits of entropy. But a+b is an integer in the range 0 to 233−2. That means it can have at best about 33 bits of entropy, and in reality it'll be slightly less than that because some values in that range are more likely than others (for the same reason that when you roll two dice and add the results, 7 is more likely than 2 or 12). So using a+b is scarcely better than just using a.

If the PRNG you're using is any good, it'll have some way to accept larger seeds. If it takes an array of 32-bit integers, and your source can provide 32-bit integers, then just use (say) 4 integers from the source in an array of length 4. Don't try to improve on the source by manipulating its output. If the source is any good, it has already done all of the necessary manipulation for you.

benrg
  • 235
  • 1
  • 4
  • Oh yes, that's a good point. I'm so used to thinking of random generators as generating bit strings that I parsed `+` as concatenation, not addition. Oh, and isn't `Math.random` a floating-point number rather than an integer? Which complicates the analysis on the distribution, but doesn't change the fundamentals. – Gilles 'SO- stop being evil' Aug 27 '19 at 19:07