diff options
author | Tobias Nießen <tniessen@tnie.de> | 2021-01-12 17:57:59 +0300 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2021-05-01 13:24:54 +0300 |
commit | 00659a9218d5ec2fc9dc8df5d95750eaf4566638 (patch) | |
tree | 8185a48816ee59bd17ad18b2f0a3accca9ea3dd4 /lib | |
parent | fa82cbc4f7569599f68b48b023daeb1ea3089d40 (diff) |
crypto: fix randomInt bias
Co-authored-by: Andrey Pechkurov <apechkurov@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/36894
Refs: https://github.com/nodejs/node/pull/34600
Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/internal/crypto/random.js | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index 8ea9f4cee76..f89bd198ade 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -176,20 +176,20 @@ function randomInt(min, max, callback) { `<= ${RAND_MAX}`, range); } - const excess = RAND_MAX % range; - const randLimit = RAND_MAX - excess; + // For (x % range) to produce an unbiased value greater than or equal to 0 and + // less than range, x must be drawn randomly from the set of integers greater + // than or equal to 0 and less than randLimit. + const randLimit = RAND_MAX - (RAND_MAX % range); if (isSync) { // Sync API while (true) { const x = randomBytes(6).readUIntBE(0, 6); - // If x > (maxVal - (maxVal % range)), we will get "modulo bias" - if (x > randLimit) { - // Try again + if (x >= randLimit) { + // Try again. continue; } - const n = (x % range) + min; - return n; + return (x % range) + min; } } else { // Async API @@ -197,9 +197,8 @@ function randomInt(min, max, callback) { randomBytes(6, (err, bytes) => { if (err) return callback(err); const x = bytes.readUIntBE(0, 6); - // If x > (maxVal - (maxVal % range)), we will get "modulo bias" - if (x > randLimit) { - // Try again + if (x >= randLimit) { + // Try again. return pickAttempt(); } const n = (x % range) + min; |