Unbiased Modulo Reduction
Unbiased Modulo Reduction
A common mistake in cryptographic code is mapping a random 64-bit value to [0, n) by x % n. This is biased unless 2^64 is divisible by n.
To avoid bias, use rejection sampling:
- Let
limit = maxUint64 - (maxUint64 % n). - Draw a random
r. - If
r < limit, returnr % n. - Otherwise, reject and retry.
Function signature
type RNG interface {
Next() uint64
}
func UniformMod(n uint64, rng RNG) uint64
Constraints
n >= 1rng.Next()returns a uniformuint64.
Notes
- You must reject values
r >= limitto remove bias. - This is a building block for safe key/nonce generation.
Run tests to see results
No issues detected