protect-mcp 0.6.2 → 0.6.3
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/dist/cli.js +24 -2645
- package/dist/cli.mjs +6 -6
- package/dist/index.d.mts +39 -11
- package/dist/index.d.ts +39 -11
- package/dist/index.js +475 -2552
- package/dist/index.mjs +110 -63
- package/package.json +4 -3
- package/dist/chunk-D733KAPG.mjs +0 -252
- package/dist/chunk-LYKNULYU.mjs +0 -2446
- package/dist/ed25519-DZMMNNVE.mjs +0 -38
- package/dist/utils-6AYZFE5A.mjs +0 -77
package/dist/index.mjs
CHANGED
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
formatReportMarkdown,
|
|
3
|
-
generateReport
|
|
4
|
-
} from "./chunk-JQDVKZBN.mjs";
|
|
5
1
|
import {
|
|
6
2
|
formatSimulation,
|
|
7
3
|
parseLogFile,
|
|
8
4
|
simulate
|
|
9
5
|
} from "./chunk-S4ICHNSP.mjs";
|
|
10
|
-
import {
|
|
11
|
-
ProtectGateway,
|
|
12
|
-
buildDecisionContext,
|
|
13
|
-
evaluateTier,
|
|
14
|
-
listCredentialLabels,
|
|
15
|
-
meetsMinTier,
|
|
16
|
-
parseNotificationConfigFromEnv,
|
|
17
|
-
queryExternalPDP,
|
|
18
|
-
resolveCredential,
|
|
19
|
-
sendApprovalNotification,
|
|
20
|
-
validateCredentials
|
|
21
|
-
} from "./chunk-PLKRTBDR.mjs";
|
|
22
6
|
import {
|
|
23
7
|
createSandboxServer
|
|
24
8
|
} from "./chunk-J6L4XCTE.mjs";
|
|
@@ -34,6 +18,22 @@ import {
|
|
|
34
18
|
getScopeBlindBridge,
|
|
35
19
|
startHookServer
|
|
36
20
|
} from "./chunk-3YCKR72H.mjs";
|
|
21
|
+
import {
|
|
22
|
+
collectSignedReceipts,
|
|
23
|
+
createAuditBundle
|
|
24
|
+
} from "./chunk-5JXFV37Y.mjs";
|
|
25
|
+
import {
|
|
26
|
+
ProtectGateway,
|
|
27
|
+
buildDecisionContext,
|
|
28
|
+
evaluateTier,
|
|
29
|
+
listCredentialLabels,
|
|
30
|
+
meetsMinTier,
|
|
31
|
+
parseNotificationConfigFromEnv,
|
|
32
|
+
queryExternalPDP,
|
|
33
|
+
resolveCredential,
|
|
34
|
+
sendApprovalNotification,
|
|
35
|
+
validateCredentials
|
|
36
|
+
} from "./chunk-PLKRTBDR.mjs";
|
|
37
37
|
import {
|
|
38
38
|
checkRateLimit,
|
|
39
39
|
evaluateCedar,
|
|
@@ -48,38 +48,33 @@ import {
|
|
|
48
48
|
signDecision
|
|
49
49
|
} from "./chunk-UV53U6D4.mjs";
|
|
50
50
|
import {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} from "./chunk-
|
|
54
|
-
import {
|
|
55
|
-
bytesToHex,
|
|
56
|
-
hexToBytes,
|
|
57
|
-
randomBytes
|
|
58
|
-
} from "./chunk-D733KAPG.mjs";
|
|
59
|
-
import {
|
|
60
|
-
collectSignedReceipts,
|
|
61
|
-
createAuditBundle
|
|
62
|
-
} from "./chunk-5JXFV37Y.mjs";
|
|
51
|
+
formatReportMarkdown,
|
|
52
|
+
generateReport
|
|
53
|
+
} from "./chunk-JQDVKZBN.mjs";
|
|
63
54
|
import "./chunk-PQJP2ZCI.mjs";
|
|
64
55
|
|
|
65
|
-
//
|
|
66
|
-
|
|
56
|
+
// src/signing-committed.ts
|
|
57
|
+
import { ed25519 } from "@noble/curves/ed25519";
|
|
58
|
+
import { sha256 as sha2563 } from "@noble/hashes/sha256";
|
|
59
|
+
import { bytesToHex as bytesToHex3, hexToBytes as hexToBytes3, randomBytes as randomBytes2 } from "@noble/hashes/utils";
|
|
67
60
|
|
|
68
61
|
// src/commitments/merkle.ts
|
|
62
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
63
|
+
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
|
|
69
64
|
var DOMAIN_LEAF = 0;
|
|
70
65
|
var DOMAIN_INTERNAL = 1;
|
|
71
66
|
function hashLeaf(leafBytes) {
|
|
72
67
|
const buf = new Uint8Array(leafBytes.length + 1);
|
|
73
68
|
buf[0] = DOMAIN_LEAF;
|
|
74
69
|
buf.set(leafBytes, 1);
|
|
75
|
-
return
|
|
70
|
+
return sha256(buf);
|
|
76
71
|
}
|
|
77
72
|
function hashInternal(left, right) {
|
|
78
73
|
const buf = new Uint8Array(left.length + right.length + 1);
|
|
79
74
|
buf[0] = DOMAIN_INTERNAL;
|
|
80
75
|
buf.set(left, 1);
|
|
81
76
|
buf.set(right, 1 + left.length);
|
|
82
|
-
return
|
|
77
|
+
return sha256(buf);
|
|
83
78
|
}
|
|
84
79
|
function merkleRoot(leafHashes) {
|
|
85
80
|
if (leafHashes.length === 0) {
|
|
@@ -133,6 +128,9 @@ function largestPowerOfTwoLessThan(n) {
|
|
|
133
128
|
}
|
|
134
129
|
|
|
135
130
|
// src/commitments/primitives.ts
|
|
131
|
+
import { sha256 as sha2562 } from "@noble/hashes/sha256";
|
|
132
|
+
import { hmac } from "@noble/hashes/hmac";
|
|
133
|
+
import { bytesToHex as bytesToHex2, hexToBytes as hexToBytes2, randomBytes } from "@noble/hashes/utils";
|
|
136
134
|
function jcs(value) {
|
|
137
135
|
if (value === null || value === void 0) return "null";
|
|
138
136
|
if (typeof value === "boolean" || typeof value === "number")
|
|
@@ -183,7 +181,7 @@ function leavesFromFields(fields) {
|
|
|
183
181
|
|
|
184
182
|
// src/signing-committed.ts
|
|
185
183
|
function freshSalt() {
|
|
186
|
-
return
|
|
184
|
+
return randomBytes2(32);
|
|
187
185
|
}
|
|
188
186
|
function signCommittedDecision(entry, committedFieldNames, signingKey, publicKey, kid, issuer) {
|
|
189
187
|
const allFields = {
|
|
@@ -223,7 +221,7 @@ function signCommittedDecision(entry, committedFieldNames, signingKey, publicKey
|
|
|
223
221
|
const { sorted, leafBytes } = leavesFromFields(committedFields);
|
|
224
222
|
const leafHashes = leafBytes.map(hashLeaf);
|
|
225
223
|
const root = merkleRoot(leafHashes);
|
|
226
|
-
committedFieldsRoot =
|
|
224
|
+
committedFieldsRoot = bytesToHex3(root);
|
|
227
225
|
sorted.forEach((f, i) => {
|
|
228
226
|
openings[f.name] = { name: f.name, value: f.value, salt: f.salt, index: i };
|
|
229
227
|
});
|
|
@@ -240,8 +238,8 @@ function signCommittedDecision(entry, committedFieldNames, signingKey, publicKey
|
|
|
240
238
|
payload.committed_field_names = committedFields.map((f) => f.name);
|
|
241
239
|
}
|
|
242
240
|
const canonical = jcs(payload);
|
|
243
|
-
const messageHash =
|
|
244
|
-
const signatureBytes = ed25519.sign(messageHash,
|
|
241
|
+
const messageHash = sha2563(new TextEncoder().encode(canonical));
|
|
242
|
+
const signatureBytes = ed25519.sign(messageHash, hexToBytes3(signingKey));
|
|
245
243
|
const signedReceipt = {
|
|
246
244
|
...payload,
|
|
247
245
|
signature: {
|
|
@@ -254,7 +252,7 @@ function signCommittedDecision(entry, committedFieldNames, signingKey, publicKey
|
|
|
254
252
|
}
|
|
255
253
|
};
|
|
256
254
|
const signedJson = JSON.stringify(signedReceipt);
|
|
257
|
-
const receiptHash =
|
|
255
|
+
const receiptHash = bytesToHex3(sha2563(new TextEncoder().encode(jcs(signedReceipt))));
|
|
258
256
|
return {
|
|
259
257
|
signed: signedJson,
|
|
260
258
|
artifact_type: "decision_receipt_committed_v1",
|
|
@@ -789,7 +787,7 @@ function createLogAnchorField(anchor) {
|
|
|
789
787
|
}
|
|
790
788
|
|
|
791
789
|
// src/selective-disclosure.ts
|
|
792
|
-
import { createHash as createHash2, randomBytes as
|
|
790
|
+
import { createHash as createHash2, randomBytes as randomBytes3 } from "crypto";
|
|
793
791
|
function redactFields(receipt, fieldsToRedact) {
|
|
794
792
|
const redacted = JSON.parse(JSON.stringify(receipt));
|
|
795
793
|
const salts = [];
|
|
@@ -805,7 +803,7 @@ function redactFields(receipt, fieldsToRedact) {
|
|
|
805
803
|
if (i === parts.length - 1) {
|
|
806
804
|
if (key in current) {
|
|
807
805
|
const originalValue = current[key];
|
|
808
|
-
const salt =
|
|
806
|
+
const salt = randomBytes3(16).toString("hex");
|
|
809
807
|
const commitment = computeCommitment(salt, originalValue);
|
|
810
808
|
salts.push({ field: fieldPath, salt, originalValue });
|
|
811
809
|
current[key] = `sha256(salt + ${typeof originalValue === "string" ? "..." : JSON.stringify(originalValue).slice(0, 20) + "..."})`;
|
|
@@ -1022,9 +1020,13 @@ MIT
|
|
|
1022
1020
|
}
|
|
1023
1021
|
|
|
1024
1022
|
// src/webauthn-approval.ts
|
|
1025
|
-
import { createHash as createHash3, randomBytes as
|
|
1023
|
+
import { createHash as createHash3, randomBytes as randomBytes4, timingSafeEqual } from "crypto";
|
|
1024
|
+
import { p256 } from "@noble/curves/p256";
|
|
1025
|
+
import { ed25519 as ed255192 } from "@noble/curves/ed25519";
|
|
1026
|
+
import { sha256 as sha2564 } from "@noble/hashes/sha256";
|
|
1027
|
+
import { hexToBytes as hexToBytes4 } from "@noble/hashes/utils";
|
|
1026
1028
|
function createApprovalChallenge(requestId, toolName, agentId, rpId = "scopeblind.com", timeoutSeconds = 300) {
|
|
1027
|
-
const challengeBytes =
|
|
1029
|
+
const challengeBytes = randomBytes4(32);
|
|
1028
1030
|
const contextHash = createHash3("sha256").update(JSON.stringify({ requestId, toolName, agentId, timestamp: Date.now() })).digest("hex");
|
|
1029
1031
|
return {
|
|
1030
1032
|
challenge: base64urlEncode(challengeBytes),
|
|
@@ -1054,43 +1056,72 @@ function toCredentialRequestOptions(challenge, allowCredentials) {
|
|
|
1054
1056
|
}
|
|
1055
1057
|
};
|
|
1056
1058
|
}
|
|
1057
|
-
function verifyApprovalAssertion(challenge, assertion) {
|
|
1059
|
+
function verifyApprovalAssertion(challenge, assertion, credentialPublicKey, opts = {}) {
|
|
1060
|
+
const now = opts.now ?? Date.now();
|
|
1061
|
+
const fail = (reason, partial = {}) => ({
|
|
1062
|
+
valid: false,
|
|
1063
|
+
reason,
|
|
1064
|
+
credentialId: assertion.credentialId,
|
|
1065
|
+
authenticatorType: "unknown",
|
|
1066
|
+
userVerified: false,
|
|
1067
|
+
signCount: 0,
|
|
1068
|
+
contextHash: challenge.contextHash,
|
|
1069
|
+
approvedAt: new Date(now).toISOString(),
|
|
1070
|
+
...partial
|
|
1071
|
+
});
|
|
1058
1072
|
const createdAt = new Date(challenge.createdAt).getTime();
|
|
1059
|
-
|
|
1060
|
-
if (
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
contextHash: challenge.contextHash,
|
|
1068
|
-
approvedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1069
|
-
};
|
|
1073
|
+
if (now - createdAt > challenge.timeoutSeconds * 1e3) return fail("challenge_expired");
|
|
1074
|
+
if (!credentialPublicKey?.publicKeyHex) return fail("missing_credential_public_key");
|
|
1075
|
+
const clientDataBytes = base64urlDecode(assertion.clientDataJSON);
|
|
1076
|
+
let clientData;
|
|
1077
|
+
try {
|
|
1078
|
+
clientData = JSON.parse(Buffer.from(clientDataBytes).toString("utf8"));
|
|
1079
|
+
} catch {
|
|
1080
|
+
return fail("client_data_parse_error");
|
|
1070
1081
|
}
|
|
1082
|
+
if (clientData.type !== "webauthn.get") return fail("wrong_client_data_type");
|
|
1083
|
+
if (!constantTimeStrEqual(clientData.challenge ?? "", challenge.challenge)) return fail("challenge_mismatch");
|
|
1084
|
+
const allowedOrigins = opts.expectedOrigin ? Array.isArray(opts.expectedOrigin) ? opts.expectedOrigin : [opts.expectedOrigin] : [`https://${challenge.rpId}`];
|
|
1085
|
+
if (!clientData.origin || !allowedOrigins.includes(clientData.origin)) return fail("origin_mismatch");
|
|
1071
1086
|
const authData = base64urlDecode(assertion.authenticatorData);
|
|
1087
|
+
if (authData.length < 37) return fail("authenticator_data_too_short");
|
|
1088
|
+
const rpIdHash = authData.slice(0, 32);
|
|
1089
|
+
const expectedRpIdHash = sha2564(new TextEncoder().encode(challenge.rpId));
|
|
1090
|
+
if (!bytesEqual(rpIdHash, expectedRpIdHash)) return fail("rp_id_hash_mismatch");
|
|
1072
1091
|
const flags = authData[32];
|
|
1073
1092
|
const userPresent = !!(flags & 1);
|
|
1074
1093
|
const userVerified = !!(flags & 4);
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1094
|
+
if (!userPresent) return fail("user_not_present");
|
|
1095
|
+
if ((opts.requireUserVerification ?? true) && !userVerified) return fail("user_verification_required", { userVerified });
|
|
1096
|
+
const signCount = authData[33] << 24 | authData[34] << 16 | authData[35] << 8 | authData[36];
|
|
1097
|
+
if (typeof opts.prevSignCount === "number" && signCount !== 0 && signCount <= opts.prevSignCount) {
|
|
1098
|
+
return fail("sign_count_regression", { userVerified, signCount });
|
|
1099
|
+
}
|
|
1100
|
+
const signedData = concatBytes(authData, sha2564(clientDataBytes));
|
|
1101
|
+
const sigBytes = base64urlDecode(assertion.signature);
|
|
1102
|
+
let sigOk = false;
|
|
1078
1103
|
try {
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1104
|
+
if (credentialPublicKey.alg === -7) {
|
|
1105
|
+
sigOk = p256.verify(sigBytes, sha2564(signedData), hexToBytes4(credentialPublicKey.publicKeyHex), { format: "der" });
|
|
1106
|
+
} else if (credentialPublicKey.alg === -8) {
|
|
1107
|
+
sigOk = ed255192.verify(sigBytes, signedData, hexToBytes4(credentialPublicKey.publicKeyHex));
|
|
1108
|
+
} else {
|
|
1109
|
+
return fail("unsupported_algorithm", { userVerified, signCount });
|
|
1082
1110
|
}
|
|
1083
1111
|
} catch {
|
|
1112
|
+
sigOk = false;
|
|
1084
1113
|
}
|
|
1114
|
+
if (!sigOk) return fail("invalid_signature", { userVerified, signCount });
|
|
1085
1115
|
return {
|
|
1086
|
-
valid:
|
|
1087
|
-
// At minimum, user must be present
|
|
1116
|
+
valid: true,
|
|
1088
1117
|
credentialId: assertion.credentialId,
|
|
1089
|
-
|
|
1118
|
+
// Heuristic: platform authenticators (TouchID/FaceID/Hello) report UV; roaming
|
|
1119
|
+
// keys without a PIN are UP-only. Attachment is authoritative only at registration.
|
|
1120
|
+
authenticatorType: userVerified ? "platform" : "cross-platform",
|
|
1090
1121
|
userVerified,
|
|
1091
1122
|
signCount,
|
|
1092
1123
|
contextHash: challenge.contextHash,
|
|
1093
|
-
approvedAt:
|
|
1124
|
+
approvedAt: new Date(now).toISOString()
|
|
1094
1125
|
};
|
|
1095
1126
|
}
|
|
1096
1127
|
function createApprovalReceiptPayload(challenge, result) {
|
|
@@ -1116,6 +1147,22 @@ function base64urlDecode(str) {
|
|
|
1116
1147
|
const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
|
|
1117
1148
|
return new Uint8Array(Buffer.from(padded, "base64"));
|
|
1118
1149
|
}
|
|
1150
|
+
function concatBytes(a, b) {
|
|
1151
|
+
const out = new Uint8Array(a.length + b.length);
|
|
1152
|
+
out.set(a, 0);
|
|
1153
|
+
out.set(b, a.length);
|
|
1154
|
+
return out;
|
|
1155
|
+
}
|
|
1156
|
+
function bytesEqual(a, b) {
|
|
1157
|
+
if (a.length !== b.length) return false;
|
|
1158
|
+
return timingSafeEqual(Buffer.from(a), Buffer.from(b));
|
|
1159
|
+
}
|
|
1160
|
+
function constantTimeStrEqual(a, b) {
|
|
1161
|
+
const ab = Buffer.from(a, "utf8");
|
|
1162
|
+
const bb = Buffer.from(b, "utf8");
|
|
1163
|
+
if (ab.length !== bb.length) return false;
|
|
1164
|
+
return timingSafeEqual(ab, bb);
|
|
1165
|
+
}
|
|
1119
1166
|
|
|
1120
1167
|
// src/did-vc.ts
|
|
1121
1168
|
function ed25519ToDIDKey(publicKeyHex) {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "protect-mcp",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"mcpName": "com.scopeblind/protect-mcp",
|
|
5
|
-
"description": "Cedar policy + signed receipts for AI agent decisions.
|
|
5
|
+
"description": "Cedar policy + Ed25519 signed receipts for AI agent decisions. The open gate behind Legate by ScopeBlind: enforce before action, verify offline. scopeblind.com",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"module": "dist/index.mjs",
|
|
@@ -62,7 +62,8 @@
|
|
|
62
62
|
"url": "https://github.com/scopeblind/scopeblind-gateway/issues"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@
|
|
65
|
+
"@noble/curves": "^1.8.0",
|
|
66
|
+
"@noble/hashes": "^1.7.0",
|
|
66
67
|
"@veritasacta/protocol": "^0.1.0"
|
|
67
68
|
},
|
|
68
69
|
"optionalDependencies": {
|
package/dist/chunk-D733KAPG.mjs
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
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
|
-
*/
|