protect-mcp 0.6.3 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/README.md +135 -414
- package/SECURITY.md +48 -0
- package/dist/{chunk-UV53U6D4.mjs → chunk-546U3A7R.mjs} +79 -47
- package/dist/chunk-D733KAPG.mjs +252 -0
- package/dist/chunk-LYKNULYU.mjs +2446 -0
- package/dist/{chunk-PLKRTBDR.mjs → chunk-OHUTUFTC.mjs} +1 -1
- package/dist/{chunk-3YCKR72H.mjs → chunk-X63ELMU4.mjs} +1 -1
- package/dist/{chunk-S4ICHNSP.mjs → chunk-ZBKJANP7.mjs} +2 -2
- package/dist/cli.js +2850 -78
- package/dist/cli.mjs +143 -18
- package/dist/ed25519-DZMMNNVE.mjs +38 -0
- package/dist/hook-server.js +50 -47
- package/dist/hook-server.mjs +2 -2
- package/dist/{http-transport-MO32ESHZ.mjs → http-transport-R5AO7X6D.mjs} +2 -2
- package/dist/index.d.mts +47 -42
- package/dist/index.d.ts +47 -42
- package/dist/index.js +2634 -523
- package/dist/index.mjs +70 -113
- package/dist/utils-6AYZFE5A.mjs +77 -0
- package/package.json +6 -5
package/SECURITY.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
This policy covers the `protect-mcp` npm package.
|
|
4
|
+
|
|
5
|
+
## Supported versions
|
|
6
|
+
|
|
7
|
+
| Version | Supported |
|
|
8
|
+
|---------|-----------|
|
|
9
|
+
| >= 0.7.0 | Yes |
|
|
10
|
+
| 0.6.x | No, upgrade |
|
|
11
|
+
| 0.5.x | No, upgrade |
|
|
12
|
+
|
|
13
|
+
## Affected versions
|
|
14
|
+
|
|
15
|
+
The 0.5.x and 0.6.x lines have a fail-open gate: the Cedar policy was not
|
|
16
|
+
evaluated correctly against the pinned engine, and the evaluator returned ALLOW
|
|
17
|
+
on evaluation error. A `forbid` rule could therefore fail to block. This is fixed
|
|
18
|
+
in 0.7.0, which fails closed (denies) on any evaluation error, missing engine, or
|
|
19
|
+
errored policy. If you are on 0.5.x or 0.6.x, upgrade to >= 0.7.0.
|
|
20
|
+
|
|
21
|
+
Advisory: [GHSA-hm46-7j72-rpv9](https://github.com/ScopeBlind/scopeblind-gateway/security/advisories/GHSA-hm46-7j72-rpv9).
|
|
22
|
+
|
|
23
|
+
## Design posture
|
|
24
|
+
|
|
25
|
+
The gate fails closed by default. On any policy error, a missing engine, or an
|
|
26
|
+
evaluation failure, the decision is DENY, never a silent ALLOW. Before arming an
|
|
27
|
+
enforcing gate, `serve --enforce` and `doctor` run a boot self-test that proves
|
|
28
|
+
the gate denies a known-forbidden vector, and refuse to start if it cannot. The
|
|
29
|
+
observe mode that allows on error is opt-in, and even then flags any call that
|
|
30
|
+
would be blocked as `would_deny: true`.
|
|
31
|
+
|
|
32
|
+
## Reporting a vulnerability
|
|
33
|
+
|
|
34
|
+
Please report security issues privately. Do not open a public issue for an
|
|
35
|
+
unpatched vulnerability.
|
|
36
|
+
|
|
37
|
+
- Email: security@scopeblind.com
|
|
38
|
+
- Or open a private advisory via [GitHub Security Advisories](https://github.com/ScopeBlind/scopeblind-gateway/security/advisories/new).
|
|
39
|
+
|
|
40
|
+
Include the affected version, a description, and (if possible) a minimal
|
|
41
|
+
reproduction. We aim to acknowledge reports within 3 business days and to ship a
|
|
42
|
+
fix or a clear remediation plan as quickly as the severity warrants.
|
|
43
|
+
|
|
44
|
+
## Disclosure and credit
|
|
45
|
+
|
|
46
|
+
We follow coordinated disclosure: we work with you on a fix and a timeline before
|
|
47
|
+
any public detail is released. Reporters who disclose responsibly are credited in
|
|
48
|
+
the advisory and the CHANGELOG unless they ask to remain anonymous.
|
|
@@ -289,14 +289,18 @@ function buildEntities(req) {
|
|
|
289
289
|
}
|
|
290
290
|
];
|
|
291
291
|
}
|
|
292
|
-
|
|
292
|
+
function onEvalError(reason, failClosed, extra) {
|
|
293
|
+
return {
|
|
294
|
+
allowed: !failClosed,
|
|
295
|
+
reason: failClosed ? reason : `${reason} (observe mode; would DENY under enforcement)`,
|
|
296
|
+
metadata: { error: true, fail_closed: failClosed, would_deny: true, ...extra || {} }
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
async function evaluateCedar(policySet, req, schema, options) {
|
|
300
|
+
const failClosed = options?.failClosed ?? true;
|
|
293
301
|
const available = await ensureCedarWasm();
|
|
294
302
|
if (!available) {
|
|
295
|
-
return {
|
|
296
|
-
allowed: true,
|
|
297
|
-
reason: "cedar_wasm_not_available",
|
|
298
|
-
metadata: { fallback: true }
|
|
299
|
-
};
|
|
303
|
+
return onEvalError("cedar_wasm_not_available", failClosed, { fallback: true });
|
|
300
304
|
}
|
|
301
305
|
try {
|
|
302
306
|
const agentId = req.agentId || req.tier;
|
|
@@ -318,7 +322,7 @@ async function evaluateCedar(policySet, req, schema) {
|
|
|
318
322
|
let result;
|
|
319
323
|
if (typeof cedarWasm.isAuthorized === "function") {
|
|
320
324
|
result = cedarWasm.isAuthorized({
|
|
321
|
-
policies: policySet.source,
|
|
325
|
+
policies: { staticPolicies: policySet.source },
|
|
322
326
|
entities,
|
|
323
327
|
principal: authRequest.principal,
|
|
324
328
|
action: authRequest.action,
|
|
@@ -336,7 +340,7 @@ async function evaluateCedar(policySet, req, schema) {
|
|
|
336
340
|
const cedarEngine = cedarWasm.default || cedarWasm;
|
|
337
341
|
if (typeof cedarEngine.isAuthorized === "function") {
|
|
338
342
|
result = cedarEngine.isAuthorized({
|
|
339
|
-
policies: policySet.source,
|
|
343
|
+
policies: { staticPolicies: policySet.source },
|
|
340
344
|
entities,
|
|
341
345
|
principal: authRequest.principal,
|
|
342
346
|
action: authRequest.action,
|
|
@@ -345,61 +349,87 @@ async function evaluateCedar(policySet, req, schema) {
|
|
|
345
349
|
schema: cedarSchema
|
|
346
350
|
});
|
|
347
351
|
} else {
|
|
348
|
-
return {
|
|
349
|
-
allowed: true,
|
|
350
|
-
reason: "cedar_wasm_api_unsupported",
|
|
351
|
-
metadata: { fallback: true, exports: Object.keys(cedarWasm) }
|
|
352
|
-
};
|
|
352
|
+
return onEvalError("cedar_wasm_api_unsupported", failClosed, { exports: Object.keys(cedarWasm) });
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
|
-
const
|
|
355
|
+
const parsed = parseWasmResult(result);
|
|
356
|
+
const policyErrors = extractPolicyErrors(result);
|
|
357
|
+
if (parsed.kind === "error") {
|
|
358
|
+
return onEvalError(`cedar_unparseable_result: ${parsed.diagnostics}`, failClosed);
|
|
359
|
+
}
|
|
360
|
+
if (policyErrors.length > 0) {
|
|
361
|
+
return onEvalError(
|
|
362
|
+
`cedar_policy_errored: ${policyErrors.length} policy error(s); decision is unsound`,
|
|
363
|
+
failClosed,
|
|
364
|
+
{ policy_errors: policyErrors.slice(0, 5), policy_digest: policySet.digest }
|
|
365
|
+
);
|
|
366
|
+
}
|
|
356
367
|
return {
|
|
357
|
-
allowed:
|
|
358
|
-
reason:
|
|
368
|
+
allowed: parsed.kind === "allow",
|
|
369
|
+
reason: parsed.kind === "allow" ? void 0 : `cedar_deny${parsed.diagnostics ? ": " + parsed.diagnostics : ""}`,
|
|
359
370
|
metadata: {
|
|
360
371
|
policy_digest: policySet.digest,
|
|
361
|
-
...
|
|
372
|
+
...parsed.matchedPolicies ? { matched_policies: parsed.matchedPolicies } : {}
|
|
362
373
|
}
|
|
363
374
|
};
|
|
364
375
|
} catch (err) {
|
|
365
|
-
return {
|
|
366
|
-
allowed: true,
|
|
367
|
-
reason: `cedar_eval_error: ${err instanceof Error ? err.message : "unknown"}`,
|
|
368
|
-
metadata: { fallback: true, error: true }
|
|
369
|
-
};
|
|
376
|
+
return onEvalError(`cedar_eval_error: ${err instanceof Error ? err.message : "unknown"}`, failClosed);
|
|
370
377
|
}
|
|
371
378
|
}
|
|
372
379
|
function parseWasmResult(result) {
|
|
373
|
-
if (!result) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
return {
|
|
381
|
-
|
|
382
|
-
diagnostics: result.diagnostics ? JSON.stringify(result.diagnostics) : void 0,
|
|
383
|
-
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
if (result.decision === "Allow") {
|
|
387
|
-
return { allowed: true };
|
|
388
|
-
}
|
|
389
|
-
if (result.decision === "Deny") {
|
|
390
|
-
return {
|
|
391
|
-
allowed: false,
|
|
392
|
-
diagnostics: result.diagnostics ? JSON.stringify(result.diagnostics) : void 0
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
if (typeof result === "boolean") {
|
|
396
|
-
return { allowed: result };
|
|
380
|
+
if (!result) return { kind: "error", diagnostics: "null result from Cedar WASM" };
|
|
381
|
+
if (result.type === "failure") {
|
|
382
|
+
return { kind: "error", diagnostics: `cedar failure: ${JSON.stringify(result.errors ?? [])}` };
|
|
383
|
+
}
|
|
384
|
+
if (result.type === "success" && result.response) {
|
|
385
|
+
const dec = result.response.decision;
|
|
386
|
+
const reasons = result.response.diagnostics?.reason;
|
|
387
|
+
if (dec === "allow" || dec === "Allow") return { kind: "allow", matchedPolicies: reasons };
|
|
388
|
+
if (dec === "deny" || dec === "Deny") {
|
|
389
|
+
return { kind: "deny", diagnostics: result.response.diagnostics ? JSON.stringify(result.response.diagnostics) : void 0, matchedPolicies: reasons };
|
|
390
|
+
}
|
|
397
391
|
}
|
|
398
|
-
|
|
392
|
+
if (result.type === "allow" || result.decision === "Allow") return { kind: "allow" };
|
|
393
|
+
if (result.type === "deny" || result.decision === "Deny") return { kind: "deny" };
|
|
394
|
+
if (typeof result === "boolean") return result ? { kind: "allow" } : { kind: "deny" };
|
|
395
|
+
return { kind: "error", diagnostics: `unknown result format: ${JSON.stringify(result)}` };
|
|
396
|
+
}
|
|
397
|
+
function extractPolicyErrors(result) {
|
|
398
|
+
if (!result || typeof result !== "object") return [];
|
|
399
|
+
const raw = result.errors ?? result.response?.diagnostics?.errors ?? result.diagnostics?.errors ?? [];
|
|
400
|
+
if (!Array.isArray(raw)) return [];
|
|
401
|
+
return raw.map((e) => typeof e === "string" ? e : e?.message ?? e?.error ?? JSON.stringify(e)).filter(Boolean);
|
|
399
402
|
}
|
|
400
403
|
async function isCedarAvailable() {
|
|
401
404
|
return ensureCedarWasm();
|
|
402
405
|
}
|
|
406
|
+
function policySetFromSource(source, name = "inline") {
|
|
407
|
+
const digest = createHash2("sha256").update(source).digest("hex").slice(0, 16);
|
|
408
|
+
return { source, digest, fileCount: 1, files: [name] };
|
|
409
|
+
}
|
|
410
|
+
async function runEvaluatorSelfTest() {
|
|
411
|
+
const wasmAvailable = await isCedarAvailable();
|
|
412
|
+
const cases = [];
|
|
413
|
+
const run = async (name, expected, policy, context) => {
|
|
414
|
+
const d = await evaluateCedar(policy, { tool: "Bash", tier: "unknown", context }, void 0, { failClosed: true });
|
|
415
|
+
const actual = d.allowed ? "ALLOW" : "DENY";
|
|
416
|
+
cases.push({ name, expected, actual, pass: actual === expected, reason: d.reason });
|
|
417
|
+
};
|
|
418
|
+
if (!wasmAvailable) {
|
|
419
|
+
await run("engine unavailable denies", "DENY", policySetFromSource("permit(principal, action, resource);"), {});
|
|
420
|
+
return { wasmAvailable, passed: cases.every((c) => c.pass), cases };
|
|
421
|
+
}
|
|
422
|
+
const correct = policySetFromSource(
|
|
423
|
+
'forbid(principal, action, resource) when { ["rm", "dd", "mkfs"].contains(context.command) };\npermit(principal, action, resource);'
|
|
424
|
+
);
|
|
425
|
+
await run("forbid denies rm", "DENY", correct, { command: "rm" });
|
|
426
|
+
await run("permit allows ls", "ALLOW", correct, { command: "ls" });
|
|
427
|
+
const broken = policySetFromSource(
|
|
428
|
+
'forbid(principal, action, resource) when { context.command in ["rm", "dd"] };\npermit(principal, action, resource);'
|
|
429
|
+
);
|
|
430
|
+
await run("in-on-String forbid does not permit-all", "DENY", broken, { command: "rm" });
|
|
431
|
+
return { wasmAvailable, passed: cases.every((c) => c.pass), cases };
|
|
432
|
+
}
|
|
403
433
|
|
|
404
434
|
// src/http-server.ts
|
|
405
435
|
import { createServer } from "http";
|
|
@@ -638,6 +668,8 @@ export {
|
|
|
638
668
|
loadCedarPolicies,
|
|
639
669
|
evaluateCedar,
|
|
640
670
|
isCedarAvailable,
|
|
671
|
+
policySetFromSource,
|
|
672
|
+
runEvaluatorSelfTest,
|
|
641
673
|
ReceiptBuffer,
|
|
642
674
|
startStatusServer
|
|
643
675
|
};
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// node_modules/@noble/hashes/esm/cryptoNode.js
|
|
2
|
+
import * as nc from "crypto";
|
|
3
|
+
var crypto = nc && typeof nc === "object" && "webcrypto" in nc ? nc.webcrypto : nc && typeof nc === "object" && "randomBytes" in nc ? nc : void 0;
|
|
4
|
+
|
|
5
|
+
// node_modules/@noble/hashes/esm/utils.js
|
|
6
|
+
function isBytes(a) {
|
|
7
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
8
|
+
}
|
|
9
|
+
function anumber(n) {
|
|
10
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
11
|
+
throw new Error("positive integer expected, got " + n);
|
|
12
|
+
}
|
|
13
|
+
function abytes(b, ...lengths) {
|
|
14
|
+
if (!isBytes(b))
|
|
15
|
+
throw new Error("Uint8Array expected");
|
|
16
|
+
if (lengths.length > 0 && !lengths.includes(b.length))
|
|
17
|
+
throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
|
|
18
|
+
}
|
|
19
|
+
function ahash(h) {
|
|
20
|
+
if (typeof h !== "function" || typeof h.create !== "function")
|
|
21
|
+
throw new Error("Hash should be wrapped by utils.createHasher");
|
|
22
|
+
anumber(h.outputLen);
|
|
23
|
+
anumber(h.blockLen);
|
|
24
|
+
}
|
|
25
|
+
function aexists(instance, checkFinished = true) {
|
|
26
|
+
if (instance.destroyed)
|
|
27
|
+
throw new Error("Hash instance has been destroyed");
|
|
28
|
+
if (checkFinished && instance.finished)
|
|
29
|
+
throw new Error("Hash#digest() has already been called");
|
|
30
|
+
}
|
|
31
|
+
function aoutput(out, instance) {
|
|
32
|
+
abytes(out);
|
|
33
|
+
const min = instance.outputLen;
|
|
34
|
+
if (out.length < min) {
|
|
35
|
+
throw new Error("digestInto() expects output buffer of length at least " + min);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function u8(arr) {
|
|
39
|
+
return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
40
|
+
}
|
|
41
|
+
function u32(arr) {
|
|
42
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
43
|
+
}
|
|
44
|
+
function clean(...arrays) {
|
|
45
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
46
|
+
arrays[i].fill(0);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function createView(arr) {
|
|
50
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
51
|
+
}
|
|
52
|
+
function rotr(word, shift) {
|
|
53
|
+
return word << 32 - shift | word >>> shift;
|
|
54
|
+
}
|
|
55
|
+
function rotl(word, shift) {
|
|
56
|
+
return word << shift | word >>> 32 - shift >>> 0;
|
|
57
|
+
}
|
|
58
|
+
var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
|
|
59
|
+
function byteSwap(word) {
|
|
60
|
+
return word << 24 & 4278190080 | word << 8 & 16711680 | word >>> 8 & 65280 | word >>> 24 & 255;
|
|
61
|
+
}
|
|
62
|
+
var swap8IfBE = isLE ? (n) => n : (n) => byteSwap(n);
|
|
63
|
+
var byteSwapIfBE = swap8IfBE;
|
|
64
|
+
function byteSwap32(arr) {
|
|
65
|
+
for (let i = 0; i < arr.length; i++) {
|
|
66
|
+
arr[i] = byteSwap(arr[i]);
|
|
67
|
+
}
|
|
68
|
+
return arr;
|
|
69
|
+
}
|
|
70
|
+
var swap32IfBE = isLE ? (u) => u : byteSwap32;
|
|
71
|
+
var hasHexBuiltin = /* @__PURE__ */ (() => (
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function"
|
|
74
|
+
))();
|
|
75
|
+
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
76
|
+
function bytesToHex(bytes) {
|
|
77
|
+
abytes(bytes);
|
|
78
|
+
if (hasHexBuiltin)
|
|
79
|
+
return bytes.toHex();
|
|
80
|
+
let hex = "";
|
|
81
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
82
|
+
hex += hexes[bytes[i]];
|
|
83
|
+
}
|
|
84
|
+
return hex;
|
|
85
|
+
}
|
|
86
|
+
var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
87
|
+
function asciiToBase16(ch) {
|
|
88
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
|
89
|
+
return ch - asciis._0;
|
|
90
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
|
91
|
+
return ch - (asciis.A - 10);
|
|
92
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
|
93
|
+
return ch - (asciis.a - 10);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
function hexToBytes(hex) {
|
|
97
|
+
if (typeof hex !== "string")
|
|
98
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
99
|
+
if (hasHexBuiltin)
|
|
100
|
+
return Uint8Array.fromHex(hex);
|
|
101
|
+
const hl = hex.length;
|
|
102
|
+
const al = hl / 2;
|
|
103
|
+
if (hl % 2)
|
|
104
|
+
throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
105
|
+
const array = new Uint8Array(al);
|
|
106
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
107
|
+
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
108
|
+
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
109
|
+
if (n1 === void 0 || n2 === void 0) {
|
|
110
|
+
const char = hex[hi] + hex[hi + 1];
|
|
111
|
+
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
112
|
+
}
|
|
113
|
+
array[ai] = n1 * 16 + n2;
|
|
114
|
+
}
|
|
115
|
+
return array;
|
|
116
|
+
}
|
|
117
|
+
var nextTick = async () => {
|
|
118
|
+
};
|
|
119
|
+
async function asyncLoop(iters, tick, cb) {
|
|
120
|
+
let ts = Date.now();
|
|
121
|
+
for (let i = 0; i < iters; i++) {
|
|
122
|
+
cb(i);
|
|
123
|
+
const diff = Date.now() - ts;
|
|
124
|
+
if (diff >= 0 && diff < tick)
|
|
125
|
+
continue;
|
|
126
|
+
await nextTick();
|
|
127
|
+
ts += diff;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function utf8ToBytes(str) {
|
|
131
|
+
if (typeof str !== "string")
|
|
132
|
+
throw new Error("string expected");
|
|
133
|
+
return new Uint8Array(new TextEncoder().encode(str));
|
|
134
|
+
}
|
|
135
|
+
function bytesToUtf8(bytes) {
|
|
136
|
+
return new TextDecoder().decode(bytes);
|
|
137
|
+
}
|
|
138
|
+
function toBytes(data) {
|
|
139
|
+
if (typeof data === "string")
|
|
140
|
+
data = utf8ToBytes(data);
|
|
141
|
+
abytes(data);
|
|
142
|
+
return data;
|
|
143
|
+
}
|
|
144
|
+
function kdfInputToBytes(data) {
|
|
145
|
+
if (typeof data === "string")
|
|
146
|
+
data = utf8ToBytes(data);
|
|
147
|
+
abytes(data);
|
|
148
|
+
return data;
|
|
149
|
+
}
|
|
150
|
+
function concatBytes(...arrays) {
|
|
151
|
+
let sum = 0;
|
|
152
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
153
|
+
const a = arrays[i];
|
|
154
|
+
abytes(a);
|
|
155
|
+
sum += a.length;
|
|
156
|
+
}
|
|
157
|
+
const res = new Uint8Array(sum);
|
|
158
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
159
|
+
const a = arrays[i];
|
|
160
|
+
res.set(a, pad);
|
|
161
|
+
pad += a.length;
|
|
162
|
+
}
|
|
163
|
+
return res;
|
|
164
|
+
}
|
|
165
|
+
function checkOpts(defaults, opts) {
|
|
166
|
+
if (opts !== void 0 && {}.toString.call(opts) !== "[object Object]")
|
|
167
|
+
throw new Error("options should be object or undefined");
|
|
168
|
+
const merged = Object.assign(defaults, opts);
|
|
169
|
+
return merged;
|
|
170
|
+
}
|
|
171
|
+
var Hash = class {
|
|
172
|
+
};
|
|
173
|
+
function createHasher(hashCons) {
|
|
174
|
+
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
|
|
175
|
+
const tmp = hashCons();
|
|
176
|
+
hashC.outputLen = tmp.outputLen;
|
|
177
|
+
hashC.blockLen = tmp.blockLen;
|
|
178
|
+
hashC.create = () => hashCons();
|
|
179
|
+
return hashC;
|
|
180
|
+
}
|
|
181
|
+
function createOptHasher(hashCons) {
|
|
182
|
+
const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
|
|
183
|
+
const tmp = hashCons({});
|
|
184
|
+
hashC.outputLen = tmp.outputLen;
|
|
185
|
+
hashC.blockLen = tmp.blockLen;
|
|
186
|
+
hashC.create = (opts) => hashCons(opts);
|
|
187
|
+
return hashC;
|
|
188
|
+
}
|
|
189
|
+
function createXOFer(hashCons) {
|
|
190
|
+
const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
|
|
191
|
+
const tmp = hashCons({});
|
|
192
|
+
hashC.outputLen = tmp.outputLen;
|
|
193
|
+
hashC.blockLen = tmp.blockLen;
|
|
194
|
+
hashC.create = (opts) => hashCons(opts);
|
|
195
|
+
return hashC;
|
|
196
|
+
}
|
|
197
|
+
var wrapConstructor = createHasher;
|
|
198
|
+
var wrapConstructorWithOpts = createOptHasher;
|
|
199
|
+
var wrapXOFConstructorWithOpts = createXOFer;
|
|
200
|
+
function randomBytes(bytesLength = 32) {
|
|
201
|
+
if (crypto && typeof crypto.getRandomValues === "function") {
|
|
202
|
+
return crypto.getRandomValues(new Uint8Array(bytesLength));
|
|
203
|
+
}
|
|
204
|
+
if (crypto && typeof crypto.randomBytes === "function") {
|
|
205
|
+
return Uint8Array.from(crypto.randomBytes(bytesLength));
|
|
206
|
+
}
|
|
207
|
+
throw new Error("crypto.getRandomValues must be defined");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export {
|
|
211
|
+
isBytes,
|
|
212
|
+
anumber,
|
|
213
|
+
abytes,
|
|
214
|
+
ahash,
|
|
215
|
+
aexists,
|
|
216
|
+
aoutput,
|
|
217
|
+
u8,
|
|
218
|
+
u32,
|
|
219
|
+
clean,
|
|
220
|
+
createView,
|
|
221
|
+
rotr,
|
|
222
|
+
rotl,
|
|
223
|
+
isLE,
|
|
224
|
+
byteSwap,
|
|
225
|
+
swap8IfBE,
|
|
226
|
+
byteSwapIfBE,
|
|
227
|
+
byteSwap32,
|
|
228
|
+
swap32IfBE,
|
|
229
|
+
bytesToHex,
|
|
230
|
+
hexToBytes,
|
|
231
|
+
nextTick,
|
|
232
|
+
asyncLoop,
|
|
233
|
+
utf8ToBytes,
|
|
234
|
+
bytesToUtf8,
|
|
235
|
+
toBytes,
|
|
236
|
+
kdfInputToBytes,
|
|
237
|
+
concatBytes,
|
|
238
|
+
checkOpts,
|
|
239
|
+
Hash,
|
|
240
|
+
createHasher,
|
|
241
|
+
createOptHasher,
|
|
242
|
+
createXOFer,
|
|
243
|
+
wrapConstructor,
|
|
244
|
+
wrapConstructorWithOpts,
|
|
245
|
+
wrapXOFConstructorWithOpts,
|
|
246
|
+
randomBytes
|
|
247
|
+
};
|
|
248
|
+
/*! Bundled license information:
|
|
249
|
+
|
|
250
|
+
@noble/hashes/esm/utils.js:
|
|
251
|
+
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
252
|
+
*/
|