Skip to content

Commit

Permalink
crypto: add generatePrime/checkPrime
Browse files Browse the repository at this point in the history
APIs for generating and checking pseudo-random primes

Signed-off-by: James M Snell <[email protected]>

PR-URL: #36997
Reviewed-By: Tobias Nießen <[email protected]>
  • Loading branch information
jasnell committed Jan 26, 2021
1 parent ecb7818 commit bb13469
Show file tree
Hide file tree
Showing 9 changed files with 769 additions and 0 deletions.
115 changes: 115 additions & 0 deletions doc/api/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]])`
<!-- YAML
added: REPLACEME
-->

* `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<sup>-64</sup> 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])`
<!-- YAML
added: REPLACEME
-->

* `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<sup>-64</sup> 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])`
<!-- YAML
added: v0.1.94
Expand Down Expand Up @@ -2694,6 +2736,78 @@ The return value `{ publicKey, privateKey }` represents the generated key pair.
When PEM encoding was selected, the respective key will be a string, otherwise
it will be a buffer containing the data encoded as DER.

### `crypto.generatePrime(size[, options[, callback]])`
<!-- YAML
added: REPLACEME
-->

* `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])`
<!-- YAML
added: REPLACEME
-->

* `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()`
<!-- YAML
added: v0.9.3
Expand Down Expand Up @@ -4234,6 +4348,7 @@ See the [list of SSL OP Flags][] for details.
[RFC 4122]: https://www.rfc-editor.org/rfc/rfc4122.txt
[RFC 5208]: https://www.rfc-editor.org/rfc/rfc5208.txt
[Web Crypto API documentation]: webcrypto.md
[`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.1/man3/BN_is_prime_ex.html
[`Buffer`]: buffer.md
[`EVP_BytesToKey`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_BytesToKey.html
[`KeyObject`]: #crypto_class_keyobject
Expand Down
8 changes: 8 additions & 0 deletions lib/crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ const {
timingSafeEqual,
} = internalBinding('crypto');
const {
checkPrime,
checkPrimeSync,
generatePrime,
generatePrimeSync,
randomBytes,
randomFill,
randomFillSync,
Expand Down Expand Up @@ -170,6 +174,8 @@ function createVerify(algorithm, options) {

module.exports = {
// Methods
checkPrime,
checkPrimeSync,
createCipheriv,
createDecipheriv,
createDiffieHellman,
Expand All @@ -183,6 +189,8 @@ module.exports = {
createSign,
createVerify,
diffieHellman,
generatePrime,
generatePrimeSync,
getCiphers,
getCipherInfo,
getCurves,
Expand Down
Loading

0 comments on commit bb13469

Please sign in to comment.