Skip to content

Commit b7d8e61

Browse files
tniessenruyadorno
authored andcommitted
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 5cbf638 commit b7d8e61

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
@@ -218,30 +218,29 @@ function randomInt(min, max, callback) {
218218
`<= ${RAND_MAX}`, range);
219219
}
220220

221-
const excess = RAND_MAX % range;
222-
const randLimit = RAND_MAX - excess;
221+
// For (x % range) to produce an unbiased value greater than or equal to 0 and
222+
// less than range, x must be drawn randomly from the set of integers greater
223+
// than or equal to 0 and less than randLimit.
224+
const randLimit = RAND_MAX - (RAND_MAX % range);
223225

224226
if (isSync) {
225227
// Sync API
226228
while (true) {
227229
const x = randomBytes(6).readUIntBE(0, 6);
228-
// If x > (maxVal - (maxVal % range)), we will get "modulo bias"
229-
if (x > randLimit) {
230-
// Try again
230+
if (x >= randLimit) {
231+
// Try again.
231232
continue;
232233
}
233-
const n = (x % range) + min;
234-
return n;
234+
return (x % range) + min;
235235
}
236236
} else {
237237
// Async API
238238
const pickAttempt = () => {
239239
randomBytes(6, (err, bytes) => {
240240
if (err) return callback(err);
241241
const x = bytes.readUIntBE(0, 6);
242-
// If x > (maxVal - (maxVal % range)), we will get "modulo bias"
243-
if (x > randLimit) {
244-
// Try again
242+
if (x >= randLimit) {
243+
// Try again.
245244
return pickAttempt();
246245
}
247246
const n = (x % range) + min;

0 commit comments

Comments
 (0)