@waku/enr 0.0.27-f599932.0 โ†’ 0.0.28-00f2e75.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.
package/bundle/index.js CHANGED
@@ -241,11 +241,12 @@ class Decoder {
241
241
  constructor(name, prefix, baseDecode) {
242
242
  this.name = name;
243
243
  this.prefix = prefix;
244
+ const prefixCodePoint = prefix.codePointAt(0);
244
245
  /* c8 ignore next 3 */
245
- if (prefix.codePointAt(0) === undefined) {
246
+ if (prefixCodePoint === undefined) {
246
247
  throw new Error('Invalid prefix character');
247
248
  }
248
- this.prefixCodePoint = prefix.codePointAt(0);
249
+ this.prefixCodePoint = prefixCodePoint;
249
250
  this.baseDecode = baseDecode;
250
251
  }
251
252
  decode(text) {
@@ -449,7 +450,14 @@ var base2$1 = /*#__PURE__*/Object.freeze({
449
450
 
450
451
  const alphabet = Array.from('๐Ÿš€๐Ÿชโ˜„๐Ÿ›ฐ๐ŸŒŒ๐ŸŒ‘๐ŸŒ’๐ŸŒ“๐ŸŒ”๐ŸŒ•๐ŸŒ–๐ŸŒ—๐ŸŒ˜๐ŸŒ๐ŸŒ๐ŸŒŽ๐Ÿ‰โ˜€๐Ÿ’ป๐Ÿ–ฅ๐Ÿ’พ๐Ÿ’ฟ๐Ÿ˜‚โค๐Ÿ˜๐Ÿคฃ๐Ÿ˜Š๐Ÿ™๐Ÿ’•๐Ÿ˜ญ๐Ÿ˜˜๐Ÿ‘๐Ÿ˜…๐Ÿ‘๐Ÿ˜๐Ÿ”ฅ๐Ÿฅฐ๐Ÿ’”๐Ÿ’–๐Ÿ’™๐Ÿ˜ข๐Ÿค”๐Ÿ˜†๐Ÿ™„๐Ÿ’ช๐Ÿ˜‰โ˜บ๐Ÿ‘Œ๐Ÿค—๐Ÿ’œ๐Ÿ˜”๐Ÿ˜Ž๐Ÿ˜‡๐ŸŒน๐Ÿคฆ๐ŸŽ‰๐Ÿ’žโœŒโœจ๐Ÿคท๐Ÿ˜ฑ๐Ÿ˜Œ๐ŸŒธ๐Ÿ™Œ๐Ÿ˜‹๐Ÿ’—๐Ÿ’š๐Ÿ˜๐Ÿ’›๐Ÿ™‚๐Ÿ’“๐Ÿคฉ๐Ÿ˜„๐Ÿ˜€๐Ÿ–ค๐Ÿ˜ƒ๐Ÿ’ฏ๐Ÿ™ˆ๐Ÿ‘‡๐ŸŽถ๐Ÿ˜’๐Ÿคญโฃ๐Ÿ˜œ๐Ÿ’‹๐Ÿ‘€๐Ÿ˜ช๐Ÿ˜‘๐Ÿ’ฅ๐Ÿ™‹๐Ÿ˜ž๐Ÿ˜ฉ๐Ÿ˜ก๐Ÿคช๐Ÿ‘Š๐Ÿฅณ๐Ÿ˜ฅ๐Ÿคค๐Ÿ‘‰๐Ÿ’ƒ๐Ÿ˜ณโœ‹๐Ÿ˜š๐Ÿ˜๐Ÿ˜ด๐ŸŒŸ๐Ÿ˜ฌ๐Ÿ™ƒ๐Ÿ€๐ŸŒท๐Ÿ˜ป๐Ÿ˜“โญโœ…๐Ÿฅบ๐ŸŒˆ๐Ÿ˜ˆ๐Ÿค˜๐Ÿ’ฆโœ”๐Ÿ˜ฃ๐Ÿƒ๐Ÿ’โ˜น๐ŸŽŠ๐Ÿ’˜๐Ÿ˜ โ˜๐Ÿ˜•๐ŸŒบ๐ŸŽ‚๐ŸŒป๐Ÿ˜๐Ÿ–•๐Ÿ’๐Ÿ™Š๐Ÿ˜น๐Ÿ—ฃ๐Ÿ’ซ๐Ÿ’€๐Ÿ‘‘๐ŸŽต๐Ÿคž๐Ÿ˜›๐Ÿ”ด๐Ÿ˜ค๐ŸŒผ๐Ÿ˜ซโšฝ๐Ÿค™โ˜•๐Ÿ†๐Ÿคซ๐Ÿ‘ˆ๐Ÿ˜ฎ๐Ÿ™†๐Ÿป๐Ÿƒ๐Ÿถ๐Ÿ’๐Ÿ˜ฒ๐ŸŒฟ๐Ÿงก๐ŸŽโšก๐ŸŒž๐ŸŽˆโŒโœŠ๐Ÿ‘‹๐Ÿ˜ฐ๐Ÿคจ๐Ÿ˜ถ๐Ÿค๐Ÿšถ๐Ÿ’ฐ๐Ÿ“๐Ÿ’ข๐ŸคŸ๐Ÿ™๐Ÿšจ๐Ÿ’จ๐Ÿคฌโœˆ๐ŸŽ€๐Ÿบ๐Ÿค“๐Ÿ˜™๐Ÿ’Ÿ๐ŸŒฑ๐Ÿ˜–๐Ÿ‘ถ๐Ÿฅดโ–ถโžกโ“๐Ÿ’Ž๐Ÿ’ธโฌ‡๐Ÿ˜จ๐ŸŒš๐Ÿฆ‹๐Ÿ˜ท๐Ÿ•บโš ๐Ÿ™…๐Ÿ˜Ÿ๐Ÿ˜ต๐Ÿ‘Ž๐Ÿคฒ๐Ÿค ๐Ÿคง๐Ÿ“Œ๐Ÿ”ต๐Ÿ’…๐Ÿง๐Ÿพ๐Ÿ’๐Ÿ˜—๐Ÿค‘๐ŸŒŠ๐Ÿคฏ๐Ÿทโ˜Ž๐Ÿ’ง๐Ÿ˜ฏ๐Ÿ’†๐Ÿ‘†๐ŸŽค๐Ÿ™‡๐Ÿ‘โ„๐ŸŒด๐Ÿ’ฃ๐Ÿธ๐Ÿ’Œ๐Ÿ“๐Ÿฅ€๐Ÿคข๐Ÿ‘…๐Ÿ’ก๐Ÿ’ฉ๐Ÿ‘๐Ÿ“ธ๐Ÿ‘ป๐Ÿค๐Ÿคฎ๐ŸŽผ๐Ÿฅต๐Ÿšฉ๐ŸŽ๐ŸŠ๐Ÿ‘ผ๐Ÿ’๐Ÿ“ฃ๐Ÿฅ‚');
451
452
  const alphabetBytesToChars = (alphabet.reduce((p, c, i) => { p[i] = c; return p; }, ([])));
452
- const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => { p[c.codePointAt(0)] = i; return p; }, ([])));
453
+ const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => {
454
+ const codePoint = c.codePointAt(0);
455
+ if (codePoint == null) {
456
+ throw new Error(`Invalid character: ${c}`);
457
+ }
458
+ p[codePoint] = i;
459
+ return p;
460
+ }, ([])));
453
461
  function encode$4(data) {
454
462
  return data.reduce((p, c) => {
455
463
  p += alphabetBytesToChars[c];
@@ -459,8 +467,12 @@ function encode$4(data) {
459
467
  function decode$5(str) {
460
468
  const byts = [];
461
469
  for (const char of str) {
462
- const byt = alphabetCharsToBytes[char.codePointAt(0)];
463
- if (byt === undefined) {
470
+ const codePoint = char.codePointAt(0);
471
+ if (codePoint == null) {
472
+ throw new Error(`Invalid character: ${char}`);
473
+ }
474
+ const byt = alphabetCharsToBytes[codePoint];
475
+ if (byt == null) {
464
476
  throw new Error(`Non-base256emoji character: ${char}`);
465
477
  }
466
478
  byts.push(byt);
@@ -643,7 +655,7 @@ new TextDecoder();
643
655
 
644
656
  /* eslint-disable */
645
657
  var encode_1 = encode$3;
646
- var MSB$1 = 0x80, REST$1 = 0x7F, MSBALL = ~REST$1, INT = Math.pow(2, 31);
658
+ var MSB$1 = 0x80, MSBALL = -128, INT = Math.pow(2, 31);
647
659
  /**
648
660
  * @param {number} num
649
661
  * @param {number[]} out
@@ -667,7 +679,7 @@ function encode$3(num, out, offset) {
667
679
  return out;
668
680
  }
669
681
  var decode$4 = read$1;
670
- var MSB$1$1 = 0x80, REST$1$1 = 0x7F;
682
+ var MSB$1$1 = 0x80, REST$1 = 0x7F;
671
683
  /**
672
684
  * @param {string | any[]} buf
673
685
  * @param {number} offset
@@ -682,8 +694,8 @@ function read$1(buf, offset) {
682
694
  }
683
695
  b = buf[counter++];
684
696
  res += shift < 28
685
- ? (b & REST$1$1) << shift
686
- : (b & REST$1$1) * Math.pow(2, shift);
697
+ ? (b & REST$1) << shift
698
+ : (b & REST$1) * Math.pow(2, shift);
687
699
  shift += 7;
688
700
  } while (b >= MSB$1$1);
689
701
  // @ts-ignore
@@ -733,7 +745,7 @@ function encodingLength$1(int) {
733
745
  /**
734
746
  * Creates a multihash digest.
735
747
  */
736
- function create$1(code, digest) {
748
+ function create(code, digest) {
737
749
  const size = digest.byteLength;
738
750
  const sizeOffset = encodingLength$1(code);
739
751
  const digestOffset = sizeOffset + encodingLength$1(size);
@@ -792,7 +804,7 @@ const code = 0x0;
792
804
  const name = 'identity';
793
805
  const encode$2 = coerce;
794
806
  function digest(input) {
795
- return create$1(code, encode$2(input));
807
+ return create(code, encode$2(input));
796
808
  }
797
809
  const identity = { code, name, encode: encode$2, digest };
798
810
 
@@ -816,9 +828,9 @@ class Hasher {
816
828
  if (input instanceof Uint8Array) {
817
829
  const result = this.encode(input);
818
830
  return result instanceof Uint8Array
819
- ? create$1(this.code, result)
831
+ ? create(this.code, result)
820
832
  /* c8 ignore next 1 */
821
- : result.then(digest => create$1(this.code, digest));
833
+ : result.then(digest => create(this.code, digest));
822
834
  }
823
835
  else {
824
836
  throw Error('Unknown type, must be binary type');
@@ -918,7 +930,7 @@ class CID {
918
930
  switch (this.version) {
919
931
  case 0: {
920
932
  const { code, digest } = this.multihash;
921
- const multihash = create$1(code, digest);
933
+ const multihash = create(code, digest);
922
934
  return (CID.createV1(this.code, multihash));
923
935
  }
924
936
  case 1: {
@@ -1148,9 +1160,13 @@ function parseCIDtoBytes(source, base) {
1148
1160
  const decoder = base ?? base32;
1149
1161
  return [base32.prefix, decoder.decode(source)];
1150
1162
  }
1163
+ case base36.prefix: {
1164
+ const decoder = base ?? base36;
1165
+ return [base36.prefix, decoder.decode(source)];
1166
+ }
1151
1167
  default: {
1152
1168
  if (base == null) {
1153
- throw Error('To parse non base32 or base58btc encoded CID multibase decoder must be provided');
1169
+ throw Error('To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided');
1154
1170
  }
1155
1171
  return [source[0], base.decode(source)];
1156
1172
  }
@@ -1570,10 +1586,10 @@ class JacobianPoint {
1570
1586
  const cond1 = window % 2 !== 0;
1571
1587
  const cond2 = wbits < 0;
1572
1588
  if (wbits === 0) {
1573
- f = f.add(constTimeNegate(cond1, precomputes[offset1]));
1589
+ f = f.add(constTimeNegate$1(cond1, precomputes[offset1]));
1574
1590
  }
1575
1591
  else {
1576
- p = p.add(constTimeNegate(cond2, precomputes[offset2]));
1592
+ p = p.add(constTimeNegate$1(cond2, precomputes[offset2]));
1577
1593
  }
1578
1594
  }
1579
1595
  return { p, f };
@@ -1586,8 +1602,8 @@ class JacobianPoint {
1586
1602
  const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
1587
1603
  let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
1588
1604
  let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
1589
- k1p = constTimeNegate(k1neg, k1p);
1590
- k2p = constTimeNegate(k2neg, k2p);
1605
+ k1p = constTimeNegate$1(k1neg, k1p);
1606
+ k2p = constTimeNegate$1(k2neg, k2p);
1591
1607
  k2p = new JacobianPoint(mod$1(k2p.x * endo.beta), k2p.y, k2p.z);
1592
1608
  point = k1p.add(k2p);
1593
1609
  fake = f1p.add(f2p);
@@ -1619,7 +1635,7 @@ class JacobianPoint {
1619
1635
  }
1620
1636
  JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n$7);
1621
1637
  JacobianPoint.ZERO = new JacobianPoint(_0n$5, _1n$7, _0n$5);
1622
- function constTimeNegate(condition, item) {
1638
+ function constTimeNegate$1(condition, item) {
1623
1639
  const neg = item.negate();
1624
1640
  return condition ? neg : item;
1625
1641
  }
@@ -3056,7 +3072,7 @@ async function sign$1(message, privateKey) {
3056
3072
  function keccak256(input) {
3057
3073
  return new Uint8Array(sha3.keccak256.arrayBuffer(input));
3058
3074
  }
3059
- function compressPublicKey$1(publicKey) {
3075
+ function compressPublicKey(publicKey) {
3060
3076
  if (publicKey.length === 64) {
3061
3077
  publicKey = concat$2([new Uint8Array([4]), publicKey], 65);
3062
3078
  }
@@ -3076,43 +3092,55 @@ function verifySignature(signature, message, publicKey) {
3076
3092
  }
3077
3093
  }
3078
3094
 
3079
- function number(n) {
3095
+ /**
3096
+ * Internal assertion helpers.
3097
+ * @module
3098
+ */
3099
+ /** Asserts something is positive integer. */
3100
+ function anumber(n) {
3080
3101
  if (!Number.isSafeInteger(n) || n < 0)
3081
- throw new Error(`positive integer expected, not ${n}`);
3102
+ throw new Error('positive integer expected, got ' + n);
3082
3103
  }
3083
- // copied from utils
3104
+ /** Is number an Uint8Array? Copied from utils for perf. */
3084
3105
  function isBytes$2(a) {
3085
- return (a instanceof Uint8Array ||
3086
- (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
3106
+ return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
3087
3107
  }
3088
- function bytes(b, ...lengths) {
3108
+ /** Asserts something is Uint8Array. */
3109
+ function abytes$1(b, ...lengths) {
3089
3110
  if (!isBytes$2(b))
3090
3111
  throw new Error('Uint8Array expected');
3091
3112
  if (lengths.length > 0 && !lengths.includes(b.length))
3092
- throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);
3113
+ throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
3093
3114
  }
3094
- function hash(h) {
3115
+ /** Asserts something is hash */
3116
+ function ahash(h) {
3095
3117
  if (typeof h !== 'function' || typeof h.create !== 'function')
3096
3118
  throw new Error('Hash should be wrapped by utils.wrapConstructor');
3097
- number(h.outputLen);
3098
- number(h.blockLen);
3119
+ anumber(h.outputLen);
3120
+ anumber(h.blockLen);
3099
3121
  }
3100
- function exists(instance, checkFinished = true) {
3122
+ /** Asserts a hash instance has not been destroyed / finished */
3123
+ function aexists(instance, checkFinished = true) {
3101
3124
  if (instance.destroyed)
3102
3125
  throw new Error('Hash instance has been destroyed');
3103
3126
  if (checkFinished && instance.finished)
3104
3127
  throw new Error('Hash#digest() has already been called');
3105
3128
  }
3106
- function output(out, instance) {
3107
- bytes(out);
3129
+ /** Asserts output is properly-sized byte array */
3130
+ function aoutput(out, instance) {
3131
+ abytes$1(out);
3108
3132
  const min = instance.outputLen;
3109
3133
  if (out.length < min) {
3110
- throw new Error(`digestInto() expects output buffer of length at least ${min}`);
3134
+ throw new Error('digestInto() expects output buffer of length at least ' + min);
3111
3135
  }
3112
3136
  }
3113
3137
 
3114
3138
  const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
3115
3139
 
3140
+ /**
3141
+ * Utilities for hex, bytes, CSPRNG.
3142
+ * @module
3143
+ */
3116
3144
  /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
3117
3145
  // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
3118
3146
  // node.js versions earlier than v19 don't declare it in global scope.
@@ -3121,33 +3149,20 @@ const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? glob
3121
3149
  // Makes the utils un-importable in browsers without a bundler.
3122
3150
  // Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
3123
3151
  // Cast array to view
3124
- const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
3125
- // The rotate right (circular right shift) operation for uint32
3126
- const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
3127
- new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
3128
- // There is no setImmediate in browser and setTimeout is slow.
3129
- // call of async fn will return Promise, which will be fullfiled only on
3130
- // next scheduler queue processing step and this is exactly what we need.
3131
- const nextTick = async () => { };
3132
- // Returns control to thread each 'tick' ms to avoid blocking
3133
- async function asyncLoop(iters, tick, cb) {
3134
- let ts = Date.now();
3135
- for (let i = 0; i < iters; i++) {
3136
- cb(i);
3137
- // Date.now() is not monotonic, so in case if clock goes backwards we return return control too
3138
- const diff = Date.now() - ts;
3139
- if (diff >= 0 && diff < tick)
3140
- continue;
3141
- await nextTick();
3142
- ts += diff;
3143
- }
3152
+ function createView(arr) {
3153
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
3154
+ }
3155
+ /** The rotate right (circular right shift) operation for uint32 */
3156
+ function rotr(word, shift) {
3157
+ return (word << (32 - shift)) | (word >>> shift);
3144
3158
  }
3145
3159
  /**
3160
+ * Convert JS string to byte array.
3146
3161
  * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
3147
3162
  */
3148
3163
  function utf8ToBytes$1(str) {
3149
3164
  if (typeof str !== 'string')
3150
- throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
3165
+ throw new Error('utf8ToBytes expected string, got ' + typeof str);
3151
3166
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
3152
3167
  }
3153
3168
  /**
@@ -3158,7 +3173,7 @@ function utf8ToBytes$1(str) {
3158
3173
  function toBytes$1(data) {
3159
3174
  if (typeof data === 'string')
3160
3175
  data = utf8ToBytes$1(data);
3161
- bytes(data);
3176
+ abytes$1(data);
3162
3177
  return data;
3163
3178
  }
3164
3179
  /**
@@ -3168,7 +3183,7 @@ function concatBytes$1(...arrays) {
3168
3183
  let sum = 0;
3169
3184
  for (let i = 0; i < arrays.length; i++) {
3170
3185
  const a = arrays[i];
3171
- bytes(a);
3186
+ abytes$1(a);
3172
3187
  sum += a.length;
3173
3188
  }
3174
3189
  const res = new Uint8Array(sum);
@@ -3179,20 +3194,14 @@ function concatBytes$1(...arrays) {
3179
3194
  }
3180
3195
  return res;
3181
3196
  }
3182
- // For runtime check if class implements interface
3197
+ /** For runtime check if class implements interface */
3183
3198
  class Hash {
3184
3199
  // Safe version that clones internal state
3185
3200
  clone() {
3186
3201
  return this._cloneInto();
3187
3202
  }
3188
3203
  }
3189
- const toStr = {}.toString;
3190
- function checkOpts(defaults, opts) {
3191
- if (opts !== undefined && toStr.call(opts) !== '[object Object]')
3192
- throw new Error('Options should be object or undefined');
3193
- const merged = Object.assign(defaults, opts);
3194
- return merged;
3195
- }
3204
+ /** Wraps hash function, creating an interface on top of it */
3196
3205
  function wrapConstructor(hashCons) {
3197
3206
  const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
3198
3207
  const tmp = hashCons();
@@ -3201,17 +3210,23 @@ function wrapConstructor(hashCons) {
3201
3210
  hashC.create = () => hashCons();
3202
3211
  return hashC;
3203
3212
  }
3204
- /**
3205
- * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
3206
- */
3207
- function randomBytes$1(bytesLength = 32) {
3213
+ /** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
3214
+ function randomBytes(bytesLength = 32) {
3208
3215
  if (crypto$1 && typeof crypto$1.getRandomValues === 'function') {
3209
3216
  return crypto$1.getRandomValues(new Uint8Array(bytesLength));
3210
3217
  }
3218
+ // Legacy Node.js compatibility
3219
+ if (crypto$1 && typeof crypto$1.randomBytes === 'function') {
3220
+ return crypto$1.randomBytes(bytesLength);
3221
+ }
3211
3222
  throw new Error('crypto.getRandomValues must be defined');
3212
3223
  }
3213
3224
 
3214
- // Polyfill for Safari 14
3225
+ /**
3226
+ * Internal Merkle-Damgard hash utils.
3227
+ * @module
3228
+ */
3229
+ /** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
3215
3230
  function setBigUint64(view, byteOffset, value, isLE) {
3216
3231
  if (typeof view.setBigUint64 === 'function')
3217
3232
  return view.setBigUint64(byteOffset, value, isLE);
@@ -3224,10 +3239,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
3224
3239
  view.setUint32(byteOffset + h, wh, isLE);
3225
3240
  view.setUint32(byteOffset + l, wl, isLE);
3226
3241
  }
3227
- // Choice: a ? b : c
3228
- const Chi = (a, b, c) => (a & b) ^ (~a & c);
3229
- // Majority function, true if any two inpust is true
3230
- const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
3242
+ /** Choice: a ? b : c */
3243
+ function Chi(a, b, c) {
3244
+ return (a & b) ^ (~a & c);
3245
+ }
3246
+ /** Majority function, true if any two inputs is true. */
3247
+ function Maj(a, b, c) {
3248
+ return (a & b) ^ (a & c) ^ (b & c);
3249
+ }
3231
3250
  /**
3232
3251
  * Merkle-Damgard hash construction base class.
3233
3252
  * Could be used to create MD5, RIPEMD, SHA1, SHA2.
@@ -3247,7 +3266,7 @@ class HashMD extends Hash {
3247
3266
  this.view = createView(this.buffer);
3248
3267
  }
3249
3268
  update(data) {
3250
- exists(this);
3269
+ aexists(this);
3251
3270
  const { view, buffer, blockLen } = this;
3252
3271
  data = toBytes$1(data);
3253
3272
  const len = data.length;
@@ -3273,8 +3292,8 @@ class HashMD extends Hash {
3273
3292
  return this;
3274
3293
  }
3275
3294
  digestInto(out) {
3276
- exists(this);
3277
- output(out, this);
3295
+ aexists(this);
3296
+ aoutput(out, this);
3278
3297
  this.finished = true;
3279
3298
  // Padding
3280
3299
  // We can avoid allocation of buffer for padding completely if it
@@ -3331,10 +3350,16 @@ class HashMD extends Hash {
3331
3350
  }
3332
3351
  }
3333
3352
 
3334
- // SHA2-256 need to try 2^128 hashes to execute birthday attack.
3335
- // BTC network is doing 2^67 hashes/sec as per early 2023.
3336
- // Round constants:
3337
- // first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
3353
+ /**
3354
+ * SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
3355
+ *
3356
+ * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
3357
+ * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
3358
+ *
3359
+ * Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
3360
+ * @module
3361
+ */
3362
+ /** Round constants: first 32 bits of fractional parts of the cube roots of the first 64 primes 2..311). */
3338
3363
  // prettier-ignore
3339
3364
  const SHA256_K = /* @__PURE__ */ new Uint32Array([
3340
3365
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -3346,14 +3371,15 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
3346
3371
  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
3347
3372
  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
3348
3373
  ]);
3349
- // Initial state:
3350
- // first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
3374
+ /** Initial state: first 32 bits of fractional parts of the square roots of the first 8 primes 2..19. */
3351
3375
  // prettier-ignore
3352
3376
  const SHA256_IV = /* @__PURE__ */ new Uint32Array([
3353
3377
  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
3354
3378
  ]);
3355
- // Temporary buffer, not used to store anything between runs
3356
- // Named this way because it matches specification.
3379
+ /**
3380
+ * Temporary buffer, not used to store anything between runs.
3381
+ * Named this way because it matches specification.
3382
+ */
3357
3383
  const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
3358
3384
  class SHA256 extends HashMD {
3359
3385
  constructor() {
@@ -3430,10 +3456,7 @@ class SHA256 extends HashMD {
3430
3456
  this.buffer.fill(0);
3431
3457
  }
3432
3458
  }
3433
- /**
3434
- * SHA2-256 hash function
3435
- * @param message - data that would be hashed
3436
- */
3459
+ /** SHA2-256 hash function */
3437
3460
  const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
3438
3461
 
3439
3462
  var Protocols;
@@ -3445,43 +3468,24 @@ var Protocols;
3445
3468
  })(Protocols || (Protocols = {}));
3446
3469
  var ProtocolError;
3447
3470
  (function (ProtocolError) {
3448
- /** Could not determine the origin of the fault. Best to check connectivity and try again */
3471
+ //
3472
+ // GENERAL ERRORS SECTION
3473
+ //
3474
+ /**
3475
+ * Could not determine the origin of the fault. Best to check connectivity and try again
3476
+ * */
3449
3477
  ProtocolError["GENERIC_FAIL"] = "Generic error";
3450
3478
  /**
3451
- * Failure to protobuf encode the message. This is not recoverable and needs
3452
- * further investigation.
3479
+ * The remote peer rejected the message. Information provided by the remote peer
3480
+ * is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
3481
+ * or `DECODE_FAILED` can be used.
3453
3482
  */
3454
- ProtocolError["ENCODE_FAILED"] = "Failed to encode";
3483
+ ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
3455
3484
  /**
3456
3485
  * Failure to protobuf decode the message. May be due to a remote peer issue,
3457
3486
  * ensuring that messages are sent via several peer enable mitigation of this error.
3458
3487
  */
3459
3488
  ProtocolError["DECODE_FAILED"] = "Failed to decode";
3460
- /**
3461
- * The message payload is empty, making the message invalid. Ensure that a non-empty
3462
- * payload is set on the outgoing message.
3463
- */
3464
- ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
3465
- /**
3466
- * The message size is above the maximum message size allowed on the Waku Network.
3467
- * Compressing the message or using an alternative strategy for large messages is recommended.
3468
- */
3469
- ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
3470
- /**
3471
- * The PubsubTopic passed to the send function is not configured on the Waku node.
3472
- * Please ensure that the PubsubTopic is used when initializing the Waku node.
3473
- */
3474
- ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
3475
- /**
3476
- * The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
3477
- * Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
3478
- */
3479
- ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
3480
- /**
3481
- * The topics passed in the decoders do not match each other, or don't exist at all.
3482
- * Ensure that all the pubsub topics used in the decoders are valid and match each other.
3483
- */
3484
- ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
3485
3489
  /**
3486
3490
  * Failure to find a peer with suitable protocols. This may due to a connection issue.
3487
3491
  * Mitigation can be: retrying after a given time period, display connectivity issue
@@ -3499,37 +3503,51 @@ var ProtocolError;
3499
3503
  * or `DECODE_FAILED` can be used.
3500
3504
  */
3501
3505
  ProtocolError["NO_RESPONSE"] = "No response received";
3506
+ //
3507
+ // SEND ERRORS SECTION
3508
+ //
3502
3509
  /**
3503
- * The remote peer rejected the message. Information provided by the remote peer
3504
- * is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
3505
- * or `DECODE_FAILED` can be used.
3510
+ * Failure to protobuf encode the message. This is not recoverable and needs
3511
+ * further investigation.
3506
3512
  */
3507
- ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
3513
+ ProtocolError["ENCODE_FAILED"] = "Failed to encode";
3508
3514
  /**
3509
- * The protocol request timed out without a response. This may be due to a connection issue.
3510
- * Mitigation can be: retrying after a given time period
3515
+ * The message payload is empty, making the message invalid. Ensure that a non-empty
3516
+ * payload is set on the outgoing message.
3511
3517
  */
3512
- ProtocolError["REQUEST_TIMEOUT"] = "Request timeout";
3518
+ ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
3513
3519
  /**
3514
- * Missing credentials info message.
3515
- * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L186
3520
+ * The message size is above the maximum message size allowed on the Waku Network.
3521
+ * Compressing the message or using an alternative strategy for large messages is recommended.
3516
3522
  */
3517
- ProtocolError["RLN_IDENTITY_MISSING"] = "Identity credentials are not set";
3523
+ ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
3518
3524
  /**
3519
- * Membership index missing info message.
3520
- * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L188
3525
+ * The PubsubTopic passed to the send function is not configured on the Waku node.
3526
+ * Please ensure that the PubsubTopic is used when initializing the Waku node.
3521
3527
  */
3522
- ProtocolError["RLN_MEMBERSHIP_INDEX"] = "Membership index is not set";
3528
+ ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
3523
3529
  /**
3524
- * Message limit is missing.
3525
- * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
3530
+ * Fails when
3526
3531
  */
3527
- ProtocolError["RLN_LIMIT_MISSING"] = "User message limit is not set";
3532
+ ProtocolError["STREAM_ABORTED"] = "Stream aborted";
3528
3533
  /**
3529
3534
  * General proof generation error message.
3530
3535
  * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
3531
3536
  */
3532
3537
  ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
3538
+ //
3539
+ // RECEIVE ERRORS SECTION
3540
+ //
3541
+ /**
3542
+ * The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
3543
+ * Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
3544
+ */
3545
+ ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
3546
+ /**
3547
+ * The topics passed in the decoders do not match each other, or don't exist at all.
3548
+ * Ensure that all the pubsub topics used in the decoders are valid and match each other.
3549
+ */
3550
+ ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
3533
3551
  })(ProtocolError || (ProtocolError = {}));
3534
3552
 
3535
3553
  var Tags;
@@ -3550,6 +3568,10 @@ var EConnectionStateEvents;
3550
3568
  EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
3551
3569
  })(EConnectionStateEvents || (EConnectionStateEvents = {}));
3552
3570
 
3571
+ var HealthStatusChangeEvents;
3572
+ (function (HealthStatusChangeEvents) {
3573
+ HealthStatusChangeEvents["StatusChange"] = "health:change";
3574
+ })(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
3553
3575
  var HealthStatus;
3554
3576
  (function (HealthStatus) {
3555
3577
  HealthStatus["Unhealthy"] = "Unhealthy";
@@ -3621,7 +3643,7 @@ function requireMs () {
3621
3643
  * @api public
3622
3644
  */
3623
3645
 
3624
- ms = function(val, options) {
3646
+ ms = function (val, options) {
3625
3647
  options = options || {};
3626
3648
  var type = typeof val;
3627
3649
  if (type === 'string' && val.length > 0) {
@@ -3928,24 +3950,62 @@ function setup(env) {
3928
3950
  createDebug.names = [];
3929
3951
  createDebug.skips = [];
3930
3952
 
3931
- let i;
3932
- const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
3933
- const len = split.length;
3953
+ const split = (typeof namespaces === 'string' ? namespaces : '')
3954
+ .trim()
3955
+ .replace(' ', ',')
3956
+ .split(',')
3957
+ .filter(Boolean);
3934
3958
 
3935
- for (i = 0; i < len; i++) {
3936
- if (!split[i]) {
3937
- // ignore empty strings
3938
- continue;
3959
+ for (const ns of split) {
3960
+ if (ns[0] === '-') {
3961
+ createDebug.skips.push(ns.slice(1));
3962
+ } else {
3963
+ createDebug.names.push(ns);
3939
3964
  }
3965
+ }
3966
+ }
3940
3967
 
3941
- namespaces = split[i].replace(/\*/g, '.*?');
3942
-
3943
- if (namespaces[0] === '-') {
3944
- createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
3968
+ /**
3969
+ * Checks if the given string matches a namespace template, honoring
3970
+ * asterisks as wildcards.
3971
+ *
3972
+ * @param {String} search
3973
+ * @param {String} template
3974
+ * @return {Boolean}
3975
+ */
3976
+ function matchesTemplate(search, template) {
3977
+ let searchIndex = 0;
3978
+ let templateIndex = 0;
3979
+ let starIndex = -1;
3980
+ let matchIndex = 0;
3981
+
3982
+ while (searchIndex < search.length) {
3983
+ if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
3984
+ // Match character or proceed with wildcard
3985
+ if (template[templateIndex] === '*') {
3986
+ starIndex = templateIndex;
3987
+ matchIndex = searchIndex;
3988
+ templateIndex++; // Skip the '*'
3989
+ } else {
3990
+ searchIndex++;
3991
+ templateIndex++;
3992
+ }
3993
+ } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
3994
+ // Backtrack to the last '*' and try to match more characters
3995
+ templateIndex = starIndex + 1;
3996
+ matchIndex++;
3997
+ searchIndex = matchIndex;
3945
3998
  } else {
3946
- createDebug.names.push(new RegExp('^' + namespaces + '$'));
3999
+ return false; // No match
3947
4000
  }
3948
4001
  }
4002
+
4003
+ // Handle trailing '*' in template
4004
+ while (templateIndex < template.length && template[templateIndex] === '*') {
4005
+ templateIndex++;
4006
+ }
4007
+
4008
+ return templateIndex === template.length;
3949
4009
  }
3950
4010
 
3951
4011
  /**
@@ -3956,8 +4016,8 @@ function setup(env) {
3956
4016
  */
3957
4017
  function disable() {
3958
4018
  const namespaces = [
3959
- ...createDebug.names.map(toNamespace),
3960
- ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
4019
+ ...createDebug.names,
4020
+ ...createDebug.skips.map(namespace => '-' + namespace)
3961
4021
  ].join(',');
3962
4022
  createDebug.enable('');
3963
4023
  return namespaces;
@@ -3971,21 +4031,14 @@ function setup(env) {
3971
4031
  * @api public
3972
4032
  */
3973
4033
  function enabled(name) {
3974
- if (name[name.length - 1] === '*') {
3975
- return true;
3976
- }
3977
-
3978
- let i;
3979
- let len;
3980
-
3981
- for (i = 0, len = createDebug.skips.length; i < len; i++) {
3982
- if (createDebug.skips[i].test(name)) {
4034
+ for (const skip of createDebug.skips) {
4035
+ if (matchesTemplate(name, skip)) {
3983
4036
  return false;
3984
4037
  }
3985
4038
  }
3986
4039
 
3987
- for (i = 0, len = createDebug.names.length; i < len; i++) {
3988
- if (createDebug.names[i].test(name)) {
4040
+ for (const ns of createDebug.names) {
4041
+ if (matchesTemplate(name, ns)) {
3989
4042
  return true;
3990
4043
  }
3991
4044
  }
@@ -3993,19 +4046,6 @@ function setup(env) {
3993
4046
  return false;
3994
4047
  }
3995
4048
 
3996
- /**
3997
- * Convert regexp to namespace
3998
- *
3999
- * @param {RegExp} regxep
4000
- * @return {String} namespace
4001
- * @api private
4002
- */
4003
- function toNamespace(regexp) {
4004
- return regexp.toString()
4005
- .substring(2, regexp.toString().length - 2)
4006
- .replace(/\.\*\?$/, '*');
4007
- }
4008
-
4009
4049
  /**
4010
4050
  * Coerce `val`.
4011
4051
  *
@@ -4167,6 +4207,7 @@ var common = setup;
4167
4207
 
4168
4208
  // Is webkit? http://stackoverflow.com/a/16459606/376773
4169
4209
  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
4210
+ // eslint-disable-next-line no-return-assign
4170
4211
  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
4171
4212
  // Is firebug? http://stackoverflow.com/a/398120/376773
4172
4213
  (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
@@ -4314,7 +4355,6 @@ var debug = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
4314
4355
 
4315
4356
  const APP_NAME = "waku";
4316
4357
  let Logger$1 = class Logger {
4317
- _debug;
4318
4358
  _info;
4319
4359
  _warn;
4320
4360
  _error;
@@ -4322,14 +4362,10 @@ let Logger$1 = class Logger {
4322
4362
  return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
4323
4363
  }
4324
4364
  constructor(prefix) {
4325
- this._debug = debug(Logger.createDebugNamespace("debug", prefix));
4326
4365
  this._info = debug(Logger.createDebugNamespace("info", prefix));
4327
4366
  this._warn = debug(Logger.createDebugNamespace("warn", prefix));
4328
4367
  this._error = debug(Logger.createDebugNamespace("error", prefix));
4329
4368
  }
4330
- get debug() {
4331
- return this._debug;
4332
- }
4333
4369
  get info() {
4334
4370
  return this._info;
4335
4371
  }
@@ -4345,34 +4381,6 @@ let Logger$1 = class Logger {
4345
4381
  }
4346
4382
  };
4347
4383
 
4348
- const peerIdSymbol = Symbol.for('@libp2p/peer-id');
4349
-
4350
- /**
4351
- * When this error is thrown it means an operation was aborted,
4352
- * usually in response to the `abort` event being emitted by an
4353
- * AbortSignal.
4354
- */
4355
- class CodeError extends Error {
4356
- code;
4357
- props;
4358
- constructor(message, code, props) {
4359
- super(message);
4360
- this.code = code;
4361
- this.name = props?.name ?? 'CodeError';
4362
- this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
4363
- }
4364
- }
4365
- class AggregateCodeError extends AggregateError {
4366
- code;
4367
- props;
4368
- constructor(errors, message, code, props) {
4369
- super(errors, message);
4370
- this.code = code;
4371
- this.name = props?.name ?? 'AggregateCodeError';
4372
- this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
4373
- }
4374
- }
4375
-
4376
4384
  /**
4377
4385
  * Returns true if the two passed Uint8Arrays have the same content
4378
4386
  */
@@ -4864,7 +4872,7 @@ function parseIPv6(input) {
4864
4872
  return parser.new(input).parseWith(() => parser.readIPv6Addr());
4865
4873
  }
4866
4874
  /** Parse `input` into IPv4 or IPv6 bytes. */
4867
- function parseIP(input) {
4875
+ function parseIP(input, mapIPv4ToIPv6 = false) {
4868
4876
  // strip zone index if it is present
4869
4877
  if (input.includes("%")) {
4870
4878
  input = input.split("%")[0];
@@ -4872,7 +4880,14 @@ function parseIP(input) {
4872
4880
  if (input.length > MAX_IPV6_LENGTH) {
4873
4881
  return undefined;
4874
4882
  }
4875
- return parser.new(input).parseWith(() => parser.readIPAddr());
4883
+ const addr = parser.new(input).parseWith(() => parser.readIPAddr());
4884
+ if (!addr) {
4885
+ return undefined;
4886
+ }
4887
+ if (mapIPv4ToIPv6 && addr.length === 4) {
4888
+ return Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, addr[0], addr[1], addr[2], addr[3]]);
4889
+ }
4890
+ return addr;
4876
4891
  }
4877
4892
 
4878
4893
  /** Check if `input` is IPv4. */
@@ -5060,17 +5075,13 @@ function getProtocol(proto) {
5060
5075
  throw new Error(`invalid protocol id type: ${typeof proto}`);
5061
5076
  }
5062
5077
 
5063
- /**
5064
- * @packageDocumentation
5065
- *
5066
- * Provides methods for converting
5067
- */
5068
5078
  getProtocol('ip4');
5069
5079
  getProtocol('ip6');
5070
5080
  getProtocol('ipcidr');
5071
5081
  /**
5072
5082
  * Convert [code,Uint8Array] to string
5073
5083
  */
5084
+ // eslint-disable-next-line complexity
5074
5085
  function convertToString(proto, buf) {
5075
5086
  const protocol = getProtocol(proto);
5076
5087
  switch (protocol.code) {
@@ -5079,6 +5090,8 @@ function convertToString(proto, buf) {
5079
5090
  return bytes2ip(buf);
5080
5091
  case 42: // ipv6zone
5081
5092
  return bytes2str(buf);
5093
+ case 43: // ipcidr
5094
+ return toString$1(buf, 'base10');
5082
5095
  case 6: // tcp
5083
5096
  case 273: // udp
5084
5097
  case 33: // dccp
@@ -5106,6 +5119,7 @@ function convertToString(proto, buf) {
5106
5119
  return toString$1(buf, 'base16'); // no clue. convert to hex
5107
5120
  }
5108
5121
  }
5122
+ // eslint-disable-next-line complexity
5109
5123
  function convertToBytes(proto, str) {
5110
5124
  const protocol = getProtocol(proto);
5111
5125
  switch (protocol.code) {
@@ -5115,6 +5129,8 @@ function convertToBytes(proto, str) {
5115
5129
  return ip2bytes(str);
5116
5130
  case 42: // ipv6zone
5117
5131
  return str2bytes(str);
5132
+ case 43: // ipcidr
5133
+ return fromString(str, 'base10');
5118
5134
  case 6: // tcp
5119
5135
  case 273: // udp
5120
5136
  case 33: // dccp
@@ -5409,19 +5425,6 @@ function ParseError(str) {
5409
5425
  return new Error('Error parsing address: ' + str);
5410
5426
  }
5411
5427
 
5412
- /**
5413
- * @packageDocumentation
5414
- *
5415
- * An implementation of a Multiaddr in JavaScript
5416
- *
5417
- * @example
5418
- *
5419
- * ```js
5420
- * import { multiaddr } from '@multiformats/multiaddr'
5421
- *
5422
- * const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
5423
- * ```
5424
- */
5425
5428
  const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
5426
5429
  const symbol = Symbol.for('@multiformats/js-multiaddr/multiaddr');
5427
5430
  const DNS_CODES = [
@@ -5430,6 +5433,12 @@ const DNS_CODES = [
5430
5433
  getProtocol('dns6').code,
5431
5434
  getProtocol('dnsaddr').code
5432
5435
  ];
5436
+ class NoAvailableResolverError extends Error {
5437
+ constructor(message = 'No available resolver') {
5438
+ super(message);
5439
+ this.name = 'NoAvailableResolverError';
5440
+ }
5441
+ }
5433
5442
  /**
5434
5443
  * Creates a {@link Multiaddr} from a {@link MultiaddrInput}
5435
5444
  */
@@ -5527,10 +5536,20 @@ class Multiaddr {
5527
5536
  return this.#tuples.map(([code]) => getProtocol(code).name);
5528
5537
  }
5529
5538
  tuples() {
5530
- return this.#tuples;
5539
+ return this.#tuples.map(([code, value]) => {
5540
+ if (value == null) {
5541
+ return [code];
5542
+ }
5543
+ return [code, value];
5544
+ });
5531
5545
  }
5532
5546
  stringTuples() {
5533
- return this.#stringTuples;
5547
+ return this.#stringTuples.map(([code, value]) => {
5548
+ if (value == null) {
5549
+ return [code];
5550
+ }
5551
+ return [code, value];
5552
+ });
5534
5553
  }
5535
5554
  encapsulate(addr) {
5536
5555
  addr = new Multiaddr(addr);
@@ -5599,7 +5618,7 @@ class Multiaddr {
5599
5618
  }
5600
5619
  const resolver = resolvers.get(resolvableProto.name);
5601
5620
  if (resolver == null) {
5602
- throw new CodeError(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
5621
+ throw new NoAvailableResolverError(`no available resolver for ${resolvableProto.name}`);
5603
5622
  }
5604
5623
  const result = await resolver(this, options);
5605
5624
  return result.map(str => multiaddr(str));
@@ -5660,10 +5679,8 @@ class Multiaddr {
5660
5679
  *
5661
5680
  * ```TypeScript
5662
5681
  * import { multiaddr } from '@multiformats/multiaddr'
5663
- * const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
5664
- * // Multiaddr(/ip4/127.0.0.1/udp/1234)
5665
5682
  *
5666
- * const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
5683
+ * const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
5667
5684
  * // Multiaddr(/ip4/127.0.0.1/udp/1234)
5668
5685
  *
5669
5686
  * addr.bytes
@@ -5702,9 +5719,9 @@ class Multiaddr {
5702
5719
  *
5703
5720
  * ```TypeScript
5704
5721
  * import { multiaddr, resolvers } from '@multiformats/multiaddr'
5705
- * import { dnsaddr } from '@multiformats/multiaddr/resolvers'
5722
+ * import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
5706
5723
  *
5707
- * resolvers.set('dnsaddr', dnsaddr)
5724
+ * resolvers.set('dnsaddr', dnsaddrResolver)
5708
5725
  *
5709
5726
  * const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
5710
5727
  *
@@ -5713,7 +5730,7 @@ class Multiaddr {
5713
5730
  * signal: AbortSignal.timeout(5000)
5714
5731
  * })
5715
5732
  *
5716
- * console.info(await ma.resolve(resolved)
5733
+ * console.info(resolved)
5717
5734
  * // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
5718
5735
  * ```
5719
5736
  *
@@ -5727,7 +5744,9 @@ class Multiaddr {
5727
5744
  * import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
5728
5745
  *
5729
5746
  * const resolver = dns({
5730
- * '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
5747
+ * resolvers: {
5748
+ * '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
5749
+ * }
5731
5750
  * })
5732
5751
  *
5733
5752
  * const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
@@ -5813,18 +5832,55 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
5813
5832
  return multiaddrFromFields(isIpv6 ? "ip6" : "ip4", protoName, ipVal, protoVal);
5814
5833
  }
5815
5834
 
5816
- function isPromise(thing) {
5817
- if (thing == null) {
5818
- return false;
5835
+ /**
5836
+ * All PeerId implementations must use this symbol as the name of a property
5837
+ * with a boolean `true` value
5838
+ */
5839
+ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
5840
+
5841
+ /**
5842
+ * When this error is thrown it means an operation was aborted,
5843
+ * usually in response to the `abort` event being emitted by an
5844
+ * AbortSignal.
5845
+ */
5846
+ /**
5847
+ * Thrown when invalid parameters are passed to a function or method call
5848
+ */
5849
+ class InvalidParametersError extends Error {
5850
+ static name = 'InvalidParametersError';
5851
+ constructor(message = 'Invalid parameters') {
5852
+ super(message);
5853
+ this.name = 'InvalidParametersError';
5854
+ }
5855
+ }
5856
+ /**
5857
+ * Thrown when a public key is invalid
5858
+ */
5859
+ class InvalidPublicKeyError extends Error {
5860
+ static name = 'InvalidPublicKeyError';
5861
+ constructor(message = 'Invalid public key') {
5862
+ super(message);
5863
+ this.name = 'InvalidPublicKeyError';
5864
+ }
5865
+ }
5866
+ /**
5867
+ * Thrown when and attempt to operate on an unsupported key was made
5868
+ */
5869
+ class UnsupportedKeyTypeError extends Error {
5870
+ static name = 'UnsupportedKeyTypeError';
5871
+ constructor(message = 'Unsupported key type') {
5872
+ super(message);
5873
+ this.name = 'UnsupportedKeyTypeError';
5819
5874
  }
5820
- return typeof thing.then === 'function' &&
5821
- typeof thing.catch === 'function' &&
5822
- typeof thing.finally === 'function';
5823
5875
  }
5824
5876
 
5877
+ /**
5878
+ * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
5879
+ * @todo re-check https://issues.chromium.org/issues/42212588
5880
+ * @module
5881
+ */
5825
5882
  const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
5826
5883
  const _32n = /* @__PURE__ */ BigInt(32);
5827
- // We are not using BigUint64Array, because they are extremely slow as per 2022
5828
5884
  function fromBig(n, le = false) {
5829
5885
  if (le)
5830
5886
  return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
@@ -5881,6 +5937,13 @@ const u64 = {
5881
5937
  add, add3L, add3H, add4L, add4H, add5H, add5L,
5882
5938
  };
5883
5939
 
5940
+ /**
5941
+ * SHA2-512 a.k.a. sha512 and sha384. It is slower than sha256 in js because u64 operations are slow.
5942
+ *
5943
+ * Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
5944
+ * [the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).
5945
+ * @module
5946
+ */
5884
5947
  // Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
5885
5948
  // prettier-ignore
5886
5949
  const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
@@ -6035,8 +6098,13 @@ class SHA512 extends HashMD {
6035
6098
  this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
6036
6099
  }
6037
6100
  }
6101
+ /** SHA2-512 hash function. */
6038
6102
  const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
6039
6103
 
6104
+ /**
6105
+ * Hex, bytes and number utilities.
6106
+ * @module
6107
+ */
6040
6108
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
6041
6109
  // 100 lines of code in the file are duplicated from noble-hashes (utils).
6042
6110
  // This is OK: `abstract` directory does not use noble-hashes.
@@ -6046,8 +6114,7 @@ const _0n$4 = /* @__PURE__ */ BigInt(0);
6046
6114
  const _1n$6 = /* @__PURE__ */ BigInt(1);
6047
6115
  const _2n$4 = /* @__PURE__ */ BigInt(2);
6048
6116
  function isBytes$1(a) {
6049
- return (a instanceof Uint8Array ||
6050
- (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
6117
+ return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
6051
6118
  }
6052
6119
  function abytes(item) {
6053
6120
  if (!isBytes$1(item))
@@ -6055,7 +6122,7 @@ function abytes(item) {
6055
6122
  }
6056
6123
  function abool(title, value) {
6057
6124
  if (typeof value !== 'boolean')
6058
- throw new Error(`${title} must be valid boolean, got "${value}".`);
6125
+ throw new Error(title + ' boolean expected, got ' + value);
6059
6126
  }
6060
6127
  // Array where index 0xf0 (240) is mapped to string 'f0'
6061
6128
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
@@ -6073,23 +6140,22 @@ function bytesToHex(bytes) {
6073
6140
  }
6074
6141
  function numberToHexUnpadded(num) {
6075
6142
  const hex = num.toString(16);
6076
- return hex.length & 1 ? `0${hex}` : hex;
6143
+ return hex.length & 1 ? '0' + hex : hex;
6077
6144
  }
6078
6145
  function hexToNumber(hex) {
6079
6146
  if (typeof hex !== 'string')
6080
6147
  throw new Error('hex string expected, got ' + typeof hex);
6081
- // Big Endian
6082
- return BigInt(hex === '' ? '0' : `0x${hex}`);
6148
+ return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
6083
6149
  }
6084
6150
  // We use optimized technique to convert hex string to byte array
6085
- const asciis = { _0: 48, _9: 57, _A: 65, _F: 70, _a: 97, _f: 102 };
6086
- function asciiToBase16(char) {
6087
- if (char >= asciis._0 && char <= asciis._9)
6088
- return char - asciis._0;
6089
- if (char >= asciis._A && char <= asciis._F)
6090
- return char - (asciis._A - 10);
6091
- if (char >= asciis._a && char <= asciis._f)
6092
- return char - (asciis._a - 10);
6151
+ const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
6152
+ function asciiToBase16(ch) {
6153
+ if (ch >= asciis._0 && ch <= asciis._9)
6154
+ return ch - asciis._0; // '2' => 50-48
6155
+ if (ch >= asciis.A && ch <= asciis.F)
6156
+ return ch - (asciis.A - 10); // 'B' => 66-(65-10)
6157
+ if (ch >= asciis.a && ch <= asciis.f)
6158
+ return ch - (asciis.a - 10); // 'b' => 98-(97-10)
6093
6159
  return;
6094
6160
  }
6095
6161
  /**
@@ -6101,7 +6167,7 @@ function hexToBytes(hex) {
6101
6167
  const hl = hex.length;
6102
6168
  const al = hl / 2;
6103
6169
  if (hl % 2)
6104
- throw new Error('padded hex string expected, got unpadded hex of length ' + hl);
6170
+ throw new Error('hex string expected, got unpadded hex of length ' + hl);
6105
6171
  const array = new Uint8Array(al);
6106
6172
  for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
6107
6173
  const n1 = asciiToBase16(hex.charCodeAt(hi));
@@ -6110,7 +6176,7 @@ function hexToBytes(hex) {
6110
6176
  const char = hex[hi] + hex[hi + 1];
6111
6177
  throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
6112
6178
  }
6113
- array[ai] = n1 * 16 + n2;
6179
+ array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
6114
6180
  }
6115
6181
  return array;
6116
6182
  }
@@ -6148,7 +6214,7 @@ function ensureBytes(title, hex, expectedLength) {
6148
6214
  res = hexToBytes(hex);
6149
6215
  }
6150
6216
  catch (e) {
6151
- throw new Error(`${title} must be valid hex string, got "${hex}". Cause: ${e}`);
6217
+ throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
6152
6218
  }
6153
6219
  }
6154
6220
  else if (isBytes$1(hex)) {
@@ -6157,11 +6223,11 @@ function ensureBytes(title, hex, expectedLength) {
6157
6223
  res = Uint8Array.from(hex);
6158
6224
  }
6159
6225
  else {
6160
- throw new Error(`${title} must be hex string or Uint8Array`);
6226
+ throw new Error(title + ' must be hex string or Uint8Array');
6161
6227
  }
6162
6228
  const len = res.length;
6163
6229
  if (typeof expectedLength === 'number' && len !== expectedLength)
6164
- throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);
6230
+ throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
6165
6231
  return res;
6166
6232
  }
6167
6233
  /**
@@ -6196,7 +6262,7 @@ function equalBytes(a, b) {
6196
6262
  */
6197
6263
  function utf8ToBytes(str) {
6198
6264
  if (typeof str !== 'string')
6199
- throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
6265
+ throw new Error('string expected');
6200
6266
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
6201
6267
  }
6202
6268
  // Is positive bigint
@@ -6216,7 +6282,7 @@ function aInRange(title, n, min, max) {
6216
6282
  // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
6217
6283
  // - our way is the cleanest: `inRange('x', x, 0n, P)
6218
6284
  if (!inRange(n, min, max))
6219
- throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
6285
+ throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);
6220
6286
  }
6221
6287
  // Bit operations
6222
6288
  /**
@@ -6326,12 +6392,12 @@ function validateObject(object, validators, optValidators = {}) {
6326
6392
  const checkField = (fieldName, type, isOptional) => {
6327
6393
  const checkVal = validatorFns[type];
6328
6394
  if (typeof checkVal !== 'function')
6329
- throw new Error(`Invalid validator "${type}", expected function`);
6395
+ throw new Error('invalid validator function');
6330
6396
  const val = object[fieldName];
6331
6397
  if (isOptional && val === undefined)
6332
6398
  return;
6333
6399
  if (!checkVal(val, object)) {
6334
- throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
6400
+ throw new Error('param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val);
6335
6401
  }
6336
6402
  };
6337
6403
  for (const [fieldName, type] of Object.entries(validators))
@@ -6400,14 +6466,17 @@ var ut = /*#__PURE__*/Object.freeze({
6400
6466
  validateObject: validateObject
6401
6467
  });
6402
6468
 
6469
+ /**
6470
+ * Utils for modular division and finite fields.
6471
+ * A finite field over 11 is integer number operations `mod 11`.
6472
+ * There is no division: it is replaced by modular multiplicative inverse.
6473
+ * @module
6474
+ */
6403
6475
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
6404
- // Utilities for modular arithmetics and finite fields
6405
6476
  // prettier-ignore
6406
- const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
6477
+ const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = /* @__PURE__ */ BigInt(2), _3n$1 = /* @__PURE__ */ BigInt(3);
6407
6478
  // prettier-ignore
6408
- const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
6409
- // prettier-ignore
6410
- BigInt(9); BigInt(16);
6479
+ const _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _8n$2 = /* @__PURE__ */ BigInt(8);
6411
6480
  // Calculates a modulo b
6412
6481
  function mod(a, b) {
6413
6482
  const result = a % b;
@@ -6416,13 +6485,15 @@ function mod(a, b) {
6416
6485
  /**
6417
6486
  * Efficiently raise num to power and do modular division.
6418
6487
  * Unsafe in some contexts: uses ladder, so can expose bigint bits.
6488
+ * @todo use field version && remove
6419
6489
  * @example
6420
6490
  * pow(2n, 6n, 11n) // 64n % 11n == 9n
6421
6491
  */
6422
- // TODO: use field version && remove
6423
6492
  function pow(num, power, modulo) {
6424
- if (modulo <= _0n$3 || power < _0n$3)
6425
- throw new Error('Expected power/modulo > 0');
6493
+ if (power < _0n$3)
6494
+ throw new Error('invalid exponent, negatives unsupported');
6495
+ if (modulo <= _0n$3)
6496
+ throw new Error('invalid modulus');
6426
6497
  if (modulo === _1n$5)
6427
6498
  return _0n$3;
6428
6499
  let res = _1n$5;
@@ -6434,7 +6505,7 @@ function pow(num, power, modulo) {
6434
6505
  }
6435
6506
  return res;
6436
6507
  }
6437
- // Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)
6508
+ /** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
6438
6509
  function pow2(x, power, modulo) {
6439
6510
  let res = x;
6440
6511
  while (power-- > _0n$3) {
@@ -6443,12 +6514,15 @@ function pow2(x, power, modulo) {
6443
6514
  }
6444
6515
  return res;
6445
6516
  }
6446
- // Inverses number over modulo
6517
+ /**
6518
+ * Inverses number over modulo.
6519
+ * Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).
6520
+ */
6447
6521
  function invert(number, modulo) {
6448
- if (number === _0n$3 || modulo <= _0n$3) {
6449
- throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
6450
- }
6451
- // Euclidean GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
6522
+ if (number === _0n$3)
6523
+ throw new Error('invert: expected non-zero number');
6524
+ if (modulo <= _0n$3)
6525
+ throw new Error('invert: expected positive modulus, got ' + modulo);
6452
6526
  // Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
6453
6527
  let a = mod(number, modulo);
6454
6528
  let b = modulo;
@@ -6488,8 +6562,11 @@ function tonelliShanks(P) {
6488
6562
  for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
6489
6563
  ;
6490
6564
  // Step 2: Select a non-square z such that (z | p) โ‰ก -1 and set c โ‰ก zq
6491
- for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++)
6492
- ;
6565
+ for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++) {
6566
+ // Crash instead of infinity loop, we cannot reasonable count until P.
6567
+ if (Z > 1000)
6568
+ throw new Error('Cannot find square root: likely non-prime P');
6569
+ }
6493
6570
  // Fast-path
6494
6571
  if (S === 1) {
6495
6572
  const p1div4 = (P + _1n$5) / _4n;
@@ -6531,9 +6608,18 @@ function tonelliShanks(P) {
6531
6608
  return x;
6532
6609
  };
6533
6610
  }
6611
+ /**
6612
+ * Square root for a finite field. It will try to check if optimizations are applicable and fall back to 4:
6613
+ *
6614
+ * 1. P โ‰ก 3 (mod 4)
6615
+ * 2. P โ‰ก 5 (mod 8)
6616
+ * 3. P โ‰ก 9 (mod 16)
6617
+ * 4. Tonelli-Shanks algorithm
6618
+ *
6619
+ * Different algorithms can give different roots, it is up to user to decide which one they want.
6620
+ * For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
6621
+ */
6534
6622
  function FpSqrt(P) {
6535
- // NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
6536
- // For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
6537
6623
  // P โ‰ก 3 (mod 4)
6538
6624
  // โˆšn = n^((P+1)/4)
6539
6625
  if (P % _4n === _3n$1) {
@@ -6597,7 +6683,7 @@ function FpPow(f, num, power) {
6597
6683
  // Should have same speed as pow for bigints
6598
6684
  // TODO: benchmark!
6599
6685
  if (power < _0n$3)
6600
- throw new Error('Expected power > 0');
6686
+ throw new Error('invalid exponent, negatives unsupported');
6601
6687
  if (power === _0n$3)
6602
6688
  return f.ONE;
6603
6689
  if (power === _1n$5)
@@ -6644,15 +6730,15 @@ function nLength(n, nBitLength) {
6644
6730
  return { nBitLength: _nBitLength, nByteLength };
6645
6731
  }
6646
6732
  /**
6647
- * Initializes a finite field over prime. **Non-primes are not supported.**
6648
- * Do not init in loop: slow. Very fragile: always run a benchmark on a change.
6733
+ * Initializes a finite field over prime.
6649
6734
  * Major performance optimizations:
6650
6735
  * * a) denormalized operations like mulN instead of mul
6651
6736
  * * b) same object shape: never add or remove keys
6652
6737
  * * c) Object.freeze
6653
- * NOTE: operations don't check 'isValid' for all elements for performance reasons,
6738
+ * Fragile: always run a benchmark on a change.
6739
+ * Security note: operations don't check 'isValid' for all elements for performance reasons,
6654
6740
  * it is caller responsibility to check this.
6655
- * This is low-level code, please make sure you know what you doing.
6741
+ * This is low-level code, please make sure you know what you're doing.
6656
6742
  * @param ORDER prime positive bigint
6657
6743
  * @param bitLen how many bits the field consumes
6658
6744
  * @param isLE (def: false) if encoding / decoding should be in little-endian
@@ -6660,13 +6746,14 @@ function nLength(n, nBitLength) {
6660
6746
  */
6661
6747
  function Field(ORDER, bitLen, isLE = false, redef = {}) {
6662
6748
  if (ORDER <= _0n$3)
6663
- throw new Error(`Expected Field ORDER > 0, got ${ORDER}`);
6749
+ throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
6664
6750
  const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
6665
6751
  if (BYTES > 2048)
6666
- throw new Error('Field lengths over 2048 bytes are not supported');
6667
- const sqrtP = FpSqrt(ORDER);
6752
+ throw new Error('invalid field: expected ORDER of <= 2048 bytes');
6753
+ let sqrtP; // cached sqrtP
6668
6754
  const f = Object.freeze({
6669
6755
  ORDER,
6756
+ isLE,
6670
6757
  BITS,
6671
6758
  BYTES,
6672
6759
  MASK: bitMask(BITS),
@@ -6675,7 +6762,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6675
6762
  create: (num) => mod(num, ORDER),
6676
6763
  isValid: (num) => {
6677
6764
  if (typeof num !== 'bigint')
6678
- throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
6765
+ throw new Error('invalid field element: expected bigint, got ' + typeof num);
6679
6766
  return _0n$3 <= num && num < ORDER; // 0 is valid element, but it's not invertible
6680
6767
  },
6681
6768
  is0: (num) => num === _0n$3,
@@ -6694,7 +6781,12 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6694
6781
  subN: (lhs, rhs) => lhs - rhs,
6695
6782
  mulN: (lhs, rhs) => lhs * rhs,
6696
6783
  inv: (num) => invert(num, ORDER),
6697
- sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
6784
+ sqrt: redef.sqrt ||
6785
+ ((n) => {
6786
+ if (!sqrtP)
6787
+ sqrtP = FpSqrt(ORDER);
6788
+ return sqrtP(f, n);
6789
+ }),
6698
6790
  invertBatch: (lst) => FpInvertBatch(f, lst),
6699
6791
  // TODO: do we really need constant cmov?
6700
6792
  // We don't have const-time bigints anyway, so probably will be not very useful
@@ -6702,7 +6794,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6702
6794
  toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
6703
6795
  fromBytes: (bytes) => {
6704
6796
  if (bytes.length !== BYTES)
6705
- throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
6797
+ throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
6706
6798
  return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
6707
6799
  },
6708
6800
  });
@@ -6750,52 +6842,80 @@ function mapHashToField(key, fieldOrder, isLE = false) {
6750
6842
  const minLen = getMinHashLength(fieldOrder);
6751
6843
  // No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.
6752
6844
  if (len < 16 || len < minLen || len > 1024)
6753
- throw new Error(`expected ${minLen}-1024 bytes of input, got ${len}`);
6754
- const num = isLE ? bytesToNumberBE(key) : bytesToNumberLE(key);
6845
+ throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
6846
+ const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
6755
6847
  // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
6756
6848
  const reduced = mod(num, fieldOrder - _1n$5) + _1n$5;
6757
6849
  return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
6758
6850
  }
6759
6851
 
6852
+ /**
6853
+ * Methods for elliptic curve multiplication by scalars.
6854
+ * Contains wNAF, pippenger
6855
+ * @module
6856
+ */
6760
6857
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
6761
- // Abelian group utilities
6762
6858
  const _0n$2 = BigInt(0);
6763
6859
  const _1n$4 = BigInt(1);
6860
+ function constTimeNegate(condition, item) {
6861
+ const neg = item.negate();
6862
+ return condition ? neg : item;
6863
+ }
6864
+ function validateW(W, bits) {
6865
+ if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
6866
+ throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);
6867
+ }
6868
+ function calcWOpts(W, bits) {
6869
+ validateW(W, bits);
6870
+ const windows = Math.ceil(bits / W) + 1; // +1, because
6871
+ const windowSize = 2 ** (W - 1); // -1 because we skip zero
6872
+ return { windows, windowSize };
6873
+ }
6874
+ function validateMSMPoints(points, c) {
6875
+ if (!Array.isArray(points))
6876
+ throw new Error('array expected');
6877
+ points.forEach((p, i) => {
6878
+ if (!(p instanceof c))
6879
+ throw new Error('invalid point at index ' + i);
6880
+ });
6881
+ }
6882
+ function validateMSMScalars(scalars, field) {
6883
+ if (!Array.isArray(scalars))
6884
+ throw new Error('array of scalars expected');
6885
+ scalars.forEach((s, i) => {
6886
+ if (!field.isValid(s))
6887
+ throw new Error('invalid scalar at index ' + i);
6888
+ });
6889
+ }
6764
6890
  // Since points in different groups cannot be equal (different object constructor),
6765
6891
  // we can have single place to store precomputes
6766
6892
  const pointPrecomputes = new WeakMap();
6767
6893
  const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
6768
- // Elliptic curve multiplication of Point by scalar. Fragile.
6769
- // Scalars should always be less than curve order: this should be checked inside of a curve itself.
6770
- // Creates precomputation tables for fast multiplication:
6771
- // - private scalar is split by fixed size windows of W bits
6772
- // - every window point is collected from window's table & added to accumulator
6773
- // - since windows are different, same point inside tables won't be accessed more than once per calc
6774
- // - each multiplication is 'Math.ceil(CURVE_ORDER / ๐‘Š) + 1' point additions (fixed for any scalar)
6775
- // - +1 window is neccessary for wNAF
6776
- // - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
6777
- // TODO: Research returning 2d JS array of windows, instead of a single window. This would allow
6778
- // windows to be in different memory locations
6894
+ function getW(P) {
6895
+ return pointWindowSizes.get(P) || 1;
6896
+ }
6897
+ /**
6898
+ * Elliptic curve multiplication of Point by scalar. Fragile.
6899
+ * Scalars should always be less than curve order: this should be checked inside of a curve itself.
6900
+ * Creates precomputation tables for fast multiplication:
6901
+ * - private scalar is split by fixed size windows of W bits
6902
+ * - every window point is collected from window's table & added to accumulator
6903
+ * - since windows are different, same point inside tables won't be accessed more than once per calc
6904
+ * - each multiplication is 'Math.ceil(CURVE_ORDER / ๐‘Š) + 1' point additions (fixed for any scalar)
6905
+ * - +1 window is neccessary for wNAF
6906
+ * - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
6907
+ *
6908
+ * @todo Research returning 2d JS array of windows, instead of a single window.
6909
+ * This would allow windows to be in different memory locations
6910
+ */
6779
6911
  function wNAF(c, bits) {
6780
- const constTimeNegate = (condition, item) => {
6781
- const neg = item.negate();
6782
- return condition ? neg : item;
6783
- };
6784
- const validateW = (W) => {
6785
- if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
6786
- throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
6787
- };
6788
- const opts = (W) => {
6789
- validateW(W);
6790
- const windows = Math.ceil(bits / W) + 1; // +1, because
6791
- const windowSize = 2 ** (W - 1); // -1 because we skip zero
6792
- return { windows, windowSize };
6793
- };
6794
6912
  return {
6795
6913
  constTimeNegate,
6914
+ hasPrecomputes(elm) {
6915
+ return getW(elm) !== 1;
6916
+ },
6796
6917
  // non-const time multiplication ladder
6797
- unsafeLadder(elm, n) {
6798
- let p = c.ZERO;
6918
+ unsafeLadder(elm, n, p = c.ZERO) {
6799
6919
  let d = elm;
6800
6920
  while (n > _0n$2) {
6801
6921
  if (n & _1n$4)
@@ -6813,10 +6933,12 @@ function wNAF(c, bits) {
6813
6933
  * - ๐‘Š is the window size
6814
6934
  * - ๐‘› is the bitlength of the curve order.
6815
6935
  * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
6936
+ * @param elm Point instance
6937
+ * @param W window size
6816
6938
  * @returns precomputed point tables flattened to a single array
6817
6939
  */
6818
6940
  precomputeWindow(elm, W) {
6819
- const { windows, windowSize } = opts(W);
6941
+ const { windows, windowSize } = calcWOpts(W, bits);
6820
6942
  const points = [];
6821
6943
  let p = elm;
6822
6944
  let base = p;
@@ -6842,7 +6964,7 @@ function wNAF(c, bits) {
6842
6964
  wNAF(W, precomputes, n) {
6843
6965
  // TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
6844
6966
  // But need to carefully remove other checks before wNAF. ORDER == bits here
6845
- const { windows, windowSize } = opts(W);
6967
+ const { windows, windowSize } = calcWOpts(W, bits);
6846
6968
  let p = c.ZERO;
6847
6969
  let f = c.BASE;
6848
6970
  const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
@@ -6886,8 +7008,44 @@ function wNAF(c, bits) {
6886
7008
  // which makes it less const-time: around 1 bigint multiply.
6887
7009
  return { p, f };
6888
7010
  },
6889
- wNAFCached(P, n, transform) {
6890
- const W = pointWindowSizes.get(P) || 1;
7011
+ /**
7012
+ * Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
7013
+ * @param W window size
7014
+ * @param precomputes precomputed tables
7015
+ * @param n scalar (we don't check here, but should be less than curve order)
7016
+ * @param acc accumulator point to add result of multiplication
7017
+ * @returns point
7018
+ */
7019
+ wNAFUnsafe(W, precomputes, n, acc = c.ZERO) {
7020
+ const { windows, windowSize } = calcWOpts(W, bits);
7021
+ const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
7022
+ const maxNumber = 2 ** W;
7023
+ const shiftBy = BigInt(W);
7024
+ for (let window = 0; window < windows; window++) {
7025
+ const offset = window * windowSize;
7026
+ if (n === _0n$2)
7027
+ break; // No need to go over empty scalar
7028
+ // Extract W bits.
7029
+ let wbits = Number(n & mask);
7030
+ // Shift number by W bits.
7031
+ n >>= shiftBy;
7032
+ // If the bits are bigger than max size, we'll split those.
7033
+ // +224 => 256 - 32
7034
+ if (wbits > windowSize) {
7035
+ wbits -= maxNumber;
7036
+ n += _1n$4;
7037
+ }
7038
+ if (wbits === 0)
7039
+ continue;
7040
+ let curr = precomputes[offset + Math.abs(wbits) - 1]; // -1 because we skip zero
7041
+ if (wbits < 0)
7042
+ curr = curr.negate();
7043
+ // NOTE: by re-using acc, we can save a lot of additions in case of MSM
7044
+ acc = acc.add(curr);
7045
+ }
7046
+ return acc;
7047
+ },
7048
+ getPrecomputes(W, P, transform) {
6891
7049
  // Calculate precomputes on a first run, reuse them after
6892
7050
  let comp = pointPrecomputes.get(P);
6893
7051
  if (!comp) {
@@ -6895,18 +7053,76 @@ function wNAF(c, bits) {
6895
7053
  if (W !== 1)
6896
7054
  pointPrecomputes.set(P, transform(comp));
6897
7055
  }
6898
- return this.wNAF(W, comp, n);
7056
+ return comp;
7057
+ },
7058
+ wNAFCached(P, n, transform) {
7059
+ const W = getW(P);
7060
+ return this.wNAF(W, this.getPrecomputes(W, P, transform), n);
7061
+ },
7062
+ wNAFCachedUnsafe(P, n, transform, prev) {
7063
+ const W = getW(P);
7064
+ if (W === 1)
7065
+ return this.unsafeLadder(P, n, prev); // For W=1 ladder is ~x2 faster
7066
+ return this.wNAFUnsafe(W, this.getPrecomputes(W, P, transform), n, prev);
6899
7067
  },
6900
7068
  // We calculate precomputes for elliptic curve point multiplication
6901
7069
  // using windowed method. This specifies window size and
6902
7070
  // stores precomputed values. Usually only base point would be precomputed.
6903
7071
  setWindowSize(P, W) {
6904
- validateW(W);
7072
+ validateW(W, bits);
6905
7073
  pointWindowSizes.set(P, W);
6906
7074
  pointPrecomputes.delete(P);
6907
7075
  },
6908
7076
  };
6909
7077
  }
7078
+ /**
7079
+ * Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
7080
+ * 30x faster vs naive addition on L=4096, 10x faster with precomputes.
7081
+ * For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
7082
+ * Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
7083
+ * @param c Curve Point constructor
7084
+ * @param fieldN field over CURVE.N - important that it's not over CURVE.P
7085
+ * @param points array of L curve points
7086
+ * @param scalars array of L scalars (aka private keys / bigints)
7087
+ */
7088
+ function pippenger(c, fieldN, points, scalars) {
7089
+ // If we split scalars by some window (let's say 8 bits), every chunk will only
7090
+ // take 256 buckets even if there are 4096 scalars, also re-uses double.
7091
+ // TODO:
7092
+ // - https://eprint.iacr.org/2024/750.pdf
7093
+ // - https://tches.iacr.org/index.php/TCHES/article/view/10287
7094
+ // 0 is accepted in scalars
7095
+ validateMSMPoints(points, c);
7096
+ validateMSMScalars(scalars, fieldN);
7097
+ if (points.length !== scalars.length)
7098
+ throw new Error('arrays of points and scalars must have equal length');
7099
+ const zero = c.ZERO;
7100
+ const wbits = bitLen(BigInt(points.length));
7101
+ const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
7102
+ const MASK = (1 << windowSize) - 1;
7103
+ const buckets = new Array(MASK + 1).fill(zero); // +1 for zero array
7104
+ const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
7105
+ let sum = zero;
7106
+ for (let i = lastBits; i >= 0; i -= windowSize) {
7107
+ buckets.fill(zero);
7108
+ for (let j = 0; j < scalars.length; j++) {
7109
+ const scalar = scalars[j];
7110
+ const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
7111
+ buckets[wbits] = buckets[wbits].add(points[j]);
7112
+ }
7113
+ let resI = zero; // not using this will do small speed-up, but will lose ct
7114
+ // Skip first bucket, because it is zero
7115
+ for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
7116
+ sumI = sumI.add(buckets[j]);
7117
+ resI = resI.add(sumI);
7118
+ }
7119
+ sum = sum.add(resI);
7120
+ if (i !== 0)
7121
+ for (let j = 0; j < windowSize; j++)
7122
+ sum = sum.double();
7123
+ }
7124
+ return sum;
7125
+ }
6910
7126
  function validateBasic(curve) {
6911
7127
  validateField(curve.Fp);
6912
7128
  validateObject(curve, {
@@ -6926,8 +7142,12 @@ function validateBasic(curve) {
6926
7142
  });
6927
7143
  }
6928
7144
 
6929
- /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
6930
- // Twisted Edwards curve. The formula is: axยฒ + yยฒ = 1 + dxยฒyยฒ
7145
+ /**
7146
+ * Twisted Edwards curve. The formula is: axยฒ + yยฒ = 1 + dxยฒyยฒ.
7147
+ * For design rationale of types / exports, see weierstrass module documentation.
7148
+ * @module
7149
+ */
7150
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
6931
7151
  // Be friendly to bad ECMAScript parsers by not using bigint literals
6932
7152
  // prettier-ignore
6933
7153
  const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
@@ -6959,8 +7179,13 @@ function validateOpts$1(curve) {
6959
7179
  function twistedEdwards(curveDef) {
6960
7180
  const CURVE = validateOpts$1(curveDef);
6961
7181
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
7182
+ // Important:
7183
+ // There are some places where Fp.BYTES is used instead of nByteLength.
7184
+ // So far, everything has been tested with curves of Fp.BYTES == nByteLength.
7185
+ // TODO: test and find curves which behave otherwise.
6962
7186
  const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
6963
7187
  const modP = Fp.create; // Function overrides
7188
+ const Fn = Field(CURVE.n, CURVE.nBitLength);
6964
7189
  // sqrt(u/v)
6965
7190
  const uvRatio = CURVE.uvRatio ||
6966
7191
  ((u, v) => {
@@ -7059,6 +7284,10 @@ function twistedEdwards(curveDef) {
7059
7284
  const toInv = Fp.invertBatch(points.map((p) => p.ez));
7060
7285
  return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
7061
7286
  }
7287
+ // Multiscalar Multiplication
7288
+ static msm(points, scalars) {
7289
+ return pippenger(Point, Fn, points, scalars);
7290
+ }
7062
7291
  // "Private method", don't use it directly
7063
7292
  _setWindowSize(windowSize) {
7064
7293
  wnaf.setWindowSize(this, windowSize);
@@ -7167,16 +7396,15 @@ function twistedEdwards(curveDef) {
7167
7396
  // It's faster, but should only be used when you don't care about
7168
7397
  // an exposed private key e.g. sig verification.
7169
7398
  // Does NOT allow scalars higher than CURVE.n.
7170
- multiplyUnsafe(scalar) {
7399
+ // Accepts optional accumulator to merge with multiply (important for sparse scalars)
7400
+ multiplyUnsafe(scalar, acc = Point.ZERO) {
7171
7401
  const n = scalar;
7172
7402
  aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
7173
7403
  if (n === _0n$1)
7174
7404
  return I;
7175
- if (this.equals(I) || n === _1n$3)
7405
+ if (this.is0() || n === _1n$3)
7176
7406
  return this;
7177
- if (this.equals(G))
7178
- return this.wNAF(n).p;
7179
- return wnaf.unsafeLadder(this, n);
7407
+ return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
7180
7408
  }
7181
7409
  // Checks if point is of small order.
7182
7410
  // If you add something to small order point, you will have "dirty"
@@ -7210,8 +7438,9 @@ function twistedEdwards(curveDef) {
7210
7438
  abool('zip215', zip215);
7211
7439
  const normed = hex.slice(); // copy again, we'll manipulate it
7212
7440
  const lastByte = hex[len - 1]; // select last byte
7213
- normed[len - 1] = lastByte & ~0x80; // clear last bit
7441
+ normed[len - 1] = lastByte & -129; // clear last bit
7214
7442
  const y = bytesToNumberLE(normed);
7443
+ // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
7215
7444
  // RFC8032 prohibits >= p, but ZIP215 doesn't
7216
7445
  // zip215=true: 0 <= y < MASK (2^256 for ed25519)
7217
7446
  // zip215=false: 0 <= y < P (2^255-19 for ed25519)
@@ -7260,7 +7489,7 @@ function twistedEdwards(curveDef) {
7260
7489
  }
7261
7490
  /** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
7262
7491
  function getExtendedPublicKey(key) {
7263
- const len = nByteLength;
7492
+ const len = Fp.BYTES;
7264
7493
  key = ensureBytes('private key', key, len);
7265
7494
  // Hash private key with curve's hash function to produce uniformingly random input
7266
7495
  // Check byte lengths: ensure(64, h(ensure(32, key)))
@@ -7293,23 +7522,29 @@ function twistedEdwards(curveDef) {
7293
7522
  const s = modN(r + k * scalar); // S = (r + k * s) mod L
7294
7523
  aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
7295
7524
  const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
7296
- return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
7525
+ return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
7297
7526
  }
7298
7527
  const verifyOpts = VERIFY_DEFAULT;
7528
+ /**
7529
+ * Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
7530
+ * An extended group equation is checked.
7531
+ */
7299
7532
  function verify(sig, msg, publicKey, options = verifyOpts) {
7300
7533
  const { context, zip215 } = options;
7301
7534
  const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
7302
7535
  sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
7303
7536
  msg = ensureBytes('message', msg);
7537
+ publicKey = ensureBytes('publicKey', publicKey, len);
7304
7538
  if (zip215 !== undefined)
7305
7539
  abool('zip215', zip215);
7306
7540
  if (prehash)
7307
7541
  msg = prehash(msg); // for ed25519ph, etc
7308
7542
  const s = bytesToNumberLE(sig.slice(len, 2 * len));
7309
- // zip215: true is good for consensus-critical apps and allows points < 2^256
7310
- // zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
7311
7543
  let A, R, SB;
7312
7544
  try {
7545
+ // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
7546
+ // zip215=true: 0 <= y < MASK (2^256 for ed25519)
7547
+ // zip215=false: 0 <= y < P (2^255-19 for ed25519)
7313
7548
  A = Point.fromHex(publicKey, zip215);
7314
7549
  R = Point.fromHex(sig.slice(0, len), zip215);
7315
7550
  SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
@@ -7321,6 +7556,7 @@ function twistedEdwards(curveDef) {
7321
7556
  return false;
7322
7557
  const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
7323
7558
  const RkA = R.add(A.multiplyUnsafe(k));
7559
+ // Extended group equation
7324
7560
  // [8][S]B = [8]R + [8][k]A'
7325
7561
  return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
7326
7562
  }
@@ -7351,13 +7587,14 @@ function twistedEdwards(curveDef) {
7351
7587
  };
7352
7588
  }
7353
7589
 
7354
- /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
7355
7590
  /**
7356
7591
  * ed25519 Twisted Edwards curve with following addons:
7357
7592
  * - X25519 ECDH
7358
7593
  * - Ristretto cofactor elimination
7359
7594
  * - Elligator hash-to-group / point indistinguishability
7595
+ * @module
7360
7596
  */
7597
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
7361
7598
  const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
7362
7599
  // โˆš(-1) aka โˆš(a) aka 2^((p-1)/4)
7363
7600
  const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
@@ -7416,7 +7653,7 @@ function uvRatio(u, v) {
7416
7653
  x = mod(-x, P);
7417
7654
  return { isValid: useRoot1 || useRoot2, value: x };
7418
7655
  }
7419
- const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
7656
+ const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
7420
7657
  const ed25519Defaults = /* @__PURE__ */ (() => ({
7421
7658
  // Param: a
7422
7659
  a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
@@ -7424,7 +7661,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
7424
7661
  // Negative number is P - number, and division is invert(number, P)
7425
7662
  d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
7426
7663
  // Finite field ๐”ฝp over which we'll do calculations; 2n**255n - 19n
7427
- Fp: Fp$1,
7664
+ Fp,
7428
7665
  // Subgroup order: how many points curve has
7429
7666
  // 2n**252n + 27742317777372353535851937790883648493n;
7430
7667
  n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
@@ -7434,7 +7671,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
7434
7671
  Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
7435
7672
  Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
7436
7673
  hash: sha512,
7437
- randomBytes: randomBytes$1,
7674
+ randomBytes,
7438
7675
  adjustScalarBytes,
7439
7676
  // dom2
7440
7677
  // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
@@ -7443,180 +7680,58 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
7443
7680
  }))();
7444
7681
  /**
7445
7682
  * ed25519 curve with EdDSA signatures.
7683
+ * @example
7684
+ * import { ed25519 } from '@noble/curves/ed25519';
7685
+ * const priv = ed25519.utils.randomPrivateKey();
7686
+ * const pub = ed25519.getPublicKey(priv);
7687
+ * const msg = new TextEncoder().encode('hello');
7688
+ * const sig = ed25519.sign(msg, priv);
7689
+ * ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
7690
+ * ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5
7446
7691
  */
7447
7692
  const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
7448
7693
 
7449
7694
  const PUBLIC_KEY_BYTE_LENGTH = 32;
7450
- const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
7451
- const KEYS_BYTE_LENGTH = 32;
7452
- function generateKey$2() {
7453
- // the actual private key (32 bytes)
7454
- const privateKeyRaw = ed25519.utils.randomPrivateKey();
7455
- const publicKey = ed25519.getPublicKey(privateKeyRaw);
7456
- // concatenated the public key to the private key
7457
- const privateKey = concatKeys(privateKeyRaw, publicKey);
7458
- return {
7459
- privateKey,
7460
- publicKey
7461
- };
7462
- }
7463
- /**
7464
- * Generate keypair from a 32 byte uint8array
7465
- */
7466
- function generateKeyFromSeed(seed) {
7467
- if (seed.length !== KEYS_BYTE_LENGTH) {
7468
- throw new TypeError('"seed" must be 32 bytes in length.');
7469
- }
7470
- else if (!(seed instanceof Uint8Array)) {
7471
- throw new TypeError('"seed" must be a node.js Buffer, or Uint8Array.');
7472
- }
7473
- // based on node forges algorithm, the seed is used directly as private key
7474
- const privateKeyRaw = seed;
7475
- const publicKey = ed25519.getPublicKey(privateKeyRaw);
7476
- const privateKey = concatKeys(privateKeyRaw, publicKey);
7477
- return {
7478
- privateKey,
7479
- publicKey
7480
- };
7481
- }
7482
- function hashAndSign$2(privateKey, msg) {
7483
- const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH);
7484
- return ed25519.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw);
7485
- }
7486
7695
  function hashAndVerify$2(publicKey, sig, msg) {
7487
7696
  return ed25519.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey);
7488
7697
  }
7489
- function concatKeys(privateKeyRaw, publicKey) {
7490
- const privateKey = new Uint8Array(PRIVATE_KEY_BYTE_LENGTH);
7491
- for (let i = 0; i < KEYS_BYTE_LENGTH; i++) {
7492
- privateKey[i] = privateKeyRaw[i];
7493
- privateKey[KEYS_BYTE_LENGTH + i] = publicKey[i];
7494
- }
7495
- return privateKey;
7496
- }
7497
7698
 
7498
- /* eslint-env browser */
7499
- // Check native crypto exists and is enabled (In insecure context `self.crypto`
7500
- // exists but `self.crypto.subtle` does not).
7501
- var webcrypto = {
7502
- get(win = globalThis) {
7503
- const nativeCrypto = win.crypto;
7504
- if (nativeCrypto?.subtle == null) {
7505
- throw Object.assign(new Error('Missing Web Crypto API. ' +
7506
- 'The most likely cause of this error is that this page is being accessed ' +
7507
- 'from an insecure context (i.e. not HTTPS). For more information and ' +
7508
- 'possible resolutions see ' +
7509
- 'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api'), { code: 'ERR_MISSING_WEB_CRYPTO' });
7510
- }
7511
- return nativeCrypto;
7699
+ class Ed25519PublicKey {
7700
+ type = 'Ed25519';
7701
+ raw;
7702
+ constructor(key) {
7703
+ this.raw = ensureEd25519Key(key, PUBLIC_KEY_BYTE_LENGTH);
7512
7704
  }
7513
- };
7514
-
7515
- // WebKit on Linux does not support deriving a key from an empty PBKDF2 key.
7516
- // So, as a workaround, we provide the generated key as a constant. We test that
7517
- // this generated key is accurate in test/workaround.spec.ts
7518
- // Generated via:
7519
- // await crypto.subtle.exportKey('jwk',
7520
- // await crypto.subtle.deriveKey(
7521
- // { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } },
7522
- // await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']),
7523
- // { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt'])
7524
- // )
7525
- const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
7526
- // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
7527
- function create(opts) {
7528
- const algorithm = 'AES-GCM';
7529
- let keyLength = 16;
7530
- const nonceLength = 12;
7531
- const digest = 'SHA-256';
7532
- const saltLength = 16;
7533
- const iterations = 32767;
7534
- const crypto = webcrypto.get();
7535
- keyLength *= 8; // Browser crypto uses bits instead of bytes
7536
- /**
7537
- * Uses the provided password to derive a pbkdf2 key. The key
7538
- * will then be used to encrypt the data.
7539
- */
7540
- async function encrypt(data, password) {
7541
- const salt = crypto.getRandomValues(new Uint8Array(saltLength));
7542
- const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
7543
- const aesGcm = { name: algorithm, iv: nonce };
7544
- if (typeof password === 'string') {
7545
- password = fromString(password);
7546
- }
7547
- let cryptoKey;
7548
- if (password.length === 0) {
7549
- cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
7550
- try {
7551
- const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
7552
- const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
7553
- cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['encrypt']);
7554
- }
7555
- catch {
7556
- cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
7557
- }
7558
- }
7559
- else {
7560
- // Derive a key using PBKDF2.
7561
- const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
7562
- const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
7563
- cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']);
7564
- }
7565
- // Encrypt the string.
7566
- const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data);
7567
- return concat$1([salt, aesGcm.iv, new Uint8Array(ciphertext)]);
7705
+ toMultihash() {
7706
+ return identity.digest(publicKeyToProtobuf(this));
7568
7707
  }
7569
- /**
7570
- * Uses the provided password to derive a pbkdf2 key. The key
7571
- * will then be used to decrypt the data. The options used to create
7572
- * this decryption cipher must be the same as those used to create
7573
- * the encryption cipher.
7574
- */
7575
- async function decrypt(data, password) {
7576
- const salt = data.subarray(0, saltLength);
7577
- const nonce = data.subarray(saltLength, saltLength + nonceLength);
7578
- const ciphertext = data.subarray(saltLength + nonceLength);
7579
- const aesGcm = { name: algorithm, iv: nonce };
7580
- if (typeof password === 'string') {
7581
- password = fromString(password);
7582
- }
7583
- let cryptoKey;
7584
- if (password.length === 0) {
7585
- try {
7586
- const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
7587
- const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
7588
- cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['decrypt']);
7589
- }
7590
- catch {
7591
- cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']);
7592
- }
7708
+ toCID() {
7709
+ return CID.createV1(114, this.toMultihash());
7710
+ }
7711
+ toString() {
7712
+ return base58btc.encode(this.toMultihash().bytes).substring(1);
7713
+ }
7714
+ equals(key) {
7715
+ if (key == null || !(key.raw instanceof Uint8Array)) {
7716
+ return false;
7593
7717
  }
7594
- else {
7595
- // Derive the key using PBKDF2.
7596
- const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
7597
- const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
7598
- cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['decrypt']);
7599
- }
7600
- // Decrypt the string.
7601
- const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext);
7602
- return new Uint8Array(plaintext);
7603
- }
7604
- const cipher = {
7605
- encrypt,
7606
- decrypt
7607
- };
7608
- return cipher;
7718
+ return equals(this.raw, key.raw);
7719
+ }
7720
+ verify(data, sig) {
7721
+ return hashAndVerify$2(this.raw, sig, data);
7722
+ }
7609
7723
  }
7610
7724
 
7611
- /**
7612
- * Exports the given PrivateKey as a base64 encoded string.
7613
- * The PrivateKey is encrypted via a password derived PBKDF2 key
7614
- * leveraging the aes-gcm cipher algorithm.
7615
- */
7616
- async function exporter(privateKey, password) {
7617
- const cipher = create();
7618
- const encryptedKey = await cipher.encrypt(privateKey, password);
7619
- return base64.encode(encryptedKey);
7725
+ function unmarshalEd25519PublicKey(bytes) {
7726
+ bytes = ensureEd25519Key(bytes, PUBLIC_KEY_BYTE_LENGTH);
7727
+ return new Ed25519PublicKey(bytes);
7728
+ }
7729
+ function ensureEd25519Key(key, length) {
7730
+ key = Uint8Array.from(key ?? []);
7731
+ if (key.length !== length) {
7732
+ throw new InvalidParametersError(`Key must be a Uint8Array of length ${length}, got ${key.length}`);
7733
+ }
7734
+ return key;
7620
7735
  }
7621
7736
 
7622
7737
  const f32 = new Float32Array([-0]);
@@ -8825,13 +8940,13 @@ var KeyType;
8825
8940
  (function (KeyType) {
8826
8941
  KeyType["RSA"] = "RSA";
8827
8942
  KeyType["Ed25519"] = "Ed25519";
8828
- KeyType["Secp256k1"] = "Secp256k1";
8943
+ KeyType["secp256k1"] = "secp256k1";
8829
8944
  })(KeyType || (KeyType = {}));
8830
8945
  var __KeyTypeValues;
8831
8946
  (function (__KeyTypeValues) {
8832
8947
  __KeyTypeValues[__KeyTypeValues["RSA"] = 0] = "RSA";
8833
8948
  __KeyTypeValues[__KeyTypeValues["Ed25519"] = 1] = "Ed25519";
8834
- __KeyTypeValues[__KeyTypeValues["Secp256k1"] = 2] = "Secp256k1";
8949
+ __KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1";
8835
8950
  })(__KeyTypeValues || (__KeyTypeValues = {}));
8836
8951
  (function (KeyType) {
8837
8952
  KeyType.codec = () => {
@@ -8858,21 +8973,24 @@ var PublicKey;
8858
8973
  if (opts.lengthDelimited !== false) {
8859
8974
  w.ldelim();
8860
8975
  }
8861
- }, (reader, length) => {
8976
+ }, (reader, length, opts = {}) => {
8862
8977
  const obj = {};
8863
8978
  const end = length == null ? reader.len : reader.pos + length;
8864
8979
  while (reader.pos < end) {
8865
8980
  const tag = reader.uint32();
8866
8981
  switch (tag >>> 3) {
8867
- case 1:
8982
+ case 1: {
8868
8983
  obj.Type = KeyType.codec().decode(reader);
8869
8984
  break;
8870
- case 2:
8985
+ }
8986
+ case 2: {
8871
8987
  obj.Data = reader.bytes();
8872
8988
  break;
8873
- default:
8989
+ }
8990
+ default: {
8874
8991
  reader.skipType(tag & 7);
8875
8992
  break;
8993
+ }
8876
8994
  }
8877
8995
  }
8878
8996
  return obj;
@@ -8883,8 +9001,8 @@ var PublicKey;
8883
9001
  PublicKey.encode = (obj) => {
8884
9002
  return encodeMessage(obj, PublicKey.codec());
8885
9003
  };
8886
- PublicKey.decode = (buf) => {
8887
- return decodeMessage(buf, PublicKey.codec());
9004
+ PublicKey.decode = (buf, opts) => {
9005
+ return decodeMessage(buf, PublicKey.codec(), opts);
8888
9006
  };
8889
9007
  })(PublicKey || (PublicKey = {}));
8890
9008
  var PrivateKey;
@@ -8907,21 +9025,24 @@ var PrivateKey;
8907
9025
  if (opts.lengthDelimited !== false) {
8908
9026
  w.ldelim();
8909
9027
  }
8910
- }, (reader, length) => {
9028
+ }, (reader, length, opts = {}) => {
8911
9029
  const obj = {};
8912
9030
  const end = length == null ? reader.len : reader.pos + length;
8913
9031
  while (reader.pos < end) {
8914
9032
  const tag = reader.uint32();
8915
9033
  switch (tag >>> 3) {
8916
- case 1:
9034
+ case 1: {
8917
9035
  obj.Type = KeyType.codec().decode(reader);
8918
9036
  break;
8919
- case 2:
9037
+ }
9038
+ case 2: {
8920
9039
  obj.Data = reader.bytes();
8921
9040
  break;
8922
- default:
9041
+ }
9042
+ default: {
8923
9043
  reader.skipType(tag & 7);
8924
9044
  break;
9045
+ }
8925
9046
  }
8926
9047
  }
8927
9048
  return obj;
@@ -8932,286 +9053,15 @@ var PrivateKey;
8932
9053
  PrivateKey.encode = (obj) => {
8933
9054
  return encodeMessage(obj, PrivateKey.codec());
8934
9055
  };
8935
- PrivateKey.decode = (buf) => {
8936
- return decodeMessage(buf, PrivateKey.codec());
9056
+ PrivateKey.decode = (buf, opts) => {
9057
+ return decodeMessage(buf, PrivateKey.codec(), opts);
8937
9058
  };
8938
9059
  })(PrivateKey || (PrivateKey = {}));
8939
9060
 
8940
- class Ed25519PublicKey {
8941
- _key;
8942
- constructor(key) {
8943
- this._key = ensureKey(key, PUBLIC_KEY_BYTE_LENGTH);
8944
- }
8945
- verify(data, sig) {
8946
- return hashAndVerify$2(this._key, sig, data);
8947
- }
8948
- marshal() {
8949
- return this._key;
8950
- }
8951
- get bytes() {
8952
- return PublicKey.encode({
8953
- Type: KeyType.Ed25519,
8954
- Data: this.marshal()
8955
- }).subarray();
8956
- }
8957
- equals(key) {
8958
- return equals(this.bytes, key.bytes);
8959
- }
8960
- hash() {
8961
- const p = sha256$1.digest(this.bytes);
8962
- if (isPromise(p)) {
8963
- return p.then(({ bytes }) => bytes);
8964
- }
8965
- return p.bytes;
8966
- }
8967
- }
8968
- class Ed25519PrivateKey {
8969
- _key;
8970
- _publicKey;
8971
- // key - 64 byte Uint8Array containing private key
8972
- // publicKey - 32 byte Uint8Array containing public key
8973
- constructor(key, publicKey) {
8974
- this._key = ensureKey(key, PRIVATE_KEY_BYTE_LENGTH);
8975
- this._publicKey = ensureKey(publicKey, PUBLIC_KEY_BYTE_LENGTH);
8976
- }
8977
- sign(message) {
8978
- return hashAndSign$2(this._key, message);
8979
- }
8980
- get public() {
8981
- return new Ed25519PublicKey(this._publicKey);
8982
- }
8983
- marshal() {
8984
- return this._key;
8985
- }
8986
- get bytes() {
8987
- return PrivateKey.encode({
8988
- Type: KeyType.Ed25519,
8989
- Data: this.marshal()
8990
- }).subarray();
8991
- }
8992
- equals(key) {
8993
- return equals(this.bytes, key.bytes);
8994
- }
8995
- async hash() {
8996
- const p = sha256$1.digest(this.bytes);
8997
- let bytes;
8998
- if (isPromise(p)) {
8999
- ({ bytes } = await p);
9000
- }
9001
- else {
9002
- bytes = p.bytes;
9003
- }
9004
- return bytes;
9005
- }
9006
- /**
9007
- * Gets the ID of the key.
9008
- *
9009
- * The key id is the base58 encoding of the identity multihash containing its public key.
9010
- * The public key is a protobuf encoding containing a type and the DER encoding
9011
- * of the PKCS SubjectPublicKeyInfo.
9012
- *
9013
- * @returns {Promise<string>}
9014
- */
9015
- async id() {
9016
- const encoding = identity.digest(this.public.bytes);
9017
- return base58btc.encode(encoding.bytes).substring(1);
9018
- }
9019
- /**
9020
- * Exports the key into a password protected `format`
9021
- */
9022
- async export(password, format = 'libp2p-key') {
9023
- if (format === 'libp2p-key') {
9024
- return exporter(this.bytes, password);
9025
- }
9026
- else {
9027
- throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
9028
- }
9029
- }
9030
- }
9031
- function unmarshalEd25519PrivateKey(bytes) {
9032
- // Try the old, redundant public key version
9033
- if (bytes.length > PRIVATE_KEY_BYTE_LENGTH) {
9034
- bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH + PUBLIC_KEY_BYTE_LENGTH);
9035
- const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
9036
- const publicKeyBytes = bytes.subarray(PRIVATE_KEY_BYTE_LENGTH, bytes.length);
9037
- return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
9038
- }
9039
- bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH);
9040
- const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
9041
- const publicKeyBytes = bytes.subarray(PUBLIC_KEY_BYTE_LENGTH);
9042
- return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
9043
- }
9044
- function unmarshalEd25519PublicKey(bytes) {
9045
- bytes = ensureKey(bytes, PUBLIC_KEY_BYTE_LENGTH);
9046
- return new Ed25519PublicKey(bytes);
9047
- }
9048
- async function generateKeyPair$2() {
9049
- const { privateKey, publicKey } = generateKey$2();
9050
- return new Ed25519PrivateKey(privateKey, publicKey);
9051
- }
9052
- async function generateKeyPairFromSeed(seed) {
9053
- const { privateKey, publicKey } = generateKeyFromSeed(seed);
9054
- return new Ed25519PrivateKey(privateKey, publicKey);
9055
- }
9056
- function ensureKey(key, length) {
9057
- key = Uint8Array.from(key ?? []);
9058
- if (key.length !== length) {
9059
- throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
9060
- }
9061
- return key;
9062
- }
9063
-
9064
- var Ed25519 = /*#__PURE__*/Object.freeze({
9065
- __proto__: null,
9066
- Ed25519PrivateKey: Ed25519PrivateKey,
9067
- Ed25519PublicKey: Ed25519PublicKey,
9068
- generateKeyPair: generateKeyPair$2,
9069
- generateKeyPairFromSeed: generateKeyPairFromSeed,
9070
- unmarshalEd25519PrivateKey: unmarshalEd25519PrivateKey,
9071
- unmarshalEd25519PublicKey: unmarshalEd25519PublicKey
9072
- });
9073
-
9074
- /**
9075
- * Generates a Uint8Array with length `number` populated by random bytes
9076
- */
9077
- function randomBytes(length) {
9078
- if (isNaN(length) || length <= 0) {
9079
- throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
9080
- }
9081
- return randomBytes$1(length);
9082
- }
9083
-
9084
- // HMAC (RFC 2104)
9085
- class HMAC extends Hash {
9086
- constructor(hash$1, _key) {
9087
- super();
9088
- this.finished = false;
9089
- this.destroyed = false;
9090
- hash(hash$1);
9091
- const key = toBytes$1(_key);
9092
- this.iHash = hash$1.create();
9093
- if (typeof this.iHash.update !== 'function')
9094
- throw new Error('Expected instance of class which extends utils.Hash');
9095
- this.blockLen = this.iHash.blockLen;
9096
- this.outputLen = this.iHash.outputLen;
9097
- const blockLen = this.blockLen;
9098
- const pad = new Uint8Array(blockLen);
9099
- // blockLen can be bigger than outputLen
9100
- pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
9101
- for (let i = 0; i < pad.length; i++)
9102
- pad[i] ^= 0x36;
9103
- this.iHash.update(pad);
9104
- // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
9105
- this.oHash = hash$1.create();
9106
- // Undo internal XOR && apply outer XOR
9107
- for (let i = 0; i < pad.length; i++)
9108
- pad[i] ^= 0x36 ^ 0x5c;
9109
- this.oHash.update(pad);
9110
- pad.fill(0);
9111
- }
9112
- update(buf) {
9113
- exists(this);
9114
- this.iHash.update(buf);
9115
- return this;
9116
- }
9117
- digestInto(out) {
9118
- exists(this);
9119
- bytes(out, this.outputLen);
9120
- this.finished = true;
9121
- this.iHash.digestInto(out);
9122
- this.oHash.update(out);
9123
- this.oHash.digestInto(out);
9124
- this.destroy();
9125
- }
9126
- digest() {
9127
- const out = new Uint8Array(this.oHash.outputLen);
9128
- this.digestInto(out);
9129
- return out;
9130
- }
9131
- _cloneInto(to) {
9132
- // Create new instance without calling constructor since key already in state and we don't know it.
9133
- to || (to = Object.create(Object.getPrototypeOf(this), {}));
9134
- const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
9135
- to = to;
9136
- to.finished = finished;
9137
- to.destroyed = destroyed;
9138
- to.blockLen = blockLen;
9139
- to.outputLen = outputLen;
9140
- to.oHash = oHash._cloneInto(to.oHash);
9141
- to.iHash = iHash._cloneInto(to.iHash);
9142
- return to;
9143
- }
9144
- destroy() {
9145
- this.destroyed = true;
9146
- this.oHash.destroy();
9147
- this.iHash.destroy();
9148
- }
9149
- }
9150
- /**
9151
- * HMAC: RFC2104 message authentication code.
9152
- * @param hash - function that would be used e.g. sha256
9153
- * @param key - message key
9154
- * @param message - message data
9155
- */
9156
- const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
9157
- hmac.create = (hash, key) => new HMAC(hash, key);
9158
-
9159
- // Common prologue and epilogue for sync/async functions
9160
- function pbkdf2Init(hash$1, _password, _salt, _opts) {
9161
- hash(hash$1);
9162
- const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
9163
- const { c, dkLen, asyncTick } = opts;
9164
- number(c);
9165
- number(dkLen);
9166
- number(asyncTick);
9167
- if (c < 1)
9168
- throw new Error('PBKDF2: iterations (c) should be >= 1');
9169
- const password = toBytes$1(_password);
9170
- const salt = toBytes$1(_salt);
9171
- // DK = PBKDF2(PRF, Password, Salt, c, dkLen);
9172
- const DK = new Uint8Array(dkLen);
9173
- // U1 = PRF(Password, Salt + INT_32_BE(i))
9174
- const PRF = hmac.create(hash$1, password);
9175
- const PRFSalt = PRF._cloneInto().update(salt);
9176
- return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
9177
- }
9178
- function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
9179
- PRF.destroy();
9180
- PRFSalt.destroy();
9181
- if (prfW)
9182
- prfW.destroy();
9183
- u.fill(0);
9184
- return DK;
9185
- }
9186
- async function pbkdf2Async(hash, password, salt, opts) {
9187
- const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
9188
- let prfW; // Working copy
9189
- const arr = new Uint8Array(4);
9190
- const view = createView(arr);
9191
- const u = new Uint8Array(PRF.outputLen);
9192
- // DK = T1 + T2 + โ‹ฏ + Tdklen/hlen
9193
- for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
9194
- // Ti = F(Password, Salt, c, i)
9195
- const Ti = DK.subarray(pos, pos + PRF.outputLen);
9196
- view.setInt32(0, ti, false);
9197
- // F(Password, Salt, c, i) = U1 ^ U2 ^ โ‹ฏ ^ Uc
9198
- // U1 = PRF(Password, Salt + INT_32_BE(i))
9199
- (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
9200
- Ti.set(u.subarray(0, Ti.length));
9201
- await asyncLoop(c - 1, asyncTick, () => {
9202
- // Uc = PRF(Password, Ucโˆ’1)
9203
- PRF._cloneInto(prfW).update(u).digestInto(u);
9204
- for (let i = 0; i < Ti.length; i++)
9205
- Ti[i] ^= u[i];
9206
- });
9207
- }
9208
- return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
9209
- }
9210
-
9211
9061
  /*!
9212
9062
  * MIT License
9213
9063
  *
9214
- * Copyright (c) 2017-2022 Peculiar Ventures, LLC
9064
+ * Copyright (c) 2017-2024 Peculiar Ventures, LLC
9215
9065
  *
9216
9066
  * Permission is hereby granted, free of charge, to any person obtaining a copy
9217
9067
  * of this software and associated documentation files (the "Software"), to deal
@@ -9323,7 +9173,7 @@ class BufferSourceConverter {
9323
9173
  }
9324
9174
 
9325
9175
  const STRING_TYPE = "string";
9326
- const HEX_REGEX = /^[0-9a-f]+$/i;
9176
+ const HEX_REGEX = /^[0-9a-f\s]+$/i;
9327
9177
  const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
9328
9178
  const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
9329
9179
  class Utf8Converter {
@@ -9557,7 +9407,7 @@ class Convert {
9557
9407
  return base64;
9558
9408
  }
9559
9409
  static formatString(data) {
9560
- return (data === null || data === void 0 ? void 0 : data.replace(/[\n\r\t ]/g, "")) || "";
9410
+ return (data === null || data === undefined ? undefined : data.replace(/[\n\r\t ]/g, "")) || "";
9561
9411
  }
9562
9412
  }
9563
9413
  Convert.DEFAULT_UTF8_ENCODING = "utf8";
@@ -9813,7 +9663,7 @@ function HexBlock(BaseClass) {
9813
9663
  var _a;
9814
9664
  super(...args);
9815
9665
  const params = args[0] || {};
9816
- this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== void 0 ? _a : false;
9666
+ this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== undefined ? _a : false;
9817
9667
  this.valueHexView = params.valueHex ? BufferSourceConverter_1.toUint8Array(params.valueHex) : EMPTY_VIEW;
9818
9668
  }
9819
9669
  get valueHex() {
@@ -9903,11 +9753,11 @@ class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
9903
9753
  var _a, _b, _c, _d;
9904
9754
  super();
9905
9755
  if (idBlock) {
9906
- this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== void 0 ? _a : false;
9756
+ this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== undefined ? _a : false;
9907
9757
  this.valueHexView = idBlock.valueHex ? BufferSourceConverter_1.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
9908
- this.tagClass = (_b = idBlock.tagClass) !== null && _b !== void 0 ? _b : -1;
9909
- this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== void 0 ? _c : -1;
9910
- this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== void 0 ? _d : false;
9758
+ this.tagClass = (_b = idBlock.tagClass) !== null && _b !== undefined ? _b : -1;
9759
+ this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== undefined ? _c : -1;
9760
+ this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== undefined ? _d : false;
9911
9761
  }
9912
9762
  else {
9913
9763
  this.tagClass = -1;
@@ -10074,9 +9924,9 @@ class LocalLengthBlock extends LocalBaseBlock {
10074
9924
  constructor({ lenBlock = {}, } = {}) {
10075
9925
  var _a, _b, _c;
10076
9926
  super();
10077
- this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !== void 0 ? _a : false;
10078
- this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== void 0 ? _b : false;
10079
- this.length = (_c = lenBlock.length) !== null && _c !== void 0 ? _c : 0;
9927
+ this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !== undefined ? _a : false;
9928
+ this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== undefined ? _b : false;
9929
+ this.length = (_c = lenBlock.length) !== null && _c !== undefined ? _c : 0;
10080
9930
  }
10081
9931
  fromBER(inputBuffer, inputOffset, inputLength) {
10082
9932
  const view = BufferSourceConverter_1.toUint8Array(inputBuffer);
@@ -10848,7 +10698,7 @@ var _a$r;
10848
10698
  class OctetString extends BaseBlock {
10849
10699
  constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
10850
10700
  var _b, _c;
10851
- (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length));
10701
+ (_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
10852
10702
  super({
10853
10703
  idBlock: {
10854
10704
  isConstructed: parameters.isConstructed,
@@ -11009,7 +10859,7 @@ var _a$q;
11009
10859
  class BitString extends BaseBlock {
11010
10860
  constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
11011
10861
  var _b, _c;
11012
- (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length));
10862
+ (_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
11013
10863
  super({
11014
10864
  idBlock: {
11015
10865
  isConstructed: parameters.isConstructed,
@@ -12211,7 +12061,7 @@ class GeneralizedTime extends UTCTime {
12211
12061
  constructor(parameters = {}) {
12212
12062
  var _b;
12213
12063
  super(parameters);
12214
- (_b = this.millisecond) !== null && _b !== void 0 ? _b : (this.millisecond = 0);
12064
+ (_b = this.millisecond) !== null && _b !== undefined ? _b : (this.millisecond = 0);
12215
12065
  this.idBlock.tagClass = 1;
12216
12066
  this.idBlock.tagNumber = 24;
12217
12067
  }
@@ -12459,272 +12309,44 @@ _a = TIME;
12459
12309
  TIME.NAME = "TIME";
12460
12310
 
12461
12311
  /**
12462
- * Convert a PKCS#1 in ASN1 DER format to a JWK key
12312
+ * Signing a message failed
12463
12313
  */
12464
- function pkcs1ToJwk(bytes) {
12465
- const { result } = fromBER(bytes);
12466
- // @ts-expect-error this looks fragile but DER is a canonical format so we are
12467
- // safe to have deeply property chains like this
12468
- const values = result.valueBlock.value;
12469
- const key = {
12470
- n: toString$1(bnToBuf(values[1].toBigInt()), 'base64url'),
12471
- e: toString$1(bnToBuf(values[2].toBigInt()), 'base64url'),
12472
- d: toString$1(bnToBuf(values[3].toBigInt()), 'base64url'),
12473
- p: toString$1(bnToBuf(values[4].toBigInt()), 'base64url'),
12474
- q: toString$1(bnToBuf(values[5].toBigInt()), 'base64url'),
12475
- dp: toString$1(bnToBuf(values[6].toBigInt()), 'base64url'),
12476
- dq: toString$1(bnToBuf(values[7].toBigInt()), 'base64url'),
12477
- qi: toString$1(bnToBuf(values[8].toBigInt()), 'base64url'),
12478
- kty: 'RSA',
12479
- alg: 'RS256'
12480
- };
12481
- return key;
12482
- }
12483
12314
  /**
12484
- * Convert a JWK key into PKCS#1 in ASN1 DER format
12315
+ * Verifying a message signature failed
12485
12316
  */
12486
- function jwkToPkcs1(jwk) {
12487
- if (jwk.n == null || jwk.e == null || jwk.d == null || jwk.p == null || jwk.q == null || jwk.dp == null || jwk.dq == null || jwk.qi == null) {
12488
- throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12317
+ class VerificationError extends Error {
12318
+ constructor(message = 'An error occurred while verifying a message') {
12319
+ super(message);
12320
+ this.name = 'VerificationError';
12489
12321
  }
12490
- const root = new Sequence({
12491
- value: [
12492
- new Integer({ value: 0 }),
12493
- Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
12494
- Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url'))),
12495
- Integer.fromBigInt(bufToBn(fromString(jwk.d, 'base64url'))),
12496
- Integer.fromBigInt(bufToBn(fromString(jwk.p, 'base64url'))),
12497
- Integer.fromBigInt(bufToBn(fromString(jwk.q, 'base64url'))),
12498
- Integer.fromBigInt(bufToBn(fromString(jwk.dp, 'base64url'))),
12499
- Integer.fromBigInt(bufToBn(fromString(jwk.dq, 'base64url'))),
12500
- Integer.fromBigInt(bufToBn(fromString(jwk.qi, 'base64url')))
12501
- ]
12502
- });
12503
- const der = root.toBER();
12504
- return new Uint8Array(der, 0, der.byteLength);
12505
- }
12506
- /**
12507
- * Convert a PKCIX in ASN1 DER format to a JWK key
12508
- */
12509
- function pkixToJwk(bytes) {
12510
- const { result } = fromBER(bytes);
12511
- // @ts-expect-error this looks fragile but DER is a canonical format so we are
12512
- // safe to have deeply property chains like this
12513
- const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
12514
- return {
12515
- kty: 'RSA',
12516
- n: toString$1(bnToBuf(values[0].toBigInt()), 'base64url'),
12517
- e: toString$1(bnToBuf(values[1].toBigInt()), 'base64url')
12518
- };
12519
12322
  }
12520
12323
  /**
12521
- * Convert a JWK key to PKCIX in ASN1 DER format
12324
+ * WebCrypto was not available in the current context
12522
12325
  */
12523
- function jwkToPkix(jwk) {
12524
- if (jwk.n == null || jwk.e == null) {
12525
- throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12326
+ class WebCryptoMissingError extends Error {
12327
+ constructor(message = 'Missing Web Crypto API') {
12328
+ super(message);
12329
+ this.name = 'WebCryptoMissingError';
12526
12330
  }
12527
- const root = new Sequence({
12528
- value: [
12529
- new Sequence({
12530
- value: [
12531
- // rsaEncryption
12532
- new ObjectIdentifier({
12533
- value: '1.2.840.113549.1.1.1'
12534
- }),
12535
- new Null()
12536
- ]
12537
- }),
12538
- // this appears to be a bug in asn1js.js - this should really be a Sequence
12539
- // and not a BitString but it generates the same bytes as node-forge so ๐Ÿคทโ€โ™‚๏ธ
12540
- new BitString({
12541
- valueHex: new Sequence({
12542
- value: [
12543
- Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
12544
- Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url')))
12545
- ]
12546
- }).toBER()
12547
- })
12548
- ]
12549
- });
12550
- const der = root.toBER();
12551
- return new Uint8Array(der, 0, der.byteLength);
12552
12331
  }
12553
- function bnToBuf(bn) {
12554
- let hex = bn.toString(16);
12555
- if (hex.length % 2 > 0) {
12556
- hex = `0${hex}`;
12557
- }
12558
- const len = hex.length / 2;
12559
- const u8 = new Uint8Array(len);
12560
- let i = 0;
12561
- let j = 0;
12562
- while (i < len) {
12563
- u8[i] = parseInt(hex.slice(j, j + 2), 16);
12564
- i += 1;
12565
- j += 2;
12566
- }
12567
- return u8;
12568
- }
12569
- function bufToBn(u8) {
12570
- const hex = [];
12571
- u8.forEach(function (i) {
12572
- let h = i.toString(16);
12573
- if (h.length % 2 > 0) {
12574
- h = `0${h}`;
12332
+
12333
+ /* eslint-env browser */
12334
+ // Check native crypto exists and is enabled (In insecure context `self.crypto`
12335
+ // exists but `self.crypto.subtle` does not).
12336
+ var webcrypto = {
12337
+ get(win = globalThis) {
12338
+ const nativeCrypto = win.crypto;
12339
+ if (nativeCrypto?.subtle == null) {
12340
+ throw new WebCryptoMissingError('Missing Web Crypto API. ' +
12341
+ 'The most likely cause of this error is that this page is being accessed ' +
12342
+ 'from an insecure context (i.e. not HTTPS). For more information and ' +
12343
+ 'possible resolutions see ' +
12344
+ 'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api');
12575
12345
  }
12576
- hex.push(h);
12577
- });
12578
- return BigInt('0x' + hex.join(''));
12579
- }
12580
- const SALT_LENGTH = 16;
12581
- const KEY_SIZE = 32;
12582
- const ITERATIONS = 10000;
12583
- async function exportToPem(privateKey, password) {
12584
- const crypto = webcrypto.get();
12585
- // PrivateKeyInfo
12586
- const keyWrapper = new Sequence({
12587
- value: [
12588
- // version (0)
12589
- new Integer({ value: 0 }),
12590
- // privateKeyAlgorithm
12591
- new Sequence({
12592
- value: [
12593
- // rsaEncryption OID
12594
- new ObjectIdentifier({
12595
- value: '1.2.840.113549.1.1.1'
12596
- }),
12597
- new Null()
12598
- ]
12599
- }),
12600
- // PrivateKey
12601
- new OctetString({
12602
- valueHex: privateKey.marshal()
12603
- })
12604
- ]
12605
- });
12606
- const keyBuf = keyWrapper.toBER();
12607
- const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
12608
- const salt = randomBytes(SALT_LENGTH);
12609
- const encryptionKey = await pbkdf2Async(sha512, password, salt, {
12610
- c: ITERATIONS,
12611
- dkLen: KEY_SIZE
12612
- });
12613
- const iv = randomBytes(16);
12614
- const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['encrypt']);
12615
- const encrypted = await crypto.subtle.encrypt({
12616
- name: 'AES-CBC',
12617
- iv
12618
- }, cryptoKey, keyArr);
12619
- const pbkdf2Params = new Sequence({
12620
- value: [
12621
- // salt
12622
- new OctetString({ valueHex: salt }),
12623
- // iteration count
12624
- new Integer({ value: ITERATIONS }),
12625
- // key length
12626
- new Integer({ value: KEY_SIZE }),
12627
- // AlgorithmIdentifier
12628
- new Sequence({
12629
- value: [
12630
- // hmacWithSHA512
12631
- new ObjectIdentifier({ value: '1.2.840.113549.2.11' }),
12632
- new Null()
12633
- ]
12634
- })
12635
- ]
12636
- });
12637
- const encryptionAlgorithm = new Sequence({
12638
- value: [
12639
- // pkcs5PBES2
12640
- new ObjectIdentifier({
12641
- value: '1.2.840.113549.1.5.13'
12642
- }),
12643
- new Sequence({
12644
- value: [
12645
- // keyDerivationFunc
12646
- new Sequence({
12647
- value: [
12648
- // pkcs5PBKDF2
12649
- new ObjectIdentifier({
12650
- value: '1.2.840.113549.1.5.12'
12651
- }),
12652
- // PBKDF2-params
12653
- pbkdf2Params
12654
- ]
12655
- }),
12656
- // encryptionScheme
12657
- new Sequence({
12658
- value: [
12659
- // aes256-CBC
12660
- new ObjectIdentifier({
12661
- value: '2.16.840.1.101.3.4.1.42'
12662
- }),
12663
- // iv
12664
- new OctetString({
12665
- valueHex: iv
12666
- })
12667
- ]
12668
- })
12669
- ]
12670
- })
12671
- ]
12672
- });
12673
- const finalWrapper = new Sequence({
12674
- value: [
12675
- encryptionAlgorithm,
12676
- new OctetString({ valueHex: encrypted })
12677
- ]
12678
- });
12679
- const finalWrapperBuf = finalWrapper.toBER();
12680
- const finalWrapperArr = new Uint8Array(finalWrapperBuf, 0, finalWrapperBuf.byteLength);
12681
- return [
12682
- '-----BEGIN ENCRYPTED PRIVATE KEY-----',
12683
- ...toString$1(finalWrapperArr, 'base64pad').split(/(.{64})/).filter(Boolean),
12684
- '-----END ENCRYPTED PRIVATE KEY-----'
12685
- ].join('\n');
12686
- }
12346
+ return nativeCrypto;
12347
+ }
12348
+ };
12687
12349
 
12688
- async function generateKey$1(bits) {
12689
- const pair = await webcrypto.get().subtle.generateKey({
12690
- name: 'RSASSA-PKCS1-v1_5',
12691
- modulusLength: bits,
12692
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
12693
- hash: { name: 'SHA-256' }
12694
- }, true, ['sign', 'verify']);
12695
- const keys = await exportKey(pair);
12696
- return {
12697
- privateKey: keys[0],
12698
- publicKey: keys[1]
12699
- };
12700
- }
12701
- // Takes a jwk key
12702
- async function unmarshalPrivateKey$1(key) {
12703
- const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
12704
- name: 'RSASSA-PKCS1-v1_5',
12705
- hash: { name: 'SHA-256' }
12706
- }, true, ['sign']);
12707
- const pair = [
12708
- privateKey,
12709
- await derivePublicFromPrivate(key)
12710
- ];
12711
- const keys = await exportKey({
12712
- privateKey: pair[0],
12713
- publicKey: pair[1]
12714
- });
12715
- return {
12716
- privateKey: keys[0],
12717
- publicKey: keys[1]
12718
- };
12719
- }
12720
- async function hashAndSign$1(key, msg) {
12721
- const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
12722
- name: 'RSASSA-PKCS1-v1_5',
12723
- hash: { name: 'SHA-256' }
12724
- }, false, ['sign']);
12725
- const sig = await webcrypto.get().subtle.sign({ name: 'RSASSA-PKCS1-v1_5' }, privateKey, msg instanceof Uint8Array ? msg : msg.subarray());
12726
- return new Uint8Array(sig, 0, sig.byteLength);
12727
- }
12728
12350
  async function hashAndVerify$1(key, sig, msg) {
12729
12351
  const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
12730
12352
  name: 'RSASSA-PKCS1-v1_5',
@@ -12732,176 +12354,245 @@ async function hashAndVerify$1(key, sig, msg) {
12732
12354
  }, false, ['verify']);
12733
12355
  return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
12734
12356
  }
12735
- async function exportKey(pair) {
12736
- if (pair.privateKey == null || pair.publicKey == null) {
12737
- throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
12738
- }
12739
- return Promise.all([
12740
- webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
12741
- webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
12742
- ]);
12743
- }
12744
- async function derivePublicFromPrivate(jwKey) {
12745
- return webcrypto.get().subtle.importKey('jwk', {
12746
- kty: jwKey.kty,
12747
- n: jwKey.n,
12748
- e: jwKey.e
12749
- }, {
12750
- name: 'RSASSA-PKCS1-v1_5',
12751
- hash: { name: 'SHA-256' }
12752
- }, true, ['verify']);
12753
- }
12754
- function keySize(jwk) {
12357
+ function rsaKeySize(jwk) {
12755
12358
  if (jwk.kty !== 'RSA') {
12756
- throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
12359
+ throw new InvalidParametersError('invalid key type');
12757
12360
  }
12758
12361
  else if (jwk.n == null) {
12759
- throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
12362
+ throw new InvalidParametersError('invalid key modulus');
12760
12363
  }
12761
12364
  const bytes = fromString(jwk.n, 'base64url');
12762
12365
  return bytes.length * 8;
12763
12366
  }
12764
12367
 
12765
- const MAX_RSA_KEY_SIZE = 8192;
12766
- class RsaPublicKey {
12368
+ class RSAPublicKey {
12369
+ type = 'RSA';
12767
12370
  _key;
12768
- constructor(key) {
12371
+ _raw;
12372
+ _multihash;
12373
+ constructor(key, digest) {
12769
12374
  this._key = key;
12375
+ this._multihash = digest;
12770
12376
  }
12771
- verify(data, sig) {
12772
- return hashAndVerify$1(this._key, sig, data);
12773
- }
12774
- marshal() {
12775
- return jwkToPkix(this._key);
12776
- }
12777
- get bytes() {
12778
- return PublicKey.encode({
12779
- Type: KeyType.RSA,
12780
- Data: this.marshal()
12781
- }).subarray();
12782
- }
12783
- equals(key) {
12784
- return equals(this.bytes, key.bytes);
12785
- }
12786
- hash() {
12787
- const p = sha256$1.digest(this.bytes);
12788
- if (isPromise(p)) {
12789
- return p.then(({ bytes }) => bytes);
12377
+ get raw() {
12378
+ if (this._raw == null) {
12379
+ this._raw = jwkToPkix(this._key);
12790
12380
  }
12791
- return p.bytes;
12792
- }
12793
- }
12794
- class RsaPrivateKey {
12795
- _key;
12796
- _publicKey;
12797
- constructor(key, publicKey) {
12798
- this._key = key;
12799
- this._publicKey = publicKey;
12800
- }
12801
- genSecret() {
12802
- return randomBytes(16);
12803
- }
12804
- sign(message) {
12805
- return hashAndSign$1(this._key, message);
12381
+ return this._raw;
12806
12382
  }
12807
- get public() {
12808
- if (this._publicKey == null) {
12809
- throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
12810
- }
12811
- return new RsaPublicKey(this._publicKey);
12383
+ toMultihash() {
12384
+ return this._multihash;
12812
12385
  }
12813
- marshal() {
12814
- return jwkToPkcs1(this._key);
12386
+ toCID() {
12387
+ return CID.createV1(114, this._multihash);
12815
12388
  }
12816
- get bytes() {
12817
- return PrivateKey.encode({
12818
- Type: KeyType.RSA,
12819
- Data: this.marshal()
12820
- }).subarray();
12389
+ toString() {
12390
+ return base58btc.encode(this.toMultihash().bytes).substring(1);
12821
12391
  }
12822
12392
  equals(key) {
12823
- return equals(this.bytes, key.bytes);
12824
- }
12825
- hash() {
12826
- const p = sha256$1.digest(this.bytes);
12827
- if (isPromise(p)) {
12828
- return p.then(({ bytes }) => bytes);
12393
+ if (key == null || !(key.raw instanceof Uint8Array)) {
12394
+ return false;
12829
12395
  }
12830
- return p.bytes;
12396
+ return equals(this.raw, key.raw);
12831
12397
  }
12832
- /**
12833
- * Gets the ID of the key.
12834
- *
12835
- * The key id is the base58 encoding of the SHA-256 multihash of its public key.
12836
- * The public key is a protobuf encoding containing a type and the DER encoding
12837
- * of the PKCS SubjectPublicKeyInfo.
12838
- */
12839
- async id() {
12840
- const hash = await this.public.hash();
12841
- return toString$1(hash, 'base58btc');
12398
+ verify(data, sig) {
12399
+ return hashAndVerify$1(this._key, sig, data);
12842
12400
  }
12843
- /**
12844
- * Exports the key as libp2p-key - a aes-gcm encrypted value with the key
12845
- * derived from the password.
12846
- *
12847
- * To export it as a password protected PEM file, please use the `exportPEM`
12848
- * function from `@libp2p/rsa`.
12849
- */
12850
- async export(password, format = 'pkcs-8') {
12851
- if (format === 'pkcs-8') {
12852
- return exportToPem(this, password);
12853
- }
12854
- else if (format === 'libp2p-key') {
12855
- return exporter(this.bytes, password);
12856
- }
12857
- else {
12858
- throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
12859
- }
12401
+ }
12402
+
12403
+ const MAX_RSA_KEY_SIZE = 8192;
12404
+ const SHA2_256_CODE = 0x12;
12405
+ /**
12406
+ * Convert a PKIX in ASN1 DER format to a JWK key
12407
+ */
12408
+ function pkixToJwk(bytes) {
12409
+ const { result } = fromBER(bytes);
12410
+ // @ts-expect-error this looks fragile but DER is a canonical format so we are
12411
+ // safe to have deeply property chains like this
12412
+ const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
12413
+ return {
12414
+ kty: 'RSA',
12415
+ n: asn1jsIntegerToBase64(values[0]),
12416
+ e: asn1jsIntegerToBase64(values[1])
12417
+ };
12418
+ }
12419
+ /**
12420
+ * Convert a JWK key to PKIX in ASN1 DER format
12421
+ */
12422
+ function jwkToPkix(jwk) {
12423
+ if (jwk.n == null || jwk.e == null) {
12424
+ throw new InvalidParametersError('JWK was missing components');
12860
12425
  }
12426
+ const root = new Sequence({
12427
+ value: [
12428
+ new Sequence({
12429
+ value: [
12430
+ // rsaEncryption
12431
+ new ObjectIdentifier({
12432
+ value: '1.2.840.113549.1.1.1'
12433
+ }),
12434
+ new Null()
12435
+ ]
12436
+ }),
12437
+ // this appears to be a bug in asn1js.js - this should really be a Sequence
12438
+ // and not a BitString but it generates the same bytes as node-forge so ๐Ÿคทโ€โ™‚๏ธ
12439
+ new BitString({
12440
+ valueHex: new Sequence({
12441
+ value: [
12442
+ Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
12443
+ Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url')))
12444
+ ]
12445
+ }).toBER()
12446
+ })
12447
+ ]
12448
+ });
12449
+ const der = root.toBER();
12450
+ return new Uint8Array(der, 0, der.byteLength);
12861
12451
  }
12862
- async function unmarshalRsaPrivateKey(bytes) {
12863
- const jwk = pkcs1ToJwk(bytes);
12864
- if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
12865
- throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
12452
+ function asn1jsIntegerToBase64(int) {
12453
+ let buf = int.valueBlock.valueHexView;
12454
+ // chrome rejects values with leading 0s
12455
+ while (buf[0] === 0) {
12456
+ buf = buf.subarray(1);
12866
12457
  }
12867
- const keys = await unmarshalPrivateKey$1(jwk);
12868
- return new RsaPrivateKey(keys.privateKey, keys.publicKey);
12458
+ return toString$1(buf, 'base64url');
12459
+ }
12460
+ function bufToBn(u8) {
12461
+ const hex = [];
12462
+ u8.forEach(function (i) {
12463
+ let h = i.toString(16);
12464
+ if (h.length % 2 > 0) {
12465
+ h = `0${h}`;
12466
+ }
12467
+ hex.push(h);
12468
+ });
12469
+ return BigInt('0x' + hex.join(''));
12869
12470
  }
12870
- function unmarshalRsaPublicKey(bytes) {
12471
+ /**
12472
+ * Turn PKIX bytes to a PublicKey
12473
+ */
12474
+ function pkixToRSAPublicKey(bytes) {
12871
12475
  const jwk = pkixToJwk(bytes);
12872
- if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
12873
- throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
12476
+ if (rsaKeySize(jwk) > MAX_RSA_KEY_SIZE) {
12477
+ throw new InvalidPublicKeyError('Key size is too large');
12874
12478
  }
12875
- return new RsaPublicKey(jwk);
12479
+ const hash = sha256(PublicKey.encode({
12480
+ Type: KeyType.RSA,
12481
+ Data: bytes
12482
+ }));
12483
+ const digest = create(SHA2_256_CODE, hash);
12484
+ return new RSAPublicKey(jwk, digest);
12876
12485
  }
12877
- async function fromJwk(jwk) {
12878
- if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
12879
- throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
12486
+
12487
+ /**
12488
+ * HMAC: RFC2104 message authentication code.
12489
+ * @module
12490
+ */
12491
+ class HMAC extends Hash {
12492
+ constructor(hash, _key) {
12493
+ super();
12494
+ this.finished = false;
12495
+ this.destroyed = false;
12496
+ ahash(hash);
12497
+ const key = toBytes$1(_key);
12498
+ this.iHash = hash.create();
12499
+ if (typeof this.iHash.update !== 'function')
12500
+ throw new Error('Expected instance of class which extends utils.Hash');
12501
+ this.blockLen = this.iHash.blockLen;
12502
+ this.outputLen = this.iHash.outputLen;
12503
+ const blockLen = this.blockLen;
12504
+ const pad = new Uint8Array(blockLen);
12505
+ // blockLen can be bigger than outputLen
12506
+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
12507
+ for (let i = 0; i < pad.length; i++)
12508
+ pad[i] ^= 0x36;
12509
+ this.iHash.update(pad);
12510
+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
12511
+ this.oHash = hash.create();
12512
+ // Undo internal XOR && apply outer XOR
12513
+ for (let i = 0; i < pad.length; i++)
12514
+ pad[i] ^= 0x36 ^ 0x5c;
12515
+ this.oHash.update(pad);
12516
+ pad.fill(0);
12880
12517
  }
12881
- const keys = await unmarshalPrivateKey$1(jwk);
12882
- return new RsaPrivateKey(keys.privateKey, keys.publicKey);
12883
- }
12884
- async function generateKeyPair$1(bits) {
12885
- if (bits > MAX_RSA_KEY_SIZE) {
12886
- throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
12518
+ update(buf) {
12519
+ aexists(this);
12520
+ this.iHash.update(buf);
12521
+ return this;
12522
+ }
12523
+ digestInto(out) {
12524
+ aexists(this);
12525
+ abytes$1(out, this.outputLen);
12526
+ this.finished = true;
12527
+ this.iHash.digestInto(out);
12528
+ this.oHash.update(out);
12529
+ this.oHash.digestInto(out);
12530
+ this.destroy();
12531
+ }
12532
+ digest() {
12533
+ const out = new Uint8Array(this.oHash.outputLen);
12534
+ this.digestInto(out);
12535
+ return out;
12536
+ }
12537
+ _cloneInto(to) {
12538
+ // Create new instance without calling constructor since key already in state and we don't know it.
12539
+ to || (to = Object.create(Object.getPrototypeOf(this), {}));
12540
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
12541
+ to = to;
12542
+ to.finished = finished;
12543
+ to.destroyed = destroyed;
12544
+ to.blockLen = blockLen;
12545
+ to.outputLen = outputLen;
12546
+ to.oHash = oHash._cloneInto(to.oHash);
12547
+ to.iHash = iHash._cloneInto(to.iHash);
12548
+ return to;
12549
+ }
12550
+ destroy() {
12551
+ this.destroyed = true;
12552
+ this.oHash.destroy();
12553
+ this.iHash.destroy();
12887
12554
  }
12888
- const keys = await generateKey$1(bits);
12889
- return new RsaPrivateKey(keys.privateKey, keys.publicKey);
12890
12555
  }
12556
+ /**
12557
+ * HMAC: RFC2104 message authentication code.
12558
+ * @param hash - function that would be used e.g. sha256
12559
+ * @param key - message key
12560
+ * @param message - message data
12561
+ * @example
12562
+ * import { hmac } from '@noble/hashes/hmac';
12563
+ * import { sha256 } from '@noble/hashes/sha2';
12564
+ * const mac1 = hmac(sha256, 'key', 'message');
12565
+ */
12566
+ const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
12567
+ hmac.create = (hash, key) => new HMAC(hash, key);
12891
12568
 
12892
- var RSA = /*#__PURE__*/Object.freeze({
12893
- __proto__: null,
12894
- MAX_RSA_KEY_SIZE: MAX_RSA_KEY_SIZE,
12895
- RsaPrivateKey: RsaPrivateKey,
12896
- RsaPublicKey: RsaPublicKey,
12897
- fromJwk: fromJwk,
12898
- generateKeyPair: generateKeyPair$1,
12899
- unmarshalRsaPrivateKey: unmarshalRsaPrivateKey,
12900
- unmarshalRsaPublicKey: unmarshalRsaPublicKey
12901
- });
12902
-
12569
+ /**
12570
+ * Short Weierstrass curve methods. The formula is: yยฒ = xยณ + ax + b.
12571
+ *
12572
+ * ### Design rationale for types
12573
+ *
12574
+ * * Interaction between classes from different curves should fail:
12575
+ * `k256.Point.BASE.add(p256.Point.BASE)`
12576
+ * * For this purpose we want to use `instanceof` operator, which is fast and works during runtime
12577
+ * * Different calls of `curve()` would return different classes -
12578
+ * `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,
12579
+ * it won't affect others
12580
+ *
12581
+ * TypeScript can't infer types for classes created inside a function. Classes is one instance
12582
+ * of nominative types in TypeScript and interfaces only check for shape, so it's hard to create
12583
+ * unique type for every function call.
12584
+ *
12585
+ * We can use generic types via some param, like curve opts, but that would:
12586
+ * 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)
12587
+ * which is hard to debug.
12588
+ * 2. Params can be generic and we can't enforce them to be constant value:
12589
+ * if somebody creates curve from non-constant params,
12590
+ * it would be allowed to interact with other curves with non-constant params
12591
+ *
12592
+ * @todo https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
12593
+ * @module
12594
+ */
12903
12595
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
12904
- // Short Weierstrass curve. The formula is: yยฒ = xยณ + ax + b
12905
12596
  function validateSigVerOpts(opts) {
12906
12597
  if (opts.lowS !== undefined)
12907
12598
  abool('lowS', opts.lowS);
@@ -12925,73 +12616,132 @@ function validatePointOpts(curve) {
12925
12616
  const { endo, Fp, a } = opts;
12926
12617
  if (endo) {
12927
12618
  if (!Fp.eql(a, Fp.ZERO)) {
12928
- throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');
12619
+ throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
12929
12620
  }
12930
12621
  if (typeof endo !== 'object' ||
12931
12622
  typeof endo.beta !== 'bigint' ||
12932
12623
  typeof endo.splitScalar !== 'function') {
12933
- throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');
12624
+ throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
12934
12625
  }
12935
12626
  }
12936
12627
  return Object.freeze({ ...opts });
12937
12628
  }
12938
- // ASN.1 DER encoding utilities
12939
12629
  const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
12630
+ class DERErr extends Error {
12631
+ constructor(m = '') {
12632
+ super(m);
12633
+ }
12634
+ }
12635
+ /**
12636
+ * ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
12637
+ *
12638
+ * [0x30 (SEQUENCE), bytelength, 0x02 (INTEGER), intLength, R, 0x02 (INTEGER), intLength, S]
12639
+ *
12640
+ * Docs: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/, https://luca.ntop.org/Teaching/Appunti/asn1.html
12641
+ */
12940
12642
  const DER = {
12941
12643
  // asn.1 DER encoding utils
12942
- Err: class DERErr extends Error {
12943
- constructor(m = '') {
12944
- super(m);
12945
- }
12644
+ Err: DERErr,
12645
+ // Basic building block is TLV (Tag-Length-Value)
12646
+ _tlv: {
12647
+ encode: (tag, data) => {
12648
+ const { Err: E } = DER;
12649
+ if (tag < 0 || tag > 256)
12650
+ throw new E('tlv.encode: wrong tag');
12651
+ if (data.length & 1)
12652
+ throw new E('tlv.encode: unpadded data');
12653
+ const dataLen = data.length / 2;
12654
+ const len = numberToHexUnpadded(dataLen);
12655
+ if ((len.length / 2) & 128)
12656
+ throw new E('tlv.encode: long form length too big');
12657
+ // length of length with long form flag
12658
+ const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
12659
+ const t = numberToHexUnpadded(tag);
12660
+ return t + lenLen + len + data;
12661
+ },
12662
+ // v - value, l - left bytes (unparsed)
12663
+ decode(tag, data) {
12664
+ const { Err: E } = DER;
12665
+ let pos = 0;
12666
+ if (tag < 0 || tag > 256)
12667
+ throw new E('tlv.encode: wrong tag');
12668
+ if (data.length < 2 || data[pos++] !== tag)
12669
+ throw new E('tlv.decode: wrong tlv');
12670
+ const first = data[pos++];
12671
+ const isLong = !!(first & 128); // First bit of first length byte is flag for short/long form
12672
+ let length = 0;
12673
+ if (!isLong)
12674
+ length = first;
12675
+ else {
12676
+ // Long form: [longFlag(1bit), lengthLength(7bit), length (BE)]
12677
+ const lenLen = first & 127;
12678
+ if (!lenLen)
12679
+ throw new E('tlv.decode(long): indefinite length not supported');
12680
+ if (lenLen > 4)
12681
+ throw new E('tlv.decode(long): byte length is too big'); // this will overflow u32 in js
12682
+ const lengthBytes = data.subarray(pos, pos + lenLen);
12683
+ if (lengthBytes.length !== lenLen)
12684
+ throw new E('tlv.decode: length bytes not complete');
12685
+ if (lengthBytes[0] === 0)
12686
+ throw new E('tlv.decode(long): zero leftmost byte');
12687
+ for (const b of lengthBytes)
12688
+ length = (length << 8) | b;
12689
+ pos += lenLen;
12690
+ if (length < 128)
12691
+ throw new E('tlv.decode(long): not minimal encoding');
12692
+ }
12693
+ const v = data.subarray(pos, pos + length);
12694
+ if (v.length !== length)
12695
+ throw new E('tlv.decode: wrong value length');
12696
+ return { v, l: data.subarray(pos + length) };
12697
+ },
12946
12698
  },
12947
- _parseInt(data) {
12948
- const { Err: E } = DER;
12949
- if (data.length < 2 || data[0] !== 0x02)
12950
- throw new E('Invalid signature integer tag');
12951
- const len = data[1];
12952
- const res = data.subarray(2, len + 2);
12953
- if (!len || res.length !== len)
12954
- throw new E('Invalid signature integer: wrong length');
12955
- // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
12956
- // since we always use positive integers here. It must always be empty:
12957
- // - add zero byte if exists
12958
- // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
12959
- if (res[0] & 0b10000000)
12960
- throw new E('Invalid signature integer: negative');
12961
- if (res[0] === 0x00 && !(res[1] & 0b10000000))
12962
- throw new E('Invalid signature integer: unnecessary leading zero');
12963
- return { d: b2n(res), l: data.subarray(len + 2) }; // d is data, l is left
12699
+ // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
12700
+ // since we always use positive integers here. It must always be empty:
12701
+ // - add zero byte if exists
12702
+ // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
12703
+ _int: {
12704
+ encode(num) {
12705
+ const { Err: E } = DER;
12706
+ if (num < _0n)
12707
+ throw new E('integer: negative integers are not allowed');
12708
+ let hex = numberToHexUnpadded(num);
12709
+ // Pad with zero byte if negative flag is present
12710
+ if (Number.parseInt(hex[0], 16) & 0b1000)
12711
+ hex = '00' + hex;
12712
+ if (hex.length & 1)
12713
+ throw new E('unexpected DER parsing assertion: unpadded hex');
12714
+ return hex;
12715
+ },
12716
+ decode(data) {
12717
+ const { Err: E } = DER;
12718
+ if (data[0] & 128)
12719
+ throw new E('invalid signature integer: negative');
12720
+ if (data[0] === 0x00 && !(data[1] & 128))
12721
+ throw new E('invalid signature integer: unnecessary leading zero');
12722
+ return b2n(data);
12723
+ },
12964
12724
  },
12965
12725
  toSig(hex) {
12966
12726
  // parse DER signature
12967
- const { Err: E } = DER;
12727
+ const { Err: E, _int: int, _tlv: tlv } = DER;
12968
12728
  const data = typeof hex === 'string' ? h2b(hex) : hex;
12969
12729
  abytes(data);
12970
- let l = data.length;
12971
- if (l < 2 || data[0] != 0x30)
12972
- throw new E('Invalid signature tag');
12973
- if (data[1] !== l - 2)
12974
- throw new E('Invalid signature: incorrect length');
12975
- const { d: r, l: sBytes } = DER._parseInt(data.subarray(2));
12976
- const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);
12977
- if (rBytesLeft.length)
12978
- throw new E('Invalid signature: left bytes after parsing');
12979
- return { r, s };
12730
+ const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
12731
+ if (seqLeftBytes.length)
12732
+ throw new E('invalid signature: left bytes after parsing');
12733
+ const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
12734
+ const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
12735
+ if (sLeftBytes.length)
12736
+ throw new E('invalid signature: left bytes after parsing');
12737
+ return { r: int.decode(rBytes), s: int.decode(sBytes) };
12980
12738
  },
12981
12739
  hexFromSig(sig) {
12982
- // Add leading zero if first byte has negative bit enabled. More details in '_parseInt'
12983
- const slice = (s) => (Number.parseInt(s[0], 16) & 0b1000 ? '00' + s : s);
12984
- const h = (num) => {
12985
- const hex = num.toString(16);
12986
- return hex.length & 1 ? `0${hex}` : hex;
12987
- };
12988
- const s = slice(h(sig.s));
12989
- const r = slice(h(sig.r));
12990
- const shl = s.length / 2;
12991
- const rhl = r.length / 2;
12992
- const sl = h(shl);
12993
- const rl = h(rhl);
12994
- return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
12740
+ const { _tlv: tlv, _int: int } = DER;
12741
+ const rs = tlv.encode(0x02, int.encode(sig.r));
12742
+ const ss = tlv.encode(0x02, int.encode(sig.s));
12743
+ const seq = rs + ss;
12744
+ return tlv.encode(0x30, seq);
12995
12745
  },
12996
12746
  };
12997
12747
  // Be friendly to bad ECMAScript parsers by not using bigint literals
@@ -13000,6 +12750,7 @@ const _0n = BigInt(0), _1n$1 = BigInt(1); BigInt(2); const _3n = BigInt(3); BigI
13000
12750
  function weierstrassPoints(opts) {
13001
12751
  const CURVE = validatePointOpts(opts);
13002
12752
  const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
12753
+ const Fn = Field(CURVE.n, CURVE.nBitLength);
13003
12754
  const toBytes = CURVE.toBytes ||
13004
12755
  ((_c, point, _isCompressed) => {
13005
12756
  const a = point.toAffine();
@@ -13043,7 +12794,7 @@ function weierstrassPoints(opts) {
13043
12794
  key = bytesToHex(key);
13044
12795
  // Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
13045
12796
  if (typeof key !== 'string' || !lengths.includes(key.length))
13046
- throw new Error('Invalid key');
12797
+ throw new Error('invalid private key');
13047
12798
  key = key.padStart(nByteLength * 2, '0');
13048
12799
  }
13049
12800
  let num;
@@ -13054,7 +12805,7 @@ function weierstrassPoints(opts) {
13054
12805
  : bytesToNumberBE(ensureBytes('private key', key, nByteLength));
13055
12806
  }
13056
12807
  catch (error) {
13057
- throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
12808
+ throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
13058
12809
  }
13059
12810
  if (wrapPrivateKey)
13060
12811
  num = mod(num, N); // disabled by default, enabled for BLS
@@ -13094,7 +12845,7 @@ function weierstrassPoints(opts) {
13094
12845
  if (p.is0()) {
13095
12846
  // (0, 1, 0) aka ZERO is invalid in most contexts.
13096
12847
  // In BLS, ZERO can be serialized, so we allow it.
13097
- // (0, 0, 0) is wrong representation of ZERO and is always invalid.
12848
+ // (0, 0, 0) is invalid representation of ZERO.
13098
12849
  if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
13099
12850
  return;
13100
12851
  throw new Error('bad point: ZERO');
@@ -13173,6 +12924,10 @@ function weierstrassPoints(opts) {
13173
12924
  static fromPrivateKey(privateKey) {
13174
12925
  return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
13175
12926
  }
12927
+ // Multiscalar Multiplication
12928
+ static msm(points, scalars) {
12929
+ return pippenger(Point, Fn, points, scalars);
12930
+ }
13176
12931
  // "Private method", don't use it directly
13177
12932
  _setWindowSize(windowSize) {
13178
12933
  wnaf.setWindowSize(this, windowSize);
@@ -13314,16 +13069,17 @@ function weierstrassPoints(opts) {
13314
13069
  * an exposed private key e.g. sig verification, which works over *public* keys.
13315
13070
  */
13316
13071
  multiplyUnsafe(sc) {
13317
- aInRange('scalar', sc, _0n, CURVE.n);
13072
+ const { endo, n: N } = CURVE;
13073
+ aInRange('scalar', sc, _0n, N);
13318
13074
  const I = Point.ZERO;
13319
13075
  if (sc === _0n)
13320
13076
  return I;
13321
- if (sc === _1n$1)
13077
+ if (this.is0() || sc === _1n$1)
13322
13078
  return this;
13323
- const { endo } = CURVE;
13324
- if (!endo)
13325
- return wnaf.unsafeLadder(this, sc);
13326
- // Apply endomorphism
13079
+ // Case a: no endomorphism. Case b: has precomputes.
13080
+ if (!endo || wnaf.hasPrecomputes(this))
13081
+ return wnaf.wNAFCachedUnsafe(this, sc, Point.normalizeZ);
13082
+ // Case c: endomorphism
13327
13083
  let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
13328
13084
  let k1p = I;
13329
13085
  let k2p = I;
@@ -13509,7 +13265,9 @@ function weierstrass(curveDef) {
13509
13265
  return { x, y };
13510
13266
  }
13511
13267
  else {
13512
- throw new Error(`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`);
13268
+ const cl = compressedLen;
13269
+ const ul = uncompressedLen;
13270
+ throw new Error('invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len);
13513
13271
  }
13514
13272
  },
13515
13273
  });
@@ -13674,6 +13432,9 @@ function weierstrass(curveDef) {
13674
13432
  // int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
13675
13433
  const bits2int = CURVE.bits2int ||
13676
13434
  function (bytes) {
13435
+ // Our custom check "just in case"
13436
+ if (bytes.length > 8192)
13437
+ throw new Error('input is too large');
13677
13438
  // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
13678
13439
  // for some cases, since bytes.length * 8 is not actual bitLength.
13679
13440
  const num = bytesToNumberBE(bytes); // check for == u8 done here
@@ -13690,15 +13451,15 @@ function weierstrass(curveDef) {
13690
13451
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
13691
13452
  */
13692
13453
  function int2octets(num) {
13693
- aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
13454
+ aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
13694
13455
  // works with order, can have different size than numToField!
13695
13456
  return numberToBytesBE(num, CURVE.nByteLength);
13696
13457
  }
13697
13458
  // Steps A, D of RFC6979 3.2
13698
13459
  // Creates RFC6979 seed; converts msg/privKey to numbers.
13699
13460
  // Used only in sign, not in verify.
13700
- // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order, this will be wrong at least for P521.
13701
- // Also it can be bigger for P224 + SHA256
13461
+ // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
13462
+ // this will be invalid at least for P521. Also it can be bigger for P224 + SHA256
13702
13463
  function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
13703
13464
  if (['recovered', 'canonical'].some((k) => k in opts))
13704
13465
  throw new Error('sign() legacy options not supported');
@@ -13792,39 +13553,48 @@ function weierstrass(curveDef) {
13792
13553
  const sg = signature;
13793
13554
  msgHash = ensureBytes('msgHash', msgHash);
13794
13555
  publicKey = ensureBytes('publicKey', publicKey);
13556
+ const { lowS, prehash, format } = opts;
13557
+ // Verify opts, deduce signature format
13558
+ validateSigVerOpts(opts);
13795
13559
  if ('strict' in opts)
13796
13560
  throw new Error('options.strict was renamed to lowS');
13797
- validateSigVerOpts(opts);
13798
- const { lowS, prehash } = opts;
13561
+ if (format !== undefined && format !== 'compact' && format !== 'der')
13562
+ throw new Error('format must be compact or der');
13563
+ const isHex = typeof sg === 'string' || isBytes$1(sg);
13564
+ const isObj = !isHex &&
13565
+ !format &&
13566
+ typeof sg === 'object' &&
13567
+ sg !== null &&
13568
+ typeof sg.r === 'bigint' &&
13569
+ typeof sg.s === 'bigint';
13570
+ if (!isHex && !isObj)
13571
+ throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
13799
13572
  let _sig = undefined;
13800
13573
  let P;
13801
13574
  try {
13802
- if (typeof sg === 'string' || isBytes$1(sg)) {
13575
+ if (isObj)
13576
+ _sig = new Signature(sg.r, sg.s);
13577
+ if (isHex) {
13803
13578
  // Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
13804
13579
  // Since DER can also be 2*nByteLength bytes, we check for it first.
13805
13580
  try {
13806
- _sig = Signature.fromDER(sg);
13581
+ if (format !== 'compact')
13582
+ _sig = Signature.fromDER(sg);
13807
13583
  }
13808
13584
  catch (derError) {
13809
13585
  if (!(derError instanceof DER.Err))
13810
13586
  throw derError;
13811
- _sig = Signature.fromCompact(sg);
13812
13587
  }
13813
- }
13814
- else if (typeof sg === 'object' && typeof sg.r === 'bigint' && typeof sg.s === 'bigint') {
13815
- const { r, s } = sg;
13816
- _sig = new Signature(r, s);
13817
- }
13818
- else {
13819
- throw new Error('PARSE');
13588
+ if (!_sig && format !== 'der')
13589
+ _sig = Signature.fromCompact(sg);
13820
13590
  }
13821
13591
  P = Point.fromHex(publicKey);
13822
13592
  }
13823
13593
  catch (error) {
13824
- if (error.message === 'PARSE')
13825
- throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
13826
13594
  return false;
13827
13595
  }
13596
+ if (!_sig)
13597
+ return false;
13828
13598
  if (lowS && _sig.hasHighS())
13829
13599
  return false;
13830
13600
  if (prehash)
@@ -13852,20 +13622,36 @@ function weierstrass(curveDef) {
13852
13622
  };
13853
13623
  }
13854
13624
 
13625
+ /**
13626
+ * Utilities for short weierstrass curves, combined with noble-hashes.
13627
+ * @module
13628
+ */
13855
13629
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
13856
- // connects noble-curves to noble-hashes
13630
+ /** connects noble-curves to noble-hashes */
13857
13631
  function getHash(hash) {
13858
13632
  return {
13859
13633
  hash,
13860
13634
  hmac: (key, ...msgs) => hmac(hash, key, concatBytes$1(...msgs)),
13861
- randomBytes: randomBytes$1,
13635
+ randomBytes,
13862
13636
  };
13863
13637
  }
13864
13638
  function createCurve(curveDef, defHash) {
13865
13639
  const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
13866
- return Object.freeze({ ...create(defHash), create });
13640
+ return { ...create(defHash), create };
13867
13641
  }
13868
13642
 
13643
+ /**
13644
+ * NIST secp256k1. See [pdf](https://www.secg.org/sec2-v2.pdf).
13645
+ *
13646
+ * Seems to be rigid (not backdoored)
13647
+ * [as per discussion](https://bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975).
13648
+ *
13649
+ * secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
13650
+ * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
13651
+ * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
13652
+ * [See explanation](https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066).
13653
+ * @module
13654
+ */
13869
13655
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
13870
13656
  const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
13871
13657
  const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
@@ -13896,31 +13682,35 @@ function sqrtMod(y) {
13896
13682
  const t1 = (pow2(b223, _23n, P) * b22) % P;
13897
13683
  const t2 = (pow2(t1, _6n, P) * b2) % P;
13898
13684
  const root = pow2(t2, _2n, P);
13899
- if (!Fp.eql(Fp.sqr(root), y))
13685
+ if (!Fpk1.eql(Fpk1.sqr(root), y))
13900
13686
  throw new Error('Cannot find square root');
13901
13687
  return root;
13902
13688
  }
13903
- const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
13689
+ const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
13904
13690
  /**
13905
13691
  * secp256k1 short weierstrass curve and ECDSA signatures over it.
13692
+ *
13693
+ * @example
13694
+ * import { secp256k1 } from '@noble/curves/secp256k1';
13695
+ *
13696
+ * const priv = secp256k1.utils.randomPrivateKey();
13697
+ * const pub = secp256k1.getPublicKey(priv);
13698
+ * const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
13699
+ * const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
13700
+ * const isValid = secp256k1.verify(sig, msg, pub) === true;
13906
13701
  */
13907
13702
  const secp256k1 = createCurve({
13908
13703
  a: BigInt(0), // equation params: a, b
13909
- b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
13910
- Fp, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
13704
+ b: BigInt(7),
13705
+ Fp: Fpk1, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
13911
13706
  n: secp256k1N, // Curve order, total count of valid points in the field
13912
13707
  // Base point (x, y) aka generator point
13913
13708
  Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
13914
13709
  Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
13915
13710
  h: BigInt(1), // Cofactor
13916
13711
  lowS: true, // Allow only low-S signatures by default in sign() and verify()
13917
- /**
13918
- * secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
13919
- * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
13920
- * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
13921
- * Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
13922
- */
13923
13712
  endo: {
13713
+ // Endomorphism, see above
13924
13714
  beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
13925
13715
  splitScalar: (k) => {
13926
13716
  const n = secp256k1N;
@@ -13951,27 +13741,15 @@ const secp256k1 = createCurve({
13951
13741
  BigInt(0);
13952
13742
  secp256k1.ProjectivePoint;
13953
13743
 
13954
- function generateKey() {
13955
- return secp256k1.utils.randomPrivateKey();
13956
- }
13957
- /**
13958
- * Hash and sign message with private key
13959
- */
13960
- function hashAndSign(key, msg) {
13961
- const p = sha256$1.digest(msg instanceof Uint8Array ? msg : msg.subarray());
13962
- if (isPromise(p)) {
13963
- return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
13964
- .catch(err => {
13965
- throw new CodeError(String(err), 'ERR_INVALID_INPUT');
13966
- });
13967
- }
13968
- try {
13969
- return secp256k1.sign(p.digest, key).toDERRawBytes();
13970
- }
13971
- catch (err) {
13972
- throw new CodeError(String(err), 'ERR_INVALID_INPUT');
13744
+ function isPromise(thing) {
13745
+ if (thing == null) {
13746
+ return false;
13973
13747
  }
13748
+ return typeof thing.then === 'function' &&
13749
+ typeof thing.catch === 'function' &&
13750
+ typeof thing.finally === 'function';
13974
13751
  }
13752
+
13975
13753
  /**
13976
13754
  * Hash message and verify signature with public key
13977
13755
  */
@@ -13980,208 +13758,93 @@ function hashAndVerify(key, sig, msg) {
13980
13758
  if (isPromise(p)) {
13981
13759
  return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
13982
13760
  .catch(err => {
13983
- throw new CodeError(String(err), 'ERR_INVALID_INPUT');
13761
+ throw new VerificationError(String(err));
13984
13762
  });
13985
13763
  }
13986
13764
  try {
13987
13765
  return secp256k1.verify(sig, p.digest, key);
13988
13766
  }
13989
13767
  catch (err) {
13990
- throw new CodeError(String(err), 'ERR_INVALID_INPUT');
13991
- }
13992
- }
13993
- function compressPublicKey(key) {
13994
- const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
13995
- return point;
13996
- }
13997
- function validatePrivateKey(key) {
13998
- try {
13999
- secp256k1.getPublicKey(key, true);
14000
- }
14001
- catch (err) {
14002
- throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
14003
- }
14004
- }
14005
- function validatePublicKey(key) {
14006
- try {
14007
- secp256k1.ProjectivePoint.fromHex(key);
14008
- }
14009
- catch (err) {
14010
- throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
14011
- }
14012
- }
14013
- function computePublicKey(privateKey) {
14014
- try {
14015
- return secp256k1.getPublicKey(privateKey, true);
14016
- }
14017
- catch (err) {
14018
- throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
13768
+ throw new VerificationError(String(err));
14019
13769
  }
14020
13770
  }
14021
13771
 
14022
13772
  class Secp256k1PublicKey {
13773
+ type = 'secp256k1';
13774
+ raw;
14023
13775
  _key;
14024
13776
  constructor(key) {
14025
- validatePublicKey(key);
14026
- this._key = key;
14027
- }
14028
- verify(data, sig) {
14029
- return hashAndVerify(this._key, sig, data);
14030
- }
14031
- marshal() {
14032
- return compressPublicKey(this._key);
14033
- }
14034
- get bytes() {
14035
- return PublicKey.encode({
14036
- Type: KeyType.Secp256k1,
14037
- Data: this.marshal()
14038
- }).subarray();
14039
- }
14040
- equals(key) {
14041
- return equals(this.bytes, key.bytes);
14042
- }
14043
- async hash() {
14044
- const p = sha256$1.digest(this.bytes);
14045
- let bytes;
14046
- if (isPromise(p)) {
14047
- ({ bytes } = await p);
14048
- }
14049
- else {
14050
- bytes = p.bytes;
14051
- }
14052
- return bytes;
13777
+ this._key = validateSecp256k1PublicKey(key);
13778
+ this.raw = compressSecp256k1PublicKey(this._key);
14053
13779
  }
14054
- }
14055
- class Secp256k1PrivateKey {
14056
- _key;
14057
- _publicKey;
14058
- constructor(key, publicKey) {
14059
- this._key = key;
14060
- this._publicKey = publicKey ?? computePublicKey(key);
14061
- validatePrivateKey(this._key);
14062
- validatePublicKey(this._publicKey);
13780
+ toMultihash() {
13781
+ return identity.digest(publicKeyToProtobuf(this));
14063
13782
  }
14064
- sign(message) {
14065
- return hashAndSign(this._key, message);
14066
- }
14067
- get public() {
14068
- return new Secp256k1PublicKey(this._publicKey);
14069
- }
14070
- marshal() {
14071
- return this._key;
13783
+ toCID() {
13784
+ return CID.createV1(114, this.toMultihash());
14072
13785
  }
14073
- get bytes() {
14074
- return PrivateKey.encode({
14075
- Type: KeyType.Secp256k1,
14076
- Data: this.marshal()
14077
- }).subarray();
13786
+ toString() {
13787
+ return base58btc.encode(this.toMultihash().bytes).substring(1);
14078
13788
  }
14079
13789
  equals(key) {
14080
- return equals(this.bytes, key.bytes);
14081
- }
14082
- hash() {
14083
- const p = sha256$1.digest(this.bytes);
14084
- if (isPromise(p)) {
14085
- return p.then(({ bytes }) => bytes);
13790
+ if (key == null || !(key.raw instanceof Uint8Array)) {
13791
+ return false;
14086
13792
  }
14087
- return p.bytes;
14088
- }
14089
- /**
14090
- * Gets the ID of the key.
14091
- *
14092
- * The key id is the base58 encoding of the SHA-256 multihash of its public key.
14093
- * The public key is a protobuf encoding containing a type and the DER encoding
14094
- * of the PKCS SubjectPublicKeyInfo.
14095
- */
14096
- async id() {
14097
- const hash = await this.public.hash();
14098
- return toString$1(hash, 'base58btc');
13793
+ return equals(this.raw, key.raw);
14099
13794
  }
14100
- /**
14101
- * Exports the key into a password protected `format`
14102
- */
14103
- async export(password, format = 'libp2p-key') {
14104
- if (format === 'libp2p-key') {
14105
- return exporter(this.bytes, password);
14106
- }
14107
- else {
14108
- throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
14109
- }
13795
+ verify(data, sig) {
13796
+ return hashAndVerify(this._key, sig, data);
14110
13797
  }
14111
13798
  }
14112
- function unmarshalSecp256k1PrivateKey(bytes) {
14113
- return new Secp256k1PrivateKey(bytes);
14114
- }
13799
+
14115
13800
  function unmarshalSecp256k1PublicKey(bytes) {
14116
13801
  return new Secp256k1PublicKey(bytes);
14117
13802
  }
14118
- async function generateKeyPair() {
14119
- const privateKeyBytes = generateKey();
14120
- return new Secp256k1PrivateKey(privateKeyBytes);
13803
+ function compressSecp256k1PublicKey(key) {
13804
+ const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
13805
+ return point;
13806
+ }
13807
+ function validateSecp256k1PublicKey(key) {
13808
+ try {
13809
+ secp256k1.ProjectivePoint.fromHex(key);
13810
+ return key;
13811
+ }
13812
+ catch (err) {
13813
+ throw new InvalidPublicKeyError(String(err));
13814
+ }
14121
13815
  }
14122
-
14123
- var Secp256k1 = /*#__PURE__*/Object.freeze({
14124
- __proto__: null,
14125
- Secp256k1PrivateKey: Secp256k1PrivateKey,
14126
- Secp256k1PublicKey: Secp256k1PublicKey,
14127
- generateKeyPair: generateKeyPair,
14128
- unmarshalSecp256k1PrivateKey: unmarshalSecp256k1PrivateKey,
14129
- unmarshalSecp256k1PublicKey: unmarshalSecp256k1PublicKey
14130
- });
14131
13816
 
14132
13817
  /**
14133
13818
  * @packageDocumentation
14134
13819
  *
14135
- * **Supported Key Types**
14136
- *
14137
- * The {@link generateKeyPair}, {@link marshalPublicKey}, and {@link marshalPrivateKey} functions accept a string `type` argument.
13820
+ * ## Supported Key Types
14138
13821
  *
14139
13822
  * Currently the `'RSA'`, `'ed25519'`, and `secp256k1` types are supported, although ed25519 and secp256k1 keys support only signing and verification of messages.
14140
13823
  *
14141
13824
  * For encryption / decryption support, RSA keys should be used.
14142
13825
  */
14143
- const supportedKeys = {
14144
- rsa: RSA,
14145
- ed25519: Ed25519,
14146
- secp256k1: Secp256k1
14147
- };
14148
- function unsupportedKey(type) {
14149
- const supported = Object.keys(supportedKeys).join(' / ');
14150
- return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
14151
- }
14152
13826
  /**
14153
- * Converts a protobuf serialized public key into its representative object
13827
+ * Creates a public key from the raw key bytes
14154
13828
  */
14155
- function unmarshalPublicKey(buf) {
14156
- const decoded = PublicKey.decode(buf);
14157
- const data = decoded.Data ?? new Uint8Array();
14158
- switch (decoded.Type) {
14159
- case KeyType.RSA:
14160
- return supportedKeys.rsa.unmarshalRsaPublicKey(data);
14161
- case KeyType.Ed25519:
14162
- return supportedKeys.ed25519.unmarshalEd25519PublicKey(data);
14163
- case KeyType.Secp256k1:
14164
- return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data);
14165
- default:
14166
- throw unsupportedKey(decoded.Type ?? 'unknown');
13829
+ function publicKeyFromRaw(buf) {
13830
+ if (buf.byteLength === 32) {
13831
+ return unmarshalEd25519PublicKey(buf);
13832
+ }
13833
+ else if (buf.byteLength === 33) {
13834
+ return unmarshalSecp256k1PublicKey(buf);
13835
+ }
13836
+ else {
13837
+ return pkixToRSAPublicKey(buf);
14167
13838
  }
14168
13839
  }
14169
13840
  /**
14170
- * Converts a protobuf serialized private key into its representative object
13841
+ * Converts a public key object into a protobuf serialized public key
14171
13842
  */
14172
- async function unmarshalPrivateKey(buf) {
14173
- const decoded = PrivateKey.decode(buf);
14174
- const data = decoded.Data ?? new Uint8Array();
14175
- switch (decoded.Type) {
14176
- case KeyType.RSA:
14177
- return supportedKeys.rsa.unmarshalRsaPrivateKey(data);
14178
- case KeyType.Ed25519:
14179
- return supportedKeys.ed25519.unmarshalEd25519PrivateKey(data);
14180
- case KeyType.Secp256k1:
14181
- return supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(data);
14182
- default:
14183
- throw unsupportedKey(decoded.Type ?? 'RSA');
14184
- }
13843
+ function publicKeyToProtobuf(key) {
13844
+ return PublicKey.encode({
13845
+ Type: KeyType[key.type],
13846
+ Data: key.raw
13847
+ });
14185
13848
  }
14186
13849
 
14187
13850
  /**
@@ -14200,25 +13863,16 @@ async function unmarshalPrivateKey(buf) {
14200
13863
  * ```
14201
13864
  */
14202
13865
  const inspect = Symbol.for('nodejs.util.inspect.custom');
14203
- const baseDecoder = Object
14204
- .values(bases)
14205
- .map(codec => codec.decoder)
14206
- // @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
14207
- .reduce((acc, curr) => acc.or(curr), bases.identity.decoder);
14208
13866
  // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
14209
13867
  const LIBP2P_KEY_CODE = 0x72;
14210
- const MARSHALLED_ED225519_PUBLIC_KEY_LENGTH = 36;
14211
- const MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH = 37;
14212
13868
  class PeerIdImpl {
14213
13869
  type;
14214
13870
  multihash;
14215
- privateKey;
14216
13871
  publicKey;
14217
13872
  string;
14218
13873
  constructor(init) {
14219
13874
  this.type = init.type;
14220
13875
  this.multihash = init.multihash;
14221
- this.privateKey = init.privateKey;
14222
13876
  // mark string cache as non-enumerable
14223
13877
  Object.defineProperty(this, 'string', {
14224
13878
  enumerable: false,
@@ -14235,17 +13889,14 @@ class PeerIdImpl {
14235
13889
  }
14236
13890
  return this.string;
14237
13891
  }
13892
+ toMultihash() {
13893
+ return this.multihash;
13894
+ }
14238
13895
  // return self-describing String representation
14239
13896
  // in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
14240
13897
  toCID() {
14241
13898
  return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
14242
13899
  }
14243
- toBytes() {
14244
- return this.multihash.bytes;
14245
- }
14246
- /**
14247
- * Returns Multiaddr as a JSON string
14248
- */
14249
13900
  toJSON() {
14250
13901
  return this.toString();
14251
13902
  }
@@ -14260,10 +13911,10 @@ class PeerIdImpl {
14260
13911
  return equals(this.multihash.bytes, id);
14261
13912
  }
14262
13913
  else if (typeof id === 'string') {
14263
- return peerIdFromString(id).equals(this);
13914
+ return this.toString() === id;
14264
13915
  }
14265
- else if (id?.multihash?.bytes != null) {
14266
- return equals(this.multihash.bytes, id.multihash.bytes);
13916
+ else if (id?.toMultihash()?.bytes != null) {
13917
+ return equals(this.multihash.bytes, id.toMultihash().bytes);
14267
13918
  }
14268
13919
  else {
14269
13920
  throw new Error('not valid Id');
@@ -14285,7 +13936,7 @@ class PeerIdImpl {
14285
13936
  return `PeerId(${this.toString()})`;
14286
13937
  }
14287
13938
  }
14288
- class RSAPeerIdImpl extends PeerIdImpl {
13939
+ class RSAPeerId extends PeerIdImpl {
14289
13940
  type = 'RSA';
14290
13941
  publicKey;
14291
13942
  constructor(init) {
@@ -14293,153 +13944,67 @@ class RSAPeerIdImpl extends PeerIdImpl {
14293
13944
  this.publicKey = init.publicKey;
14294
13945
  }
14295
13946
  }
14296
- class Ed25519PeerIdImpl extends PeerIdImpl {
13947
+ class Ed25519PeerId extends PeerIdImpl {
14297
13948
  type = 'Ed25519';
14298
13949
  publicKey;
14299
13950
  constructor(init) {
14300
13951
  super({ ...init, type: 'Ed25519' });
14301
- this.publicKey = init.multihash.digest;
13952
+ this.publicKey = init.publicKey;
14302
13953
  }
14303
13954
  }
14304
- class Secp256k1PeerIdImpl extends PeerIdImpl {
13955
+ class Secp256k1PeerId extends PeerIdImpl {
14305
13956
  type = 'secp256k1';
14306
13957
  publicKey;
14307
13958
  constructor(init) {
14308
13959
  super({ ...init, type: 'secp256k1' });
14309
- this.publicKey = init.multihash.digest;
14310
- }
14311
- }
14312
- // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
14313
- const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
14314
- class URLPeerIdImpl {
14315
- type = 'url';
14316
- multihash;
14317
- privateKey;
14318
- publicKey;
14319
- url;
14320
- constructor(url) {
14321
- this.url = url.toString();
14322
- this.multihash = identity.digest(fromString(this.url));
14323
- }
14324
- [inspect]() {
14325
- return `PeerId(${this.url})`;
14326
- }
14327
- [peerIdSymbol] = true;
14328
- toString() {
14329
- return this.toCID().toString();
14330
- }
14331
- toCID() {
14332
- return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
14333
- }
14334
- toBytes() {
14335
- return this.toCID().bytes;
14336
- }
14337
- equals(other) {
14338
- if (other == null) {
14339
- return false;
14340
- }
14341
- if (other instanceof Uint8Array) {
14342
- other = toString$1(other);
14343
- }
14344
- return other.toString() === this.toString();
14345
- }
14346
- }
14347
- function peerIdFromString(str, decoder) {
14348
- if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
14349
- // identity hash ed25519/secp256k1 key or sha2-256 hash of
14350
- // rsa public key - base58btc encoded either way
14351
- const multihash = decode$2(base58btc.decode(`z${str}`));
14352
- if (str.startsWith('12D')) {
14353
- return new Ed25519PeerIdImpl({ multihash });
14354
- }
14355
- else if (str.startsWith('16U')) {
14356
- return new Secp256k1PeerIdImpl({ multihash });
14357
- }
14358
- else {
14359
- return new RSAPeerIdImpl({ multihash });
14360
- }
14361
- }
14362
- return peerIdFromBytes(baseDecoder.decode(str));
14363
- }
14364
- function peerIdFromBytes(buf) {
14365
- try {
14366
- const multihash = decode$2(buf);
14367
- if (multihash.code === identity.code) {
14368
- if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
14369
- return new Ed25519PeerIdImpl({ multihash });
14370
- }
14371
- else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
14372
- return new Secp256k1PeerIdImpl({ multihash });
14373
- }
14374
- }
14375
- if (multihash.code === sha256$1.code) {
14376
- return new RSAPeerIdImpl({ multihash });
14377
- }
14378
- }
14379
- catch {
14380
- return peerIdFromCID(CID.decode(buf));
14381
- }
14382
- throw new Error('Supplied PeerID CID is invalid');
14383
- }
14384
- function peerIdFromCID(cid) {
14385
- if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
14386
- throw new Error('Supplied PeerID CID is invalid');
14387
- }
14388
- if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
14389
- const url = toString$1(cid.multihash.digest);
14390
- return new URLPeerIdImpl(new URL(url));
14391
- }
14392
- const multihash = cid.multihash;
14393
- if (multihash.code === sha256$1.code) {
14394
- return new RSAPeerIdImpl({ multihash: cid.multihash });
14395
- }
14396
- else if (multihash.code === identity.code) {
14397
- if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
14398
- return new Ed25519PeerIdImpl({ multihash: cid.multihash });
14399
- }
14400
- else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
14401
- return new Secp256k1PeerIdImpl({ multihash: cid.multihash });
14402
- }
13960
+ this.publicKey = init.publicKey;
14403
13961
  }
14404
- throw new Error('Supplied PeerID CID is invalid');
14405
13962
  }
13963
+
14406
13964
  /**
14407
- * @param publicKey - A marshalled public key
14408
- * @param privateKey - A marshalled private key
13965
+ * @packageDocumentation
13966
+ *
13967
+ * An implementation of a peer id
13968
+ *
13969
+ * @example
13970
+ *
13971
+ * ```TypeScript
13972
+ * import { peerIdFromString } from '@libp2p/peer-id'
13973
+ * const peer = peerIdFromString('12D3KooWKnDdG3iXw9eTFijk3EWSunZcFi54Zka4wmtqtt6rPxc8')
13974
+ *
13975
+ * console.log(peer.toCID()) // CID(bafzaa...)
13976
+ * console.log(peer.toString()) // "12D3K..."
13977
+ * ```
14409
13978
  */
14410
- async function peerIdFromKeys(publicKey, privateKey) {
14411
- if (publicKey.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
14412
- return new Ed25519PeerIdImpl({ multihash: create$1(identity.code, publicKey), privateKey });
13979
+ function peerIdFromPublicKey(publicKey) {
13980
+ if (publicKey.type === 'Ed25519') {
13981
+ return new Ed25519PeerId({
13982
+ multihash: publicKey.toCID().multihash,
13983
+ publicKey
13984
+ });
13985
+ }
13986
+ else if (publicKey.type === 'secp256k1') {
13987
+ return new Secp256k1PeerId({
13988
+ multihash: publicKey.toCID().multihash,
13989
+ publicKey
13990
+ });
14413
13991
  }
14414
- if (publicKey.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
14415
- return new Secp256k1PeerIdImpl({ multihash: create$1(identity.code, publicKey), privateKey });
13992
+ else if (publicKey.type === 'RSA') {
13993
+ return new RSAPeerId({
13994
+ multihash: publicKey.toCID().multihash,
13995
+ publicKey
13996
+ });
14416
13997
  }
14417
- return new RSAPeerIdImpl({ multihash: await sha256$1.digest(publicKey), publicKey, privateKey });
13998
+ throw new UnsupportedKeyTypeError();
14418
13999
  }
14419
14000
 
14001
+ const ERR_TYPE_NOT_IMPLEMENTED = "Keypair type not implemented";
14420
14002
  function createPeerIdFromPublicKey(publicKey) {
14421
- const _publicKey = new supportedKeys.secp256k1.Secp256k1PublicKey(publicKey);
14422
- return peerIdFromKeys(_publicKey.bytes, undefined);
14423
- }
14424
- function getPublicKeyFromPeerId(peerId) {
14425
- if (peerId.type !== "secp256k1") {
14426
- throw new Error("Unsupported peer id type");
14427
- }
14428
- if (!peerId.publicKey) {
14429
- throw new Error("Public key not present on peer id");
14430
- }
14431
- return unmarshalPublicKey(peerId.publicKey).marshal();
14432
- }
14433
- // Only used in tests
14434
- async function getPrivateKeyFromPeerId(peerId) {
14435
- if (peerId.type !== "secp256k1") {
14436
- throw new Error("Unsupported peer id type");
14437
- }
14438
- if (!peerId.privateKey) {
14439
- throw new Error("Private key not present on peer id");
14003
+ const pubKey = publicKeyFromRaw(publicKey);
14004
+ if (pubKey.type !== "secp256k1") {
14005
+ throw new Error(ERR_TYPE_NOT_IMPLEMENTED);
14440
14006
  }
14441
- const privateKey = await unmarshalPrivateKey(peerId.privateKey);
14442
- return privateKey.marshal();
14007
+ return peerIdFromPublicKey(pubKey);
14443
14008
  }
14444
14009
 
14445
14010
  function decodeMultiaddrs(bytes) {
@@ -14686,12 +14251,12 @@ var TransportProtocolPerIpVersion;
14686
14251
  class ENR extends RawEnr {
14687
14252
  static RECORD_PREFIX = "enr:";
14688
14253
  peerId;
14689
- static async create(kvs = {}, seq = BigInt(1), signature) {
14254
+ static create(kvs = {}, seq = BigInt(1), signature) {
14690
14255
  const enr = new ENR(kvs, seq, signature);
14691
14256
  try {
14692
14257
  const publicKey = enr.publicKey;
14693
14258
  if (publicKey) {
14694
- enr.peerId = await createPeerIdFromPublicKey(publicKey);
14259
+ enr.peerId = createPeerIdFromPublicKey(publicKey);
14695
14260
  }
14696
14261
  }
14697
14262
  catch (e) {
@@ -14813,7 +14378,7 @@ class EnrCreator {
14813
14378
  static fromPublicKey(publicKey, kvs = {}) {
14814
14379
  // EIP-778 specifies that the key must be in compressed format, 33 bytes
14815
14380
  if (publicKey.length !== 33) {
14816
- publicKey = compressPublicKey$1(publicKey);
14381
+ publicKey = compressPublicKey(publicKey);
14817
14382
  }
14818
14383
  return ENR.create({
14819
14384
  ...kvs,
@@ -14824,7 +14389,7 @@ class EnrCreator {
14824
14389
  static async fromPeerId(peerId, kvs = {}) {
14825
14390
  switch (peerId.type) {
14826
14391
  case "secp256k1":
14827
- return EnrCreator.fromPublicKey(getPublicKeyFromPeerId(peerId), kvs);
14392
+ return EnrCreator.fromPublicKey(peerId.publicKey.raw, kvs);
14828
14393
  default:
14829
14394
  throw new Error();
14830
14395
  }
@@ -15478,7 +15043,7 @@ async function fromValues(values) {
15478
15043
  }
15479
15044
  }
15480
15045
  const _seq = decodeSeq(seq);
15481
- const enr = await ENR.create(obj, _seq, signature);
15046
+ const enr = ENR.create(obj, _seq, signature);
15482
15047
  checkSignature(seq, kvs, enr, signature);
15483
15048
  return enr;
15484
15049
  }
@@ -15511,4 +15076,4 @@ function checkSignature(seq, kvs, enr, signature) {
15511
15076
  }
15512
15077
  }
15513
15078
 
15514
- export { ENR, ERR_INVALID_ID, ERR_NO_SIGNATURE, EnrCreator, EnrDecoder, MAX_RECORD_SIZE, MULTIADDR_LENGTH_SIZE, TransportProtocol, TransportProtocolPerIpVersion, compressPublicKey$1 as compressPublicKey, createPeerIdFromPublicKey, decodeWaku2, encodeWaku2, getPrivateKeyFromPeerId, getPublicKeyFromPeerId, keccak256, sign$1 as sign, verifySignature };
15079
+ export { ENR, ERR_INVALID_ID, ERR_NO_SIGNATURE, ERR_TYPE_NOT_IMPLEMENTED, EnrCreator, EnrDecoder, MAX_RECORD_SIZE, MULTIADDR_LENGTH_SIZE, TransportProtocol, TransportProtocolPerIpVersion, compressPublicKey, createPeerIdFromPublicKey, decodeWaku2, encodeWaku2, keccak256, sign$1 as sign, verifySignature };