Live data from Hacker News

Secure Randomness in Go 1.22

go.dev

21–30 of 98 posts

Re: Secure Randomness in Go 1.22

#21
post #4

I've often thought about why the default implementation of many randoms around programming languages is to use LSFRs, MTs, and other fast RNGs in the 2020s. It seems to be better to err on the side of 'people dont know if they want a PRNG or a CSPRNG' and switch the default to the latter with an explicit choice for the former for people that know what they need :)

Recently I started using a new golang library that generated random IDs for different components of a complex data structure. My own use case had tens of thousands of components, and profiling revealed that a significant chunk of the time initializing the data structure was in crypto/rand's Read(), which on my Macbook was executing system calls. Patching the library to use math/rand's Read() instead increased performance significantly.

In addition to math/rand being faster, I was worried about exhausting the system's entropy pool for no good reason: in this case, the only possible reason to have the ID's be random would be to serialize and de-serialize the data structure, then add more components later; which I had no intention of doing.

Not sure exactly how the timing of the changes mentioned in this blog compare to my experience -- possibly I was using an older version of the library, and this would make crypto/rand basically indistinguishable from math/rand, in which case, sure, why not. :-)

Re: Secure Randomness in Go 1.22

#22
post #19

From the article > Go aims to help developers write code that is secure by default. When we observe a common mistake with security consequences, we look for ways to reduce the risk of that mistake or eliminate it entirely. In this case, math/rand’s global generator was far too predictable, leading to serious problems in a variety of contexts. > For example, when Go 1.20 deprecated math/rand’s Read, we heard from deve…

Would not have happened in C# which uses distinct Random (and Random.Shared) as PRNG and RandomNumberGenerator[0] as CSPRNG even when mixing namespaces.

Also has corresponding analyzer rule if you want to enforce this project-wide[1].

[0] https://learn.microsoft.com/en-us/dotnet/api/system.security...

[1] https://learn.microsoft.com/en-us/dotnet/fundamentals/code-a...

Re: Secure Randomness in Go 1.22

#23
> a lightly modified version of Daniel J. Bernstein’s ChaCha stream cipher. ChaCha is widely used in a 20-round form called ChaCha20, including in TLS and SSH. Jean-Philippe Aumasson’s paper “Too Much Crypto” argues persuasively that the 8-round form ChaCha8 is secure too (and it’s roughly 2.5X faster)

Call me paranoid but my mind immediately jumps to the question of whether this paper can be trusted or if it has been planted by a TLA to intentionally weaken crypto.

I don't know Jean-Philippe, or much about them, but they seem to be both an experienced cryptographer and someone who has founded a company that is close to many government-adjacent organisations (UNHCR, banks, payment services, defence contractors—and that's just from the home page [0]) and therefore could easily have been exposed to persuasive state actors.

Does anyone know more about the security of the 8-round form and whether we should be concerned?

[0] https://www.taurushq.com/

Re: Secure Randomness in Go 1.22

#24
post #4

I've often thought about why the default implementation of many randoms around programming languages is to use LSFRs, MTs, and other fast RNGs in the 2020s. It seems to be better to err on the side of 'people dont know if they want a PRNG or a CSPRNG' and switch the default to the latter with an explicit choice for the former for people that know what they need :)

> It seems to be better to err on the side of 'people dont know if they want a PRNG or a CSPRNG' and switch the default to the latter with an explicit choice for the former for people that know what they need :)

That’s exactly what we did in PHP 8.2 [1] with the new object-oriented randomness API: If you as the developer don’t make an explicit choice for the random engine to use, you’ll get the CSPRNG.

Now unfortunately the hard part is convincing folks to migrate to the new API - or even from the global Mt19937 instance using mt_rand() to the CSPRNG using random_int() which is already available since 7.0.

[1] https://www.php.net/releases/8.2/en.php#random_extension

Re: Secure Randomness in Go 1.22

#25
post #19

From the article > Go aims to help developers write code that is secure by default. When we observe a common mistake with security consequences, we look for ways to reduce the risk of that mistake or eliminate it entirely. In this case, math/rand’s global generator was far too predictable, leading to serious problems in a variety of contexts. > For example, when Go 1.20 deprecated math/rand’s Read, we heard from deve…

