@@ -283,6 +283,15 @@ func (p *PRNG) Range(min, max int) int {
return n
}
+// RangeUint32 selects an unsigned 32-bit random integer in [min, max].
+// If max < min, min is returned.
+func (p *PRNG) RangeUint32(min, max uint32) uint32 {
+ if max < min {
+ return min
+ }
+ return min + uint32(p.rand.Int63n(int64(max-min)+1))
+}
+
// Bytes returns a new slice containing length random bytes.
func (p *PRNG) Bytes(length int) []byte {
b := make([]byte, length)
@@ -376,6 +385,10 @@ func Range(min, max int) int {
return p.Range(min, max)
+func RangeUint32(min, max uint32) uint32 {
+ return p.RangeUint32(min, max)
func Bytes(length int) []byte {
return p.Bytes(length)
@@ -196,6 +196,40 @@ func TestRange(t *testing.T) {
+func TestUint32Range(t *testing.T) {
+ p, err := NewPRNG()
+ if err != nil {
+ t.Fatalf("NewPRNG failed: %s", err)
+ var min uint32 = math.MaxUint32 - 19
+ var max uint32 = math.MaxUint32
+ var gotMin, gotMax bool
+ for n := 0; n < 1000; n++ {
+ i := p.RangeUint32(min, max)
+ if i < min || i > max {
+ t.Error("out of range")
+ if i == min {
+ gotMin = true
+ if i == max {
+ gotMax = true
+ if !gotMin {
+ t.Error("missing min")
+ if !gotMax {
+ t.Error("missing max")
func TestPeriod(t *testing.T) {
p, err := NewPRNG()
@@ -868,7 +868,8 @@ func getUTLSClientHelloID(
// Generates typical PSK extension values.
labelLengths := []int{192, 208, 224, 226, 235, 240, 273, 421, 429, 441}
label := prng.Bytes(labelLengths[prng.Intn(len(labelLengths))])
- obfuscatedTicketAge := uint32(prng.Range(13029567, math.MaxUint32))
+ obfuscatedTicketAge := prng.RangeUint32(13029567, math.MaxUint32)
binder := prng.Bytes(33)
binder[0] = 0x20 // Binder's length