From bb13469acb66e555feb6d278991ba3f4042130d8 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 18 Jan 2021 23:03:58 -0800 Subject: [PATCH] crypto: add generatePrime/checkPrime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit APIs for generating and checking pseudo-random primes Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/36997 Reviewed-By: Tobias Nießen --- doc/api/crypto.md | 115 ++++++++++ lib/crypto.js | 8 + lib/internal/crypto/random.js | 205 ++++++++++++++++++ src/async_wrap.h | 2 + src/crypto/crypto_random.cc | 167 ++++++++++++++ src/crypto/crypto_random.h | 73 +++++++ src/crypto/crypto_util.h | 2 + test/parallel/test-crypto-prime.js | 195 +++++++++++++++++ test/sequential/test-async-wrap-getasyncid.js | 2 + 9 files changed, 769 insertions(+) create mode 100644 test/parallel/test-crypto-prime.js diff --git a/doc/api/crypto.md b/doc/api/crypto.md index e43f3fa5dafc43..9462cf0ef43ecc 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1961,6 +1961,48 @@ is currently in use. Setting to true requires a FIPS build of Node.js. This property is deprecated. Please use `crypto.setFips()` and `crypto.getFips()` instead. +### `crypto.checkPrime(candidate[, options, [callback]])` + + +* `candidate` {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} + A possible prime encoded as a sequence of big endian octets of arbitrary + length. +* `options` {Object} + * `checks` {number} The number of Miller-Rabin probabilistic primality + iterations to perform. When the value is `0` (zero), a number of checks + is used that yields a false positive rate of at most 2-64 for + random input. Care must be used when selecting a number of checks. Refer + to the OpenSSL documentation for the [`BN_is_prime_ex`][] function `nchecks` + options for more details. **Defaults**: `0` +* `callback` {Function} + * `err` {Error} Set to an {Error} object if an error occured during check. + * `result` {boolean} `true` if the candidate is a prime with an error + probability less than `0.25 ** options.checks`. + +Checks the primality of the `candidate`. + +### `crypto.checkPrimeSync(candidate[, options])` + + +* `candidate` {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} + A possible prime encoded as a sequence of big endian octets of arbitrary + length. +* `options` {Object} + * `checks` {number} The number of Miller-Rabin probabilistic primality + iterations to perform. When the value is `0` (zero), a number of checks + is used that yields a false positive rate of at most 2-64 for + random input. Care must be used when selecting a number of checks. Refer + to the OpenSSL documentation for the [`BN_is_prime_ex`][] function `nchecks` + options for more details. **Defaults**: `0` +* Returns: {boolean} `true` if the candidate is a prime with an error + probability less than `0.25 ** options.checks`. + +Checks the primality of the `candidate`. + ### `crypto.createCipher(algorithm, password[, options])` + +* `size` {number} The size (in bits) of the prime to generate. +* `options` {Object} + * `add` {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} + * `rem` {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} + * `safe` {boolean} **Defaults**: `false`. + * `bigint` {boolean} When `true`, the generated prime is returned + as a `bigint`. +* `callback` {Function} + * `err` {Error} + * `prime` {ArrayBuffer|bigint} + +Generates a pseudo-random prime of `size` bits. + +If `options.safe` is `true`, the prime will be a safe prime -- that is, +`(prime - 1) / 2` will also be a prime. + +If `options.add` and `options.rem` are set, the prime will satisfy the +condition that `prime % add = rem`. The `options.rem` is ignored if +`options.add` is not given. If `options.safe` is `true`, `options.add` +is given, and `options.rem` is `undefined`, then the prime generated +will satisfy the condition `prime % add = 3`. Otherwise if `options.safe` +is `false` and `options.rem` is `undefined`, `options.add` will be +ignored. + +Both `options.add` and `options.rem` must be encoded as big-endian sequences +if given as an `ArrayBuffer`, `SharedArrayBuffer`, `TypedArray`, `Buffer`, or +`DataView`. + +By default, the prime is encoded as a big-endian sequence of octets +in an {ArrayBuffer}. If the `bigint` option is `true`, then a {bigint} +is provided. + +### `crypto.generatePrimeSync(size[, options])` + + +* `size` {number} The size (in bits) of the prime to generate. +* `options` {Object} + * `add` {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} + * `rem` {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} + * `safe` {boolean} **Defaults**: `false`. + * `bigint` {boolean} When `true`, the generated prime is returned + as a `bigint`. +* Returns: {ArrayBuffer|bigint} + +Generates a pseudo-random prime of `size` bits. + +If `options.safe` is `true`, the prime will be a safe prime -- that is, +`(prime - 1)` / 2 will also be a prime. + +If `options.add` and `options.rem` are set, the prime will satisfy the +condition that `prime % add = rem`. The `options.rem` is ignored if +`options.add` is not given. If `options.safe` is `true`, `options.add` +is given, and `options.rem` is `undefined`, then the prime generated +will satisfy the condition `prime % add = 3`. Otherwise if `options.safe` +is `false` and `options.rem` is `undefined`, `options.add` will be +ignored. + +Both `options.add` and `options.rem` must be encoded as big-endian sequences +if given as an `ArrayBuffer`, `SharedArrayBuffer`, `TypedArray`, `Buffer`, or +`DataView`. + +By default, the prime is encoded as a big-endian sequence of octets +in an {ArrayBuffer}. If the `bigint` option is `true`, then a {bigint} +is provided. + ### `crypto.getCiphers()`