@waku/discovery 0.0.6-f599932.0 → 0.0.7-1c0c5ee.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
@@ -19,31 +19,35 @@
19
19
  */
20
20
  const peerDiscoverySymbol = Symbol.for('@libp2p/peer-discovery');
21
21
 
22
- const peerIdSymbol = Symbol.for('@libp2p/peer-id');
22
+ /**
23
+ * All PeerId implementations must use this symbol as the name of a property
24
+ * with a boolean `true` value
25
+ */
26
+ const peerIdSymbol$1 = Symbol.for('@libp2p/peer-id');
23
27
 
24
28
  /**
25
29
  * When this error is thrown it means an operation was aborted,
26
30
  * usually in response to the `abort` event being emitted by an
27
31
  * AbortSignal.
28
32
  */
29
- class CodeError extends Error {
30
- code;
31
- props;
32
- constructor(message, code, props) {
33
+ /**
34
+ * Thrown when invalid parameters are passed to a function or method call
35
+ */
36
+ let InvalidParametersError$1 = class InvalidParametersError extends Error {
37
+ static name = 'InvalidParametersError';
38
+ constructor(message = 'Invalid parameters') {
33
39
  super(message);
34
- this.code = code;
35
- this.name = props?.name ?? 'CodeError';
36
- this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
40
+ this.name = 'InvalidParametersError';
37
41
  }
38
- }
39
- class AggregateCodeError extends AggregateError {
40
- code;
41
- props;
42
- constructor(errors, message, code, props) {
43
- super(errors, message);
44
- this.code = code;
45
- this.name = props?.name ?? 'AggregateCodeError';
46
- this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
42
+ };
43
+ /**
44
+ * Thrown when an invalid multihash is encountered
45
+ */
46
+ class InvalidMultihashError extends Error {
47
+ static name = 'InvalidMultihashError';
48
+ constructor(message = 'Invalid Multihash') {
49
+ super(message);
50
+ this.name = 'InvalidMultihashError';
47
51
  }
48
52
  }
49
53
 
@@ -114,7 +118,6 @@ class TypedEventEmitter extends EventTarget {
114
118
  return this.dispatchEvent(new CustomEvent(type, detail));
115
119
  }
116
120
  }
117
- const CustomEvent = globalThis.CustomEvent;
118
121
 
119
122
  var Protocols;
120
123
  (function (Protocols) {
@@ -292,23 +295,6 @@ const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLen
292
295
  // The rotate right (circular right shift) operation for uint32
293
296
  const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
294
297
  new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
295
- // There is no setImmediate in browser and setTimeout is slow.
296
- // call of async fn will return Promise, which will be fullfiled only on
297
- // next scheduler queue processing step and this is exactly what we need.
298
- const nextTick = async () => { };
299
- // Returns control to thread each 'tick' ms to avoid blocking
300
- async function asyncLoop(iters, tick, cb) {
301
- let ts = Date.now();
302
- for (let i = 0; i < iters; i++) {
303
- cb(i);
304
- // Date.now() is not monotonic, so in case if clock goes backwards we return return control too
305
- const diff = Date.now() - ts;
306
- if (diff >= 0 && diff < tick)
307
- continue;
308
- await nextTick();
309
- ts += diff;
310
- }
311
- }
312
298
  /**
313
299
  * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
314
300
  */
@@ -353,13 +339,6 @@ class Hash {
353
339
  return this._cloneInto();
354
340
  }
355
341
  }
356
- const toStr = {}.toString;
357
- function checkOpts(defaults, opts) {
358
- if (opts !== undefined && toStr.call(opts) !== '[object Object]')
359
- throw new Error('Options should be object or undefined');
360
- const merged = Object.assign(defaults, opts);
361
- return merged;
362
- }
363
342
  function wrapConstructor(hashCons) {
364
343
  const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
365
344
  const tmp = hashCons();
@@ -371,14 +350,20 @@ function wrapConstructor(hashCons) {
371
350
  /**
372
351
  * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
373
352
  */
374
- function randomBytes$1(bytesLength = 32) {
353
+ function randomBytes(bytesLength = 32) {
375
354
  if (crypto$2 && typeof crypto$2.getRandomValues === 'function') {
376
355
  return crypto$2.getRandomValues(new Uint8Array(bytesLength));
377
356
  }
357
+ // Legacy Node.js compatibility
358
+ if (crypto$2 && typeof crypto$2.randomBytes === 'function') {
359
+ return crypto$2.randomBytes(bytesLength);
360
+ }
378
361
  throw new Error('crypto.getRandomValues must be defined');
379
362
  }
380
363
 
381
- // Polyfill for Safari 14
364
+ /**
365
+ * Polyfill for Safari 14
366
+ */
382
367
  function setBigUint64(view, byteOffset, value, isLE) {
383
368
  if (typeof view.setBigUint64 === 'function')
384
369
  return view.setBigUint64(byteOffset, value, isLE);
@@ -391,9 +376,13 @@ function setBigUint64(view, byteOffset, value, isLE) {
391
376
  view.setUint32(byteOffset + h, wh, isLE);
392
377
  view.setUint32(byteOffset + l, wl, isLE);
393
378
  }
394
- // Choice: a ? b : c
379
+ /**
380
+ * Choice: a ? b : c
381
+ */
395
382
  const Chi = (a, b, c) => (a & b) ^ (~a & c);
396
- // Majority function, true if any two inpust is true
383
+ /**
384
+ * Majority function, true if any two inputs is true
385
+ */
397
386
  const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
398
387
  /**
399
388
  * Merkle-Damgard hash construction base class.
@@ -838,11 +827,12 @@ class Decoder {
838
827
  constructor(name, prefix, baseDecode) {
839
828
  this.name = name;
840
829
  this.prefix = prefix;
830
+ const prefixCodePoint = prefix.codePointAt(0);
841
831
  /* c8 ignore next 3 */
842
- if (prefix.codePointAt(0) === undefined) {
832
+ if (prefixCodePoint === undefined) {
843
833
  throw new Error('Invalid prefix character');
844
834
  }
845
- this.prefixCodePoint = prefix.codePointAt(0);
835
+ this.prefixCodePoint = prefixCodePoint;
846
836
  this.baseDecode = baseDecode;
847
837
  }
848
838
  decode(text) {
@@ -1046,7 +1036,14 @@ var base2$1 = /*#__PURE__*/Object.freeze({
1046
1036
 
1047
1037
  const alphabet = Array.from('🚀🪐☄🛰🌌🌑🌒🌓🌔🌕🌖🌗🌘🌍🌏🌎🐉☀💻🖥💾💿😂❤😍🤣😊🙏💕😭😘👍😅👏😁🔥🥰💔💖💙😢🤔😆🙄💪😉☺👌🤗💜😔😎😇🌹🤦🎉💞✌✨🤷😱😌🌸🙌😋💗💚😏💛🙂💓🤩😄😀🖤😃💯🙈👇🎶😒🤭❣😜💋👀😪😑💥🙋😞😩😡🤪👊🥳😥🤤👉💃😳✋😚😝😴🌟😬🙃🍀🌷😻😓⭐✅🥺🌈😈🤘💦✔😣🏃💐☹🎊💘😠☝😕🌺🎂🌻😐🖕💝🙊😹🗣💫💀👑🎵🤞😛🔴😤🌼😫⚽🤙☕🏆🤫👈😮🙆🍻🍃🐶💁😲🌿🧡🎁⚡🌞🎈❌✊👋😰🤨😶🤝🚶💰🍓💢🤟🙁🚨💨🤬✈🎀🍺🤓😙💟🌱😖👶🥴▶➡❓💎💸⬇😨🌚🦋😷🕺⚠🙅😟😵👎🤲🤠🤧📌🔵💅🧐🐾🍒😗🤑🌊🤯🐷☎💧😯💆👆🎤🙇🍑❄🌴💣🐸💌📍🥀🤢👅💡💩👐📸👻🤐🤮🎼🥵🚩🍎🍊👼💍📣🥂');
1048
1038
  const alphabetBytesToChars = (alphabet.reduce((p, c, i) => { p[i] = c; return p; }, ([])));
1049
- const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => { p[c.codePointAt(0)] = i; return p; }, ([])));
1039
+ const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => {
1040
+ const codePoint = c.codePointAt(0);
1041
+ if (codePoint == null) {
1042
+ throw new Error(`Invalid character: ${c}`);
1043
+ }
1044
+ p[codePoint] = i;
1045
+ return p;
1046
+ }, ([])));
1050
1047
  function encode$8(data) {
1051
1048
  return data.reduce((p, c) => {
1052
1049
  p += alphabetBytesToChars[c];
@@ -1056,8 +1053,12 @@ function encode$8(data) {
1056
1053
  function decode$9(str) {
1057
1054
  const byts = [];
1058
1055
  for (const char of str) {
1059
- const byt = alphabetCharsToBytes[char.codePointAt(0)];
1060
- if (byt === undefined) {
1056
+ const codePoint = char.codePointAt(0);
1057
+ if (codePoint == null) {
1058
+ throw new Error(`Invalid character: ${char}`);
1059
+ }
1060
+ const byt = alphabetCharsToBytes[codePoint];
1061
+ if (byt == null) {
1061
1062
  throw new Error(`Non-base256emoji character: ${char}`);
1062
1063
  }
1063
1064
  byts.push(byt);
@@ -1330,7 +1331,7 @@ function encodingLength$3(int) {
1330
1331
  /**
1331
1332
  * Creates a multihash digest.
1332
1333
  */
1333
- function create$1(code, digest) {
1334
+ function create(code, digest) {
1334
1335
  const size = digest.byteLength;
1335
1336
  const sizeOffset = encodingLength$3(code);
1336
1337
  const digestOffset = sizeOffset + encodingLength$3(size);
@@ -1389,7 +1390,7 @@ const code = 0x0;
1389
1390
  const name$1 = 'identity';
1390
1391
  const encode$6 = coerce;
1391
1392
  function digest(input) {
1392
- return create$1(code, encode$6(input));
1393
+ return create(code, encode$6(input));
1393
1394
  }
1394
1395
  const identity = { code, name: name$1, encode: encode$6, digest };
1395
1396
 
@@ -1413,9 +1414,9 @@ class Hasher {
1413
1414
  if (input instanceof Uint8Array) {
1414
1415
  const result = this.encode(input);
1415
1416
  return result instanceof Uint8Array
1416
- ? create$1(this.code, result)
1417
+ ? create(this.code, result)
1417
1418
  /* c8 ignore next 1 */
1418
- : result.then(digest => create$1(this.code, digest));
1419
+ : result.then(digest => create(this.code, digest));
1419
1420
  }
1420
1421
  else {
1421
1422
  throw Error('Unknown type, must be binary type');
@@ -1515,7 +1516,7 @@ class CID {
1515
1516
  switch (this.version) {
1516
1517
  case 0: {
1517
1518
  const { code, digest } = this.multihash;
1518
- const multihash = create$1(code, digest);
1519
+ const multihash = create(code, digest);
1519
1520
  return (CID.createV1(this.code, multihash));
1520
1521
  }
1521
1522
  case 1: {
@@ -1745,9 +1746,13 @@ function parseCIDtoBytes(source, base) {
1745
1746
  const decoder = base ?? base32$2;
1746
1747
  return [base32$2.prefix, decoder.decode(source)];
1747
1748
  }
1749
+ case base36.prefix: {
1750
+ const decoder = base ?? base36;
1751
+ return [base36.prefix, decoder.decode(source)];
1752
+ }
1748
1753
  default: {
1749
1754
  if (base == null) {
1750
- throw Error('To parse non base32 or base58btc encoded CID multibase decoder must be provided');
1755
+ throw Error('To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided');
1751
1756
  }
1752
1757
  return [source[0], base.decode(source)];
1753
1758
  }
@@ -2014,7 +2019,7 @@ function requireMs () {
2014
2019
  * @api public
2015
2020
  */
2016
2021
 
2017
- ms = function(val, options) {
2022
+ ms = function (val, options) {
2018
2023
  options = options || {};
2019
2024
  var type = typeof val;
2020
2025
  if (type === 'string' && val.length > 0) {
@@ -2707,7 +2712,6 @@ var debug = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
2707
2712
 
2708
2713
  const APP_NAME = "waku";
2709
2714
  let Logger$1 = class Logger {
2710
- _debug;
2711
2715
  _info;
2712
2716
  _warn;
2713
2717
  _error;
@@ -2715,14 +2719,10 @@ let Logger$1 = class Logger {
2715
2719
  return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
2716
2720
  }
2717
2721
  constructor(prefix) {
2718
- this._debug = debug(Logger.createDebugNamespace("debug", prefix));
2719
2722
  this._info = debug(Logger.createDebugNamespace("info", prefix));
2720
2723
  this._warn = debug(Logger.createDebugNamespace("warn", prefix));
2721
2724
  this._error = debug(Logger.createDebugNamespace("error", prefix));
2722
2725
  }
2723
- get debug() {
2724
- return this._debug;
2725
- }
2726
2726
  get info() {
2727
2727
  return this._info;
2728
2728
  }
@@ -5532,7 +5532,7 @@ function ParseError(str) {
5532
5532
  * const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
5533
5533
  * ```
5534
5534
  */
5535
- const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
5535
+ const inspect$2 = Symbol.for('nodejs.util.inspect.custom');
5536
5536
  const symbol$1 = Symbol.for('@multiformats/js-multiaddr/multiaddr');
5537
5537
  const DNS_CODES = [
5538
5538
  getProtocol('dns').code,
@@ -5540,6 +5540,12 @@ const DNS_CODES = [
5540
5540
  getProtocol('dns6').code,
5541
5541
  getProtocol('dnsaddr').code
5542
5542
  ];
5543
+ class NoAvailableResolverError extends Error {
5544
+ constructor(message = 'No available resolver') {
5545
+ super(message);
5546
+ this.name = 'NoAvailableResolverError';
5547
+ }
5548
+ }
5543
5549
  /**
5544
5550
  * Creates a {@link Multiaddr} from a {@link MultiaddrInput}
5545
5551
  */
@@ -5709,7 +5715,7 @@ class Multiaddr {
5709
5715
  }
5710
5716
  const resolver = resolvers$1.get(resolvableProto.name);
5711
5717
  if (resolver == null) {
5712
- throw new CodeError(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
5718
+ throw new NoAvailableResolverError(`no available resolver for ${resolvableProto.name}`);
5713
5719
  }
5714
5720
  const result = await resolver(this, options);
5715
5721
  return result.map(str => multiaddr(str));
@@ -5750,7 +5756,7 @@ class Multiaddr {
5750
5756
  * // 'Multiaddr(/ip4/127.0.0.1/tcp/4001)'
5751
5757
  * ```
5752
5758
  */
5753
- [inspect$1]() {
5759
+ [inspect$2]() {
5754
5760
  return `Multiaddr(${this.#string})`;
5755
5761
  }
5756
5762
  }
@@ -5923,14 +5929,41 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
5923
5929
  return multiaddrFromFields(isIpv6 ? "ip6" : "ip4", protoName, ipVal, protoVal);
5924
5930
  }
5925
5931
 
5926
- function isPromise$1(thing) {
5927
- if (thing == null) {
5928
- return false;
5932
+ /**
5933
+ * When this error is thrown it means an operation was aborted,
5934
+ * usually in response to the `abort` event being emitted by an
5935
+ * AbortSignal.
5936
+ */
5937
+ /**
5938
+ * Thrown when invalid parameters are passed to a function or method call
5939
+ */
5940
+ class InvalidParametersError extends Error {
5941
+ static name = 'InvalidParametersError';
5942
+ constructor(message = 'Invalid parameters') {
5943
+ super(message);
5944
+ this.name = 'InvalidParametersError';
5945
+ }
5946
+ }
5947
+ /**
5948
+ * Thrown when a public key is invalid
5949
+ */
5950
+ class InvalidPublicKeyError extends Error {
5951
+ static name = 'InvalidPublicKeyError';
5952
+ constructor(message = 'Invalid public key') {
5953
+ super(message);
5954
+ this.name = 'InvalidPublicKeyError';
5929
5955
  }
5930
- return typeof thing.then === 'function' &&
5931
- typeof thing.catch === 'function' &&
5932
- typeof thing.finally === 'function';
5933
5956
  }
5957
+ /**
5958
+ * Thrown when and attempt to operate on an unsupported key was made
5959
+ */
5960
+ let UnsupportedKeyTypeError$1 = class UnsupportedKeyTypeError extends Error {
5961
+ static name = 'UnsupportedKeyTypeError';
5962
+ constructor(message = 'Unsupported key type') {
5963
+ super(message);
5964
+ this.name = 'UnsupportedKeyTypeError';
5965
+ }
5966
+ };
5934
5967
 
5935
5968
  const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
5936
5969
  const _32n = /* @__PURE__ */ BigInt(32);
@@ -7017,6 +7050,60 @@ function wNAF(c, bits) {
7017
7050
  },
7018
7051
  };
7019
7052
  }
7053
+ /**
7054
+ * Pippenger algorithm for multi-scalar multiplication (MSM).
7055
+ * MSM is basically (Pa + Qb + Rc + ...).
7056
+ * 30x faster vs naive addition on L=4096, 10x faster with precomputes.
7057
+ * For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
7058
+ * Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
7059
+ * @param c Curve Point constructor
7060
+ * @param field field over CURVE.N - important that it's not over CURVE.P
7061
+ * @param points array of L curve points
7062
+ * @param scalars array of L scalars (aka private keys / bigints)
7063
+ */
7064
+ function pippenger(c, field, points, scalars) {
7065
+ // If we split scalars by some window (let's say 8 bits), every chunk will only
7066
+ // take 256 buckets even if there are 4096 scalars, also re-uses double.
7067
+ // TODO:
7068
+ // - https://eprint.iacr.org/2024/750.pdf
7069
+ // - https://tches.iacr.org/index.php/TCHES/article/view/10287
7070
+ // 0 is accepted in scalars
7071
+ if (!Array.isArray(points) || !Array.isArray(scalars) || scalars.length !== points.length)
7072
+ throw new Error('arrays of points and scalars must have equal length');
7073
+ scalars.forEach((s, i) => {
7074
+ if (!field.isValid(s))
7075
+ throw new Error(`wrong scalar at index ${i}`);
7076
+ });
7077
+ points.forEach((p, i) => {
7078
+ if (!(p instanceof c))
7079
+ throw new Error(`wrong point at index ${i}`);
7080
+ });
7081
+ const wbits = bitLen(BigInt(points.length));
7082
+ const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
7083
+ const MASK = (1 << windowSize) - 1;
7084
+ const buckets = new Array(MASK + 1).fill(c.ZERO); // +1 for zero array
7085
+ const lastBits = Math.floor((field.BITS - 1) / windowSize) * windowSize;
7086
+ let sum = c.ZERO;
7087
+ for (let i = lastBits; i >= 0; i -= windowSize) {
7088
+ buckets.fill(c.ZERO);
7089
+ for (let j = 0; j < scalars.length; j++) {
7090
+ const scalar = scalars[j];
7091
+ const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
7092
+ buckets[wbits] = buckets[wbits].add(points[j]);
7093
+ }
7094
+ let resI = c.ZERO; // not using this will do small speed-up, but will lose ct
7095
+ // Skip first bucket, because it is zero
7096
+ for (let j = buckets.length - 1, sumI = c.ZERO; j > 0; j--) {
7097
+ sumI = sumI.add(buckets[j]);
7098
+ resI = resI.add(sumI);
7099
+ }
7100
+ sum = sum.add(resI);
7101
+ if (i !== 0)
7102
+ for (let j = 0; j < windowSize; j++)
7103
+ sum = sum.double();
7104
+ }
7105
+ return sum;
7106
+ }
7020
7107
  function validateBasic(curve) {
7021
7108
  validateField(curve.Fp);
7022
7109
  validateObject(curve, {
@@ -7071,6 +7158,7 @@ function twistedEdwards(curveDef) {
7071
7158
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
7072
7159
  const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
7073
7160
  const modP = Fp.create; // Function overrides
7161
+ const Fn = Field(CURVE.n, CURVE.nBitLength);
7074
7162
  // sqrt(u/v)
7075
7163
  const uvRatio = CURVE.uvRatio ||
7076
7164
  ((u, v) => {
@@ -7169,6 +7257,10 @@ function twistedEdwards(curveDef) {
7169
7257
  const toInv = Fp.invertBatch(points.map((p) => p.ez));
7170
7258
  return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
7171
7259
  }
7260
+ // Multiscalar Multiplication
7261
+ static msm(points, scalars) {
7262
+ return pippenger(Point, Fn, points, scalars);
7263
+ }
7172
7264
  // "Private method", don't use it directly
7173
7265
  _setWindowSize(windowSize) {
7174
7266
  wnaf.setWindowSize(this, windowSize);
@@ -7544,7 +7636,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
7544
7636
  Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
7545
7637
  Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
7546
7638
  hash: sha512,
7547
- randomBytes: randomBytes$1,
7639
+ randomBytes,
7548
7640
  adjustScalarBytes,
7549
7641
  // dom2
7550
7642
  // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
@@ -7557,176 +7649,46 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
7557
7649
  const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
7558
7650
 
7559
7651
  const PUBLIC_KEY_BYTE_LENGTH = 32;
7560
- const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
7561
- const KEYS_BYTE_LENGTH = 32;
7562
- function generateKey$2() {
7563
- // the actual private key (32 bytes)
7564
- const privateKeyRaw = ed25519.utils.randomPrivateKey();
7565
- const publicKey = ed25519.getPublicKey(privateKeyRaw);
7566
- // concatenated the public key to the private key
7567
- const privateKey = concatKeys(privateKeyRaw, publicKey);
7568
- return {
7569
- privateKey,
7570
- publicKey
7571
- };
7572
- }
7573
- /**
7574
- * Generate keypair from a 32 byte uint8array
7575
- */
7576
- function generateKeyFromSeed(seed) {
7577
- if (seed.length !== KEYS_BYTE_LENGTH) {
7578
- throw new TypeError('"seed" must be 32 bytes in length.');
7579
- }
7580
- else if (!(seed instanceof Uint8Array)) {
7581
- throw new TypeError('"seed" must be a node.js Buffer, or Uint8Array.');
7582
- }
7583
- // based on node forges algorithm, the seed is used directly as private key
7584
- const privateKeyRaw = seed;
7585
- const publicKey = ed25519.getPublicKey(privateKeyRaw);
7586
- const privateKey = concatKeys(privateKeyRaw, publicKey);
7587
- return {
7588
- privateKey,
7589
- publicKey
7590
- };
7591
- }
7592
- function hashAndSign$2(privateKey, msg) {
7593
- const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH);
7594
- return ed25519.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw);
7595
- }
7596
7652
  function hashAndVerify$2(publicKey, sig, msg) {
7597
7653
  return ed25519.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey);
7598
7654
  }
7599
- function concatKeys(privateKeyRaw, publicKey) {
7600
- const privateKey = new Uint8Array(PRIVATE_KEY_BYTE_LENGTH);
7601
- for (let i = 0; i < KEYS_BYTE_LENGTH; i++) {
7602
- privateKey[i] = privateKeyRaw[i];
7603
- privateKey[KEYS_BYTE_LENGTH + i] = publicKey[i];
7604
- }
7605
- return privateKey;
7606
- }
7607
7655
 
7608
- /* eslint-env browser */
7609
- // Check native crypto exists and is enabled (In insecure context `self.crypto`
7610
- // exists but `self.crypto.subtle` does not).
7611
- var webcrypto = {
7612
- get(win = globalThis) {
7613
- const nativeCrypto = win.crypto;
7614
- if (nativeCrypto?.subtle == null) {
7615
- throw Object.assign(new Error('Missing Web Crypto API. ' +
7616
- 'The most likely cause of this error is that this page is being accessed ' +
7617
- 'from an insecure context (i.e. not HTTPS). For more information and ' +
7618
- 'possible resolutions see ' +
7619
- 'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api'), { code: 'ERR_MISSING_WEB_CRYPTO' });
7620
- }
7621
- return nativeCrypto;
7656
+ class Ed25519PublicKey {
7657
+ type = 'Ed25519';
7658
+ raw;
7659
+ constructor(key) {
7660
+ this.raw = ensureEd25519Key(key, PUBLIC_KEY_BYTE_LENGTH);
7622
7661
  }
7623
- };
7624
-
7625
- // WebKit on Linux does not support deriving a key from an empty PBKDF2 key.
7626
- // So, as a workaround, we provide the generated key as a constant. We test that
7627
- // this generated key is accurate in test/workaround.spec.ts
7628
- // Generated via:
7629
- // await crypto.subtle.exportKey('jwk',
7630
- // await crypto.subtle.deriveKey(
7631
- // { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } },
7632
- // await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']),
7633
- // { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt'])
7634
- // )
7635
- const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
7636
- // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
7637
- function create(opts) {
7638
- const algorithm = 'AES-GCM';
7639
- let keyLength = 16;
7640
- const nonceLength = 12;
7641
- const digest = 'SHA-256';
7642
- const saltLength = 16;
7643
- const iterations = 32767;
7644
- const crypto = webcrypto.get();
7645
- keyLength *= 8; // Browser crypto uses bits instead of bytes
7646
- /**
7647
- * Uses the provided password to derive a pbkdf2 key. The key
7648
- * will then be used to encrypt the data.
7649
- */
7650
- async function encrypt(data, password) {
7651
- const salt = crypto.getRandomValues(new Uint8Array(saltLength));
7652
- const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
7653
- const aesGcm = { name: algorithm, iv: nonce };
7654
- if (typeof password === 'string') {
7655
- password = fromString(password);
7656
- }
7657
- let cryptoKey;
7658
- if (password.length === 0) {
7659
- cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
7660
- try {
7661
- const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
7662
- const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
7663
- cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['encrypt']);
7664
- }
7665
- catch {
7666
- cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
7667
- }
7668
- }
7669
- else {
7670
- // Derive a key using PBKDF2.
7671
- const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
7672
- const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
7673
- cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']);
7674
- }
7675
- // Encrypt the string.
7676
- const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data);
7677
- return concat$1([salt, aesGcm.iv, new Uint8Array(ciphertext)]);
7662
+ toMultihash() {
7663
+ return identity.digest(publicKeyToProtobuf(this));
7678
7664
  }
7679
- /**
7680
- * Uses the provided password to derive a pbkdf2 key. The key
7681
- * will then be used to decrypt the data. The options used to create
7682
- * this decryption cipher must be the same as those used to create
7683
- * the encryption cipher.
7684
- */
7685
- async function decrypt(data, password) {
7686
- const salt = data.subarray(0, saltLength);
7687
- const nonce = data.subarray(saltLength, saltLength + nonceLength);
7688
- const ciphertext = data.subarray(saltLength + nonceLength);
7689
- const aesGcm = { name: algorithm, iv: nonce };
7690
- if (typeof password === 'string') {
7691
- password = fromString(password);
7692
- }
7693
- let cryptoKey;
7694
- if (password.length === 0) {
7695
- try {
7696
- const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
7697
- const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
7698
- cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['decrypt']);
7699
- }
7700
- catch {
7701
- cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']);
7702
- }
7665
+ toCID() {
7666
+ return CID.createV1(114, this.toMultihash());
7667
+ }
7668
+ toString() {
7669
+ return base58btc.encode(this.toMultihash().bytes).substring(1);
7670
+ }
7671
+ equals(key) {
7672
+ if (key == null || !(key.raw instanceof Uint8Array)) {
7673
+ return false;
7703
7674
  }
7704
- else {
7705
- // Derive the key using PBKDF2.
7706
- const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
7707
- const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
7708
- cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['decrypt']);
7709
- }
7710
- // Decrypt the string.
7711
- const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext);
7712
- return new Uint8Array(plaintext);
7713
- }
7714
- const cipher = {
7715
- encrypt,
7716
- decrypt
7717
- };
7718
- return cipher;
7675
+ return equals(this.raw, key.raw);
7676
+ }
7677
+ verify(data, sig) {
7678
+ return hashAndVerify$2(this.raw, sig, data);
7679
+ }
7719
7680
  }
7720
7681
 
7721
- /**
7722
- * Exports the given PrivateKey as a base64 encoded string.
7723
- * The PrivateKey is encrypted via a password derived PBKDF2 key
7724
- * leveraging the aes-gcm cipher algorithm.
7725
- */
7726
- async function exporter(privateKey, password) {
7727
- const cipher = create();
7728
- const encryptedKey = await cipher.encrypt(privateKey, password);
7729
- return base64.encode(encryptedKey);
7682
+ function unmarshalEd25519PublicKey(bytes) {
7683
+ bytes = ensureEd25519Key(bytes, PUBLIC_KEY_BYTE_LENGTH);
7684
+ return new Ed25519PublicKey(bytes);
7685
+ }
7686
+ function ensureEd25519Key(key, length) {
7687
+ key = Uint8Array.from(key ?? []);
7688
+ if (key.length !== length) {
7689
+ throw new InvalidParametersError(`Key must be a Uint8Array of length ${length}, got ${key.length}`);
7690
+ }
7691
+ return key;
7730
7692
  }
7731
7693
 
7732
7694
  const f32 = new Float32Array([-0]);
@@ -8959,13 +8921,13 @@ var KeyType;
8959
8921
  (function (KeyType) {
8960
8922
  KeyType["RSA"] = "RSA";
8961
8923
  KeyType["Ed25519"] = "Ed25519";
8962
- KeyType["Secp256k1"] = "Secp256k1";
8924
+ KeyType["secp256k1"] = "secp256k1";
8963
8925
  })(KeyType || (KeyType = {}));
8964
8926
  var __KeyTypeValues;
8965
8927
  (function (__KeyTypeValues) {
8966
8928
  __KeyTypeValues[__KeyTypeValues["RSA"] = 0] = "RSA";
8967
8929
  __KeyTypeValues[__KeyTypeValues["Ed25519"] = 1] = "Ed25519";
8968
- __KeyTypeValues[__KeyTypeValues["Secp256k1"] = 2] = "Secp256k1";
8930
+ __KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1";
8969
8931
  })(__KeyTypeValues || (__KeyTypeValues = {}));
8970
8932
  (function (KeyType) {
8971
8933
  KeyType.codec = () => {
@@ -8992,21 +8954,24 @@ var PublicKey;
8992
8954
  if (opts.lengthDelimited !== false) {
8993
8955
  w.ldelim();
8994
8956
  }
8995
- }, (reader, length) => {
8957
+ }, (reader, length, opts = {}) => {
8996
8958
  const obj = {};
8997
8959
  const end = length == null ? reader.len : reader.pos + length;
8998
8960
  while (reader.pos < end) {
8999
8961
  const tag = reader.uint32();
9000
8962
  switch (tag >>> 3) {
9001
- case 1:
8963
+ case 1: {
9002
8964
  obj.Type = KeyType.codec().decode(reader);
9003
8965
  break;
9004
- case 2:
8966
+ }
8967
+ case 2: {
9005
8968
  obj.Data = reader.bytes();
9006
8969
  break;
9007
- default:
8970
+ }
8971
+ default: {
9008
8972
  reader.skipType(tag & 7);
9009
8973
  break;
8974
+ }
9010
8975
  }
9011
8976
  }
9012
8977
  return obj;
@@ -9017,8 +8982,8 @@ var PublicKey;
9017
8982
  PublicKey.encode = (obj) => {
9018
8983
  return encodeMessage(obj, PublicKey.codec());
9019
8984
  };
9020
- PublicKey.decode = (buf) => {
9021
- return decodeMessage(buf, PublicKey.codec());
8985
+ PublicKey.decode = (buf, opts) => {
8986
+ return decodeMessage(buf, PublicKey.codec(), opts);
9022
8987
  };
9023
8988
  })(PublicKey || (PublicKey = {}));
9024
8989
  var PrivateKey;
@@ -9041,21 +9006,24 @@ var PrivateKey;
9041
9006
  if (opts.lengthDelimited !== false) {
9042
9007
  w.ldelim();
9043
9008
  }
9044
- }, (reader, length) => {
9009
+ }, (reader, length, opts = {}) => {
9045
9010
  const obj = {};
9046
9011
  const end = length == null ? reader.len : reader.pos + length;
9047
9012
  while (reader.pos < end) {
9048
9013
  const tag = reader.uint32();
9049
9014
  switch (tag >>> 3) {
9050
- case 1:
9015
+ case 1: {
9051
9016
  obj.Type = KeyType.codec().decode(reader);
9052
9017
  break;
9053
- case 2:
9018
+ }
9019
+ case 2: {
9054
9020
  obj.Data = reader.bytes();
9055
9021
  break;
9056
- default:
9022
+ }
9023
+ default: {
9057
9024
  reader.skipType(tag & 7);
9058
9025
  break;
9026
+ }
9059
9027
  }
9060
9028
  }
9061
9029
  return obj;
@@ -9066,377 +9034,106 @@ var PrivateKey;
9066
9034
  PrivateKey.encode = (obj) => {
9067
9035
  return encodeMessage(obj, PrivateKey.codec());
9068
9036
  };
9069
- PrivateKey.decode = (buf) => {
9070
- return decodeMessage(buf, PrivateKey.codec());
9037
+ PrivateKey.decode = (buf, opts) => {
9038
+ return decodeMessage(buf, PrivateKey.codec(), opts);
9071
9039
  };
9072
9040
  })(PrivateKey || (PrivateKey = {}));
9073
9041
 
9074
- class Ed25519PublicKey {
9075
- _key;
9076
- constructor(key) {
9077
- this._key = ensureKey(key, PUBLIC_KEY_BYTE_LENGTH);
9078
- }
9079
- verify(data, sig) {
9080
- return hashAndVerify$2(this._key, sig, data);
9081
- }
9082
- marshal() {
9083
- return this._key;
9084
- }
9085
- get bytes() {
9086
- return PublicKey.encode({
9087
- Type: KeyType.Ed25519,
9088
- Data: this.marshal()
9089
- }).subarray();
9090
- }
9091
- equals(key) {
9092
- return equals(this.bytes, key.bytes);
9042
+ /*!
9043
+ * MIT License
9044
+ *
9045
+ * Copyright (c) 2017-2022 Peculiar Ventures, LLC
9046
+ *
9047
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9048
+ * of this software and associated documentation files (the "Software"), to deal
9049
+ * in the Software without restriction, including without limitation the rights
9050
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9051
+ * copies of the Software, and to permit persons to whom the Software is
9052
+ * furnished to do so, subject to the following conditions:
9053
+ *
9054
+ * The above copyright notice and this permission notice shall be included in all
9055
+ * copies or substantial portions of the Software.
9056
+ *
9057
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9058
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9059
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9060
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9061
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9062
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
9063
+ * SOFTWARE.
9064
+ *
9065
+ */
9066
+
9067
+ const ARRAY_BUFFER_NAME = "[object ArrayBuffer]";
9068
+ class BufferSourceConverter {
9069
+ static isArrayBuffer(data) {
9070
+ return Object.prototype.toString.call(data) === ARRAY_BUFFER_NAME;
9093
9071
  }
9094
- hash() {
9095
- const p = sha256.digest(this.bytes);
9096
- if (isPromise$1(p)) {
9097
- return p.then(({ bytes }) => bytes);
9072
+ static toArrayBuffer(data) {
9073
+ if (this.isArrayBuffer(data)) {
9074
+ return data;
9098
9075
  }
9099
- return p.bytes;
9100
- }
9101
- }
9102
- class Ed25519PrivateKey {
9103
- _key;
9104
- _publicKey;
9105
- // key - 64 byte Uint8Array containing private key
9106
- // publicKey - 32 byte Uint8Array containing public key
9107
- constructor(key, publicKey) {
9108
- this._key = ensureKey(key, PRIVATE_KEY_BYTE_LENGTH);
9109
- this._publicKey = ensureKey(publicKey, PUBLIC_KEY_BYTE_LENGTH);
9110
- }
9111
- sign(message) {
9112
- return hashAndSign$2(this._key, message);
9076
+ if (data.byteLength === data.buffer.byteLength) {
9077
+ return data.buffer;
9078
+ }
9079
+ if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
9080
+ return data.buffer;
9081
+ }
9082
+ return this.toUint8Array(data.buffer)
9083
+ .slice(data.byteOffset, data.byteOffset + data.byteLength)
9084
+ .buffer;
9113
9085
  }
9114
- get public() {
9115
- return new Ed25519PublicKey(this._publicKey);
9086
+ static toUint8Array(data) {
9087
+ return this.toView(data, Uint8Array);
9116
9088
  }
9117
- marshal() {
9118
- return this._key;
9089
+ static toView(data, type) {
9090
+ if (data.constructor === type) {
9091
+ return data;
9092
+ }
9093
+ if (this.isArrayBuffer(data)) {
9094
+ return new type(data);
9095
+ }
9096
+ if (this.isArrayBufferView(data)) {
9097
+ return new type(data.buffer, data.byteOffset, data.byteLength);
9098
+ }
9099
+ throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
9119
9100
  }
9120
- get bytes() {
9121
- return PrivateKey.encode({
9122
- Type: KeyType.Ed25519,
9123
- Data: this.marshal()
9124
- }).subarray();
9101
+ static isBufferSource(data) {
9102
+ return this.isArrayBufferView(data)
9103
+ || this.isArrayBuffer(data);
9125
9104
  }
9126
- equals(key) {
9127
- return equals(this.bytes, key.bytes);
9105
+ static isArrayBufferView(data) {
9106
+ return ArrayBuffer.isView(data)
9107
+ || (data && this.isArrayBuffer(data.buffer));
9128
9108
  }
9129
- async hash() {
9130
- const p = sha256.digest(this.bytes);
9131
- let bytes;
9132
- if (isPromise$1(p)) {
9133
- ({ bytes } = await p);
9109
+ static isEqual(a, b) {
9110
+ const aView = BufferSourceConverter.toUint8Array(a);
9111
+ const bView = BufferSourceConverter.toUint8Array(b);
9112
+ if (aView.length !== bView.byteLength) {
9113
+ return false;
9134
9114
  }
9135
- else {
9136
- bytes = p.bytes;
9115
+ for (let i = 0; i < aView.length; i++) {
9116
+ if (aView[i] !== bView[i]) {
9117
+ return false;
9118
+ }
9137
9119
  }
9138
- return bytes;
9139
- }
9140
- /**
9141
- * Gets the ID of the key.
9142
- *
9143
- * The key id is the base58 encoding of the identity multihash containing its public key.
9144
- * The public key is a protobuf encoding containing a type and the DER encoding
9145
- * of the PKCS SubjectPublicKeyInfo.
9146
- *
9147
- * @returns {Promise<string>}
9148
- */
9149
- async id() {
9150
- const encoding = identity.digest(this.public.bytes);
9151
- return base58btc.encode(encoding.bytes).substring(1);
9120
+ return true;
9152
9121
  }
9153
- /**
9154
- * Exports the key into a password protected `format`
9155
- */
9156
- async export(password, format = 'libp2p-key') {
9157
- if (format === 'libp2p-key') {
9158
- return exporter(this.bytes, password);
9122
+ static concat(...args) {
9123
+ let buffers;
9124
+ if (Array.isArray(args[0]) && !(args[1] instanceof Function)) {
9125
+ buffers = args[0];
9126
+ }
9127
+ else if (Array.isArray(args[0]) && args[1] instanceof Function) {
9128
+ buffers = args[0];
9159
9129
  }
9160
9130
  else {
9161
- throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
9162
- }
9163
- }
9164
- }
9165
- function unmarshalEd25519PrivateKey(bytes) {
9166
- // Try the old, redundant public key version
9167
- if (bytes.length > PRIVATE_KEY_BYTE_LENGTH) {
9168
- bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH + PUBLIC_KEY_BYTE_LENGTH);
9169
- const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
9170
- const publicKeyBytes = bytes.subarray(PRIVATE_KEY_BYTE_LENGTH, bytes.length);
9171
- return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
9172
- }
9173
- bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH);
9174
- const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
9175
- const publicKeyBytes = bytes.subarray(PUBLIC_KEY_BYTE_LENGTH);
9176
- return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
9177
- }
9178
- function unmarshalEd25519PublicKey(bytes) {
9179
- bytes = ensureKey(bytes, PUBLIC_KEY_BYTE_LENGTH);
9180
- return new Ed25519PublicKey(bytes);
9181
- }
9182
- async function generateKeyPair$2() {
9183
- const { privateKey, publicKey } = generateKey$2();
9184
- return new Ed25519PrivateKey(privateKey, publicKey);
9185
- }
9186
- async function generateKeyPairFromSeed(seed) {
9187
- const { privateKey, publicKey } = generateKeyFromSeed(seed);
9188
- return new Ed25519PrivateKey(privateKey, publicKey);
9189
- }
9190
- function ensureKey(key, length) {
9191
- key = Uint8Array.from(key ?? []);
9192
- if (key.length !== length) {
9193
- throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
9194
- }
9195
- return key;
9196
- }
9197
-
9198
- var Ed25519 = /*#__PURE__*/Object.freeze({
9199
- __proto__: null,
9200
- Ed25519PrivateKey: Ed25519PrivateKey,
9201
- Ed25519PublicKey: Ed25519PublicKey,
9202
- generateKeyPair: generateKeyPair$2,
9203
- generateKeyPairFromSeed: generateKeyPairFromSeed,
9204
- unmarshalEd25519PrivateKey: unmarshalEd25519PrivateKey,
9205
- unmarshalEd25519PublicKey: unmarshalEd25519PublicKey
9206
- });
9207
-
9208
- /**
9209
- * Generates a Uint8Array with length `number` populated by random bytes
9210
- */
9211
- function randomBytes(length) {
9212
- if (isNaN(length) || length <= 0) {
9213
- throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
9214
- }
9215
- return randomBytes$1(length);
9216
- }
9217
-
9218
- // HMAC (RFC 2104)
9219
- class HMAC extends Hash {
9220
- constructor(hash$1, _key) {
9221
- super();
9222
- this.finished = false;
9223
- this.destroyed = false;
9224
- hash(hash$1);
9225
- const key = toBytes$1(_key);
9226
- this.iHash = hash$1.create();
9227
- if (typeof this.iHash.update !== 'function')
9228
- throw new Error('Expected instance of class which extends utils.Hash');
9229
- this.blockLen = this.iHash.blockLen;
9230
- this.outputLen = this.iHash.outputLen;
9231
- const blockLen = this.blockLen;
9232
- const pad = new Uint8Array(blockLen);
9233
- // blockLen can be bigger than outputLen
9234
- pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
9235
- for (let i = 0; i < pad.length; i++)
9236
- pad[i] ^= 0x36;
9237
- this.iHash.update(pad);
9238
- // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
9239
- this.oHash = hash$1.create();
9240
- // Undo internal XOR && apply outer XOR
9241
- for (let i = 0; i < pad.length; i++)
9242
- pad[i] ^= 0x36 ^ 0x5c;
9243
- this.oHash.update(pad);
9244
- pad.fill(0);
9245
- }
9246
- update(buf) {
9247
- exists(this);
9248
- this.iHash.update(buf);
9249
- return this;
9250
- }
9251
- digestInto(out) {
9252
- exists(this);
9253
- bytes(out, this.outputLen);
9254
- this.finished = true;
9255
- this.iHash.digestInto(out);
9256
- this.oHash.update(out);
9257
- this.oHash.digestInto(out);
9258
- this.destroy();
9259
- }
9260
- digest() {
9261
- const out = new Uint8Array(this.oHash.outputLen);
9262
- this.digestInto(out);
9263
- return out;
9264
- }
9265
- _cloneInto(to) {
9266
- // Create new instance without calling constructor since key already in state and we don't know it.
9267
- to || (to = Object.create(Object.getPrototypeOf(this), {}));
9268
- const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
9269
- to = to;
9270
- to.finished = finished;
9271
- to.destroyed = destroyed;
9272
- to.blockLen = blockLen;
9273
- to.outputLen = outputLen;
9274
- to.oHash = oHash._cloneInto(to.oHash);
9275
- to.iHash = iHash._cloneInto(to.iHash);
9276
- return to;
9277
- }
9278
- destroy() {
9279
- this.destroyed = true;
9280
- this.oHash.destroy();
9281
- this.iHash.destroy();
9282
- }
9283
- }
9284
- /**
9285
- * HMAC: RFC2104 message authentication code.
9286
- * @param hash - function that would be used e.g. sha256
9287
- * @param key - message key
9288
- * @param message - message data
9289
- */
9290
- const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
9291
- hmac.create = (hash, key) => new HMAC(hash, key);
9292
-
9293
- // Common prologue and epilogue for sync/async functions
9294
- function pbkdf2Init(hash$1, _password, _salt, _opts) {
9295
- hash(hash$1);
9296
- const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
9297
- const { c, dkLen, asyncTick } = opts;
9298
- number(c);
9299
- number(dkLen);
9300
- number(asyncTick);
9301
- if (c < 1)
9302
- throw new Error('PBKDF2: iterations (c) should be >= 1');
9303
- const password = toBytes$1(_password);
9304
- const salt = toBytes$1(_salt);
9305
- // DK = PBKDF2(PRF, Password, Salt, c, dkLen);
9306
- const DK = new Uint8Array(dkLen);
9307
- // U1 = PRF(Password, Salt + INT_32_BE(i))
9308
- const PRF = hmac.create(hash$1, password);
9309
- const PRFSalt = PRF._cloneInto().update(salt);
9310
- return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
9311
- }
9312
- function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
9313
- PRF.destroy();
9314
- PRFSalt.destroy();
9315
- if (prfW)
9316
- prfW.destroy();
9317
- u.fill(0);
9318
- return DK;
9319
- }
9320
- async function pbkdf2Async(hash, password, salt, opts) {
9321
- const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
9322
- let prfW; // Working copy
9323
- const arr = new Uint8Array(4);
9324
- const view = createView(arr);
9325
- const u = new Uint8Array(PRF.outputLen);
9326
- // DK = T1 + T2 + ⋯ + Tdklen/hlen
9327
- for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
9328
- // Ti = F(Password, Salt, c, i)
9329
- const Ti = DK.subarray(pos, pos + PRF.outputLen);
9330
- view.setInt32(0, ti, false);
9331
- // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
9332
- // U1 = PRF(Password, Salt + INT_32_BE(i))
9333
- (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
9334
- Ti.set(u.subarray(0, Ti.length));
9335
- await asyncLoop(c - 1, asyncTick, () => {
9336
- // Uc = PRF(Password, Uc−1)
9337
- PRF._cloneInto(prfW).update(u).digestInto(u);
9338
- for (let i = 0; i < Ti.length; i++)
9339
- Ti[i] ^= u[i];
9340
- });
9341
- }
9342
- return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
9343
- }
9344
-
9345
- /*!
9346
- * MIT License
9347
- *
9348
- * Copyright (c) 2017-2022 Peculiar Ventures, LLC
9349
- *
9350
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9351
- * of this software and associated documentation files (the "Software"), to deal
9352
- * in the Software without restriction, including without limitation the rights
9353
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9354
- * copies of the Software, and to permit persons to whom the Software is
9355
- * furnished to do so, subject to the following conditions:
9356
- *
9357
- * The above copyright notice and this permission notice shall be included in all
9358
- * copies or substantial portions of the Software.
9359
- *
9360
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9361
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9362
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9363
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9364
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9365
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
9366
- * SOFTWARE.
9367
- *
9368
- */
9369
-
9370
- const ARRAY_BUFFER_NAME = "[object ArrayBuffer]";
9371
- class BufferSourceConverter {
9372
- static isArrayBuffer(data) {
9373
- return Object.prototype.toString.call(data) === ARRAY_BUFFER_NAME;
9374
- }
9375
- static toArrayBuffer(data) {
9376
- if (this.isArrayBuffer(data)) {
9377
- return data;
9378
- }
9379
- if (data.byteLength === data.buffer.byteLength) {
9380
- return data.buffer;
9381
- }
9382
- if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
9383
- return data.buffer;
9384
- }
9385
- return this.toUint8Array(data.buffer)
9386
- .slice(data.byteOffset, data.byteOffset + data.byteLength)
9387
- .buffer;
9388
- }
9389
- static toUint8Array(data) {
9390
- return this.toView(data, Uint8Array);
9391
- }
9392
- static toView(data, type) {
9393
- if (data.constructor === type) {
9394
- return data;
9395
- }
9396
- if (this.isArrayBuffer(data)) {
9397
- return new type(data);
9398
- }
9399
- if (this.isArrayBufferView(data)) {
9400
- return new type(data.buffer, data.byteOffset, data.byteLength);
9401
- }
9402
- throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
9403
- }
9404
- static isBufferSource(data) {
9405
- return this.isArrayBufferView(data)
9406
- || this.isArrayBuffer(data);
9407
- }
9408
- static isArrayBufferView(data) {
9409
- return ArrayBuffer.isView(data)
9410
- || (data && this.isArrayBuffer(data.buffer));
9411
- }
9412
- static isEqual(a, b) {
9413
- const aView = BufferSourceConverter.toUint8Array(a);
9414
- const bView = BufferSourceConverter.toUint8Array(b);
9415
- if (aView.length !== bView.byteLength) {
9416
- return false;
9417
- }
9418
- for (let i = 0; i < aView.length; i++) {
9419
- if (aView[i] !== bView[i]) {
9420
- return false;
9421
- }
9422
- }
9423
- return true;
9424
- }
9425
- static concat(...args) {
9426
- let buffers;
9427
- if (Array.isArray(args[0]) && !(args[1] instanceof Function)) {
9428
- buffers = args[0];
9429
- }
9430
- else if (Array.isArray(args[0]) && args[1] instanceof Function) {
9431
- buffers = args[0];
9432
- }
9433
- else {
9434
- if (args[args.length - 1] instanceof Function) {
9435
- buffers = args.slice(0, args.length - 1);
9436
- }
9437
- else {
9438
- buffers = args;
9439
- }
9131
+ if (args[args.length - 1] instanceof Function) {
9132
+ buffers = args.slice(0, args.length - 1);
9133
+ }
9134
+ else {
9135
+ buffers = args;
9136
+ }
9440
9137
  }
9441
9138
  let size = 0;
9442
9139
  for (const buffer of buffers) {
@@ -12593,272 +12290,44 @@ _a = TIME;
12593
12290
  TIME.NAME = "TIME";
12594
12291
 
12595
12292
  /**
12596
- * Convert a PKCS#1 in ASN1 DER format to a JWK key
12293
+ * Signing a message failed
12597
12294
  */
12598
- function pkcs1ToJwk(bytes) {
12599
- const { result } = fromBER(bytes);
12600
- // @ts-expect-error this looks fragile but DER is a canonical format so we are
12601
- // safe to have deeply property chains like this
12602
- const values = result.valueBlock.value;
12603
- const key = {
12604
- n: toString$6(bnToBuf(values[1].toBigInt()), 'base64url'),
12605
- e: toString$6(bnToBuf(values[2].toBigInt()), 'base64url'),
12606
- d: toString$6(bnToBuf(values[3].toBigInt()), 'base64url'),
12607
- p: toString$6(bnToBuf(values[4].toBigInt()), 'base64url'),
12608
- q: toString$6(bnToBuf(values[5].toBigInt()), 'base64url'),
12609
- dp: toString$6(bnToBuf(values[6].toBigInt()), 'base64url'),
12610
- dq: toString$6(bnToBuf(values[7].toBigInt()), 'base64url'),
12611
- qi: toString$6(bnToBuf(values[8].toBigInt()), 'base64url'),
12612
- kty: 'RSA',
12613
- alg: 'RS256'
12614
- };
12615
- return key;
12616
- }
12617
12295
  /**
12618
- * Convert a JWK key into PKCS#1 in ASN1 DER format
12296
+ * Verifying a message signature failed
12619
12297
  */
12620
- function jwkToPkcs1(jwk) {
12621
- 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) {
12622
- throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12298
+ class VerificationError extends Error {
12299
+ constructor(message = 'An error occurred while verifying a message') {
12300
+ super(message);
12301
+ this.name = 'VerificationError';
12623
12302
  }
12624
- const root = new Sequence({
12625
- value: [
12626
- new Integer({ value: 0 }),
12627
- Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
12628
- Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url'))),
12629
- Integer.fromBigInt(bufToBn(fromString(jwk.d, 'base64url'))),
12630
- Integer.fromBigInt(bufToBn(fromString(jwk.p, 'base64url'))),
12631
- Integer.fromBigInt(bufToBn(fromString(jwk.q, 'base64url'))),
12632
- Integer.fromBigInt(bufToBn(fromString(jwk.dp, 'base64url'))),
12633
- Integer.fromBigInt(bufToBn(fromString(jwk.dq, 'base64url'))),
12634
- Integer.fromBigInt(bufToBn(fromString(jwk.qi, 'base64url')))
12635
- ]
12636
- });
12637
- const der = root.toBER();
12638
- return new Uint8Array(der, 0, der.byteLength);
12639
- }
12640
- /**
12641
- * Convert a PKCIX in ASN1 DER format to a JWK key
12642
- */
12643
- function pkixToJwk(bytes) {
12644
- const { result } = fromBER(bytes);
12645
- // @ts-expect-error this looks fragile but DER is a canonical format so we are
12646
- // safe to have deeply property chains like this
12647
- const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
12648
- return {
12649
- kty: 'RSA',
12650
- n: toString$6(bnToBuf(values[0].toBigInt()), 'base64url'),
12651
- e: toString$6(bnToBuf(values[1].toBigInt()), 'base64url')
12652
- };
12653
12303
  }
12654
12304
  /**
12655
- * Convert a JWK key to PKCIX in ASN1 DER format
12305
+ * WebCrypto was not available in the current context
12656
12306
  */
12657
- function jwkToPkix(jwk) {
12658
- if (jwk.n == null || jwk.e == null) {
12659
- throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12307
+ class WebCryptoMissingError extends Error {
12308
+ constructor(message = 'Missing Web Crypto API') {
12309
+ super(message);
12310
+ this.name = 'WebCryptoMissingError';
12660
12311
  }
12661
- const root = new Sequence({
12662
- value: [
12663
- new Sequence({
12664
- value: [
12665
- // rsaEncryption
12666
- new ObjectIdentifier({
12667
- value: '1.2.840.113549.1.1.1'
12668
- }),
12669
- new Null()
12670
- ]
12671
- }),
12672
- // this appears to be a bug in asn1js.js - this should really be a Sequence
12673
- // and not a BitString but it generates the same bytes as node-forge so 🤷‍♂️
12674
- new BitString({
12675
- valueHex: new Sequence({
12676
- value: [
12677
- Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
12678
- Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url')))
12679
- ]
12680
- }).toBER()
12681
- })
12682
- ]
12683
- });
12684
- const der = root.toBER();
12685
- return new Uint8Array(der, 0, der.byteLength);
12686
12312
  }
12687
- function bnToBuf(bn) {
12688
- let hex = bn.toString(16);
12689
- if (hex.length % 2 > 0) {
12690
- hex = `0${hex}`;
12313
+
12314
+ /* eslint-env browser */
12315
+ // Check native crypto exists and is enabled (In insecure context `self.crypto`
12316
+ // exists but `self.crypto.subtle` does not).
12317
+ var webcrypto = {
12318
+ get(win = globalThis) {
12319
+ const nativeCrypto = win.crypto;
12320
+ if (nativeCrypto?.subtle == null) {
12321
+ throw new WebCryptoMissingError('Missing Web Crypto API. ' +
12322
+ 'The most likely cause of this error is that this page is being accessed ' +
12323
+ 'from an insecure context (i.e. not HTTPS). For more information and ' +
12324
+ 'possible resolutions see ' +
12325
+ 'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api');
12326
+ }
12327
+ return nativeCrypto;
12691
12328
  }
12692
- const len = hex.length / 2;
12693
- const u8 = new Uint8Array(len);
12694
- let i = 0;
12695
- let j = 0;
12696
- while (i < len) {
12697
- u8[i] = parseInt(hex.slice(j, j + 2), 16);
12698
- i += 1;
12699
- j += 2;
12700
- }
12701
- return u8;
12702
- }
12703
- function bufToBn(u8) {
12704
- const hex = [];
12705
- u8.forEach(function (i) {
12706
- let h = i.toString(16);
12707
- if (h.length % 2 > 0) {
12708
- h = `0${h}`;
12709
- }
12710
- hex.push(h);
12711
- });
12712
- return BigInt('0x' + hex.join(''));
12713
- }
12714
- const SALT_LENGTH = 16;
12715
- const KEY_SIZE = 32;
12716
- const ITERATIONS = 10000;
12717
- async function exportToPem(privateKey, password) {
12718
- const crypto = webcrypto.get();
12719
- // PrivateKeyInfo
12720
- const keyWrapper = new Sequence({
12721
- value: [
12722
- // version (0)
12723
- new Integer({ value: 0 }),
12724
- // privateKeyAlgorithm
12725
- new Sequence({
12726
- value: [
12727
- // rsaEncryption OID
12728
- new ObjectIdentifier({
12729
- value: '1.2.840.113549.1.1.1'
12730
- }),
12731
- new Null()
12732
- ]
12733
- }),
12734
- // PrivateKey
12735
- new OctetString({
12736
- valueHex: privateKey.marshal()
12737
- })
12738
- ]
12739
- });
12740
- const keyBuf = keyWrapper.toBER();
12741
- const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
12742
- const salt = randomBytes(SALT_LENGTH);
12743
- const encryptionKey = await pbkdf2Async(sha512, password, salt, {
12744
- c: ITERATIONS,
12745
- dkLen: KEY_SIZE
12746
- });
12747
- const iv = randomBytes(16);
12748
- const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['encrypt']);
12749
- const encrypted = await crypto.subtle.encrypt({
12750
- name: 'AES-CBC',
12751
- iv
12752
- }, cryptoKey, keyArr);
12753
- const pbkdf2Params = new Sequence({
12754
- value: [
12755
- // salt
12756
- new OctetString({ valueHex: salt }),
12757
- // iteration count
12758
- new Integer({ value: ITERATIONS }),
12759
- // key length
12760
- new Integer({ value: KEY_SIZE }),
12761
- // AlgorithmIdentifier
12762
- new Sequence({
12763
- value: [
12764
- // hmacWithSHA512
12765
- new ObjectIdentifier({ value: '1.2.840.113549.2.11' }),
12766
- new Null()
12767
- ]
12768
- })
12769
- ]
12770
- });
12771
- const encryptionAlgorithm = new Sequence({
12772
- value: [
12773
- // pkcs5PBES2
12774
- new ObjectIdentifier({
12775
- value: '1.2.840.113549.1.5.13'
12776
- }),
12777
- new Sequence({
12778
- value: [
12779
- // keyDerivationFunc
12780
- new Sequence({
12781
- value: [
12782
- // pkcs5PBKDF2
12783
- new ObjectIdentifier({
12784
- value: '1.2.840.113549.1.5.12'
12785
- }),
12786
- // PBKDF2-params
12787
- pbkdf2Params
12788
- ]
12789
- }),
12790
- // encryptionScheme
12791
- new Sequence({
12792
- value: [
12793
- // aes256-CBC
12794
- new ObjectIdentifier({
12795
- value: '2.16.840.1.101.3.4.1.42'
12796
- }),
12797
- // iv
12798
- new OctetString({
12799
- valueHex: iv
12800
- })
12801
- ]
12802
- })
12803
- ]
12804
- })
12805
- ]
12806
- });
12807
- const finalWrapper = new Sequence({
12808
- value: [
12809
- encryptionAlgorithm,
12810
- new OctetString({ valueHex: encrypted })
12811
- ]
12812
- });
12813
- const finalWrapperBuf = finalWrapper.toBER();
12814
- const finalWrapperArr = new Uint8Array(finalWrapperBuf, 0, finalWrapperBuf.byteLength);
12815
- return [
12816
- '-----BEGIN ENCRYPTED PRIVATE KEY-----',
12817
- ...toString$6(finalWrapperArr, 'base64pad').split(/(.{64})/).filter(Boolean),
12818
- '-----END ENCRYPTED PRIVATE KEY-----'
12819
- ].join('\n');
12820
- }
12329
+ };
12821
12330
 
12822
- async function generateKey$1(bits) {
12823
- const pair = await webcrypto.get().subtle.generateKey({
12824
- name: 'RSASSA-PKCS1-v1_5',
12825
- modulusLength: bits,
12826
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
12827
- hash: { name: 'SHA-256' }
12828
- }, true, ['sign', 'verify']);
12829
- const keys = await exportKey(pair);
12830
- return {
12831
- privateKey: keys[0],
12832
- publicKey: keys[1]
12833
- };
12834
- }
12835
- // Takes a jwk key
12836
- async function unmarshalPrivateKey$1(key) {
12837
- const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
12838
- name: 'RSASSA-PKCS1-v1_5',
12839
- hash: { name: 'SHA-256' }
12840
- }, true, ['sign']);
12841
- const pair = [
12842
- privateKey,
12843
- await derivePublicFromPrivate(key)
12844
- ];
12845
- const keys = await exportKey({
12846
- privateKey: pair[0],
12847
- publicKey: pair[1]
12848
- });
12849
- return {
12850
- privateKey: keys[0],
12851
- publicKey: keys[1]
12852
- };
12853
- }
12854
- async function hashAndSign$1(key, msg) {
12855
- const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
12856
- name: 'RSASSA-PKCS1-v1_5',
12857
- hash: { name: 'SHA-256' }
12858
- }, false, ['sign']);
12859
- const sig = await webcrypto.get().subtle.sign({ name: 'RSASSA-PKCS1-v1_5' }, privateKey, msg instanceof Uint8Array ? msg : msg.subarray());
12860
- return new Uint8Array(sig, 0, sig.byteLength);
12861
- }
12862
12331
  async function hashAndVerify$1(key, sig, msg) {
12863
12332
  const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
12864
12333
  name: 'RSASSA-PKCS1-v1_5',
@@ -12866,173 +12335,214 @@ async function hashAndVerify$1(key, sig, msg) {
12866
12335
  }, false, ['verify']);
12867
12336
  return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
12868
12337
  }
12869
- async function exportKey(pair) {
12870
- if (pair.privateKey == null || pair.publicKey == null) {
12871
- throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
12872
- }
12873
- return Promise.all([
12874
- webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
12875
- webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
12876
- ]);
12877
- }
12878
- async function derivePublicFromPrivate(jwKey) {
12879
- return webcrypto.get().subtle.importKey('jwk', {
12880
- kty: jwKey.kty,
12881
- n: jwKey.n,
12882
- e: jwKey.e
12883
- }, {
12884
- name: 'RSASSA-PKCS1-v1_5',
12885
- hash: { name: 'SHA-256' }
12886
- }, true, ['verify']);
12887
- }
12888
- function keySize(jwk) {
12338
+ function rsaKeySize(jwk) {
12889
12339
  if (jwk.kty !== 'RSA') {
12890
- throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
12340
+ throw new InvalidParametersError('invalid key type');
12891
12341
  }
12892
12342
  else if (jwk.n == null) {
12893
- throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
12343
+ throw new InvalidParametersError('invalid key modulus');
12894
12344
  }
12895
12345
  const bytes = fromString(jwk.n, 'base64url');
12896
12346
  return bytes.length * 8;
12897
12347
  }
12898
12348
 
12899
- const MAX_RSA_KEY_SIZE = 8192;
12900
- class RsaPublicKey {
12349
+ class RSAPublicKey {
12350
+ type = 'RSA';
12901
12351
  _key;
12902
- constructor(key) {
12352
+ _raw;
12353
+ _multihash;
12354
+ constructor(key, digest) {
12903
12355
  this._key = key;
12356
+ this._multihash = digest;
12904
12357
  }
12905
- verify(data, sig) {
12906
- return hashAndVerify$1(this._key, sig, data);
12907
- }
12908
- marshal() {
12909
- return jwkToPkix(this._key);
12910
- }
12911
- get bytes() {
12912
- return PublicKey.encode({
12913
- Type: KeyType.RSA,
12914
- Data: this.marshal()
12915
- }).subarray();
12916
- }
12917
- equals(key) {
12918
- return equals(this.bytes, key.bytes);
12919
- }
12920
- hash() {
12921
- const p = sha256.digest(this.bytes);
12922
- if (isPromise$1(p)) {
12923
- return p.then(({ bytes }) => bytes);
12358
+ get raw() {
12359
+ if (this._raw == null) {
12360
+ this._raw = jwkToPkix(this._key);
12924
12361
  }
12925
- return p.bytes;
12926
- }
12927
- }
12928
- class RsaPrivateKey {
12929
- _key;
12930
- _publicKey;
12931
- constructor(key, publicKey) {
12932
- this._key = key;
12933
- this._publicKey = publicKey;
12934
- }
12935
- genSecret() {
12936
- return randomBytes(16);
12362
+ return this._raw;
12937
12363
  }
12938
- sign(message) {
12939
- return hashAndSign$1(this._key, message);
12364
+ toMultihash() {
12365
+ return this._multihash;
12940
12366
  }
12941
- get public() {
12942
- if (this._publicKey == null) {
12943
- throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
12944
- }
12945
- return new RsaPublicKey(this._publicKey);
12946
- }
12947
- marshal() {
12948
- return jwkToPkcs1(this._key);
12367
+ toCID() {
12368
+ return CID.createV1(114, this._multihash);
12949
12369
  }
12950
- get bytes() {
12951
- return PrivateKey.encode({
12952
- Type: KeyType.RSA,
12953
- Data: this.marshal()
12954
- }).subarray();
12370
+ toString() {
12371
+ return base58btc.encode(this.toMultihash().bytes).substring(1);
12955
12372
  }
12956
12373
  equals(key) {
12957
- return equals(this.bytes, key.bytes);
12958
- }
12959
- hash() {
12960
- const p = sha256.digest(this.bytes);
12961
- if (isPromise$1(p)) {
12962
- return p.then(({ bytes }) => bytes);
12374
+ if (key == null || !(key.raw instanceof Uint8Array)) {
12375
+ return false;
12963
12376
  }
12964
- return p.bytes;
12377
+ return equals(this.raw, key.raw);
12965
12378
  }
12966
- /**
12967
- * Gets the ID of the key.
12968
- *
12969
- * The key id is the base58 encoding of the SHA-256 multihash of its public key.
12970
- * The public key is a protobuf encoding containing a type and the DER encoding
12971
- * of the PKCS SubjectPublicKeyInfo.
12972
- */
12973
- async id() {
12974
- const hash = await this.public.hash();
12975
- return toString$6(hash, 'base58btc');
12379
+ verify(data, sig) {
12380
+ return hashAndVerify$1(this._key, sig, data);
12976
12381
  }
12977
- /**
12978
- * Exports the key as libp2p-key - a aes-gcm encrypted value with the key
12979
- * derived from the password.
12980
- *
12981
- * To export it as a password protected PEM file, please use the `exportPEM`
12982
- * function from `@libp2p/rsa`.
12983
- */
12984
- async export(password, format = 'pkcs-8') {
12985
- if (format === 'pkcs-8') {
12986
- return exportToPem(this, password);
12987
- }
12988
- else if (format === 'libp2p-key') {
12989
- return exporter(this.bytes, password);
12990
- }
12991
- else {
12992
- throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
12993
- }
12382
+ }
12383
+
12384
+ const MAX_RSA_KEY_SIZE = 8192;
12385
+ const SHA2_256_CODE = 0x12;
12386
+ /**
12387
+ * Convert a PKIX in ASN1 DER format to a JWK key
12388
+ */
12389
+ function pkixToJwk(bytes) {
12390
+ const { result } = fromBER(bytes);
12391
+ // @ts-expect-error this looks fragile but DER is a canonical format so we are
12392
+ // safe to have deeply property chains like this
12393
+ const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
12394
+ return {
12395
+ kty: 'RSA',
12396
+ n: asn1jsIntegerToBase64(values[0]),
12397
+ e: asn1jsIntegerToBase64(values[1])
12398
+ };
12399
+ }
12400
+ /**
12401
+ * Convert a JWK key to PKIX in ASN1 DER format
12402
+ */
12403
+ function jwkToPkix(jwk) {
12404
+ if (jwk.n == null || jwk.e == null) {
12405
+ throw new InvalidParametersError('JWK was missing components');
12994
12406
  }
12407
+ const root = new Sequence({
12408
+ value: [
12409
+ new Sequence({
12410
+ value: [
12411
+ // rsaEncryption
12412
+ new ObjectIdentifier({
12413
+ value: '1.2.840.113549.1.1.1'
12414
+ }),
12415
+ new Null()
12416
+ ]
12417
+ }),
12418
+ // this appears to be a bug in asn1js.js - this should really be a Sequence
12419
+ // and not a BitString but it generates the same bytes as node-forge so 🤷‍♂️
12420
+ new BitString({
12421
+ valueHex: new Sequence({
12422
+ value: [
12423
+ Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
12424
+ Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url')))
12425
+ ]
12426
+ }).toBER()
12427
+ })
12428
+ ]
12429
+ });
12430
+ const der = root.toBER();
12431
+ return new Uint8Array(der, 0, der.byteLength);
12995
12432
  }
12996
- async function unmarshalRsaPrivateKey(bytes) {
12997
- const jwk = pkcs1ToJwk(bytes);
12998
- if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
12999
- throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
12433
+ function asn1jsIntegerToBase64(int) {
12434
+ let buf = int.valueBlock.valueHexView;
12435
+ // chrome rejects values with leading 0s
12436
+ while (buf[0] === 0) {
12437
+ buf = buf.subarray(1);
13000
12438
  }
13001
- const keys = await unmarshalPrivateKey$1(jwk);
13002
- return new RsaPrivateKey(keys.privateKey, keys.publicKey);
12439
+ return toString$6(buf, 'base64url');
12440
+ }
12441
+ function bufToBn(u8) {
12442
+ const hex = [];
12443
+ u8.forEach(function (i) {
12444
+ let h = i.toString(16);
12445
+ if (h.length % 2 > 0) {
12446
+ h = `0${h}`;
12447
+ }
12448
+ hex.push(h);
12449
+ });
12450
+ return BigInt('0x' + hex.join(''));
13003
12451
  }
13004
- function unmarshalRsaPublicKey(bytes) {
12452
+ /**
12453
+ * Turn PKIX bytes to a PublicKey
12454
+ */
12455
+ function pkixToRSAPublicKey(bytes) {
13005
12456
  const jwk = pkixToJwk(bytes);
13006
- if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13007
- throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
12457
+ if (rsaKeySize(jwk) > MAX_RSA_KEY_SIZE) {
12458
+ throw new InvalidPublicKeyError('Key size is too large');
13008
12459
  }
13009
- return new RsaPublicKey(jwk);
12460
+ const hash = sha256$1(PublicKey.encode({
12461
+ Type: KeyType.RSA,
12462
+ Data: bytes
12463
+ }));
12464
+ const digest = create(SHA2_256_CODE, hash);
12465
+ return new RSAPublicKey(jwk, digest);
13010
12466
  }
13011
- async function fromJwk(jwk) {
13012
- if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13013
- throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
12467
+
12468
+ // HMAC (RFC 2104)
12469
+ class HMAC extends Hash {
12470
+ constructor(hash$1, _key) {
12471
+ super();
12472
+ this.finished = false;
12473
+ this.destroyed = false;
12474
+ hash(hash$1);
12475
+ const key = toBytes$1(_key);
12476
+ this.iHash = hash$1.create();
12477
+ if (typeof this.iHash.update !== 'function')
12478
+ throw new Error('Expected instance of class which extends utils.Hash');
12479
+ this.blockLen = this.iHash.blockLen;
12480
+ this.outputLen = this.iHash.outputLen;
12481
+ const blockLen = this.blockLen;
12482
+ const pad = new Uint8Array(blockLen);
12483
+ // blockLen can be bigger than outputLen
12484
+ pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
12485
+ for (let i = 0; i < pad.length; i++)
12486
+ pad[i] ^= 0x36;
12487
+ this.iHash.update(pad);
12488
+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
12489
+ this.oHash = hash$1.create();
12490
+ // Undo internal XOR && apply outer XOR
12491
+ for (let i = 0; i < pad.length; i++)
12492
+ pad[i] ^= 0x36 ^ 0x5c;
12493
+ this.oHash.update(pad);
12494
+ pad.fill(0);
13014
12495
  }
13015
- const keys = await unmarshalPrivateKey$1(jwk);
13016
- return new RsaPrivateKey(keys.privateKey, keys.publicKey);
13017
- }
13018
- async function generateKeyPair$1(bits) {
13019
- if (bits > MAX_RSA_KEY_SIZE) {
13020
- throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
12496
+ update(buf) {
12497
+ exists(this);
12498
+ this.iHash.update(buf);
12499
+ return this;
12500
+ }
12501
+ digestInto(out) {
12502
+ exists(this);
12503
+ bytes(out, this.outputLen);
12504
+ this.finished = true;
12505
+ this.iHash.digestInto(out);
12506
+ this.oHash.update(out);
12507
+ this.oHash.digestInto(out);
12508
+ this.destroy();
12509
+ }
12510
+ digest() {
12511
+ const out = new Uint8Array(this.oHash.outputLen);
12512
+ this.digestInto(out);
12513
+ return out;
12514
+ }
12515
+ _cloneInto(to) {
12516
+ // Create new instance without calling constructor since key already in state and we don't know it.
12517
+ to || (to = Object.create(Object.getPrototypeOf(this), {}));
12518
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
12519
+ to = to;
12520
+ to.finished = finished;
12521
+ to.destroyed = destroyed;
12522
+ to.blockLen = blockLen;
12523
+ to.outputLen = outputLen;
12524
+ to.oHash = oHash._cloneInto(to.oHash);
12525
+ to.iHash = iHash._cloneInto(to.iHash);
12526
+ return to;
12527
+ }
12528
+ destroy() {
12529
+ this.destroyed = true;
12530
+ this.oHash.destroy();
12531
+ this.iHash.destroy();
13021
12532
  }
13022
- const keys = await generateKey$1(bits);
13023
- return new RsaPrivateKey(keys.privateKey, keys.publicKey);
13024
12533
  }
13025
-
13026
- var RSA = /*#__PURE__*/Object.freeze({
13027
- __proto__: null,
13028
- MAX_RSA_KEY_SIZE: MAX_RSA_KEY_SIZE,
13029
- RsaPrivateKey: RsaPrivateKey,
13030
- RsaPublicKey: RsaPublicKey,
13031
- fromJwk: fromJwk,
13032
- generateKeyPair: generateKeyPair$1,
13033
- unmarshalRsaPrivateKey: unmarshalRsaPrivateKey,
13034
- unmarshalRsaPublicKey: unmarshalRsaPublicKey
13035
- });
12534
+ /**
12535
+ * HMAC: RFC2104 message authentication code.
12536
+ * @param hash - function that would be used e.g. sha256
12537
+ * @param key - message key
12538
+ * @param message - message data
12539
+ * @example
12540
+ * import { hmac } from '@noble/hashes/hmac';
12541
+ * import { sha256 } from '@noble/hashes/sha2';
12542
+ * const mac1 = hmac(sha256, 'key', 'message');
12543
+ */
12544
+ const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
12545
+ hmac.create = (hash, key) => new HMAC(hash, key);
13036
12546
 
13037
12547
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
13038
12548
  // Short Weierstrass curve. The formula is: y² = x³ + ax + b
@@ -13069,8 +12579,14 @@ function validatePointOpts(curve) {
13069
12579
  }
13070
12580
  return Object.freeze({ ...opts });
13071
12581
  }
13072
- // ASN.1 DER encoding utilities
13073
12582
  const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
12583
+ /**
12584
+ * ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
12585
+ *
12586
+ * [0x30 (SEQUENCE), bytelength, 0x02 (INTEGER), intLength, R, 0x02 (INTEGER), intLength, S]
12587
+ *
12588
+ * Docs: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/, https://luca.ntop.org/Teaching/Appunti/asn1.html
12589
+ */
13074
12590
  const DER = {
13075
12591
  // asn.1 DER encoding utils
13076
12592
  Err: class DERErr extends Error {
@@ -13078,54 +12594,103 @@ const DER = {
13078
12594
  super(m);
13079
12595
  }
13080
12596
  },
13081
- _parseInt(data) {
13082
- const { Err: E } = DER;
13083
- if (data.length < 2 || data[0] !== 0x02)
13084
- throw new E('Invalid signature integer tag');
13085
- const len = data[1];
13086
- const res = data.subarray(2, len + 2);
13087
- if (!len || res.length !== len)
13088
- throw new E('Invalid signature integer: wrong length');
13089
- // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
13090
- // since we always use positive integers here. It must always be empty:
13091
- // - add zero byte if exists
13092
- // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
13093
- if (res[0] & 0b10000000)
13094
- throw new E('Invalid signature integer: negative');
13095
- if (res[0] === 0x00 && !(res[1] & 0b10000000))
13096
- throw new E('Invalid signature integer: unnecessary leading zero');
13097
- return { d: b2n(res), l: data.subarray(len + 2) }; // d is data, l is left
12597
+ // Basic building block is TLV (Tag-Length-Value)
12598
+ _tlv: {
12599
+ encode: (tag, data) => {
12600
+ const { Err: E } = DER;
12601
+ if (tag < 0 || tag > 256)
12602
+ throw new E('tlv.encode: wrong tag');
12603
+ if (data.length & 1)
12604
+ throw new E('tlv.encode: unpadded data');
12605
+ const dataLen = data.length / 2;
12606
+ const len = numberToHexUnpadded(dataLen);
12607
+ if ((len.length / 2) & 128)
12608
+ throw new E('tlv.encode: long form length too big');
12609
+ // length of length with long form flag
12610
+ const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
12611
+ return `${numberToHexUnpadded(tag)}${lenLen}${len}${data}`;
12612
+ },
12613
+ // v - value, l - left bytes (unparsed)
12614
+ decode(tag, data) {
12615
+ const { Err: E } = DER;
12616
+ let pos = 0;
12617
+ if (tag < 0 || tag > 256)
12618
+ throw new E('tlv.encode: wrong tag');
12619
+ if (data.length < 2 || data[pos++] !== tag)
12620
+ throw new E('tlv.decode: wrong tlv');
12621
+ const first = data[pos++];
12622
+ const isLong = !!(first & 128); // First bit of first length byte is flag for short/long form
12623
+ let length = 0;
12624
+ if (!isLong)
12625
+ length = first;
12626
+ else {
12627
+ // Long form: [longFlag(1bit), lengthLength(7bit), length (BE)]
12628
+ const lenLen = first & 127;
12629
+ if (!lenLen)
12630
+ throw new E('tlv.decode(long): indefinite length not supported');
12631
+ if (lenLen > 4)
12632
+ throw new E('tlv.decode(long): byte length is too big'); // this will overflow u32 in js
12633
+ const lengthBytes = data.subarray(pos, pos + lenLen);
12634
+ if (lengthBytes.length !== lenLen)
12635
+ throw new E('tlv.decode: length bytes not complete');
12636
+ if (lengthBytes[0] === 0)
12637
+ throw new E('tlv.decode(long): zero leftmost byte');
12638
+ for (const b of lengthBytes)
12639
+ length = (length << 8) | b;
12640
+ pos += lenLen;
12641
+ if (length < 128)
12642
+ throw new E('tlv.decode(long): not minimal encoding');
12643
+ }
12644
+ const v = data.subarray(pos, pos + length);
12645
+ if (v.length !== length)
12646
+ throw new E('tlv.decode: wrong value length');
12647
+ return { v, l: data.subarray(pos + length) };
12648
+ },
12649
+ },
12650
+ // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
12651
+ // since we always use positive integers here. It must always be empty:
12652
+ // - add zero byte if exists
12653
+ // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
12654
+ _int: {
12655
+ encode(num) {
12656
+ const { Err: E } = DER;
12657
+ if (num < _0n)
12658
+ throw new E('integer: negative integers are not allowed');
12659
+ let hex = numberToHexUnpadded(num);
12660
+ // Pad with zero byte if negative flag is present
12661
+ if (Number.parseInt(hex[0], 16) & 0b1000)
12662
+ hex = '00' + hex;
12663
+ if (hex.length & 1)
12664
+ throw new E('unexpected assertion');
12665
+ return hex;
12666
+ },
12667
+ decode(data) {
12668
+ const { Err: E } = DER;
12669
+ if (data[0] & 128)
12670
+ throw new E('Invalid signature integer: negative');
12671
+ if (data[0] === 0x00 && !(data[1] & 128))
12672
+ throw new E('Invalid signature integer: unnecessary leading zero');
12673
+ return b2n(data);
12674
+ },
13098
12675
  },
13099
12676
  toSig(hex) {
13100
12677
  // parse DER signature
13101
- const { Err: E } = DER;
12678
+ const { Err: E, _int: int, _tlv: tlv } = DER;
13102
12679
  const data = typeof hex === 'string' ? h2b(hex) : hex;
13103
12680
  abytes(data);
13104
- let l = data.length;
13105
- if (l < 2 || data[0] != 0x30)
13106
- throw new E('Invalid signature tag');
13107
- if (data[1] !== l - 2)
13108
- throw new E('Invalid signature: incorrect length');
13109
- const { d: r, l: sBytes } = DER._parseInt(data.subarray(2));
13110
- const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);
13111
- if (rBytesLeft.length)
12681
+ const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
12682
+ if (seqLeftBytes.length)
13112
12683
  throw new E('Invalid signature: left bytes after parsing');
13113
- return { r, s };
12684
+ const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
12685
+ const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
12686
+ if (sLeftBytes.length)
12687
+ throw new E('Invalid signature: left bytes after parsing');
12688
+ return { r: int.decode(rBytes), s: int.decode(sBytes) };
13114
12689
  },
13115
12690
  hexFromSig(sig) {
13116
- // Add leading zero if first byte has negative bit enabled. More details in '_parseInt'
13117
- const slice = (s) => (Number.parseInt(s[0], 16) & 0b1000 ? '00' + s : s);
13118
- const h = (num) => {
13119
- const hex = num.toString(16);
13120
- return hex.length & 1 ? `0${hex}` : hex;
13121
- };
13122
- const s = slice(h(sig.s));
13123
- const r = slice(h(sig.r));
13124
- const shl = s.length / 2;
13125
- const rhl = r.length / 2;
13126
- const sl = h(shl);
13127
- const rl = h(rhl);
13128
- return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
12691
+ const { _tlv: tlv, _int: int } = DER;
12692
+ const seq = `${tlv.encode(0x02, int.encode(sig.r))}${tlv.encode(0x02, int.encode(sig.s))}`;
12693
+ return tlv.encode(0x30, seq);
13129
12694
  },
13130
12695
  };
13131
12696
  // Be friendly to bad ECMAScript parsers by not using bigint literals
@@ -13134,6 +12699,7 @@ const _0n = BigInt(0), _1n$1 = BigInt(1); BigInt(2); const _3n = BigInt(3); BigI
13134
12699
  function weierstrassPoints(opts) {
13135
12700
  const CURVE = validatePointOpts(opts);
13136
12701
  const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
12702
+ const Fn = Field(CURVE.n, CURVE.nBitLength);
13137
12703
  const toBytes = CURVE.toBytes ||
13138
12704
  ((_c, point, _isCompressed) => {
13139
12705
  const a = point.toAffine();
@@ -13307,6 +12873,10 @@ function weierstrassPoints(opts) {
13307
12873
  static fromPrivateKey(privateKey) {
13308
12874
  return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
13309
12875
  }
12876
+ // Multiscalar Multiplication
12877
+ static msm(points, scalars) {
12878
+ return pippenger(Point, Fn, points, scalars);
12879
+ }
13310
12880
  // "Private method", don't use it directly
13311
12881
  _setWindowSize(windowSize) {
13312
12882
  wnaf.setWindowSize(this, windowSize);
@@ -13992,7 +13562,7 @@ function getHash(hash) {
13992
13562
  return {
13993
13563
  hash,
13994
13564
  hmac: (key, ...msgs) => hmac(hash, key, concatBytes$2(...msgs)),
13995
- randomBytes: randomBytes$1,
13565
+ randomBytes,
13996
13566
  };
13997
13567
  }
13998
13568
  function createCurve(curveDef, defHash) {
@@ -14085,27 +13655,15 @@ const secp256k1 = createCurve({
14085
13655
  BigInt(0);
14086
13656
  secp256k1.ProjectivePoint;
14087
13657
 
14088
- function generateKey() {
14089
- return secp256k1.utils.randomPrivateKey();
14090
- }
14091
- /**
14092
- * Hash and sign message with private key
14093
- */
14094
- function hashAndSign(key, msg) {
14095
- const p = sha256.digest(msg instanceof Uint8Array ? msg : msg.subarray());
14096
- if (isPromise$1(p)) {
14097
- return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
14098
- .catch(err => {
14099
- throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14100
- });
14101
- }
14102
- try {
14103
- return secp256k1.sign(p.digest, key).toDERRawBytes();
14104
- }
14105
- catch (err) {
14106
- throw new CodeError(String(err), 'ERR_INVALID_INPUT');
13658
+ function isPromise$1(thing) {
13659
+ if (thing == null) {
13660
+ return false;
14107
13661
  }
13662
+ return typeof thing.then === 'function' &&
13663
+ typeof thing.catch === 'function' &&
13664
+ typeof thing.finally === 'function';
14108
13665
  }
13666
+
14109
13667
  /**
14110
13668
  * Hash message and verify signature with public key
14111
13669
  */
@@ -14114,231 +13672,134 @@ function hashAndVerify(key, sig, msg) {
14114
13672
  if (isPromise$1(p)) {
14115
13673
  return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
14116
13674
  .catch(err => {
14117
- throw new CodeError(String(err), 'ERR_INVALID_INPUT');
13675
+ throw new VerificationError(String(err));
14118
13676
  });
14119
13677
  }
14120
13678
  try {
14121
13679
  return secp256k1.verify(sig, p.digest, key);
14122
13680
  }
14123
13681
  catch (err) {
14124
- throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14125
- }
14126
- }
14127
- function compressPublicKey(key) {
14128
- const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
14129
- return point;
14130
- }
14131
- function validatePrivateKey(key) {
14132
- try {
14133
- secp256k1.getPublicKey(key, true);
14134
- }
14135
- catch (err) {
14136
- throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
14137
- }
14138
- }
14139
- function validatePublicKey(key) {
14140
- try {
14141
- secp256k1.ProjectivePoint.fromHex(key);
14142
- }
14143
- catch (err) {
14144
- throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
14145
- }
14146
- }
14147
- function computePublicKey(privateKey) {
14148
- try {
14149
- return secp256k1.getPublicKey(privateKey, true);
14150
- }
14151
- catch (err) {
14152
- throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
13682
+ throw new VerificationError(String(err));
14153
13683
  }
14154
13684
  }
14155
13685
 
14156
13686
  class Secp256k1PublicKey {
13687
+ type = 'secp256k1';
13688
+ raw;
14157
13689
  _key;
14158
13690
  constructor(key) {
14159
- validatePublicKey(key);
14160
- this._key = key;
14161
- }
14162
- verify(data, sig) {
14163
- return hashAndVerify(this._key, sig, data);
14164
- }
14165
- marshal() {
14166
- return compressPublicKey(this._key);
14167
- }
14168
- get bytes() {
14169
- return PublicKey.encode({
14170
- Type: KeyType.Secp256k1,
14171
- Data: this.marshal()
14172
- }).subarray();
13691
+ this._key = validateSecp256k1PublicKey(key);
13692
+ this.raw = compressSecp256k1PublicKey(this._key);
14173
13693
  }
14174
- equals(key) {
14175
- return equals(this.bytes, key.bytes);
14176
- }
14177
- async hash() {
14178
- const p = sha256.digest(this.bytes);
14179
- let bytes;
14180
- if (isPromise$1(p)) {
14181
- ({ bytes } = await p);
14182
- }
14183
- else {
14184
- bytes = p.bytes;
14185
- }
14186
- return bytes;
14187
- }
14188
- }
14189
- class Secp256k1PrivateKey {
14190
- _key;
14191
- _publicKey;
14192
- constructor(key, publicKey) {
14193
- this._key = key;
14194
- this._publicKey = publicKey ?? computePublicKey(key);
14195
- validatePrivateKey(this._key);
14196
- validatePublicKey(this._publicKey);
14197
- }
14198
- sign(message) {
14199
- return hashAndSign(this._key, message);
13694
+ toMultihash() {
13695
+ return identity.digest(publicKeyToProtobuf(this));
14200
13696
  }
14201
- get public() {
14202
- return new Secp256k1PublicKey(this._publicKey);
14203
- }
14204
- marshal() {
14205
- return this._key;
13697
+ toCID() {
13698
+ return CID.createV1(114, this.toMultihash());
14206
13699
  }
14207
- get bytes() {
14208
- return PrivateKey.encode({
14209
- Type: KeyType.Secp256k1,
14210
- Data: this.marshal()
14211
- }).subarray();
13700
+ toString() {
13701
+ return base58btc.encode(this.toMultihash().bytes).substring(1);
14212
13702
  }
14213
13703
  equals(key) {
14214
- return equals(this.bytes, key.bytes);
14215
- }
14216
- hash() {
14217
- const p = sha256.digest(this.bytes);
14218
- if (isPromise$1(p)) {
14219
- return p.then(({ bytes }) => bytes);
13704
+ if (key == null || !(key.raw instanceof Uint8Array)) {
13705
+ return false;
14220
13706
  }
14221
- return p.bytes;
13707
+ return equals(this.raw, key.raw);
14222
13708
  }
14223
- /**
14224
- * Gets the ID of the key.
14225
- *
14226
- * The key id is the base58 encoding of the SHA-256 multihash of its public key.
14227
- * The public key is a protobuf encoding containing a type and the DER encoding
14228
- * of the PKCS SubjectPublicKeyInfo.
14229
- */
14230
- async id() {
14231
- const hash = await this.public.hash();
14232
- return toString$6(hash, 'base58btc');
14233
- }
14234
- /**
14235
- * Exports the key into a password protected `format`
14236
- */
14237
- async export(password, format = 'libp2p-key') {
14238
- if (format === 'libp2p-key') {
14239
- return exporter(this.bytes, password);
14240
- }
14241
- else {
14242
- throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
14243
- }
13709
+ verify(data, sig) {
13710
+ return hashAndVerify(this._key, sig, data);
14244
13711
  }
14245
13712
  }
14246
- function unmarshalSecp256k1PrivateKey(bytes) {
14247
- return new Secp256k1PrivateKey(bytes);
14248
- }
13713
+
14249
13714
  function unmarshalSecp256k1PublicKey(bytes) {
14250
13715
  return new Secp256k1PublicKey(bytes);
14251
13716
  }
14252
- async function generateKeyPair() {
14253
- const privateKeyBytes = generateKey();
14254
- return new Secp256k1PrivateKey(privateKeyBytes);
13717
+ function compressSecp256k1PublicKey(key) {
13718
+ const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
13719
+ return point;
13720
+ }
13721
+ function validateSecp256k1PublicKey(key) {
13722
+ try {
13723
+ secp256k1.ProjectivePoint.fromHex(key);
13724
+ return key;
13725
+ }
13726
+ catch (err) {
13727
+ throw new InvalidPublicKeyError(String(err));
13728
+ }
14255
13729
  }
14256
-
14257
- var Secp256k1 = /*#__PURE__*/Object.freeze({
14258
- __proto__: null,
14259
- Secp256k1PrivateKey: Secp256k1PrivateKey,
14260
- Secp256k1PublicKey: Secp256k1PublicKey,
14261
- generateKeyPair: generateKeyPair,
14262
- unmarshalSecp256k1PrivateKey: unmarshalSecp256k1PrivateKey,
14263
- unmarshalSecp256k1PublicKey: unmarshalSecp256k1PublicKey
14264
- });
14265
13730
 
14266
13731
  /**
14267
13732
  * @packageDocumentation
14268
13733
  *
14269
- * **Supported Key Types**
14270
- *
14271
- * The {@link generateKeyPair}, {@link marshalPublicKey}, and {@link marshalPrivateKey} functions accept a string `type` argument.
13734
+ * ## Supported Key Types
14272
13735
  *
14273
13736
  * Currently the `'RSA'`, `'ed25519'`, and `secp256k1` types are supported, although ed25519 and secp256k1 keys support only signing and verification of messages.
14274
13737
  *
14275
13738
  * For encryption / decryption support, RSA keys should be used.
14276
13739
  */
14277
- const supportedKeys = {
14278
- rsa: RSA,
14279
- ed25519: Ed25519,
14280
- secp256k1: Secp256k1
14281
- };
14282
- function unsupportedKey(type) {
14283
- const supported = Object.keys(supportedKeys).join(' / ');
14284
- return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
14285
- }
14286
- function typeToKey(type) {
14287
- type = type.toLowerCase();
14288
- if (type === 'rsa' || type === 'ed25519' || type === 'secp256k1') {
14289
- return supportedKeys[type];
13740
+ /**
13741
+ * Creates a public key from the raw key bytes
13742
+ */
13743
+ function publicKeyFromRaw(buf) {
13744
+ if (buf.byteLength === 32) {
13745
+ return unmarshalEd25519PublicKey(buf);
13746
+ }
13747
+ else if (buf.byteLength === 33) {
13748
+ return unmarshalSecp256k1PublicKey(buf);
13749
+ }
13750
+ else {
13751
+ return pkixToRSAPublicKey(buf);
14290
13752
  }
14291
- throw unsupportedKey(type);
14292
13753
  }
14293
13754
  /**
14294
- * Converts a protobuf serialized public key into its representative object
13755
+ * Creates a public key from an identity multihash which contains a protobuf
13756
+ * encoded Ed25519 or secp256k1 public key.
13757
+ *
13758
+ * RSA keys are not supported as in practice we they are not stored in identity
13759
+ * multihashes since the hash would be very large.
14295
13760
  */
14296
- function unmarshalPublicKey(buf) {
14297
- const decoded = PublicKey.decode(buf);
14298
- const data = decoded.Data ?? new Uint8Array();
14299
- switch (decoded.Type) {
14300
- case KeyType.RSA:
14301
- return supportedKeys.rsa.unmarshalRsaPublicKey(data);
13761
+ function publicKeyFromMultihash(digest) {
13762
+ const { Type, Data } = PublicKey.decode(digest.digest);
13763
+ const data = Data ?? new Uint8Array();
13764
+ switch (Type) {
14302
13765
  case KeyType.Ed25519:
14303
- return supportedKeys.ed25519.unmarshalEd25519PublicKey(data);
14304
- case KeyType.Secp256k1:
14305
- return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data);
13766
+ return unmarshalEd25519PublicKey(data);
13767
+ case KeyType.secp256k1:
13768
+ return unmarshalSecp256k1PublicKey(data);
14306
13769
  default:
14307
- throw unsupportedKey(decoded.Type ?? 'unknown');
13770
+ throw new UnsupportedKeyTypeError$1();
14308
13771
  }
14309
13772
  }
14310
13773
  /**
14311
13774
  * Converts a public key object into a protobuf serialized public key
14312
13775
  */
14313
- function marshalPublicKey(key, type) {
14314
- type = (type ?? 'rsa').toLowerCase();
14315
- typeToKey(type); // check type
14316
- return key.bytes;
13776
+ function publicKeyToProtobuf(key) {
13777
+ return PublicKey.encode({
13778
+ Type: KeyType[key.type],
13779
+ Data: key.raw
13780
+ });
14317
13781
  }
13782
+
14318
13783
  /**
14319
- * Converts a protobuf serialized private key into its representative object
13784
+ * All PeerId implementations must use this symbol as the name of a property
13785
+ * with a boolean `true` value
14320
13786
  */
14321
- async function unmarshalPrivateKey(buf) {
14322
- const decoded = PrivateKey.decode(buf);
14323
- const data = decoded.Data ?? new Uint8Array();
14324
- switch (decoded.Type) {
14325
- case KeyType.RSA:
14326
- return supportedKeys.rsa.unmarshalRsaPrivateKey(data);
14327
- case KeyType.Ed25519:
14328
- return supportedKeys.ed25519.unmarshalEd25519PrivateKey(data);
14329
- case KeyType.Secp256k1:
14330
- return supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(data);
14331
- default:
14332
- throw unsupportedKey(decoded.Type ?? 'RSA');
14333
- }
14334
- }
13787
+ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
13788
+
14335
13789
  /**
14336
- * Converts a private key object into a protobuf serialized private key
13790
+ * When this error is thrown it means an operation was aborted,
13791
+ * usually in response to the `abort` event being emitted by an
13792
+ * AbortSignal.
14337
13793
  */
14338
- function marshalPrivateKey(key, type) {
14339
- type = (type ?? 'rsa').toLowerCase();
14340
- typeToKey(type); // check type
14341
- return key.bytes;
13794
+ /**
13795
+ * Thrown when and attempt to operate on an unsupported key was made
13796
+ */
13797
+ class UnsupportedKeyTypeError extends Error {
13798
+ static name = 'UnsupportedKeyTypeError';
13799
+ constructor(message = 'Unsupported key type') {
13800
+ super(message);
13801
+ this.name = 'UnsupportedKeyTypeError';
13802
+ }
14342
13803
  }
14343
13804
 
14344
13805
  /**
@@ -14356,26 +13817,17 @@ function marshalPrivateKey(key, type) {
14356
13817
  * console.log(peer.toString()) // "12D3K..."
14357
13818
  * ```
14358
13819
  */
14359
- const inspect = Symbol.for('nodejs.util.inspect.custom');
14360
- const baseDecoder = Object
14361
- .values(bases)
14362
- .map(codec => codec.decoder)
14363
- // @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
14364
- .reduce((acc, curr) => acc.or(curr), bases.identity.decoder);
13820
+ const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
14365
13821
  // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
14366
- const LIBP2P_KEY_CODE = 0x72;
14367
- const MARSHALLED_ED225519_PUBLIC_KEY_LENGTH = 36;
14368
- const MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH = 37;
14369
- class PeerIdImpl {
13822
+ const LIBP2P_KEY_CODE$1 = 0x72;
13823
+ let PeerIdImpl$1 = class PeerIdImpl {
14370
13824
  type;
14371
13825
  multihash;
14372
- privateKey;
14373
13826
  publicKey;
14374
13827
  string;
14375
13828
  constructor(init) {
14376
13829
  this.type = init.type;
14377
13830
  this.multihash = init.multihash;
14378
- this.privateKey = init.privateKey;
14379
13831
  // mark string cache as non-enumerable
14380
13832
  Object.defineProperty(this, 'string', {
14381
13833
  enumerable: false,
@@ -14392,17 +13844,14 @@ class PeerIdImpl {
14392
13844
  }
14393
13845
  return this.string;
14394
13846
  }
13847
+ toMultihash() {
13848
+ return this.multihash;
13849
+ }
14395
13850
  // return self-describing String representation
14396
13851
  // in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
14397
13852
  toCID() {
14398
- return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
13853
+ return CID.createV1(LIBP2P_KEY_CODE$1, this.multihash);
14399
13854
  }
14400
- toBytes() {
14401
- return this.multihash.bytes;
14402
- }
14403
- /**
14404
- * Returns Multiaddr as a JSON string
14405
- */
14406
13855
  toJSON() {
14407
13856
  return this.toString();
14408
13857
  }
@@ -14417,10 +13866,10 @@ class PeerIdImpl {
14417
13866
  return equals(this.multihash.bytes, id);
14418
13867
  }
14419
13868
  else if (typeof id === 'string') {
14420
- return peerIdFromString(id).equals(this);
13869
+ return this.toString() === id;
14421
13870
  }
14422
- else if (id?.multihash?.bytes != null) {
14423
- return equals(this.multihash.bytes, id.multihash.bytes);
13871
+ else if (id?.toMultihash()?.bytes != null) {
13872
+ return equals(this.multihash.bytes, id.toMultihash().bytes);
14424
13873
  }
14425
13874
  else {
14426
13875
  throw new Error('not valid Id');
@@ -14429,154 +13878,88 @@ class PeerIdImpl {
14429
13878
  /**
14430
13879
  * Returns PeerId as a human-readable string
14431
13880
  * https://nodejs.org/api/util.html#utilinspectcustom
14432
- *
14433
- * @example
14434
- * ```TypeScript
14435
- * import { peerIdFromString } from '@libp2p/peer-id'
14436
- *
14437
- * console.info(peerIdFromString('QmFoo'))
14438
- * // 'PeerId(QmFoo)'
14439
- * ```
14440
- */
14441
- [inspect]() {
14442
- return `PeerId(${this.toString()})`;
14443
- }
14444
- }
14445
- class RSAPeerIdImpl extends PeerIdImpl {
14446
- type = 'RSA';
14447
- publicKey;
14448
- constructor(init) {
14449
- super({ ...init, type: 'RSA' });
14450
- this.publicKey = init.publicKey;
14451
- }
14452
- }
14453
- class Ed25519PeerIdImpl extends PeerIdImpl {
14454
- type = 'Ed25519';
14455
- publicKey;
14456
- constructor(init) {
14457
- super({ ...init, type: 'Ed25519' });
14458
- this.publicKey = init.multihash.digest;
14459
- }
14460
- }
14461
- class Secp256k1PeerIdImpl extends PeerIdImpl {
14462
- type = 'secp256k1';
14463
- publicKey;
14464
- constructor(init) {
14465
- super({ ...init, type: 'secp256k1' });
14466
- this.publicKey = init.multihash.digest;
14467
- }
14468
- }
14469
- // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
14470
- const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
14471
- class URLPeerIdImpl {
14472
- type = 'url';
14473
- multihash;
14474
- privateKey;
14475
- publicKey;
14476
- url;
14477
- constructor(url) {
14478
- this.url = url.toString();
14479
- this.multihash = identity.digest(fromString(this.url));
14480
- }
14481
- [inspect]() {
14482
- return `PeerId(${this.url})`;
14483
- }
14484
- [peerIdSymbol] = true;
14485
- toString() {
14486
- return this.toCID().toString();
14487
- }
14488
- toCID() {
14489
- return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
14490
- }
14491
- toBytes() {
14492
- return this.toCID().bytes;
14493
- }
14494
- equals(other) {
14495
- if (other == null) {
14496
- return false;
14497
- }
14498
- if (other instanceof Uint8Array) {
14499
- other = toString$6(other);
14500
- }
14501
- return other.toString() === this.toString();
14502
- }
14503
- }
14504
- function peerIdFromString(str, decoder) {
14505
- if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
14506
- // identity hash ed25519/secp256k1 key or sha2-256 hash of
14507
- // rsa public key - base58btc encoded either way
14508
- const multihash = decode$6(base58btc.decode(`z${str}`));
14509
- if (str.startsWith('12D')) {
14510
- return new Ed25519PeerIdImpl({ multihash });
14511
- }
14512
- else if (str.startsWith('16U')) {
14513
- return new Secp256k1PeerIdImpl({ multihash });
14514
- }
14515
- else {
14516
- return new RSAPeerIdImpl({ multihash });
14517
- }
14518
- }
14519
- return peerIdFromBytes(baseDecoder.decode(str));
14520
- }
14521
- function peerIdFromBytes(buf) {
14522
- try {
14523
- const multihash = decode$6(buf);
14524
- if (multihash.code === identity.code) {
14525
- if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
14526
- return new Ed25519PeerIdImpl({ multihash });
14527
- }
14528
- else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
14529
- return new Secp256k1PeerIdImpl({ multihash });
14530
- }
14531
- }
14532
- if (multihash.code === sha256.code) {
14533
- return new RSAPeerIdImpl({ multihash });
14534
- }
14535
- }
14536
- catch {
14537
- return peerIdFromCID(CID.decode(buf));
14538
- }
14539
- throw new Error('Supplied PeerID CID is invalid');
14540
- }
14541
- function peerIdFromCID(cid) {
14542
- if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
14543
- throw new Error('Supplied PeerID CID is invalid');
13881
+ *
13882
+ * @example
13883
+ * ```TypeScript
13884
+ * import { peerIdFromString } from '@libp2p/peer-id'
13885
+ *
13886
+ * console.info(peerIdFromString('QmFoo'))
13887
+ * // 'PeerId(QmFoo)'
13888
+ * ```
13889
+ */
13890
+ [inspect$1]() {
13891
+ return `PeerId(${this.toString()})`;
14544
13892
  }
14545
- if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
14546
- const url = toString$6(cid.multihash.digest);
14547
- return new URLPeerIdImpl(new URL(url));
13893
+ };
13894
+ let RSAPeerId$1 = class RSAPeerId extends PeerIdImpl$1 {
13895
+ type = 'RSA';
13896
+ publicKey;
13897
+ constructor(init) {
13898
+ super({ ...init, type: 'RSA' });
13899
+ this.publicKey = init.publicKey;
14548
13900
  }
14549
- const multihash = cid.multihash;
14550
- if (multihash.code === sha256.code) {
14551
- return new RSAPeerIdImpl({ multihash: cid.multihash });
13901
+ };
13902
+ let Ed25519PeerId$1 = class Ed25519PeerId extends PeerIdImpl$1 {
13903
+ type = 'Ed25519';
13904
+ publicKey;
13905
+ constructor(init) {
13906
+ super({ ...init, type: 'Ed25519' });
13907
+ this.publicKey = init.publicKey;
14552
13908
  }
14553
- else if (multihash.code === identity.code) {
14554
- if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
14555
- return new Ed25519PeerIdImpl({ multihash: cid.multihash });
14556
- }
14557
- else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
14558
- return new Secp256k1PeerIdImpl({ multihash: cid.multihash });
14559
- }
13909
+ };
13910
+ let Secp256k1PeerId$1 = class Secp256k1PeerId extends PeerIdImpl$1 {
13911
+ type = 'secp256k1';
13912
+ publicKey;
13913
+ constructor(init) {
13914
+ super({ ...init, type: 'secp256k1' });
13915
+ this.publicKey = init.publicKey;
14560
13916
  }
14561
- throw new Error('Supplied PeerID CID is invalid');
14562
- }
13917
+ };
13918
+
14563
13919
  /**
14564
- * @param publicKey - A marshalled public key
14565
- * @param privateKey - A marshalled private key
13920
+ * @packageDocumentation
13921
+ *
13922
+ * An implementation of a peer id
13923
+ *
13924
+ * @example
13925
+ *
13926
+ * ```TypeScript
13927
+ * import { peerIdFromString } from '@libp2p/peer-id'
13928
+ * const peer = peerIdFromString('12D3KooWKnDdG3iXw9eTFijk3EWSunZcFi54Zka4wmtqtt6rPxc8')
13929
+ *
13930
+ * console.log(peer.toCID()) // CID(bafzaa...)
13931
+ * console.log(peer.toString()) // "12D3K..."
13932
+ * ```
14566
13933
  */
14567
- async function peerIdFromKeys(publicKey, privateKey) {
14568
- if (publicKey.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
14569
- return new Ed25519PeerIdImpl({ multihash: create$1(identity.code, publicKey), privateKey });
13934
+ function peerIdFromPublicKey(publicKey) {
13935
+ if (publicKey.type === 'Ed25519') {
13936
+ return new Ed25519PeerId$1({
13937
+ multihash: publicKey.toCID().multihash,
13938
+ publicKey
13939
+ });
13940
+ }
13941
+ else if (publicKey.type === 'secp256k1') {
13942
+ return new Secp256k1PeerId$1({
13943
+ multihash: publicKey.toCID().multihash,
13944
+ publicKey
13945
+ });
14570
13946
  }
14571
- if (publicKey.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
14572
- return new Secp256k1PeerIdImpl({ multihash: create$1(identity.code, publicKey), privateKey });
13947
+ else if (publicKey.type === 'RSA') {
13948
+ return new RSAPeerId$1({
13949
+ multihash: publicKey.toCID().multihash,
13950
+ publicKey
13951
+ });
14573
13952
  }
14574
- return new RSAPeerIdImpl({ multihash: await sha256.digest(publicKey), publicKey, privateKey });
13953
+ throw new UnsupportedKeyTypeError();
14575
13954
  }
14576
13955
 
13956
+ const ERR_TYPE_NOT_IMPLEMENTED = "Keypair type not implemented";
14577
13957
  function createPeerIdFromPublicKey(publicKey) {
14578
- const _publicKey = new supportedKeys.secp256k1.Secp256k1PublicKey(publicKey);
14579
- return peerIdFromKeys(_publicKey.bytes, undefined);
13958
+ const pubKey = publicKeyFromRaw(publicKey);
13959
+ if (pubKey.type !== "secp256k1") {
13960
+ throw new Error(ERR_TYPE_NOT_IMPLEMENTED);
13961
+ }
13962
+ return peerIdFromPublicKey(pubKey);
14580
13963
  }
14581
13964
 
14582
13965
  function decodeMultiaddrs(bytes) {
@@ -14823,12 +14206,12 @@ var TransportProtocolPerIpVersion;
14823
14206
  class ENR extends RawEnr {
14824
14207
  static RECORD_PREFIX = "enr:";
14825
14208
  peerId;
14826
- static async create(kvs = {}, seq = BigInt(1), signature) {
14209
+ static create(kvs = {}, seq = BigInt(1), signature) {
14827
14210
  const enr = new ENR(kvs, seq, signature);
14828
14211
  try {
14829
14212
  const publicKey = enr.publicKey;
14830
14213
  if (publicKey) {
14831
- enr.peerId = await createPeerIdFromPublicKey(publicKey);
14214
+ enr.peerId = createPeerIdFromPublicKey(publicKey);
14832
14215
  }
14833
14216
  }
14834
14217
  catch (e) {
@@ -15593,7 +14976,7 @@ async function fromValues(values) {
15593
14976
  }
15594
14977
  }
15595
14978
  const _seq = decodeSeq(seq);
15596
- const enr = await ENR.create(obj, _seq, signature);
14979
+ const enr = ENR.create(obj, _seq, signature);
15597
14980
  checkSignature(seq, kvs, enr, signature);
15598
14981
  return enr;
15599
14982
  }
@@ -20744,110 +20127,129 @@ function filterPeersByDiscovery(peers, numPeers, maxBootstrapPeers) {
20744
20127
  return selectedPeers;
20745
20128
  }
20746
20129
 
20747
- function selectConnection(connections) {
20748
- if (!connections.length)
20749
- return;
20750
- if (connections.length === 1)
20751
- return connections[0];
20752
- let latestConnection;
20753
- connections.forEach((connection) => {
20754
- if (connection.status === "open") {
20755
- if (!latestConnection) {
20756
- latestConnection = connection;
20757
- }
20758
- else if (connection.timeline.open > latestConnection.timeline.open) {
20759
- latestConnection = connection;
20760
- }
20761
- }
20762
- });
20763
- return latestConnection;
20130
+ function selectOpenConnection(connections) {
20131
+ return connections
20132
+ .filter((c) => c.status === "open")
20133
+ .sort((left, right) => right.timeline.open - left.timeline.open)
20134
+ .at(0);
20764
20135
  }
20765
20136
 
20766
- const CONNECTION_TIMEOUT = 5_000;
20767
- const RETRY_BACKOFF_BASE = 1_000;
20768
- const MAX_RETRIES = 3;
20137
+ const STREAM_LOCK_KEY = "consumed";
20769
20138
  class StreamManager {
20770
20139
  multicodec;
20771
20140
  getConnections;
20772
20141
  addEventListener;
20773
- streamPool;
20774
20142
  log;
20143
+ ongoingCreation = new Set();
20144
+ streamPool = new Map();
20775
20145
  constructor(multicodec, getConnections, addEventListener) {
20776
20146
  this.multicodec = multicodec;
20777
20147
  this.getConnections = getConnections;
20778
20148
  this.addEventListener = addEventListener;
20779
20149
  this.log = new Logger$1(`stream-manager:${multicodec}`);
20780
- this.streamPool = new Map();
20781
20150
  this.addEventListener("peer:update", this.handlePeerUpdateStreamPool);
20782
20151
  }
20783
20152
  async getStream(peer) {
20784
- const peerIdStr = peer.id.toString();
20785
- const streamPromise = this.streamPool.get(peerIdStr);
20786
- if (!streamPromise) {
20787
- return this.createStream(peer);
20153
+ const peerId = peer.id.toString();
20154
+ const scheduledStream = this.streamPool.get(peerId);
20155
+ if (scheduledStream) {
20156
+ this.streamPool.delete(peerId);
20157
+ await scheduledStream;
20158
+ }
20159
+ let stream = this.getOpenStreamForCodec(peer.id);
20160
+ if (stream) {
20161
+ this.log.info(`Found existing stream peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20162
+ this.lockStream(peer.id.toString(), stream);
20163
+ return stream;
20164
+ }
20165
+ stream = await this.createStream(peer);
20166
+ this.lockStream(peer.id.toString(), stream);
20167
+ return stream;
20168
+ }
20169
+ async createStream(peer, retries = 0) {
20170
+ const connections = this.getConnections(peer.id);
20171
+ const connection = selectOpenConnection(connections);
20172
+ if (!connection) {
20173
+ throw new Error(`Failed to get a connection to the peer peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20788
20174
  }
20789
- this.streamPool.delete(peerIdStr);
20790
- this.prepareStream(peer);
20791
- try {
20792
- const stream = await streamPromise;
20793
- if (stream && stream.status !== "closed") {
20794
- return stream;
20175
+ let lastError;
20176
+ let stream;
20177
+ for (let i = 0; i < retries + 1; i++) {
20178
+ try {
20179
+ this.log.info(`Attempting to create a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20180
+ stream = await connection.newStream(this.multicodec);
20181
+ this.log.info(`Created stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20182
+ break;
20183
+ }
20184
+ catch (error) {
20185
+ lastError = error;
20795
20186
  }
20796
20187
  }
20797
- catch (error) {
20798
- this.log.warn(`Failed to get stream for ${peerIdStr} -- `, error);
20799
- this.log.warn("Attempting to create a new stream for the peer");
20188
+ if (!stream) {
20189
+ throw new Error(`Failed to create a new stream for ${peer.id.toString()} -- ` +
20190
+ lastError);
20800
20191
  }
20801
- return this.createStream(peer);
20192
+ return stream;
20802
20193
  }
20803
- async createStream(peer, retries = 0) {
20804
- const connections = this.getConnections(peer.id);
20805
- const connection = selectConnection(connections);
20806
- if (!connection) {
20807
- throw new Error("Failed to get a connection to the peer");
20194
+ async createStreamWithLock(peer) {
20195
+ const peerId = peer.id.toString();
20196
+ if (this.ongoingCreation.has(peerId)) {
20197
+ this.log.info(`Skipping creation of a stream due to lock for peerId=${peerId} multicodec=${this.multicodec}`);
20198
+ return;
20808
20199
  }
20809
20200
  try {
20810
- return await connection.newStream(this.multicodec);
20201
+ this.ongoingCreation.add(peerId);
20202
+ await this.createStream(peer);
20811
20203
  }
20812
20204
  catch (error) {
20813
- if (retries < MAX_RETRIES) {
20814
- const backoff = RETRY_BACKOFF_BASE * Math.pow(2, retries);
20815
- await new Promise((resolve) => setTimeout(resolve, backoff));
20816
- return this.createStream(peer, retries + 1);
20817
- }
20818
- throw new Error(`Failed to create a new stream for ${peer.id.toString()} -- ` + error);
20205
+ this.log.error(`Failed to createStreamWithLock:`, error);
20819
20206
  }
20820
- }
20821
- prepareStream(peer) {
20822
- const timeoutPromise = new Promise((resolve) => setTimeout(resolve, CONNECTION_TIMEOUT));
20823
- const streamPromise = Promise.race([
20824
- this.createStream(peer),
20825
- timeoutPromise.then(() => {
20826
- throw new Error("Connection timeout");
20827
- })
20828
- ]).catch((error) => {
20829
- this.log.error(`Failed to prepare a new stream for ${peer.id.toString()} -- `, error);
20830
- });
20831
- this.streamPool.set(peer.id.toString(), streamPromise);
20207
+ finally {
20208
+ this.ongoingCreation.delete(peerId);
20209
+ }
20210
+ return;
20832
20211
  }
20833
20212
  handlePeerUpdateStreamPool = (evt) => {
20834
20213
  const { peer } = evt.detail;
20835
- if (peer.protocols.includes(this.multicodec)) {
20836
- const isConnected = this.isConnectedTo(peer.id);
20837
- if (isConnected) {
20838
- this.log.info(`Preemptively opening a stream to ${peer.id.toString()}`);
20839
- this.prepareStream(peer);
20840
- }
20841
- else {
20842
- const peerIdStr = peer.id.toString();
20843
- this.streamPool.delete(peerIdStr);
20844
- this.log.info(`Removed pending stream for disconnected peer ${peerIdStr}`);
20845
- }
20214
+ if (!peer.protocols.includes(this.multicodec)) {
20215
+ return;
20216
+ }
20217
+ const stream = this.getOpenStreamForCodec(peer.id);
20218
+ if (stream) {
20219
+ return;
20846
20220
  }
20221
+ this.scheduleNewStream(peer);
20847
20222
  };
20848
- isConnectedTo(peerId) {
20223
+ scheduleNewStream(peer) {
20224
+ this.log.info(`Scheduling creation of a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20225
+ // abandon previous attempt
20226
+ if (this.streamPool.has(peer.id.toString())) {
20227
+ this.streamPool.delete(peer.id.toString());
20228
+ }
20229
+ this.streamPool.set(peer.id.toString(), this.createStreamWithLock(peer));
20230
+ }
20231
+ getOpenStreamForCodec(peerId) {
20849
20232
  const connections = this.getConnections(peerId);
20850
- return connections.some((connection) => connection.status === "open");
20233
+ const connection = selectOpenConnection(connections);
20234
+ if (!connection) {
20235
+ return;
20236
+ }
20237
+ const stream = connection.streams.find((s) => s.protocol === this.multicodec);
20238
+ if (!stream) {
20239
+ return;
20240
+ }
20241
+ const isStreamUnusable = ["done", "closed", "closing"].includes(stream.writeStatus || "");
20242
+ if (isStreamUnusable || this.isStreamLocked(stream)) {
20243
+ return;
20244
+ }
20245
+ return stream;
20246
+ }
20247
+ lockStream(peerId, stream) {
20248
+ this.log.info(`Locking stream for peerId:${peerId}\tstreamId:${stream.id}`);
20249
+ stream.metadata[STREAM_LOCK_KEY] = true;
20250
+ }
20251
+ isStreamLocked(stream) {
20252
+ return !!stream.metadata[STREAM_LOCK_KEY];
20851
20253
  }
20852
20254
  }
20853
20255
 
@@ -20875,7 +20277,6 @@ class BaseProtocol {
20875
20277
  async getStream(peer) {
20876
20278
  return this.streamManager.getStream(peer);
20877
20279
  }
20878
- //TODO: move to SDK
20879
20280
  /**
20880
20281
  * Returns known peers from the address book (`libp2p.peerStore`) that support
20881
20282
  * the class protocol. Waku may or may not be currently connected to these
@@ -20884,13 +20285,10 @@ class BaseProtocol {
20884
20285
  async allPeers() {
20885
20286
  return getPeersForProtocol(this.components.peerStore, [this.multicodec]);
20886
20287
  }
20887
- async connectedPeers(withOpenStreams = false) {
20288
+ async connectedPeers() {
20888
20289
  const peers = await this.allPeers();
20889
20290
  return peers.filter((peer) => {
20890
20291
  const connections = this.components.connectionManager.getConnections(peer.id);
20891
- if (withOpenStreams) {
20892
- return connections.some((c) => c.streams.some((s) => s.protocol === this.multicodec));
20893
- }
20894
20292
  return connections.length > 0;
20895
20293
  });
20896
20294
  }
@@ -24844,50 +24242,210 @@ function wakuPeerExchangeDiscovery(pubsubTopics) {
24844
24242
  /**
24845
24243
  * @packageDocumentation
24846
24244
  *
24847
- * Generate, import, and export PeerIDs.
24848
- *
24849
- * A Peer ID is the SHA-256 [multihash](https://github.com/multiformats/multihash) of a public key.
24850
- *
24851
- * The public key is a base64 encoded string of a protobuf containing an RSA DER buffer. This uses a node buffer to pass the base64 encoded public key protobuf to the multihash for ID generation.
24245
+ * An implementation of a peer id
24852
24246
  *
24853
24247
  * @example
24854
24248
  *
24855
24249
  * ```TypeScript
24856
- * import { createEd25519PeerId } from '@libp2p/peer-id-factory'
24857
- *
24858
- * const peerId = await createEd25519PeerId()
24859
- * console.log(peerId.toString())
24860
- * ```
24250
+ * import { peerIdFromString } from '@libp2p/peer-id'
24251
+ * const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
24861
24252
  *
24862
- * ```bash
24863
- * 12D3KooWRm8J3iL796zPFi2EtGGtUJn58AG67gcqzMFHZnnsTzqD
24253
+ * console.log(peer.toCID()) // CID(bafzaa...)
24254
+ * console.log(peer.toString()) // "12D3K..."
24864
24255
  * ```
24865
24256
  */
24866
- async function createFromPubKey(publicKey) {
24867
- return peerIdFromKeys(marshalPublicKey(publicKey));
24257
+ const inspect = Symbol.for('nodejs.util.inspect.custom');
24258
+ // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
24259
+ const LIBP2P_KEY_CODE = 0x72;
24260
+ class PeerIdImpl {
24261
+ type;
24262
+ multihash;
24263
+ publicKey;
24264
+ string;
24265
+ constructor(init) {
24266
+ this.type = init.type;
24267
+ this.multihash = init.multihash;
24268
+ // mark string cache as non-enumerable
24269
+ Object.defineProperty(this, 'string', {
24270
+ enumerable: false,
24271
+ writable: true
24272
+ });
24273
+ }
24274
+ get [Symbol.toStringTag]() {
24275
+ return `PeerId(${this.toString()})`;
24276
+ }
24277
+ [peerIdSymbol$1] = true;
24278
+ toString() {
24279
+ if (this.string == null) {
24280
+ this.string = base58btc.encode(this.multihash.bytes).slice(1);
24281
+ }
24282
+ return this.string;
24283
+ }
24284
+ toMultihash() {
24285
+ return this.multihash;
24286
+ }
24287
+ // return self-describing String representation
24288
+ // in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
24289
+ toCID() {
24290
+ return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
24291
+ }
24292
+ toJSON() {
24293
+ return this.toString();
24294
+ }
24295
+ /**
24296
+ * Checks the equality of `this` peer against a given PeerId
24297
+ */
24298
+ equals(id) {
24299
+ if (id == null) {
24300
+ return false;
24301
+ }
24302
+ if (id instanceof Uint8Array) {
24303
+ return equals(this.multihash.bytes, id);
24304
+ }
24305
+ else if (typeof id === 'string') {
24306
+ return this.toString() === id;
24307
+ }
24308
+ else if (id?.toMultihash()?.bytes != null) {
24309
+ return equals(this.multihash.bytes, id.toMultihash().bytes);
24310
+ }
24311
+ else {
24312
+ throw new Error('not valid Id');
24313
+ }
24314
+ }
24315
+ /**
24316
+ * Returns PeerId as a human-readable string
24317
+ * https://nodejs.org/api/util.html#utilinspectcustom
24318
+ *
24319
+ * @example
24320
+ * ```TypeScript
24321
+ * import { peerIdFromString } from '@libp2p/peer-id'
24322
+ *
24323
+ * console.info(peerIdFromString('QmFoo'))
24324
+ * // 'PeerId(QmFoo)'
24325
+ * ```
24326
+ */
24327
+ [inspect]() {
24328
+ return `PeerId(${this.toString()})`;
24329
+ }
24330
+ }
24331
+ class RSAPeerId extends PeerIdImpl {
24332
+ type = 'RSA';
24333
+ publicKey;
24334
+ constructor(init) {
24335
+ super({ ...init, type: 'RSA' });
24336
+ this.publicKey = init.publicKey;
24337
+ }
24338
+ }
24339
+ class Ed25519PeerId extends PeerIdImpl {
24340
+ type = 'Ed25519';
24341
+ publicKey;
24342
+ constructor(init) {
24343
+ super({ ...init, type: 'Ed25519' });
24344
+ this.publicKey = init.publicKey;
24345
+ }
24868
24346
  }
24869
- async function createFromPrivKey(privateKey) {
24870
- return peerIdFromKeys(marshalPublicKey(privateKey.public), marshalPrivateKey(privateKey));
24347
+ class Secp256k1PeerId extends PeerIdImpl {
24348
+ type = 'secp256k1';
24349
+ publicKey;
24350
+ constructor(init) {
24351
+ super({ ...init, type: 'secp256k1' });
24352
+ this.publicKey = init.publicKey;
24353
+ }
24871
24354
  }
24872
- async function createFromJSON(obj) {
24873
- return createFromParts(fromString(obj.id, 'base58btc'), obj.privKey != null ? fromString(obj.privKey, 'base64pad') : undefined, obj.pubKey != null ? fromString(obj.pubKey, 'base64pad') : undefined);
24355
+ // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
24356
+ const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
24357
+ class URLPeerId {
24358
+ type = 'url';
24359
+ multihash;
24360
+ publicKey;
24361
+ url;
24362
+ constructor(url) {
24363
+ this.url = url.toString();
24364
+ this.multihash = identity.digest(fromString(this.url));
24365
+ }
24366
+ [inspect]() {
24367
+ return `PeerId(${this.url})`;
24368
+ }
24369
+ [peerIdSymbol$1] = true;
24370
+ toString() {
24371
+ return this.toCID().toString();
24372
+ }
24373
+ toMultihash() {
24374
+ return this.multihash;
24375
+ }
24376
+ toCID() {
24377
+ return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.toMultihash());
24378
+ }
24379
+ toJSON() {
24380
+ return this.toString();
24381
+ }
24382
+ equals(other) {
24383
+ if (other == null) {
24384
+ return false;
24385
+ }
24386
+ if (other instanceof Uint8Array) {
24387
+ other = toString$6(other);
24388
+ }
24389
+ return other.toString() === this.toString();
24390
+ }
24874
24391
  }
24875
- async function createFromParts(multihash, privKey, pubKey) {
24876
- if (privKey != null) {
24877
- const key = await unmarshalPrivateKey(privKey);
24878
- return createFromPrivKey(key);
24392
+
24393
+ /**
24394
+ * @packageDocumentation
24395
+ *
24396
+ * An implementation of a peer id
24397
+ *
24398
+ * @example
24399
+ *
24400
+ * ```TypeScript
24401
+ * import { peerIdFromString } from '@libp2p/peer-id'
24402
+ * const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
24403
+ *
24404
+ * console.log(peer.toCID()) // CID(bafzaa...)
24405
+ * console.log(peer.toString()) // "12D3K..."
24406
+ * ```
24407
+ */
24408
+ function peerIdFromString(str, decoder) {
24409
+ let multihash;
24410
+ if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
24411
+ // identity hash ed25519/secp256k1 key or sha2-256 hash of
24412
+ // rsa public key - base58btc encoded either way
24413
+ multihash = decode$6(base58btc.decode(`z${str}`));
24414
+ }
24415
+ else {
24416
+ {
24417
+ throw new InvalidParametersError$1('Please pass a multibase decoder for strings that do not start with "1" or "Q"');
24418
+ }
24879
24419
  }
24880
- else if (pubKey != null) {
24881
- const key = unmarshalPublicKey(pubKey);
24882
- return createFromPubKey(key);
24420
+ return peerIdFromMultihash(multihash);
24421
+ }
24422
+ function peerIdFromMultihash(multihash) {
24423
+ if (isSha256Multihash(multihash)) {
24424
+ return new RSAPeerId({ multihash });
24883
24425
  }
24884
- const peerId = peerIdFromBytes(multihash);
24885
- if (peerId.type !== 'Ed25519' && peerId.type !== 'secp256k1' && peerId.type !== 'RSA') {
24886
- // should not be possible since `multihash` is derived from keys and these
24887
- // are the cryptographic peer id types
24888
- throw new Error('Supplied PeerID is invalid');
24426
+ else if (isIdentityMultihash(multihash)) {
24427
+ try {
24428
+ const publicKey = publicKeyFromMultihash(multihash);
24429
+ if (publicKey.type === 'Ed25519') {
24430
+ return new Ed25519PeerId({ multihash, publicKey });
24431
+ }
24432
+ else if (publicKey.type === 'secp256k1') {
24433
+ return new Secp256k1PeerId({ multihash, publicKey });
24434
+ }
24435
+ }
24436
+ catch (err) {
24437
+ // was not Ed or secp key, try URL
24438
+ const url = toString$6(multihash.digest);
24439
+ return new URLPeerId(new URL(url));
24440
+ }
24889
24441
  }
24890
- return peerId;
24442
+ throw new InvalidMultihashError('Supplied PeerID Multihash is invalid');
24443
+ }
24444
+ function isIdentityMultihash(multihash) {
24445
+ return multihash.code === identity.code;
24446
+ }
24447
+ function isSha256Multihash(multihash) {
24448
+ return multihash.code === sha256.code;
24891
24449
  }
24892
24450
 
24893
24451
  const log = new Logger$1("peer-exchange-discovery");
@@ -24915,7 +24473,7 @@ class LocalPeerCacheDiscovery extends TypedEventEmitter {
24915
24473
  log.info("Starting Local Storage Discovery");
24916
24474
  this.components.events.addEventListener("peer:identify", this.handleNewPeers);
24917
24475
  for (const { id: idStr, address } of this.peers) {
24918
- const peerId = await createFromJSON({ id: idStr });
24476
+ const peerId = peerIdFromString(idStr);
24919
24477
  if (await this.components.peerStore.has(peerId))
24920
24478
  continue;
24921
24479
  await this.components.peerStore.save(peerId, {