summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/internal/crypto/random.ts
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-03-28 16:26:38 +0530
committerGitHub <noreply@github.com>2023-03-28 10:56:38 +0000
commit10012c2fe312a4f7ddc5217adaa6718c91bfb819 (patch)
treea5e5124a43465e5a5fed4e32771e92356b37aa5f /ext/node/polyfills/internal/crypto/random.ts
parent67e21e71ce6a9c7d0f261219609de61f6dd0c7a3 (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.ts89
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 {