Can I generate cryptographically secure random data from a combination of random_device and mt19937 with repetition?

I need to create cryptographically secure random data in C ++ 11, and I'm worried that using random_device for all data will severely limit performance (see slide 23 from Stephan T. Lavavej " rand () is considered harmful , where he says when he tested it (on his system), random_device was 1.93 MB / s, and mt19937 - 499 MB / s), since this code will work on mobile devices (Android via JNI and iOS), which are probably slower than the numbers above.

In addition, I know that mt19937 is not cryptographically secure, from wikipedia : "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 made) allows us to predict all future iterations."

Given all the above information, can I generate cryptographically secure random data by generating a new random seed from random_device every 624 iterations of mt19937? Or is (possibly) better, all X iterations, where X is a random number (from random_device or mt19937 sown by random_device) between 1 and 624?

+6
source share
2 answers

Do not do this. Seriously, just don't. This is not just asking for trouble - it is more like asking and begging, getting into the most criminal part of the most dangerous city that you can find, carrying a lot of valuable things.

Instead of trying to pick up MT 19937 often enough to hide how unsafe it is, I would advise generating your random numbers by running AES in counter mode. This requires that you get one (but only one) good random number of the correct size to use as the source "seed" for your generator.

You use this as a key for AES and just use it to encrypt consecutive numbers to get an output stream that looks random but easy to play.

This has many advantages. Firstly, it uses an algorithm that has actually been studied to a large extent, and is generally considered very safe. Secondly, this means that you only need to distribute one (rather small) random number as a “key” for the whole system. Thirdly, it probably gives better throughput. Both Intel and (apparently) independent tests show a bandwidth range that starts to compete with what you quote MT 19937 at the lower end and about 4-5 times faster at the upper end. Given how you use it, I expect you to get results close to (and possibly even exceeding 1 ) the upper end of the range that they show.

Bottom line: AES in counter mode is obviously the best solution. The best you can hope for is that the MT 19937 ends as fast and close as safe. In fact, this is likely to disappoint both of these hopes, and as a result they will become slower and substantially less secure.


<sub> 1. How will he exceed these results? This, of course, is based on encryption of bulk data, that is, reading a block of data from RAM, encrypting it, and writing the result back to RAM. In your case, you do not need to read the result from RAM - you just need to generate sequential numbers in the CPU, encrypt them and write the results. Sub>

+6
source

Short answer: no, you cannot. The requirements for cryptographically secure RNGs are very strict, and if you should ask this question here, then you are not well aware of these requirements. According to Jerry, AES-CTR is one option if you need repeatability. Another option that does not allow repeatability is to look for an implementation of Yarrow or Fortuna for your system. In general, it is much better to find CSRNG in the library than to collapse your own. Library authors are quite knowledgeable about the requirements for a good CSRNG.

+5
source

Source: https://habr.com/ru/post/987975/


All Articles