ulid icon indicating copy to clipboard operation
ulid copied to clipboard

Switch defaultEntropy to math/rand/v2

Open bojanz opened this issue 1 year ago • 5 comments

defaultEntropy() uses math/rand in order to be fast by default:

	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
BenchmarkNew/WithCryptoEntropy-8      2000000        771 ns/op      20.73 MB/s   16 B/op   1 allocs/op
BenchmarkNew/WithEntropy-8            20000000      65.8 ns/op     243.01 MB/s   16 B/op   1 allocs/op

Go 1.22 introduces math/rand/v2 which uses the ChaCha8Rand generator, greatly improving security with a minimal performance cost. From today's blog post:

For example, consider generating a random UUID. Since UUIDs are not secret, using math/rand might seem fine. But if math/rand has been seeded with the current time, then running it at the same instant on different computers will produce the same value, making them not “universally unique”. This is especially likely on systems where the current time is only available with millisecond precision. Even with auto-seeding using OS-provided entropy, as introduced in Go 1.20, the Go 1 generator’s seed is only a 63-bit integer, so a program that generates a UUID at startup can only generate 2⁶³ possible UUIDs and is likely to see collisions after 2³¹ or so UUIDs. Using Go 1.22, the new ChaCha8Rand generator is seeded from 256 bits of entropy and can generate 2²⁵⁶ possible first UUIDs. It does not need to worry about collisions.

Overall, ChaCha8Rand is slower than the Go 1 generator, but it is never more than twice as slow, and on typical servers the difference is never more than 3ns. Very few programs will be bottlenecked by this difference, and many programs will enjoy the improved security.

So, requiring Go 1.22 and switching defaultEntropy to math/rand/v2 sounds like a win.

bojanz avatar May 03 '24 09:05 bojanz