@didcid/cipher 0.1.3 → 0.2.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.
@@ -2,6 +2,7 @@
2
2
 
3
3
  var bip39 = require('bip39');
4
4
  var secp = require('@noble/secp256k1');
5
+ var aes = require('./aes-B3jnKULi.cjs');
5
6
  var canonicalizeModule = require('canonicalize');
6
7
 
7
8
  function _interopNamespaceDefault(e) {
@@ -244,435 +245,6 @@ rfc4648({
244
245
  bitsPerChar: 6
245
246
  });
246
247
 
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
248
  /**
677
249
  * SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
678
250
  *
@@ -684,141 +256,7 @@ const sha256$1 = /* @__PURE__ */ createHasher(() => new SHA256());
684
256
  * @deprecated
685
257
  */
686
258
  /** @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
- }
259
+ const sha256 = aes.sha256;
822
260
 
823
261
  // Poly1305 is a fast and parallel secret-key message-authentication code.
824
262
  // https://cr.yp.to/mac.html, https://cr.yp.to/mac/poly1305-20050329.pdf
@@ -835,8 +273,8 @@ class Poly1305 {
835
273
  this.pad = new Uint16Array(8);
836
274
  this.pos = 0;
837
275
  this.finished = false;
838
- key = toBytes(key);
839
- ensureBytes(key, 32);
276
+ key = aes.toBytes(key);
277
+ aes.ensureBytes(key, 32);
840
278
  const t0 = u8to16(key, 0);
841
279
  const t1 = u8to16(key, 2);
842
280
  const t2 = u8to16(key, 4);
@@ -1015,9 +453,9 @@ class Poly1305 {
1015
453
  }
1016
454
  }
1017
455
  update(data) {
1018
- exists(this);
456
+ aes.exists(this);
1019
457
  const { buffer, blockLen } = this;
1020
- data = toBytes(data);
458
+ data = aes.toBytes(data);
1021
459
  const len = data.length;
1022
460
  for (let pos = 0; pos < len;) {
1023
461
  const take = Math.min(blockLen - this.pos, len - pos);
@@ -1044,8 +482,8 @@ class Poly1305 {
1044
482
  this.pad.fill(0);
1045
483
  }
1046
484
  digestInto(out) {
1047
- exists(this);
1048
- output(out, this);
485
+ aes.exists(this);
486
+ aes.output(out, this);
1049
487
  this.finished = true;
1050
488
  const { buffer, h } = this;
1051
489
  let { pos } = this;
@@ -1073,7 +511,7 @@ class Poly1305 {
1073
511
  }
1074
512
  }
1075
513
  function wrapConstructorWithKey(hashCons) {
1076
- const hashC = (msg, key) => hashCons(key).update(toBytes(msg)).digest();
514
+ const hashC = (msg, key) => hashCons(key).update(aes.toBytes(msg)).digest();
1077
515
  const tmp = hashCons(new Uint8Array(32));
1078
516
  hashC.outputLen = tmp.outputLen;
1079
517
  hashC.blockLen = tmp.blockLen;
@@ -1117,10 +555,10 @@ xchacha [^2] uses the subkey and remaining 8 byte nonce with ChaCha20 as normal
1117
555
  [^1]: https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/
1118
556
  [^2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2
1119
557
  */
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);
558
+ const sigma16 = aes.utf8ToBytes('expand 16-byte k');
559
+ const sigma32 = aes.utf8ToBytes('expand 32-byte k');
560
+ const sigma16_32 = aes.u32(sigma16);
561
+ const sigma32_32 = aes.u32(sigma32);
1124
562
  function rotl(a, b) {
1125
563
  return (a << b) | (a >>> (32 - b));
1126
564
  }
