Live data from Hacker News

Need a PRNG? Use a CSPRNG

sortingsearching.com

31–40 of 105 posts

Re: Need a PRNG? Use a CSPRNG

#31
post #17

An alternative to the post is to take any PRNG's output and calculate the SHA3 hash of it, then use the hash as the random number. If SHA3 is not available, use AES. In either case, all statistical weaknesses and side-channel attacks will be eliminated. The platform is far more likely to have support for either of those in the system libraries, than a bespoke CSPRNG, which would need to be packaged with your app/game…

That might be convenient so you don’t have to go fishing for 3rd party libraries - which is especially a problem in C/C++. But I expect the result will be much slower than using an optimized csrng like chacha.

Re: Need a PRNG? Use a CSPRNG

#32
post #17

An alternative to the post is to take any PRNG's output and calculate the SHA3 hash of it, then use the hash as the random number. If SHA3 is not available, use AES. In either case, all statistical weaknesses and side-channel attacks will be eliminated. The platform is far more likely to have support for either of those in the system libraries, than a bespoke CSPRNG, which would need to be packaged with your app/game…

Would be better to simply use a counter and a random seed in that case. Who knows when your prng will loop around, but your counter will always loop at 2^32.

At which point, if you use AES, you've just implemented the AES-CTR csprng that TFA suggests.

Re: Need a PRNG? Use a CSPRNG

#33
post #27
post #21

My biggest use case for random numbers is for fuzz testing. I fuzz test all over the place - any time I have some clear invariants and some complex code to test, I’ll generate random data in a loop and make sure the invariants always hold. This finds so many bugs . But for this kind of work, a good prng is better. The reason is simple: when I find a failing test, I can print out the seed that generated that test. The…

I recommend you research CSPRNGs before arriving at a conclusion. They, too, are seeded, which is helpful for deterministically replaying a sequence, say for fuzzing.

Oh, TIL! And indeed chacha in Rust’s rand crate can be seeded. Cool!

https://rust-random.github.io/rand/rand_chacha/struct.ChaCha...

Re: Need a PRNG? Use a CSPRNG

#34
There are lots of cases where a PRNG is more appropriate than a CSPRNG. Wiping disks is one of them, as the CSPRNG becomes the bottleneck with large arrays. Testing i/o or network throughput is another; you don’t want your algorithm tainting the results.

I like the thrust of the article but if you’re going to be particular, you should also be correct. CSPRNGs are not suitable replacements in 100% of cases.

Engineering is about trade-offs.

Re: Need a PRNG? Use a CSPRNG

#35
post #11
post #6

For many kinds of Monte Carlo algorithms, CSPRNGs are stupidly slow. The author compares two handpicked examples of a fast CSPRNG and a very slow PRNG, arriving at a factor of 4. In practice, e.g. comparing to very simple stuff like multiply-add RNGs, it is more like a factor of 4000. Only to then claim that "But that would only be true if generating random bits was the hot spot, the bottleneck of your program. It ne…

It's not true that I cherry-picked a slow PRNG for my 7 GB/s number. In fact I selected the second-fastest PRNG on that page (because it's popular)! The fastest one is 8 GB/s. PCG32 is 3 GB/s. Your 4000x factor speed up for a linear-congruential generator is just a completely false number. Yes I did pick ChaCha20 for its speed -- it's designed for speed! "A few hundred FPU instructions" in your Monte Carlo is not com…

Upon a closer look, do not trust the numbers on https://rust-random.github.io/book/guide-rngs.html in any way, they are clearly bogus and implausible. Their figure for their "StepRNG" which is just a counter is 51GB/s. Their XorShift RNG at 5GB/s, which is just a XOR and a shift is slower than Xorshiro at 7GB/s, which is a xor, shift and rotate, 1 op more. Both XorShift and Xorshiro should actually be of comparable performance to a counter of the same width because with modern CPUs, all those trivial bit operations like shift, rotate and XOR are sub-cycle microops. And all three of those should either be memory-bound and therefore of the same performance, or quite a bit faster than memory-bound if they just measure the in-register performance.

> Your 4000x factor speed up for a linear-congruential generator is just a completely false number. > Yes I did pick ChaCha20 for its speed -- it's designed for speed!

1 Chacha20 block takes 20 rounds, each of which consists of 4 QR (quarter round) operations. A QR is 4 additions, 4 XORs and 4 ROTLs, so 12 instructions on 32bit values. Multiply that together and you arrive at 960 operations per block (actually a handful more for the counter, maybe the round loop and stuff like that, but not a lot), each block gives you 16 uint32 values. So 60 instructions per uint32 or 15 instructions per byte.

