Live data from Hacker News

Secure Randomness in Go 1.22

go.dev

41–50 of 98 posts

Re: Secure Randomness in Go 1.22

#41
post #17

Earlier quoted context omitted.

> CSPRNG api always includes an error you need to handle; in case the sys call fails A user-side CSPRNG — which is the point of adding a ChaCha8 PRNG to math/rand — performs no syscall outside of seeding (unless it supports reseeding). > you run out of entropy. Running out of entropy has never been a thing except in the fevered minds of linux kernel developers.

> Running out of entropy has never been a thing except in the fevered minds of linux kernel developers. Linux used user input and network jitter to generate random numbers, not a pure pseudo random number generator. For a perfectly deterministic pseudo random number generator entropy is only required for seeding and even then you can avoid it if you have no problem with others reproducing the same chain of numbers.

The difference between “I don’t have enough entropy” and “I have enough entropy to last until the heat death of the universe” is only a small factor.

Attack on the RNG state or entropy is much more of a risk. The entropy required is not a function of how much randomness you need to generate but how much time the system has been running.

Re: Secure Randomness in Go 1.22

#42

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.

This is a pet theory borne of no research at all, but from my fiddling around with Go I feel like this is a necessary feature for one reason:

Go will refuse to compile if you have unused imports.

When I'd be playing around trying to get things to work, the import management thing was a lifesaver, I'd delete a line of code that was only a temporary exploration and its imports would disappear, I'd write something similar and the tool would add the imports back again. The annoyance of having to add them back constantly or always make sure there was some dummy "use" somewhere or manually comment them out and back in every time would be incredible to me.

It seems like it would be a lot better to simply warn on used imports and maybe refuse in release mode, but Go apparently thinks religious purity in one aspect is worth the price of making standard tooling remarkably lax in another?

Re: Secure Randomness in Go 1.22

#43
post #10
post #6

Even in the worst case benchmark the new strategy is only about half as slow as an insecure random number generator. However most benchmarks were much closer. Go is doing the right balance between safety and performance for the standard library (and for the apps built on top of it). Hopefully other ecosystems follow suit. If an application needs fast insecure random numbers - they should implement an app internal gen…

Except this honestly seems worse. Encouraging people to assume the "random" primitive is cryptographically secure is just encouraging bad practice. Making math/rand/v2 cryptographically secure might solve a problem, but it's now making something which doesn't look like it's promises security "okay". `math/rand` functions in general though do not have the convention of being cryptographically secure - changing them so…

I think what you're saying is that the problem which was once easily diagnosable from an incorrect import may now become much more difficult to diagnose from an incorrect interface implementation. I think that is somewhat valid in a technical sense but a lot less likely to occur in practice, because most people will use the package-level functions which are guaranteed to use the CSPRNG.

Re: Secure Randomness in Go 1.22

#44

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.

I have a distinct memory from the first Go contributor summit where I brought this up (I have no idea what we were discussing or what it was in response to) and the attitude of every other developer at the table was "yah, but we special cased this after it caused problems with crypto/rand, math/rand so goimports is fixed now and it's fine". And then it happened again with every IDE. And with other packages that haven…

The "write out your imports" ship sailed with modules. Nobody wants to write out "code.internal.corporate.domain/bureaucratic/hierarchy/of/orgs/foo" when they're looking for "foo". Even GitHub-hosted modules have fairly long names.

The tools need to get better though. I'd rather they fall back to asking me than guessing when the import is ambiguous. I also think they should only ever autoimport from the stdlib or what's directly referenced in go.mod.

Re: Secure Randomness in Go 1.22

#46

Earlier quoted context omitted.

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.

The main issue was math/rand having a `Read` utility function with the same signature as crypto/rand, compounded by packages being namespaced but the namespacing not being preserved by importing. So a call to `rand.Read()` could be cryptographic or not you'd have to check the import to be sure.

Re: Secure Randomness in Go 1.22

#47
This love like a good direction.

I’m furious at C++ for removing the easy to use random_shuffle, with no easy to use replacement.

I’ve seen several programs use C++s new random generators wrong, and end up breaking programs while removing random_shuffle.

Re: Secure Randomness in Go 1.22

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

> this would make crypto/rand basically indistinguishable from math/rand, in which case, sure, why not. :-)

It's closer to the other way around. crypto/rand was not modified in any way, its purpose is to expose the OS's randomness source, and it does that just fine.

math/rand was modified to be harder to confuse with crypto/rand (and thus used inappropriately), as well as to provide a stronger, safer randomness source by default (the default RNG source has much larger state and should be practically impossible to predict from a sample in adversarial contexts).

> I was worried about exhausting the system's entropy pool for no good reason

No good reason indeed: there's no such thing as "exhausting the system's entropy pool", it's a linux myth which even the linux kernel developers have finally abandoned.

Re: Secure Randomness in Go 1.22

#49

For those unaware, gosec (and by extension golangci-lint) will warn about uses of `math/rand` https://github.com/securego/gosec/blob/d3b2359ae29fe344f4df5...

One of my favorite things about math/rand/v2 is that I can use it at work without a nolint directive and the subsequent pr discussions.

Re: Secure Randomness in Go 1.22

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

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.
Post reply on HN