@waku/discovery 0.0.4-88a29c3.0 → 0.0.4-c33844e.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
@@ -26,7 +26,7 @@ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
26
26
  * usually in response to the `abort` event being emitted by an
27
27
  * AbortSignal.
28
28
  */
29
- let CodeError$1 = class CodeError extends Error {
29
+ class CodeError extends Error {
30
30
  code;
31
31
  props;
32
32
  constructor(message, code, props) {
@@ -35,7 +35,7 @@ let CodeError$1 = class CodeError extends Error {
35
35
  this.name = props?.name ?? 'CodeError';
36
36
  this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
37
37
  }
38
- };
38
+ }
39
39
  class AggregateCodeError extends AggregateError {
40
40
  code;
41
41
  props;
@@ -590,11 +590,6 @@ var EConnectionStateEvents;
590
590
  EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
591
591
  })(EConnectionStateEvents || (EConnectionStateEvents = {}));
592
592
 
593
- /**
594
- * The default cluster ID for The Waku Network
595
- */
596
- const DEFAULT_CLUSTER_ID = 1;
597
-
598
593
  var HealthStatus;
599
594
  (function (HealthStatus) {
600
595
  HealthStatus["Unhealthy"] = "Unhealthy";
@@ -1911,41 +1906,7 @@ const bytesToUtf8 = (b) => toString$6(b, "utf8");
1911
1906
  * Encode utf-8 string to byte array.
1912
1907
  */
1913
1908
  const utf8ToBytes$1 = (s) => fromString(s, "utf8");
1914
- /**
1915
- * Concatenate using Uint8Arrays as `Buffer` has a different behavior with `DataView`
1916
- */
1917
- function concat$2(byteArrays, totalLength) {
1918
- const len = totalLength ?? byteArrays.reduce((acc, curr) => acc + curr.length, 0);
1919
- const res = new Uint8Array(len);
1920
- let offset = 0;
1921
- for (const bytes of byteArrays) {
1922
- res.set(bytes, offset);
1923
- offset += bytes.length;
1924
- }
1925
- return res;
1926
- }
1927
1909
 
1928
- const shardInfoToPubsubTopics = (shardInfo) => {
1929
- if ("contentTopics" in shardInfo && shardInfo.contentTopics) {
1930
- // Autosharding: explicitly defined content topics
1931
- return Array.from(new Set(shardInfo.contentTopics.map((contentTopic) => contentTopicToPubsubTopic(contentTopic, shardInfo.clusterId))));
1932
- }
1933
- else if ("shards" in shardInfo) {
1934
- // Static sharding
1935
- if (shardInfo.shards === undefined)
1936
- throw new Error("Invalid shard");
1937
- return Array.from(new Set(shardInfo.shards.map((index) => `/waku/2/rs/${shardInfo.clusterId ?? DEFAULT_CLUSTER_ID}/${index}`)));
1938
- }
1939
- else if ("application" in shardInfo && "version" in shardInfo) {
1940
- // Autosharding: single shard from application and version
1941
- return [
1942
- contentTopicToPubsubTopic(`/${shardInfo.application}/${shardInfo.version}/default/default`, shardInfo.clusterId)
1943
- ];
1944
- }
1945
- else {
1946
- throw new Error("Missing required configuration in shard parameters");
1947
- }
1948
- };
1949
1910
  const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
1950
1911
  const parts = pubsubTopics.split("/");
1951
1912
  if (parts.length != 6 ||
@@ -1962,112 +1923,26 @@ const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
1962
1923
  shard
1963
1924
  };
1964
1925
  };
1965
- /**
1966
- * Given a string, will throw an error if it is not formatted as a valid content topic for autosharding based on https://rfc.vac.dev/spec/51/
1967
- * @param contentTopic String to validate
1968
- * @returns Object with each content topic field as an attribute
1969
- */
1970
- function ensureValidContentTopic(contentTopic) {
1971
- const parts = contentTopic.split("/");
1972
- if (parts.length < 5 || parts.length > 6) {
1973
- throw Error("Content topic format is invalid");
1974
- }
1975
- // Validate generation field if present
1976
- let generation = 0;
1977
- if (parts.length == 6) {
1978
- generation = parseInt(parts[1]);
1979
- if (isNaN(generation)) {
1980
- throw new Error("Invalid generation field in content topic");
1981
- }
1982
- if (generation > 0) {
1983
- throw new Error("Generation greater than 0 is not supported");
1984
- }
1985
- }
1986
- // Validate remaining fields
1987
- const fields = parts.splice(-4);
1988
- // Validate application field
1989
- if (fields[0].length == 0) {
1990
- throw new Error("Application field cannot be empty");
1991
- }
1992
- // Validate version field
1993
- if (fields[1].length == 0) {
1994
- throw new Error("Version field cannot be empty");
1995
- }
1996
- // Validate topic name field
1997
- if (fields[2].length == 0) {
1998
- throw new Error("Topic name field cannot be empty");
1999
- }
2000
- // Validate encoding field
2001
- if (fields[3].length == 0) {
2002
- throw new Error("Encoding field cannot be empty");
2003
- }
1926
+ const pubsubTopicsToShardInfo = (pubsubTopics) => {
1927
+ const shardInfoSet = new Set();
1928
+ const clusterIds = new Set();
1929
+ for (const topic of pubsubTopics) {
1930
+ const { clusterId, shard } = pubsubTopicToSingleShardInfo(topic);
1931
+ shardInfoSet.add(`${clusterId}:${shard}`);
1932
+ clusterIds.add(clusterId);
1933
+ }
1934
+ if (shardInfoSet.size === 0) {
1935
+ throw new Error("No valid pubsub topics provided");
1936
+ }
1937
+ if (clusterIds.size > 1) {
1938
+ throw new Error("Pubsub topics from multiple cluster IDs are not supported");
1939
+ }
1940
+ const clusterId = clusterIds.values().next().value;
1941
+ const shards = Array.from(shardInfoSet).map((info) => parseInt(info.split(":")[1]));
2004
1942
  return {
2005
- generation,
2006
- application: fields[0],
2007
- version: fields[1],
2008
- topicName: fields[2],
2009
- encoding: fields[3]
1943
+ clusterId,
1944
+ shards
2010
1945
  };
2011
- }
2012
- /**
2013
- * Given a string, determines which autoshard index to use for its pubsub topic.
2014
- * Based on the algorithm described in the RFC: https://rfc.vac.dev/spec/51//#algorithm
2015
- */
2016
- function contentTopicToShardIndex(contentTopic, networkShards = 8) {
2017
- const { application, version } = ensureValidContentTopic(contentTopic);
2018
- const digest = sha256$1(concat$2([utf8ToBytes$1(application), utf8ToBytes$1(version)]));
2019
- const dataview = new DataView(digest.buffer.slice(-8));
2020
- return Number(dataview.getBigUint64(0, false) % BigInt(networkShards));
2021
- }
2022
- function contentTopicToPubsubTopic(contentTopic, clusterId = DEFAULT_CLUSTER_ID, networkShards = 8) {
2023
- if (!contentTopic) {
2024
- throw Error("Content topic must be specified");
2025
- }
2026
- const shardIndex = contentTopicToShardIndex(contentTopic, networkShards);
2027
- return `/waku/2/rs/${clusterId}/${shardIndex}`;
2028
- }
2029
- /**
2030
- * Validates sharding configuration and sets defaults where possible.
2031
- * @returns Validated sharding parameters, with any missing values set to defaults
2032
- */
2033
- const ensureShardingConfigured = (shardInfo) => {
2034
- const clusterId = shardInfo.clusterId ?? DEFAULT_CLUSTER_ID;
2035
- const shards = "shards" in shardInfo ? shardInfo.shards : [];
2036
- const contentTopics = "contentTopics" in shardInfo ? shardInfo.contentTopics : [];
2037
- const [application, version] = "application" in shardInfo && "version" in shardInfo
2038
- ? [shardInfo.application, shardInfo.version]
2039
- : [undefined, undefined];
2040
- const isShardsConfigured = shards && shards.length > 0;
2041
- const isContentTopicsConfigured = contentTopics && contentTopics.length > 0;
2042
- const isApplicationVersionConfigured = application && version;
2043
- if (isShardsConfigured) {
2044
- return {
2045
- shardingParams: { clusterId, shards },
2046
- shardInfo: { clusterId, shards },
2047
- pubsubTopics: shardInfoToPubsubTopics({ clusterId, shards })
2048
- };
2049
- }
2050
- if (isContentTopicsConfigured) {
2051
- const pubsubTopics = Array.from(new Set(contentTopics.map((topic) => contentTopicToPubsubTopic(topic, clusterId))));
2052
- const shards = Array.from(new Set(contentTopics.map((topic) => contentTopicToShardIndex(topic))));
2053
- return {
2054
- shardingParams: { clusterId, contentTopics },
2055
- shardInfo: { clusterId, shards },
2056
- pubsubTopics
2057
- };
2058
- }
2059
- if (isApplicationVersionConfigured) {
2060
- const pubsubTopic = contentTopicToPubsubTopic(`/${application}/${version}/default/default`, clusterId);
2061
- return {
2062
- shardingParams: { clusterId, application, version },
2063
- shardInfo: {
2064
- clusterId,
2065
- shards: [pubsubTopicToSingleShardInfo(pubsubTopic).shard]
2066
- },
2067
- pubsubTopics: [pubsubTopic]
2068
- };
2069
- }
2070
- throw new Error("Missing minimum required configuration options for static sharding or autosharding.");
2071
1946
  };
2072
1947
 
2073
1948
  const decodeRelayShard = (bytes) => {
@@ -2713,6 +2588,8 @@ var common = setup;
2713
2588
  return false;
2714
2589
  }
2715
2590
 
2591
+ let m;
2592
+
2716
2593
  // Is webkit? http://stackoverflow.com/a/16459606/376773
2717
2594
  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
2718
2595
  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
@@ -2720,7 +2597,7 @@ var common = setup;
2720
2597
  (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
2721
2598
  // Is firefox >= v31?
2722
2599
  // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
2723
- (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
2600
+ (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
2724
2601
  // Double check webkit in userAgent just in case we are in a worker
2725
2602
  (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
2726
2603
  }
@@ -2923,7 +2800,7 @@ const _0n$5 = BigInt(0);
2923
2800
  const _1n$7 = BigInt(1);
2924
2801
  const _2n$5 = BigInt(2);
2925
2802
  const _3n$2 = BigInt(3);
2926
- const _8n$2 = BigInt(8);
2803
+ const _8n$3 = BigInt(8);
2927
2804
  const CURVE = Object.freeze({
2928
2805
  a: _0n$5,
2929
2806
  b: BigInt(7),
@@ -3027,7 +2904,7 @@ class JacobianPoint {
3027
2904
  const E = mod$1(_3n$2 * A);
3028
2905
  const F = mod$1(E * E);
3029
2906
  const X3 = mod$1(F - _2n$5 * D);
3030
- const Y3 = mod$1(E * (D - X3) - _8n$2 * C);
2907
+ const Y3 = mod$1(E * (D - X3) - _8n$3 * C);
3031
2908
  const Z3 = mod$1(_2n$5 * Y1 * Z1);
3032
2909
  return new JacobianPoint(X3, Y3, Z3);
3033
2910
  }
@@ -3127,12 +3004,12 @@ class JacobianPoint {
3127
3004
  if (256 % W) {
3128
3005
  throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
3129
3006
  }
3130
- let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
3007
+ let precomputes = affinePoint && pointPrecomputes$1.get(affinePoint);
3131
3008
  if (!precomputes) {
3132
3009
  precomputes = this.precomputeWindow(W);
3133
3010
  if (affinePoint && W !== 1) {
3134
3011
  precomputes = JacobianPoint.normalizeZ(precomputes);
3135
- pointPrecomputes.set(affinePoint, precomputes);
3012
+ pointPrecomputes$1.set(affinePoint, precomputes);
3136
3013
  }
3137
3014
  }
3138
3015
  let p = JacobianPoint.ZERO;
@@ -3188,7 +3065,7 @@ class JacobianPoint {
3188
3065
  const { x, y, z } = this;
3189
3066
  const is0 = this.equals(JacobianPoint.ZERO);
3190
3067
  if (invZ == null)
3191
- invZ = is0 ? _8n$2 : invert$1(z);
3068
+ invZ = is0 ? _8n$3 : invert$1(z);
3192
3069
  const iz1 = invZ;
3193
3070
  const iz2 = mod$1(iz1 * iz1);
3194
3071
  const iz3 = mod$1(iz2 * iz1);
@@ -3208,7 +3085,7 @@ function constTimeNegate(condition, item) {
3208
3085
  const neg = item.negate();
3209
3086
  return condition ? neg : item;
3210
3087
  }
3211
- const pointPrecomputes = new WeakMap();
3088
+ const pointPrecomputes$1 = new WeakMap();
3212
3089
  class Point {
3213
3090
  constructor(x, y) {
3214
3091
  this.x = x;
@@ -3216,7 +3093,7 @@ class Point {
3216
3093
  }
3217
3094
  _setWindowSize(windowSize) {
3218
3095
  this._WINDOW_SIZE = windowSize;
3219
- pointPrecomputes.delete(this);
3096
+ pointPrecomputes$1.delete(this);
3220
3097
  }
3221
3098
  hasEvenY() {
3222
3099
  return this.y % _2n$5 === _0n$5;
@@ -5274,6 +5151,7 @@ const table = [
5274
5151
  [478, 0, 'wss'],
5275
5152
  [479, 0, 'p2p-websocket-star'],
5276
5153
  [480, 0, 'http'],
5154
+ [481, V, 'http-path'],
5277
5155
  [777, V, 'memory']
5278
5156
  ];
5279
5157
  // populate tables
@@ -5359,6 +5237,8 @@ function convertToString(proto, buf) {
5359
5237
  return bytes2onion(buf);
5360
5238
  case 466: // certhash
5361
5239
  return bytes2mb(buf);
5240
+ case 481: // http-path
5241
+ return globalThis.encodeURIComponent(bytes2str(buf));
5362
5242
  default:
5363
5243
  return toString$6(buf, 'base16'); // no clue. convert to hex
5364
5244
  }
@@ -5393,6 +5273,8 @@ function convertToBytes(proto, str) {
5393
5273
  return onion32bytes(str);
5394
5274
  case 466: // certhash
5395
5275
  return mb2bytes(str);
5276
+ case 481: // http-path
5277
+ return str2bytes(globalThis.decodeURIComponent(str));
5396
5278
  default:
5397
5279
  return fromString(str, 'base16'); // no clue. convert from hex
5398
5280
  }
@@ -5854,7 +5736,7 @@ class Multiaddr {
5854
5736
  }
5855
5737
  const resolver = resolvers$1.get(resolvableProto.name);
5856
5738
  if (resolver == null) {
5857
- throw new CodeError$1(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
5739
+ throw new CodeError(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
5858
5740
  }
5859
5741
  const result = await resolver(this, options);
5860
5742
  return result.map(str => multiaddr(str));
@@ -6297,9 +6179,9 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
6297
6179
  // This is OK: `abstract` directory does not use noble-hashes.
6298
6180
  // User may opt-in into using different hashing library. This way, noble-hashes
6299
6181
  // won't be included into their bundle.
6300
- const _0n$4 = BigInt(0);
6301
- const _1n$6 = BigInt(1);
6302
- const _2n$4 = BigInt(2);
6182
+ const _0n$4 = /* @__PURE__ */ BigInt(0);
6183
+ const _1n$6 = /* @__PURE__ */ BigInt(1);
6184
+ const _2n$4 = /* @__PURE__ */ BigInt(2);
6303
6185
  function isBytes$1(a) {
6304
6186
  return (a instanceof Uint8Array ||
6305
6187
  (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
@@ -6308,6 +6190,10 @@ function abytes(item) {
6308
6190
  if (!isBytes$1(item))
6309
6191
  throw new Error('Uint8Array expected');
6310
6192
  }
6193
+ function abool(title, value) {
6194
+ if (typeof value !== 'boolean')
6195
+ throw new Error(`${title} must be valid boolean, got "${value}".`);
6196
+ }
6311
6197
  // Array where index 0xf0 (240) is mapped to string 'f0'
6312
6198
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
6313
6199
  /**
@@ -6450,6 +6336,25 @@ function utf8ToBytes(str) {
6450
6336
  throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
6451
6337
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
6452
6338
  }
6339
+ // Is positive bigint
6340
+ const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
6341
+ function inRange(n, min, max) {
6342
+ return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
6343
+ }
6344
+ /**
6345
+ * Asserts min <= n < max. NOTE: It's < max and not <= max.
6346
+ * @example
6347
+ * aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)
6348
+ */
6349
+ function aInRange(title, n, min, max) {
6350
+ // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?
6351
+ // consider P=256n, min=0n, max=P
6352
+ // - a for min=0 would require -1: `inRange('x', x, -1n, P)`
6353
+ // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
6354
+ // - our way is the cleanest: `inRange('x', x, 0n, P)
6355
+ if (!inRange(n, min, max))
6356
+ throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
6357
+ }
6453
6358
  // Bit operations
6454
6359
  /**
6455
6360
  * Calculates amount of bits in a bigint.
@@ -6580,9 +6485,32 @@ function validateObject(object, validators, optValidators = {}) {
6580
6485
  // const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
6581
6486
  // const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
6582
6487
  // const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
6488
+ /**
6489
+ * throws not implemented error
6490
+ */
6491
+ const notImplemented = () => {
6492
+ throw new Error('not implemented');
6493
+ };
6494
+ /**
6495
+ * Memoizes (caches) computation result.
6496
+ * Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
6497
+ */
6498
+ function memoized(fn) {
6499
+ const map = new WeakMap();
6500
+ return (arg, ...args) => {
6501
+ const val = map.get(arg);
6502
+ if (val !== undefined)
6503
+ return val;
6504
+ const computed = fn(arg, ...args);
6505
+ map.set(arg, computed);
6506
+ return computed;
6507
+ };
6508
+ }
6583
6509
 
6584
6510
  var ut = /*#__PURE__*/Object.freeze({
6585
6511
  __proto__: null,
6512
+ aInRange: aInRange,
6513
+ abool: abool,
6586
6514
  abytes: abytes,
6587
6515
  bitGet: bitGet,
6588
6516
  bitLen: bitLen,
@@ -6597,7 +6525,10 @@ var ut = /*#__PURE__*/Object.freeze({
6597
6525
  equalBytes: equalBytes,
6598
6526
  hexToBytes: hexToBytes,
6599
6527
  hexToNumber: hexToNumber,
6528
+ inRange: inRange,
6600
6529
  isBytes: isBytes$1,
6530
+ memoized: memoized,
6531
+ notImplemented: notImplemented,
6601
6532
  numberToBytesBE: numberToBytesBE,
6602
6533
  numberToBytesLE: numberToBytesLE,
6603
6534
  numberToHexUnpadded: numberToHexUnpadded,
@@ -6611,7 +6542,7 @@ var ut = /*#__PURE__*/Object.freeze({
6611
6542
  // prettier-ignore
6612
6543
  const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
6613
6544
  // prettier-ignore
6614
- const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$1 = BigInt(8);
6545
+ const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
6615
6546
  // prettier-ignore
6616
6547
  BigInt(9); BigInt(16);
6617
6548
  // Calculates a modulo b
@@ -6757,8 +6688,8 @@ function FpSqrt(P) {
6757
6688
  };
6758
6689
  }
6759
6690
  // Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
6760
- if (P % _8n$1 === _5n$1) {
6761
- const c1 = (P - _5n$1) / _8n$1;
6691
+ if (P % _8n$2 === _5n$1) {
6692
+ const c1 = (P - _5n$1) / _8n$2;
6762
6693
  return function sqrt5mod8(Fp, n) {
6763
6694
  const n2 = Fp.mul(n, _2n$3);
6764
6695
  const v = Fp.pow(n2, c1);
@@ -6856,6 +6787,9 @@ function nLength(n, nBitLength) {
6856
6787
  * * a) denormalized operations like mulN instead of mul
6857
6788
  * * b) same object shape: never add or remove keys
6858
6789
  * * c) Object.freeze
6790
+ * NOTE: operations don't check 'isValid' for all elements for performance reasons,
6791
+ * it is caller responsibility to check this.
6792
+ * This is low-level code, please make sure you know what you doing.
6859
6793
  * @param ORDER prime positive bigint
6860
6794
  * @param bitLen how many bits the field consumes
6861
6795
  * @param isLE (def: false) if encoding / decoding should be in little-endian
@@ -6911,12 +6845,6 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6911
6845
  });
6912
6846
  return Object.freeze(f);
6913
6847
  }
6914
- function FpSqrtEven(Fp, elm) {
6915
- if (!Fp.isOdd)
6916
- throw new Error(`Field doesn't have isOdd`);
6917
- const root = Fp.sqrt(elm);
6918
- return Fp.isOdd(root) ? Fp.neg(root) : root;
6919
- }
6920
6848
  /**
6921
6849
  * Returns total number of bytes consumed by the field element.
6922
6850
  * For example, 32 bytes for usual 256-bit weierstrass curve.
@@ -6970,6 +6898,10 @@ function mapHashToField(key, fieldOrder, isLE = false) {
6970
6898
  // Abelian group utilities
6971
6899
  const _0n$2 = BigInt(0);
6972
6900
  const _1n$4 = BigInt(1);
6901
+ // Since points in different groups cannot be equal (different object constructor),
6902
+ // we can have single place to store precomputes
6903
+ const pointPrecomputes = new WeakMap();
6904
+ const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
6973
6905
  // Elliptic curve multiplication of Point by scalar. Fragile.
6974
6906
  // Scalars should always be less than curve order: this should be checked inside of a curve itself.
6975
6907
  // Creates precomputation tables for fast multiplication:
@@ -6986,7 +6918,12 @@ function wNAF(c, bits) {
6986
6918
  const neg = item.negate();
6987
6919
  return condition ? neg : item;
6988
6920
  };
6921
+ const validateW = (W) => {
6922
+ if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
6923
+ throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
6924
+ };
6989
6925
  const opts = (W) => {
6926
+ validateW(W);
6990
6927
  const windows = Math.ceil(bits / W) + 1; // +1, because
6991
6928
  const windowSize = 2 ** (W - 1); // -1 because we skip zero
6992
6929
  return { windows, windowSize };
@@ -7086,19 +7023,25 @@ function wNAF(c, bits) {
7086
7023
  // which makes it less const-time: around 1 bigint multiply.
7087
7024
  return { p, f };
7088
7025
  },
7089
- wNAFCached(P, precomputesMap, n, transform) {
7090
- // @ts-ignore
7091
- const W = P._WINDOW_SIZE || 1;
7026
+ wNAFCached(P, n, transform) {
7027
+ const W = pointWindowSizes.get(P) || 1;
7092
7028
  // Calculate precomputes on a first run, reuse them after
7093
- let comp = precomputesMap.get(P);
7029
+ let comp = pointPrecomputes.get(P);
7094
7030
  if (!comp) {
7095
7031
  comp = this.precomputeWindow(P, W);
7096
- if (W !== 1) {
7097
- precomputesMap.set(P, transform(comp));
7098
- }
7032
+ if (W !== 1)
7033
+ pointPrecomputes.set(P, transform(comp));
7099
7034
  }
7100
7035
  return this.wNAF(W, comp, n);
7101
7036
  },
7037
+ // We calculate precomputes for elliptic curve point multiplication
7038
+ // using windowed method. This specifies window size and
7039
+ // stores precomputed values. Usually only base point would be precomputed.
7040
+ setWindowSize(P, W) {
7041
+ validateW(W);
7042
+ pointWindowSizes.set(P, W);
7043
+ pointPrecomputes.delete(P);
7044
+ },
7102
7045
  };
7103
7046
  }
7104
7047
  function validateBasic(curve) {
@@ -7124,7 +7067,7 @@ function validateBasic(curve) {
7124
7067
  // Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
7125
7068
  // Be friendly to bad ECMAScript parsers by not using bigint literals
7126
7069
  // prettier-ignore
7127
- const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n = BigInt(8);
7070
+ const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
7128
7071
  // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
7129
7072
  const VERIFY_DEFAULT = { zip215: true };
7130
7073
  function validateOpts$1(curve) {
@@ -7143,7 +7086,13 @@ function validateOpts$1(curve) {
7143
7086
  // Set defaults
7144
7087
  return Object.freeze({ ...opts });
7145
7088
  }
7146
- // It is not generic twisted curve for now, but ed25519/ed448 generic implementation
7089
+ /**
7090
+ * Creates Twisted Edwards curve with EdDSA signatures.
7091
+ * @example
7092
+ * import { Field } from '@noble/curves/abstract/modular';
7093
+ * // Before that, define BigInt-s: a, d, p, n, Gx, Gy, h
7094
+ * const curve = twistedEdwards({ a, d, Fp: Field(p), n, Gx, Gy, h })
7095
+ */
7147
7096
  function twistedEdwards(curveDef) {
7148
7097
  const CURVE = validateOpts$1(curveDef);
7149
7098
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
@@ -7162,28 +7111,59 @@ function twistedEdwards(curveDef) {
7162
7111
  const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
7163
7112
  const domain = CURVE.domain ||
7164
7113
  ((data, ctx, phflag) => {
7114
+ abool('phflag', phflag);
7165
7115
  if (ctx.length || phflag)
7166
7116
  throw new Error('Contexts/pre-hash are not supported');
7167
7117
  return data;
7168
7118
  }); // NOOP
7169
- const inBig = (n) => typeof n === 'bigint' && _0n$1 < n; // n in [1..]
7170
- const inRange = (n, max) => inBig(n) && inBig(max) && n < max; // n in [1..max-1]
7171
- const in0MaskRange = (n) => n === _0n$1 || inRange(n, MASK); // n in [0..MASK-1]
7172
- function assertInRange(n, max) {
7173
- // n in [1..max-1]
7174
- if (inRange(n, max))
7175
- return n;
7176
- throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
7177
- }
7178
- function assertGE0(n) {
7179
- // n in [0..CURVE_ORDER-1]
7180
- return n === _0n$1 ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
7181
- }
7182
- const pointPrecomputes = new Map();
7183
- function isPoint(other) {
7119
+ // 0 <= n < MASK
7120
+ // Coordinates larger than Fp.ORDER are allowed for zip215
7121
+ function aCoordinate(title, n) {
7122
+ aInRange('coordinate ' + title, n, _0n$1, MASK);
7123
+ }
7124
+ function assertPoint(other) {
7184
7125
  if (!(other instanceof Point))
7185
7126
  throw new Error('ExtendedPoint expected');
7186
7127
  }
7128
+ // Converts Extended point to default (x, y) coordinates.
7129
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
7130
+ const toAffineMemo = memoized((p, iz) => {
7131
+ const { ex: x, ey: y, ez: z } = p;
7132
+ const is0 = p.is0();
7133
+ if (iz == null)
7134
+ iz = is0 ? _8n$1 : Fp.inv(z); // 8 was chosen arbitrarily
7135
+ const ax = modP(x * iz);
7136
+ const ay = modP(y * iz);
7137
+ const zz = modP(z * iz);
7138
+ if (is0)
7139
+ return { x: _0n$1, y: _1n$3 };
7140
+ if (zz !== _1n$3)
7141
+ throw new Error('invZ was invalid');
7142
+ return { x: ax, y: ay };
7143
+ });
7144
+ const assertValidMemo = memoized((p) => {
7145
+ const { a, d } = CURVE;
7146
+ if (p.is0())
7147
+ throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
7148
+ // Equation in affine coordinates: ax² + y² = 1 + dx²y²
7149
+ // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
7150
+ const { ex: X, ey: Y, ez: Z, et: T } = p;
7151
+ const X2 = modP(X * X); // X²
7152
+ const Y2 = modP(Y * Y); // Y²
7153
+ const Z2 = modP(Z * Z); // Z²
7154
+ const Z4 = modP(Z2 * Z2); // Z⁴
7155
+ const aX2 = modP(X2 * a); // aX²
7156
+ const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
7157
+ const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
7158
+ if (left !== right)
7159
+ throw new Error('bad point: equation left != right (1)');
7160
+ // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
7161
+ const XY = modP(X * Y);
7162
+ const ZT = modP(Z * T);
7163
+ if (XY !== ZT)
7164
+ throw new Error('bad point: equation left != right (2)');
7165
+ return true;
7166
+ });
7187
7167
  // Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
7188
7168
  // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
7189
7169
  class Point {
@@ -7192,14 +7172,11 @@ function twistedEdwards(curveDef) {
7192
7172
  this.ey = ey;
7193
7173
  this.ez = ez;
7194
7174
  this.et = et;
7195
- if (!in0MaskRange(ex))
7196
- throw new Error('x required');
7197
- if (!in0MaskRange(ey))
7198
- throw new Error('y required');
7199
- if (!in0MaskRange(ez))
7200
- throw new Error('z required');
7201
- if (!in0MaskRange(et))
7202
- throw new Error('t required');
7175
+ aCoordinate('x', ex);
7176
+ aCoordinate('y', ey);
7177
+ aCoordinate('z', ez);
7178
+ aCoordinate('t', et);
7179
+ Object.freeze(this);
7203
7180
  }
7204
7181
  get x() {
7205
7182
  return this.toAffine().x;
@@ -7211,8 +7188,8 @@ function twistedEdwards(curveDef) {
7211
7188
  if (p instanceof Point)
7212
7189
  throw new Error('extended point not allowed');
7213
7190
  const { x, y } = p || {};
7214
- if (!in0MaskRange(x) || !in0MaskRange(y))
7215
- throw new Error('invalid affine point');
7191
+ aCoordinate('x', x);
7192
+ aCoordinate('y', y);
7216
7193
  return new Point(x, y, _1n$3, modP(x * y));
7217
7194
  }
7218
7195
  static normalizeZ(points) {
@@ -7221,36 +7198,16 @@ function twistedEdwards(curveDef) {
7221
7198
  }
7222
7199
  // "Private method", don't use it directly
7223
7200
  _setWindowSize(windowSize) {
7224
- this._WINDOW_SIZE = windowSize;
7225
- pointPrecomputes.delete(this);
7201
+ wnaf.setWindowSize(this, windowSize);
7226
7202
  }
7227
7203
  // Not required for fromHex(), which always creates valid points.
7228
7204
  // Could be useful for fromAffine().
7229
7205
  assertValidity() {
7230
- const { a, d } = CURVE;
7231
- if (this.is0())
7232
- throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
7233
- // Equation in affine coordinates: ax² + y² = 1 + dx²y²
7234
- // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
7235
- const { ex: X, ey: Y, ez: Z, et: T } = this;
7236
- const X2 = modP(X * X); // X²
7237
- const Y2 = modP(Y * Y); // Y²
7238
- const Z2 = modP(Z * Z); // Z²
7239
- const Z4 = modP(Z2 * Z2); // Z⁴
7240
- const aX2 = modP(X2 * a); // aX²
7241
- const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
7242
- const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
7243
- if (left !== right)
7244
- throw new Error('bad point: equation left != right (1)');
7245
- // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
7246
- const XY = modP(X * Y);
7247
- const ZT = modP(Z * T);
7248
- if (XY !== ZT)
7249
- throw new Error('bad point: equation left != right (2)');
7206
+ assertValidMemo(this);
7250
7207
  }
7251
7208
  // Compare one point to another.
7252
7209
  equals(other) {
7253
- isPoint(other);
7210
+ assertPoint(other);
7254
7211
  const { ex: X1, ey: Y1, ez: Z1 } = this;
7255
7212
  const { ex: X2, ey: Y2, ez: Z2 } = other;
7256
7213
  const X1Z2 = modP(X1 * Z2);
@@ -7291,7 +7248,7 @@ function twistedEdwards(curveDef) {
7291
7248
  // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
7292
7249
  // Cost: 9M + 1*a + 1*d + 7add.
7293
7250
  add(other) {
7294
- isPoint(other);
7251
+ assertPoint(other);
7295
7252
  const { a, d } = CURVE;
7296
7253
  const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
7297
7254
  const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
@@ -7334,11 +7291,13 @@ function twistedEdwards(curveDef) {
7334
7291
  return this.add(other.negate());
7335
7292
  }
7336
7293
  wNAF(n) {
7337
- return wnaf.wNAFCached(this, pointPrecomputes, n, Point.normalizeZ);
7294
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
7338
7295
  }
7339
7296
  // Constant-time multiplication.
7340
7297
  multiply(scalar) {
7341
- const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
7298
+ const n = scalar;
7299
+ aInRange('scalar', n, _1n$3, CURVE_ORDER); // 1 <= scalar < L
7300
+ const { p, f } = this.wNAF(n);
7342
7301
  return Point.normalizeZ([p, f])[0];
7343
7302
  }
7344
7303
  // Non-constant-time multiplication. Uses double-and-add algorithm.
@@ -7346,7 +7305,8 @@ function twistedEdwards(curveDef) {
7346
7305
  // an exposed private key e.g. sig verification.
7347
7306
  // Does NOT allow scalars higher than CURVE.n.
7348
7307
  multiplyUnsafe(scalar) {
7349
- let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
7308
+ const n = scalar;
7309
+ aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
7350
7310
  if (n === _0n$1)
7351
7311
  return I;
7352
7312
  if (this.equals(I) || n === _1n$3)
@@ -7370,18 +7330,7 @@ function twistedEdwards(curveDef) {
7370
7330
  // Converts Extended point to default (x, y) coordinates.
7371
7331
  // Can accept precomputed Z^-1 - for example, from invertBatch.
7372
7332
  toAffine(iz) {
7373
- const { ex: x, ey: y, ez: z } = this;
7374
- const is0 = this.is0();
7375
- if (iz == null)
7376
- iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
7377
- const ax = modP(x * iz);
7378
- const ay = modP(y * iz);
7379
- const zz = modP(z * iz);
7380
- if (is0)
7381
- return { x: _0n$1, y: _1n$3 };
7382
- if (zz !== _1n$3)
7383
- throw new Error('invZ was invalid');
7384
- return { x: ax, y: ay };
7333
+ return toAffineMemo(this, iz);
7385
7334
  }
7386
7335
  clearCofactor() {
7387
7336
  const { h: cofactor } = CURVE;
@@ -7395,18 +7344,16 @@ function twistedEdwards(curveDef) {
7395
7344
  const { d, a } = CURVE;
7396
7345
  const len = Fp.BYTES;
7397
7346
  hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
7347
+ abool('zip215', zip215);
7398
7348
  const normed = hex.slice(); // copy again, we'll manipulate it
7399
7349
  const lastByte = hex[len - 1]; // select last byte
7400
7350
  normed[len - 1] = lastByte & ~0x80; // clear last bit
7401
7351
  const y = bytesToNumberLE(normed);
7402
- if (y === _0n$1) ;
7403
- else {
7404
- // RFC8032 prohibits >= p, but ZIP215 doesn't
7405
- if (zip215)
7406
- assertInRange(y, MASK); // zip215=true [1..P-1] (2^255-19-1 for ed25519)
7407
- else
7408
- assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
7409
- }
7352
+ // RFC8032 prohibits >= p, but ZIP215 doesn't
7353
+ // zip215=true: 0 <= y < MASK (2^256 for ed25519)
7354
+ // zip215=false: 0 <= y < P (2^255-19 for ed25519)
7355
+ const max = zip215 ? MASK : Fp.ORDER;
7356
+ aInRange('pointHex.y', y, _0n$1, max);
7410
7357
  // Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
7411
7358
  // ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
7412
7359
  const y2 = modP(y * y); // denominator is always non-0 mod p.
@@ -7481,7 +7428,7 @@ function twistedEdwards(curveDef) {
7481
7428
  const R = G.multiply(r).toRawBytes(); // R = rG
7482
7429
  const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
7483
7430
  const s = modN(r + k * scalar); // S = (r + k * s) mod L
7484
- assertGE0(s); // 0 <= s < l
7431
+ aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
7485
7432
  const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
7486
7433
  return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
7487
7434
  }
@@ -7491,6 +7438,8 @@ function twistedEdwards(curveDef) {
7491
7438
  const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
7492
7439
  sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
7493
7440
  msg = ensureBytes('message', msg);
7441
+ if (zip215 !== undefined)
7442
+ abool('zip215', zip215);
7494
7443
  if (prehash)
7495
7444
  msg = prehash(msg); // for ed25519ph, etc
7496
7445
  const s = bytesToNumberLE(sig.slice(len, 2 * len));
@@ -7548,12 +7497,14 @@ function twistedEdwards(curveDef) {
7548
7497
  */
7549
7498
  const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
7550
7499
  // √(-1) aka √(a) aka 2^((p-1)/4)
7551
- const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
7500
+ const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
7552
7501
  // prettier-ignore
7553
- BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2), _5n = BigInt(5);
7502
+ BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
7554
7503
  // prettier-ignore
7555
- const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
7504
+ const _5n = BigInt(5), _8n = BigInt(8);
7556
7505
  function ed25519_pow_2_252_3(x) {
7506
+ // prettier-ignore
7507
+ const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
7557
7508
  const P = ED25519_P;
7558
7509
  const x2 = (x * x) % P;
7559
7510
  const b2 = (x2 * x) % P; // x^3, 11
@@ -7602,8 +7553,8 @@ function uvRatio(u, v) {
7602
7553
  x = mod(-x, P);
7603
7554
  return { isValid: useRoot1 || useRoot2, value: x };
7604
7555
  }
7605
- const Fp$1 = Field(ED25519_P, undefined, true);
7606
- const ed25519Defaults = {
7556
+ const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
7557
+ const ed25519Defaults = /* @__PURE__ */ (() => ({
7607
7558
  // Param: a
7608
7559
  a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
7609
7560
  // d is equal to -121665/121666 over finite field.
@@ -7615,7 +7566,7 @@ const ed25519Defaults = {
7615
7566
  // 2n**252n + 27742317777372353535851937790883648493n;
7616
7567
  n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
7617
7568
  // Cofactor
7618
- h: BigInt(8),
7569
+ h: _8n,
7619
7570
  // Base point (x, y) aka generator point
7620
7571
  Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
7621
7572
  Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
@@ -7626,40 +7577,11 @@ const ed25519Defaults = {
7626
7577
  // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
7627
7578
  // Constant-time, u/√v
7628
7579
  uvRatio,
7629
- };
7630
- const ed25519 = /* @__PURE__ */ twistedEdwards(ed25519Defaults);
7631
- function ed25519_domain(data, ctx, phflag) {
7632
- if (ctx.length > 255)
7633
- throw new Error('Context is too big');
7634
- return concatBytes$2(utf8ToBytes$2('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
7635
- }
7636
- /* @__PURE__ */ twistedEdwards({
7637
- ...ed25519Defaults,
7638
- domain: ed25519_domain,
7639
- });
7640
- /* @__PURE__ */ twistedEdwards({
7641
- ...ed25519Defaults,
7642
- domain: ed25519_domain,
7643
- prehash: sha512,
7644
- });
7645
- // Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
7646
- // NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
7647
- // SageMath returns different root first and everything falls apart
7648
- const ELL2_C1 = (Fp$1.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
7649
- Fp$1.pow(_2n$1, ELL2_C1); // 2. c2 = 2^c1
7650
- Fp$1.sqrt(Fp$1.neg(Fp$1.ONE)); // 3. c3 = sqrt(-1)
7651
- (Fp$1.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
7652
- BigInt(486662);
7653
- FpSqrtEven(Fp$1, Fp$1.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
7654
- // √(ad - 1)
7655
- BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
7656
- // 1 / √(a-d)
7657
- BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
7658
- // 1-d²
7659
- BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
7660
- // (d-1)²
7661
- BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
7662
- BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
7580
+ }))();
7581
+ /**
7582
+ * ed25519 curve with EdDSA signatures.
7583
+ */
7584
+ const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
7663
7585
 
7664
7586
  const PUBLIC_KEY_BYTE_LENGTH = 32;
7665
7587
  const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
@@ -7716,7 +7638,7 @@ function concatKeys(privateKeyRaw, publicKey) {
7716
7638
  var webcrypto = {
7717
7639
  get(win = globalThis) {
7718
7640
  const nativeCrypto = win.crypto;
7719
- if (nativeCrypto == null || nativeCrypto.subtle == null) {
7641
+ if (nativeCrypto?.subtle == null) {
7720
7642
  throw Object.assign(new Error('Missing Web Crypto API. ' +
7721
7643
  'The most likely cause of this error is that this page is being accessed ' +
7722
7644
  'from an insecure context (i.e. not HTTPS). For more information and ' +
@@ -7740,12 +7662,12 @@ var webcrypto = {
7740
7662
  const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
7741
7663
  // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
7742
7664
  function create(opts) {
7743
- const algorithm = opts?.algorithm ?? 'AES-GCM';
7744
- let keyLength = opts?.keyLength ?? 16;
7745
- const nonceLength = opts?.nonceLength ?? 12;
7746
- const digest = opts?.digest ?? 'SHA-256';
7747
- const saltLength = opts?.saltLength ?? 16;
7748
- const iterations = opts?.iterations ?? 32767;
7665
+ const algorithm = 'AES-GCM';
7666
+ let keyLength = 16;
7667
+ const nonceLength = 12;
7668
+ const digest = 'SHA-256';
7669
+ const saltLength = 16;
7670
+ const iterations = 32767;
7749
7671
  const crypto = webcrypto.get();
7750
7672
  keyLength *= 8; // Browser crypto uses bits instead of bytes
7751
7673
  /**
@@ -8529,7 +8451,7 @@ function decodeMessage(buf, codec, opts) {
8529
8451
  * A general purpose buffer pool
8530
8452
  */
8531
8453
  function pool(size) {
8532
- const SIZE = size ?? 8192;
8454
+ const SIZE = 8192;
8533
8455
  const MAX = SIZE >>> 1;
8534
8456
  let slab;
8535
8457
  let offset = SIZE;
@@ -9042,12 +8964,17 @@ function message(encode, decode) {
9042
8964
  * npm i protons-runtime
9043
8965
  * ```
9044
8966
  */
9045
- class CodeError extends Error {
9046
- code;
9047
- constructor(message, code, options) {
9048
- super(message, options);
9049
- this.code = code;
9050
- }
8967
+ /**
8968
+ * Thrown when a repeated field has too many elements
8969
+ */
8970
+ class MaxLengthError extends Error {
8971
+ /**
8972
+ * This will be removed in a future release
8973
+ *
8974
+ * @deprecated use the `.name` property instead
8975
+ */
8976
+ code = 'ERR_MAX_LENGTH';
8977
+ name = 'MaxLengthError';
9051
8978
  }
9052
8979
 
9053
8980
  /* eslint-disable import/export */
@@ -9258,7 +9185,7 @@ class Ed25519PrivateKey {
9258
9185
  return exporter(this.bytes, password);
9259
9186
  }
9260
9187
  else {
9261
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
9188
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
9262
9189
  }
9263
9190
  }
9264
9191
  }
@@ -9290,7 +9217,7 @@ async function generateKeyPairFromSeed(seed) {
9290
9217
  function ensureKey(key, length) {
9291
9218
  key = Uint8Array.from(key ?? []);
9292
9219
  if (key.length !== length) {
9293
- throw new CodeError$1(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
9220
+ throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
9294
9221
  }
9295
9222
  return key;
9296
9223
  }
@@ -9310,7 +9237,7 @@ var Ed25519 = /*#__PURE__*/Object.freeze({
9310
9237
  */
9311
9238
  function randomBytes(length) {
9312
9239
  if (isNaN(length) || length <= 0) {
9313
- throw new CodeError$1('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
9240
+ throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
9314
9241
  }
9315
9242
  return randomBytes$1(length);
9316
9243
  }
@@ -12719,7 +12646,7 @@ function pkcs1ToJwk(bytes) {
12719
12646
  */
12720
12647
  function jwkToPkcs1(jwk) {
12721
12648
  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) {
12722
- throw new CodeError$1('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12649
+ throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12723
12650
  }
12724
12651
  const root = new Sequence({
12725
12652
  value: [
@@ -12756,7 +12683,7 @@ function pkixToJwk(bytes) {
12756
12683
  */
12757
12684
  function jwkToPkix(jwk) {
12758
12685
  if (jwk.n == null || jwk.e == null) {
12759
- throw new CodeError$1('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12686
+ throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
12760
12687
  }
12761
12688
  const root = new Sequence({
12762
12689
  value: [
@@ -12968,7 +12895,7 @@ async function hashAndVerify$1(key, sig, msg) {
12968
12895
  }
12969
12896
  async function exportKey(pair) {
12970
12897
  if (pair.privateKey == null || pair.publicKey == null) {
12971
- throw new CodeError$1('Private and public key are required', 'ERR_INVALID_PARAMETERS');
12898
+ throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
12972
12899
  }
12973
12900
  return Promise.all([
12974
12901
  webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
@@ -12987,10 +12914,10 @@ async function derivePublicFromPrivate(jwKey) {
12987
12914
  }
12988
12915
  function keySize(jwk) {
12989
12916
  if (jwk.kty !== 'RSA') {
12990
- throw new CodeError$1('invalid key type', 'ERR_INVALID_KEY_TYPE');
12917
+ throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
12991
12918
  }
12992
12919
  else if (jwk.n == null) {
12993
- throw new CodeError$1('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
12920
+ throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
12994
12921
  }
12995
12922
  const bytes = fromString(jwk.n, 'base64url');
12996
12923
  return bytes.length * 8;
@@ -13040,7 +12967,7 @@ class RsaPrivateKey {
13040
12967
  }
13041
12968
  get public() {
13042
12969
  if (this._publicKey == null) {
13043
- throw new CodeError$1('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
12970
+ throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
13044
12971
  }
13045
12972
  return new RsaPublicKey(this._publicKey);
13046
12973
  }
@@ -13089,14 +13016,14 @@ class RsaPrivateKey {
13089
13016
  return exporter(this.bytes, password);
13090
13017
  }
13091
13018
  else {
13092
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
13019
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
13093
13020
  }
13094
13021
  }
13095
13022
  }
13096
13023
  async function unmarshalRsaPrivateKey(bytes) {
13097
13024
  const jwk = pkcs1ToJwk(bytes);
13098
13025
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13099
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13026
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13100
13027
  }
13101
13028
  const keys = await unmarshalPrivateKey$1(jwk);
13102
13029
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
@@ -13104,20 +13031,20 @@ async function unmarshalRsaPrivateKey(bytes) {
13104
13031
  function unmarshalRsaPublicKey(bytes) {
13105
13032
  const jwk = pkixToJwk(bytes);
13106
13033
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13107
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13034
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13108
13035
  }
13109
13036
  return new RsaPublicKey(jwk);
13110
13037
  }
13111
13038
  async function fromJwk(jwk) {
13112
13039
  if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
13113
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13040
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13114
13041
  }
13115
13042
  const keys = await unmarshalPrivateKey$1(jwk);
13116
13043
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
13117
13044
  }
13118
13045
  async function generateKeyPair$1(bits) {
13119
13046
  if (bits > MAX_RSA_KEY_SIZE) {
13120
- throw new CodeError$1('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13047
+ throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
13121
13048
  }
13122
13049
  const keys = await generateKey$1(bits);
13123
13050
  return new RsaPrivateKey(keys.privateKey, keys.publicKey);
@@ -13136,6 +13063,12 @@ var RSA = /*#__PURE__*/Object.freeze({
13136
13063
 
13137
13064
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
13138
13065
  // Short Weierstrass curve. The formula is: y² = x³ + ax + b
13066
+ function validateSigVerOpts(opts) {
13067
+ if (opts.lowS !== undefined)
13068
+ abool('lowS', opts.lowS);
13069
+ if (opts.prehash !== undefined)
13070
+ abool('prehash', opts.prehash);
13071
+ }
13139
13072
  function validatePointOpts(curve) {
13140
13073
  const opts = validateBasic(curve);
13141
13074
  validateObject(opts, {
@@ -13260,16 +13193,12 @@ function weierstrassPoints(opts) {
13260
13193
  throw new Error('bad generator point: equation left != right');
13261
13194
  // Valid group elements reside in range 1..n-1
13262
13195
  function isWithinCurveOrder(num) {
13263
- return typeof num === 'bigint' && _0n < num && num < CURVE.n;
13264
- }
13265
- function assertGE(num) {
13266
- if (!isWithinCurveOrder(num))
13267
- throw new Error('Expected valid bigint: 0 < bigint < curve.n');
13196
+ return inRange(num, _1n$1, CURVE.n);
13268
13197
  }
13269
13198
  // Validates if priv key is valid and converts it to bigint.
13270
13199
  // Supports options allowedPrivateKeyLengths and wrapPrivateKey.
13271
13200
  function normPrivateKeyToScalar(key) {
13272
- const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
13201
+ const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
13273
13202
  if (lengths && typeof key !== 'bigint') {
13274
13203
  if (isBytes$1(key))
13275
13204
  key = bytesToHex(key);
@@ -13289,15 +13218,61 @@ function weierstrassPoints(opts) {
13289
13218
  throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
13290
13219
  }
13291
13220
  if (wrapPrivateKey)
13292
- num = mod(num, n); // disabled by default, enabled for BLS
13293
- assertGE(num); // num in range [1..N-1]
13221
+ num = mod(num, N); // disabled by default, enabled for BLS
13222
+ aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
13294
13223
  return num;
13295
13224
  }
13296
- const pointPrecomputes = new Map();
13297
13225
  function assertPrjPoint(other) {
13298
13226
  if (!(other instanceof Point))
13299
13227
  throw new Error('ProjectivePoint expected');
13300
13228
  }
13229
+ // Memoized toAffine / validity check. They are heavy. Points are immutable.
13230
+ // Converts Projective point to affine (x, y) coordinates.
13231
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
13232
+ // (x, y, z) ∋ (x=x/z, y=y/z)
13233
+ const toAffineMemo = memoized((p, iz) => {
13234
+ const { px: x, py: y, pz: z } = p;
13235
+ // Fast-path for normalized points
13236
+ if (Fp.eql(z, Fp.ONE))
13237
+ return { x, y };
13238
+ const is0 = p.is0();
13239
+ // If invZ was 0, we return zero point. However we still want to execute
13240
+ // all operations, so we replace invZ with a random number, 1.
13241
+ if (iz == null)
13242
+ iz = is0 ? Fp.ONE : Fp.inv(z);
13243
+ const ax = Fp.mul(x, iz);
13244
+ const ay = Fp.mul(y, iz);
13245
+ const zz = Fp.mul(z, iz);
13246
+ if (is0)
13247
+ return { x: Fp.ZERO, y: Fp.ZERO };
13248
+ if (!Fp.eql(zz, Fp.ONE))
13249
+ throw new Error('invZ was invalid');
13250
+ return { x: ax, y: ay };
13251
+ });
13252
+ // NOTE: on exception this will crash 'cached' and no value will be set.
13253
+ // Otherwise true will be return
13254
+ const assertValidMemo = memoized((p) => {
13255
+ if (p.is0()) {
13256
+ // (0, 1, 0) aka ZERO is invalid in most contexts.
13257
+ // In BLS, ZERO can be serialized, so we allow it.
13258
+ // (0, 0, 0) is wrong representation of ZERO and is always invalid.
13259
+ if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
13260
+ return;
13261
+ throw new Error('bad point: ZERO');
13262
+ }
13263
+ // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
13264
+ const { x, y } = p.toAffine();
13265
+ // Check if x, y are valid field elements
13266
+ if (!Fp.isValid(x) || !Fp.isValid(y))
13267
+ throw new Error('bad point: x or y not FE');
13268
+ const left = Fp.sqr(y); // y²
13269
+ const right = weierstrassEquation(x); // x³ + ax + b
13270
+ if (!Fp.eql(left, right))
13271
+ throw new Error('bad point: equation left != right');
13272
+ if (!p.isTorsionFree())
13273
+ throw new Error('bad point: not in prime-order subgroup');
13274
+ return true;
13275
+ });
13301
13276
  /**
13302
13277
  * Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
13303
13278
  * Default Point works in 2d / affine coordinates: (x, y)
@@ -13314,6 +13289,7 @@ function weierstrassPoints(opts) {
13314
13289
  throw new Error('y required');
13315
13290
  if (pz == null || !Fp.isValid(pz))
13316
13291
  throw new Error('z required');
13292
+ Object.freeze(this);
13317
13293
  }
13318
13294
  // Does not validate if the point is on-curve.
13319
13295
  // Use fromHex instead, or call assertValidity() later.
@@ -13360,30 +13336,11 @@ function weierstrassPoints(opts) {
13360
13336
  }
13361
13337
  // "Private method", don't use it directly
13362
13338
  _setWindowSize(windowSize) {
13363
- this._WINDOW_SIZE = windowSize;
13364
- pointPrecomputes.delete(this);
13339
+ wnaf.setWindowSize(this, windowSize);
13365
13340
  }
13366
13341
  // A point on curve is valid if it conforms to equation.
13367
13342
  assertValidity() {
13368
- if (this.is0()) {
13369
- // (0, 1, 0) aka ZERO is invalid in most contexts.
13370
- // In BLS, ZERO can be serialized, so we allow it.
13371
- // (0, 0, 0) is wrong representation of ZERO and is always invalid.
13372
- if (CURVE.allowInfinityPoint && !Fp.is0(this.py))
13373
- return;
13374
- throw new Error('bad point: ZERO');
13375
- }
13376
- // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
13377
- const { x, y } = this.toAffine();
13378
- // Check if x, y are valid field elements
13379
- if (!Fp.isValid(x) || !Fp.isValid(y))
13380
- throw new Error('bad point: x or y not FE');
13381
- const left = Fp.sqr(y); // y²
13382
- const right = weierstrassEquation(x); // x³ + ax + b
13383
- if (!Fp.eql(left, right))
13384
- throw new Error('bad point: equation left != right');
13385
- if (!this.isTorsionFree())
13386
- throw new Error('bad point: not in prime-order subgroup');
13343
+ assertValidMemo(this);
13387
13344
  }
13388
13345
  hasEvenY() {
13389
13346
  const { y } = this.toAffine();
@@ -13510,28 +13467,25 @@ function weierstrassPoints(opts) {
13510
13467
  return this.equals(Point.ZERO);
13511
13468
  }
13512
13469
  wNAF(n) {
13513
- return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => {
13514
- const toInv = Fp.invertBatch(comp.map((p) => p.pz));
13515
- return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
13516
- });
13470
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
13517
13471
  }
13518
13472
  /**
13519
13473
  * Non-constant-time multiplication. Uses double-and-add algorithm.
13520
13474
  * It's faster, but should only be used when you don't care about
13521
13475
  * an exposed private key e.g. sig verification, which works over *public* keys.
13522
13476
  */
13523
- multiplyUnsafe(n) {
13477
+ multiplyUnsafe(sc) {
13478
+ aInRange('scalar', sc, _0n, CURVE.n);
13524
13479
  const I = Point.ZERO;
13525
- if (n === _0n)
13480
+ if (sc === _0n)
13526
13481
  return I;
13527
- assertGE(n); // Will throw on 0
13528
- if (n === _1n$1)
13482
+ if (sc === _1n$1)
13529
13483
  return this;
13530
13484
  const { endo } = CURVE;
13531
13485
  if (!endo)
13532
- return wnaf.unsafeLadder(this, n);
13486
+ return wnaf.unsafeLadder(this, sc);
13533
13487
  // Apply endomorphism
13534
- let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
13488
+ let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
13535
13489
  let k1p = I;
13536
13490
  let k2p = I;
13537
13491
  let d = this;
@@ -13561,12 +13515,11 @@ function weierstrassPoints(opts) {
13561
13515
  * @returns New point
13562
13516
  */
13563
13517
  multiply(scalar) {
13564
- assertGE(scalar);
13565
- let n = scalar;
13518
+ const { endo, n: N } = CURVE;
13519
+ aInRange('scalar', scalar, _1n$1, N);
13566
13520
  let point, fake; // Fake point is used to const-time mult
13567
- const { endo } = CURVE;
13568
13521
  if (endo) {
13569
- const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
13522
+ const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
13570
13523
  let { p: k1p, f: f1p } = this.wNAF(k1);
13571
13524
  let { p: k2p, f: f2p } = this.wNAF(k2);
13572
13525
  k1p = wnaf.constTimeNegate(k1neg, k1p);
@@ -13576,7 +13529,7 @@ function weierstrassPoints(opts) {
13576
13529
  fake = f1p.add(f2p);
13577
13530
  }
13578
13531
  else {
13579
- const { p, f } = this.wNAF(n);
13532
+ const { p, f } = this.wNAF(scalar);
13580
13533
  point = p;
13581
13534
  fake = f;
13582
13535
  }
@@ -13600,20 +13553,7 @@ function weierstrassPoints(opts) {
13600
13553
  // Can accept precomputed Z^-1 - for example, from invertBatch.
13601
13554
  // (x, y, z) ∋ (x=x/z, y=y/z)
13602
13555
  toAffine(iz) {
13603
- const { px: x, py: y, pz: z } = this;
13604
- const is0 = this.is0();
13605
- // If invZ was 0, we return zero point. However we still want to execute
13606
- // all operations, so we replace invZ with a random number, 1.
13607
- if (iz == null)
13608
- iz = is0 ? Fp.ONE : Fp.inv(z);
13609
- const ax = Fp.mul(x, iz);
13610
- const ay = Fp.mul(y, iz);
13611
- const zz = Fp.mul(z, iz);
13612
- if (is0)
13613
- return { x: Fp.ZERO, y: Fp.ZERO };
13614
- if (!Fp.eql(zz, Fp.ONE))
13615
- throw new Error('invZ was invalid');
13616
- return { x: ax, y: ay };
13556
+ return toAffineMemo(this, iz);
13617
13557
  }
13618
13558
  isTorsionFree() {
13619
13559
  const { h: cofactor, isTorsionFree } = CURVE;
@@ -13632,10 +13572,12 @@ function weierstrassPoints(opts) {
13632
13572
  return this.multiplyUnsafe(CURVE.h);
13633
13573
  }
13634
13574
  toRawBytes(isCompressed = true) {
13575
+ abool('isCompressed', isCompressed);
13635
13576
  this.assertValidity();
13636
13577
  return toBytes(Point, this, isCompressed);
13637
13578
  }
13638
13579
  toHex(isCompressed = true) {
13580
+ abool('isCompressed', isCompressed);
13639
13581
  return bytesToHex(this.toRawBytes(isCompressed));
13640
13582
  }
13641
13583
  }
@@ -13665,14 +13607,18 @@ function validateOpts(curve) {
13665
13607
  });
13666
13608
  return Object.freeze({ lowS: true, ...opts });
13667
13609
  }
13610
+ /**
13611
+ * Creates short weierstrass curve and ECDSA signature methods for it.
13612
+ * @example
13613
+ * import { Field } from '@noble/curves/abstract/modular';
13614
+ * // Before that, define BigInt-s: a, b, p, n, Gx, Gy
13615
+ * const curve = weierstrass({ a, b, Fp: Field(p), n, Gx, Gy, h: 1n })
13616
+ */
13668
13617
  function weierstrass(curveDef) {
13669
13618
  const CURVE = validateOpts(curveDef);
13670
13619
  const { Fp, n: CURVE_ORDER } = CURVE;
13671
13620
  const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
13672
13621
  const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
13673
- function isValidFieldElement(num) {
13674
- return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE
13675
- }
13676
13622
  function modN(a) {
13677
13623
  return mod(a, CURVE_ORDER);
13678
13624
  }
@@ -13685,6 +13631,7 @@ function weierstrass(curveDef) {
13685
13631
  const a = point.toAffine();
13686
13632
  const x = Fp.toBytes(a.x);
13687
13633
  const cat = concatBytes;
13634
+ abool('isCompressed', isCompressed);
13688
13635
  if (isCompressed) {
13689
13636
  return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
13690
13637
  }
@@ -13699,7 +13646,7 @@ function weierstrass(curveDef) {
13699
13646
  // this.assertValidity() is done inside of fromHex
13700
13647
  if (len === compressedLen && (head === 0x02 || head === 0x03)) {
13701
13648
  const x = bytesToNumberBE(tail);
13702
- if (!isValidFieldElement(x))
13649
+ if (!inRange(x, _1n$1, Fp.ORDER))
13703
13650
  throw new Error('Point is not on curve');
13704
13651
  const y2 = weierstrassEquation(x); // y² = x³ + ax + b
13705
13652
  let y;
@@ -13760,11 +13707,8 @@ function weierstrass(curveDef) {
13760
13707
  return new Signature(r, s);
13761
13708
  }
13762
13709
  assertValidity() {
13763
- // can use assertGE here
13764
- if (!isWithinCurveOrder(this.r))
13765
- throw new Error('r must be 0 < r < CURVE.n');
13766
- if (!isWithinCurveOrder(this.s))
13767
- throw new Error('s must be 0 < s < CURVE.n');
13710
+ aInRange('r', this.r, _1n$1, CURVE_ORDER); // r in [1..N]
13711
+ aInRange('s', this.s, _1n$1, CURVE_ORDER); // s in [1..N]
13768
13712
  }
13769
13713
  addRecoveryBit(recovery) {
13770
13714
  return new Signature(this.r, this.s, recovery);
@@ -13907,10 +13851,7 @@ function weierstrass(curveDef) {
13907
13851
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
13908
13852
  */
13909
13853
  function int2octets(num) {
13910
- if (typeof num !== 'bigint')
13911
- throw new Error('bigint expected');
13912
- if (!(_0n <= num && num < ORDER_MASK))
13913
- throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
13854
+ aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
13914
13855
  // works with order, can have different size than numToField!
13915
13856
  return numberToBytesBE(num, CURVE.nByteLength);
13916
13857
  }
@@ -13927,6 +13868,7 @@ function weierstrass(curveDef) {
13927
13868
  if (lowS == null)
13928
13869
  lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
13929
13870
  msgHash = ensureBytes('msgHash', msgHash);
13871
+ validateSigVerOpts(opts);
13930
13872
  if (prehash)
13931
13873
  msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
13932
13874
  // We can't later call bits2octets, since nested bits2int is broken for curves
@@ -14013,6 +13955,7 @@ function weierstrass(curveDef) {
14013
13955
  publicKey = ensureBytes('publicKey', publicKey);
14014
13956
  if ('strict' in opts)
14015
13957
  throw new Error('options.strict was renamed to lowS');
13958
+ validateSigVerOpts(opts);
14016
13959
  const { lowS, prehash } = opts;
14017
13960
  let _sig = undefined;
14018
13961
  let P;
@@ -14119,6 +14062,9 @@ function sqrtMod(y) {
14119
14062
  return root;
14120
14063
  }
14121
14064
  const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
14065
+ /**
14066
+ * secp256k1 short weierstrass curve and ECDSA signatures over it.
14067
+ */
14122
14068
  const secp256k1 = createCurve({
14123
14069
  a: BigInt(0), // equation params: a, b
14124
14070
  b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
@@ -14177,14 +14123,14 @@ function hashAndSign(key, msg) {
14177
14123
  if (isPromise$1(p)) {
14178
14124
  return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
14179
14125
  .catch(err => {
14180
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14126
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14181
14127
  });
14182
14128
  }
14183
14129
  try {
14184
14130
  return secp256k1.sign(p.digest, key).toDERRawBytes();
14185
14131
  }
14186
14132
  catch (err) {
14187
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14133
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14188
14134
  }
14189
14135
  }
14190
14136
  /**
@@ -14195,14 +14141,14 @@ function hashAndVerify(key, sig, msg) {
14195
14141
  if (isPromise$1(p)) {
14196
14142
  return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
14197
14143
  .catch(err => {
14198
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14144
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14199
14145
  });
14200
14146
  }
14201
14147
  try {
14202
14148
  return secp256k1.verify(sig, p.digest, key);
14203
14149
  }
14204
14150
  catch (err) {
14205
- throw new CodeError$1(String(err), 'ERR_INVALID_INPUT');
14151
+ throw new CodeError(String(err), 'ERR_INVALID_INPUT');
14206
14152
  }
14207
14153
  }
14208
14154
  function compressPublicKey(key) {
@@ -14214,7 +14160,7 @@ function validatePrivateKey(key) {
14214
14160
  secp256k1.getPublicKey(key, true);
14215
14161
  }
14216
14162
  catch (err) {
14217
- throw new CodeError$1(String(err), 'ERR_INVALID_PRIVATE_KEY');
14163
+ throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
14218
14164
  }
14219
14165
  }
14220
14166
  function validatePublicKey(key) {
@@ -14222,7 +14168,7 @@ function validatePublicKey(key) {
14222
14168
  secp256k1.ProjectivePoint.fromHex(key);
14223
14169
  }
14224
14170
  catch (err) {
14225
- throw new CodeError$1(String(err), 'ERR_INVALID_PUBLIC_KEY');
14171
+ throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
14226
14172
  }
14227
14173
  }
14228
14174
  function computePublicKey(privateKey) {
@@ -14230,7 +14176,7 @@ function computePublicKey(privateKey) {
14230
14176
  return secp256k1.getPublicKey(privateKey, true);
14231
14177
  }
14232
14178
  catch (err) {
14233
- throw new CodeError$1(String(err), 'ERR_INVALID_PRIVATE_KEY');
14179
+ throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
14234
14180
  }
14235
14181
  }
14236
14182
 
@@ -14320,7 +14266,7 @@ class Secp256k1PrivateKey {
14320
14266
  return exporter(this.bytes, password);
14321
14267
  }
14322
14268
  else {
14323
- throw new CodeError$1(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
14269
+ throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
14324
14270
  }
14325
14271
  }
14326
14272
  }
@@ -14362,7 +14308,7 @@ const supportedKeys = {
14362
14308
  };
14363
14309
  function unsupportedKey(type) {
14364
14310
  const supported = Object.keys(supportedKeys).join(' / ');
14365
- return new CodeError$1(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
14311
+ return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
14366
14312
  }
14367
14313
  function typeToKey(type) {
14368
14314
  type = type.toLowerCase();
@@ -14547,6 +14493,41 @@ class Secp256k1PeerIdImpl extends PeerIdImpl {
14547
14493
  this.publicKey = init.multihash.digest;
14548
14494
  }
14549
14495
  }
14496
+ // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
14497
+ const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
14498
+ class URLPeerIdImpl {
14499
+ type = 'url';
14500
+ multihash;
14501
+ privateKey;
14502
+ publicKey;
14503
+ url;
14504
+ constructor(url) {
14505
+ this.url = url.toString();
14506
+ this.multihash = identity.digest(fromString(this.url));
14507
+ }
14508
+ [inspect]() {
14509
+ return `PeerId(${this.url})`;
14510
+ }
14511
+ [peerIdSymbol] = true;
14512
+ toString() {
14513
+ return this.toCID().toString();
14514
+ }
14515
+ toCID() {
14516
+ return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
14517
+ }
14518
+ toBytes() {
14519
+ return this.toCID().bytes;
14520
+ }
14521
+ equals(other) {
14522
+ if (other == null) {
14523
+ return false;
14524
+ }
14525
+ if (other instanceof Uint8Array) {
14526
+ other = toString$6(other);
14527
+ }
14528
+ return other.toString() === this.toString();
14529
+ }
14530
+ }
14550
14531
  function peerIdFromString(str, decoder) {
14551
14532
  if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
14552
14533
  // identity hash ed25519/secp256k1 key or sha2-256 hash of
@@ -14585,9 +14566,13 @@ function peerIdFromBytes(buf) {
14585
14566
  throw new Error('Supplied PeerID CID is invalid');
14586
14567
  }
14587
14568
  function peerIdFromCID(cid) {
14588
- if (cid == null || cid.multihash == null || cid.version == null || (cid.version === 1 && cid.code !== LIBP2P_KEY_CODE)) {
14569
+ if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
14589
14570
  throw new Error('Supplied PeerID CID is invalid');
14590
14571
  }
14572
+ if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
14573
+ const url = toString$6(cid.multihash.digest);
14574
+ return new URLPeerIdImpl(new URL(url));
14575
+ }
14591
14576
  const multihash = cid.multihash;
14592
14577
  if (multihash.code === sha256.code) {
14593
14578
  return new RSAPeerIdImpl({ multihash: cid.multihash });
@@ -15433,9 +15418,6 @@ function isHexString(value, length) {
15433
15418
  if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
15434
15419
  return false;
15435
15420
  }
15436
- if (length && value.length !== 2 + 2 * length) {
15437
- return false;
15438
- }
15439
15421
  return true;
15440
15422
  }
15441
15423
  const HexCharacters = "0123456789abcdef";
@@ -17859,7 +17841,7 @@ if (!AbortError$1) {
17859
17841
  AbortError$1.prototype.name = 'AbortError';
17860
17842
  AbortError$1.prototype.code = 'ABORT_ERR';
17861
17843
 
17862
- const URL = (typeof globalThis !== 'undefined' && globalThis.URL) || require('url').URL;
17844
+ const URL$1 = (typeof globalThis !== 'undefined' && globalThis.URL) || require('url').URL;
17863
17845
 
17864
17846
  class HTTPStatusError extends Error {
17865
17847
  constructor (uri, code, method) {
@@ -18108,7 +18090,7 @@ class HTTPEndpoint extends BaseEndpoint {
18108
18090
  }
18109
18091
  const url = `${this.protocol}//${safeHost(this.host)}:${this.port}${this.path}`;
18110
18092
  try {
18111
- this.url = new URL(url);
18093
+ this.url = new URL$1(url);
18112
18094
  } catch (err) {
18113
18095
  throw new Error(err.message + ` [${url}]`)
18114
18096
  }
@@ -18190,7 +18172,7 @@ async function loadJSON (url, cache, timeout, abortSignal) {
18190
18172
 
18191
18173
  function requestRaw (url, method, data, timeout, abortSignal) {
18192
18174
  return new Promise((resolve, reject) => {
18193
- const target = new URL(url);
18175
+ const target = new URL$1(url);
18194
18176
  if (method === 'GET' && data) {
18195
18177
  target.search = '?dns=' + base64URL.decode(data);
18196
18178
  }
@@ -19569,7 +19551,7 @@ function queryDoh (endpoint, query, timeout, abortSignal) {
19569
19551
  )
19570
19552
  }
19571
19553
 
19572
- const UPDATE_URL = new URL('https://martinheidegger.github.io/dns-query/resolvers.json');
19554
+ const UPDATE_URL = new URL$1('https://martinheidegger.github.io/dns-query/resolvers.json');
19573
19555
 
19574
19556
  function isNameString (entry) {
19575
19557
  return /^@/.test(entry)
@@ -20924,16 +20906,14 @@ class BaseProtocol {
20924
20906
  components;
20925
20907
  log;
20926
20908
  pubsubTopics;
20927
- options;
20928
20909
  addLibp2pEventListener;
20929
20910
  removeLibp2pEventListener;
20930
20911
  streamManager;
20931
- constructor(multicodec, components, log, pubsubTopics, options) {
20912
+ constructor(multicodec, components, log, pubsubTopics) {
20932
20913
  this.multicodec = multicodec;
20933
20914
  this.components = components;
20934
20915
  this.log = log;
20935
20916
  this.pubsubTopics = pubsubTopics;
20936
- this.options = options;
20937
20917
  this.addLibp2pEventListener = components.events.addEventListener.bind(components.events);
20938
20918
  this.removeLibp2pEventListener = components.events.removeEventListener.bind(components.events);
20939
20919
  this.streamManager = new StreamManager(multicodec, components.connectionManager.getConnections.bind(components.connectionManager), this.addLibp2pEventListener);
@@ -20971,9 +20951,7 @@ class BaseProtocol {
20971
20951
  numPeers: 0
20972
20952
  }) {
20973
20953
  // Retrieve all connected peers that support the protocol & shard (if configured)
20974
- const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], this.options?.shardInfo
20975
- ? ensureShardingConfigured(this.options.shardInfo).shardInfo
20976
- : undefined);
20954
+ const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], pubsubTopicsToShardInfo(this.pubsubTopics));
20977
20955
  // Filter the peers based on discovery & number of peers requested
20978
20956
  const filteredPeers = filterPeersByDiscovery(connectedPeersForProtocolAndShard, numPeers, maxBootstrapPeers);
20979
20957
  // Sort the peers by latency
@@ -21663,74 +21641,35 @@ encode.single = (chunk, options) => {
21663
21641
  };
21664
21642
 
21665
21643
  /**
21666
- * @typedef {{ [key: string]: any }} Extensions
21667
- * @typedef {Error} Err
21668
- * @property {string} message
21644
+ * The reported length of the next data message was not a positive integer
21669
21645
  */
21670
-
21646
+ class InvalidMessageLengthError extends Error {
21647
+ name = 'InvalidMessageLengthError';
21648
+ code = 'ERR_INVALID_MSG_LENGTH';
21649
+ }
21671
21650
  /**
21672
- *
21673
- * @param {Error} obj
21674
- * @param {Extensions} props
21675
- * @returns {Error & Extensions}
21651
+ * The reported length of the next data message was larger than the configured
21652
+ * max allowable value
21676
21653
  */
21677
- function assign(obj, props) {
21678
- for (const key in props) {
21679
- Object.defineProperty(obj, key, {
21680
- value: props[key],
21681
- enumerable: true,
21682
- configurable: true,
21683
- });
21684
- }
21685
-
21686
- return obj;
21654
+ class InvalidDataLengthError extends Error {
21655
+ name = 'InvalidDataLengthError';
21656
+ code = 'ERR_MSG_DATA_TOO_LONG';
21687
21657
  }
21688
-
21689
21658
  /**
21690
- *
21691
- * @param {any} err - An Error
21692
- * @param {string|Extensions} code - A string code or props to set on the error
21693
- * @param {Extensions} [props] - Props to set on the error
21694
- * @returns {Error & Extensions}
21659
+ * The varint used to specify the length of the next data message contained more
21660
+ * bytes than the configured max allowable value
21695
21661
  */
21696
- function createError(err, code, props) {
21697
- if (!err || typeof err === 'string') {
21698
- throw new TypeError('Please pass an Error to err-code');
21699
- }
21700
-
21701
- if (!props) {
21702
- props = {};
21703
- }
21704
-
21705
- if (typeof code === 'object') {
21706
- props = code;
21707
- code = '';
21708
- }
21709
-
21710
- if (code) {
21711
- props.code = code;
21712
- }
21713
-
21714
- try {
21715
- return assign(err, props);
21716
- } catch (_) {
21717
- props.message = err.message;
21718
- props.stack = err.stack;
21719
-
21720
- const ErrClass = function () {};
21721
-
21722
- ErrClass.prototype = Object.create(Object.getPrototypeOf(err));
21723
-
21724
- // @ts-ignore
21725
- const output = assign(new ErrClass(), props);
21726
-
21727
- return output;
21728
- }
21662
+ class InvalidDataLengthLengthError extends Error {
21663
+ name = 'InvalidDataLengthLengthError';
21664
+ code = 'ERR_MSG_LENGTH_TOO_LONG';
21665
+ }
21666
+ /**
21667
+ * The incoming stream ended before the expected number of bytes were read
21668
+ */
21669
+ class UnexpectedEOFError extends Error {
21670
+ name = 'UnexpectedEOFError';
21671
+ code = 'ERR_UNEXPECTED_EOF';
21729
21672
  }
21730
-
21731
- var errCode = createError;
21732
-
21733
- var errCode$1 = /*@__PURE__*/getDefaultExportFromCjs(errCode);
21734
21673
 
21735
21674
  /* eslint max-depth: ["error", 6] */
21736
21675
  // Maximum length of the length section of the message
@@ -21762,10 +21701,10 @@ function decode(source, options) {
21762
21701
  try {
21763
21702
  dataLength = lengthDecoder(buffer);
21764
21703
  if (dataLength < 0) {
21765
- throw errCode$1(new Error('invalid message length'), 'ERR_INVALID_MSG_LENGTH');
21704
+ throw new InvalidMessageLengthError('Invalid message length');
21766
21705
  }
21767
21706
  if (dataLength > maxDataLength) {
21768
- throw errCode$1(new Error('message length too long'), 'ERR_MSG_DATA_TOO_LONG');
21707
+ throw new InvalidDataLengthError('Message length too long');
21769
21708
  }
21770
21709
  const dataLengthLength = lengthDecoder.bytes;
21771
21710
  buffer.consume(dataLengthLength);
@@ -21777,7 +21716,7 @@ function decode(source, options) {
21777
21716
  catch (err) {
21778
21717
  if (err instanceof RangeError) {
21779
21718
  if (buffer.byteLength > maxLengthLength) {
21780
- throw errCode$1(new Error('message length length too long'), 'ERR_MSG_LENGTH_TOO_LONG');
21719
+ throw new InvalidDataLengthLengthError('Message length length too long');
21781
21720
  }
21782
21721
  break;
21783
21722
  }
@@ -21806,7 +21745,7 @@ function decode(source, options) {
21806
21745
  yield* maybeYield();
21807
21746
  }
21808
21747
  if (buffer.byteLength > 0) {
21809
- throw errCode$1(new Error('unexpected end of input'), 'ERR_UNEXPECTED_EOF');
21748
+ throw new UnexpectedEOFError('Unexpected end of input');
21810
21749
  }
21811
21750
  })();
21812
21751
  }
@@ -21816,7 +21755,7 @@ function decode(source, options) {
21816
21755
  yield* maybeYield();
21817
21756
  }
21818
21757
  if (buffer.byteLength > 0) {
21819
- throw errCode$1(new Error('unexpected end of input'), 'ERR_UNEXPECTED_EOF');
21758
+ throw new UnexpectedEOFError('Unexpected end of input');
21820
21759
  }
21821
21760
  })();
21822
21761
  }
@@ -22651,7 +22590,7 @@ var FilterRequest;
22651
22590
  }
22652
22591
  case 3: {
22653
22592
  if (opts.limits?.contentFilters != null && obj.contentFilters.length === opts.limits.contentFilters) {
22654
- throw new CodeError('decode error - map field "contentFilters" had too many elements', 'ERR_MAX_LENGTH');
22593
+ throw new MaxLengthError('Decode error - map field "contentFilters" had too many elements');
22655
22594
  }
22656
22595
  obj.contentFilters.push(FilterRequest.ContentFilter.codec().decode(reader, reader.uint32(), {
22657
22596
  limits: opts.limits?.contentFilters$
@@ -22704,7 +22643,7 @@ var MessagePush$1;
22704
22643
  switch (tag >>> 3) {
22705
22644
  case 1: {
22706
22645
  if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
22707
- throw new CodeError('decode error - map field "messages" had too many elements', 'ERR_MAX_LENGTH');
22646
+ throw new MaxLengthError('Decode error - map field "messages" had too many elements');
22708
22647
  }
22709
22648
  obj.messages.push(WakuMessage$3.codec().decode(reader, reader.uint32(), {
22710
22649
  limits: opts.limits?.messages$
@@ -23123,7 +23062,7 @@ var FilterSubscribeRequest;
23123
23062
  }
23124
23063
  case 11: {
23125
23064
  if (opts.limits?.contentTopics != null && obj.contentTopics.length === opts.limits.contentTopics) {
23126
- throw new CodeError('decode error - map field "contentTopics" had too many elements', 'ERR_MAX_LENGTH');
23065
+ throw new MaxLengthError('Decode error - map field "contentTopics" had too many elements');
23127
23066
  }
23128
23067
  obj.contentTopics.push(reader.string());
23129
23068
  break;
@@ -23989,7 +23928,7 @@ var StoreQueryRequest;
23989
23928
  }
23990
23929
  case 11: {
23991
23930
  if (opts.limits?.contentTopics != null && obj.contentTopics.length === opts.limits.contentTopics) {
23992
- throw new CodeError('decode error - map field "contentTopics" had too many elements', 'ERR_MAX_LENGTH');
23931
+ throw new MaxLengthError('Decode error - map field "contentTopics" had too many elements');
23993
23932
  }
23994
23933
  obj.contentTopics.push(reader.string());
23995
23934
  break;
@@ -24004,7 +23943,7 @@ var StoreQueryRequest;
24004
23943
  }
24005
23944
  case 20: {
24006
23945
  if (opts.limits?.messageHashes != null && obj.messageHashes.length === opts.limits.messageHashes) {
24007
- throw new CodeError('decode error - map field "messageHashes" had too many elements', 'ERR_MAX_LENGTH');
23946
+ throw new MaxLengthError('Decode error - map field "messageHashes" had too many elements');
24008
23947
  }
24009
23948
  obj.messageHashes.push(reader.bytes());
24010
23949
  break;
@@ -24096,7 +24035,7 @@ var StoreQueryResponse;
24096
24035
  }
24097
24036
  case 20: {
24098
24037
  if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
24099
- throw new CodeError('decode error - map field "messages" had too many elements', 'ERR_MAX_LENGTH');
24038
+ throw new MaxLengthError('Decode error - map field "messages" had too many elements');
24100
24039
  }
24101
24040
  obj.messages.push(WakuMessageKeyValue.codec().decode(reader, reader.uint32(), {
24102
24041
  limits: opts.limits?.messages$
@@ -24444,7 +24383,7 @@ var PeerExchangeResponse;
24444
24383
  switch (tag >>> 3) {
24445
24384
  case 1: {
24446
24385
  if (opts.limits?.peerInfos != null && obj.peerInfos.length === opts.limits.peerInfos) {
24447
- throw new CodeError('decode error - map field "peerInfos" had too many elements', 'ERR_MAX_LENGTH');
24386
+ throw new MaxLengthError('Decode error - map field "peerInfos" had too many elements');
24448
24387
  }
24449
24388
  obj.peerInfos.push(PeerInfo.codec().decode(reader, reader.uint32(), {
24450
24389
  limits: opts.limits?.peerInfos$
@@ -24567,7 +24506,7 @@ var WakuMetadataRequest;
24567
24506
  }
24568
24507
  case 2: {
24569
24508
  if (opts.limits?.shards != null && obj.shards.length === opts.limits.shards) {
24570
- throw new CodeError('decode error - map field "shards" had too many elements', 'ERR_MAX_LENGTH');
24509
+ throw new MaxLengthError('Decode error - map field "shards" had too many elements');
24571
24510
  }
24572
24511
  obj.shards.push(reader.uint32());
24573
24512
  break;
@@ -24626,7 +24565,7 @@ var WakuMetadataResponse;
24626
24565
  }
24627
24566
  case 2: {
24628
24567
  if (opts.limits?.shards != null && obj.shards.length === opts.limits.shards) {
24629
- throw new CodeError('decode error - map field "shards" had too many elements', 'ERR_MAX_LENGTH');
24568
+ throw new MaxLengthError('Decode error - map field "shards" had too many elements');
24630
24569
  }
24631
24570
  obj.shards.push(reader.uint32());
24632
24571
  break;
@@ -24987,7 +24926,13 @@ async function createFromParts(multihash, privKey, pubKey) {
24987
24926
  const key = unmarshalPublicKey(pubKey);
24988
24927
  return createFromPubKey(key);
24989
24928
  }
24990
- return peerIdFromBytes(multihash);
24929
+ const peerId = peerIdFromBytes(multihash);
24930
+ if (peerId.type !== 'Ed25519' && peerId.type !== 'secp256k1' && peerId.type !== 'RSA') {
24931
+ // should not be possible since `multihash` is derived from keys and these
24932
+ // are the cryptographic peer id types
24933
+ throw new Error('Supplied PeerID is invalid');
24934
+ }
24935
+ return peerId;
24991
24936
  }
24992
24937
 
24993
24938
  const log = new Logger$1("peer-exchange-discovery");