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…
Secure Randomness in Go 1.22
11–20 of 98 posts
Re: Secure Randomness in Go 1.22
#12Even 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…
> Using Go 1.20, that mistake is a serious security problem that merits a detailed investigation to understand the damage. Where were the keys used? How were the keys exposed? Were other random outputs exposed that might allow an attacker to derive the keys? And so on. Using Go 1.22, that mistake is just a mistake.
It is not masking a mistake - you should be using a CSPRNG in security sensitive contexts, however if you screw up the collateral damage is much lower. You should be detecting this mistake with static analysis and code audits rather then observing the random number generator on prod.
Re: Secure Randomness in Go 1.22
#13Earlier quoted context omitted.
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…
The article explains this rationale very clearly: > Using Go 1.20, that mistake is a serious security problem that merits a detailed investigation to understand the damage. Where were the keys used? How were the keys exposed? Were other random outputs exposed that might allow an attacker to derive the keys? And so on. Using Go 1.22, that mistake is just a mistake. It is not masking a mistake - you should be using a C…
Whereas `crypto/rand` is very obviously "the CSPRNG function".
I understand the motivation, but if we're trying to find bad code why not go further and just require people to put //go:I AM NOT DOING CRYPTOGRAPHY at the top of files which use math/rand or something?
It's unloading the gun but not worrying that people are still pointing it around and clicking the trigger.
Re: Secure Randomness in Go 1.22
#14Earlier quoted context omitted.
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 authors already did admit that introducing two rand packages was a mistake, so they're now just correcting (most) programs automatically so that the existing packages become more secure, and raising awareness that math/rand should no longer be used. I think it's the best they can do in this situation
Re: Secure Randomness in Go 1.22
#15I'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 :)
Whats are other cases where you would need the former? I can only think of fixed seeding for things that need reproducible results (e.g tests, verifications). I think theres another little force that pushes people towards the PRNG even when they don't need seeding: CSPRNG api always includes an error you need to handle; in case the sys call fails or you run out of entropy. I'm curious how often crpyto.Rand read 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.
Re: Secure Randomness in Go 1.22
#16Re: Secure Randomness in Go 1.22
#17Earlier quoted context omitted.
Whats are other cases where you would need the former? I can only think of fixed seeding for things that need reproducible results (e.g tests, verifications). I think theres another little force that pushes people towards the PRNG even when they don't need seeding: CSPRNG api always includes an error you need to handle; in case the sys call fails or you run out of entropy. I'm curious how often crpyto.Rand read fails…
> 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.
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.
Re: Secure Randomness in Go 1.22
#18I'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 :)
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.)
Re: Secure Randomness in Go 1.22
#19> 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 developers who discovered (thanks to tooling pointing out use of deprecated functionality) they had been using it in places where crypto/rand’s Read was definitely needed, like generating key material.
I made exactly this mistake in rclone. I refactored some code which was using the Read function from crypt/rand and during the process the import got automatically changed (probably by goimports when mixing code which did use math/rand) to math/rand. So it changed from using a secure random number generator to a deterministic one rclone seeded with the time of day. I didn't notice in the diffs :-( Hence
https://www.cvedetails.com/cve/CVE-2020-28924/
So this change gets a big :+1: from me.