diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2023-03-28 16:26:38 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-28 10:56:38 +0000 |
commit | 10012c2fe312a4f7ddc5217adaa6718c91bfb819 (patch) | |
tree | a5e5124a43465e5a5fed4e32771e92356b37aa5f /ext/node/polyfills/internal/crypto/random.ts | |
parent | 67e21e71ce6a9c7d0f261219609de61f6dd0c7a3 (diff) |
feat(ext/node): add `crypto.checkPrime` API (#18465)
Towards #18455
This commit implements `checkPrimeSync` and `checkPrime` in node:crypto
using the Miller-Rabin primality test (fun fact: it actually is a test
for composite numbers)
It first compares the candidate against many known small primes and if
not, proceeds to run the Miller-Rabin primality test.
http://nickle.org/examples/miller-rabin.5c used as reference
implementation.
Diffstat (limited to 'ext/node/polyfills/internal/crypto/random.ts')
-rw-r--r-- | ext/node/polyfills/internal/crypto/random.ts | 89 |
1 files changed, 82 insertions, 7 deletions
diff --git a/ext/node/polyfills/internal/crypto/random.ts b/ext/node/polyfills/internal/crypto/random.ts index cd2333d8c..07d91976a 100644 --- a/ext/node/polyfills/internal/crypto/random.ts +++ b/ext/node/polyfills/internal/crypto/random.ts @@ -7,6 +7,16 @@ import randomFill, { randomFillSync, } from "ext:deno_node/internal/crypto/_randomFill.ts"; import randomInt from "ext:deno_node/internal/crypto/_randomInt.ts"; +import { + validateFunction, + validateInt32, + validateObject, +} from "ext:deno_node/internal/validators.mjs"; +import { + isAnyArrayBuffer, + isArrayBufferView, +} from "ext:deno_node/internal/util/types.ts"; +import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts"; export { default as randomBytes } from "ext:deno_node/internal/crypto/_randomBytes.ts"; export { @@ -15,6 +25,9 @@ export { } from "ext:deno_node/internal/crypto/_randomFill.ts"; export { default as randomInt } from "ext:deno_node/internal/crypto/_randomInt.ts"; +const { core } = globalThis.__bootstrap; +const { ops } = core; + export type LargeNumberLike = | ArrayBufferView | SharedArrayBuffer @@ -43,18 +56,80 @@ export function checkPrime( callback: (err: Error | null, result: boolean) => void, ): void; export function checkPrime( - _candidate: LargeNumberLike, - _options?: CheckPrimeOptions | ((err: Error | null, result: boolean) => void), - _callback?: (err: Error | null, result: boolean) => void, + candidate: LargeNumberLike, + options: CheckPrimeOptions | ((err: Error | null, result: boolean) => void) = + {}, + callback?: (err: Error | null, result: boolean) => void, ) { - notImplemented("crypto.checkPrime"); + if (typeof options === "function") { + callback = options; + options = {}; + } + + validateFunction(callback, "callback"); + validateObject(options, "options"); + + const { + checks = 0, + } = options!; + + validateInt32(checks, "options.checks", 0); + + let op = "op_node_check_prime_bytes_async"; + if (typeof candidate === "bigint") { + op = "op_node_check_prime_async"; + } else if (!isAnyArrayBuffer(candidate) && !isArrayBufferView(candidate)) { + throw new ERR_INVALID_ARG_TYPE( + "candidate", + [ + "ArrayBuffer", + "TypedArray", + "Buffer", + "DataView", + "bigint", + ], + candidate, + ); + } + + core.opAsync(op, candidate, checks).then( + (result) => { + callback?.(null, result); + }, + ).catch((err) => { + callback?.(err, false); + }); } export function checkPrimeSync( - _candidate: LargeNumberLike, - _options?: CheckPrimeOptions, + candidate: LargeNumberLike, + options: CheckPrimeOptions = {}, ): boolean { - notImplemented("crypto.checkPrimeSync"); + validateObject(options, "options"); + + const { + checks = 0, + } = options!; + + validateInt32(checks, "options.checks", 0); + + if (typeof candidate === "bigint") { + return ops.op_node_check_prime(candidate, checks); + } else if (!isAnyArrayBuffer(candidate) && !isArrayBufferView(candidate)) { + throw new ERR_INVALID_ARG_TYPE( + "candidate", + [ + "ArrayBuffer", + "TypedArray", + "Buffer", + "DataView", + "bigint", + ], + candidate, + ); + } + + return ops.op_node_check_prime_bytes(candidate, checks); } export interface GeneratePrimeOptions { |