@cardanowall/sdk-ts 0.0.0

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.
Files changed (67) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +207 -0
  3. package/dist/client/index.cjs +2695 -0
  4. package/dist/client/index.cjs.map +1 -0
  5. package/dist/client/index.d.cts +397 -0
  6. package/dist/client/index.d.ts +397 -0
  7. package/dist/client/index.js +2641 -0
  8. package/dist/client/index.js.map +1 -0
  9. package/dist/conformance/cli.cjs +4901 -0
  10. package/dist/conformance/cli.cjs.map +1 -0
  11. package/dist/conformance/cli.d.cts +18 -0
  12. package/dist/conformance/cli.d.ts +18 -0
  13. package/dist/conformance/cli.js +4878 -0
  14. package/dist/conformance/cli.js.map +1 -0
  15. package/dist/fetch/index.cjs +335 -0
  16. package/dist/fetch/index.cjs.map +1 -0
  17. package/dist/fetch/index.d.cts +13 -0
  18. package/dist/fetch/index.d.ts +13 -0
  19. package/dist/fetch/index.js +323 -0
  20. package/dist/fetch/index.js.map +1 -0
  21. package/dist/fetch-outbound-BT5-NiYN.d.cts +76 -0
  22. package/dist/fetch-outbound-BT5-NiYN.d.ts +76 -0
  23. package/dist/hash/index.cjs +25 -0
  24. package/dist/hash/index.cjs.map +1 -0
  25. package/dist/hash/index.d.cts +1 -0
  26. package/dist/hash/index.d.ts +1 -0
  27. package/dist/hash/index.js +21 -0
  28. package/dist/hash/index.js.map +1 -0
  29. package/dist/identity/index.cjs +1388 -0
  30. package/dist/identity/index.cjs.map +1 -0
  31. package/dist/identity/index.d.cts +27 -0
  32. package/dist/identity/index.d.ts +27 -0
  33. package/dist/identity/index.js +1362 -0
  34. package/dist/identity/index.js.map +1 -0
  35. package/dist/ids/index.cjs +146 -0
  36. package/dist/ids/index.cjs.map +1 -0
  37. package/dist/ids/index.d.cts +55 -0
  38. package/dist/ids/index.d.ts +55 -0
  39. package/dist/ids/index.js +135 -0
  40. package/dist/ids/index.js.map +1 -0
  41. package/dist/index-BhnlWJAY.d.cts +10 -0
  42. package/dist/index-BhnlWJAY.d.ts +10 -0
  43. package/dist/index-Cg1QqVmA.d.cts +19 -0
  44. package/dist/index-Cg1QqVmA.d.ts +19 -0
  45. package/dist/index.cjs +7127 -0
  46. package/dist/index.cjs.map +1 -0
  47. package/dist/index.d.cts +21 -0
  48. package/dist/index.d.ts +21 -0
  49. package/dist/index.js +7004 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/merkle/index.cjs +396 -0
  52. package/dist/merkle/index.cjs.map +1 -0
  53. package/dist/merkle/index.d.cts +2 -0
  54. package/dist/merkle/index.d.ts +2 -0
  55. package/dist/merkle/index.js +387 -0
  56. package/dist/merkle/index.js.map +1 -0
  57. package/dist/types-B8Q3gW54.d.ts +123 -0
  58. package/dist/types-BQMtbRCb.d.cts +321 -0
  59. package/dist/types-BQMtbRCb.d.ts +321 -0
  60. package/dist/types-CLXdbjqr.d.cts +123 -0
  61. package/dist/verifier/index.cjs +4901 -0
  62. package/dist/verifier/index.cjs.map +1 -0
  63. package/dist/verifier/index.d.cts +176 -0
  64. package/dist/verifier/index.d.ts +176 -0
  65. package/dist/verifier/index.js +4848 -0
  66. package/dist/verifier/index.js.map +1 -0
  67. package/package.json +108 -0
