Live data from Hacker News

Secure Randomness in Go 1.22

go.dev

51–60 of 98 posts

Re: Secure Randomness in Go 1.22

#51
post #39
post #7

Earlier quoted context omitted.

One of the better arguments for using a CSPRNG (here, ChaCha8) is that they benchmark it within a factor of 2 of PCG. The state is still comparatively large (64 bytes vs 16), but not nearly as bad as something like mt19937 or the old Go PRNG. (If the CSPRNG was much much slower, which is generally true for CSPRNGs other than the reduced-round ChaCha variant, it becomes a less appealing default.)

How did you get to 64 bytes of state? Last I looked, Go's ChaCha8 implementation had 300 bytes of state. Most of that was spent on a buffer which was necessary for optimal amortized performance.

That's correct - the state is 300 bytes (36 uint64 + 3 uint32). https://go.dev/src/internal/chacha8rand/chacha8.go

Re: Secure Randomness in Go 1.22

#52
post #50

Earlier quoted context omitted.

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...

If I had to guess which of Random and RandomNumberGenerator was the cryptographically secure one, I would have guessed wrong. It's not clear either way.

Maybe so, but once you know you won’t need to scroll to the top of the file to know which one you are using.

Re: Secure Randomness in Go 1.22

#53

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 an…

I'm not sure what happened in your case, but it probably wasn't what you describe. We changed goimports in 2016 to prefer crypto/rand over math/rand (https://go-review.googlesource.com/24847), and that was before there was VSCode support for Go.

Re: Secure Randomness in Go 1.22

#54

Earlier quoted context omitted.

Someone else mentioned this same thing. Tbh the practice of automatically adding imports seems totally crazy and defeats the whole point of segregating names into different namespaces.

It's convenient, and probably fine when imports are unambiguous. The problem here is that there were multiple possible imports for the same name, and in such situation, the extension picks an arbitrary one. It feels rather like a bug (or a design issue) in the extension, that can be fixed, than a conceptual issue in automatic imports.

It doesn't pick an arbitrary one. It prefers crypto/rand, and has since 2016 (https://go-review.googlesource.com/24847).

Re: Secure Randomness in Go 1.22

#55

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 an…

Someone else mentioned this same thing. Tbh the practice of automatically adding imports seems totally crazy and defeats the whole point of segregating names into different namespaces.

In general there is very little overlap. crypto/rand vs math/rand don't even overlap except for rand.Read, and that was a mistake. We also corrected the import fixer in 2016 to prefer crypto/rand, so no one should have run into this problem in a very long time. https://go-review.googlesource.com/24847

Re: Secure Randomness in Go 1.22

#56
post #20

Russell Cox consistently produces excellent technical blogs and proposals (and work). If you want to improve the clarity of your writing and thinking, he is a great place to start.

His series on FSAs and regular expressions made me fall in love with all of that. I wasn't aware of who Russ Cox was at the time too, but that series of articles was just incredible. That's probably the highest quality content freely available about implementation of REs. Runner ups being various compiler focused books, but those aren't freely available and easily searchable via the web.

Re: Secure Randomness in Go 1.22

#57
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…

Ouch, apologies for that. We changed goimports to prefer crypto/rand back in 2016, so I'm not entirely sure what happened during your refactoring. Perhaps code that used other math/rand-only APIs ended up in the same file. https://go-review.googlesource.com/24847

Anyway, I'm glad we're cleaning all this up!

Re: Secure Randomness in Go 1.22

#58
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…

goimports has special-cased math/rand.Read vs crypto/rand.Read from basically the beginning. But https://github.com/golang/tools/commit/0835c735343e0d8e375f0... in 2016 references a time window where it could resolve "rand.Read" as "math/rand". Maybe you were in that time window?

Re: Secure Randomness in Go 1.22

#59
post #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 perform…

Others have already addressed the impossibility of exhausting the system entropy pool, however, I would add that you can buffer Read() to amortize the cost of the syscall.

Also, make sure that your patch does not introduce a secure vulnerability as math/rand output is not suitable for anything security related.

Re: Secure Randomness in Go 1.22

#60

> 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…

> Call me paranoid

You're being too paranoid. If you have a substantive disagreement with the content of the "Too Much Crypto" paper then we can talk about it, but to posit that Aumasson was compromised by a TLA(with no evidence) and that this paper is the result is pure conspiracy thinking.

Aumasson designed BLAKE[0], as well SipHash[1] and SPHINCS+[2](both of which he designed with DJB, btw).

[0]: https://www.blake2.net/#co [1]: https://en.wikipedia.org/wiki/SipHash [2]: https://sphincs.org/

Post reply on HN