@waku/discovery 0.0.7-9f1d8ca.0 → 0.0.7-a3e7f15.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
@@ -23,7 +23,7 @@ const peerDiscoverySymbol = Symbol.for('@libp2p/peer-discovery');
23
23
  * All PeerId implementations must use this symbol as the name of a property
24
24
  * with a boolean `true` value
25
25
  */
26
- const peerIdSymbol$1 = Symbol.for('@libp2p/peer-id');
26
+ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
27
27
 
28
28
  /**
29
29
  * When this error is thrown it means an operation was aborted,
@@ -33,13 +33,23 @@ const peerIdSymbol$1 = Symbol.for('@libp2p/peer-id');
33
33
  /**
34
34
  * Thrown when invalid parameters are passed to a function or method call
35
35
  */
36
- let InvalidParametersError$1 = class InvalidParametersError extends Error {
36
+ class InvalidParametersError extends Error {
37
37
  static name = 'InvalidParametersError';
38
38
  constructor(message = 'Invalid parameters') {
39
39
  super(message);
40
40
  this.name = 'InvalidParametersError';
41
41
  }
42
- };
42
+ }
43
+ /**
44
+ * Thrown when a public key is invalid
45
+ */
46
+ class InvalidPublicKeyError extends Error {
47
+ static name = 'InvalidPublicKeyError';
48
+ constructor(message = 'Invalid public key') {
49
+ super(message);
50
+ this.name = 'InvalidPublicKeyError';
51
+ }
52
+ }
43
53
  /**
44
54
  * Thrown when an invalid multihash is encountered
45
55
  */
@@ -50,11 +60,25 @@ class InvalidMultihashError extends Error {
50
60
  this.name = 'InvalidMultihashError';
51
61
  }
52
62
  }
63
+ /**
64
+ * Thrown when and attempt to operate on an unsupported key was made
65
+ */
66
+ class UnsupportedKeyTypeError extends Error {
67
+ static name = 'UnsupportedKeyTypeError';
68
+ constructor(message = 'Unsupported key type') {
69
+ super(message);
70
+ this.name = 'UnsupportedKeyTypeError';
71
+ }
72
+ }
53
73
 
54
- /** Noop for browser compatibility */
74
+ /**
75
+ * Noop for browser compatibility
76
+ */
55
77
  function setMaxListeners$1() { }
56
78
 
57
- // create a setMaxListeners that doesn't break browser usage
79
+ /**
80
+ * Create a setMaxListeners that doesn't break browser usage
81
+ */
58
82
  const setMaxListeners = (n, ...eventTargets) => {
59
83
  try {
60
84
  setMaxListeners$1(n, ...eventTargets);
@@ -128,43 +152,24 @@ var Protocols;
128
152
  })(Protocols || (Protocols = {}));
129
153
  var ProtocolError;
130
154
  (function (ProtocolError) {
131
- /** Could not determine the origin of the fault. Best to check connectivity and try again */
155
+ //
156
+ // GENERAL ERRORS SECTION
157
+ //
158
+ /**
159
+ * Could not determine the origin of the fault. Best to check connectivity and try again
160
+ * */
132
161
  ProtocolError["GENERIC_FAIL"] = "Generic error";
133
162
  /**
134
- * Failure to protobuf encode the message. This is not recoverable and needs
135
- * further investigation.
163
+ * The remote peer rejected the message. Information provided by the remote peer
164
+ * is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
165
+ * or `DECODE_FAILED` can be used.
136
166
  */
137
- ProtocolError["ENCODE_FAILED"] = "Failed to encode";
167
+ ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
138
168
  /**
139
169
  * Failure to protobuf decode the message. May be due to a remote peer issue,
140
170
  * ensuring that messages are sent via several peer enable mitigation of this error.
141
171
  */
142
172
  ProtocolError["DECODE_FAILED"] = "Failed to decode";
143
- /**
144
- * The message payload is empty, making the message invalid. Ensure that a non-empty
145
- * payload is set on the outgoing message.
146
- */
147
- ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
148
- /**
149
- * The message size is above the maximum message size allowed on the Waku Network.
150
- * Compressing the message or using an alternative strategy for large messages is recommended.
151
- */
152
- ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
153
- /**
154
- * The PubsubTopic passed to the send function is not configured on the Waku node.
155
- * Please ensure that the PubsubTopic is used when initializing the Waku node.
156
- */
157
- ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
158
- /**
159
- * The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
160
- * Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
161
- */
162
- ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
163
- /**
164
- * The topics passed in the decoders do not match each other, or don't exist at all.
165
- * Ensure that all the pubsub topics used in the decoders are valid and match each other.
166
- */
167
- ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
168
173
  /**
169
174
  * Failure to find a peer with suitable protocols. This may due to a connection issue.
170
175
  * Mitigation can be: retrying after a given time period, display connectivity issue
@@ -182,37 +187,51 @@ var ProtocolError;
182
187
  * or `DECODE_FAILED` can be used.
183
188
  */
184
189
  ProtocolError["NO_RESPONSE"] = "No response received";
190
+ //
191
+ // SEND ERRORS SECTION
192
+ //
185
193
  /**
186
- * The remote peer rejected the message. Information provided by the remote peer
187
- * is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
188
- * or `DECODE_FAILED` can be used.
194
+ * Failure to protobuf encode the message. This is not recoverable and needs
195
+ * further investigation.
189
196
  */
190
- ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
197
+ ProtocolError["ENCODE_FAILED"] = "Failed to encode";
191
198
  /**
192
- * The protocol request timed out without a response. This may be due to a connection issue.
193
- * Mitigation can be: retrying after a given time period
199
+ * The message payload is empty, making the message invalid. Ensure that a non-empty
200
+ * payload is set on the outgoing message.
194
201
  */
195
- ProtocolError["REQUEST_TIMEOUT"] = "Request timeout";
202
+ ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
196
203
  /**
197
- * Missing credentials info message.
198
- * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L186
204
+ * The message size is above the maximum message size allowed on the Waku Network.
205
+ * Compressing the message or using an alternative strategy for large messages is recommended.
199
206
  */
200
- ProtocolError["RLN_IDENTITY_MISSING"] = "Identity credentials are not set";
207
+ ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
201
208
  /**
202
- * Membership index missing info message.
203
- * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L188
209
+ * The PubsubTopic passed to the send function is not configured on the Waku node.
210
+ * Please ensure that the PubsubTopic is used when initializing the Waku node.
204
211
  */
205
- ProtocolError["RLN_MEMBERSHIP_INDEX"] = "Membership index is not set";
212
+ ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
206
213
  /**
207
- * Message limit is missing.
208
- * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
214
+ * Fails when
209
215
  */
210
- ProtocolError["RLN_LIMIT_MISSING"] = "User message limit is not set";
216
+ ProtocolError["STREAM_ABORTED"] = "Stream aborted";
211
217
  /**
212
218
  * General proof generation error message.
213
219
  * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
214
220
  */
215
221
  ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
222
+ //
223
+ // RECEIVE ERRORS SECTION
224
+ //
225
+ /**
226
+ * The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
227
+ * Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
228
+ */
229
+ ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
230
+ /**
231
+ * The topics passed in the decoders do not match each other, or don't exist at all.
232
+ * Ensure that all the pubsub topics used in the decoders are valid and match each other.
233
+ */
234
+ ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
216
235
  })(ProtocolError || (ProtocolError = {}));
217
236
 
218
237
  var Tags;
@@ -235,6 +254,10 @@ var EConnectionStateEvents;
235
254
 
236
255
  const DNS_DISCOVERY_TAG = "@waku/bootstrap";
237
256
 
