Skip to content

Commit 00659a9

Browse files
tniessentargos
authored andcommittedMay 1, 2021
crypto: fix randomInt bias
Co-authored-by: Andrey Pechkurov <apechkurov@gmail.com> PR-URL: #36894 Refs: #34600 Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent fa82cbc commit 00659a9

File tree

1 file changed

+9
-10
lines changed

1 file changed

+9
-10
lines changed
 

‎lib/internal/crypto/random.js

+9-10
Original file line numberDiff line numberDiff line change
@@ -176,30 +176,29 @@ function randomInt(min, max, callback) {
176176
`<= ${RAND_MAX}`, range);
177177
}
178178

179-
const excess = RAND_MAX % range;
180-
const randLimit = RAND_MAX - excess;
179+
// For (x % range) to produce an unbiased value greater than or equal to 0 and
180+
// less than range, x must be drawn randomly from the set of integers greater
181+
// than or equal to 0 and less than randLimit.
182+
const randLimit = RAND_MAX - (RAND_MAX % range);
181183

182184
if (isSync) {
183185
// Sync API
184186
while (true) {
185187
const x = randomBytes(6).readUIntBE(0, 6);
186-
// If x > (maxVal - (maxVal % range)), we will get "modulo bias"
187-
if (x > randLimit) {
188-
// Try again
188+
if (x >= randLimit) {
189+
// Try again.
189190
continue;
190191
}
191-
const n = (x % range) + min;
192-
return n;
192+
return (x % range) + min;
193193
}
194194
} else {
195195
// Async API
196196
const pickAttempt = () => {
197197
randomBytes(6, (err, bytes) => {
198198
if (err) return callback(err);
199199
const x = bytes.readUIntBE(0, 6);
200-
// If x > (maxVal - (maxVal % range)), we will get "modulo bias"
201-
if (x > randLimit) {
202-
// Try again
200+
if (x >= randLimit) {
201+
// Try again.
203202
return pickAttempt();
204203
}
205204
const n = (x % range) + min;

0 commit comments

Comments
 (0)
Please sign in to comment.