0

Most papers either do not even mention it or just say get an "initial vector" from somewhere somehow.

The approach posted in a lot of places is to use system time. However isn't this a serious vulnerability (assuming the algorithms are known)? If the time is known withing a few seconds I estimate (by doing a few trivial tests using QueryPerformanceCounter) there would be less than 24 bits of actual information (quite pathetic). Plus since time has a somewhat predictable nature, one could generate necessary information for a hypothetical attack in advance.

Is there a way to initialize a PRNG and not feel sad?

beothunder
  • 551
  • 2
  • 14
  • 1
    What application do you have in mind? Is it for a game, a simulation, or an information security application? For the latter, a related question: https://stackoverflow.com/questions/62375129 For the first two, a related question: https://stackoverflow.com/questions/59263562/impact-of-setting-random-seed-to-recreate-a-simulated-behaviour-and-choosing-t/59268858#59268858 Also, NumPy initializes its generators using the operating system's randomizer, rather than a mere timestamp, by default: https://stackoverflow.com/questions/66092967 – Peter O. Sep 15 '21 at 20:39
  • I am not doing anything in particular. Just was curious. Time would do just fine for a no adversary situation like a game or simulation. The link you posted (for the cryptographic case) is interesting. However all it basically says is "try harder" :D – beothunder Sep 15 '21 at 20:48
  • Perhaps `(time(0)*0x10000) ^ getpid()` or the like? – chux - Reinstate Monica Sep 15 '21 at 21:07
  • pid is public information. And I am assuming the algorithm is known. So the information content will not increase from these modifications. – beothunder Sep 15 '21 at 21:11
  • 1
    If you are looking for a cryptographic secure seed, code needs something like [urandom](https://linux.die.net/man/4/urandom) - a true random source. If looking to cause different behavior of 2 simultaneous program invocations, `^ getpid()` is useful. Not all programs using random() functions need a cryptographic secure PRNG seed. "What should be used as a PRNG seed?" is program requirement specific issue, not a _general_ one. – chux - Reinstate Monica Sep 15 '21 at 21:21
  • There is a similar discussion on SO [here](https://stackoverflow.com/questions/68828745/which-seed-when-using-pytorch-manual-seedseed), within the context of PyTorch and a 64 bits seed; with some Python code samples. – jpmarinier Sep 17 '21 at 12:58

1 Answers1

0

If you are needing to generate cryptographically secure random numbers, you should almost always use the operating system's CSPRNG; that is, /dev/urandom, CryptGenRandom, getrandom, getentropy, or the like. This will be secure, well-seeded, well-tested, and generally foolproof.

In the unlikely event that you actually need a different CSPRNG, then the PRNG entropy should either be drawn from the system CSPRNG or another CSPRNG that is seeded from the system one. For example, in the event you really need to generate random numbers very quickly and the OS generator is not fast enough, you could use a per-thread CSPRNG seeded from the OS generator.

We assume that an attacker knows how your code is designed and structured, so if you seed a CSPRNG with easily guessable values like the PID, time, or user ID, then it's likely that an attacker will be able to guess future output based on seeing a small amount of output.

If you don't need cryptographic security, you can draw the seed from any source you like, but the OS CSPRNG is not a bad choice if you don't care very much but just want a good seed. For non-cryptographic purposes, I like ChaCha8 (which is a cryptographic algorithm, but with 8 rounds is insufficiently conservative) as my PRNG because it is generally faster than most alternatives, has good statistical properties, and can easily be seeded with any 32- or 64-bit value by just repeating that value as the key. In such a case, as long as the seed is unlikely to repeat, it will probably produce good output.

bk2204
  • 64,793
  • 6
  • 84
  • 100