@didcid/cipher 0.1.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.
@@ -0,0 +1,1695 @@
1
+ 'use strict';
2
+
3
+ var bip39 = require('bip39');
4
+ var secp = require('@noble/secp256k1');
5
+ var canonicalizeModule = require('canonicalize');
6
+
7
+ function _interopNamespaceDefault(e) {
8
+ var n = Object.create(null);
9
+ if (e) {
10
+ Object.keys(e).forEach(function (k) {
11
+ if (k !== 'default') {
12
+ var d = Object.getOwnPropertyDescriptor(e, k);
13
+ Object.defineProperty(n, k, d.get ? d : {
14
+ enumerable: true,
15
+ get: function () { return e[k]; }
16
+ });
17
+ }
18
+ });
19
+ }
20
+ n.default = e;
21
+ return Object.freeze(n);
22
+ }
23
+
24
+ var bip39__namespace = /*#__PURE__*/_interopNamespaceDefault(bip39);
25
+ var secp__namespace = /*#__PURE__*/_interopNamespaceDefault(secp);
26
+
27
+ /**
28
+ * Class represents both BaseEncoder and MultibaseEncoder meaning it
29
+ * can be used to encode to multibase or base encode without multibase
30
+ * prefix.
31
+ */
32
+ class Encoder {
33
+ name;
34
+ prefix;
35
+ baseEncode;
36
+ constructor(name, prefix, baseEncode) {
37
+ this.name = name;
38
+ this.prefix = prefix;
39
+ this.baseEncode = baseEncode;
40
+ }
41
+ encode(bytes) {
42
+ if (bytes instanceof Uint8Array) {
43
+ return `${this.prefix}${this.baseEncode(bytes)}`;
44
+ }
45
+ else {
46
+ throw Error('Unknown type, must be binary type');
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * Class represents both BaseDecoder and MultibaseDecoder so it could be used
52
+ * to decode multibases (with matching prefix) or just base decode strings
53
+ * with corresponding base encoding.
54
+ */
55
+ class Decoder {
56
+ name;
57
+ prefix;
58
+ baseDecode;
59
+ prefixCodePoint;
60
+ constructor(name, prefix, baseDecode) {
61
+ this.name = name;
62
+ this.prefix = prefix;
63
+ const prefixCodePoint = prefix.codePointAt(0);
64
+ /* c8 ignore next 3 */
65
+ if (prefixCodePoint === undefined) {
66
+ throw new Error('Invalid prefix character');
67
+ }
68
+ this.prefixCodePoint = prefixCodePoint;
69
+ this.baseDecode = baseDecode;
70
+ }
71
+ decode(text) {
72
+ if (typeof text === 'string') {
73
+ if (text.codePointAt(0) !== this.prefixCodePoint) {
74
+ throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);
75
+ }
76
+ return this.baseDecode(text.slice(this.prefix.length));
77
+ }
78
+ else {
79
+ throw Error('Can only multibase decode strings');
80
+ }
81
+ }
82
+ or(decoder) {
83
+ return or(this, decoder);
84
+ }
85
+ }
86
+ class ComposedDecoder {
87
+ decoders;
88
+ constructor(decoders) {
89
+ this.decoders = decoders;
90
+ }
91
+ or(decoder) {
92
+ return or(this, decoder);
93
+ }
94
+ decode(input) {
95
+ const prefix = input[0];
96
+ const decoder = this.decoders[prefix];
97
+ if (decoder != null) {
98
+ return decoder.decode(input);
99
+ }
100
+ else {
101
+ throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`);
102
+ }
103
+ }
104
+ }
105
+ function or(left, right) {
106
+ return new ComposedDecoder({
107
+ ...(left.decoders ?? { [left.prefix]: left }),
108
+ ...(right.decoders ?? { [right.prefix]: right })
109
+ });
110
+ }
111
+ class Codec {
112
+ name;
113
+ prefix;
114
+ baseEncode;
115
+ baseDecode;
116
+ encoder;
117
+ decoder;
118
+ constructor(name, prefix, baseEncode, baseDecode) {
119
+ this.name = name;
120
+ this.prefix = prefix;
121
+ this.baseEncode = baseEncode;
122
+ this.baseDecode = baseDecode;
123
+ this.encoder = new Encoder(name, prefix, baseEncode);
124
+ this.decoder = new Decoder(name, prefix, baseDecode);
125
+ }
126
+ encode(input) {
127
+ return this.encoder.encode(input);
128
+ }
129
+ decode(input) {
130
+ return this.decoder.decode(input);
131
+ }
132
+ }
133
+ function from({ name, prefix, encode, decode }) {
134
+ return new Codec(name, prefix, encode, decode);
135
+ }
136
+ function decode(string, alphabetIdx, bitsPerChar, name) {
137
+ // Count the padding bytes:
138
+ let end = string.length;
139
+ while (string[end - 1] === '=') {
140
+ --end;
141
+ }
142
+ // Allocate the output:
143
+ const out = new Uint8Array((end * bitsPerChar / 8) | 0);
144
+ // Parse the data:
145
+ let bits = 0; // Number of bits currently in the buffer
146
+ let buffer = 0; // Bits waiting to be written out, MSB first
147
+ let written = 0; // Next byte to write
148
+ for (let i = 0; i < end; ++i) {
149
+ // Read one character from the string:
150
+ const value = alphabetIdx[string[i]];
151
+ if (value === undefined) {
152
+ throw new SyntaxError(`Non-${name} character`);
153
+ }
154
+ // Append the bits to the buffer:
155
+ buffer = (buffer << bitsPerChar) | value;
156
+ bits += bitsPerChar;
157
+ // Write out some bits if the buffer has a byte's worth:
158
+ if (bits >= 8) {
159
+ bits -= 8;
160
+ out[written++] = 0xff & (buffer >> bits);
161
+ }
162
+ }
163
+ // Verify that we have received just enough bits:
164
+ if (bits >= bitsPerChar || (0xff & (buffer << (8 - bits))) !== 0) {
165
+ throw new SyntaxError('Unexpected end of data');
166
+ }
167
+ return out;
168
+ }
169
+ function encode(data, alphabet, bitsPerChar) {
170
+ const pad = alphabet[alphabet.length - 1] === '=';
171
+ const mask = (1 << bitsPerChar) - 1;
172
+ let out = '';
173
+ let bits = 0; // Number of bits currently in the buffer
174
+ let buffer = 0; // Bits waiting to be written out, MSB first
175
+ for (let i = 0; i < data.length; ++i) {
176
+ // Slurp data into the buffer:
177
+ buffer = (buffer << 8) | data[i];
178
+ bits += 8;
179
+ // Write out as much as we can:
180
+ while (bits > bitsPerChar) {
181
+ bits -= bitsPerChar;
182
+ out += alphabet[mask & (buffer >> bits)];
183
+ }
184
+ }
185
+ // Partial character:
186
+ if (bits !== 0) {
187
+ out += alphabet[mask & (buffer << (bitsPerChar - bits))];
188
+ }
189
+ // Add padding characters until we hit a byte boundary:
190
+ if (pad) {
191
+ while (((out.length * bitsPerChar) & 7) !== 0) {
192
+ out += '=';
193
+ }
194
+ }
195
+ return out;
196
+ }
197
+ function createAlphabetIdx(alphabet) {
198
+ // Build the character lookup table:
199
+ const alphabetIdx = {};
200
+ for (let i = 0; i < alphabet.length; ++i) {
201
+ alphabetIdx[alphabet[i]] = i;
202
+ }
203
+ return alphabetIdx;
204
+ }
205
+ /**
206
+ * RFC4648 Factory
207
+ */
208
+ function rfc4648({ name, prefix, bitsPerChar, alphabet }) {
209
+ const alphabetIdx = createAlphabetIdx(alphabet);
210
+ return from({
211
+ prefix,
212
+ name,
213
+ encode(input) {
214
+ return encode(input, alphabet, bitsPerChar);
215
+ },
216
+ decode(input) {
217
+ return decode(input, alphabetIdx, bitsPerChar, name);
218
+ }
219
+ });
220
+ }
221
+
222
+ rfc4648({
223
+ prefix: 'm',
224
+ name: 'base64',
225
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
226
+ bitsPerChar: 6
227
+ });
228
+ rfc4648({
229
+ prefix: 'M',
230
+ name: 'base64pad',
231
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
232
+ bitsPerChar: 6
233
+ });
234
+ const base64url = rfc4648({
235
+ prefix: 'u',
236
+ name: 'base64url',
237
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
238
+ bitsPerChar: 6
239
+ });
240
+ rfc4648({
241
+ prefix: 'U',
242
+ name: 'base64urlpad',
243
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=',
244
+ bitsPerChar: 6
245
+ });
246
+
247
+ /**
248
+ * Utilities for hex, bytes, CSPRNG.
249
+ * @module
250
+ */
251
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
252
+ // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
253
+ // node.js versions earlier than v19 don't declare it in global scope.
254
+ // For node.js, package.json#exports field mapping rewrites import
255
+ // from `crypto` to `cryptoNode`, which imports native module.
256
+ // Makes the utils un-importable in browsers without a bundler.
257
+ // Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
258
+ /** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
259
+ function isBytes$2(a) {
260
+ return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
261
+ }
262
+ /** Asserts something is positive integer. */
263
+ function anumber(n) {
264
+ if (!Number.isSafeInteger(n) || n < 0)
265
+ throw new Error('positive integer expected, got ' + n);
266
+ }
267
+ /** Asserts something is Uint8Array. */
268
+ function abytes(b, ...lengths) {
269
+ if (!isBytes$2(b))
270
+ throw new Error('Uint8Array expected');
271
+ if (lengths.length > 0 && !lengths.includes(b.length))
272
+ throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
273
+ }
274
+ /** Asserts something is hash */
275
+ function ahash(h) {
276
+ if (typeof h !== 'function' || typeof h.create !== 'function')
277
+ throw new Error('Hash should be wrapped by utils.createHasher');
278
+ anumber(h.outputLen);
279
+ anumber(h.blockLen);
280
+ }
281
+ /** Asserts a hash instance has not been destroyed / finished */
282
+ function aexists(instance, checkFinished = true) {
283
+ if (instance.destroyed)
284
+ throw new Error('Hash instance has been destroyed');
285
+ if (checkFinished && instance.finished)
286
+ throw new Error('Hash#digest() has already been called');
287
+ }
288
+ /** Asserts output is properly-sized byte array */
289
+ function aoutput(out, instance) {
290
+ abytes(out);
291
+ const min = instance.outputLen;
292
+ if (out.length < min) {
293
+ throw new Error('digestInto() expects output buffer of length at least ' + min);
294
+ }
295
+ }
296
+ /** Zeroize a byte array. Warning: JS provides no guarantees. */
297
+ function clean(...arrays) {
298
+ for (let i = 0; i < arrays.length; i++) {
299
+ arrays[i].fill(0);
300
+ }
301
+ }
302
+ /** Create DataView of an array for easy byte-level manipulation. */
303
+ function createView$1(arr) {
304
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
305
+ }
306
+ /** The rotate right (circular right shift) operation for uint32 */
307
+ function rotr(word, shift) {
308
+ return (word << (32 - shift)) | (word >>> shift);
309
+ }
310
+ /**
311
+ * Converts string to bytes using UTF8 encoding.
312
+ * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
313
+ */
314
+ function utf8ToBytes$1(str) {
315
+ if (typeof str !== 'string')
316
+ throw new Error('string expected');
317
+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
318
+ }
319
+ /**
320
+ * Normalizes (non-hex) string or Uint8Array to Uint8Array.
321
+ * Warning: when Uint8Array is passed, it would NOT get copied.
322
+ * Keep in mind for future mutable operations.
323
+ */
324
+ function toBytes$1(data) {
325
+ if (typeof data === 'string')
326
+ data = utf8ToBytes$1(data);
327
+ abytes(data);
328
+ return data;
329
+ }
330
+ /** For runtime check if class implements interface */
331
+ class Hash {
332
+ }
333
+ /** Wraps hash function, creating an interface on top of it */
334
+ function createHasher(hashCons) {
335
+ const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
336
+ const tmp = hashCons();
337
+ hashC.outputLen = tmp.outputLen;
338
+ hashC.blockLen = tmp.blockLen;
339
+ hashC.create = () => hashCons();
340
+ return hashC;
341
+ }
342
+
343
+ /**
344
+ * HMAC: RFC2104 message authentication code.
345
+ * @module
346
+ */
347
+ class HMAC extends Hash {
348
+ constructor(hash, _key) {
349
+ super();
350
+ this.finished = false;
351
+ this.destroyed = false;
352
+ ahash(hash);
353
+ const key = toBytes$1(_key);
354
+ this.iHash = hash.create();
355
+ if (typeof this.iHash.update !== 'function')
356
+ throw new Error('Expected instance of class which extends utils.Hash');
357
+ this.blockLen = this.iHash.blockLen;
358
+ this.outputLen = this.iHash.outputLen;
359
+ const blockLen = this.blockLen;
360
+ const pad = new Uint8Array(blockLen);
361
+ // blockLen can be bigger than outputLen
362
+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
363
+ for (let i = 0; i < pad.length; i++)
364
+ pad[i] ^= 0x36;
365
+ this.iHash.update(pad);
366
+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
367
+ this.oHash = hash.create();
368
+ // Undo internal XOR && apply outer XOR
369
+ for (let i = 0; i < pad.length; i++)
370
+ pad[i] ^= 0x36 ^ 0x5c;
371
+ this.oHash.update(pad);
372
+ clean(pad);
373
+ }
374
+ update(buf) {
375
+ aexists(this);
376
+ this.iHash.update(buf);
377
+ return this;
378
+ }
379
+ digestInto(out) {
380
+ aexists(this);
381
+ abytes(out, this.outputLen);
382
+ this.finished = true;
383
+ this.iHash.digestInto(out);
384
+ this.oHash.update(out);
385
+ this.oHash.digestInto(out);
386
+ this.destroy();
387
+ }
388
+ digest() {
389
+ const out = new Uint8Array(this.oHash.outputLen);
390
+ this.digestInto(out);
391
+ return out;
392
+ }
393
+ _cloneInto(to) {
394
+ // Create new instance without calling constructor since key already in state and we don't know it.
395
+ to || (to = Object.create(Object.getPrototypeOf(this), {}));
396
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
397
+ to = to;
398
+ to.finished = finished;
399
+ to.destroyed = destroyed;
400
+ to.blockLen = blockLen;
401
+ to.outputLen = outputLen;
402
+ to.oHash = oHash._cloneInto(to.oHash);
403
+ to.iHash = iHash._cloneInto(to.iHash);
404
+ return to;
405
+ }
406
+ clone() {
407
+ return this._cloneInto();
408
+ }
409
+ destroy() {
410
+ this.destroyed = true;
411
+ this.oHash.destroy();
412
+ this.iHash.destroy();
413
+ }
414
+ }
415
+ /**
416
+ * HMAC: RFC2104 message authentication code.
417
+ * @param hash - function that would be used e.g. sha256
418
+ * @param key - message key
419
+ * @param message - message data
420
+ * @example
421
+ * import { hmac } from '@noble/hashes/hmac';
422
+ * import { sha256 } from '@noble/hashes/sha2';
423
+ * const mac1 = hmac(sha256, 'key', 'message');
424
+ */
425
+ const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
426
+ hmac.create = (hash, key) => new HMAC(hash, key);
427
+
428
+ /**
429
+ * Internal Merkle-Damgard hash utils.
430
+ * @module
431
+ */
432
+ /** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
433
+ function setBigUint64$1(view, byteOffset, value, isLE) {
434
+ if (typeof view.setBigUint64 === 'function')
435
+ return view.setBigUint64(byteOffset, value, isLE);
436
+ const _32n = BigInt(32);
437
+ const _u32_max = BigInt(0xffffffff);
438
+ const wh = Number((value >> _32n) & _u32_max);
439
+ const wl = Number(value & _u32_max);
440
+ const h = isLE ? 4 : 0;
441
+ const l = isLE ? 0 : 4;
442
+ view.setUint32(byteOffset + h, wh, isLE);
443
+ view.setUint32(byteOffset + l, wl, isLE);
444
+ }
445
+ /** Choice: a ? b : c */
446
+ function Chi(a, b, c) {
447
+ return (a & b) ^ (~a & c);
448
+ }
449
+ /** Majority function, true if any two inputs is true. */
450
+ function Maj(a, b, c) {
451
+ return (a & b) ^ (a & c) ^ (b & c);
452
+ }
453
+ /**
454
+ * Merkle-Damgard hash construction base class.
455
+ * Could be used to create MD5, RIPEMD, SHA1, SHA2.
456
+ */
457
+ class HashMD extends Hash {
458
+ constructor(blockLen, outputLen, padOffset, isLE) {
459
+ super();
460
+ this.finished = false;
461
+ this.length = 0;
462
+ this.pos = 0;
463
+ this.destroyed = false;
464
+ this.blockLen = blockLen;
465
+ this.outputLen = outputLen;
466
+ this.padOffset = padOffset;
467
+ this.isLE = isLE;
468
+ this.buffer = new Uint8Array(blockLen);
469
+ this.view = createView$1(this.buffer);
470
+ }
471
+ update(data) {
472
+ aexists(this);
473
+ data = toBytes$1(data);
474
+ abytes(data);
475
+ const { view, buffer, blockLen } = this;
476
+ const len = data.length;
477
+ for (let pos = 0; pos < len;) {
478
+ const take = Math.min(blockLen - this.pos, len - pos);
479
+ // Fast path: we have at least one block in input, cast it to view and process
480
+ if (take === blockLen) {
481
+ const dataView = createView$1(data);
482
+ for (; blockLen <= len - pos; pos += blockLen)
483
+ this.process(dataView, pos);
484
+ continue;
485
+ }
486
+ buffer.set(data.subarray(pos, pos + take), this.pos);
487
+ this.pos += take;
488
+ pos += take;
489
+ if (this.pos === blockLen) {
490
+ this.process(view, 0);
491
+ this.pos = 0;
492
+ }
493
+ }
494
+ this.length += data.length;
495
+ this.roundClean();
496
+ return this;
497
+ }
498
+ digestInto(out) {
499
+ aexists(this);
500
+ aoutput(out, this);
501
+ this.finished = true;
502
+ // Padding
503
+ // We can avoid allocation of buffer for padding completely if it
504
+ // was previously not allocated here. But it won't change performance.
505
+ const { buffer, view, blockLen, isLE } = this;
506
+ let { pos } = this;
507
+ // append the bit '1' to the message
508
+ buffer[pos++] = 0b10000000;
509
+ clean(this.buffer.subarray(pos));
510
+ // we have less than padOffset left in buffer, so we cannot put length in
511
+ // current block, need process it and pad again
512
+ if (this.padOffset > blockLen - pos) {
513
+ this.process(view, 0);
514
+ pos = 0;
515
+ }
516
+ // Pad until full block byte with zeros
517
+ for (let i = pos; i < blockLen; i++)
518
+ buffer[i] = 0;
519
+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
520
+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
521
+ // So we just write lowest 64 bits of that value.
522
+ setBigUint64$1(view, blockLen - 8, BigInt(this.length * 8), isLE);
523
+ this.process(view, 0);
524
+ const oview = createView$1(out);
525
+ const len = this.outputLen;
526
+ // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
527
+ if (len % 4)
528
+ throw new Error('_sha2: outputLen should be aligned to 32bit');
529
+ const outLen = len / 4;
530
+ const state = this.get();
531
+ if (outLen > state.length)
532
+ throw new Error('_sha2: outputLen bigger than state');
533
+ for (let i = 0; i < outLen; i++)
534
+ oview.setUint32(4 * i, state[i], isLE);
535
+ }
536
+ digest() {
537
+ const { buffer, outputLen } = this;
538
+ this.digestInto(buffer);
539
+ const res = buffer.slice(0, outputLen);
540
+ this.destroy();
541
+ return res;
542
+ }
543
+ _cloneInto(to) {
544
+ to || (to = new this.constructor());
545
+ to.set(...this.get());
546
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
547
+ to.destroyed = destroyed;
548
+ to.finished = finished;
549
+ to.length = length;
550
+ to.pos = pos;
551
+ if (length % blockLen)
552
+ to.buffer.set(buffer);
553
+ return to;
554
+ }
555
+ clone() {
556
+ return this._cloneInto();
557
+ }
558
+ }
559
+ /**
560
+ * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
561
+ * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
562
+ */
563
+ /** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
564
+ const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
565
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
566
+ ]);
567
+
568
+ /**
569
+ * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
570
+ * SHA256 is the fastest hash implementable in JS, even faster than Blake3.
571
+ * Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
572
+ * [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
573
+ * @module
574
+ */
575
+ /**
576
+ * Round constants:
577
+ * First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
578
+ */
579
+ // prettier-ignore
580
+ const SHA256_K = /* @__PURE__ */ Uint32Array.from([
581
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
582
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
583
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
584
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
585
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
586
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
587
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
588
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
589
+ ]);
590
+ /** Reusable temporary buffer. "W" comes straight from spec. */
591
+ const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
592
+ class SHA256 extends HashMD {
593
+ constructor(outputLen = 32) {
594
+ super(64, outputLen, 8, false);
595
+ // We cannot use array here since array allows indexing by variable
596
+ // which means optimizer/compiler cannot use registers.
597
+ this.A = SHA256_IV[0] | 0;
598
+ this.B = SHA256_IV[1] | 0;
599
+ this.C = SHA256_IV[2] | 0;
600
+ this.D = SHA256_IV[3] | 0;
601
+ this.E = SHA256_IV[4] | 0;
602
+ this.F = SHA256_IV[5] | 0;
603
+ this.G = SHA256_IV[6] | 0;
604
+ this.H = SHA256_IV[7] | 0;
605
+ }
606
+ get() {
607
+ const { A, B, C, D, E, F, G, H } = this;
608
+ return [A, B, C, D, E, F, G, H];
609
+ }
610
+ // prettier-ignore
611
+ set(A, B, C, D, E, F, G, H) {
612
+ this.A = A | 0;
613
+ this.B = B | 0;
614
+ this.C = C | 0;
615
+ this.D = D | 0;
616
+ this.E = E | 0;
617
+ this.F = F | 0;
618
+ this.G = G | 0;
619
+ this.H = H | 0;
620
+ }
621
+ process(view, offset) {
622
+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
623
+ for (let i = 0; i < 16; i++, offset += 4)
624
+ SHA256_W[i] = view.getUint32(offset, false);
625
+ for (let i = 16; i < 64; i++) {
626
+ const W15 = SHA256_W[i - 15];
627
+ const W2 = SHA256_W[i - 2];
628
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
629
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
630
+ SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
631
+ }
632
+ // Compression function main loop, 64 rounds
633
+ let { A, B, C, D, E, F, G, H } = this;
634
+ for (let i = 0; i < 64; i++) {
635
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
636
+ const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
637
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
638
+ const T2 = (sigma0 + Maj(A, B, C)) | 0;
639
+ H = G;
640
+ G = F;
641
+ F = E;
642
+ E = (D + T1) | 0;
643
+ D = C;
644
+ C = B;
645
+ B = A;
646
+ A = (T1 + T2) | 0;
647
+ }
648
+ // Add the compressed chunk to the current hash value
649
+ A = (A + this.A) | 0;
650
+ B = (B + this.B) | 0;
651
+ C = (C + this.C) | 0;
652
+ D = (D + this.D) | 0;
653
+ E = (E + this.E) | 0;
654
+ F = (F + this.F) | 0;
655
+ G = (G + this.G) | 0;
656
+ H = (H + this.H) | 0;
657
+ this.set(A, B, C, D, E, F, G, H);
658
+ }
659
+ roundClean() {
660
+ clean(SHA256_W);
661
+ }
662
+ destroy() {
663
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
664
+ clean(this.buffer);
665
+ }
666
+ }
667
+ /**
668
+ * SHA2-256 hash function from RFC 4634.
669
+ *
670
+ * It is the fastest JS hash, even faster than Blake3.
671
+ * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
672
+ * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
673
+ */
674
+ const sha256$1 = /* @__PURE__ */ createHasher(() => new SHA256());
675
+
676
+ /**
677
+ * SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
678
+ *
679
+ * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
680
+ * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
681
+ *
682
+ * Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
683
+ * @module
684
+ * @deprecated
685
+ */
686
+ /** @deprecated Use import from `noble/hashes/sha2` module */
687
+ const sha256 = sha256$1;
688
+
689
+ /*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */
690
+ // Cast array to different type
691
+ const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
692
+ function isBytes$1(a) {
693
+ return (a instanceof Uint8Array ||
694
+ (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
695
+ }
696
+ // Cast array to view
697
+ const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
698
+ // big-endian hardware is rare. Just in case someone still decides to run ciphers:
699
+ // early-throw an error because we don't support BE yet.
700
+ const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
701
+ if (!isLE)
702
+ throw new Error('Non little-endian hardware is not supported');
703
+ /**
704
+ * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
705
+ */
706
+ function utf8ToBytes(str) {
707
+ if (typeof str !== 'string')
708
+ throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
709
+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
710
+ }
711
+ function bytesToUtf8(bytes) {
712
+ return new TextDecoder().decode(bytes);
713
+ }
714
+ /**
715
+ * Normalizes (non-hex) string or Uint8Array to Uint8Array.
716
+ * Warning: when Uint8Array is passed, it would NOT get copied.
717
+ * Keep in mind for future mutable operations.
718
+ */
719
+ function toBytes(data) {
720
+ if (typeof data === 'string')
721
+ data = utf8ToBytes(data);
722
+ else if (isBytes$1(data))
723
+ data = data.slice();
724
+ else
725
+ throw new Error(`expected Uint8Array, got ${typeof data}`);
726
+ return data;
727
+ }
728
+ /**
729
+ * Copies several Uint8Arrays into one.
730
+ */
731
+ function concatBytes(...arrays) {
732
+ let sum = 0;
733
+ for (let i = 0; i < arrays.length; i++) {
734
+ const a = arrays[i];
735
+ if (!isBytes$1(a))
736
+ throw new Error('Uint8Array expected');
737
+ sum += a.length;
738
+ }
739
+ const res = new Uint8Array(sum);
740
+ for (let i = 0, pad = 0; i < arrays.length; i++) {
741
+ const a = arrays[i];
742
+ res.set(a, pad);
743
+ pad += a.length;
744
+ }
745
+ return res;
746
+ }
747
+ // Check if object doens't have custom constructor (like Uint8Array/Array)
748
+ const isPlainObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]' && obj.constructor === Object;
749
+ function checkOpts(defaults, opts) {
750
+ if (opts !== undefined && (typeof opts !== 'object' || !isPlainObject(opts)))
751
+ throw new Error('options must be object or undefined');
752
+ const merged = Object.assign(defaults, opts);
753
+ return merged;
754
+ }
755
+ function ensureBytes(b, len) {
756
+ if (!isBytes$1(b))
757
+ throw new Error('Uint8Array expected');
758
+ if (typeof len === 'number')
759
+ if (b.length !== len)
760
+ throw new Error(`Uint8Array length ${len} expected`);
761
+ }
762
+ // Compares 2 u8a-s in kinda constant time
763
+ function equalBytes(a, b) {
764
+ if (a.length !== b.length)
765
+ return false;
766
+ let diff = 0;
767
+ for (let i = 0; i < a.length; i++)
768
+ diff |= a[i] ^ b[i];
769
+ return diff === 0;
770
+ }
771
+ const wrapCipher = (params, c) => {
772
+ Object.assign(c, params);
773
+ return c;
774
+ };
775
+ // Polyfill for Safari 14
776
+ function setBigUint64(view, byteOffset, value, isLE) {
777
+ if (typeof view.setBigUint64 === 'function')
778
+ return view.setBigUint64(byteOffset, value, isLE);
779
+ const _32n = BigInt(32);
780
+ const _u32_max = BigInt(0xffffffff);
781
+ const wh = Number((value >> _32n) & _u32_max);
782
+ const wl = Number(value & _u32_max);
783
+ const h = 4 ;
784
+ const l = 0 ;
785
+ view.setUint32(byteOffset + h, wh, isLE);
786
+ view.setUint32(byteOffset + l, wl, isLE);
787
+ }
788
+
789
+ function number(n) {
790
+ if (!Number.isSafeInteger(n) || n < 0)
791
+ throw new Error(`wrong positive integer: ${n}`);
792
+ }
793
+ function bool(b) {
794
+ if (typeof b !== 'boolean')
795
+ throw new Error(`boolean expected, not ${b}`);
796
+ }
797
+ // TODO: merge with utils
798
+ function isBytes(a) {
799
+ return (a != null &&
800
+ typeof a === 'object' &&
801
+ (a instanceof Uint8Array || a.constructor.name === 'Uint8Array'));
802
+ }
803
+ function bytes(b, ...lengths) {
804
+ if (!isBytes(b))
805
+ throw new Error('Uint8Array expected');
806
+ if (lengths.length > 0 && !lengths.includes(b.length))
807
+ throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);
808
+ }
809
+ function exists(instance, checkFinished = true) {
810
+ if (instance.destroyed)
811
+ throw new Error('Hash instance has been destroyed');
812
+ if (checkFinished && instance.finished)
813
+ throw new Error('Hash#digest() has already been called');
814
+ }
815
+ function output(out, instance) {
816
+ bytes(out);
817
+ const min = instance.outputLen;
818
+ if (out.length < min) {
819
+ throw new Error(`digestInto() expects output buffer of length at least ${min}`);
820
+ }
821
+ }
822
+
823
+ // Poly1305 is a fast and parallel secret-key message-authentication code.
824
+ // https://cr.yp.to/mac.html, https://cr.yp.to/mac/poly1305-20050329.pdf
825
+ // https://datatracker.ietf.org/doc/html/rfc8439
826
+ // Based on Public Domain poly1305-donna https://github.com/floodyberry/poly1305-donna
827
+ const u8to16 = (a, i) => (a[i++] & 0xff) | ((a[i++] & 0xff) << 8);
828
+ class Poly1305 {
829
+ constructor(key) {
830
+ this.blockLen = 16;
831
+ this.outputLen = 16;
832
+ this.buffer = new Uint8Array(16);
833
+ this.r = new Uint16Array(10);
834
+ this.h = new Uint16Array(10);
835
+ this.pad = new Uint16Array(8);
836
+ this.pos = 0;
837
+ this.finished = false;
838
+ key = toBytes(key);
839
+ ensureBytes(key, 32);
840
+ const t0 = u8to16(key, 0);
841
+ const t1 = u8to16(key, 2);
842
+ const t2 = u8to16(key, 4);
843
+ const t3 = u8to16(key, 6);
844
+ const t4 = u8to16(key, 8);
845
+ const t5 = u8to16(key, 10);
846
+ const t6 = u8to16(key, 12);
847
+ const t7 = u8to16(key, 14);
848
+ // https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47
849
+ this.r[0] = t0 & 0x1fff;
850
+ this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
851
+ this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
852
+ this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
853
+ this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
854
+ this.r[5] = (t4 >>> 1) & 0x1ffe;
855
+ this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
856
+ this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
857
+ this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
858
+ this.r[9] = (t7 >>> 5) & 0x007f;
859
+ for (let i = 0; i < 8; i++)
860
+ this.pad[i] = u8to16(key, 16 + 2 * i);
861
+ }
862
+ process(data, offset, isLast = false) {
863
+ const hibit = isLast ? 0 : 1 << 11;
864
+ const { h, r } = this;
865
+ const r0 = r[0];
866
+ const r1 = r[1];
867
+ const r2 = r[2];
868
+ const r3 = r[3];
869
+ const r4 = r[4];
870
+ const r5 = r[5];
871
+ const r6 = r[6];
872
+ const r7 = r[7];
873
+ const r8 = r[8];
874
+ const r9 = r[9];
875
+ const t0 = u8to16(data, offset + 0);
876
+ const t1 = u8to16(data, offset + 2);
877
+ const t2 = u8to16(data, offset + 4);
878
+ const t3 = u8to16(data, offset + 6);
879
+ const t4 = u8to16(data, offset + 8);
880
+ const t5 = u8to16(data, offset + 10);
881
+ const t6 = u8to16(data, offset + 12);
882
+ const t7 = u8to16(data, offset + 14);
883
+ let h0 = h[0] + (t0 & 0x1fff);
884
+ let h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff);
885
+ let h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff);
886
+ let h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff);
887
+ let h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff);
888
+ let h5 = h[5] + ((t4 >>> 1) & 0x1fff);
889
+ let h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff);
890
+ let h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff);
891
+ let h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff);
892
+ let h9 = h[9] + ((t7 >>> 5) | hibit);
893
+ let c = 0;
894
+ let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6);
895
+ c = d0 >>> 13;
896
+ d0 &= 0x1fff;
897
+ d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1);
898
+ c += d0 >>> 13;
899
+ d0 &= 0x1fff;
900
+ let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7);
901
+ c = d1 >>> 13;
902
+ d1 &= 0x1fff;
903
+ d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2);
904
+ c += d1 >>> 13;
905
+ d1 &= 0x1fff;
906
+ let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);
907
+ c = d2 >>> 13;
908
+ d2 &= 0x1fff;
909
+ d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3);
910
+ c += d2 >>> 13;
911
+ d2 &= 0x1fff;
912
+ let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);
913
+ c = d3 >>> 13;
914
+ d3 &= 0x1fff;
915
+ d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4);
916
+ c += d3 >>> 13;
917
+ d3 &= 0x1fff;
918
+ let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;
919
+ c = d4 >>> 13;
920
+ d4 &= 0x1fff;
921
+ d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5);
922
+ c += d4 >>> 13;
923
+ d4 &= 0x1fff;
924
+ let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;
925
+ c = d5 >>> 13;
926
+ d5 &= 0x1fff;
927
+ d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6);
928
+ c += d5 >>> 13;
929
+ d5 &= 0x1fff;
930
+ let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;
931
+ c = d6 >>> 13;
932
+ d6 &= 0x1fff;
933
+ d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);
934
+ c += d6 >>> 13;
935
+ d6 &= 0x1fff;
936
+ let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;
937
+ c = d7 >>> 13;
938
+ d7 &= 0x1fff;
939
+ d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);
940
+ c += d7 >>> 13;
941
+ d7 &= 0x1fff;
942
+ let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;
943
+ c = d8 >>> 13;
944
+ d8 &= 0x1fff;
945
+ d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);
946
+ c += d8 >>> 13;
947
+ d8 &= 0x1fff;
948
+ let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;
949
+ c = d9 >>> 13;
950
+ d9 &= 0x1fff;
951
+ d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;
952
+ c += d9 >>> 13;
953
+ d9 &= 0x1fff;
954
+ c = ((c << 2) + c) | 0;
955
+ c = (c + d0) | 0;
956
+ d0 = c & 0x1fff;
957
+ c = c >>> 13;
958
+ d1 += c;
959
+ h[0] = d0;
960
+ h[1] = d1;
961
+ h[2] = d2;
962
+ h[3] = d3;
963
+ h[4] = d4;
964
+ h[5] = d5;
965
+ h[6] = d6;
966
+ h[7] = d7;
967
+ h[8] = d8;
968
+ h[9] = d9;
969
+ }
970
+ finalize() {
971
+ const { h, pad } = this;
972
+ const g = new Uint16Array(10);
973
+ let c = h[1] >>> 13;
974
+ h[1] &= 0x1fff;
975
+ for (let i = 2; i < 10; i++) {
976
+ h[i] += c;
977
+ c = h[i] >>> 13;
978
+ h[i] &= 0x1fff;
979
+ }
980
+ h[0] += c * 5;
981
+ c = h[0] >>> 13;
982
+ h[0] &= 0x1fff;
983
+ h[1] += c;
984
+ c = h[1] >>> 13;
985
+ h[1] &= 0x1fff;
986
+ h[2] += c;
987
+ g[0] = h[0] + 5;
988
+ c = g[0] >>> 13;
989
+ g[0] &= 0x1fff;
990
+ for (let i = 1; i < 10; i++) {
991
+ g[i] = h[i] + c;
992
+ c = g[i] >>> 13;
993
+ g[i] &= 0x1fff;
994
+ }
995
+ g[9] -= 1 << 13;
996
+ let mask = (c ^ 1) - 1;
997
+ for (let i = 0; i < 10; i++)
998
+ g[i] &= mask;
999
+ mask = ~mask;
1000
+ for (let i = 0; i < 10; i++)
1001
+ h[i] = (h[i] & mask) | g[i];
1002
+ h[0] = (h[0] | (h[1] << 13)) & 0xffff;
1003
+ h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff;
1004
+ h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff;
1005
+ h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff;
1006
+ h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff;
1007
+ h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff;
1008
+ h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff;
1009
+ h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff;
1010
+ let f = h[0] + pad[0];
1011
+ h[0] = f & 0xffff;
1012
+ for (let i = 1; i < 8; i++) {
1013
+ f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0;
1014
+ h[i] = f & 0xffff;
1015
+ }
1016
+ }
1017
+ update(data) {
1018
+ exists(this);
1019
+ const { buffer, blockLen } = this;
1020
+ data = toBytes(data);
1021
+ const len = data.length;
1022
+ for (let pos = 0; pos < len;) {
1023
+ const take = Math.min(blockLen - this.pos, len - pos);
1024
+ // Fast path: we have at least one block in input
1025
+ if (take === blockLen) {
1026
+ for (; blockLen <= len - pos; pos += blockLen)
1027
+ this.process(data, pos);
1028
+ continue;
1029
+ }
1030
+ buffer.set(data.subarray(pos, pos + take), this.pos);
1031
+ this.pos += take;
1032
+ pos += take;
1033
+ if (this.pos === blockLen) {
1034
+ this.process(buffer, 0, false);
1035
+ this.pos = 0;
1036
+ }
1037
+ }
1038
+ return this;
1039
+ }
1040
+ destroy() {
1041
+ this.h.fill(0);
1042
+ this.r.fill(0);
1043
+ this.buffer.fill(0);
1044
+ this.pad.fill(0);
1045
+ }
1046
+ digestInto(out) {
1047
+ exists(this);
1048
+ output(out, this);
1049
+ this.finished = true;
1050
+ const { buffer, h } = this;
1051
+ let { pos } = this;
1052
+ if (pos) {
1053
+ buffer[pos++] = 1;
1054
+ // buffer.subarray(pos).fill(0);
1055
+ for (; pos < 16; pos++)
1056
+ buffer[pos] = 0;
1057
+ this.process(buffer, 0, true);
1058
+ }
1059
+ this.finalize();
1060
+ let opos = 0;
1061
+ for (let i = 0; i < 8; i++) {
1062
+ out[opos++] = h[i] >>> 0;
1063
+ out[opos++] = h[i] >>> 8;
1064
+ }
1065
+ return out;
1066
+ }
1067
+ digest() {
1068
+ const { buffer, outputLen } = this;
1069
+ this.digestInto(buffer);
1070
+ const res = buffer.slice(0, outputLen);
1071
+ this.destroy();
1072
+ return res;
1073
+ }
1074
+ }
1075
+ function wrapConstructorWithKey(hashCons) {
1076
+ const hashC = (msg, key) => hashCons(key).update(toBytes(msg)).digest();
1077
+ const tmp = hashCons(new Uint8Array(32));
1078
+ hashC.outputLen = tmp.outputLen;
1079
+ hashC.blockLen = tmp.blockLen;
1080
+ hashC.create = (key) => hashCons(key);
1081
+ return hashC;
1082
+ }
1083
+ const poly1305 = wrapConstructorWithKey((key) => new Poly1305(key));
1084
+
1085
+ // Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.
1086
+ /*
1087
+ RFC8439 requires multi-step cipher stream, where
1088
+ authKey starts with counter: 0, actual msg with counter: 1.
1089
+
1090
+ For this, we need a way to re-use nonce / counter:
1091
+
1092
+ const counter = new Uint8Array(4);
1093
+ chacha(..., counter, ...); // counter is now 1
1094
+ chacha(..., counter, ...); // counter is now 2
1095
+
1096
+ This is complicated:
1097
+
1098
+ - 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB
1099
+ - Original papers don't allow mutating counters
1100
+ - Counter overflow is undefined [^1]
1101
+ - Idea A: allow providing (nonce | counter) instead of just nonce, re-use it
1102
+ - Caveat: Cannot be re-used through all cases:
1103
+ - * chacha has (counter | nonce)
1104
+ - * xchacha has (nonce16 | counter | nonce16)
1105
+ - Idea B: separate nonce / counter and provide separate API for counter re-use
1106
+ - Caveat: there are different counter sizes depending on an algorithm.
1107
+ - salsa & chacha also differ in structures of key & sigma:
1108
+ salsa20: s[0] | k(4) | s[1] | nonce(2) | ctr(2) | s[2] | k(4) | s[3]
1109
+ chacha: s(4) | k(8) | ctr(1) | nonce(3)
1110
+ chacha20orig: s(4) | k(8) | ctr(2) | nonce(2)
1111
+ - Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`
1112
+ - Caveat: we can't re-use counter array
1113
+
1114
+ xchacha [^2] uses the subkey and remaining 8 byte nonce with ChaCha20 as normal
1115
+ (prefixed by 4 NUL bytes, since [RFC8439] specifies a 12-byte nonce).
1116
+
1117
+ [^1]: https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/
1118
+ [^2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2
1119
+ */
1120
+ const sigma16 = utf8ToBytes('expand 16-byte k');
1121
+ const sigma32 = utf8ToBytes('expand 32-byte k');
1122
+ const sigma16_32 = u32(sigma16);
1123
+ const sigma32_32 = u32(sigma32);
1124
+ function rotl(a, b) {
1125
+ return (a << b) | (a >>> (32 - b));
1126
+ }
1127
+ // Is byte array aligned to 4 byte offset (u32)?
1128
+ function isAligned32(b) {
1129
+ return b.byteOffset % 4 === 0;
1130
+ }
1131
+ // Salsa and Chacha block length is always 512-bit
1132
+ const BLOCK_LEN = 64;
1133
+ const BLOCK_LEN32 = 16;
1134
+ // new Uint32Array([2**32]) // => Uint32Array(1) [ 0 ]
1135
+ // new Uint32Array([2**32-1]) // => Uint32Array(1) [ 4294967295 ]
1136
+ const MAX_COUNTER = 2 ** 32 - 1;
1137
+ const U32_EMPTY = new Uint32Array();
1138
+ function runCipher(core, sigma, key, nonce, data, output, counter, rounds) {
1139
+ const len = data.length;
1140
+ const block = new Uint8Array(BLOCK_LEN);
1141
+ const b32 = u32(block);
1142
+ // Make sure that buffers aligned to 4 bytes
1143
+ const isAligned = isAligned32(data) && isAligned32(output);
1144
+ const d32 = isAligned ? u32(data) : U32_EMPTY;
1145
+ const o32 = isAligned ? u32(output) : U32_EMPTY;
1146
+ for (let pos = 0; pos < len; counter++) {
1147
+ core(sigma, key, nonce, b32, counter, rounds);
1148
+ if (counter >= MAX_COUNTER)
1149
+ throw new Error('arx: counter overflow');
1150
+ const take = Math.min(BLOCK_LEN, len - pos);
1151
+ // aligned to 4 bytes
1152
+ if (isAligned && take === BLOCK_LEN) {
1153
+ const pos32 = pos / 4;
1154
+ if (pos % 4 !== 0)
1155
+ throw new Error('arx: invalid block position');
1156
+ for (let j = 0, posj; j < BLOCK_LEN32; j++) {
1157
+ posj = pos32 + j;
1158
+ o32[posj] = d32[posj] ^ b32[j];
1159
+ }
1160
+ pos += BLOCK_LEN;
1161
+ continue;
1162
+ }
1163
+ for (let j = 0, posj; j < take; j++) {
1164
+ posj = pos + j;
1165
+ output[posj] = data[posj] ^ block[j];
1166
+ }
1167
+ pos += take;
1168
+ }
1169
+ }
1170
+ function createCipher(core, opts) {
1171
+ const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts);
1172
+ if (typeof core !== 'function')
1173
+ throw new Error('core must be a function');
1174
+ number(counterLength);
1175
+ number(rounds);
1176
+ bool(counterRight);
1177
+ bool(allowShortKeys);
1178
+ return (key, nonce, data, output, counter = 0) => {
1179
+ bytes(key);
1180
+ bytes(nonce);
1181
+ bytes(data);
1182
+ const len = data.length;
1183
+ if (!output)
1184
+ output = new Uint8Array(len);
1185
+ bytes(output);
1186
+ number(counter);
1187
+ if (counter < 0 || counter >= MAX_COUNTER)
1188
+ throw new Error('arx: counter overflow');
1189
+ if (output.length < len)
1190
+ throw new Error(`arx: output (${output.length}) is shorter than data (${len})`);
1191
+ const toClean = [];
1192
+ // Key & sigma
1193
+ // key=16 -> sigma16, k=key|key
1194
+ // key=32 -> sigma32, k=key
1195
+ let l = key.length, k, sigma;
1196
+ if (l === 32) {
1197
+ k = key.slice();
1198
+ toClean.push(k);
1199
+ sigma = sigma32_32;
1200
+ }
1201
+ else if (l === 16 && allowShortKeys) {
1202
+ k = new Uint8Array(32);
1203
+ k.set(key);
1204
+ k.set(key, 16);
1205
+ sigma = sigma16_32;
1206
+ toClean.push(k);
1207
+ }
1208
+ else {
1209
+ throw new Error(`arx: invalid 32-byte key, got length=${l}`);
1210
+ }
1211
+ // Nonce
1212
+ // salsa20: 8 (8-byte counter)
1213
+ // chacha20orig: 8 (8-byte counter)
1214
+ // chacha20: 12 (4-byte counter)
1215
+ // xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)
1216
+ // xchacha20: 24 (16 -> hchacha, 8 -> old nonce)
1217
+ // Align nonce to 4 bytes
1218
+ if (!isAligned32(nonce)) {
1219
+ nonce = nonce.slice();
1220
+ toClean.push(nonce);
1221
+ }
1222
+ const k32 = u32(k);
1223
+ // hsalsa & hchacha: handle extended nonce
1224
+ if (extendNonceFn) {
1225
+ if (nonce.length !== 24)
1226
+ throw new Error(`arx: extended nonce must be 24 bytes`);
1227
+ extendNonceFn(sigma, k32, u32(nonce.subarray(0, 16)), k32);
1228
+ nonce = nonce.subarray(16);
1229
+ }
1230
+ // Handle nonce counter
1231
+ const nonceNcLen = 16 - counterLength;
1232
+ if (nonceNcLen !== nonce.length)
1233
+ throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);
1234
+ // Pad counter when nonce is 64 bit
1235
+ if (nonceNcLen !== 12) {
1236
+ const nc = new Uint8Array(12);
1237
+ nc.set(nonce, counterRight ? 0 : 12 - nonce.length);
1238
+ nonce = nc;
1239
+ toClean.push(nonce);
1240
+ }
1241
+ const n32 = u32(nonce);
1242
+ runCipher(core, sigma, k32, n32, data, output, counter, rounds);
1243
+ while (toClean.length > 0)
1244
+ toClean.pop().fill(0);
1245
+ return output;
1246
+ };
1247
+ }
1248
+
1249
+ // ChaCha20 stream cipher was released in 2008. ChaCha aims to increase
1250
+ // the diffusion per round, but had slightly less cryptanalysis.
1251
+ // https://cr.yp.to/chacha.html, http://cr.yp.to/chacha/chacha-20080128.pdf
1252
+ /**
1253
+ * ChaCha core function.
1254
+ */
1255
+ // prettier-ignore
1256
+ function chachaCore(s, k, n, out, cnt, rounds = 20) {
1257
+ let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // "expa" "nd 3" "2-by" "te k"
1258
+ y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key
1259
+ y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key
1260
+ y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Counter Nonce Nonce
1261
+ // Save state to temporary variables
1262
+ let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
1263
+ for (let r = 0; r < rounds; r += 2) {
1264
+ x00 = (x00 + x04) | 0;
1265
+ x12 = rotl(x12 ^ x00, 16);
1266
+ x08 = (x08 + x12) | 0;
1267
+ x04 = rotl(x04 ^ x08, 12);
1268
+ x00 = (x00 + x04) | 0;
1269
+ x12 = rotl(x12 ^ x00, 8);
1270
+ x08 = (x08 + x12) | 0;
1271
+ x04 = rotl(x04 ^ x08, 7);
1272
+ x01 = (x01 + x05) | 0;
1273
+ x13 = rotl(x13 ^ x01, 16);
1274
+ x09 = (x09 + x13) | 0;
1275
+ x05 = rotl(x05 ^ x09, 12);
1276
+ x01 = (x01 + x05) | 0;
1277
+ x13 = rotl(x13 ^ x01, 8);
1278
+ x09 = (x09 + x13) | 0;
1279
+ x05 = rotl(x05 ^ x09, 7);
1280
+ x02 = (x02 + x06) | 0;
1281
+ x14 = rotl(x14 ^ x02, 16);
1282
+ x10 = (x10 + x14) | 0;
1283
+ x06 = rotl(x06 ^ x10, 12);
1284
+ x02 = (x02 + x06) | 0;
1285
+ x14 = rotl(x14 ^ x02, 8);
1286
+ x10 = (x10 + x14) | 0;
1287
+ x06 = rotl(x06 ^ x10, 7);
1288
+ x03 = (x03 + x07) | 0;
1289
+ x15 = rotl(x15 ^ x03, 16);
1290
+ x11 = (x11 + x15) | 0;
1291
+ x07 = rotl(x07 ^ x11, 12);
1292
+ x03 = (x03 + x07) | 0;
1293
+ x15 = rotl(x15 ^ x03, 8);
1294
+ x11 = (x11 + x15) | 0;
1295
+ x07 = rotl(x07 ^ x11, 7);
1296
+ x00 = (x00 + x05) | 0;
1297
+ x15 = rotl(x15 ^ x00, 16);
1298
+ x10 = (x10 + x15) | 0;
1299
+ x05 = rotl(x05 ^ x10, 12);
1300
+ x00 = (x00 + x05) | 0;
1301
+ x15 = rotl(x15 ^ x00, 8);
1302
+ x10 = (x10 + x15) | 0;
1303
+ x05 = rotl(x05 ^ x10, 7);
1304
+ x01 = (x01 + x06) | 0;
1305
+ x12 = rotl(x12 ^ x01, 16);
1306
+ x11 = (x11 + x12) | 0;
1307
+ x06 = rotl(x06 ^ x11, 12);
1308
+ x01 = (x01 + x06) | 0;
1309
+ x12 = rotl(x12 ^ x01, 8);
1310
+ x11 = (x11 + x12) | 0;
1311
+ x06 = rotl(x06 ^ x11, 7);
1312
+ x02 = (x02 + x07) | 0;
1313
+ x13 = rotl(x13 ^ x02, 16);
1314
+ x08 = (x08 + x13) | 0;
1315
+ x07 = rotl(x07 ^ x08, 12);
1316
+ x02 = (x02 + x07) | 0;
1317
+ x13 = rotl(x13 ^ x02, 8);
1318
+ x08 = (x08 + x13) | 0;
1319
+ x07 = rotl(x07 ^ x08, 7);
1320
+ x03 = (x03 + x04) | 0;
1321
+ x14 = rotl(x14 ^ x03, 16);
1322
+ x09 = (x09 + x14) | 0;
1323
+ x04 = rotl(x04 ^ x09, 12);
1324
+ x03 = (x03 + x04) | 0;
1325
+ x14 = rotl(x14 ^ x03, 8);
1326
+ x09 = (x09 + x14) | 0;
1327
+ x04 = rotl(x04 ^ x09, 7);
1328
+ }
1329
+ // Write output
1330
+ let oi = 0;
1331
+ out[oi++] = (y00 + x00) | 0;
1332
+ out[oi++] = (y01 + x01) | 0;
1333
+ out[oi++] = (y02 + x02) | 0;
1334
+ out[oi++] = (y03 + x03) | 0;
1335
+ out[oi++] = (y04 + x04) | 0;
1336
+ out[oi++] = (y05 + x05) | 0;
1337
+ out[oi++] = (y06 + x06) | 0;
1338
+ out[oi++] = (y07 + x07) | 0;
1339
+ out[oi++] = (y08 + x08) | 0;
1340
+ out[oi++] = (y09 + x09) | 0;
1341
+ out[oi++] = (y10 + x10) | 0;
1342
+ out[oi++] = (y11 + x11) | 0;
1343
+ out[oi++] = (y12 + x12) | 0;
1344
+ out[oi++] = (y13 + x13) | 0;
1345
+ out[oi++] = (y14 + x14) | 0;
1346
+ out[oi++] = (y15 + x15) | 0;
1347
+ }
1348
+ /**
1349
+ * hchacha helper method, used primarily in xchacha, to hash
1350
+ * key and nonce into key' and nonce'.
1351
+ * Same as chachaCore, but there doesn't seem to be a way to move the block
1352
+ * out without 25% performance hit.
1353
+ */
1354
+ // prettier-ignore
1355
+ function hchacha(s, k, i, o32) {
1356
+ let x00 = s[0], x01 = s[1], x02 = s[2], x03 = s[3], x04 = k[0], x05 = k[1], x06 = k[2], x07 = k[3], x08 = k[4], x09 = k[5], x10 = k[6], x11 = k[7], x12 = i[0], x13 = i[1], x14 = i[2], x15 = i[3];
1357
+ for (let r = 0; r < 20; r += 2) {
1358
+ x00 = (x00 + x04) | 0;
1359
+ x12 = rotl(x12 ^ x00, 16);
1360
+ x08 = (x08 + x12) | 0;
1361
+ x04 = rotl(x04 ^ x08, 12);
1362
+ x00 = (x00 + x04) | 0;
1363
+ x12 = rotl(x12 ^ x00, 8);
1364
+ x08 = (x08 + x12) | 0;
1365
+ x04 = rotl(x04 ^ x08, 7);
1366
+ x01 = (x01 + x05) | 0;
1367
+ x13 = rotl(x13 ^ x01, 16);
1368
+ x09 = (x09 + x13) | 0;
1369
+ x05 = rotl(x05 ^ x09, 12);
1370
+ x01 = (x01 + x05) | 0;
1371
+ x13 = rotl(x13 ^ x01, 8);
1372
+ x09 = (x09 + x13) | 0;
1373
+ x05 = rotl(x05 ^ x09, 7);
1374
+ x02 = (x02 + x06) | 0;
1375
+ x14 = rotl(x14 ^ x02, 16);
1376
+ x10 = (x10 + x14) | 0;
1377
+ x06 = rotl(x06 ^ x10, 12);
1378
+ x02 = (x02 + x06) | 0;
1379
+ x14 = rotl(x14 ^ x02, 8);
1380
+ x10 = (x10 + x14) | 0;
1381
+ x06 = rotl(x06 ^ x10, 7);
1382
+ x03 = (x03 + x07) | 0;
1383
+ x15 = rotl(x15 ^ x03, 16);
1384
+ x11 = (x11 + x15) | 0;
1385
+ x07 = rotl(x07 ^ x11, 12);
1386
+ x03 = (x03 + x07) | 0;
1387
+ x15 = rotl(x15 ^ x03, 8);
1388
+ x11 = (x11 + x15) | 0;
1389
+ x07 = rotl(x07 ^ x11, 7);
1390
+ x00 = (x00 + x05) | 0;
1391
+ x15 = rotl(x15 ^ x00, 16);
1392
+ x10 = (x10 + x15) | 0;
1393
+ x05 = rotl(x05 ^ x10, 12);
1394
+ x00 = (x00 + x05) | 0;
1395
+ x15 = rotl(x15 ^ x00, 8);
1396
+ x10 = (x10 + x15) | 0;
1397
+ x05 = rotl(x05 ^ x10, 7);
1398
+ x01 = (x01 + x06) | 0;
1399
+ x12 = rotl(x12 ^ x01, 16);
1400
+ x11 = (x11 + x12) | 0;
1401
+ x06 = rotl(x06 ^ x11, 12);
1402
+ x01 = (x01 + x06) | 0;
1403
+ x12 = rotl(x12 ^ x01, 8);
1404
+ x11 = (x11 + x12) | 0;
1405
+ x06 = rotl(x06 ^ x11, 7);
1406
+ x02 = (x02 + x07) | 0;
1407
+ x13 = rotl(x13 ^ x02, 16);
1408
+ x08 = (x08 + x13) | 0;
1409
+ x07 = rotl(x07 ^ x08, 12);
1410
+ x02 = (x02 + x07) | 0;
1411
+ x13 = rotl(x13 ^ x02, 8);
1412
+ x08 = (x08 + x13) | 0;
1413
+ x07 = rotl(x07 ^ x08, 7);
1414
+ x03 = (x03 + x04) | 0;
1415
+ x14 = rotl(x14 ^ x03, 16);
1416
+ x09 = (x09 + x14) | 0;
1417
+ x04 = rotl(x04 ^ x09, 12);
1418
+ x03 = (x03 + x04) | 0;
1419
+ x14 = rotl(x14 ^ x03, 8);
1420
+ x09 = (x09 + x14) | 0;
1421
+ x04 = rotl(x04 ^ x09, 7);
1422
+ }
1423
+ let oi = 0;
1424
+ o32[oi++] = x00;
1425
+ o32[oi++] = x01;
1426
+ o32[oi++] = x02;
1427
+ o32[oi++] = x03;
1428
+ o32[oi++] = x12;
1429
+ o32[oi++] = x13;
1430
+ o32[oi++] = x14;
1431
+ o32[oi++] = x15;
1432
+ }
1433
+ /**
1434
+ * XChaCha eXtended-nonce ChaCha. 24-byte nonce.
1435
+ * With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
1436
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
1437
+ */
1438
+ const xchacha20 = /* @__PURE__ */ createCipher(chachaCore, {
1439
+ counterRight: false,
1440
+ counterLength: 8,
1441
+ extendNonceFn: hchacha,
1442
+ allowShortKeys: false,
1443
+ });
1444
+ const ZEROS16 = /* @__PURE__ */ new Uint8Array(16);
1445
+ // Pad to digest size with zeros
1446
+ const updatePadded = (h, msg) => {
1447
+ h.update(msg);
1448
+ const left = msg.length % 16;
1449
+ if (left)
1450
+ h.update(ZEROS16.subarray(left));
1451
+ };
1452
+ const ZEROS32 = /* @__PURE__ */ new Uint8Array(32);
1453
+ function computeTag(fn, key, nonce, data, AAD) {
1454
+ const authKey = fn(key, nonce, ZEROS32);
1455
+ const h = poly1305.create(authKey);
1456
+ if (AAD)
1457
+ updatePadded(h, AAD);
1458
+ updatePadded(h, data);
1459
+ const num = new Uint8Array(16);
1460
+ const view = createView(num);
1461
+ setBigUint64(view, 0, BigInt(AAD ? AAD.length : 0), true);
1462
+ setBigUint64(view, 8, BigInt(data.length), true);
1463
+ h.update(num);
1464
+ const res = h.digest();
1465
+ authKey.fill(0);
1466
+ return res;
1467
+ }
1468
+ /**
1469
+ * AEAD algorithm from RFC 8439.
1470
+ * Salsa20 and chacha (RFC 8439) use poly1305 differently.
1471
+ * We could have composed them similar to:
1472
+ * https://github.com/paulmillr/scure-base/blob/b266c73dde977b1dd7ef40ef7a23cc15aab526b3/index.ts#L250
1473
+ * But it's hard because of authKey:
1474
+ * In salsa20, authKey changes position in salsa stream.
1475
+ * In chacha, authKey can't be computed inside computeTag, it modifies the counter.
1476
+ */
1477
+ const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
1478
+ const tagLength = 16;
1479
+ ensureBytes(key, 32);
1480
+ ensureBytes(nonce);
1481
+ return {
1482
+ encrypt: (plaintext, output) => {
1483
+ const plength = plaintext.length;
1484
+ const clength = plength + tagLength;
1485
+ if (output) {
1486
+ ensureBytes(output, clength);
1487
+ }
1488
+ else {
1489
+ output = new Uint8Array(clength);
1490
+ }
1491
+ xorStream(key, nonce, plaintext, output, 1);
1492
+ const tag = computeTag(xorStream, key, nonce, output.subarray(0, -tagLength), AAD);
1493
+ output.set(tag, plength); // append tag
1494
+ return output;
1495
+ },
1496
+ decrypt: (ciphertext, output) => {
1497
+ const clength = ciphertext.length;
1498
+ const plength = clength - tagLength;
1499
+ if (clength < tagLength)
1500
+ throw new Error(`encrypted data must be at least ${tagLength} bytes`);
1501
+ if (output) {
1502
+ ensureBytes(output, plength);
1503
+ }
1504
+ else {
1505
+ output = new Uint8Array(plength);
1506
+ }
1507
+ const data = ciphertext.subarray(0, -tagLength);
1508
+ const passedTag = ciphertext.subarray(-tagLength);
1509
+ const tag = computeTag(xorStream, key, nonce, data, AAD);
1510
+ if (!equalBytes(passedTag, tag))
1511
+ throw new Error('invalid tag');
1512
+ xorStream(key, nonce, data, output, 1);
1513
+ return output;
1514
+ },
1515
+ };
1516
+ };
1517
+ /**
1518
+ * XChaCha20-Poly1305 extended-nonce chacha.
1519
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
1520
+ * With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
1521
+ */
1522
+ const xchacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, _poly1305_aead(xchacha20));
1523
+
1524
+ const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
1525
+
1526
+ // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
1527
+ // node.js versions earlier than v19 don't declare it in global scope.
1528
+ // For node.js, package.js on#exports field mapping rewrites import
1529
+ // from `crypto` to `cryptoNode`, which imports native module.
1530
+ // Makes the utils un-importable in browsers without a bundler.
1531
+ // Once node.js 18 is deprecated, we can just drop the import.
1532
+ /**
1533
+ * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
1534
+ */
1535
+ function randomBytes(bytesLength = 32) {
1536
+ if (crypto && typeof crypto.getRandomValues === 'function') {
1537
+ return crypto.getRandomValues(new Uint8Array(bytesLength));
1538
+ }
1539
+ throw new Error('crypto.getRandomValues must be defined');
1540
+ }
1541
+ // Uses CSPRG for nonce, nonce injected in ciphertext
1542
+ function managedNonce(fn) {
1543
+ number(fn.nonceLength);
1544
+ return ((key, ...args) => ({
1545
+ encrypt: (plaintext, ...argsEnc) => {
1546
+ const { nonceLength } = fn;
1547
+ const nonce = randomBytes(nonceLength);
1548
+ const ciphertext = fn(key, nonce, ...args).encrypt(plaintext, ...argsEnc);
1549
+ const out = concatBytes(nonce, ciphertext);
1550
+ ciphertext.fill(0);
1551
+ return out;
1552
+ },
1553
+ decrypt: (ciphertext, ...argsDec) => {
1554
+ const { nonceLength } = fn;
1555
+ const nonce = ciphertext.subarray(0, nonceLength);
1556
+ const data = ciphertext.subarray(nonceLength);
1557
+ return fn(key, nonce, ...args).decrypt(data, ...argsDec);
1558
+ },
1559
+ }));
1560
+ }
1561
+ // // Type tests
1562
+ // import { siv, gcm, ctr, ecb, cbc } from '../aes.js';
1563
+ // import { xsalsa20poly1305 } from '../salsa.js';
1564
+ // import { chacha20poly1305, xchacha20poly1305 } from '../chacha.js';
1565
+ // const wsiv = managedNonce(siv);
1566
+ // const wgcm = managedNonce(gcm);
1567
+ // const wctr = managedNonce(ctr);
1568
+ // const wcbc = managedNonce(cbc);
1569
+ // const wsalsapoly = managedNonce(xsalsa20poly1305);
1570
+ // const wchacha = managedNonce(chacha20poly1305);
1571
+ // const wxchacha = managedNonce(xchacha20poly1305);
1572
+ // // should fail
1573
+ // const wcbc2 = managedNonce(managedNonce(cbc));
1574
+ // const wecb = managedNonce(ecb);
1575
+
1576
+ const canonicalize = canonicalizeModule;
1577
+ // Polyfill for synchronous signatures
1578
+ secp__namespace.etc.hmacSha256Sync = (k, ...m) => hmac(sha256, k, secp__namespace.etc.concatBytes(...m));
1579
+ class CipherBase {
1580
+ generateMnemonic() {
1581
+ return bip39__namespace.generateMnemonic();
1582
+ }
1583
+ generateJwk(privateKeyBytes) {
1584
+ const compressedPublicKeyBytes = secp__namespace.getPublicKey(privateKeyBytes);
1585
+ const compressedPublicKeyHex = secp__namespace.etc.bytesToHex(compressedPublicKeyBytes);
1586
+ const curvePoints = secp__namespace.ProjectivePoint.fromHex(compressedPublicKeyHex);
1587
+ const uncompressedPublicKeyBytes = curvePoints.toRawBytes(false);
1588
+ const d = base64url.baseEncode(privateKeyBytes);
1589
+ const x = base64url.baseEncode(uncompressedPublicKeyBytes.subarray(1, 33));
1590
+ const y = base64url.baseEncode(uncompressedPublicKeyBytes.subarray(33, 65));
1591
+ const publicJwk = {
1592
+ kty: 'EC',
1593
+ crv: 'secp256k1',
1594
+ x,
1595
+ y
1596
+ };
1597
+ const privateJwk = { ...publicJwk, d };
1598
+ return { publicJwk, privateJwk };
1599
+ }
1600
+ generateRandomJwk() {
1601
+ const privKey = secp__namespace.utils.randomPrivateKey();
1602
+ return this.generateJwk(privKey);
1603
+ }
1604
+ convertJwkToCompressedBytes(jwk) {
1605
+ const xBytes = base64url.baseDecode(jwk.x);
1606
+ const yBytes = base64url.baseDecode(jwk.y);
1607
+ const prefix = yBytes[yBytes.length - 1] % 2 === 0 ? 0x02 : 0x03;
1608
+ return new Uint8Array([prefix, ...xBytes]);
1609
+ }
1610
+ hashMessage(msg) {
1611
+ const hash = sha256(msg);
1612
+ return Buffer.from(hash).toString('hex');
1613
+ }
1614
+ canonicalizeJSON(json) {
1615
+ return canonicalize(json);
1616
+ }
1617
+ hashJSON(json) {
1618
+ return this.hashMessage(this.canonicalizeJSON(json));
1619
+ }
1620
+ signHash(msgHash, privateJwk) {
1621
+ const privKey = base64url.baseDecode(privateJwk.d);
1622
+ const signature = secp__namespace.sign(msgHash, privKey);
1623
+ return signature.toCompactHex();
1624
+ }
1625
+ verifySig(msgHash, sigHex, publicJwk) {
1626
+ const compressedPublicKeyBytes = this.convertJwkToCompressedBytes(publicJwk);
1627
+ const signature = secp__namespace.Signature.fromCompact(sigHex);
1628
+ return secp__namespace.verify(signature, msgHash, compressedPublicKeyBytes);
1629
+ }
1630
+ encryptBytes(pubKey, privKey, data) {
1631
+ const priv = base64url.baseDecode(privKey.d);
1632
+ const pub = this.convertJwkToCompressedBytes(pubKey);
1633
+ const ss = secp__namespace.getSharedSecret(priv, pub);
1634
+ const key = ss.slice(0, 32);
1635
+ const chacha = managedNonce(xchacha20poly1305)(key);
1636
+ const ciphertext = chacha.encrypt(data);
1637
+ return base64url.baseEncode(ciphertext);
1638
+ }
1639
+ decryptBytes(pubKey, privKey, ciphertext) {
1640
+ const priv = base64url.baseDecode(privKey.d);
1641
+ const pub = this.convertJwkToCompressedBytes(pubKey);
1642
+ const ss = secp__namespace.getSharedSecret(priv, pub);
1643
+ const key = ss.slice(0, 32);
1644
+ const chacha = managedNonce(xchacha20poly1305)(key);
1645
+ const cipherdata = base64url.baseDecode(ciphertext);
1646
+ return chacha.decrypt(cipherdata);
1647
+ }
1648
+ encryptMessage(pubKey, privKey, message) {
1649
+ const data = utf8ToBytes(message);
1650
+ return this.encryptBytes(pubKey, privKey, data);
1651
+ }
1652
+ decryptMessage(pubKey, privKey, ciphertext) {
1653
+ const data = this.decryptBytes(pubKey, privKey, ciphertext);
1654
+ return bytesToUtf8(data);
1655
+ }
1656
+ hasLeadingZeroBits(hexHash, bits) {
1657
+ const binary = BigInt('0x' + hexHash).toString(2).padStart(hexHash.length * 4, '0');
1658
+ return binary.startsWith('0'.repeat(bits));
1659
+ }
1660
+ addProofOfWork(obj, difficulty) {
1661
+ if (!Number.isInteger(difficulty) || difficulty < 0 || difficulty > 256) {
1662
+ throw new Error('Invalid difficulty: must be an integer between 0 and 256.');
1663
+ }
1664
+ let nonce = 0;
1665
+ while (true) {
1666
+ const candidate = {
1667
+ ...obj,
1668
+ pow: {
1669
+ nonce: nonce.toString(16),
1670
+ difficulty,
1671
+ }
1672
+ };
1673
+ const hash = this.hashJSON(candidate);
1674
+ if (this.hasLeadingZeroBits(hash, difficulty)) {
1675
+ return candidate;
1676
+ }
1677
+ nonce++;
1678
+ }
1679
+ }
1680
+ checkProofOfWork(obj) {
1681
+ if (!obj ||
1682
+ typeof obj !== 'object' ||
1683
+ !('pow' in obj) ||
1684
+ typeof obj.pow !== 'object' ||
1685
+ typeof obj.pow.nonce !== 'string' ||
1686
+ typeof obj.pow.difficulty !== 'number') {
1687
+ return false;
1688
+ }
1689
+ const hash = this.hashJSON(obj);
1690
+ return this.hasLeadingZeroBits(hash, obj.pow.difficulty);
1691
+ }
1692
+ }
1693
+
1694
+ exports.CipherBase = CipherBase;
1695
+ exports.base64url = base64url;