1package mox
2
3import (
4 cryptorand "crypto/rand"
5 "encoding/binary"
6 mathrand2 "math/rand/v2"
7 "sync"
8)
9
10type rand struct {
11 rand *mathrand2.Rand
12 sync.Mutex
13}
14
15// NewPseudoRand returns a new PRNG seeded with random bytes from crypto/rand. Its
16// functions can be called concurrently.
17func NewPseudoRand() *rand {
18 var seed [32]byte
19 cryptorand.Read(seed[:])
20 return &rand{rand: mathrand2.New(mathrand2.NewChaCha8(seed))}
21}
22
23func (r *rand) Float64() float64 {
24 r.Lock()
25 defer r.Unlock()
26 return r.rand.Float64()
27}
28
29func (r *rand) IntN(n int) int {
30 r.Lock()
31 defer r.Unlock()
32 return r.rand.IntN(n)
33}
34
35// CryptoRandInt returns a cryptographically random number.
36func CryptoRandInt() int64 {
37 var buf [8]byte
38 cryptorand.Read(buf[:])
39 return int64(binary.LittleEndian.Uint64(buf[:]))
40}
41