@@ -0,0 +1,1362 @@
1
+ import { hkdf } from '@noble/hashes/hkdf.js';
2
+ import { sha512, sha256 } from '@noble/hashes/sha2.js';
3
+ import '@noble/curves/abstract/edwards.js';
4
+ import '@noble/curves/abstract/montgomery.js';
5
+ import '@noble/curves/abstract/weierstrass.js';
6
+ import { x25519 } from '@noble/curves/ed25519.js';
7
+ import '@noble/curves/nist.js';
8
+ import { concatBytes, asciiToBytes, bytesToNumberLE, bytesToNumberBE } from '@noble/curves/utils.js';
9
+ import { sha3_256, shake256, sha3_512, shake128 } from '@noble/hashes/sha3.js';
10
+ import { anumber, abytes, randomBytes as randomBytes$1, u32, swap32IfBE } from '@noble/hashes/utils.js';
11
+ import { FFTCore, reverseBits } from '@noble/curves/abstract/fft.js';
12
+ import * as ed from '@noble/ed25519';
13
+ import '@noble/ciphers/utils.js';
14
+ import { hmac } from '@noble/hashes/hmac.js';
15
+ import { xchacha20poly1305, chacha20poly1305 } from '@noble/ciphers/chacha.js';
16
+ import { encode } from 'cbor2';
17
+ import { sortCoreDeterministic } from 'cbor2/sorts';
18
+
19
+ // ../crypto-core/dist/seed-derive.js
20
+ var abytesDoc = abytes;
21
+ var randomBytes = randomBytes$1;
22
+ function equalBytes(a, b) {
23
+ if (a.length !== b.length)
24
+ return false;
25
+ let diff = 0;
26
+ for (let i = 0; i < a.length; i++)
27
+ diff |= a[i] ^ b[i];
28
+ return diff === 0;
29
+ }
30
+ function copyBytes(bytes) {
31
+ return Uint8Array.from(abytes(bytes));
32
+ }
33
+ function splitCoder(label, ...lengths) {
34
+ const getLength = (c) => typeof c === "number" ? c : c.bytesLen;
35
+ const bytesLen = lengths.reduce((sum, a) => sum + getLength(a), 0);
36
+ return {
37
+ bytesLen,
38
+ encode: (bufs) => {
39
+ const res = new Uint8Array(bytesLen);
40
+ for (let i = 0, pos = 0; i < lengths.length; i++) {
41
+ const c = lengths[i];
42
+ const l = getLength(c);
43
+ const b = typeof c === "number" ? bufs[i] : c.encode(bufs[i]);
44
+ abytes(b, l, label);
45
+ res.set(b, pos);
46
+ if (typeof c !== "number")
47
+ b.fill(0);
48
+ pos += l;
49
+ }
50
+ return res;
51
+ },
52
+ decode: (buf) => {
53
+ abytes(buf, bytesLen, label);
54
+ const res = [];
55
+ for (const c of lengths) {
56
+ const l = getLength(c);
57
+ const b = buf.subarray(0, l);
58
+ res.push(typeof c === "number" ? b : c.decode(b));
59
+ buf = buf.subarray(l);
60
+ }
61
+ return res;
62
+ }
63
+ };
64
+ }
65
+ function vecCoder(c, vecLen) {
66
+ const coder = c;
67
+ const bytesLen = vecLen * coder.bytesLen;
68
+ return {
69
+ bytesLen,
70
+ encode: (u) => {
71
+ if (u.length !== vecLen)
72
+ throw new RangeError(`vecCoder.encode: wrong length=${u.length}. Expected: ${vecLen}`);
73
+ const res = new Uint8Array(bytesLen);
74
+ for (let i = 0, pos = 0; i < u.length; i++) {
75
+ const b = coder.encode(u[i]);
76
+ res.set(b, pos);
77
+ b.fill(0);
78
+ pos += b.length;
79
+ }
80
+ return res;
81
+ },
82
+ decode: (a) => {
83
+ abytes(a, bytesLen);
84
+ const r = [];
85
+ for (let i = 0; i < a.length; i += coder.bytesLen)
86
+ r.push(coder.decode(a.subarray(i, i + coder.bytesLen)));
87
+ return r;
88
+ }
89
+ };
90
+ }
91
+ function cleanBytes(...list) {
92
+ for (const t of list) {
93
+ if (Array.isArray(t))
94
+ for (const b of t)
95
+ b.fill(0);
96
+ else
97
+ t.fill(0);
98
+ }
99
+ }
100
+ function getMask(bits) {
101
+ if (!Number.isSafeInteger(bits) || bits < 0 || bits > 32)
102
+ throw new RangeError(`expected bits in [0..32], got ${bits}`);
103
+ return bits === 32 ? 4294967295 : ~(-1 << bits) >>> 0;
104
+ }
105
+
106
+ // ../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/_crystals.js
107
+ var genCrystals = (opts2) => {
108
+ const { newPoly, N: N2, Q: Q2, F: F2, ROOT_OF_UNITY: ROOT_OF_UNITY2, brvBits} = opts2;
109
+ const mod = (a, modulo = Q2) => {
110
+ const result = a % modulo | 0;
111
+ return (result >= 0 ? result | 0 : modulo + result | 0) | 0;
112
+ };
113
+ const smod = (a, modulo = Q2) => {
114
+ const r = mod(a, modulo) | 0;
115
+ return (r > modulo >> 1 ? r - modulo | 0 : r) | 0;
116
+ };
117
+ function getZettas() {
118
+ const out = newPoly(N2);
119
+ for (let i = 0; i < N2; i++) {
120
+ const b = reverseBits(i, brvBits);
121
+ const p = BigInt(ROOT_OF_UNITY2) ** BigInt(b) % BigInt(Q2);
122
+ out[i] = Number(p) | 0;
123
+ }
124
+ return out;
125
+ }
126
+ const nttZetas = getZettas();
127
+ const field = {
128
+ add: (a, b) => mod((a | 0) + (b | 0)) | 0,
129
+ sub: (a, b) => mod((a | 0) - (b | 0)) | 0,
130
+ mul: (a, b) => mod((a | 0) * (b | 0)) | 0,
131
+ inv: (_a) => {
132
+ throw new Error("not implemented");
133
+ }
134
+ };
135
+ const nttOpts = {
136
+ N: N2,
137
+ roots: nttZetas,
138
+ invertButterflies: true,
139
+ skipStages: 1 ,
140
+ brp: false
141
+ };
142
+ const dif = FFTCore(field, { dit: false, ...nttOpts });
143
+ const dit = FFTCore(field, { dit: true, ...nttOpts });
144
+ const NTT = {
145
+ encode: (r) => {
146
+ return dif(r);
147
+ },
148
+ decode: (r) => {
149
+ dit(r);
150
+ for (let i = 0; i < r.length; i++)
151
+ r[i] = mod(F2 * r[i]);
152
+ return r;
153
+ }
154
+ };
155
+ const bitsCoder = (d, c) => {
156
+ const mask = getMask(d);
157
+ const bytesLen = d * (N2 / 8);
158
+ return {
159
+ bytesLen,
160
+ encode: (poly_) => {
161
+ const poly = poly_;
162
+ const r = new Uint8Array(bytesLen);
163
+ for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < poly.length; i++) {
164
+ buf |= (c.encode(poly[i]) & mask) << bufLen;
165
+ bufLen += d;
166
+ for (; bufLen >= 8; bufLen -= 8, buf >>= 8)
167
+ r[pos++] = buf & getMask(bufLen);
168
+ }
169
+ return r;
170
+ },
171
+ decode: (bytes) => {
172
+ const r = newPoly(N2);
173
+ for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < bytes.length; i++) {
174
+ buf |= bytes[i] << bufLen;
175
+ bufLen += 8;
176
+ for (; bufLen >= d; bufLen -= d, buf >>= d)
177
+ r[pos++] = c.decode(buf & mask);
178
+ }
179
+ return r;
180
+ }
181
+ };
182
+ };
183
+ return {
184
+ mod,
185
+ smod,
186
+ nttZetas,
187
+ NTT: {
188
+ encode: (r) => NTT.encode(r),
189
+ decode: (r) => NTT.decode(r)
190
+ },
191
+ bitsCoder
192
+ };
193
+ };
194
+ var createXofShake = (shake) => (seed, blockLen) => {
195
+ if (!blockLen)
196
+ blockLen = shake.blockLen;
197
+ const _seed = new Uint8Array(seed.length + 2);
198
+ _seed.set(seed);
199
+ const seedLen = seed.length;
200
+ const buf = new Uint8Array(blockLen);
201
+ let h = shake.create({});
202
+ let calls = 0;
203
+ let xofs = 0;
204
+ return {
205
+ stats: () => ({ calls, xofs }),
206
+ get: (x, y) => {
207
+ _seed[seedLen + 0] = x;
208
+ _seed[seedLen + 1] = y;
209
+ h.destroy();
210
+ h = shake.create({}).update(_seed);
211
+ calls++;
212
+ return () => {
213
+ xofs++;
214
+ return h.xofInto(buf);
215
+ };
216
+ },
217
+ clean: () => {
218
+ h.destroy();
219
+ cleanBytes(buf, _seed);
220
+ }
221
+ };
222
+ };
223
+ var XOF128 = /* @__PURE__ */ createXofShake(shake128);
224
+
225
+ // ../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/ml-kem.js
226
+ var N = 256;
227
+ var Q = 3329;
228
+ var F = 3303;
229
+ var ROOT_OF_UNITY = 17;
230
+ var crystals = /* @__PURE__ */ genCrystals({
231
+ N,
232
+ Q,
233
+ F,
234
+ ROOT_OF_UNITY,
235
+ newPoly: (n) => new Uint16Array(n),
236
+ brvBits: 7});
237
+ var PARAMS = /* @__PURE__ */ (() => Object.freeze({
238
+ 512: Object.freeze({ N, Q, K: 2, ETA1: 3, ETA2: 2, du: 10, dv: 4, RBGstrength: 128 }),
239
+ 768: Object.freeze({ N, Q, K: 3, ETA1: 2, ETA2: 2, du: 10, dv: 4, RBGstrength: 192 }),
240
+ 1024: Object.freeze({ N, Q, K: 4, ETA1: 2, ETA2: 2, du: 11, dv: 5, RBGstrength: 256 })
241
+ }))();
242
+ var compress = (d) => {
243
+ if (d >= 12)
244
+ return { encode: (i) => i, decode: (i) => i >= Q ? i - Q : i };
245
+ const a = 2 ** (d - 1);
246
+ return {
247
+ // This only matches standalone Compress_d after bitsCoder masks the result into Z_(2^d).
248
+ encode: (i) => ((i << d) + Q / 2) / Q,
249
+ // const decompress = (i: number) => round((Q / 2 ** d) * i);
250
+ decode: (i) => i * Q + a >>> d
251
+ };
252
+ };
253
+ var byteCoder = (d) => crystals.bitsCoder(d, { encode: (i) => i, decode: (i) => i >= Q ? i - Q : i } );
254
+ var polyCoder = (d) => d === 12 ? byteCoder(12) : crystals.bitsCoder(d, compress(d));
255
+ function polyAdd(a_, b_) {
256
+ const a = a_;
257
+ const b = b_;
258
+ for (let i = 0; i < N; i++)
259
+ a[i] = crystals.mod(a[i] + b[i]);
260
+ }
261
+ function polySub(a_, b_) {
262
+ const a = a_;
263
+ const b = b_;
264
+ for (let i = 0; i < N; i++)
265
+ a[i] = crystals.mod(a[i] - b[i]);
266
+ }
267
+ function BaseCaseMultiply(a0, a1, b0, b1, zeta) {
268
+ const c0 = crystals.mod(a1 * b1 * zeta + a0 * b0);
269
+ const c1 = crystals.mod(a0 * b1 + a1 * b0);
270
+ return { c0, c1 };
271
+ }
272
+ function MultiplyNTTs(f_, g_) {
273
+ const f = f_;
274
+ const g = g_;
275
+ for (let i = 0; i < N / 2; i++) {
276
+ let z = crystals.nttZetas[64 + (i >> 1)];
277
+ if (i & 1)
278
+ z = -z;
279
+ const { c0, c1 } = BaseCaseMultiply(f[2 * i + 0], f[2 * i + 1], g[2 * i + 0], g[2 * i + 1], z);
280
+ f[2 * i + 0] = c0;
281
+ f[2 * i + 1] = c1;
282
+ }
283
+ return f;
284
+ }
285
+ function SampleNTT(xof_) {
286
+ const xof = xof_;
287
+ const r = new Uint16Array(N);
288
+ for (let j = 0; j < N; ) {
289
+ const b = xof();
290
+ if (b.length % 3)
291
+ throw new Error("SampleNTT: unaligned block");
292
+ for (let i = 0; j < N && i + 3 <= b.length; i += 3) {
293
+ const d1 = (b[i + 0] >> 0 | b[i + 1] << 8) & 4095;
294
+ const d2 = (b[i + 1] >> 4 | b[i + 2] << 4) & 4095;
295
+ if (d1 < Q)
296
+ r[j++] = d1;
297
+ if (j < N && d2 < Q)
298
+ r[j++] = d2;
299
+ }
300
+ }
301
+ return r;
302
+ }
303
+ var sampleCBDBytes = (buf, eta) => {
304
+ const r = new Uint16Array(N);
305
+ const b32 = u32(buf);
306
+ swap32IfBE(b32);
307
+ let len = 0;
308
+ for (let i = 0, p = 0, bb = 0, t0 = 0; i < b32.length; i++) {
309
+ let b = b32[i];
310
+ for (let j = 0; j < 32; j++) {
311
+ bb += b & 1;
312
+ b >>= 1;
313
+ len += 1;
314
+ if (len === eta) {
315
+ t0 = bb;
316
+ bb = 0;
317
+ } else if (len === 2 * eta) {
318
+ r[p++] = crystals.mod(t0 - bb);
319
+ bb = 0;
320
+ len = 0;
321
+ }
322
+ }
323
+ }
324
+ swap32IfBE(b32);
325
+ if (len)
326
+ throw new Error(`sampleCBD: leftover bits: ${len}`);
327
+ return r;
328
+ };
329
+ function sampleCBD(PRF_, seed, nonce, eta) {
330
+ const PRF = PRF_;
331
+ return sampleCBDBytes(PRF(eta * N / 4, seed, nonce), eta);
332
+ }
333
+ var genKPKE = (opts_) => {
334
+ const opts2 = opts_;
335
+ const { K, PRF, XOF, HASH512, ETA1, ETA2, du, dv } = opts2;
336
+ const poly1 = polyCoder(1);
337
+ const polyV = polyCoder(dv);
338
+ const polyU = polyCoder(du);
339
+ const publicCoder = splitCoder("publicKey", vecCoder(polyCoder(12), K), 32);
340
+ const secretCoder = vecCoder(polyCoder(12), K);
341
+ const cipherCoder = splitCoder("ciphertext", vecCoder(polyU, K), polyV);
342
+ const seedCoder = splitCoder("seed", 32, 32);
343
+ return {
344
+ secretCoder,
345
+ lengths: {
346
+ secretKey: secretCoder.bytesLen,
347
+ publicKey: publicCoder.bytesLen,
348
+ cipherText: cipherCoder.bytesLen
349
+ },
350
+ keygen: (seed) => {
351
+ abytesDoc(seed, 32, "seed");
352
+ const seedDst = new Uint8Array(33);
353
+ seedDst.set(seed);
354
+ seedDst[32] = K;
355
+ const seedHash = HASH512(seedDst);
356
+ const [rho, sigma] = seedCoder.decode(seedHash);
357
+ const sHat = [];
358
+ const tHat = [];
359
+ for (let i = 0; i < K; i++)
360
+ sHat.push(crystals.NTT.encode(sampleCBD(PRF, sigma, i, ETA1)));
361
+ const x = XOF(rho);
362
+ for (let i = 0; i < K; i++) {
363
+ const e = crystals.NTT.encode(sampleCBD(PRF, sigma, K + i, ETA1));
364
+ for (let j = 0; j < K; j++) {
365
+ const aji = SampleNTT(x.get(j, i));
366
+ polyAdd(e, MultiplyNTTs(aji, sHat[j]));
367
+ }
368
+ tHat.push(e);
369
+ }
370
+ x.clean();
371
+ const res = {
372
+ publicKey: publicCoder.encode([tHat, rho]),
373
+ secretKey: secretCoder.encode(sHat)
374
+ };
375
+ cleanBytes(rho, sigma, sHat, tHat, seedDst, seedHash);
376
+ return res;
377
+ },
378
+ encrypt: (publicKey, msg, seed) => {
379
+ const [tHat, rho] = publicCoder.decode(publicKey);
380
+ const rHat = [];
381
+ for (let i = 0; i < K; i++)
382
+ rHat.push(crystals.NTT.encode(sampleCBD(PRF, seed, i, ETA1)));
383
+ const x = XOF(rho);
384
+ const tmp2 = new Uint16Array(N);
385
+ const u = [];
386
+ for (let i = 0; i < K; i++) {
387
+ const e1 = sampleCBD(PRF, seed, K + i, ETA2);
388
+ const tmp = new Uint16Array(N);
389
+ for (let j = 0; j < K; j++) {
390
+ const aij = SampleNTT(x.get(i, j));
391
+ polyAdd(tmp, MultiplyNTTs(aij, rHat[j]));
392
+ }
393
+ polyAdd(e1, crystals.NTT.decode(tmp));
394
+ u.push(e1);
395
+ polyAdd(tmp2, MultiplyNTTs(tHat[i], rHat[i]));
396
+ cleanBytes(tmp);
397
+ }
398
+ x.clean();
399
+ const e2 = sampleCBD(PRF, seed, 2 * K, ETA2);
400
+ polyAdd(e2, crystals.NTT.decode(tmp2));
401
+ const v = poly1.decode(msg);
402
+ polyAdd(v, e2);
403
+ cleanBytes(tHat, rHat, tmp2, e2);
404
+ return cipherCoder.encode([u, v]);
405
+ },
406
+ decrypt: (cipherText, privateKey) => {
407
+ const [u, v] = cipherCoder.decode(cipherText);
408
+ const sk = secretCoder.decode(privateKey);
409
+ const tmp = new Uint16Array(N);
410
+ for (let i = 0; i < K; i++)
411
+ polyAdd(tmp, MultiplyNTTs(sk[i], crystals.NTT.encode(u[i])));
412
+ polySub(v, crystals.NTT.decode(tmp));
413
+ cleanBytes(tmp, sk, u);
414
+ return poly1.encode(v);
415
+ }
416
+ };
417
+ };
418
+ function createKyber(opts2) {
419
+ const rawOpts = opts2;
420
+ const KPKE = genKPKE(rawOpts);
421
+ const { HASH256, HASH512, KDF } = rawOpts;
422
+ const { secretCoder: KPKESecretCoder, lengths } = KPKE;
423
+ const secretCoder = splitCoder("secretKey", lengths.secretKey, lengths.publicKey, 32, 32);
424
+ const msgLen = 32;
425
+ const seedLen = 64;
426
+ const kemLengths = Object.freeze({
427
+ ...lengths,
428
+ seed: 64,
429
+ msg: msgLen,
430
+ msgRand: msgLen,
431
+ secretKey: secretCoder.bytesLen
432
+ });
433
+ return Object.freeze({
434
+ info: Object.freeze({ type: "ml-kem" }),
435
+ lengths: kemLengths,
436
+ keygen: (seed = randomBytes(seedLen)) => {
437
+ abytesDoc(seed, seedLen, "seed");
438
+ const { publicKey, secretKey: sk } = KPKE.keygen(seed.subarray(0, 32));
439
+ const publicKeyHash = HASH256(publicKey);
440
+ const secretKey = secretCoder.encode([sk, publicKey, publicKeyHash, seed.subarray(32)]);
441
+ cleanBytes(sk, publicKeyHash);
442
+ return {
443
+ publicKey,
444
+ secretKey
445
+ };
446
+ },
447
+ getPublicKey: (secretKey) => {
448
+ const [_sk, publicKey, _publicKeyHash, _z] = secretCoder.decode(secretKey);
449
+ return Uint8Array.from(publicKey);
450
+ },
451
+ encapsulate: (publicKey, msg = randomBytes(msgLen)) => {
452
+ abytesDoc(publicKey, lengths.publicKey, "publicKey");
453
+ abytesDoc(msg, msgLen, "message");
454
+ const eke = publicKey.subarray(0, 384 * opts2.K);
455
+ const ek = KPKESecretCoder.encode(KPKESecretCoder.decode(copyBytes(eke)));
456
+ if (!equalBytes(ek, eke)) {
457
+ cleanBytes(ek);
458
+ throw new Error("ML-KEM.encapsulate: wrong publicKey modulus");
459
+ }
460
+ cleanBytes(ek);
461
+ const kr = HASH512.create().update(msg).update(HASH256(publicKey)).digest();
462
+ const cipherText = KPKE.encrypt(publicKey, msg, kr.subarray(32, 64));
463
+ cleanBytes(kr.subarray(32));
464
+ return {
465
+ cipherText,
466
+ sharedSecret: kr.subarray(0, 32)
467
+ };
468
+ },
469
+ decapsulate: (cipherText, secretKey) => {
470
+ abytesDoc(secretKey, secretCoder.bytesLen, "secretKey");
471
+ abytesDoc(cipherText, lengths.cipherText, "cipherText");
472
+ const k768 = secretCoder.bytesLen - 96;
473
+ const start = k768 + 32;
474
+ const test = HASH256(secretKey.subarray(k768 / 2, start));
475
+ if (!equalBytes(test, secretKey.subarray(start, start + 32)))
476
+ throw new Error("invalid secretKey: hash check failed");
477
+ const [sk, publicKey, publicKeyHash, z] = secretCoder.decode(secretKey);
478
+ const msg = KPKE.decrypt(cipherText, sk);
479
+ const kr = HASH512.create().update(msg).update(publicKeyHash).digest();
480
+ const Khat = kr.subarray(0, 32);
481
+ const cipherText2 = KPKE.encrypt(publicKey, msg, kr.subarray(32, 64));
482
+ const isValid = equalBytes(cipherText, cipherText2);
483
+ const Kbar = KDF.create({ dkLen: 32 }).update(z).update(cipherText).digest();
484
+ cleanBytes(msg, cipherText2, !isValid ? Khat : Kbar);
485
+ return isValid ? Khat : Kbar;
486
+ }
487
+ });
488
+ }
489
+ function shakePRF(dkLen, key, nonce) {
490
+ return shake256.create({ dkLen }).update(key).update(new Uint8Array([nonce])).digest();
491
+ }
492
+ var opts = /* @__PURE__ */ (() => ({
493
+ HASH256: sha3_256,
494
+ HASH512: sha3_512,
495
+ KDF: shake256,
496
+ XOF: XOF128,
497
+ PRF: shakePRF
498
+ }))();
499
+ var mk = (params) => createKyber({
500
+ ...opts,
501
+ ...params
502
+ });
503
+ var ml_kem768 = /* @__PURE__ */ (() => mk(PARAMS[768]))();
504
+
505
+ // ../../node_modules/.pnpm/@noble+post-quantum@0.6.1/node_modules/@noble/post-quantum/hybrid.js
506
+ function ecKeygen(curve, allowZeroKey = false) {
507
+ const lengths = curve.lengths;
508
+ let keygen = curve.keygen;
509
+ if (allowZeroKey) {
510
+ if (!("getSharedSecret" in curve && "sign" in curve && "verify" in curve))
511
+ throw new Error("allowZeroKey requires a Weierstrass curve");
512
+ const wCurve = curve;
513
+ const Fn = wCurve.Point.Fn;
514
+ keygen = (seed = randomBytes(lengths.seed)) => {
515
+ abytes(seed, lengths.seed, "seed");
516
+ const seedScalar = Fn.isLE ? bytesToNumberLE(seed) : bytesToNumberBE(seed);
517
+ const secretKey = Fn.toBytes(Fn.create(seedScalar));
518
+ return {
519
+ secretKey,
520
+ publicKey: curve.getPublicKey(secretKey)
521
+ };
522
+ };
523
+ }
524
+ return {
525
+ lengths: { secretKey: lengths.secretKey, publicKey: lengths.publicKey, seed: lengths.seed },
526
+ keygen: (seed) => keygen(seed),
527
+ getPublicKey: (secretKey) => curve.getPublicKey(secretKey)
528
+ };
529
+ }
530
+ function ecdhKem(curve, allowZeroKey = false) {
531
+ const kg = ecKeygen(curve, allowZeroKey);
532
+ if (!curve.getSharedSecret)
533
+ throw new Error("wrong curve");
534
+ return {
535
+ lengths: { ...kg.lengths, msg: kg.lengths.seed, cipherText: kg.lengths.publicKey },
536
+ keygen: kg.keygen,
537
+ getPublicKey: kg.getPublicKey,
538
+ encapsulate(publicKey, rand = randomBytes(curve.lengths.seed)) {
539
+ const seed = copyBytes(rand);
540
+ let ek = void 0;
541
+ try {
542
+ ek = this.keygen(seed).secretKey;
543
+ const sharedSecret = this.decapsulate(publicKey, ek);
544
+ const cipherText = curve.getPublicKey(ek);
545
+ return { sharedSecret, cipherText };
546
+ } finally {
547
+ cleanBytes(seed);
548
+ if (ek)
549
+ cleanBytes(ek);
550
+ }
551
+ },
552
+ decapsulate(cipherText, secretKey) {
553
+ const res = curve.getSharedSecret(secretKey, cipherText);
554
+ return curve.lengths.publicKeyHasPrefix ? res.subarray(1) : res;
555
+ }
556
+ };
557
+ }
558
+ function splitLengths(lst, name) {
559
+ return splitCoder(name, ...lst.map((i) => {
560
+ if (typeof i.lengths[name] !== "number")
561
+ throw new Error("wrong length: " + name);
562
+ return i.lengths[name];
563
+ }));
564
+ }
565
+ function expandSeedXof(xof) {
566
+ return ((seed, seedLen) => xof(seed, { dkLen: seedLen }));
567
+ }
568
+ function combineKeys(realSeedLen, expandSeed_, ...ck_) {
569
+ const expandSeed = expandSeed_;
570
+ const ck = ck_;
571
+ const seedCoder = splitLengths(ck, "seed");
572
+ const pkCoder = splitLengths(ck, "publicKey");
573
+ anumber(realSeedLen);
574
+ function expandDecapsulationKey(seed) {
575
+ abytes(seed, realSeedLen);
576
+ const expandedRaw = expandSeed(seed, seedCoder.bytesLen);
577
+ const expandedSeed = expandedRaw.buffer === seed.buffer ? copyBytes(expandedRaw) : expandedRaw;
578
+ const expanded = [];
579
+ const keySecret = [];
580
+ const secretKey = [];
581
+ const publicKey = [];
582
+ let ok = false;
583
+ try {
584
+ for (const part of seedCoder.decode(expandedSeed))
585
+ expanded.push(copyBytes(part));
586
+ for (let i = 0; i < ck.length; i++) {
587
+ const keys = ck[i].keygen(expanded[i]);
588
+ keySecret.push(keys.secretKey);
589
+ secretKey.push(copyBytes(keys.secretKey));
590
+ publicKey.push(keys.publicKey);
591
+ }
592
+ ok = true;
593
+ return { secretKey, publicKey };
594
+ } finally {
595
+ cleanBytes(expandedSeed, expanded, keySecret);
596
+ if (!ok)
597
+ cleanBytes(secretKey);
598
+ }
599
+ }
600
+ return {
601
+ info: { lengths: { seed: realSeedLen, publicKey: pkCoder.bytesLen, secretKey: realSeedLen } },
602
+ getPublicKey(secretKey) {
603
+ return this.keygen(secretKey).publicKey;
604
+ },
605
+ keygen(seed = randomBytes(realSeedLen)) {
606
+ const { publicKey: pk, secretKey } = expandDecapsulationKey(seed);
607
+ try {
608
+ const publicKey = pkCoder.encode(pk);
609
+ return { secretKey: seed, publicKey };
610
+ } finally {
611
+ cleanBytes(pk);
612
+ cleanBytes(secretKey);
613
+ }
614
+ },
615
+ expandDecapsulationKey,
616
+ realSeedLen
617
+ };
618
+ }
619
+ function combineKEMS(realSeedLen, realMsgLen, expandSeed, combiner, ...kems) {
620
+ const rawCombiner = combiner;
621
+ const rawKems = kems;
622
+ const keys = combineKeys(realSeedLen, expandSeed, ...rawKems);
623
+ const ctCoder = splitLengths(rawKems, "cipherText");
624
+ const pkCoder = splitLengths(rawKems, "publicKey");
625
+ const msgCoder = splitLengths(rawKems, "msg");
626
+ anumber(realMsgLen);
627
+ const lengths = Object.freeze({
628
+ ...keys.info.lengths,
629
+ msg: realMsgLen,
630
+ msgRand: msgCoder.bytesLen,
631
+ cipherText: ctCoder.bytesLen
632
+ });
633
+ return Object.freeze({
634
+ lengths,
635
+ getPublicKey: keys.getPublicKey,
636
+ keygen: keys.keygen,
637
+ encapsulate(pk, randomness = randomBytes(msgCoder.bytesLen)) {
638
+ const pks = pkCoder.decode(pk);
639
+ const rand = msgCoder.decode(randomness);
640
+ const sharedSecret = [];
641
+ const cipherText = [];
642
+ try {
643
+ for (let i = 0; i < rawKems.length; i++) {
644
+ const enc = rawKems[i].encapsulate(pks[i], rand[i]);
645
+ sharedSecret.push(enc.sharedSecret);
646
+ cipherText.push(enc.cipherText);
647
+ }
648
+ return {
649
+ // Detach the combiner result before cleanup: a caller-provided combiner may alias one of
650
+ // the child sharedSecret buffers, and those child buffers are zeroized immediately below.
651
+ sharedSecret: copyBytes(rawCombiner(pks, cipherText, sharedSecret)),
652
+ cipherText: ctCoder.encode(cipherText)
653
+ };
654
+ } finally {
655
+ cleanBytes(sharedSecret, cipherText);
656
+ }
657
+ },
658
+ decapsulate(ct, seed) {
659
+ const cts = ctCoder.decode(ct);
660
+ const { publicKey, secretKey } = keys.expandDecapsulationKey(seed);
661
+ const sharedSecret = rawKems.map((i, j) => i.decapsulate(cts[j], secretKey[j]));
662
+ try {
663
+ return copyBytes(rawCombiner(publicKey, cts, sharedSecret));
664
+ } finally {
665
+ cleanBytes(secretKey, sharedSecret);
666
+ }
667
+ }
668
+ });
669
+ }
670
+ var x25519kem = /* @__PURE__ */ ecdhKem(x25519);
671
+ var ml_kem768_x25519 = /* @__PURE__ */ (() => combineKEMS(
672
+ 32,
673
+ 32,
674
+ expandSeedXof(shake256),
675
+ // Awesome label, so much escaping hell in a single line.
676
+ (pk, ct, ss) => sha3_256(concatBytes(ss[0], ss[1], ct[1], pk[1], asciiToBytes("\\.//^\\"))),
677
+ ml_kem768,
678
+ x25519kem
679
+ ))();
680
+ var XWing = /* @__PURE__ */ (() => ml_kem768_x25519)();
681
+ function hkdfSha256(opts2) {
682
+ return hkdf(sha256, opts2.ikm, opts2.salt, opts2.info, opts2.length);
683
+ }
684
+ var MLKEM768X25519_SEED_LENGTH = 32;
685
+ function mlkem768x25519Keygen(seed) {
686
+ if (seed.length !== MLKEM768X25519_SEED_LENGTH) {
687
+ throw new Error(
688
+ `mlkem768x25519 seed must be ${MLKEM768X25519_SEED_LENGTH} bytes, got ${seed.length}`
689
+ );
690
+ }
691
+ const { secretKey, publicKey } = XWing.keygen(seed);
692
+ return { secretSeed: secretKey, publicKey };
693
+ }
694
+ function x25519PublicKey(opts2) {
695
+ return x25519.getPublicKey(opts2.secretKey);
696
+ }
697
+ ed.hashes.sha512 = sha512;
698
+ ed.Point.CURVE().n;
699
+ function getPublicKeyEd25519(opts2) {
700
+ return ed.getPublicKey(opts2.seed);
701
+ }
702
+ var SeedDeriveError = class extends Error {
703
+ code;
704
+ constructor(code, message, options) {
705
+ super(message, options);
706
+ this.name = "SeedDeriveError";
707
+ this.code = code;
708
+ }
709
+ };
710
+ var INFO_ED25519 = new TextEncoder().encode("cardano-poe-ed25519-v1");
711
+ var INFO_X25519 = new TextEncoder().encode("cardano-poe-x25519-v1");
712
+ var INFO_MLKEM768X25519 = new TextEncoder().encode(
713
+ "cardano-poe-mlkem768x25519-v1"
714
+ );
715
+ if (INFO_ED25519.length !== 22) {
716
+ throw new Error("INFO_ED25519 byte-length invariant violated (expected 22)");
717
+ }
718
+ if (INFO_X25519.length !== 21) {
719
+ throw new Error("INFO_X25519 byte-length invariant violated (expected 21)");
720
+ }
721
+ if (INFO_MLKEM768X25519.length !== 29) {
722
+ throw new Error("INFO_MLKEM768X25519 byte-length invariant violated (expected 29)");
723
+ }
724
+ var EMPTY_SALT = new Uint8Array(0);
725
+ var SEED_LENGTH = 32;
726
+ var DERIVED_LENGTH = 32;
727
+ function assertSeedLength(seed) {
728
+ if (seed.length !== SEED_LENGTH) {
729
+ throw new SeedDeriveError(
730
+ "INVALID_SEED_LENGTH",
731
+ `seed must be exactly 32 bytes, got ${seed.length}`
732
+ );
733
+ }
734
+ }
735
+ function deriveEd25519KeypairFromSeed(seed) {
736
+ assertSeedLength(seed);
737
+ const secretKey = hkdfSha256({
738
+ ikm: seed,
739
+ salt: EMPTY_SALT,
740
+ info: INFO_ED25519,
741
+ length: DERIVED_LENGTH
742
+ });
743
+ const publicKey = getPublicKeyEd25519({ seed: secretKey });
744
+ return { secretKey, publicKey };
745
+ }
746
+ function deriveX25519KeypairFromSeed(seed) {
747
+ assertSeedLength(seed);
748
+ const secretKey = hkdfSha256({
749
+ ikm: seed,
750
+ salt: EMPTY_SALT,
751
+ info: INFO_X25519,
752
+ length: DERIVED_LENGTH
753
+ });
754
+ const publicKey = x25519PublicKey({ secretKey });
755
+ return { secretKey, publicKey };
756
+ }
757
+ function deriveMlKem768X25519KeypairFromSeed(seed) {
758
+ assertSeedLength(seed);
759
+ const xwingSeed = hkdfSha256({
760
+ ikm: seed,
761
+ salt: EMPTY_SALT,
762
+ info: INFO_MLKEM768X25519,
763
+ length: DERIVED_LENGTH
764
+ });
765
+ return mlkem768x25519Keygen(xwingSeed);
766
+ }
767
+
768
+ // ../crypto-core/dist/recipient.js
769
+ var BECH32_ALPHABET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
770
+ var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
771
+ var ENCODING_CONST = 1;
772
+ function polymodStep(pre) {
773
+ const b = pre >> 25;
774
+ let chk = (pre & 33554431) << 5;
775
+ for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
776
+ if ((b >> i & 1) === 1) chk ^= POLYMOD_GENERATORS[i];
777
+ }
778
+ return chk;
779
+ }
780
+ function bytesToWords(bytes) {
781
+ const words = [];
782
+ let carry = 0;
783
+ let pos = 0;
784
+ const mask = (1 << 5) - 1;
785
+ for (const n of bytes) {
786
+ carry = carry << 8 | n;
787
+ pos += 8;
788
+ for (; pos >= 5; pos -= 5) words.push(carry >> pos - 5 & mask);
789
+ carry &= (1 << pos) - 1;
790
+ }
791
+ if (pos > 0) words.push(carry << 5 - pos & mask);
792
+ return words;
793
+ }
794
+ function checksum(prefix, words) {
795
+ let chk = 1;
796
+ for (let i = 0; i < prefix.length; i++) {
797
+ const c = prefix.charCodeAt(i);
798
+ if (c < 33 || c > 126) throw new Error(`bech32: invalid prefix (${prefix})`);
799
+ chk = polymodStep(chk) ^ c >> 5;
800
+ }
801
+ chk = polymodStep(chk);
802
+ for (let i = 0; i < prefix.length; i++) chk = polymodStep(chk) ^ prefix.charCodeAt(i) & 31;
803
+ for (const v of words) chk = polymodStep(chk) ^ v;
804
+ for (let i = 0; i < 6; i++) chk = polymodStep(chk);
805
+ chk ^= ENCODING_CONST;
806
+ let out = "";
807
+ for (let i = 0; i < 6; i++) out += BECH32_ALPHABET[chk >> 5 * (5 - i) & 31];
808
+ return out;
809
+ }
810
+ function bech32EncodeNoLimit(prefix, bytes) {
811
+ if (prefix.length === 0) throw new Error("bech32: empty prefix");
812
+ const words = bytesToWords(bytes);
813
+ let payload = "";
814
+ for (const w of words) payload += BECH32_ALPHABET[w];
815
+ const lowered = prefix.toLowerCase();
816
+ return `${lowered}1${payload}${checksum(lowered, words)}`;
817
+ }
818
+ var X25519_HRP = "age";
819
+ var XWING_HRP = "age1pqc";
820
+ var X25519_PUBLIC_KEY_BYTES = 32;
821
+ var XWING_PUBLIC_KEY_BYTES = 1216;
822
+ function encodeAgeX25519Recipient(publicKey) {
823
+ if (publicKey.length !== X25519_PUBLIC_KEY_BYTES) {
824
+ throw new Error("encodeAgeX25519Recipient: publicKey must be exactly 32 bytes");
825
+ }
826
+ return bech32EncodeNoLimit(X25519_HRP, publicKey);
827
+ }
828
+ function encodeAgeXWingRecipient(publicKey) {
829
+ if (publicKey.length !== XWING_PUBLIC_KEY_BYTES) {
830
+ throw new Error("encodeAgeXWingRecipient: publicKey must be exactly 1216 bytes");
831
+ }
832
+ return bech32EncodeNoLimit(XWING_HRP, publicKey);
833
+ }
834
+ var AeadVerificationError = class extends Error {
835
+ code = "aead_verification_failed";
836
+ constructor(message, options) {
837
+ super(message, options);
838
+ this.name = "AeadVerificationError";
839
+ }
840
+ };
841
+ function chacha20Poly1305Decrypt(opts2) {
842
+ try {
843
+ return chacha20poly1305(opts2.key, opts2.nonce, opts2.aad).decrypt(opts2.ciphertext);
844
+ } catch (cause) {
845
+ throw new AeadVerificationError("chacha20-poly1305 decrypt failed", { cause });
846
+ }
847
+ }
848
+ function xchacha20Poly1305Decrypt(opts2) {
849
+ try {
850
+ return xchacha20poly1305(opts2.key, opts2.nonce, opts2.aad).decrypt(opts2.ciphertext);
851
+ } catch (cause) {
852
+ throw new AeadVerificationError("xchacha20-poly1305 decrypt failed", { cause });
853
+ }
854
+ }
855
+ function hkdfSha2562(opts2) {
856
+ return hkdf(sha256, opts2.ikm, opts2.salt, opts2.info, opts2.length);
857
+ }
858
+ var MLKEM768X25519_ENC_LENGTH = 1120;
859
+ var MLKEM768X25519_SEED_LENGTH2 = 32;
860
+ function mlkem768x25519Decapsulate(opts2) {
861
+ if (opts2.secretSeed.length !== MLKEM768X25519_SEED_LENGTH2) {
862
+ throw new Error(
863
+ `mlkem768x25519 secret seed must be ${MLKEM768X25519_SEED_LENGTH2} bytes, got ${opts2.secretSeed.length}`
864
+ );
865
+ }
866
+ if (opts2.enc.length !== MLKEM768X25519_ENC_LENGTH) {
867
+ throw new Error(
868
+ `mlkem768x25519 enc must be ${MLKEM768X25519_ENC_LENGTH} bytes, got ${opts2.enc.length}`
869
+ );
870
+ }
871
+ return XWing.decapsulate(opts2.enc, opts2.secretSeed);
872
+ }
873
+ var X25519LowOrderPointError = class extends Error {
874
+ code = "X25519_LOW_ORDER_POINT";
875
+ constructor(options) {
876
+ super("x25519 ECDH rejected: peer public key is a small-order point", options);
877
+ this.name = "X25519LowOrderPointError";
878
+ }
879
+ };
880
+ var NOBLE_LOW_ORDER_MESSAGE = "invalid private or public key received";
881
+ function x25519PublicKey2(opts2) {
882
+ return x25519.getPublicKey(opts2.secretKey);
883
+ }
884
+ function x25519Ecdh(opts2) {
885
+ try {
886
+ return x25519.getSharedSecret(opts2.secretKey, opts2.theirPublicKey);
887
+ } catch (e) {
888
+ if (e instanceof Error && e.message === NOBLE_LOW_ORDER_MESSAGE) {
889
+ throw new X25519LowOrderPointError({ cause: e });
890
+ }
891
+ throw e;
892
+ }
893
+ }
894
+ var EciesSealedPoeError = class extends Error {
895
+ code;
896
+ constructor(code, message, options) {
897
+ super(message, options);
898
+ this.name = "EciesSealedPoeError";
899
+ this.code = code;
900
+ }
901
+ };
902
+ function encodeCanonicalCbor(value) {
903
+ return encode(value, {
904
+ cde: true,
905
+ collapseBigInts: true,
906
+ rejectDuplicateKeys: true,
907
+ sortKeys: sortCoreDeterministic
908
+ });
909
+ }
910
+ var CHUNK_MAX_BYTES = 64;
911
+ function chunkKemCt(value) {
912
+ if (value.length === 0) {
913
+ throw new Error("chunkKemCt: refusing to chunk an empty byte string");
914
+ }
915
+ const chunks = [];
916
+ for (let i = 0; i < value.length; i += CHUNK_MAX_BYTES) {
917
+ chunks.push(value.subarray(i, Math.min(i + CHUNK_MAX_BYTES, value.length)));
918
+ }
919
+ return chunks;
920
+ }
921
+ function joinKemCt(chunks) {
922
+ let total = 0;
923
+ for (const c of chunks) total += c.length;
924
+ const out = new Uint8Array(total);
925
+ let offset = 0;
926
+ for (const c of chunks) {
927
+ out.set(c, offset);
928
+ offset += c.length;
929
+ }
930
+ return out;
931
+ }
932
+ function slotsToMacCbor(slots, kem) {
933
+ let value;
934
+ if (kem === "x25519") {
935
+ value = slots.map((s) => ({ epk: s.epk, wrap: s.wrap }));
936
+ } else {
937
+ value = slots.map((s) => ({
938
+ // Canonicalize the chunk boundaries before the MAC commits to them:
939
+ // reassemble the logical ciphertext and re-split into canonical ≤ 64-byte
940
+ // chunks. The on-wire `kem_ct` array is a transport detail (the Cardano
941
+ // ledger's 64-byte metadatum cap), and a hostile or non-canonical chunking
942
+ // ([1, 63, …] instead of [64, …]) reassembles to the SAME bytes — so the
943
+ // MAC must be invariant to it. Committing to the verbatim wire chunks would
944
+ // let an attacker re-chunk an honest envelope and break the slots_mac match
945
+ // for an honest recipient. Honest (already-64B-chunked) records are
946
+ // unchanged; a real byte flip still changes the reassembled bytes and is
947
+ // still rejected.
948
+ kem_ct: chunkKemCt(joinKemCt(s.kem_ct)),
949
+ wrap: s.wrap
950
+ }));
951
+ }
952
+ return encodeCanonicalCbor(value);
953
+ }
954
+ var CARDANO_POE_HKDF_INFO_KEK = new TextEncoder().encode("cardano-poe-kek-v1");
955
+ var CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519 = new TextEncoder().encode(
956
+ "cardano-poe-kek-mlkem768x25519-v1"
957
+ );
958
+ var CARDANO_POE_HKDF_INFO_SLOTS_MAC = new TextEncoder().encode(
959
+ "cardano-poe-slots-mac-v1"
960
+ );
961
+ var ZERO_NONCE_12 = new Uint8Array(12);
962
+ if (CARDANO_POE_HKDF_INFO_KEK.length !== 18) {
963
+ throw new Error("CARDANO_POE_HKDF_INFO_KEK byte-length invariant violated (expected 18)");
964
+ }
965
+ if (CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519.length !== 33) {
966
+ throw new Error(
967
+ "CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519 byte-length invariant violated (expected 33)"
968
+ );
969
+ }
970
+ if (CARDANO_POE_HKDF_INFO_SLOTS_MAC.length !== 24) {
971
+ throw new Error("CARDANO_POE_HKDF_INFO_SLOTS_MAC byte-length invariant violated (expected 24)");
972
+ }
973
+ if (ZERO_NONCE_12.length !== 12) {
974
+ throw new Error("ZERO_NONCE_12 byte-length invariant violated (expected 12)");
975
+ }
976
+ function compareCt(a, b) {
977
+ if (a.length !== b.length) return false;
978
+ let diff = 0;
979
+ for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
980
+ return diff === 0;
981
+ }
982
+ function selectBundleSecrets(envelope, bundle) {
983
+ return envelope.kem === "x25519" ? bundle.x25519PrivateKeys : bundle.mlkem768x25519SecretSeeds;
984
+ }
985
+ var ZERO_NONCE_122 = new Uint8Array(12);
986
+ var EMPTY_SALT22 = new Uint8Array(0);
987
+ var X25519_SECRET_KEY_LENGTH2 = 32;
988
+ var X25519_PUBLIC_KEY_LENGTH2 = 32;
989
+ var NONCE_LENGTH2 = 24;
990
+ var WRAP_LENGTH2 = 48;
991
+ var SLOTS_MAC_LENGTH2 = 32;
992
+ function concat2(a, b) {
993
+ const out = new Uint8Array(a.length + b.length);
994
+ out.set(a, 0);
995
+ out.set(b, a.length);
996
+ return out;
997
+ }
998
+ function assertEnvelopeStructure(envelope, multiPrivKeys, singlePrivKey) {
999
+ if (envelope.scheme !== 1) {
1000
+ throw new EciesSealedPoeError(
1001
+ "UNSUPPORTED_ENC_VERSION",
1002
+ `envelope.scheme=${String(envelope.scheme)} unsupported (expected 1)`
1003
+ );
1004
+ }
1005
+ if (envelope.aead !== "xchacha20-poly1305") {
1006
+ throw new EciesSealedPoeError(
1007
+ "UNSUPPORTED_AEAD_ALG",
1008
+ `envelope.aead=${String(envelope.aead)} unsupported (expected 'xchacha20-poly1305')`
1009
+ );
1010
+ }
1011
+ if (envelope.kem !== "x25519" && envelope.kem !== "mlkem768x25519") {
1012
+ throw new EciesSealedPoeError(
1013
+ "UNSUPPORTED_KEM_ALG",
1014
+ `envelope.kem=${String(envelope.kem)} unsupported (expected 'x25519' or 'mlkem768x25519')`
1015
+ );
1016
+ }
1017
+ const n = envelope.slots.length;
1018
+ if (n < 1) {
1019
+ throw new EciesSealedPoeError("ENC_SLOTS_EMPTY", `envelope.slots.length=${n} must be >= 1`);
1020
+ }
1021
+ if (envelope.nonce.length !== NONCE_LENGTH2) {
1022
+ throw new EciesSealedPoeError(
1023
+ "NONCE_LENGTH_MISMATCH",
1024
+ `envelope.nonce MUST be exactly ${NONCE_LENGTH2} bytes, got ${envelope.nonce.length}`
1025
+ );
1026
+ }
1027
+ if (envelope.slots_mac.length !== SLOTS_MAC_LENGTH2) {
1028
+ throw new EciesSealedPoeError(
1029
+ "ENC_SLOTS_MAC_INVALID_LENGTH",
1030
+ `envelope.slots_mac MUST be exactly ${SLOTS_MAC_LENGTH2} bytes, got ${envelope.slots_mac.length}`
1031
+ );
1032
+ }
1033
+ if (envelope.kem === "x25519") {
1034
+ for (let i = 0; i < n; i++) {
1035
+ const slot = envelope.slots[i];
1036
+ if (slot.epk.length !== X25519_PUBLIC_KEY_LENGTH2) {
1037
+ throw new EciesSealedPoeError(
1038
+ "KEM_EPK_LENGTH_MISMATCH",
1039
+ `envelope.slots[${i}].epk MUST be exactly ${X25519_PUBLIC_KEY_LENGTH2} bytes, got ${slot.epk.length}`
1040
+ );
1041
+ }
1042
+ if (slot.wrap.length !== WRAP_LENGTH2) {
1043
+ throw new EciesSealedPoeError(
1044
+ "WRAP_LENGTH_MISMATCH",
1045
+ `envelope.slots[${i}].wrap MUST be exactly ${WRAP_LENGTH2} bytes, got ${slot.wrap.length}`
1046
+ );
1047
+ }
1048
+ }
1049
+ } else {
1050
+ for (let i = 0; i < n; i++) {
1051
+ const slot = envelope.slots[i];
1052
+ const enc = joinKemCt(slot.kem_ct);
1053
+ if (enc.length !== MLKEM768X25519_ENC_LENGTH) {
1054
+ throw new EciesSealedPoeError(
1055
+ "KEM_CT_LENGTH_MISMATCH",
1056
+ `envelope.slots[${i}].kem_ct MUST reassemble to exactly ${MLKEM768X25519_ENC_LENGTH} bytes, got ${enc.length}`
1057
+ );
1058
+ }
1059
+ if (slot.wrap.length !== WRAP_LENGTH2) {
1060
+ throw new EciesSealedPoeError(
1061
+ "WRAP_LENGTH_MISMATCH",
1062
+ `envelope.slots[${i}].wrap MUST be exactly ${WRAP_LENGTH2} bytes, got ${slot.wrap.length}`
1063
+ );
1064
+ }
1065
+ }
1066
+ }
1067
+ if (multiPrivKeys !== void 0) {
1068
+ for (let i = 0; i < multiPrivKeys.length; i++) {
1069
+ if (multiPrivKeys[i].length !== X25519_SECRET_KEY_LENGTH2) {
1070
+ throw new EciesSealedPoeError(
1071
+ "INVALID_RECIPIENT_KEY",
1072
+ `recipientSecretKeys[${i}] MUST be exactly ${X25519_SECRET_KEY_LENGTH2} bytes, got ${multiPrivKeys[i].length}`
1073
+ );
1074
+ }
1075
+ }
1076
+ } else if (singlePrivKey !== void 0) {
1077
+ if (singlePrivKey.length !== X25519_SECRET_KEY_LENGTH2) {
1078
+ throw new EciesSealedPoeError(
1079
+ "INVALID_RECIPIENT_KEY",
1080
+ `recipientSecretKey MUST be exactly ${X25519_SECRET_KEY_LENGTH2} bytes, got ${singlePrivKey.length}`
1081
+ );
1082
+ }
1083
+ }
1084
+ }
1085
+ function tryX25519Slot(args) {
1086
+ if (args.liveSlot) {
1087
+ try {
1088
+ const shared = x25519Ecdh({
1089
+ secretKey: args.recipientSecretKey,
1090
+ theirPublicKey: args.slot.epk
1091
+ });
1092
+ const kek = hkdfSha2562({
1093
+ ikm: shared,
1094
+ salt: concat2(args.slot.epk, args.pubRLocal),
1095
+ info: CARDANO_POE_HKDF_INFO_KEK,
1096
+ length: 32
1097
+ });
1098
+ return chacha20Poly1305Decrypt({
1099
+ key: kek,
1100
+ nonce: ZERO_NONCE_122,
1101
+ aad: CARDANO_POE_HKDF_INFO_KEK,
1102
+ ciphertext: args.slot.wrap
1103
+ });
1104
+ } catch (e) {
1105
+ if (!(e instanceof AeadVerificationError) && !(e instanceof X25519LowOrderPointError)) {
1106
+ throw e;
1107
+ }
1108
+ return null;
1109
+ }
1110
+ }
1111
+ try {
1112
+ const shared = x25519Ecdh({
1113
+ secretKey: args.recipientSecretKey,
1114
+ theirPublicKey: args.slot.epk
1115
+ });
1116
+ hkdfSha2562({
1117
+ ikm: shared,
1118
+ salt: concat2(args.slot.epk, args.pubRLocal),
1119
+ info: CARDANO_POE_HKDF_INFO_KEK,
1120
+ length: 32
1121
+ });
1122
+ } catch (e) {
1123
+ if (!(e instanceof X25519LowOrderPointError)) throw e;
1124
+ }
1125
+ return null;
1126
+ }
1127
+ function tryMlkem768X25519Slot(args) {
1128
+ const enc = joinKemCt(args.slot.kem_ct);
1129
+ const ss = mlkem768x25519Decapsulate({ secretSeed: args.recipientSecretKey, enc });
1130
+ const kek = hkdfSha2562({
1131
+ ikm: ss,
1132
+ salt: EMPTY_SALT22,
1133
+ info: CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519,
1134
+ length: 32
1135
+ });
1136
+ if (!args.liveSlot) {
1137
+ return null;
1138
+ }
1139
+ try {
1140
+ return chacha20Poly1305Decrypt({
1141
+ key: kek,
1142
+ nonce: ZERO_NONCE_122,
1143
+ aad: CARDANO_POE_HKDF_INFO_KEK_MLKEM768X25519,
1144
+ ciphertext: args.slot.wrap
1145
+ });
1146
+ } catch (e) {
1147
+ if (!(e instanceof AeadVerificationError)) throw e;
1148
+ return null;
1149
+ }
1150
+ }
1151
+ function tryRecipientUnwrapWithIdx(envelope, recipientSecretKey, constantTimeN, slotsAttemptedOut) {
1152
+ const n = envelope.slots.length;
1153
+ let cek = null;
1154
+ let matchedSlotIdx = -1;
1155
+ if (envelope.kem === "x25519") {
1156
+ const pubRLocal = x25519PublicKey2({ secretKey: recipientSecretKey });
1157
+ for (let i = 0; i < n; i++) {
1158
+ if (slotsAttemptedOut !== void 0) {
1159
+ slotsAttemptedOut.count = i + 1;
1160
+ }
1161
+ const candidate = tryX25519Slot({
1162
+ slot: envelope.slots[i],
1163
+ recipientSecretKey,
1164
+ pubRLocal,
1165
+ liveSlot: cek === null
1166
+ });
1167
+ if (cek === null && candidate !== null) {
1168
+ cek = candidate;
1169
+ matchedSlotIdx = i;
1170
+ }
1171
+ if (cek !== null && !constantTimeN) break;
1172
+ }
1173
+ } else {
1174
+ for (let i = 0; i < n; i++) {
1175
+ if (slotsAttemptedOut !== void 0) {
1176
+ slotsAttemptedOut.count = i + 1;
1177
+ }
1178
+ const candidate = tryMlkem768X25519Slot({
1179
+ slot: envelope.slots[i],
1180
+ recipientSecretKey,
1181
+ liveSlot: cek === null
1182
+ });
1183
+ if (cek === null && candidate !== null) {
1184
+ cek = candidate;
1185
+ matchedSlotIdx = i;
1186
+ }
1187
+ if (cek !== null && !constantTimeN) break;
1188
+ }
1189
+ }
1190
+ return cek === null ? null : { cek, slotIdx: matchedSlotIdx };
1191
+ }
1192
+ function tryRecipientUnwrap(envelope, recipientSecretKey, constantTimeN, slotsAttemptedOut) {
1193
+ return tryRecipientUnwrapWithIdx(envelope, recipientSecretKey, constantTimeN, slotsAttemptedOut)?.cek ?? null;
1194
+ }
1195
+ function slotsMacCborBytes(envelope) {
1196
+ return slotsToMacCbor(
1197
+ envelope.slots,
1198
+ envelope.kem
1199
+ );
1200
+ }
1201
+ function eciesSealedPoeUnwrap(args) {
1202
+ const { envelope, ciphertext } = args;
1203
+ const constantTimeN = args.constantTimeN ?? true;
1204
+ const hasSingle = "recipientSecretKey" in args;
1205
+ const hasBundle = "recipientKeyBundle" in args;
1206
+ const multiPrivKeys = hasBundle ? selectBundleSecrets(envelope, args.recipientKeyBundle) : "recipientSecretKeys" in args ? args.recipientSecretKeys : void 0;
1207
+ const hasMulti = multiPrivKeys !== void 0;
1208
+ if (hasSingle === hasMulti) {
1209
+ throw new EciesSealedPoeError(
1210
+ "INVALID_RECIPIENT_KEY",
1211
+ "exactly one of recipientSecretKey / recipientSecretKeys / recipientKeyBundle MUST be supplied"
1212
+ );
1213
+ }
1214
+ if (hasMulti && multiPrivKeys.length === 0) {
1215
+ if (hasBundle) {
1216
+ return { matched: false, reason: "WRONG_RECIPIENT_KEY" };
1217
+ }
1218
+ throw new EciesSealedPoeError(
1219
+ "INVALID_RECIPIENT_KEY",
1220
+ "recipientSecretKeys MUST be a non-empty array, got length=0"
1221
+ );
1222
+ }
1223
+ if (hasMulti) {
1224
+ assertEnvelopeStructure(envelope, multiPrivKeys, void 0);
1225
+ } else {
1226
+ assertEnvelopeStructure(envelope, void 0, args.recipientSecretKey);
1227
+ }
1228
+ let matchedCek = null;
1229
+ let anyCandidateRecovered = false;
1230
+ if (hasSingle) {
1231
+ const recipientSecretKey = args.recipientSecretKey;
1232
+ const cek = tryRecipientUnwrap(
1233
+ envelope,
1234
+ recipientSecretKey,
1235
+ constantTimeN,
1236
+ args._slotsAttemptedOut
1237
+ );
1238
+ if (cek === null) {
1239
+ return { matched: false, reason: "WRONG_RECIPIENT_KEY" };
1240
+ }
1241
+ const slotsCbor = slotsMacCborBytes(envelope);
1242
+ const hmacKey = hkdfSha2562({
1243
+ ikm: cek,
1244
+ salt: EMPTY_SALT22,
1245
+ info: CARDANO_POE_HKDF_INFO_SLOTS_MAC,
1246
+ length: 32
1247
+ });
1248
+ const slotsMacCalc = hmac(sha256, hmacKey, slotsCbor);
1249
+ if (!compareCt(slotsMacCalc, envelope.slots_mac)) {
1250
+ return { matched: false, reason: "TAMPERED_HEADER" };
1251
+ }
1252
+ matchedCek = cek;
1253
+ } else {
1254
+ const slotsCbor = slotsMacCborBytes(envelope);
1255
+ const recipientSecretKeys = multiPrivKeys;
1256
+ for (let k = 0; k < recipientSecretKeys.length; k++) {
1257
+ if (args._privsAttemptedOut !== void 0) {
1258
+ args._privsAttemptedOut.count = k + 1;
1259
+ }
1260
+ if (args._slotsAttemptedOut !== void 0) {
1261
+ args._slotsAttemptedOut.count = 0;
1262
+ }
1263
+ const cek = tryRecipientUnwrap(
1264
+ envelope,
1265
+ recipientSecretKeys[k],
1266
+ constantTimeN,
1267
+ args._slotsAttemptedOut
1268
+ );
1269
+ if (args._slotsAttemptedOut?.perPrivCounts !== void 0) {
1270
+ args._slotsAttemptedOut.perPrivCounts.push(args._slotsAttemptedOut.count);
1271
+ }
1272
+ if (cek === null) continue;
1273
+ const hmacKey = hkdfSha2562({
1274
+ ikm: cek,
1275
+ salt: EMPTY_SALT22,
1276
+ info: CARDANO_POE_HKDF_INFO_SLOTS_MAC,
1277
+ length: 32
1278
+ });
1279
+ const slotsMacCalc = hmac(sha256, hmacKey, slotsCbor);
1280
+ if (compareCt(slotsMacCalc, envelope.slots_mac)) {
1281
+ matchedCek = cek;
1282
+ break;
1283
+ }
1284
+ anyCandidateRecovered = true;
1285
+ }
1286
+ if (matchedCek === null) {
1287
+ return {
1288
+ matched: false,
1289
+ reason: anyCandidateRecovered ? "TAMPERED_HEADER" : "WRONG_RECIPIENT_KEY"
1290
+ };
1291
+ }
1292
+ }
1293
+ const adContent = concat2(envelope.nonce, envelope.slots_mac);
1294
+ try {
1295
+ const plaintext = xchacha20Poly1305Decrypt({
1296
+ key: matchedCek,
1297
+ nonce: envelope.nonce,
1298
+ aad: adContent,
1299
+ ciphertext
1300
+ });
1301
+ return { matched: true, plaintext };
1302
+ } catch (e) {
1303
+ if (!(e instanceof AeadVerificationError)) throw e;
1304
+ return { matched: false, reason: "TAMPERED_CIPHERTEXT" };
1305
+ }
1306
+ }
1307
+ ed.hashes.sha512 = sha512;
1308
+ ed.Point.CURVE().n;
1309
+ function signEd25519(opts2) {
1310
+ return ed.sign(opts2.message, opts2.seed);
1311
+ }
1312
+
1313
+ // src/identity/seed-identity.ts
1314
+ function deriveKeysFromSeed(seed) {
1315
+ return {
1316
+ ed25519: deriveEd25519KeypairFromSeed(seed),
1317
+ x25519: deriveX25519KeypairFromSeed(seed),
1318
+ mlkem768x25519: deriveMlKem768X25519KeypairFromSeed(seed)
1319
+ };
1320
+ }
1321
+ function recipientsFromSeed(seed) {
1322
+ const keys = deriveKeysFromSeed(seed);
1323
+ return {
1324
+ age: encodeAgeX25519Recipient(keys.x25519.publicKey),
1325
+ age1pqc: encodeAgeXWingRecipient(keys.mlkem768x25519.publicKey)
1326
+ };
1327
+ }
1328
+ function signerFromSeed(seed) {
1329
+ const { secretKey, publicKey } = deriveEd25519KeypairFromSeed(seed);
1330
+ return {
1331
+ signerPubkey: publicKey,
1332
+ async sign(sigStructureBytes) {
1333
+ return signEd25519({ seed: secretKey, message: sigStructureBytes });
1334
+ }
1335
+ };
1336
+ }
1337
+ function recipientKeyBundleFromSeed(seed) {
1338
+ const keys = deriveKeysFromSeed(seed);
1339
+ return {
1340
+ x25519PrivateKeys: [keys.x25519.secretKey],
1341
+ mlkem768x25519SecretSeeds: [keys.mlkem768x25519.secretSeed]
1342
+ };
1343
+ }
1344
+ function decryptSealedFromSeed(args) {
1345
+ return eciesSealedPoeUnwrap({
1346
+ envelope: args.envelope,
1347
+ ciphertext: args.ciphertext,
1348
+ recipientKeyBundle: recipientKeyBundleFromSeed(args.seed)
1349
+ });
1350
+ }
1351
+ /*! Bundled license information:
1352
+
1353
+ @noble/post-quantum/utils.js:
1354
+ @noble/post-quantum/_crystals.js:
1355
+ @noble/post-quantum/ml-kem.js:
1356
+ @noble/post-quantum/hybrid.js:
1357
+ (*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) *)
1358
+ */
1359
+
1360
+ export { decryptSealedFromSeed, deriveKeysFromSeed, recipientKeyBundleFromSeed, recipientsFromSeed, signerFromSeed };
1361
+ //# sourceMappingURL=index.js.map
1362
+ //# sourceMappingURL=index.js.map