@optimystic/quereus-plugin-crypto 0.13.5 → 0.16.2

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/index.js CHANGED
@@ -1,11 +1,17 @@
1
1
  import { sha512, sha256 } from '@noble/hashes/sha2.js';
2
2
  import { blake3 } from '@noble/hashes/blake3.js';
3
- import { randomBytes as randomBytes$1, concatBytes, utf8ToBytes } from '@noble/hashes/utils.js';
3
+ import { concatBytes, randomBytes as randomBytes$1, utf8ToBytes } from '@noble/hashes/utils.js';
4
4
  import { secp256k1 } from '@noble/curves/secp256k1.js';
5
5
  import { p256 } from '@noble/curves/nist.js';
6
6
  import { ed25519 } from '@noble/curves/ed25519.js';
7
- import { hexToBytes, bytesToHex } from '@noble/curves/utils.js';
8
- import { fromString, toString } from 'uint8arrays';
7
+ import { bytesToHex, hexToBytes } from '@noble/curves/utils.js';
8
+ import { toString, fromString } from 'uint8arrays';
9
+ import { CID } from 'multiformats/cid';
10
+ import * as Digest from 'multiformats/hashes/digest';
11
+ import { base32 } from 'multiformats/bases/base32';
12
+ import { base58btc } from 'multiformats/bases/base58';
13
+ import { base64url } from 'multiformats/bases/base64';
14
+ import { base16 } from 'multiformats/bases/base16';
9
15
 
10
16
  // src/crypto.ts
11
17
  function toBytes(input, encoding = "base64url") {
@@ -47,29 +53,141 @@ function fromBytes(bytes, encoding = "base64url") {
47
53
  return toString(bytes, "base64url");
48
54
  }
49
55
  }