It would not be so tough to provide an API call with a name like "PredictableRand".

Re: Secure Randomness in Go 1.22

#26

> a lightly modified version of Daniel J. Bernstein’s ChaCha stream cipher. ChaCha is widely used in a 20-round form called ChaCha20, including in TLS and SSH. Jean-Philippe Aumasson’s paper “Too Much Crypto” argues persuasively that the 8-round form ChaCha8 is secure too (and it’s roughly 2.5X faster) Call me paranoid but my mind immediately jumps to the question of whether this paper can be trusted or if it has bee…

The cited paper[0] only increases my concern:

> “But what if your adversary is NSA or Mossad? Won’t they have the computing capabilities to run a 280 attack?” Such a question is irrelevant. If your problem is to protect against such adversaries, the answer is probably not cryptography.

Handwaving away better cryptographic security on the basis that they'll probably get what they want some other way does not work for me. This is likely and often true, but those other methods may be more expensive, be unusable without revealing their hand, or be politically or diplomatically sensitive.

We should not give up on our security being as resistant as possible to these agencies on such a basis.

[0] https://eprint.iacr.org/2019/1492.pdf

Re: Secure Randomness in Go 1.22

#27

> a lightly modified version of Daniel J. Bernstein’s ChaCha stream cipher. ChaCha is widely used in a 20-round form called ChaCha20, including in TLS and SSH. Jean-Philippe Aumasson’s paper “Too Much Crypto” argues persuasively that the 8-round form ChaCha8 is secure too (and it’s roughly 2.5X faster) Call me paranoid but my mind immediately jumps to the question of whether this paper can be trusted or if it has bee…

This is a fair concern.

> Does anyone know more about the security of the 8-round form and whether we should be concerned?

This is the latest cryptanalysis I could find (see Table 2 and 3 for an overview):

https://ieeexplore.ieee.org/document/10410840

We don't even have an attack against ChaCha8. While it is likely one will appear as cryptanalysis improves, it is far less likely such an attack will ever become practical.

But obviously, not everyone from within the cryptographic community would agree with JP Aumasson either. For example, DJB had this to say 1 year and 5 months before "Too Much Crypto" first appeared on the IACR ePrint archive: https://twitter.com/hashbreaker/status/1023969586696388613.

So in conclusion; somewhat inconclusive? Going by the results so far, ChaCha8 is probably fine.

Re: Secure Randomness in Go 1.22

#28
I've been using `math/rand` instead of `crypto/rand` where `crypto/rand` was absolutely needed. This resulted in static keys being used in early versions of dnscrypt-proxy2.

The reason is that I'm using the VSCode extension that automatically adds imports. In all the source files requiring secure randomness, I carefully imported `crypto/rand` manually, but I forgot to do it in one of the files. Everything compiled and worked file, and I didn't notice that in that specific file, the extension silently added a `math/rand` import.

Since then, I import `crypto/rand` as `cryptorand` to avoid the wrong `rand` to be automatically imported.

By the way, Zig also uses a ChaCha8-based random number generator, and for cryptographic operations, people can't supply their own generator; the secure one is always used. For testing, some functions accept an explicit seed. For constrained environments, the standard library also includes a smaller one based on the Ascon permutation and the Reverie construction.

Re: Secure Randomness in Go 1.22

#29
post #19

From the article > Go aims to help developers write code that is secure by default. When we observe a common mistake with security consequences, we look for ways to reduce the risk of that mistake or eliminate it entirely. In this case, math/rand’s global generator was far too predictable, leading to serious problems in a variety of contexts. > For example, when Go 1.20 deprecated math/rand’s Read, we heard from deve…

It would not be so tough to provide an API call with a name like "PredictableRand".

Or SemiRand, UnsafeRand, that kinda thing. Bit more explicit naming. I feel like a lot of Go's naming is down to legacy / what people are used to, which on the one side is good because familiarity, but on the other it opens it up to the same mistakes and confusion that has already been made in the past.
Post reply on HN