A multiply-add generator takes only 2 instructions (you could use fused-multiply-add if available, but i'll leave that out as I left out sub-microop-rotate before, just to not overcomplicate things) per uint32 or half an instruction per byte. Yes, that is not yet a hyperbolic factor of 4000.

But then you'll have to use your random values. Since your Chacha20 random number stream only comes in blocks, on many CPU architectures, you will have all your registers full with your resulting block. Meaning that for the subsequent calculation, you have to store those random numbers somewhere or throw them away, do your other calc, then load the randomness again, etc. So you will always pay a penalty for cache and memory accesses and you will always have unnecessary register pressure. Even a L1 cache access will cost you about 4 cycles of access latency, other cache levels are far worse. Which means that it probably won't be 4000 yet, but a lot more.

Now we'll arrive at "yes, but somebody said ChaCha20 is roughly 1 cycle per byte!". Which isn't wrong, but you have to read carefully: 1 _cycle_, not 1 _instruction_. That benchmark relies on calculating multiple ChaCha20 blocks in parallel, because a modern CPU has multiple execution units and thus can execute multiple independent instructions within one cycle. There is also SIMD, where one instruction can operate on multiple pieces of data. But to be fair, we also need to do this with our multiply-add-RNG. And where I can have 16 registers of 32bits calculating one ChaCha20 block, I can also have 16 of the same 32bit registers calculating 16 multiply-add random numbers in parallel.

Thus giving us 60 cycles per ChaCha20 uint32 vs. 0.125 cycles (2/16) per multiply-add uint32. That is a factor of 480, not taking possible memory or cache penalties into account, because that really depends on the computation between the randomness steps. Still not 4k, I admit, that was hyperbole.

Re: Need a PRNG? Use a CSPRNG

#36
post #26

This is wrong for two reasons Firstly Reproducibility Using "true" randomness sacrifices that Secondly Performance In simulations you often need billions of these There are cases for true randomness, it is a good thing it is available those rare occasions5

> Reproducibility

That's a very silly objection: CSPRNGs can be seeded just like a PRNG. The "P" in both abbreviations is the key, it stands for "pseudo".

Re: Need a PRNG? Use a CSPRNG

#37
post #26

This is wrong for two reasons Firstly Reproducibility Using "true" randomness sacrifices that Secondly Performance In simulations you often need billions of these There are cases for true randomness, it is a good thing it is available those rare occasions5

CSPRNGs are not true randomness. They are PRNGs (with a seed and all), but with cryptographic guarantees. That also means, as a corollary, that they are generally good RNGs.

TRNG appliances can get very high throughput, too.

Re: Need a PRNG? Use a CSPRNG

#38
The author is a bit too categorical, there are certainly use-cases where both speed and code-size matters a great deal. Others have mentioned Monte Carlo algorithms, but there are others: not very long ago I was doing an effect in a shader that needed a PRNG, it would have been lunacy to use a CSPRNG. High quality statistical properties are not important at all, but speed and instruction size is VERY important. My hunch is that this is often true in game-dev: Minecraft probably should not use a CSPRNG to generate its random world.

However, in general, I basically agree: for MOST tasks where you need a random number generator, a CSPRNG is probably the right choice and it's a reasonable "default" choice if you don't have good reasons why it shouldn't be. It's a continual annoyance to me that PRNG libraries usually don't include any solid CSPRNGs (looking at you, C++ header ) when it's often the right choice.

Re: Need a PRNG? Use a CSPRNG

#39
post #11

Earlier quoted context omitted.

It's not true that I cherry-picked a slow PRNG for my 7 GB/s number. In fact I selected the second-fastest PRNG on that page (because it's popular)! The fastest one is 8 GB/s. PCG32 is 3 GB/s. Your 4000x factor speed up for a linear-congruential generator is just a completely false number. Yes I did pick ChaCha20 for its speed -- it's designed for speed! "A few hundred FPU instructions" in your Monte Carlo is not com…

The state of the art in super-fast PRNGs is about 0.3 cycles per byte at the moment. I believe this is done with SIMD versions of the xoroshiro algorithms right now. 0.3 cycles per byte compared to "a few" cycles per byte is an order of magnitude difference in throughput. Here's the comparison from the maintainers of Julia: https://prng.di.unimi.it/#shootout Still, most crypto libraries are designed with extreme perf…

I haven't paid close attention recently but that doesn't seem that far off of performance available via (hardware accelerated) AES?

Looking at https://eprint.iacr.org/2018/392.pdf , it seems like:

- Intel CPUs can use AESNI to do AES at 0.64 cpb - AMD Zen cores have two AESNI cores and can achieve 0.31 cpb - Vectorized AES instructions (supposed to ship in Ice Lake five years ago, but maybe a casualty of Intel's AVX512 mishaps) were expected to bring it down to 0.16 cpb

In some sense this isn't a "fair" comparison in that it's fast because there's hardware acceleration, but that doesn't really matter, the hardware is there so it might as well be used.

Re: Need a PRNG? Use a CSPRNG

#40
post #17

An alternative to the post is to take any PRNG's output and calculate the SHA3 hash of it, then use the hash as the random number. If SHA3 is not available, use AES. In either case, all statistical weaknesses and side-channel attacks will be eliminated. The platform is far more likely to have support for either of those in the system libraries, than a bespoke CSPRNG, which would need to be packaged with your app/game…

[deleted]
Post reply on HN