@@ -1138,11 +576,11 @@ const U32_EMPTY = new Uint32Array();
1138
576
  function runCipher(core, sigma, key, nonce, data, output, counter, rounds) {
1139
577
  const len = data.length;
1140
578
  const block = new Uint8Array(BLOCK_LEN);
1141
- const b32 = u32(block);
579
+ const b32 = aes.u32(block);
1142
580
  // Make sure that buffers aligned to 4 bytes
1143
581
  const isAligned = isAligned32(data) && isAligned32(output);
1144
- const d32 = isAligned ? u32(data) : U32_EMPTY;
1145
- const o32 = isAligned ? u32(output) : U32_EMPTY;
582
+ const d32 = isAligned ? aes.u32(data) : U32_EMPTY;
583
+ const o32 = isAligned ? aes.u32(output) : U32_EMPTY;
1146
584
  for (let pos = 0; pos < len; counter++) {
1147
585
  core(sigma, key, nonce, b32, counter, rounds);
1148
586
  if (counter >= MAX_COUNTER)
@@ -1168,22 +606,22 @@ function runCipher(core, sigma, key, nonce, data, output, counter, rounds) {
1168
606
  }
1169
607
  }
1170
608
  function createCipher(core, opts) {
1171
- const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts);
609
+ const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = aes.checkOpts({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts);
1172
610
  if (typeof core !== 'function')
1173
611
  throw new Error('core must be a function');
1174
- number(counterLength);
1175
- number(rounds);
1176
- bool(counterRight);
1177
- bool(allowShortKeys);
612
+ aes.number(counterLength);
613
+ aes.number(rounds);
614
+ aes.bool(counterRight);
615
+ aes.bool(allowShortKeys);
1178
616
  return (key, nonce, data, output, counter = 0) => {
1179
- bytes(key);
1180
- bytes(nonce);
1181
- bytes(data);
617
+ aes.bytes(key);
618
+ aes.bytes(nonce);
619
+ aes.bytes(data);
1182
620
  const len = data.length;
1183
621
  if (!output)
1184
622
  output = new Uint8Array(len);
1185
- bytes(output);
1186
- number(counter);
623
+ aes.bytes(output);
624
+ aes.number(counter);
1187
625
  if (counter < 0 || counter >= MAX_COUNTER)
1188
626
  throw new Error('arx: counter overflow');
1189
627
  if (output.length < len)
@@ -1219,12 +657,12 @@ function createCipher(core, opts) {
1219
657
  nonce = nonce.slice();
1220
658
  toClean.push(nonce);
1221
659
  }
1222
- const k32 = u32(k);
660
+ const k32 = aes.u32(k);
1223
661
  // hsalsa & hchacha: handle extended nonce
1224
662
  if (extendNonceFn) {
1225
663
  if (nonce.length !== 24)
1226
664
  throw new Error(`arx: extended nonce must be 24 bytes`);
1227
- extendNonceFn(sigma, k32, u32(nonce.subarray(0, 16)), k32);
665
+ extendNonceFn(sigma, k32, aes.u32(nonce.subarray(0, 16)), k32);
1228
666
  nonce = nonce.subarray(16);
1229
667
  }
1230
668
  // Handle nonce counter
@@ -1238,7 +676,7 @@ function createCipher(core, opts) {
1238
676
  nonce = nc;
1239
677
  toClean.push(nonce);
1240
678
  }
1241
- const n32 = u32(nonce);
679
+ const n32 = aes.u32(nonce);
1242
680
  runCipher(core, sigma, k32, n32, data, output, counter, rounds);
1243
681
  while (toClean.length > 0)
1244
682
  toClean.pop().fill(0);
@@ -1457,9 +895,9 @@ function computeTag(fn, key, nonce, data, AAD) {
1457
895
  updatePadded(h, AAD);
1458
896
  updatePadded(h, data);
1459
897
  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);
898
+ const view = aes.createView(num);
899
+ aes.setBigUint64(view, 0, BigInt(AAD ? AAD.length : 0), true);
900
+ aes.setBigUint64(view, 8, BigInt(data.length), true);
1463
901
  h.update(num);
1464
902
  const res = h.digest();
1465
903
  authKey.fill(0);
@@ -1476,14 +914,14 @@ function computeTag(fn, key, nonce, data, AAD) {
1476
914
  */
1477
915
  const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
1478
916
  const tagLength = 16;
1479
- ensureBytes(key, 32);
1480
- ensureBytes(nonce);
917
+ aes.ensureBytes(key, 32);
918
+ aes.ensureBytes(nonce);
1481
919
  return {
1482
920
  encrypt: (plaintext, output) => {
1483
921
  const plength = plaintext.length;
1484
922
  const clength = plength + tagLength;
1485
923
  if (output) {
1486
- ensureBytes(output, clength);
924
+ aes.ensureBytes(output, clength);
1487
925
  }
1488
926
  else {
1489
927
  output = new Uint8Array(clength);
@@ -1499,7 +937,7 @@ const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
1499
937
  if (clength < tagLength)
1500
938
  throw new Error(`encrypted data must be at least ${tagLength} bytes`);
1501
939
  if (output) {
1502
- ensureBytes(output, plength);
940
+ aes.ensureBytes(output, plength);
1503
941
  }
1504
942
  else {
1505
943
  output = new Uint8Array(plength);
@@ -1507,7 +945,7 @@ const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
1507
945
  const data = ciphertext.subarray(0, -tagLength);
1508
946
  const passedTag = ciphertext.subarray(-tagLength);
1509
947
  const tag = computeTag(xorStream, key, nonce, data, AAD);
1510
- if (!equalBytes(passedTag, tag))
948
+ if (!aes.equalBytes(passedTag, tag))
1511
949
  throw new Error('invalid tag');
1512
950
  xorStream(key, nonce, data, output, 1);
1513
951
  return output;
@@ -1519,7 +957,7 @@ const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
1519
957
  * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
1520
958
  * With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
1521
959
  */
1522
- const xchacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, _poly1305_aead(xchacha20));
960
+ const xchacha20poly1305 = /* @__PURE__ */ aes.wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, _poly1305_aead(xchacha20));
1523
961
 
1524
962
  const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
1525
963
 
@@ -1540,13 +978,13 @@ function randomBytes(bytesLength = 32) {
1540
978
  }
1541
979
  // Uses CSPRG for nonce, nonce injected in ciphertext
1542
980
  function managedNonce(fn) {
1543
- number(fn.nonceLength);
981
+ aes.number(fn.nonceLength);
1544
982
  return ((key, ...args) => ({
1545
983
  encrypt: (plaintext, ...argsEnc) => {
1546
984
  const { nonceLength } = fn;
1547
985
  const nonce = randomBytes(nonceLength);
1548
986
  const ciphertext = fn(key, nonce, ...args).encrypt(plaintext, ...argsEnc);
1549
- const out = concatBytes(nonce, ciphertext);
987
+ const out = aes.concatBytes(nonce, ciphertext);
1550
988
  ciphertext.fill(0);
1551
989
  return out;
1552
990
  },
@@ -1573,9 +1011,180 @@ function managedNonce(fn) {
1573
1011
  // const wcbc2 = managedNonce(managedNonce(cbc));
1574
1012
  // const wecb = managedNonce(ecb);
1575
1013
 
1014
+ /**
1015
+ * Concat KDF (Single Step KDF) per NIST SP 800-56A and RFC 7518 §4.6.2.
1016
+ *
1017
+ * Derives a symmetric key from an ECDH shared secret for use in JWE.
1018
+ *
1019
+ * @param sharedSecret - The raw ECDH shared secret (Z)
1020
+ * @param keyBitLength - Desired key length in bits (e.g. 128, 256)
1021
+ * @param algorithmId - The "enc" value for ECDH-ES or "alg" for ECDH-ES+A*KW
1022
+ * @param apu - Agreement PartyUInfo (typically empty)
1023
+ * @param apv - Agreement PartyVInfo (typically empty)
1024
+ * @returns Derived key as Uint8Array
1025
+ */
1026
+ function concatKdf(sharedSecret, keyBitLength, algorithmId, apu = new Uint8Array(0), apv = new Uint8Array(0)) {
1027
+ const algIdBytes = new TextEncoder().encode(algorithmId);
1028
+ // Build otherInfo per RFC 7518 §4.6.2:
1029
+ // AlgorithmID = len(algId) || algId
1030
+ // PartyUInfo = len(apu) || apu
1031
+ // PartyVInfo = len(apv) || apv
1032
+ // SuppPubInfo = keydatalen (32-bit BE, in bits)
1033
+ const otherInfo = concatBytes(uint32BE(algIdBytes.length), algIdBytes, uint32BE(apu.length), apu, uint32BE(apv.length), apv, uint32BE(keyBitLength));
1034
+ const hashLength = 256; // SHA-256 output in bits
1035
+ const reps = Math.ceil(keyBitLength / hashLength);
1036
+ const result = new Uint8Array(reps * 32);
1037
+ for (let counter = 1; counter <= reps; counter++) {
1038
+ const input = concatBytes(uint32BE(counter), sharedSecret, otherInfo);
1039
+ const digest = sha256(input);
1040
+ result.set(digest, (counter - 1) * 32);
1041
+ }
1042
+ return result.slice(0, keyBitLength / 8);
1043
+ }
1044
+ function uint32BE(value) {
1045
+ const buf = new Uint8Array(4);
1046
+ buf[0] = (value >>> 24) & 0xff;
1047
+ buf[1] = (value >>> 16) & 0xff;
1048
+ buf[2] = (value >>> 8) & 0xff;
1049
+ buf[3] = value & 0xff;
1050
+ return buf;
1051
+ }
1052
+ function concatBytes(...arrays) {
1053
+ let totalLength = 0;
1054
+ for (const arr of arrays)
1055
+ totalLength += arr.length;
1056
+ const result = new Uint8Array(totalLength);
1057
+ let offset = 0;
1058
+ for (const arr of arrays) {
1059
+ result.set(arr, offset);
1060
+ offset += arr.length;
1061
+ }
1062
+ return result;
1063
+ }
1064
+
1065
+ const ENCODER = new TextEncoder();
1066
+ const DECODER = new TextDecoder();
1067
+ /**
1068
+ * Build a JWE Compact Serialization string using ECDH-ES + A256GCM.
1069
+ *
1070
+ * Uses an ephemeral secp256k1 keypair for key agreement.
1071
+ * The sender's identity key is NOT involved — only the recipient's public key.
1072
+ *
1073
+ * @param recipientPubKey - Recipient's public key (secp256k1 JWK)
1074
+ * @param plaintext - Data to encrypt
1075
+ * @returns JWE Compact string: header.encryptedKey.iv.ciphertext.tag
1076
+ */
1077
+ function buildJweCompact(recipientPubKey, plaintext) {
1078
+ // 1. Generate ephemeral keypair
1079
+ const ephemeralPrivKey = secp__namespace.utils.randomPrivateKey();
1080
+ const ephemeralPubKeyBytes = secp__namespace.getPublicKey(ephemeralPrivKey);
1081
+ // Get uncompressed public key coordinates for the JWE header
1082
+ const ephemeralPubHex = secp__namespace.etc.bytesToHex(ephemeralPubKeyBytes);
1083
+ const curvePoints = secp__namespace.ProjectivePoint.fromHex(ephemeralPubHex);
1084
+ const uncompressed = curvePoints.toRawBytes(false);
1085
+ const epkX = base64url.baseEncode(uncompressed.subarray(1, 33));
1086
+ const epkY = base64url.baseEncode(uncompressed.subarray(33, 65));
1087
+ // 2. Build protected header
1088
+ const header = {
1089
+ alg: 'ECDH-ES',
1090
+ enc: 'A256GCM',
1091
+ epk: {
1092
+ kty: 'EC',
1093
+ crv: 'secp256k1',
1094
+ x: epkX,
1095
+ y: epkY,
1096
+ },
1097
+ };
1098
+ const headerJson = JSON.stringify(header);
1099
+ const headerB64 = base64url.baseEncode(ENCODER.encode(headerJson));
1100
+ // 3. ECDH key agreement: ephemeral private + recipient public
1101
+ const recipientPubBytes = jwkToCompressedBytes(recipientPubKey);
1102
+ const sharedSecret = secp__namespace.getSharedSecret(ephemeralPrivKey, recipientPubBytes);
1103
+ // 4. Derive CEK via Concat KDF (RFC 7518 §4.6.2)
1104
+ // For ECDH-ES (direct), algorithmId = enc value
1105
+ const cek = concatKdf(sharedSecret.slice(1), 256, 'A256GCM');
1106
+ // 5. Generate random 96-bit IV
1107
+ const iv = secp__namespace.utils.randomPrivateKey().slice(0, 12);
1108
+ // 6. Encrypt with AES-256-GCM
1109
+ // AAD = ASCII bytes of the base64url-encoded protected header
1110
+ const aad = ENCODER.encode(headerB64);
1111
+ const cipher = aes.gcm(cek, iv, aad);
1112
+ const encrypted = cipher.encrypt(plaintext); // returns ciphertext || tag
1113
+ // 7. Split ciphertext and tag (tag is last 16 bytes)
1114
+ const ciphertext = encrypted.slice(0, encrypted.length - 16);
1115
+ const tag = encrypted.slice(encrypted.length - 16);
1116
+ // 8. Assemble JWE Compact: header.encryptedKey.iv.ciphertext.tag
1117
+ // For ECDH-ES (direct), encrypted key is empty
1118
+ return [
1119
+ headerB64,
1120
+ '', // empty encrypted key
1121
+ base64url.baseEncode(iv),
1122
+ base64url.baseEncode(ciphertext),
1123
+ base64url.baseEncode(tag),
1124
+ ].join('.');
1125
+ }
1126
+ /**
1127
+ * Parse and decrypt a JWE Compact Serialization string.
1128
+ *
1129
+ * @param recipientPrivKey - Recipient's private key (secp256k1 JWK)
1130
+ * @param jweCompact - The JWE Compact string to decrypt
1131
+ * @returns Decrypted plaintext
1132
+ */
1133
+ function parseJweCompact(recipientPrivKey, jweCompact) {
1134
+ // 1. Split into 5 parts
1135
+ const parts = jweCompact.split('.');
1136
+ if (parts.length !== 5) {
1137
+ throw new Error('Invalid JWE Compact: expected 5 segments');
1138
+ }
1139
+ const [headerB64, , ivB64, ciphertextB64, tagB64] = parts;
1140
+ // 2. Parse protected header
1141
+ const headerJson = DECODER.decode(base64url.baseDecode(headerB64));
1142
+ const header = JSON.parse(headerJson);
1143
+ if (header.alg !== 'ECDH-ES') {
1144
+ throw new Error(`Unsupported JWE alg: ${header.alg}`);
1145
+ }
1146
+ if (header.enc !== 'A256GCM') {
1147
+ throw new Error(`Unsupported JWE enc: ${header.enc}`);
1148
+ }
1149
+ // 3. Reconstruct ephemeral public key from header
1150
+ const epk = header.epk;
1151
+ const ephemeralPubBytes = jwkToCompressedBytes(epk);
1152
+ // 4. ECDH key agreement: recipient private + ephemeral public
1153
+ const recipientPrivBytes = base64url.baseDecode(recipientPrivKey.d);
1154
+ const sharedSecret = secp__namespace.getSharedSecret(recipientPrivBytes, ephemeralPubBytes);
1155
+ // 5. Derive CEK via Concat KDF
1156
+ const cek = concatKdf(sharedSecret.slice(1), 256, 'A256GCM');
1157
+ // 6. Decrypt with AES-256-GCM
1158
+ const iv = base64url.baseDecode(ivB64);
1159
+ const ciphertext = base64url.baseDecode(ciphertextB64);
1160
+ const tag = base64url.baseDecode(tagB64);
1161
+ // Reassemble ciphertext || tag for @noble/ciphers GCM
1162
+ const encrypted = new Uint8Array(ciphertext.length + tag.length);
1163
+ encrypted.set(ciphertext, 0);
1164
+ encrypted.set(tag, ciphertext.length);
1165
+ const aad = ENCODER.encode(headerB64);
1166
+ const cipher = aes.gcm(cek, iv, aad);
1167
+ return cipher.decrypt(encrypted);
1168
+ }
1169
+ /**
1170
+ * Detect whether a string is a JWE Compact Serialization.
1171
+ */
1172
+ function isJweCompact(ciphertext) {
1173
+ return ciphertext.startsWith('eyJ') && ciphertext.split('.').length === 5;
1174
+ }
1175
+ /**
1176
+ * Convert a JWK public key to compressed secp256k1 bytes.
1177
+ */
1178
+ function jwkToCompressedBytes(jwk) {
1179
+ const xBytes = base64url.baseDecode(jwk.x);
1180
+ const yBytes = base64url.baseDecode(jwk.y);
1181
+ const prefix = yBytes[yBytes.length - 1] % 2 === 0 ? 0x02 : 0x03;
1182
+ return new Uint8Array([prefix, ...xBytes]);
1183
+ }
1184
+
1576
1185
  const canonicalize = canonicalizeModule;
1577
1186
  // Polyfill for synchronous signatures
1578
- secp__namespace.etc.hmacSha256Sync = (k, ...m) => hmac(sha256, k, secp__namespace.etc.concatBytes(...m));
1187
+ secp__namespace.etc.hmacSha256Sync = (k, ...m) => aes.hmac(sha256, k, secp__namespace.etc.concatBytes(...m));
1579
1188
  class CipherBase {
1580
1189
  generateMnemonic() {
1581
1190
  return bip39__namespace.generateMnemonic();
@@ -1627,16 +1236,27 @@ class CipherBase {
1627
1236
  const signature = secp__namespace.Signature.fromCompact(sigHex);
1628
1237
  return secp__namespace.verify(signature, msgHash, compressedPublicKeyBytes);
1629
1238
  }
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);
1239
+ encryptBytes(recipientPubKey, data) {
1240
+ return buildJweCompact(recipientPubKey, data);
1638
1241
  }
1639
- decryptBytes(pubKey, privKey, ciphertext) {
1242
+ decryptBytes(recipientPrivKey, ciphertext, legacyPubKey) {
1243
+ if (isJweCompact(ciphertext)) {
1244
+ return parseJweCompact(recipientPrivKey, ciphertext);
1245
+ }
1246
+ if (legacyPubKey) {
1247
+ return this.decryptBytesLegacy(legacyPubKey, recipientPrivKey, ciphertext);
1248
+ }
1249
+ throw new Error('Cannot decrypt: not a JWE and no legacy public key provided. Pass legacyPubKey as the third argument for old ciphertext.');
1250
+ }
1251
+ encryptMessage(recipientPubKey, message) {
1252
+ const data = aes.utf8ToBytes(message);
1253
+ return this.encryptBytes(recipientPubKey, data);
1254
+ }
1255
+ decryptMessage(recipientPrivKey, ciphertext, legacyPubKey) {
1256
+ const data = this.decryptBytes(recipientPrivKey, ciphertext, legacyPubKey);
1257
+ return aes.bytesToUtf8(data);
1258
+ }
1259
+ decryptBytesLegacy(pubKey, privKey, ciphertext) {
1640
1260
  const priv = base64url.baseDecode(privKey.d);
1641
1261
  const pub = this.convertJwkToCompressedBytes(pubKey);
1642
1262
  const ss = secp__namespace.getSharedSecret(priv, pub);
@@ -1645,13 +1265,9 @@ class CipherBase {
1645
1265
  const cipherdata = base64url.baseDecode(ciphertext);
1646
1266
  return chacha.decrypt(cipherdata);
1647
1267
  }
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);
1268
+ decryptMessageLegacy(pubKey, privKey, ciphertext) {
1269
+ const data = this.decryptBytesLegacy(pubKey, privKey, ciphertext);
1270
+ return aes.bytesToUtf8(data);
1655
1271
  }
1656
1272
  hasLeadingZeroBits(hexHash, bits) {
1657
1273
  const binary = BigInt('0x' + hexHash).toString(2).padStart(hexHash.length * 4, '0');