50
- function digest(data, algorithm = "sha256", inputEncoding = "base64url", outputEncoding = "base64url") {
51
- const bytes = toBytes(data, inputEncoding);
52
- let hashBytes;
53
- switch (algorithm) {
54
- case "sha256":
55
- hashBytes = sha256(bytes);
56
- break;
57
- case "sha512":
58
- hashBytes = sha512(bytes);
59
- break;
60
- case "blake3":
61
- hashBytes = blake3(bytes);
62
- break;
56
+ var HASHERS = {
57
+ sha256,
58
+ sha512,
59
+ blake3
60
+ };
61
+ var OUTPUT_ENCODERS = {
62
+ base64url: (bytes) => toString(bytes, "base64url"),
63
+ base64: (bytes) => toString(bytes, "base64"),
64
+ hex: (bytes) => bytesToHex(bytes),
65
+ bytes: (bytes) => bytes
66
+ };
67
+ function resolveHasher(algorithm) {
68
+ const hasher = HASHERS[algorithm];
69
+ if (!hasher) {
70
+ throw new Error(`Unsupported hash algorithm: ${algorithm}`);
71
+ }
72
+ return hasher;
73
+ }
74
+ function resolveOutputEncoder(encoding) {
75
+ const encoder = OUTPUT_ENCODERS[encoding];
76
+ if (!encoder) {
77
+ throw new Error(`Unsupported output encoding: ${encoding}`);
78
+ }
79
+ return encoder;
80
+ }
81
+ var DIGEST_FORMAT_V1 = 1;
82
+ var TAG_NULL = 0;
83
+ var TAG_INT = 1;
84
+ var TAG_REAL = 2;
85
+ var TAG_TEXT = 3;
86
+ var TAG_BOOL = 4;
87
+ var TAG_BLOB = 5;
88
+ var TAG_JSON = 6;
89
+ function writeVarint(out, value) {
90
+ if (!Number.isInteger(value) || value < 0) {
91
+ throw new Error(`varint expects a non-negative integer, got ${value}`);
92
+ }
93
+ let v = value;
94
+ while (v >= 128) {
95
+ out.push(v & 127 | 128);
96
+ v = Math.floor(v / 128);
97
+ }
98
+ out.push(v);
99
+ }
100
+ function framed(tag, payload) {
101
+ const header = [tag];
102
+ writeVarint(header, payload.length);
103
+ return concatBytes(Uint8Array.from(header), payload);
104
+ }
105
+ function canonicalJson(value) {
106
+ if (value === null) return "null";
107
+ const t = typeof value;
108
+ if (t === "string") return JSON.stringify(value);
109
+ if (t === "boolean") return value ? "true" : "false";
110
+ if (t === "number") {
111
+ if (!Number.isFinite(value)) {
112
+ throw new Error("digest: cannot encode a non-finite number inside a JSON field");
113
+ }
114
+ return JSON.stringify(value);
115
+ }
116
+ if (t === "bigint") {
117
+ throw new Error("digest: bigint is not representable inside a JSON field");
118
+ }
119
+ if (Array.isArray(value)) {
120
+ return `[${value.map((el) => {
121
+ if (el === void 0) {
122
+ throw new Error("digest: undefined / sparse element inside a JSON field");
123
+ }
124
+ return canonicalJson(el);
125
+ }).join(",")}]`;
126
+ }
127
+ if (t === "object") {
128
+ const proto = Object.getPrototypeOf(value);
129
+ if (proto !== Object.prototype && proto !== null) {
130
+ throw new Error("digest: only plain objects are allowed inside a JSON field");
131
+ }
132
+ const obj = value;
133
+ const keys = Object.keys(obj).sort();
134
+ return `{${keys.map((k) => {
135
+ if (obj[k] === void 0) {
136
+ throw new Error(`digest: undefined value for JSON key '${k}'`);
137
+ }
138
+ return `${JSON.stringify(k)}:${canonicalJson(obj[k])}`;
139
+ }).join(",")}}`;
140
+ }
141
+ throw new Error(`digest: unsupported value of type '${t}' inside a JSON field`);
142
+ }
143
+ function encodeField(field) {
144
+ if (field === null || field === void 0) {
145
+ return Uint8Array.of(TAG_NULL);
146
+ }
147
+ switch (typeof field) {
148
+ case "boolean":
149
+ return Uint8Array.of(TAG_BOOL, field ? 1 : 0);
150
+ case "bigint":
151
+ return framed(TAG_INT, utf8ToBytes(field.toString()));
152
+ case "number":
153
+ if (!Number.isFinite(field)) {
154
+ throw new Error("digest: cannot encode a non-finite number");
155
+ }
156
+ return Number.isInteger(field) ? framed(TAG_INT, utf8ToBytes(BigInt(field).toString())) : framed(TAG_REAL, utf8ToBytes(field.toString()));
157
+ case "string":
158
+ return framed(TAG_TEXT, utf8ToBytes(field));
159
+ case "object":
160
+ if (field instanceof Uint8Array) {
161
+ return framed(TAG_BLOB, field);
162
+ }
163
+ return framed(TAG_JSON, utf8ToBytes(canonicalJson(field)));
63
164
  default:
64
- throw new Error(`Unsupported hash algorithm: ${algorithm}`);
165
+ throw new Error(`digest: unsupported field type '${typeof field}'`);
166
+ }
167
+ }
168
+ function encodeFields(fields) {
169
+ const chunks = [Uint8Array.of(DIGEST_FORMAT_V1)];
170
+ for (const field of fields) {
171
+ chunks.push(encodeField(field));
172
+ }
173
+ return concatBytes(...chunks);
174
+ }
175
+ function digestFields(fields, hasher, encode) {
176
+ return encode(hasher(encodeFields(fields)));
177
+ }
178
+ function digest(fields, algorithm = "sha256", encoding = "base64url") {
179
+ if (!Array.isArray(fields)) {
180
+ throw new Error(
181
+ `digest(fields, algorithm?, encoding?): 'fields' must be an array of values. The digest API changed in v0.14: it is now variadic/injective over fields, the per-call inputEncoding was removed, and algorithm + output encoding are bound at plugin load time. Migrate digest(value, algo, inputEncoding, outputEncoding) \u2192 digest([value], algo, outputEncoding) \u2014 note the result is now a *framed* digest, not a bare hash of the bytes.`
182
+ );
65
183
  }
66
- return fromBytes(hashBytes, outputEncoding);
184
+ return digestFields(fields, resolveHasher(algorithm), resolveOutputEncoder(encoding));
67
185
  }
68
186
  function hashMod(data, bits, algorithm = "sha256", inputEncoding = "base64url") {
69
187
  if (bits <= 0 || bits > 53) {
70
188
  throw new Error("Bits must be between 1 and 53 (JavaScript safe integer limit)");
71
189
  }
72
- const hashBytes = toBytes(digest(data, algorithm, inputEncoding, "base64url"), "base64url");
190
+ const hashBytes = resolveHasher(algorithm)(toBytes(data, inputEncoding));
73
191
  const view = new DataView(hashBytes.buffer, hashBytes.byteOffset, Math.min(8, hashBytes.length));
74
192
  const fullHash = view.getBigUint64(0, false);
75
193
  const modulus = BigInt(2) ** BigInt(bits);
@@ -157,285 +275,167 @@ function getPublicKey(privateKey, curve = "secp256k1", keyEncoding = "base64url"
157
275
  }
158
276
  return fromBytes(pubBytes, outputEncoding);
159
277
  }
160
- function inputToBytes(input) {
161
- if (input === null || input === void 0) {
162
- return new Uint8Array(0);
163
- }
164
- if (typeof input === "string") {
165
- return utf8ToBytes(input);
166
- }
167
- if (input instanceof Uint8Array) {
168
- return input;
169
- }
170
- if (typeof input === "number") {
171
- const buffer = new ArrayBuffer(8);
172
- const view = new DataView(buffer);
173
- view.setFloat64(0, input, false);
174
- return new Uint8Array(buffer);
175
- }
176
- if (typeof input === "boolean") {
177
- return new Uint8Array([input ? 1 : 0]);
178
- }
179
- return utf8ToBytes(String(input));
180
- }
181
- function getHashFunction(algorithm) {
182
- switch (algorithm) {
183
- case "sha256":
184
- return sha256;
185
- case "sha512":
186
- return sha512;
187
- case "blake3":
188
- return blake3;
189
- default:
190
- throw new Error(`Unsupported hash algorithm: ${algorithm}`);
191
- }
192
- }
193
- function Digest(...args) {
194
- return DigestWithOptions({ algorithm: "sha256", output: "uint8array" }, ...args);
195
- }
196
- function DigestWithOptions(options, ...args) {
197
- const algorithm = options.algorithm || "sha256";
198
- const output = options.output || "uint8array";
199
- const byteArrays = args.map(inputToBytes);
200
- const combined = concatBytes(...byteArrays);
201
- const hashFunction = getHashFunction(algorithm);
202
- const hash = hashFunction(combined);
203
- if (output === "hex") {
204
- return Array.from(hash).map((b) => b.toString(16).padStart(2, "0")).join("");
205
- }
206
- return hash;
207
- }
208
- Digest.withOptions = (options) => {
209
- return (...args) => DigestWithOptions(options, ...args);
210
- };
211
- Digest.sha256 = (...args) => {
212
- return DigestWithOptions({ algorithm: "sha256" }, ...args);
213
- };
214
- Digest.sha512 = (...args) => {
215
- return DigestWithOptions({ algorithm: "sha512" }, ...args);
278
+ var MULTICODEC_CODES = {
279
+ "raw": 85,
280
+ "dag-cbor": 113
216
281
  };
217
- Digest.blake3 = (...args) => {
218
- return DigestWithOptions({ algorithm: "blake3" }, ...args);
282
+ var MULTIHASH_CODES = {
283
+ "sha2-256": 18,
284
+ "sha2-512": 19,
285
+ "blake3": 30
219
286
  };
220
- Digest.hex = (...args) => {
221
- return DigestWithOptions({ algorithm: "sha256", output: "hex" }, ...args);
287
+ var MULTIHASH_TO_ALGORITHM = {
288
+ "sha2-256": "sha256",
289
+ "sha2-512": "sha512",
290
+ "blake3": "blake3"
222
291
  };
223
- Digest.sha256Hex = (...args) => {
224
- return DigestWithOptions({ algorithm: "sha256", output: "hex" }, ...args);
292
+ var MULTIHASH_DIGEST_LENGTHS = {
293
+ "sha2-256": 32,
294
+ "sha2-512": 64,
295
+ "blake3": 32
225
296
  };
226
- Digest.sha512Hex = (...args) => {
227
- return DigestWithOptions({ algorithm: "sha512", output: "hex" }, ...args);
297
+ var MULTICODEC_NAMES = new Map(
298
+ Object.entries(MULTICODEC_CODES).map(([name, code]) => [code, name])
299
+ );
300
+ var MULTIHASH_NAMES = new Map(
301
+ Object.entries(MULTIHASH_CODES).map(([name, code]) => [code, name])
302
+ );
303
+ var MULTIBASE_ENCODERS = {
304
+ "base32": base32,
305
+ "base58btc": base58btc,
306
+ "base64url": base64url,
307
+ "base16": base16
228
308
  };
229
- Digest.blake3Hex = (...args) => {
230
- return DigestWithOptions({ algorithm: "blake3", output: "hex" }, ...args);
231
- };
232
- function normalizePrivateKey(privateKey) {
233
- if (privateKey instanceof Uint8Array) {
234
- return privateKey;
235
- }
236
- if (typeof privateKey === "string") {
237
- return hexToBytes(privateKey);
238
- }
239
- if (typeof privateKey === "bigint") {
240
- const hex = privateKey.toString(16).padStart(64, "0");
241
- return hexToBytes(hex);
309
+ var MULTIBASE_DECODER = base32.decoder.or(base58btc.decoder).or(base64url.decoder).or(base16.decoder);
310
+ function resolveCodecCode(codec) {
311
+ const code = MULTICODEC_CODES[codec];
312
+ if (code === void 0) {
313
+ throw new Error(`cid: unsupported multicodec '${codec}' (expected one of ${Object.keys(MULTICODEC_CODES).join(", ")})`);
242
314
  }
243
- throw new Error("Invalid private key format");
315
+ return code;
244
316
  }
245
- function normalizeDigest(digest2) {
246
- if (digest2 instanceof Uint8Array) {
247
- return digest2;
317
+ function resolveBaseEncoder(base) {
318
+ const encoder = MULTIBASE_ENCODERS[base];
319
+ if (!encoder) {
320
+ throw new Error(`cid: unsupported multibase '${base}' (expected one of ${Object.keys(MULTIBASE_ENCODERS).join(", ")})`);
248
321
  }
249
- if (typeof digest2 === "string") {
250
- return hexToBytes(digest2);
251
- }
252
- throw new Error("Invalid digest format");
322
+ return encoder;
253
323
  }
254
- function formatSignature(signature, format, curve) {
255
- switch (format) {
256
- case "uint8array":
257
- case "compact":
258
- return signature;
259
- case "hex":
260
- return bytesToHex(signature);
261
- case "der":
262
- if (curve === "ed25519") {
263
- throw new Error("DER format not supported for ed25519");
264
- }
265
- return signature;
266
- default:
267
- throw new Error(`Unsupported signature format: ${format}`);
268
- }
324
+ function cidV1(digest2, hash, codec = "raw", base = "base32") {
325
+ const hashCode = MULTIHASH_CODES[hash];
326
+ if (hashCode === void 0) {
327
+ throw new Error(`cid: unsupported multihash code '${hash}' (expected one of ${Object.keys(MULTIHASH_CODES).join(", ")})`);
328
+ }
329
+ const expectedLength = MULTIHASH_DIGEST_LENGTHS[hash];
330
+ if (digest2.length !== expectedLength) {
331
+ throw new Error(`cid: digest length ${digest2.length} does not match asserted hash '${hash}' (expected ${expectedLength} bytes)`);
332
+ }
333
+ const codecCode = resolveCodecCode(codec);
334
+ const encoder = resolveBaseEncoder(base);
335
+ const multihash = Digest.create(hashCode, digest2);
336
+ return CID.createV1(codecCode, multihash).toString(encoder);
269
337
  }
270
- function Sign(digest2, privateKey, options = {}) {
271
- const {
272
- curve = "secp256k1",
273
- format = "uint8array",
274
- extraEntropy = false,
275
- lowS = true
276
- } = options;
277
- const normalizedDigest = normalizeDigest(digest2);
278
- const normalizedPrivateKey = normalizePrivateKey(privateKey);
279
- let signature;
280
- switch (curve) {
281
- case "secp256k1": {
282
- const signOptions = { lowS };
283
- if (extraEntropy) {
284
- signOptions.extraEntropy = extraEntropy;
285
- }
286
- signature = secp256k1.sign(normalizedDigest, normalizedPrivateKey, signOptions);
287
- break;
288
- }
289
- case "p256": {
290
- const signOptions = { lowS };
291
- if (extraEntropy) {
292
- signOptions.extraEntropy = extraEntropy;
293
- }
294
- signature = p256.sign(normalizedDigest, normalizedPrivateKey, signOptions);
295
- break;
296
- }
297
- case "ed25519": {
298
- signature = ed25519.sign(normalizedDigest, normalizedPrivateKey);
299
- break;
300
- }
301
- default:
302
- throw new Error(`Unsupported curve: ${curve}`);
338
+ function cid(data, codec = "raw", hash = "sha2-256", base = "base32") {
339
+ const algorithm = MULTIHASH_TO_ALGORITHM[hash];
340
+ if (!algorithm) {
341
+ throw new Error(`cid: unsupported multihash code '${hash}' (expected one of ${Object.keys(MULTIHASH_CODES).join(", ")})`);
303
342
  }
304
- return formatSignature(signature, format, curve);
343
+ const digest2 = resolveHasher(algorithm)(data);
344
+ return cidV1(digest2, hash, codec, base);
305
345
  }
306
- Sign.secp256k1 = (digest2, privateKey, options = {}) => {
307
- return Sign(digest2, privateKey, { ...options, curve: "secp256k1" });
308
- };
309
- Sign.p256 = (digest2, privateKey, options = {}) => {
310
- return Sign(digest2, privateKey, { ...options, curve: "p256" });
311
- };
312
- Sign.ed25519 = (digest2, privateKey, options = {}) => {
313
- return Sign(digest2, privateKey, { ...options, curve: "ed25519" });
314
- };
315
- Sign.generatePrivateKey = (curve = "secp256k1") => {
316
- switch (curve) {
317
- case "secp256k1":
318
- return secp256k1.utils.randomSecretKey();
319
- case "p256":
320
- return p256.utils.randomSecretKey();
321
- case "ed25519":
322
- return ed25519.utils.randomSecretKey();
323
- default:
324
- throw new Error(`Unsupported curve: ${curve}`);
325
- }
326
- };
327
- Sign.getPublicKey = (privateKey, curve = "secp256k1") => {
328
- const normalizedPrivateKey = normalizePrivateKey(privateKey);
329
- switch (curve) {
330
- case "secp256k1":
331
- return secp256k1.getPublicKey(normalizedPrivateKey);
332
- case "p256":
333
- return p256.getPublicKey(normalizedPrivateKey);
334
- case "ed25519":
335
- return ed25519.getPublicKey(normalizedPrivateKey);
336
- default:
337
- throw new Error(`Unsupported curve: ${curve}`);
338
- }
339
- };
340
- function normalizeBytes(input) {
341
- if (input instanceof Uint8Array) {
342
- return input;
343
- }
344
- if (typeof input === "string") {
345
- return hexToBytes(input);
346
- }
347
- throw new Error("Invalid input format - expected Uint8Array or hex string");
346
+ function cidDecode(value) {
347
+ const parsed = CID.parse(value, MULTIBASE_DECODER);
348
+ return {
349
+ version: parsed.version,
350
+ codec: MULTICODEC_NAMES.get(parsed.code) ?? parsed.code,
351
+ hashCode: MULTIHASH_NAMES.get(parsed.multihash.code) ?? parsed.multihash.code,
352
+ digest: parsed.multihash.digest
353
+ };
348
354
  }
349
- function detectSignatureFormat(signature, curve) {
350
- const length = signature.length;
351
- if (curve === "ed25519") {
352
- return "raw";
355
+ var SD_LEAF_DOMAIN_V1 = "optimystic/sd-leaf/v1";
356
+ var SD_SET_DOMAIN_V1 = "optimystic/sd-set/v1";
357
+ var HIDDEN_ENCODING = "base64url";
358
+ function compareBytes(a, b) {
359
+ const len = Math.min(a.length, b.length);
360
+ for (let i = 0; i < len; i++) {
361
+ const d = a[i] - b[i];
362
+ if (d !== 0) return d;
363
+ }
364
+ return a.length - b.length;
365
+ }
366
+ function bytesEqual(a, b) {
367
+ if (a.length !== b.length) return false;
368
+ for (let i = 0; i < a.length; i++) {
369
+ if (a[i] !== b[i]) return false;
353
370
  }
354
- if (length === 64) {
355
- return "compact";
371
+ return true;
372
+ }
373
+ function requireSaltBytes(leaf) {
374
+ const { salt } = leaf;
375
+ if (salt == null) {
376
+ throw new Error(`set commitment: leaf '${leaf.name}' is missing a salt (an unsalted leaf is brute-forceable)`);
356
377
  }
357
- if (length >= 70 && length <= 72 && signature[0] === 48) {
358
- return "der";
378
+ const bytes = salt instanceof Uint8Array ? salt : fromString(salt, HIDDEN_ENCODING);
379
+ if (bytes.length === 0) {
380
+ throw new Error(`set commitment: leaf '${leaf.name}' has an empty salt (an unsalted leaf is brute-forceable)`);
359
381
  }
360
- return "compact";
382
+ return bytes;
361
383
  }
362
- function parseSignature(signature, format, curve) {
363
- if (curve === "ed25519") {
364
- return signature;
384
+ function assertUniqueNames(leaves) {
385
+ const seen = /* @__PURE__ */ new Set();
386
+ for (const leaf of leaves) {
387
+ if (seen.has(leaf.name)) {
388
+ throw new Error(`set commitment: duplicate leaf name '${leaf.name}'`);
389
+ }
390
+ seen.add(leaf.name);
365
391
  }
366
- const sigFormat = format === "raw" ? "compact" : format;
367
- if (curve === "secp256k1") {
368
- return secp256k1.Signature.fromBytes(signature, sigFormat).toBytes();
369
- } else if (curve === "p256") {
370
- return p256.Signature.fromBytes(signature, sigFormat).toBytes();
392
+ }
393
+ function leafDigest(leaf, hasher) {
394
+ const saltBytes = requireSaltBytes(leaf);
395
+ return hasher(encodeFields([SD_LEAF_DOMAIN_V1, leaf.name, leaf.value, saltBytes]));
396
+ }
397
+ function setCommit(leaves, hasher = resolveHasher("sha256"), encode = resolveOutputEncoder("base64url")) {
398
+ assertUniqueNames(leaves);
399
+ const leafDigests = leaves.map((leaf) => leafDigest(leaf, hasher));
400
+ leafDigests.sort(compareBytes);
401
+ return encode(hasher(encodeFields([SD_SET_DOMAIN_V1, ...leafDigests])));
402
+ }
403
+ function setDisclose(leaves, revealNames, hasher = resolveHasher("sha256")) {
404
+ assertUniqueNames(leaves);
405
+ const reveal = new Set(revealNames);
406
+ const disclosed = [];
407
+ const hidden = [];
408
+ for (const leaf of leaves) {
409
+ if (reveal.has(leaf.name)) {
410
+ disclosed.push(leaf);
411
+ } else {
412
+ hidden.push(toString(leafDigest(leaf, hasher), HIDDEN_ENCODING));
413
+ }
371
414
  }
372
- throw new Error(`Failed to parse signature for curve ${curve} with format ${format}`);
415
+ return { disclosed, hidden };
373
416
  }
374
- function SignatureValid(digest2, signature, publicKey, options = {}) {
417
+ function setVerify(root, disclosure, hasher = resolveHasher("sha256"), encode = resolveOutputEncoder("base64url")) {
375
418
  try {
376
- const {
377
- curve = "secp256k1",
378
- signatureFormat,
379
- allowMalleableSignatures
380
- } = options;
381
- const normalizedDigest = normalizeBytes(digest2);
382
- const normalizedSignature = normalizeBytes(signature);
383
- const normalizedPublicKey = normalizeBytes(publicKey);
384
- const detectedFormat = signatureFormat || detectSignatureFormat(normalizedSignature, curve);
385
- const parsedSignature = parseSignature(normalizedSignature, detectedFormat, curve);
386
- const verifyOptions = {};
387
- if (curve !== "ed25519" && allowMalleableSignatures !== void 0) {
388
- verifyOptions.lowS = !allowMalleableSignatures;
419
+ const { disclosed, hidden } = disclosure;
420
+ const digests = [];
421
+ for (const leaf of disclosed) {
422
+ digests.push(leafDigest(leaf, hasher));
389
423
  }
390
- switch (curve) {
391
- case "secp256k1":
392
- return secp256k1.verify(parsedSignature, normalizedDigest, normalizedPublicKey, verifyOptions);
393
- case "p256":
394
- return p256.verify(parsedSignature, normalizedDigest, normalizedPublicKey, verifyOptions);
395
- case "ed25519":
396
- return ed25519.verify(parsedSignature, normalizedDigest, normalizedPublicKey);
397
- default:
398
- throw new Error(`Unsupported curve: ${curve}`);
424
+ for (const h of hidden) {
425
+ digests.push(fromString(h, HIDDEN_ENCODING));
399
426
  }
400
- } catch (error) {
427
+ digests.sort(compareBytes);
428
+ const recomputed = hasher(encodeFields([SD_SET_DOMAIN_V1, ...digests]));
429
+ if (root instanceof Uint8Array) {
430
+ return bytesEqual(recomputed, root);
431
+ }
432
+ const encoded = encode(recomputed);
433
+ return typeof encoded === "string" && encoded === root;
434
+ } catch {
401
435
  return false;
402
436
  }
403
437
  }
404
- SignatureValid.secp256k1 = (digest2, signature, publicKey, options = {}) => {
405
- return SignatureValid(digest2, signature, publicKey, { ...options, curve: "secp256k1" });
406
- };
407
- SignatureValid.p256 = (digest2, signature, publicKey, options = {}) => {
408
- return SignatureValid(digest2, signature, publicKey, { ...options, curve: "p256" });
409
- };
410
- SignatureValid.ed25519 = (digest2, signature, publicKey, options = {}) => {
411
- return SignatureValid(digest2, signature, publicKey, { ...options, curve: "ed25519" });
412
- };
413
- SignatureValid.batch = (verifications) => {
414
- return verifications.map(
415
- ({ digest: digest2, signature, publicKey, options }) => SignatureValid(digest2, signature, publicKey, options)
416
- );
417
- };
418
- SignatureValid.detailed = (digest2, signature, publicKey, options = {}) => {
419
- const curve = options.curve || "secp256k1";
420
- try {
421
- const normalizedSignature = normalizeBytes(signature);
422
- const detectedFormat = options.signatureFormat || detectSignatureFormat(normalizedSignature, curve);
423
- const valid = SignatureValid(digest2, signature, publicKey, options);
424
- return {
425
- valid,
426
- curve,
427
- signatureFormat: detectedFormat
428
- };
429
- } catch (error) {
430
- return {
431
- valid: false,
432
- curve,
433
- signatureFormat: "unknown",
434
- error: error instanceof Error ? error.message : "Unknown error"
435
- };
436
- }
437
- };
438
438
 
439
- export { Digest, Sign, SignatureValid, digest, generatePrivateKey, getPublicKey, hashMod, randomBytes, sign, verify };
439
+ export { cid, cidDecode, cidV1, digest, digestFields, encodeFields, generatePrivateKey, getPublicKey, hashMod, leafDigest, randomBytes, resolveHasher, resolveOutputEncoder, setCommit, setDisclose, setVerify, sign, verify };
440
440
  //# sourceMappingURL=index.js.map
441
441
  //# sourceMappingURL=index.js.map