257
+ var HealthStatusChangeEvents;
258
+ (function (HealthStatusChangeEvents) {
259
+ HealthStatusChangeEvents["StatusChange"] = "health:change";
260
+ })(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
238
261
  var HealthStatus;
239
262
  (function (HealthStatus) {
240
263
  HealthStatus["Unhealthy"] = "Unhealthy";
@@ -246,43 +269,55 @@ function isDefined(value) {
246
269
  return Boolean(value);
247
270
  }
248
271
 
249
- function number(n) {
272
+ /**
273
+ * Internal assertion helpers.
274
+ * @module
275
+ */
276
+ /** Asserts something is positive integer. */
277
+ function anumber(n) {
250
278
  if (!Number.isSafeInteger(n) || n < 0)
251
- throw new Error(`positive integer expected, not ${n}`);
279
+ throw new Error('positive integer expected, got ' + n);
252
280
  }
253
- // copied from utils
281
+ /** Is number an Uint8Array? Copied from utils for perf. */
254
282
  function isBytes$2(a) {
255
- return (a instanceof Uint8Array ||
256
- (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
283
+ return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
257
284
  }
258
- function bytes(b, ...lengths) {
285
+ /** Asserts something is Uint8Array. */
286
+ function abytes$1(b, ...lengths) {
259
287
  if (!isBytes$2(b))
260
288
  throw new Error('Uint8Array expected');
261
289
  if (lengths.length > 0 && !lengths.includes(b.length))
262
- throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);
290
+ throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
263
291
  }
264
- function hash(h) {
292
+ /** Asserts something is hash */
293
+ function ahash(h) {
265
294
  if (typeof h !== 'function' || typeof h.create !== 'function')
266
295
  throw new Error('Hash should be wrapped by utils.wrapConstructor');
267
- number(h.outputLen);
268
- number(h.blockLen);
296
+ anumber(h.outputLen);
297
+ anumber(h.blockLen);
269
298
  }
270
- function exists(instance, checkFinished = true) {
299
+ /** Asserts a hash instance has not been destroyed / finished */
300
+ function aexists(instance, checkFinished = true) {
271
301
  if (instance.destroyed)
272
302
  throw new Error('Hash instance has been destroyed');
273
303
  if (checkFinished && instance.finished)
274
304
  throw new Error('Hash#digest() has already been called');
275
305
  }
276
- function output(out, instance) {
277
- bytes(out);
306
+ /** Asserts output is properly-sized byte array */
307
+ function aoutput(out, instance) {
308
+ abytes$1(out);
278
309
  const min = instance.outputLen;
279
310
  if (out.length < min) {
280
- throw new Error(`digestInto() expects output buffer of length at least ${min}`);
311
+ throw new Error('digestInto() expects output buffer of length at least ' + min);
281
312
  }
282
313
  }
283
314
 
284
315
  const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
285
316
 
317
+ /**
318
+ * Utilities for hex, bytes, CSPRNG.
319
+ * @module
320
+ */
286
321
  /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
287
322
  // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
288
323
  // node.js versions earlier than v19 don't declare it in global scope.
@@ -291,16 +326,20 @@ const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? glob
291
326
  // Makes the utils un-importable in browsers without a bundler.
292
327
  // Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
293
328
  // Cast array to view
294
- const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
295
- // The rotate right (circular right shift) operation for uint32
296
- const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
297
- new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
329
+ function createView(arr) {
330
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
331
+ }
332
+ /** The rotate right (circular right shift) operation for uint32 */
333
+ function rotr(word, shift) {
334
+ return (word << (32 - shift)) | (word >>> shift);
335
+ }
298
336
  /**
337
+ * Convert JS string to byte array.
299
338
  * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
300
339
  */
301
340
  function utf8ToBytes$2(str) {
302
341
  if (typeof str !== 'string')
303
- throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
342
+ throw new Error('utf8ToBytes expected string, got ' + typeof str);
304
343
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
305
344
  }
306
345
  /**
@@ -311,7 +350,7 @@ function utf8ToBytes$2(str) {
311
350
  function toBytes$1(data) {
312
351
  if (typeof data === 'string')
313
352
  data = utf8ToBytes$2(data);
314
- bytes(data);
353
+ abytes$1(data);
315
354
  return data;
316
355
  }
317
356
  /**
@@ -321,7 +360,7 @@ function concatBytes$2(...arrays) {
321
360
  let sum = 0;
322
361
  for (let i = 0; i < arrays.length; i++) {
323
362
  const a = arrays[i];
324
- bytes(a);
363
+ abytes$1(a);
325
364
  sum += a.length;
326
365
  }
327
366
  const res = new Uint8Array(sum);
@@ -332,13 +371,14 @@ function concatBytes$2(...arrays) {
332
371
  }
333
372
  return res;
334
373
  }
335
- // For runtime check if class implements interface
374
+ /** For runtime check if class implements interface */
336
375
  class Hash {
337
376
  // Safe version that clones internal state
338
377
  clone() {
339
378
  return this._cloneInto();
340
379
  }
341
380
  }
381
+ /** Wraps hash function, creating an interface on top of it */
342
382
  function wrapConstructor(hashCons) {
343
383
  const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
344
384
  const tmp = hashCons();
@@ -347,9 +387,7 @@ function wrapConstructor(hashCons) {
347
387
  hashC.create = () => hashCons();
348
388
  return hashC;
349
389
  }
350
- /**
351
- * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
352
- */
390
+ /** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
353
391
  function randomBytes(bytesLength = 32) {
354
392
  if (crypto$2 && typeof crypto$2.getRandomValues === 'function') {
355
393
  return crypto$2.getRandomValues(new Uint8Array(bytesLength));
@@ -362,8 +400,10 @@ function randomBytes(bytesLength = 32) {
362
400
  }
363
401
 
364
402
  /**
365
- * Polyfill for Safari 14
403
+ * Internal Merkle-Damgard hash utils.
404
+ * @module
366
405
  */
406
+ /** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
367
407
  function setBigUint64(view, byteOffset, value, isLE) {
368
408
  if (typeof view.setBigUint64 === 'function')
369
409
  return view.setBigUint64(byteOffset, value, isLE);
@@ -376,14 +416,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
376
416
  view.setUint32(byteOffset + h, wh, isLE);
377
417
  view.setUint32(byteOffset + l, wl, isLE);
378
418
  }
379
- /**
380
- * Choice: a ? b : c
381
- */
382
- const Chi = (a, b, c) => (a & b) ^ (~a & c);
383
- /**
384
- * Majority function, true if any two inputs is true
385
- */
386
- const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
419
+ /** Choice: a ? b : c */
420
+ function Chi(a, b, c) {
421
+ return (a & b) ^ (~a & c);
422
+ }
423
+ /** Majority function, true if any two inputs is true. */
424
+ function Maj(a, b, c) {
425
+ return (a & b) ^ (a & c) ^ (b & c);
426
+ }
387
427
  /**
388
428
  * Merkle-Damgard hash construction base class.
389
429
  * Could be used to create MD5, RIPEMD, SHA1, SHA2.
@@ -403,7 +443,7 @@ class HashMD extends Hash {
403
443
  this.view = createView(this.buffer);
404
444
  }
405
445
  update(data) {
406
- exists(this);
446
+ aexists(this);
407
447
  const { view, buffer, blockLen } = this;
408
448
  data = toBytes$1(data);
409
449
  const len = data.length;
@@ -429,8 +469,8 @@ class HashMD extends Hash {
429
469
  return this;
430
470
  }
431
471
  digestInto(out) {
432
- exists(this);
433
- output(out, this);
472
+ aexists(this);
473
+ aoutput(out, this);
434
474
  this.finished = true;
435
475
  // Padding
436
476
  // We can avoid allocation of buffer for padding completely if it
@@ -487,10 +527,16 @@ class HashMD extends Hash {
487
527
  }
488
528
  }
489
529
 
490
- // SHA2-256 need to try 2^128 hashes to execute birthday attack.
491
- // BTC network is doing 2^67 hashes/sec as per early 2023.
492
- // Round constants:
493
- // first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
530
+ /**
531
+ * SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
532
+ *
533
+ * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
534
+ * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
535
+ *
536
+ * Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
537
+ * @module
538
+ */
539
+ /** Round constants: first 32 bits of fractional parts of the cube roots of the first 64 primes 2..311). */
494
540
  // prettier-ignore
495
541
  const SHA256_K = /* @__PURE__ */ new Uint32Array([
496
542
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -502,14 +548,15 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
502
548
  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
503
549
  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
504
550
  ]);
505
- // Initial state:
506
- // first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
551
+ /** Initial state: first 32 bits of fractional parts of the square roots of the first 8 primes 2..19. */
507
552
  // prettier-ignore
508
553
  const SHA256_IV = /* @__PURE__ */ new Uint32Array([
509
554
  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
510
555
  ]);
511
- // Temporary buffer, not used to store anything between runs
512
- // Named this way because it matches specification.
556
+ /**
557
+ * Temporary buffer, not used to store anything between runs.
558
+ * Named this way because it matches specification.
559
+ */
513
560
  const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
514
561
  class SHA256 extends HashMD {
515
562
  constructor() {
@@ -586,10 +633,7 @@ class SHA256 extends HashMD {
586
633
  this.buffer.fill(0);
587
634
  }
588
635
  }
589
- /**
590
- * SHA2-256 hash function
591
- * @param message - data that would be hashed
592
- */
636
+ /** SHA2-256 hash function */
593
637
  const sha256$1 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
594
638
 
595
639
  function equals$2(aa, bb) {
@@ -1241,7 +1285,7 @@ new TextDecoder();
1241
1285
 
1242
1286
  /* eslint-disable */
1243
1287
  var encode_1 = encode$7;
1244
- var MSB$1 = 0x80, REST$1 = 0x7F, MSBALL = ~REST$1, INT = Math.pow(2, 31);
1288
+ var MSB$1 = 0x80, MSBALL = -128, INT = Math.pow(2, 31);
1245
1289
  /**
1246
1290
  * @param {number} num
1247
1291
  * @param {number[]} out
@@ -1265,7 +1309,7 @@ function encode$7(num, out, offset) {
1265
1309
  return out;
1266
1310
  }
1267
1311
  var decode$8 = read$1;
1268
- var MSB$1$1 = 0x80, REST$1$1 = 0x7F;
1312
+ var MSB$1$1 = 0x80, REST$1 = 0x7F;
1269
1313
  /**
1270
1314
  * @param {string | any[]} buf
1271
1315
  * @param {number} offset
@@ -1280,8 +1324,8 @@ function read$1(buf, offset) {
1280
1324
  }
1281
1325
  b = buf[counter++];
1282
1326
  res += shift < 28
1283
- ? (b & REST$1$1) << shift
1284
- : (b & REST$1$1) * Math.pow(2, shift);
1327
+ ? (b & REST$1) << shift
1328
+ : (b & REST$1) * Math.pow(2, shift);
1285
1329
  shift += 7;
1286
1330
  } while (b >= MSB$1$1);
1287
1331
  // @ts-ignore
@@ -2326,24 +2370,62 @@ function setup(env) {
2326
2370
  createDebug.names = [];
2327
2371
  createDebug.skips = [];
2328
2372
 
2329
- let i;
2330
- const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
2331
- const len = split.length;
2373
+ const split = (typeof namespaces === 'string' ? namespaces : '')
2374
+ .trim()
2375
+ .replace(' ', ',')
2376
+ .split(',')
2377
+ .filter(Boolean);
2332
2378
 
2333
- for (i = 0; i < len; i++) {
2334
- if (!split[i]) {
2335
- // ignore empty strings
2336
- continue;
2379
+ for (const ns of split) {
2380
+ if (ns[0] === '-') {
2381
+ createDebug.skips.push(ns.slice(1));
2382
+ } else {
2383
+ createDebug.names.push(ns);
2337
2384
  }
2385
+ }
2386
+ }
2338
2387
 
2339
- namespaces = split[i].replace(/\*/g, '.*?');
2340
-
2341
- if (namespaces[0] === '-') {
2342
- createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
2388
+ /**
2389
+ * Checks if the given string matches a namespace template, honoring
2390
+ * asterisks as wildcards.
2391
+ *
2392
+ * @param {String} search
2393
+ * @param {String} template
2394
+ * @return {Boolean}
2395
+ */
2396
+ function matchesTemplate(search, template) {
2397
+ let searchIndex = 0;
2398
+ let templateIndex = 0;
2399
+ let starIndex = -1;
2400
+ let matchIndex = 0;
2401
+
2402
+ while (searchIndex < search.length) {
2403
+ if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
2404
+ // Match character or proceed with wildcard
2405
+ if (template[templateIndex] === '*') {
2406
+ starIndex = templateIndex;
2407
+ matchIndex = searchIndex;
2408
+ templateIndex++; // Skip the '*'
2409
+ } else {
2410
+ searchIndex++;
2411
+ templateIndex++;
2412
+ }
2413
+ } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
2414
+ // Backtrack to the last '*' and try to match more characters
2415
+ templateIndex = starIndex + 1;
2416
+ matchIndex++;
2417
+ searchIndex = matchIndex;
2343
2418
  } else {
2344
- createDebug.names.push(new RegExp('^' + namespaces + '$'));
2419
+ return false; // No match
2345
2420
  }
2346
2421
  }
2422
+
2423
+ // Handle trailing '*' in template
2424
+ while (templateIndex < template.length && template[templateIndex] === '*') {
2425
+ templateIndex++;
2426
+ }
2427
+
2428
+ return templateIndex === template.length;
2347
2429
  }
2348
2430
 
2349
2431
  /**
@@ -2354,8 +2436,8 @@ function setup(env) {
2354
2436
  */
2355
2437
  function disable() {
2356
2438
  const namespaces = [
2357
- ...createDebug.names.map(toNamespace),
2358
- ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
2439
+ ...createDebug.names,
2440
+ ...createDebug.skips.map(namespace => '-' + namespace)
2359
2441
  ].join(',');
2360
2442
  createDebug.enable('');
2361
2443
  return namespaces;
@@ -2369,21 +2451,14 @@ function setup(env) {
2369
2451
  * @api public
2370
2452
  */
2371
2453
  function enabled(name) {
2372
- if (name[name.length - 1] === '*') {
2373
- return true;
2374
- }
2375
-
2376
- let i;
2377
- let len;
2378
-
2379
- for (i = 0, len = createDebug.skips.length; i < len; i++) {
2380
- if (createDebug.skips[i].test(name)) {
2454
+ for (const skip of createDebug.skips) {
2455
+ if (matchesTemplate(name, skip)) {
2381
2456
  return false;
2382
2457
  }
2383
2458
  }
2384
2459
 
2385
- for (i = 0, len = createDebug.names.length; i < len; i++) {
2386
- if (createDebug.names[i].test(name)) {
2460
+ for (const ns of createDebug.names) {
2461
+ if (matchesTemplate(name, ns)) {
2387
2462
  return true;
2388
2463
  }
2389
2464
  }
@@ -2391,19 +2466,6 @@ function setup(env) {
2391
2466
  return false;
2392
2467
  }
2393
2468
 
2394
- /**
2395
- * Convert regexp to namespace
2396
- *
2397
- * @param {RegExp} regxep
2398
- * @return {String} namespace
2399
- * @api private
2400
- */
2401
- function toNamespace(regexp) {
2402
- return regexp.toString()
2403
- .substring(2, regexp.toString().length - 2)
2404
- .replace(/\.\*\?$/, '*');
2405
- }
2406
-
2407
2469
  /**
2408
2470
  * Coerce `val`.
2409
2471
  *
@@ -2565,6 +2627,7 @@ var common = setup;
2565
2627
 
2566
2628
  // Is webkit? http://stackoverflow.com/a/16459606/376773
2567
2629
  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
2630
+ // eslint-disable-next-line no-return-assign
2568
2631
  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
2569
2632
  // Is firebug? http://stackoverflow.com/a/398120/376773
2570
2633
  (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
@@ -3005,10 +3068,10 @@ class JacobianPoint {
3005
3068
  const cond1 = window % 2 !== 0;
3006
3069
  const cond2 = wbits < 0;
3007
3070
  if (wbits === 0) {
3008
- f = f.add(constTimeNegate(cond1, precomputes[offset1]));
3071
+ f = f.add(constTimeNegate$1(cond1, precomputes[offset1]));
3009
3072
  }
3010
3073
  else {
3011
- p = p.add(constTimeNegate(cond2, precomputes[offset2]));
3074
+ p = p.add(constTimeNegate$1(cond2, precomputes[offset2]));
3012
3075
  }
3013
3076
  }
3014
3077
  return { p, f };
@@ -3021,8 +3084,8 @@ class JacobianPoint {
3021
3084
  const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
3022
3085
  let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
3023
3086
  let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
3024
- k1p = constTimeNegate(k1neg, k1p);
3025
- k2p = constTimeNegate(k2neg, k2p);
3087
+ k1p = constTimeNegate$1(k1neg, k1p);
3088
+ k2p = constTimeNegate$1(k2neg, k2p);
3026
3089
  k2p = new JacobianPoint(mod$1(k2p.x * endo.beta), k2p.y, k2p.z);
3027
3090
  point = k1p.add(k2p);
3028
3091
  fake = f1p.add(f2p);
@@ -3054,7 +3117,7 @@ class JacobianPoint {
3054
3117
  }
3055
3118
  JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n$7);
3056
3119
  JacobianPoint.ZERO = new JacobianPoint(_0n$5, _1n$7, _0n$5);
3057
- function constTimeNegate(condition, item) {
3120
+ function constTimeNegate$1(condition, item) {
3058
3121
  const neg = item.negate();
3059
3122
  return condition ? neg : item;
3060
3123
  }
@@ -4974,7 +5037,7 @@ function parseIPv6(input) {
4974
5037
  return parser.new(input).parseWith(() => parser.readIPv6Addr());
4975
5038
  }
4976
5039
  /** Parse `input` into IPv4 or IPv6 bytes. */
4977
- function parseIP(input) {
5040
+ function parseIP(input, mapIPv4ToIPv6 = false) {
4978
5041
  // strip zone index if it is present
4979
5042
  if (input.includes("%")) {
4980
5043
  input = input.split("%")[0];
@@ -4982,7 +5045,14 @@ function parseIP(input) {
4982
5045
  if (input.length > MAX_IPV6_LENGTH) {
4983
5046
  return undefined;
4984
5047
  }
4985
- return parser.new(input).parseWith(() => parser.readIPAddr());
5048
+ const addr = parser.new(input).parseWith(() => parser.readIPAddr());
5049
+ if (!addr) {
5050
+ return undefined;
5051
+ }
5052
+ if (mapIPv4ToIPv6 && addr.length === 4) {
5053
+ return Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, addr[0], addr[1], addr[2], addr[3]]);
5054
+ }
5055
+ return addr;
4986
5056
  }
4987
5057
 
4988
5058
  /** Check if `input` is IPv4. */
@@ -5170,17 +5240,13 @@ function getProtocol(proto) {
5170
5240
  throw new Error(`invalid protocol id type: ${typeof proto}`);
5171
5241
  }
5172
5242
 
5173
- /**
5174
- * @packageDocumentation
5175
- *
5176
- * Provides methods for converting
5177
- */
5178
5243
  getProtocol('ip4');
5179
5244
  getProtocol('ip6');
5180
5245
  getProtocol('ipcidr');
5181
5246
  /**
5182
5247
  * Convert [code,Uint8Array] to string
5183
5248
  */
5249
+ // eslint-disable-next-line complexity
5184
5250
  function convertToString(proto, buf) {
5185
5251
  const protocol = getProtocol(proto);
5186
5252
  switch (protocol.code) {
@@ -5189,6 +5255,8 @@ function convertToString(proto, buf) {
5189
5255
  return bytes2ip(buf);
5190
5256
  case 42: // ipv6zone
5191
5257
  return bytes2str(buf);
5258
+ case 43: // ipcidr
5259
+ return toString$6(buf, 'base10');
5192
5260
  case 6: // tcp
5193
5261
  case 273: // udp
5194
5262
  case 33: // dccp
@@ -5216,6 +5284,7 @@ function convertToString(proto, buf) {
5216
5284
  return toString$6(buf, 'base16'); // no clue. convert to hex
5217
5285
  }
5218
5286
  }
5287
+ // eslint-disable-next-line complexity
5219
5288
  function convertToBytes(proto, str) {
5220
5289
  const protocol = getProtocol(proto);
5221
5290
  switch (protocol.code) {
@@ -5225,6 +5294,8 @@ function convertToBytes(proto, str) {
5225
5294
  return ip2bytes(str);
5226
5295
  case 42: // ipv6zone
5227
5296
  return str2bytes(str);
5297
+ case 43: // ipcidr
5298
+ return fromString(str, 'base10');
5228
5299
  case 6: // tcp
5229
5300
  case 273: // udp
5230
5301
  case 33: // dccp
@@ -5519,19 +5590,6 @@ function ParseError(str) {
5519
5590
  return new Error('Error parsing address: ' + str);
5520
5591
  }
5521
5592
 
5522
- /**
5523
- * @packageDocumentation
5524
- *
5525
- * An implementation of a Multiaddr in JavaScript
5526
- *
5527
- * @example
5528
- *
5529
- * ```js
5530
- * import { multiaddr } from '@multiformats/multiaddr'
5531
- *
5532
- * const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
5533
- * ```
5534
- */
5535
5593
  const inspect$2 = Symbol.for('nodejs.util.inspect.custom');
5536
5594
  const symbol$1 = Symbol.for('@multiformats/js-multiaddr/multiaddr');
5537
5595
  const DNS_CODES = [
@@ -5643,10 +5701,20 @@ class Multiaddr {
5643
5701
  return this.#tuples.map(([code]) => getProtocol(code).name);
5644
5702
  }
5645
5703
  tuples() {
5646
- return this.#tuples;
5704
+ return this.#tuples.map(([code, value]) => {
5705
+ if (value == null) {
5706
+ return [code];
5707
+ }
5708
+ return [code, value];
5709
+ });
5647
5710
  }
5648
5711
  stringTuples() {
5649
- return this.#stringTuples;
5712
+ return this.#stringTuples.map(([code, value]) => {
5713
+ if (value == null) {
5714
+ return [code];
5715
+ }
5716
+ return [code, value];
5717
+ });
5650
5718
  }
5651
5719
  encapsulate(addr) {
5652
5720
  addr = new Multiaddr(addr);
@@ -5776,10 +5844,8 @@ class Multiaddr {
5776
5844
  *
5777
5845
  * ```TypeScript
5778
5846
  * import { multiaddr } from '@multiformats/multiaddr'
5779
- * const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
5780
- * // Multiaddr(/ip4/127.0.0.1/udp/1234)
5781
5847
  *
5782
- * const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
5848
+ * const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
5783
5849
  * // Multiaddr(/ip4/127.0.0.1/udp/1234)
5784
5850
  *
5785
5851
  * addr.bytes
@@ -5818,9 +5884,9 @@ class Multiaddr {
5818
5884
  *
5819
5885
  * ```TypeScript
5820
5886
  * import { multiaddr, resolvers } from '@multiformats/multiaddr'
5821
- * import { dnsaddr } from '@multiformats/multiaddr/resolvers'
5887
+ * import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
5822
5888
  *
5823
- * resolvers.set('dnsaddr', dnsaddr)
5889
+ * resolvers.set('dnsaddr', dnsaddrResolver)
5824
5890
  *
5825
5891
  * const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
5826
5892
  *
@@ -5829,7 +5895,7 @@ class Multiaddr {
5829
5895
  * signal: AbortSignal.timeout(5000)
5830
5896
  * })
5831
5897
  *
5832
- * console.info(await ma.resolve(resolved)
5898
+ * console.info(resolved)
5833
5899
  * // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
5834
5900
  * ```
5835
5901
  *
@@ -5843,7 +5909,9 @@ class Multiaddr {
5843
5909
  * import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
5844
5910
  *
5845
5911
  * const resolver = dns({
5846
- * '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
5912
+ * resolvers: {
5913
+ * '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
5914
+ * }
5847
5915
  * })
5848
5916
  *
5849
5917
  * const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
@@ -5930,44 +5998,12 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
5930
5998
  }
5931
5999
 
5932
6000
  /**
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
6001
+ * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
6002
+ * @todo re-check https://issues.chromium.org/issues/42212588
6003
+ * @module
5939
6004
  */
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';
5955
- }
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
- };
5967
-
5968
6005
  const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
5969
6006
  const _32n = /* @__PURE__ */ BigInt(32);
5970
- // We are not using BigUint64Array, because they are extremely slow as per 2022
5971
6007
  function fromBig(n, le = false) {
5972
6008
  if (le)
5973
6009
  return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
@@ -6024,6 +6060,13 @@ const u64 = {
6024
6060
  add, add3L, add3H, add4L, add4H, add5H, add5L,
6025
6061
  };
6026
6062
 
6063
+ /**
6064
+ * SHA2-512 a.k.a. sha512 and sha384. It is slower than sha256 in js because u64 operations are slow.
6065
+ *
6066
+ * Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
6067
+ * [the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).
6068
+ * @module
6069
+ */
6027
6070
  // Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
6028
6071
  // prettier-ignore
6029
6072
  const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
@@ -6178,8 +6221,13 @@ class SHA512 extends HashMD {
6178
6221
  this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
6179
6222
  }
6180
6223
  }
6224
+ /** SHA2-512 hash function. */
6181
6225
  const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
6182
6226
 
6227
+ /**
6228
+ * Hex, bytes and number utilities.
6229
+ * @module
6230
+ */
6183
6231
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
6184
6232
  // 100 lines of code in the file are duplicated from noble-hashes (utils).
6185
6233
  // This is OK: `abstract` directory does not use noble-hashes.
@@ -6189,8 +6237,7 @@ const _0n$4 = /* @__PURE__ */ BigInt(0);
6189
6237
  const _1n$6 = /* @__PURE__ */ BigInt(1);
6190
6238
  const _2n$4 = /* @__PURE__ */ BigInt(2);
6191
6239
  function isBytes$1(a) {
6192
- return (a instanceof Uint8Array ||
6193
- (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
6240
+ return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
6194
6241
  }
6195
6242
  function abytes(item) {
6196
6243
  if (!isBytes$1(item))
@@ -6198,7 +6245,7 @@ function abytes(item) {
6198
6245
  }
6199
6246
  function abool(title, value) {
6200
6247
  if (typeof value !== 'boolean')
6201
- throw new Error(`${title} must be valid boolean, got "${value}".`);
6248
+ throw new Error(title + ' boolean expected, got ' + value);
6202
6249
  }
6203
6250
  // Array where index 0xf0 (240) is mapped to string 'f0'
6204
6251
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
@@ -6216,23 +6263,22 @@ function bytesToHex(bytes) {
6216
6263
  }
6217
6264
  function numberToHexUnpadded(num) {
6218
6265
  const hex = num.toString(16);
6219
- return hex.length & 1 ? `0${hex}` : hex;
6266
+ return hex.length & 1 ? '0' + hex : hex;
6220
6267
  }
6221
6268
  function hexToNumber(hex) {
6222
6269
  if (typeof hex !== 'string')
6223
6270
  throw new Error('hex string expected, got ' + typeof hex);
6224
- // Big Endian
6225
- return BigInt(hex === '' ? '0' : `0x${hex}`);
6271
+ return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
6226
6272
  }
6227
6273
  // We use optimized technique to convert hex string to byte array
6228
- const asciis = { _0: 48, _9: 57, _A: 65, _F: 70, _a: 97, _f: 102 };
6229
- function asciiToBase16(char) {
6230
- if (char >= asciis._0 && char <= asciis._9)
6231
- return char - asciis._0;
6232
- if (char >= asciis._A && char <= asciis._F)
6233
- return char - (asciis._A - 10);
6234
- if (char >= asciis._a && char <= asciis._f)
6235
- return char - (asciis._a - 10);
6274
+ const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
6275
+ function asciiToBase16(ch) {
6276
+ if (ch >= asciis._0 && ch <= asciis._9)
6277
+ return ch - asciis._0; // '2' => 50-48
6278
+ if (ch >= asciis.A && ch <= asciis.F)
6279
+ return ch - (asciis.A - 10); // 'B' => 66-(65-10)
6280
+ if (ch >= asciis.a && ch <= asciis.f)
6281
+ return ch - (asciis.a - 10); // 'b' => 98-(97-10)
6236
6282
  return;
6237
6283
  }
6238
6284
  /**
@@ -6244,7 +6290,7 @@ function hexToBytes(hex) {
6244
6290
  const hl = hex.length;
6245
6291
  const al = hl / 2;
6246
6292
  if (hl % 2)
6247
- throw new Error('padded hex string expected, got unpadded hex of length ' + hl);
6293
+ throw new Error('hex string expected, got unpadded hex of length ' + hl);
6248
6294
  const array = new Uint8Array(al);
6249
6295
  for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
6250
6296
  const n1 = asciiToBase16(hex.charCodeAt(hi));
@@ -6253,7 +6299,7 @@ function hexToBytes(hex) {
6253
6299
  const char = hex[hi] + hex[hi + 1];
6254
6300
  throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
6255
6301
  }
6256
- array[ai] = n1 * 16 + n2;
6302
+ array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
6257
6303
  }
6258
6304
  return array;
6259
6305
  }
@@ -6291,7 +6337,7 @@ function ensureBytes(title, hex, expectedLength) {
6291
6337
  res = hexToBytes(hex);
6292
6338
  }
6293
6339
  catch (e) {
6294
- throw new Error(`${title} must be valid hex string, got "${hex}". Cause: ${e}`);
6340
+ throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
6295
6341
  }
6296
6342
  }
6297
6343
  else if (isBytes$1(hex)) {
@@ -6300,11 +6346,11 @@ function ensureBytes(title, hex, expectedLength) {
6300
6346
  res = Uint8Array.from(hex);
6301
6347
  }
6302
6348
  else {
6303
- throw new Error(`${title} must be hex string or Uint8Array`);
6349
+ throw new Error(title + ' must be hex string or Uint8Array');
6304
6350
  }
6305
6351
  const len = res.length;
6306
6352
  if (typeof expectedLength === 'number' && len !== expectedLength)
6307
- throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);
6353
+ throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
6308
6354
  return res;
6309
6355
  }
6310
6356
  /**
@@ -6339,7 +6385,7 @@ function equalBytes(a, b) {
6339
6385
  */
6340
6386
  function utf8ToBytes(str) {
6341
6387
  if (typeof str !== 'string')
6342
- throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
6388
+ throw new Error('string expected');
6343
6389
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
6344
6390
  }
6345
6391
  // Is positive bigint
@@ -6359,7 +6405,7 @@ function aInRange(title, n, min, max) {
6359
6405
  // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
6360
6406
  // - our way is the cleanest: `inRange('x', x, 0n, P)
6361
6407
  if (!inRange(n, min, max))
6362
- throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
6408
+ throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);
6363
6409
  }
6364
6410
  // Bit operations
6365
6411
  /**
@@ -6469,12 +6515,12 @@ function validateObject(object, validators, optValidators = {}) {
6469
6515
  const checkField = (fieldName, type, isOptional) => {
6470
6516
  const checkVal = validatorFns[type];
6471
6517
  if (typeof checkVal !== 'function')
6472
- throw new Error(`Invalid validator "${type}", expected function`);
6518
+ throw new Error('invalid validator function');
6473
6519
  const val = object[fieldName];
6474
6520
  if (isOptional && val === undefined)
6475
6521
  return;
6476
6522
  if (!checkVal(val, object)) {
6477
- throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
6523
+ throw new Error('param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val);
6478
6524
  }
6479
6525
  };
6480
6526
  for (const [fieldName, type] of Object.entries(validators))
@@ -6543,14 +6589,17 @@ var ut = /*#__PURE__*/Object.freeze({
6543
6589
  validateObject: validateObject
6544
6590
  });
6545
6591
 
6592
+ /**
6593
+ * Utils for modular division and finite fields.
6594
+ * A finite field over 11 is integer number operations `mod 11`.
6595
+ * There is no division: it is replaced by modular multiplicative inverse.
6596
+ * @module
6597
+ */
6546
6598
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
6547
- // Utilities for modular arithmetics and finite fields
6548
- // prettier-ignore
6549
- const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
6550
6599
  // prettier-ignore
6551
- const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
6600
+ const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = /* @__PURE__ */ BigInt(2), _3n$1 = /* @__PURE__ */ BigInt(3);
6552
6601
  // prettier-ignore
6553
- BigInt(9); BigInt(16);
6602
+ const _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _8n$2 = /* @__PURE__ */ BigInt(8);
6554
6603
  // Calculates a modulo b
6555
6604
  function mod(a, b) {
6556
6605
  const result = a % b;
@@ -6559,13 +6608,15 @@ function mod(a, b) {
6559
6608
  /**
6560
6609
  * Efficiently raise num to power and do modular division.
6561
6610
  * Unsafe in some contexts: uses ladder, so can expose bigint bits.
6611
+ * @todo use field version && remove
6562
6612
  * @example
6563
6613
  * pow(2n, 6n, 11n) // 64n % 11n == 9n
6564
6614
  */
6565
- // TODO: use field version && remove
6566
6615
  function pow(num, power, modulo) {
6567
- if (modulo <= _0n$3 || power < _0n$3)
6568
- throw new Error('Expected power/modulo > 0');
6616
+ if (power < _0n$3)
6617
+ throw new Error('invalid exponent, negatives unsupported');
6618
+ if (modulo <= _0n$3)
6619
+ throw new Error('invalid modulus');
6569
6620
  if (modulo === _1n$5)
6570
6621
  return _0n$3;
6571
6622
  let res = _1n$5;
@@ -6577,7 +6628,7 @@ function pow(num, power, modulo) {
6577
6628
  }
6578
6629
  return res;
6579
6630
  }
6580
- // Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)
6631
+ /** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
6581
6632
  function pow2(x, power, modulo) {
6582
6633
  let res = x;
6583
6634
  while (power-- > _0n$3) {
@@ -6586,12 +6637,15 @@ function pow2(x, power, modulo) {
6586
6637
  }
6587
6638
  return res;
6588
6639
  }
6589
- // Inverses number over modulo
6640
+ /**
6641
+ * Inverses number over modulo.
6642
+ * Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).
6643
+ */
6590
6644
  function invert(number, modulo) {
6591
- if (number === _0n$3 || modulo <= _0n$3) {
6592
- throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
6593
- }
6594
- // Euclidean GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
6645
+ if (number === _0n$3)
6646
+ throw new Error('invert: expected non-zero number');
6647
+ if (modulo <= _0n$3)
6648
+ throw new Error('invert: expected positive modulus, got ' + modulo);
6595
6649
  // Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
6596
6650
  let a = mod(number, modulo);
6597
6651
  let b = modulo;
@@ -6631,8 +6685,11 @@ function tonelliShanks(P) {
6631
6685
  for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
6632
6686
  ;
6633
6687
  // Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
6634
- for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++)
6635
- ;
6688
+ for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++) {
6689
+ // Crash instead of infinity loop, we cannot reasonable count until P.
6690
+ if (Z > 1000)
6691
+ throw new Error('Cannot find square root: likely non-prime P');
6692
+ }
6636
6693
  // Fast-path
6637
6694
  if (S === 1) {
6638
6695
  const p1div4 = (P + _1n$5) / _4n;
@@ -6674,9 +6731,18 @@ function tonelliShanks(P) {
6674
6731
  return x;
6675
6732
  };
6676
6733
  }
6734
+ /**
6735
+ * Square root for a finite field. It will try to check if optimizations are applicable and fall back to 4:
6736
+ *
6737
+ * 1. P ≡ 3 (mod 4)
6738
+ * 2. P ≡ 5 (mod 8)
6739
+ * 3. P ≡ 9 (mod 16)
6740
+ * 4. Tonelli-Shanks algorithm
6741
+ *
6742
+ * Different algorithms can give different roots, it is up to user to decide which one they want.
6743
+ * For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
6744
+ */
6677
6745
  function FpSqrt(P) {
6678
- // NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
6679
- // For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
6680
6746
  // P ≡ 3 (mod 4)
6681
6747
  // √n = n^((P+1)/4)
6682
6748
  if (P % _4n === _3n$1) {
@@ -6740,7 +6806,7 @@ function FpPow(f, num, power) {
6740
6806
  // Should have same speed as pow for bigints
6741
6807
  // TODO: benchmark!
6742
6808
  if (power < _0n$3)
6743
- throw new Error('Expected power > 0');
6809
+ throw new Error('invalid exponent, negatives unsupported');
6744
6810
  if (power === _0n$3)
6745
6811
  return f.ONE;
6746
6812
  if (power === _1n$5)
@@ -6787,15 +6853,15 @@ function nLength(n, nBitLength) {
6787
6853
  return { nBitLength: _nBitLength, nByteLength };
6788
6854
  }
6789
6855
  /**
6790
- * Initializes a finite field over prime. **Non-primes are not supported.**
6791
- * Do not init in loop: slow. Very fragile: always run a benchmark on a change.
6856
+ * Initializes a finite field over prime.
6792
6857
  * Major performance optimizations:
6793
6858
  * * a) denormalized operations like mulN instead of mul
6794
6859
  * * b) same object shape: never add or remove keys
6795
6860
  * * c) Object.freeze
6796
- * NOTE: operations don't check 'isValid' for all elements for performance reasons,
6861
+ * Fragile: always run a benchmark on a change.
6862
+ * Security note: operations don't check 'isValid' for all elements for performance reasons,
6797
6863
  * it is caller responsibility to check this.
6798
- * This is low-level code, please make sure you know what you doing.
6864
+ * This is low-level code, please make sure you know what you're doing.
6799
6865
  * @param ORDER prime positive bigint
6800
6866
  * @param bitLen how many bits the field consumes
6801
6867
  * @param isLE (def: false) if encoding / decoding should be in little-endian
@@ -6803,13 +6869,14 @@ function nLength(n, nBitLength) {
6803
6869
  */
6804
6870
  function Field(ORDER, bitLen, isLE = false, redef = {}) {
6805
6871
  if (ORDER <= _0n$3)
6806
- throw new Error(`Expected Field ORDER > 0, got ${ORDER}`);
6872
+ throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
6807
6873
  const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
6808
6874
  if (BYTES > 2048)
6809
- throw new Error('Field lengths over 2048 bytes are not supported');
6810
- const sqrtP = FpSqrt(ORDER);
6875
+ throw new Error('invalid field: expected ORDER of <= 2048 bytes');
6876
+ let sqrtP; // cached sqrtP
6811
6877
  const f = Object.freeze({
6812
6878
  ORDER,
6879
+ isLE,
6813
6880
  BITS,
6814
6881
  BYTES,
6815
6882
  MASK: bitMask(BITS),
@@ -6818,7 +6885,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6818
6885
  create: (num) => mod(num, ORDER),
6819
6886
  isValid: (num) => {
6820
6887
  if (typeof num !== 'bigint')
6821
- throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
6888
+ throw new Error('invalid field element: expected bigint, got ' + typeof num);
6822
6889
  return _0n$3 <= num && num < ORDER; // 0 is valid element, but it's not invertible
6823
6890
  },
6824
6891
  is0: (num) => num === _0n$3,
@@ -6837,7 +6904,12 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6837
6904
  subN: (lhs, rhs) => lhs - rhs,
6838
6905
  mulN: (lhs, rhs) => lhs * rhs,
6839
6906
  inv: (num) => invert(num, ORDER),
6840
- sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
6907
+ sqrt: redef.sqrt ||
6908
+ ((n) => {
6909
+ if (!sqrtP)
6910
+ sqrtP = FpSqrt(ORDER);
6911
+ return sqrtP(f, n);
6912
+ }),
6841
6913
  invertBatch: (lst) => FpInvertBatch(f, lst),
6842
6914
  // TODO: do we really need constant cmov?
6843
6915
  // We don't have const-time bigints anyway, so probably will be not very useful
@@ -6845,7 +6917,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6845
6917
  toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
6846
6918
  fromBytes: (bytes) => {
6847
6919
  if (bytes.length !== BYTES)
6848
- throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
6920
+ throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
6849
6921
  return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
6850
6922
  },
6851
6923
  });
@@ -6893,52 +6965,80 @@ function mapHashToField(key, fieldOrder, isLE = false) {
6893
6965
  const minLen = getMinHashLength(fieldOrder);
6894
6966
  // No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.
6895
6967
  if (len < 16 || len < minLen || len > 1024)
6896
- throw new Error(`expected ${minLen}-1024 bytes of input, got ${len}`);
6897
- const num = isLE ? bytesToNumberBE(key) : bytesToNumberLE(key);
6968
+ throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
6969
+ const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
6898
6970
  // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
6899
6971
  const reduced = mod(num, fieldOrder - _1n$5) + _1n$5;
6900
6972
  return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
6901
6973
  }
6902
6974
 
6975
+ /**
6976
+ * Methods for elliptic curve multiplication by scalars.
6977
+ * Contains wNAF, pippenger
6978
+ * @module
6979
+ */
6903
6980
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
6904
- // Abelian group utilities
6905
6981
  const _0n$2 = BigInt(0);
6906
6982
  const _1n$4 = BigInt(1);
6983
+ function constTimeNegate(condition, item) {
6984
+ const neg = item.negate();
6985
+ return condition ? neg : item;
6986
+ }
6987
+ function validateW(W, bits) {
6988
+ if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
6989
+ throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);
6990
+ }
6991
+ function calcWOpts(W, bits) {
6992
+ validateW(W, bits);
6993
+ const windows = Math.ceil(bits / W) + 1; // +1, because
6994
+ const windowSize = 2 ** (W - 1); // -1 because we skip zero
6995
+ return { windows, windowSize };
6996
+ }
6997
+ function validateMSMPoints(points, c) {
6998
+ if (!Array.isArray(points))
6999
+ throw new Error('array expected');
7000
+ points.forEach((p, i) => {
7001
+ if (!(p instanceof c))
7002
+ throw new Error('invalid point at index ' + i);
7003
+ });
7004
+ }
7005
+ function validateMSMScalars(scalars, field) {
7006
+ if (!Array.isArray(scalars))
7007
+ throw new Error('array of scalars expected');
7008
+ scalars.forEach((s, i) => {
7009
+ if (!field.isValid(s))
7010
+ throw new Error('invalid scalar at index ' + i);
7011
+ });
7012
+ }
6907
7013
  // Since points in different groups cannot be equal (different object constructor),
6908
7014
  // we can have single place to store precomputes
6909
7015
  const pointPrecomputes = new WeakMap();
6910
7016
  const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
6911
- // Elliptic curve multiplication of Point by scalar. Fragile.
6912
- // Scalars should always be less than curve order: this should be checked inside of a curve itself.
6913
- // Creates precomputation tables for fast multiplication:
6914
- // - private scalar is split by fixed size windows of W bits
6915
- // - every window point is collected from window's table & added to accumulator
6916
- // - since windows are different, same point inside tables won't be accessed more than once per calc
6917
- // - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)
6918
- // - +1 window is neccessary for wNAF
6919
- // - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
6920
- // TODO: Research returning 2d JS array of windows, instead of a single window. This would allow
6921
- // windows to be in different memory locations
7017
+ function getW(P) {
7018
+ return pointWindowSizes.get(P) || 1;
7019
+ }
7020
+ /**
7021
+ * Elliptic curve multiplication of Point by scalar. Fragile.
7022
+ * Scalars should always be less than curve order: this should be checked inside of a curve itself.
7023
+ * Creates precomputation tables for fast multiplication:
7024
+ * - private scalar is split by fixed size windows of W bits
7025
+ * - every window point is collected from window's table & added to accumulator
7026
+ * - since windows are different, same point inside tables won't be accessed more than once per calc
7027
+ * - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)
7028
+ * - +1 window is neccessary for wNAF
7029
+ * - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
7030
+ *
7031
+ * @todo Research returning 2d JS array of windows, instead of a single window.
7032
+ * This would allow windows to be in different memory locations
7033
+ */
6922
7034
  function wNAF(c, bits) {
6923
- const constTimeNegate = (condition, item) => {
6924
- const neg = item.negate();
6925
- return condition ? neg : item;
6926
- };
6927
- const validateW = (W) => {
6928
- if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
6929
- throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
6930
- };
6931
- const opts = (W) => {
6932
- validateW(W);
6933
- const windows = Math.ceil(bits / W) + 1; // +1, because
6934
- const windowSize = 2 ** (W - 1); // -1 because we skip zero
6935
- return { windows, windowSize };
6936
- };
6937
7035
  return {
6938
7036
  constTimeNegate,
7037
+ hasPrecomputes(elm) {
7038
+ return getW(elm) !== 1;
7039
+ },
6939
7040
  // non-const time multiplication ladder
6940
- unsafeLadder(elm, n) {
6941
- let p = c.ZERO;
7041
+ unsafeLadder(elm, n, p = c.ZERO) {
6942
7042
  let d = elm;
6943
7043
  while (n > _0n$2) {
6944
7044
  if (n & _1n$4)
@@ -6956,10 +7056,12 @@ function wNAF(c, bits) {
6956
7056
  * - 𝑊 is the window size
6957
7057
  * - 𝑛 is the bitlength of the curve order.
6958
7058
  * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
7059
+ * @param elm Point instance
7060
+ * @param W window size
6959
7061
  * @returns precomputed point tables flattened to a single array
6960
7062
  */
6961
7063
  precomputeWindow(elm, W) {
6962
- const { windows, windowSize } = opts(W);
7064
+ const { windows, windowSize } = calcWOpts(W, bits);
6963
7065
  const points = [];
6964
7066
  let p = elm;
6965
7067
  let base = p;
@@ -6985,7 +7087,7 @@ function wNAF(c, bits) {
6985
7087
  wNAF(W, precomputes, n) {
6986
7088
  // TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
6987
7089
  // But need to carefully remove other checks before wNAF. ORDER == bits here
6988
- const { windows, windowSize } = opts(W);
7090
+ const { windows, windowSize } = calcWOpts(W, bits);
6989
7091
  let p = c.ZERO;
6990
7092
  let f = c.BASE;
6991
7093
  const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
@@ -7029,8 +7131,44 @@ function wNAF(c, bits) {
7029
7131
  // which makes it less const-time: around 1 bigint multiply.
7030
7132
  return { p, f };
7031
7133
  },
7032
- wNAFCached(P, n, transform) {
7033
- const W = pointWindowSizes.get(P) || 1;
7134
+ /**
7135
+ * Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
7136
+ * @param W window size
7137
+ * @param precomputes precomputed tables
7138
+ * @param n scalar (we don't check here, but should be less than curve order)
7139
+ * @param acc accumulator point to add result of multiplication
7140
+ * @returns point
7141
+ */
7142
+ wNAFUnsafe(W, precomputes, n, acc = c.ZERO) {
7143
+ const { windows, windowSize } = calcWOpts(W, bits);
7144
+ const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
7145
+ const maxNumber = 2 ** W;
7146
+ const shiftBy = BigInt(W);
7147
+ for (let window = 0; window < windows; window++) {
7148
+ const offset = window * windowSize;
7149
+ if (n === _0n$2)
7150
+ break; // No need to go over empty scalar
7151
+ // Extract W bits.
7152
+ let wbits = Number(n & mask);
7153
+ // Shift number by W bits.
7154
+ n >>= shiftBy;
7155
+ // If the bits are bigger than max size, we'll split those.
7156
+ // +224 => 256 - 32
7157
+ if (wbits > windowSize) {
7158
+ wbits -= maxNumber;
7159
+ n += _1n$4;
7160
+ }
7161
+ if (wbits === 0)
7162
+ continue;
7163
+ let curr = precomputes[offset + Math.abs(wbits) - 1]; // -1 because we skip zero
7164
+ if (wbits < 0)
7165
+ curr = curr.negate();
7166
+ // NOTE: by re-using acc, we can save a lot of additions in case of MSM
7167
+ acc = acc.add(curr);
7168
+ }
7169
+ return acc;
7170
+ },
7171
+ getPrecomputes(W, P, transform) {
7034
7172
  // Calculate precomputes on a first run, reuse them after
7035
7173
  let comp = pointPrecomputes.get(P);
7036
7174
  if (!comp) {
@@ -7038,62 +7176,66 @@ function wNAF(c, bits) {
7038
7176
  if (W !== 1)
7039
7177
  pointPrecomputes.set(P, transform(comp));
7040
7178
  }
7041
- return this.wNAF(W, comp, n);
7179
+ return comp;
7180
+ },
7181
+ wNAFCached(P, n, transform) {
7182
+ const W = getW(P);
7183
+ return this.wNAF(W, this.getPrecomputes(W, P, transform), n);
7184
+ },
7185
+ wNAFCachedUnsafe(P, n, transform, prev) {
7186
+ const W = getW(P);
7187
+ if (W === 1)
7188
+ return this.unsafeLadder(P, n, prev); // For W=1 ladder is ~x2 faster
7189
+ return this.wNAFUnsafe(W, this.getPrecomputes(W, P, transform), n, prev);
7042
7190
  },
7043
7191
  // We calculate precomputes for elliptic curve point multiplication
7044
7192
  // using windowed method. This specifies window size and
7045
7193
  // stores precomputed values. Usually only base point would be precomputed.
7046
7194
  setWindowSize(P, W) {
7047
- validateW(W);
7195
+ validateW(W, bits);
7048
7196
  pointWindowSizes.set(P, W);
7049
7197
  pointPrecomputes.delete(P);
7050
7198
  },
7051
7199
  };
7052
7200
  }
7053
7201
  /**
7054
- * Pippenger algorithm for multi-scalar multiplication (MSM).
7055
- * MSM is basically (Pa + Qb + Rc + ...).
7202
+ * Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
7056
7203
  * 30x faster vs naive addition on L=4096, 10x faster with precomputes.
7057
7204
  * For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
7058
7205
  * Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
7059
7206
  * @param c Curve Point constructor
7060
- * @param field field over CURVE.N - important that it's not over CURVE.P
7207
+ * @param fieldN field over CURVE.N - important that it's not over CURVE.P
7061
7208
  * @param points array of L curve points
7062
7209
  * @param scalars array of L scalars (aka private keys / bigints)
7063
7210
  */
7064
- function pippenger(c, field, points, scalars) {
7211
+ function pippenger(c, fieldN, points, scalars) {
7065
7212
  // If we split scalars by some window (let's say 8 bits), every chunk will only
7066
7213
  // take 256 buckets even if there are 4096 scalars, also re-uses double.
7067
7214
  // TODO:
7068
7215
  // - https://eprint.iacr.org/2024/750.pdf
7069
7216
  // - https://tches.iacr.org/index.php/TCHES/article/view/10287
7070
7217
  // 0 is accepted in scalars
7071
- if (!Array.isArray(points) || !Array.isArray(scalars) || scalars.length !== points.length)
7218
+ validateMSMPoints(points, c);
7219
+ validateMSMScalars(scalars, fieldN);
7220
+ if (points.length !== scalars.length)
7072
7221
  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
- });
7222
+ const zero = c.ZERO;
7081
7223
  const wbits = bitLen(BigInt(points.length));
7082
7224
  const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
7083
7225
  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;
7226
+ const buckets = new Array(MASK + 1).fill(zero); // +1 for zero array
7227
+ const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
7228
+ let sum = zero;
7087
7229
  for (let i = lastBits; i >= 0; i -= windowSize) {
7088
- buckets.fill(c.ZERO);
7230
+ buckets.fill(zero);
7089
7231
  for (let j = 0; j < scalars.length; j++) {
7090
7232
  const scalar = scalars[j];
7091
7233
  const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
7092
7234
  buckets[wbits] = buckets[wbits].add(points[j]);
7093
7235
  }
7094
- let resI = c.ZERO; // not using this will do small speed-up, but will lose ct
7236
+ let resI = zero; // not using this will do small speed-up, but will lose ct
7095
7237
  // Skip first bucket, because it is zero
7096
- for (let j = buckets.length - 1, sumI = c.ZERO; j > 0; j--) {
7238
+ for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
7097
7239
  sumI = sumI.add(buckets[j]);
7098
7240
  resI = resI.add(sumI);
7099
7241
  }
@@ -7123,8 +7265,12 @@ function validateBasic(curve) {
7123
7265
  });
7124
7266
  }
7125
7267
 
7268
+ /**
7269
+ * Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y².
7270
+ * For design rationale of types / exports, see weierstrass module documentation.
7271
+ * @module
7272
+ */
7126
7273
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
7127
- // Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
7128
7274
  // Be friendly to bad ECMAScript parsers by not using bigint literals
7129
7275
  // prettier-ignore
7130
7276
  const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
@@ -7156,6 +7302,10 @@ function validateOpts$1(curve) {
7156
7302
  function twistedEdwards(curveDef) {
7157
7303
  const CURVE = validateOpts$1(curveDef);
7158
7304
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
7305
+ // Important:
7306
+ // There are some places where Fp.BYTES is used instead of nByteLength.
7307
+ // So far, everything has been tested with curves of Fp.BYTES == nByteLength.
7308
+ // TODO: test and find curves which behave otherwise.
7159
7309
  const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
7160
7310
  const modP = Fp.create; // Function overrides
7161
7311
  const Fn = Field(CURVE.n, CURVE.nBitLength);
@@ -7369,16 +7519,15 @@ function twistedEdwards(curveDef) {
7369
7519
  // It's faster, but should only be used when you don't care about
7370
7520
  // an exposed private key e.g. sig verification.
7371
7521
  // Does NOT allow scalars higher than CURVE.n.
7372
- multiplyUnsafe(scalar) {
7522
+ // Accepts optional accumulator to merge with multiply (important for sparse scalars)
7523
+ multiplyUnsafe(scalar, acc = Point.ZERO) {
7373
7524
  const n = scalar;
7374
7525
  aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
7375
7526
  if (n === _0n$1)
7376
7527
  return I;
7377
- if (this.equals(I) || n === _1n$3)
7528
+ if (this.is0() || n === _1n$3)
7378
7529
  return this;
7379
- if (this.equals(G))
7380
- return this.wNAF(n).p;
7381
- return wnaf.unsafeLadder(this, n);
7530
+ return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
7382
7531
  }
7383
7532
  // Checks if point is of small order.
7384
7533
  // If you add something to small order point, you will have "dirty"
@@ -7412,8 +7561,9 @@ function twistedEdwards(curveDef) {
7412
7561
  abool('zip215', zip215);
7413
7562
  const normed = hex.slice(); // copy again, we'll manipulate it
7414
7563
  const lastByte = hex[len - 1]; // select last byte
7415
- normed[len - 1] = lastByte & ~0x80; // clear last bit
7564
+ normed[len - 1] = lastByte & -129; // clear last bit
7416
7565
  const y = bytesToNumberLE(normed);
7566
+ // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
7417
7567
  // RFC8032 prohibits >= p, but ZIP215 doesn't
7418
7568
  // zip215=true: 0 <= y < MASK (2^256 for ed25519)
7419
7569
  // zip215=false: 0 <= y < P (2^255-19 for ed25519)
@@ -7462,7 +7612,7 @@ function twistedEdwards(curveDef) {
7462
7612
  }
7463
7613
  /** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
7464
7614
  function getExtendedPublicKey(key) {
7465
- const len = nByteLength;
7615
+ const len = Fp.BYTES;
7466
7616
  key = ensureBytes('private key', key, len);
7467
7617
  // Hash private key with curve's hash function to produce uniformingly random input
7468
7618
  // Check byte lengths: ensure(64, h(ensure(32, key)))
@@ -7495,23 +7645,29 @@ function twistedEdwards(curveDef) {
7495
7645
  const s = modN(r + k * scalar); // S = (r + k * s) mod L
7496
7646
  aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
7497
7647
  const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
7498
- return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
7648
+ return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
7499
7649
  }
7500
7650
  const verifyOpts = VERIFY_DEFAULT;
7651
+ /**
7652
+ * Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
7653
+ * An extended group equation is checked.
7654
+ */
7501
7655
  function verify(sig, msg, publicKey, options = verifyOpts) {
7502
7656
  const { context, zip215 } = options;
7503
7657
  const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
7504
7658
  sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
7505
7659
  msg = ensureBytes('message', msg);
7660
+ publicKey = ensureBytes('publicKey', publicKey, len);
7506
7661
  if (zip215 !== undefined)
7507
7662
  abool('zip215', zip215);
7508
7663
  if (prehash)
7509
7664
  msg = prehash(msg); // for ed25519ph, etc
7510
7665
  const s = bytesToNumberLE(sig.slice(len, 2 * len));
7511
- // zip215: true is good for consensus-critical apps and allows points < 2^256
7512
- // zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
7513
7666
  let A, R, SB;
7514
7667
  try {
7668
+ // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
7669
+ // zip215=true: 0 <= y < MASK (2^256 for ed25519)
7670
+ // zip215=false: 0 <= y < P (2^255-19 for ed25519)
7515
7671
  A = Point.fromHex(publicKey, zip215);
7516
7672
  R = Point.fromHex(sig.slice(0, len), zip215);
7517
7673
  SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
@@ -7523,6 +7679,7 @@ function twistedEdwards(curveDef) {
7523
7679
  return false;
7524
7680
  const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
7525
7681
  const RkA = R.add(A.multiplyUnsafe(k));
7682
+ // Extended group equation
7526
7683
  // [8][S]B = [8]R + [8][k]A'
7527
7684
  return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
7528
7685
  }
@@ -7553,13 +7710,14 @@ function twistedEdwards(curveDef) {
7553
7710
  };
7554
7711
  }
7555
7712
 
7556
- /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
7557
7713
  /**
7558
7714
  * ed25519 Twisted Edwards curve with following addons:
7559
7715
  * - X25519 ECDH
7560
7716
  * - Ristretto cofactor elimination
7561
7717
  * - Elligator hash-to-group / point indistinguishability
7718
+ * @module
7562
7719
  */
7720
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
7563
7721
  const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
7564
7722
  // √(-1) aka √(a) aka 2^((p-1)/4)
7565
7723
  const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
@@ -7618,7 +7776,7 @@ function uvRatio(u, v) {
7618
7776
  x = mod(-x, P);
7619
7777
  return { isValid: useRoot1 || useRoot2, value: x };
7620
7778
  }
7621
- const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
7779
+ const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
7622
7780
  const ed25519Defaults = /* @__PURE__ */ (() => ({
7623
7781
  // Param: a
7624
7782
  a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
@@ -7626,7 +7784,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
7626
7784
  // Negative number is P - number, and division is invert(number, P)
7627
7785
  d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
7628
7786
  // Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
7629
- Fp: Fp$1,
7787
+ Fp,
7630
7788
  // Subgroup order: how many points curve has
7631
7789
  // 2n**252n + 27742317777372353535851937790883648493n;
7632
7790
  n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
@@ -7645,6 +7803,14 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
7645
7803
  }))();
7646
7804
  /**
7647
7805
  * ed25519 curve with EdDSA signatures.
7806
+ * @example
7807
+ * import { ed25519 } from '@noble/curves/ed25519';
7808
+ * const priv = ed25519.utils.randomPrivateKey();
7809
+ * const pub = ed25519.getPublicKey(priv);
7810
+ * const msg = new TextEncoder().encode('hello');
7811
+ * const sig = ed25519.sign(msg, priv);
7812
+ * ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
7813
+ * ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5
7648
7814
  */
7649
7815
  const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
7650
7816
 
@@ -9042,7 +9208,7 @@ var PrivateKey;
9042
9208
  /*!
9043
9209
  * MIT License
9044
9210
  *
9045
- * Copyright (c) 2017-2022 Peculiar Ventures, LLC
9211
+ * Copyright (c) 2017-2024 Peculiar Ventures, LLC
9046
9212
  *
9047
9213
  * Permission is hereby granted, free of charge, to any person obtaining a copy
9048
9214
  * of this software and associated documentation files (the "Software"), to deal
@@ -9154,7 +9320,7 @@ class BufferSourceConverter {
9154
9320
  }
9155
9321
 
9156
9322
  const STRING_TYPE = "string";
9157
- const HEX_REGEX = /^[0-9a-f]+$/i;
9323
+ const HEX_REGEX = /^[0-9a-f\s]+$/i;
9158
9324
  const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
9159
9325
  const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
9160
9326
  class Utf8Converter {
@@ -9388,7 +9554,7 @@ class Convert {
9388
9554
  return base64;
9389
9555
  }
9390
9556
  static formatString(data) {
9391
- return (data === null || data === void 0 ? void 0 : data.replace(/[\n\r\t ]/g, "")) || "";
9557
+ return (data === null || data === undefined ? undefined : data.replace(/[\n\r\t ]/g, "")) || "";
9392
9558
  }
9393
9559
  }
9394
9560
  Convert.DEFAULT_UTF8_ENCODING = "utf8";
@@ -9644,7 +9810,7 @@ function HexBlock(BaseClass) {
9644
9810
  var _a;
9645
9811
  super(...args);
9646
9812
  const params = args[0] || {};
9647
- this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== void 0 ? _a : false;
9813
+ this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== undefined ? _a : false;
9648
9814
  this.valueHexView = params.valueHex ? BufferSourceConverter_1.toUint8Array(params.valueHex) : EMPTY_VIEW;
9649
9815
  }
9650
9816
  get valueHex() {
@@ -9734,11 +9900,11 @@ class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
9734
9900
  var _a, _b, _c, _d;
9735
9901
  super();
9736
9902
  if (idBlock) {
9737
- this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== void 0 ? _a : false;
9903
+ this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== undefined ? _a : false;
9738
9904
  this.valueHexView = idBlock.valueHex ? BufferSourceConverter_1.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
9739
- this.tagClass = (_b = idBlock.tagClass) !== null && _b !== void 0 ? _b : -1;
9740
- this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== void 0 ? _c : -1;
9741
- this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== void 0 ? _d : false;
9905
+ this.tagClass = (_b = idBlock.tagClass) !== null && _b !== undefined ? _b : -1;
9906
+ this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== undefined ? _c : -1;
9907
+ this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== undefined ? _d : false;
9742
9908
  }
9743
9909
  else {
9744
9910
  this.tagClass = -1;
@@ -9905,9 +10071,9 @@ class LocalLengthBlock extends LocalBaseBlock {
9905
10071
  constructor({ lenBlock = {}, } = {}) {
9906
10072
  var _a, _b, _c;
9907
10073
  super();
9908
- this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !== void 0 ? _a : false;
9909
- this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== void 0 ? _b : false;
9910
- this.length = (_c = lenBlock.length) !== null && _c !== void 0 ? _c : 0;
10074
+ this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !== undefined ? _a : false;
10075
+ this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== undefined ? _b : false;
10076
+ this.length = (_c = lenBlock.length) !== null && _c !== undefined ? _c : 0;
9911
10077
  }
9912
10078
  fromBER(inputBuffer, inputOffset, inputLength) {
9913
10079
  const view = BufferSourceConverter_1.toUint8Array(inputBuffer);
@@ -10679,7 +10845,7 @@ var _a$r;
10679
10845
  class OctetString extends BaseBlock {
10680
10846
  constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
10681
10847
  var _b, _c;
10682
- (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length));
10848
+ (_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
10683
10849
  super({
10684
10850
  idBlock: {
10685
10851
  isConstructed: parameters.isConstructed,
@@ -10840,7 +11006,7 @@ var _a$q;
10840
11006
  class BitString extends BaseBlock {
10841
11007
  constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
10842
11008
  var _b, _c;
10843
- (_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length));
11009
+ (_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
10844
11010
  super({
10845
11011
  idBlock: {
10846
11012
  isConstructed: parameters.isConstructed,
@@ -12042,7 +12208,7 @@ class GeneralizedTime extends UTCTime {
12042
12208
  constructor(parameters = {}) {
12043
12209
  var _b;
12044
12210
  super(parameters);
12045
- (_b = this.millisecond) !== null && _b !== void 0 ? _b : (this.millisecond = 0);
12211
+ (_b = this.millisecond) !== null && _b !== undefined ? _b : (this.millisecond = 0);
12046
12212
  this.idBlock.tagClass = 1;
12047
12213
  this.idBlock.tagNumber = 24;
12048
12214
  }
@@ -12465,15 +12631,18 @@ function pkixToRSAPublicKey(bytes) {
12465
12631
  return new RSAPublicKey(jwk, digest);
12466
12632
  }
12467
12633
 
12468
- // HMAC (RFC 2104)
12634
+ /**
12635
+ * HMAC: RFC2104 message authentication code.
12636
+ * @module
12637
+ */
12469
12638
  class HMAC extends Hash {
12470
- constructor(hash$1, _key) {
12639
+ constructor(hash, _key) {
12471
12640
  super();
12472
12641
  this.finished = false;
12473
12642
  this.destroyed = false;
12474
- hash(hash$1);
12643
+ ahash(hash);
12475
12644
  const key = toBytes$1(_key);
12476
- this.iHash = hash$1.create();
12645
+ this.iHash = hash.create();
12477
12646
  if (typeof this.iHash.update !== 'function')
12478
12647
  throw new Error('Expected instance of class which extends utils.Hash');
12479
12648
  this.blockLen = this.iHash.blockLen;
@@ -12481,12 +12650,12 @@ class HMAC extends Hash {
12481
12650
  const blockLen = this.blockLen;
12482
12651
  const pad = new Uint8Array(blockLen);
12483
12652
  // blockLen can be bigger than outputLen
12484
- pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
12653
+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
12485
12654
  for (let i = 0; i < pad.length; i++)
12486
12655
  pad[i] ^= 0x36;
12487
12656
  this.iHash.update(pad);
12488
12657
  // 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();
12658
+ this.oHash = hash.create();
12490
12659
  // Undo internal XOR && apply outer XOR
12491
12660
  for (let i = 0; i < pad.length; i++)
12492
12661
  pad[i] ^= 0x36 ^ 0x5c;
@@ -12494,13 +12663,13 @@ class HMAC extends Hash {
12494
12663
  pad.fill(0);
12495
12664
  }
12496
12665
  update(buf) {
12497
- exists(this);
12666
+ aexists(this);
12498
12667
  this.iHash.update(buf);
12499
12668
  return this;
12500
12669
  }
12501
12670
  digestInto(out) {
12502
- exists(this);
12503
- bytes(out, this.outputLen);
12671
+ aexists(this);
12672
+ abytes$1(out, this.outputLen);
12504
12673
  this.finished = true;
12505
12674
  this.iHash.digestInto(out);
12506
12675
  this.oHash.update(out);
@@ -12544,8 +12713,33 @@ class HMAC extends Hash {
12544
12713
  const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
12545
12714
  hmac.create = (hash, key) => new HMAC(hash, key);
12546
12715
 
12716
+ /**
12717
+ * Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
12718
+ *
12719
+ * ### Design rationale for types
12720
+ *
12721
+ * * Interaction between classes from different curves should fail:
12722
+ * `k256.Point.BASE.add(p256.Point.BASE)`
12723
+ * * For this purpose we want to use `instanceof` operator, which is fast and works during runtime
12724
+ * * Different calls of `curve()` would return different classes -
12725
+ * `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,
12726
+ * it won't affect others
12727
+ *
12728
+ * TypeScript can't infer types for classes created inside a function. Classes is one instance
12729
+ * of nominative types in TypeScript and interfaces only check for shape, so it's hard to create
12730
+ * unique type for every function call.
12731
+ *
12732
+ * We can use generic types via some param, like curve opts, but that would:
12733
+ * 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)
12734
+ * which is hard to debug.
12735
+ * 2. Params can be generic and we can't enforce them to be constant value:
12736
+ * if somebody creates curve from non-constant params,
12737
+ * it would be allowed to interact with other curves with non-constant params
12738
+ *
12739
+ * @todo https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
12740
+ * @module
12741
+ */
12547
12742
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
12548
- // Short Weierstrass curve. The formula is: y² = x³ + ax + b
12549
12743
  function validateSigVerOpts(opts) {
12550
12744
  if (opts.lowS !== undefined)
12551
12745
  abool('lowS', opts.lowS);
@@ -12569,17 +12763,22 @@ function validatePointOpts(curve) {
12569
12763
  const { endo, Fp, a } = opts;
12570
12764
  if (endo) {
12571
12765
  if (!Fp.eql(a, Fp.ZERO)) {
12572
- throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');
12766
+ throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
12573
12767
  }
12574
12768
  if (typeof endo !== 'object' ||
12575
12769
  typeof endo.beta !== 'bigint' ||
12576
12770
  typeof endo.splitScalar !== 'function') {
12577
- throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');
12771
+ throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
12578
12772
  }
12579
12773
  }
12580
12774
  return Object.freeze({ ...opts });
12581
12775
  }
12582
12776
  const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
12777
+ class DERErr extends Error {
12778
+ constructor(m = '') {
12779
+ super(m);
12780
+ }
12781
+ }
12583
12782
  /**
12584
12783
  * ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
12585
12784
  *
@@ -12589,11 +12788,7 @@ const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
12589
12788
  */
12590
12789
  const DER = {
12591
12790
  // asn.1 DER encoding utils
12592
- Err: class DERErr extends Error {
12593
- constructor(m = '') {
12594
- super(m);
12595
- }
12596
- },
12791
+ Err: DERErr,
12597
12792
  // Basic building block is TLV (Tag-Length-Value)
12598
12793
  _tlv: {
12599
12794
  encode: (tag, data) => {
@@ -12608,7 +12803,8 @@ const DER = {
12608
12803
  throw new E('tlv.encode: long form length too big');
12609
12804
  // length of length with long form flag
12610
12805
  const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
12611
- return `${numberToHexUnpadded(tag)}${lenLen}${len}${data}`;
12806
+ const t = numberToHexUnpadded(tag);
12807
+ return t + lenLen + len + data;
12612
12808
  },
12613
12809
  // v - value, l - left bytes (unparsed)
12614
12810
  decode(tag, data) {
@@ -12661,15 +12857,15 @@ const DER = {
12661
12857
  if (Number.parseInt(hex[0], 16) & 0b1000)
12662
12858
  hex = '00' + hex;
12663
12859
  if (hex.length & 1)
12664
- throw new E('unexpected assertion');
12860
+ throw new E('unexpected DER parsing assertion: unpadded hex');
12665
12861
  return hex;
12666
12862
  },
12667
12863
  decode(data) {
12668
12864
  const { Err: E } = DER;
12669
12865
  if (data[0] & 128)
12670
- throw new E('Invalid signature integer: negative');
12866
+ throw new E('invalid signature integer: negative');
12671
12867
  if (data[0] === 0x00 && !(data[1] & 128))
12672
- throw new E('Invalid signature integer: unnecessary leading zero');
12868
+ throw new E('invalid signature integer: unnecessary leading zero');
12673
12869
  return b2n(data);
12674
12870
  },
12675
12871
  },
@@ -12680,16 +12876,18 @@ const DER = {
12680
12876
  abytes(data);
12681
12877
  const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
12682
12878
  if (seqLeftBytes.length)
12683
- throw new E('Invalid signature: left bytes after parsing');
12879
+ throw new E('invalid signature: left bytes after parsing');
12684
12880
  const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
12685
12881
  const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
12686
12882
  if (sLeftBytes.length)
12687
- throw new E('Invalid signature: left bytes after parsing');
12883
+ throw new E('invalid signature: left bytes after parsing');
12688
12884
  return { r: int.decode(rBytes), s: int.decode(sBytes) };
12689
12885
  },
12690
12886
  hexFromSig(sig) {
12691
12887
  const { _tlv: tlv, _int: int } = DER;
12692
- const seq = `${tlv.encode(0x02, int.encode(sig.r))}${tlv.encode(0x02, int.encode(sig.s))}`;
12888
+ const rs = tlv.encode(0x02, int.encode(sig.r));
12889
+ const ss = tlv.encode(0x02, int.encode(sig.s));
12890
+ const seq = rs + ss;
12693
12891
  return tlv.encode(0x30, seq);
12694
12892
  },
12695
12893
  };
@@ -12743,7 +12941,7 @@ function weierstrassPoints(opts) {
12743
12941
  key = bytesToHex(key);
12744
12942
  // Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
12745
12943
  if (typeof key !== 'string' || !lengths.includes(key.length))
12746
- throw new Error('Invalid key');
12944
+ throw new Error('invalid private key');
12747
12945
  key = key.padStart(nByteLength * 2, '0');
12748
12946
  }
12749
12947
  let num;
@@ -12754,7 +12952,7 @@ function weierstrassPoints(opts) {
12754
12952
  : bytesToNumberBE(ensureBytes('private key', key, nByteLength));
12755
12953
  }
12756
12954
  catch (error) {
12757
- throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
12955
+ throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
12758
12956
  }
12759
12957
  if (wrapPrivateKey)
12760
12958
  num = mod(num, N); // disabled by default, enabled for BLS
@@ -12794,7 +12992,7 @@ function weierstrassPoints(opts) {
12794
12992
  if (p.is0()) {
12795
12993
  // (0, 1, 0) aka ZERO is invalid in most contexts.
12796
12994
  // In BLS, ZERO can be serialized, so we allow it.
12797
- // (0, 0, 0) is wrong representation of ZERO and is always invalid.
12995
+ // (0, 0, 0) is invalid representation of ZERO.
12798
12996
  if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
12799
12997
  return;
12800
12998
  throw new Error('bad point: ZERO');
@@ -13018,16 +13216,17 @@ function weierstrassPoints(opts) {
13018
13216
  * an exposed private key e.g. sig verification, which works over *public* keys.
13019
13217
  */
13020
13218
  multiplyUnsafe(sc) {
13021
- aInRange('scalar', sc, _0n, CURVE.n);
13219
+ const { endo, n: N } = CURVE;
13220
+ aInRange('scalar', sc, _0n, N);
13022
13221
  const I = Point.ZERO;
13023
13222
  if (sc === _0n)
13024
13223
  return I;
13025
- if (sc === _1n$1)
13224
+ if (this.is0() || sc === _1n$1)
13026
13225
  return this;
13027
- const { endo } = CURVE;
13028
- if (!endo)
13029
- return wnaf.unsafeLadder(this, sc);
13030
- // Apply endomorphism
13226
+ // Case a: no endomorphism. Case b: has precomputes.
13227
+ if (!endo || wnaf.hasPrecomputes(this))
13228
+ return wnaf.wNAFCachedUnsafe(this, sc, Point.normalizeZ);
13229
+ // Case c: endomorphism
13031
13230
  let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
13032
13231
  let k1p = I;
13033
13232
  let k2p = I;
@@ -13213,7 +13412,9 @@ function weierstrass(curveDef) {
13213
13412
  return { x, y };
13214
13413
  }
13215
13414
  else {
13216
- throw new Error(`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`);
13415
+ const cl = compressedLen;
13416
+ const ul = uncompressedLen;
13417
+ throw new Error('invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len);
13217
13418
  }
13218
13419
  },
13219
13420
  });
@@ -13378,6 +13579,9 @@ function weierstrass(curveDef) {
13378
13579
  // int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
13379
13580
  const bits2int = CURVE.bits2int ||
13380
13581
  function (bytes) {
13582
+ // Our custom check "just in case"
13583
+ if (bytes.length > 8192)
13584
+ throw new Error('input is too large');
13381
13585
  // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
13382
13586
  // for some cases, since bytes.length * 8 is not actual bitLength.
13383
13587
  const num = bytesToNumberBE(bytes); // check for == u8 done here
@@ -13394,15 +13598,15 @@ function weierstrass(curveDef) {
13394
13598
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
13395
13599
  */
13396
13600
  function int2octets(num) {
13397
- aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
13601
+ aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
13398
13602
  // works with order, can have different size than numToField!
13399
13603
  return numberToBytesBE(num, CURVE.nByteLength);
13400
13604
  }
13401
13605
  // Steps A, D of RFC6979 3.2
13402
13606
  // Creates RFC6979 seed; converts msg/privKey to numbers.
13403
13607
  // Used only in sign, not in verify.
13404
- // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order, this will be wrong at least for P521.
13405
- // Also it can be bigger for P224 + SHA256
13608
+ // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
13609
+ // this will be invalid at least for P521. Also it can be bigger for P224 + SHA256
13406
13610
  function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
13407
13611
  if (['recovered', 'canonical'].some((k) => k in opts))
13408
13612
  throw new Error('sign() legacy options not supported');
@@ -13496,39 +13700,48 @@ function weierstrass(curveDef) {
13496
13700
  const sg = signature;
13497
13701
  msgHash = ensureBytes('msgHash', msgHash);
13498
13702
  publicKey = ensureBytes('publicKey', publicKey);
13703
+ const { lowS, prehash, format } = opts;
13704
+ // Verify opts, deduce signature format
13705
+ validateSigVerOpts(opts);
13499
13706
  if ('strict' in opts)
13500
13707
  throw new Error('options.strict was renamed to lowS');
13501
- validateSigVerOpts(opts);
13502
- const { lowS, prehash } = opts;
13708
+ if (format !== undefined && format !== 'compact' && format !== 'der')
13709
+ throw new Error('format must be compact or der');
13710
+ const isHex = typeof sg === 'string' || isBytes$1(sg);
13711
+ const isObj = !isHex &&
13712
+ !format &&
13713
+ typeof sg === 'object' &&
13714
+ sg !== null &&
13715
+ typeof sg.r === 'bigint' &&
13716
+ typeof sg.s === 'bigint';
13717
+ if (!isHex && !isObj)
13718
+ throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
13503
13719
  let _sig = undefined;
13504
13720
  let P;
13505
13721
  try {
13506
- if (typeof sg === 'string' || isBytes$1(sg)) {
13722
+ if (isObj)
13723
+ _sig = new Signature(sg.r, sg.s);
13724
+ if (isHex) {
13507
13725
  // Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
13508
13726
  // Since DER can also be 2*nByteLength bytes, we check for it first.
13509
13727
  try {
13510
- _sig = Signature.fromDER(sg);
13728
+ if (format !== 'compact')
13729
+ _sig = Signature.fromDER(sg);
13511
13730
  }
13512
13731
  catch (derError) {
13513
13732
  if (!(derError instanceof DER.Err))
13514
13733
  throw derError;
13515
- _sig = Signature.fromCompact(sg);
13516
13734
  }
13517
- }
13518
- else if (typeof sg === 'object' && typeof sg.r === 'bigint' && typeof sg.s === 'bigint') {
13519
- const { r, s } = sg;
13520
- _sig = new Signature(r, s);
13521
- }
13522
- else {
13523
- throw new Error('PARSE');
13735
+ if (!_sig && format !== 'der')
13736
+ _sig = Signature.fromCompact(sg);
13524
13737
  }
13525
13738
  P = Point.fromHex(publicKey);
13526
13739
  }
13527
13740
  catch (error) {
13528
- if (error.message === 'PARSE')
13529
- throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
13530
13741
  return false;
13531
13742
  }
13743
+ if (!_sig)
13744
+ return false;
13532
13745
  if (lowS && _sig.hasHighS())
13533
13746
  return false;
13534
13747
  if (prehash)
@@ -13556,8 +13769,12 @@ function weierstrass(curveDef) {
13556
13769
  };
13557
13770
  }
13558
13771
 
13772
+ /**
13773
+ * Utilities for short weierstrass curves, combined with noble-hashes.
13774
+ * @module
13775
+ */
13559
13776
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
13560
- // connects noble-curves to noble-hashes
13777
+ /** connects noble-curves to noble-hashes */
13561
13778
  function getHash(hash) {
13562
13779
  return {
13563
13780
  hash,
@@ -13567,9 +13784,21 @@ function getHash(hash) {
13567
13784
  }
13568
13785
  function createCurve(curveDef, defHash) {
13569
13786
  const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
13570
- return Object.freeze({ ...create(defHash), create });
13787
+ return { ...create(defHash), create };
13571
13788
  }
13572
13789
 
13790
+ /**
13791
+ * NIST secp256k1. See [pdf](https://www.secg.org/sec2-v2.pdf).
13792
+ *
13793
+ * Seems to be rigid (not backdoored)
13794
+ * [as per discussion](https://bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975).
13795
+ *
13796
+ * secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
13797
+ * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
13798
+ * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
13799
+ * [See explanation](https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066).
13800
+ * @module
13801
+ */
13573
13802
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
13574
13803
  const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
13575
13804
  const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
@@ -13600,31 +13829,35 @@ function sqrtMod(y) {
13600
13829
  const t1 = (pow2(b223, _23n, P) * b22) % P;
13601
13830
  const t2 = (pow2(t1, _6n, P) * b2) % P;
13602
13831
  const root = pow2(t2, _2n, P);
13603
- if (!Fp.eql(Fp.sqr(root), y))
13832
+ if (!Fpk1.eql(Fpk1.sqr(root), y))
13604
13833
  throw new Error('Cannot find square root');
13605
13834
  return root;
13606
13835
  }
13607
- const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
13836
+ const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
13608
13837
  /**
13609
13838
  * secp256k1 short weierstrass curve and ECDSA signatures over it.
13839
+ *
13840
+ * @example
13841
+ * import { secp256k1 } from '@noble/curves/secp256k1';
13842
+ *
13843
+ * const priv = secp256k1.utils.randomPrivateKey();
13844
+ * const pub = secp256k1.getPublicKey(priv);
13845
+ * const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
13846
+ * const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
13847
+ * const isValid = secp256k1.verify(sig, msg, pub) === true;
13610
13848
  */
13611
13849
  const secp256k1 = createCurve({
13612
13850
  a: BigInt(0), // equation params: a, b
13613
- b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
13614
- Fp, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
13851
+ b: BigInt(7),
13852
+ Fp: Fpk1, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
13615
13853
  n: secp256k1N, // Curve order, total count of valid points in the field
13616
13854
  // Base point (x, y) aka generator point
13617
13855
  Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
13618
13856
  Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
13619
13857
  h: BigInt(1), // Cofactor
13620
13858
  lowS: true, // Allow only low-S signatures by default in sign() and verify()
13621
- /**
13622
- * secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
13623
- * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
13624
- * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
13625
- * Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
13626
- */
13627
13859
  endo: {
13860
+ // Endomorphism, see above
13628
13861
  beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
13629
13862
  splitScalar: (k) => {
13630
13863
  const n = secp256k1N;
@@ -13767,7 +14000,7 @@ function publicKeyFromMultihash(digest) {
13767
14000
  case KeyType.secp256k1:
13768
14001
  return unmarshalSecp256k1PublicKey(data);
13769
14002
  default:
13770
- throw new UnsupportedKeyTypeError$1();
14003
+ throw new UnsupportedKeyTypeError();
13771
14004
  }
13772
14005
  }
13773
14006
  /**
@@ -13780,28 +14013,6 @@ function publicKeyToProtobuf(key) {
13780
14013
  });
13781
14014
  }
13782
14015
 
13783
- /**
13784
- * All PeerId implementations must use this symbol as the name of a property
13785
- * with a boolean `true` value
13786
- */
13787
- const peerIdSymbol = Symbol.for('@libp2p/peer-id');
13788
-
13789
- /**
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.
13793
- */
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
- }
13803
- }
13804
-
13805
14016
  /**
13806
14017
  * @packageDocumentation
13807
14018
  *
@@ -15660,9 +15871,9 @@ function _copyActual (source, target, targetStart, sourceStart, sourceEnd) {
15660
15871
  const QUERY_FLAG = 0;
15661
15872
  const RESPONSE_FLAG = 1 << 15;
15662
15873
  const FLUSH_MASK = 1 << 15;
15663
- const NOT_FLUSH_MASK = ~FLUSH_MASK;
15874
+ const NOT_FLUSH_MASK = -32769;
15664
15875
  const QU_MASK = 1 << 15;
15665
- const NOT_QU_MASK = ~QU_MASK;
15876
+ const NOT_QU_MASK = -32769;
15666
15877
 
15667
15878
  function codec ({ bytes = 0, encode, decode, encodingLength }) {
15668
15879
  encode.bytes = bytes;
@@ -20047,86 +20258,6 @@ function wakuDnsDiscovery(enrUrls, wantedNodeCapabilityCount = DEFAULT_NODE_REQU
20047
20258
  return (components) => new PeerDiscoveryDns(components, { enrUrls, wantedNodeCapabilityCount });
20048
20259
  }
20049
20260
 
20050
- /**
20051
- * Function to sort peers by latency from lowest to highest
20052
- * @param peerStore - The Libp2p PeerStore
20053
- * @param peers - The list of peers to choose from
20054
- * @returns Sorted array of peers by latency
20055
- */
20056
- async function sortPeersByLatency(peerStore, peers) {
20057
- if (peers.length === 0)
20058
- return [];
20059
- const results = await Promise.all(peers.map(async (peer) => {
20060
- try {
20061
- const pingBytes = (await peerStore.get(peer.id)).metadata.get("ping");
20062
- if (!pingBytes)
20063
- return { peer, ping: Infinity };
20064
- const ping = Number(bytesToUtf8(pingBytes));
20065
- return { peer, ping };
20066
- }
20067
- catch (error) {
20068
- return { peer, ping: Infinity };
20069
- }
20070
- }));
20071
- // filter out null values
20072
- const validResults = results.filter((result) => result !== null);
20073
- return validResults
20074
- .sort((a, b) => a.ping - b.ping)
20075
- .map((result) => result.peer);
20076
- }
20077
- /**
20078
- * Returns the list of peers that supports the given protocol.
20079
- */
20080
- async function getPeersForProtocol(peerStore, protocols) {
20081
- const peers = [];
20082
- await peerStore.forEach((peer) => {
20083
- for (let i = 0; i < protocols.length; i++) {
20084
- if (peer.protocols.includes(protocols[i])) {
20085
- peers.push(peer);
20086
- break;
20087
- }
20088
- }
20089
- });
20090
- return peers;
20091
- }
20092
-
20093
- /**
20094
- * Retrieves a list of peers based on the specified criteria:
20095
- * 1. If numPeers is 0, return all peers
20096
- * 2. Bootstrap peers are prioritized
20097
- * 3. Non-bootstrap peers are randomly selected to fill up to numPeers
20098
- *
20099
- * @param peers - The list of peers to filter from.
20100
- * @param numPeers - The total number of peers to retrieve. If 0, all peers are returned, irrespective of `maxBootstrapPeers`.
20101
- * @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
20102
- * @returns An array of peers based on the specified criteria.
20103
- */
20104
- function filterPeersByDiscovery(peers, numPeers, maxBootstrapPeers) {
20105
- // Collect the bootstrap peers up to the specified maximum
20106
- let bootstrapPeers = peers
20107
- .filter((peer) => peer.tags.has(Tags.BOOTSTRAP))
20108
- .slice(0, maxBootstrapPeers);
20109
- // If numPeers is less than the number of bootstrap peers, adjust the bootstrapPeers array
20110
- if (numPeers > 0 && numPeers < bootstrapPeers.length) {
20111
- bootstrapPeers = bootstrapPeers.slice(0, numPeers);
20112
- }
20113
- // Collect non-bootstrap peers
20114
- const nonBootstrapPeers = peers.filter((peer) => !peer.tags.has(Tags.BOOTSTRAP));
20115
- // If numPeers is 0, return all peers
20116
- if (numPeers === 0) {
20117
- return [...bootstrapPeers, ...nonBootstrapPeers];
20118
- }
20119
- // Initialize the list of selected peers with the bootstrap peers
20120
- const selectedPeers = [...bootstrapPeers];
20121
- // Fill up to numPeers with remaining random peers if needed
20122
- while (selectedPeers.length < numPeers && nonBootstrapPeers.length > 0) {
20123
- const randomIndex = Math.floor(Math.random() * nonBootstrapPeers.length);
20124
- const randomPeer = nonBootstrapPeers.splice(randomIndex, 1)[0];
20125
- selectedPeers.push(randomPeer);
20126
- }
20127
- return selectedPeers;
20128
- }
20129
-
20130
20261
  function selectOpenConnection(connections) {
20131
20262
  return connections
20132
20263
  .filter((c) => c.status === "open")
@@ -20149,36 +20280,36 @@ class StreamManager {
20149
20280
  this.log = new Logger$1(`stream-manager:${multicodec}`);
20150
20281
  this.addEventListener("peer:update", this.handlePeerUpdateStreamPool);
20151
20282
  }
20152
- async getStream(peer) {
20153
- const peerId = peer.id.toString();
20154
- const scheduledStream = this.streamPool.get(peerId);
20283
+ async getStream(peerId) {
20284
+ const peerIdStr = peerId.toString();
20285
+ const scheduledStream = this.streamPool.get(peerIdStr);
20155
20286
  if (scheduledStream) {
20156
- this.streamPool.delete(peerId);
20287
+ this.streamPool.delete(peerIdStr);
20157
20288
  await scheduledStream;
20158
20289
  }
20159
- let stream = this.getOpenStreamForCodec(peer.id);
20290
+ let stream = this.getOpenStreamForCodec(peerId);
20160
20291
  if (stream) {
20161
- this.log.info(`Found existing stream peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20162
- this.lockStream(peer.id.toString(), stream);
20292
+ this.log.info(`Found existing stream peerId=${peerIdStr} multicodec=${this.multicodec}`);
20293
+ this.lockStream(peerIdStr, stream);
20163
20294
  return stream;
20164
20295
  }
20165
- stream = await this.createStream(peer);
20166
- this.lockStream(peer.id.toString(), stream);
20296
+ stream = await this.createStream(peerId);
20297
+ this.lockStream(peerIdStr, stream);
20167
20298
  return stream;
20168
20299
  }
20169
- async createStream(peer, retries = 0) {
20170
- const connections = this.getConnections(peer.id);
20300
+ async createStream(peerId, retries = 0) {
20301
+ const connections = this.getConnections(peerId);
20171
20302
  const connection = selectOpenConnection(connections);
20172
20303
  if (!connection) {
20173
- throw new Error(`Failed to get a connection to the peer peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20304
+ throw new Error(`Failed to get a connection to the peer peerId=${peerId.toString()} multicodec=${this.multicodec}`);
20174
20305
  }
20175
20306
  let lastError;
20176
20307
  let stream;
20177
20308
  for (let i = 0; i < retries + 1; i++) {
20178
20309
  try {
20179
- this.log.info(`Attempting to create a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20310
+ this.log.info(`Attempting to create a stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
20180
20311
  stream = await connection.newStream(this.multicodec);
20181
- this.log.info(`Created stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
20312
+ this.log.info(`Created stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
20182
20313
  break;
20183
20314
  }
20184
20315
  catch (error) {
@@ -20186,8 +20317,7 @@ class StreamManager {
20186
20317
  }
20187
20318
  }
20188
20319
  if (!stream) {
20189
- throw new Error(`Failed to create a new stream for ${peer.id.toString()} -- ` +
20190
- lastError);
20320
+ throw new Error(`Failed to create a new stream for ${peerId.toString()} -- ` + lastError);
20191
20321
  }
20192
20322
  return stream;
20193
20323
  }
@@ -20199,7 +20329,7 @@ class StreamManager {
20199
20329
  }
20200
20330
  try {
20201
20331
  this.ongoingCreation.add(peerId);
20202
- await this.createStream(peer);
20332
+ await this.createStream(peer.id);
20203
20333
  }
20204
20334
  catch (error) {
20205
20335
  this.log.error(`Failed to createStreamWithLock:`, error);
@@ -20260,62 +20390,20 @@ class StreamManager {
20260
20390
  class BaseProtocol {
20261
20391
  multicodec;
20262
20392
  components;
20263
- log;
20264
20393
  pubsubTopics;
20265
20394
  addLibp2pEventListener;
20266
20395
  removeLibp2pEventListener;
20267
20396
  streamManager;
20268
- constructor(multicodec, components, log, pubsubTopics) {
20397
+ constructor(multicodec, components, pubsubTopics) {
20269
20398
  this.multicodec = multicodec;
20270
20399
  this.components = components;
20271
- this.log = log;
20272
20400
  this.pubsubTopics = pubsubTopics;
20273
20401
  this.addLibp2pEventListener = components.events.addEventListener.bind(components.events);
20274
20402
  this.removeLibp2pEventListener = components.events.removeEventListener.bind(components.events);
20275
20403
  this.streamManager = new StreamManager(multicodec, components.connectionManager.getConnections.bind(components.connectionManager), this.addLibp2pEventListener);
20276
20404
  }
20277
- async getStream(peer) {
20278
- return this.streamManager.getStream(peer);
20279
- }
20280
- /**
20281
- * Returns known peers from the address book (`libp2p.peerStore`) that support
20282
- * the class protocol. Waku may or may not be currently connected to these
20283
- * peers.
20284
- */
20285
- async allPeers() {
20286
- return getPeersForProtocol(this.components.peerStore, [this.multicodec]);
20287
- }
20288
- async connectedPeers() {
20289
- const peers = await this.allPeers();
20290
- return peers.filter((peer) => {
20291
- const connections = this.components.connectionManager.getConnections(peer.id);
20292
- return connections.length > 0;
20293
- });
20294
- }
20295
- /**
20296
- * Retrieves a list of connected peers that support the protocol. The list is sorted by latency.
20297
- *
20298
- * @param numPeers - The total number of peers to retrieve. If 0, all peers are returned.
20299
- * @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
20300
- * @returns A list of peers that support the protocol sorted by latency. By default, returns all peers available, including bootstrap.
20301
- */
20302
- async getPeers({ numPeers, maxBootstrapPeers } = {
20303
- maxBootstrapPeers: 0,
20304
- numPeers: 0
20305
- }) {
20306
- // Retrieve all connected peers that support the protocol & shard (if configured)
20307
- const allAvailableConnectedPeers = await this.connectedPeers();
20308
- // Filter the peers based on discovery & number of peers requested
20309
- const filteredPeers = filterPeersByDiscovery(allAvailableConnectedPeers, numPeers, maxBootstrapPeers);
20310
- // Sort the peers by latency
20311
- const sortedFilteredPeers = await sortPeersByLatency(this.components.peerStore, filteredPeers);
20312
- if (sortedFilteredPeers.length === 0) {
20313
- this.log.warn("No peers found. Ensure you have a connection to the network.");
20314
- }
20315
- if (sortedFilteredPeers.length < numPeers) {
20316
- this.log.warn(`Only ${sortedFilteredPeers.length} peers found. Requested ${numPeers}.`);
20317
- }
20318
- return sortedFilteredPeers;
20405
+ async getStream(peerId) {
20406
+ return this.streamManager.getStream(peerId);
20319
20407
  }
20320
20408
  }
20321
20409
 
@@ -23942,6 +24030,105 @@ var WakuMetadataResponse;
23942
24030
  };
23943
24031
  })(WakuMetadataResponse || (WakuMetadataResponse = {}));
23944
24032
 
24033
+ /* eslint-disable import/export */
24034
+ /* eslint-disable complexity */
24035
+ /* eslint-disable @typescript-eslint/no-namespace */
24036
+ /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
24037
+ /* eslint-disable @typescript-eslint/no-empty-interface */
24038
+ var SdsMessage;
24039
+ (function (SdsMessage) {
24040
+ let _codec;
24041
+ SdsMessage.codec = () => {
24042
+ if (_codec == null) {
24043
+ _codec = message((obj, w, opts = {}) => {
24044
+ if (opts.lengthDelimited !== false) {
24045
+ w.fork();
24046
+ }
24047
+ if ((obj.messageId != null && obj.messageId !== '')) {
24048
+ w.uint32(18);
24049
+ w.string(obj.messageId);
24050
+ }
24051
+ if ((obj.channelId != null && obj.channelId !== '')) {
24052
+ w.uint32(26);
24053
+ w.string(obj.channelId);
24054
+ }
24055
+ if (obj.lamportTimestamp != null) {
24056
+ w.uint32(80);
24057
+ w.int32(obj.lamportTimestamp);
24058
+ }
24059
+ if (obj.causalHistory != null) {
24060
+ for (const value of obj.causalHistory) {
24061
+ w.uint32(90);
24062
+ w.string(value);
24063
+ }
24064
+ }
24065
+ if (obj.bloomFilter != null) {
24066
+ w.uint32(98);
24067
+ w.bytes(obj.bloomFilter);
24068
+ }
24069
+ if (obj.content != null) {
24070
+ w.uint32(162);
24071
+ w.bytes(obj.content);
24072
+ }
24073
+ if (opts.lengthDelimited !== false) {
24074
+ w.ldelim();
24075
+ }
24076
+ }, (reader, length, opts = {}) => {
24077
+ const obj = {
24078
+ messageId: '',
24079
+ channelId: '',
24080
+ causalHistory: []
24081
+ };
24082
+ const end = length == null ? reader.len : reader.pos + length;
24083
+ while (reader.pos < end) {
24084
+ const tag = reader.uint32();
24085
+ switch (tag >>> 3) {
24086
+ case 2: {
24087
+ obj.messageId = reader.string();
24088
+ break;
24089
+ }
24090
+ case 3: {
24091
+ obj.channelId = reader.string();
24092
+ break;
24093
+ }
24094
+ case 10: {
24095
+ obj.lamportTimestamp = reader.int32();
24096
+ break;
24097
+ }
24098
+ case 11: {
24099
+ if (opts.limits?.causalHistory != null && obj.causalHistory.length === opts.limits.causalHistory) {
24100
+ throw new MaxLengthError('Decode error - map field "causalHistory" had too many elements');
24101
+ }
24102
+ obj.causalHistory.push(reader.string());
24103
+ break;
24104
+ }
24105
+ case 12: {
24106
+ obj.bloomFilter = reader.bytes();
24107
+ break;
24108
+ }
24109
+ case 20: {
24110
+ obj.content = reader.bytes();
24111
+ break;
24112
+ }
24113
+ default: {
24114
+ reader.skipType(tag & 7);
24115
+ break;
24116
+ }
24117
+ }
24118
+ }
24119
+ return obj;
24120
+ });
24121
+ }
24122
+ return _codec;
24123
+ };
24124
+ SdsMessage.encode = (obj) => {
24125
+ return encodeMessage(obj, SdsMessage.codec());
24126
+ };
24127
+ SdsMessage.decode = (buf, opts) => {
24128
+ return decodeMessage(buf, SdsMessage.codec(), opts);
24129
+ };
24130
+ })(SdsMessage || (SdsMessage = {}));
24131
+
23945
24132
  /**
23946
24133
  * PeerExchangeRPC represents a message conforming to the Waku Peer Exchange protocol
23947
24134
  */
@@ -23992,7 +24179,7 @@ class WakuPeerExchange extends BaseProtocol {
23992
24179
  * @param components - libp2p components
23993
24180
  */
23994
24181
  constructor(components, pubsubTopics) {
23995
- super(PeerExchangeCodec, components, log$2, pubsubTopics);
24182
+ super(PeerExchangeCodec, components, pubsubTopics);
23996
24183
  }
23997
24184
  /**
23998
24185
  * Make a peer exchange query to a peer
@@ -24011,7 +24198,7 @@ class WakuPeerExchange extends BaseProtocol {
24011
24198
  }
24012
24199
  let stream;
24013
24200
  try {
24014
- stream = await this.getStream(peer);
24201
+ stream = await this.getStream(peerId);
24015
24202
  }
24016
24203
  catch (err) {
24017
24204
  log$2.error("Failed to get stream", err);
@@ -24226,7 +24413,7 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
24226
24413
  const existingShardInfoBytes = peer.metadata.get("shardInfo");
24227
24414
  if (existingShardInfoBytes) {
24228
24415
  const existingShardInfo = decodeRelayShard(existingShardInfoBytes);
24229
- if (existingShardInfo || shardInfo) {
24416
+ {
24230
24417
  hasShardDiff =
24231
24418
  existingShardInfo.clusterId !== shardInfo?.clusterId ||
24232
24419
  existingShardInfo.shards.some((shard) => !shardInfo?.shards.includes(shard));
@@ -24274,7 +24461,7 @@ class PeerIdImpl {
24274
24461
  get [Symbol.toStringTag]() {
24275
24462
  return `PeerId(${this.toString()})`;
24276
24463
  }
24277
- [peerIdSymbol$1] = true;
24464
+ [peerIdSymbol] = true;
24278
24465
  toString() {
24279
24466
  if (this.string == null) {
24280
24467
  this.string = base58btc.encode(this.multihash.bytes).slice(1);
@@ -24366,7 +24553,7 @@ class URLPeerId {
24366
24553
  [inspect]() {
24367
24554
  return `PeerId(${this.url})`;
24368
24555
  }
24369
- [peerIdSymbol$1] = true;
24556
+ [peerIdSymbol] = true;
24370
24557
  toString() {
24371
24558
  return this.toCID().toString();
24372
24559
  }
@@ -24414,7 +24601,7 @@ function peerIdFromString(str, decoder) {
24414
24601
  }
24415
24602
  else {
24416
24603
  {
24417
- throw new InvalidParametersError$1('Please pass a multibase decoder for strings that do not start with "1" or "Q"');
24604
+ throw new InvalidParametersError('Please pass a multibase decoder for strings that do not start with "1" or "Q"');
24418
24605
  }
24419
24606
  }
24420
24607
  return peerIdFromMultihash(multihash);