@waku/discovery 0.0.7-c43cec2.0 → 0.0.7-c8128d1.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
@@ -152,43 +152,24 @@ var Protocols;
|
|
152
152
|
})(Protocols || (Protocols = {}));
|
153
153
|
var ProtocolError;
|
154
154
|
(function (ProtocolError) {
|
155
|
-
|
155
|
+
//
|
156
|
+
// GENERAL ERRORS SECTION
|
157
|
+
//
|
158
|
+
/**
|
159
|
+
* Could not determine the origin of the fault. Best to check connectivity and try again
|
160
|
+
* */
|
156
161
|
ProtocolError["GENERIC_FAIL"] = "Generic error";
|
157
162
|
/**
|
158
|
-
*
|
159
|
-
*
|
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.
|
160
166
|
*/
|
161
|
-
ProtocolError["
|
167
|
+
ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
162
168
|
/**
|
163
169
|
* Failure to protobuf decode the message. May be due to a remote peer issue,
|
164
170
|
* ensuring that messages are sent via several peer enable mitigation of this error.
|
165
171
|
*/
|
166
172
|
ProtocolError["DECODE_FAILED"] = "Failed to decode";
|
167
|
-
/**
|
168
|
-
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
169
|
-
* payload is set on the outgoing message.
|
170
|
-
*/
|
171
|
-
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
172
|
-
/**
|
173
|
-
* The message size is above the maximum message size allowed on the Waku Network.
|
174
|
-
* Compressing the message or using an alternative strategy for large messages is recommended.
|
175
|
-
*/
|
176
|
-
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
177
|
-
/**
|
178
|
-
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
179
|
-
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
180
|
-
*/
|
181
|
-
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
182
|
-
/**
|
183
|
-
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
184
|
-
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
185
|
-
*/
|
186
|
-
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
187
|
-
/**
|
188
|
-
* The topics passed in the decoders do not match each other, or don't exist at all.
|
189
|
-
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
190
|
-
*/
|
191
|
-
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
192
173
|
/**
|
193
174
|
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
194
175
|
* Mitigation can be: retrying after a given time period, display connectivity issue
|
@@ -206,37 +187,51 @@ var ProtocolError;
|
|
206
187
|
* or `DECODE_FAILED` can be used.
|
207
188
|
*/
|
208
189
|
ProtocolError["NO_RESPONSE"] = "No response received";
|
190
|
+
//
|
191
|
+
// SEND ERRORS SECTION
|
192
|
+
//
|
209
193
|
/**
|
210
|
-
*
|
211
|
-
*
|
212
|
-
* or `DECODE_FAILED` can be used.
|
194
|
+
* Failure to protobuf encode the message. This is not recoverable and needs
|
195
|
+
* further investigation.
|
213
196
|
*/
|
214
|
-
ProtocolError["
|
197
|
+
ProtocolError["ENCODE_FAILED"] = "Failed to encode";
|
215
198
|
/**
|
216
|
-
* The
|
217
|
-
*
|
199
|
+
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
200
|
+
* payload is set on the outgoing message.
|
218
201
|
*/
|
219
|
-
ProtocolError["
|
202
|
+
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
220
203
|
/**
|
221
|
-
*
|
222
|
-
*
|
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.
|
223
206
|
*/
|
224
|
-
ProtocolError["
|
207
|
+
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
225
208
|
/**
|
226
|
-
*
|
227
|
-
*
|
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.
|
228
211
|
*/
|
229
|
-
ProtocolError["
|
212
|
+
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
230
213
|
/**
|
231
|
-
*
|
232
|
-
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
|
214
|
+
* Fails when
|
233
215
|
*/
|
234
|
-
ProtocolError["
|
216
|
+
ProtocolError["STREAM_ABORTED"] = "Stream aborted";
|
235
217
|
/**
|
236
218
|
* General proof generation error message.
|
237
219
|
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
|
238
220
|
*/
|
239
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";
|
240
235
|
})(ProtocolError || (ProtocolError = {}));
|
241
236
|
|
242
237
|
var Tags;
|
@@ -259,6 +254,10 @@ var EConnectionStateEvents;
|
|
259
254
|
|
260
255
|
const DNS_DISCOVERY_TAG = "@waku/bootstrap";
|
261
256
|
|
257
|
+
var HealthStatusChangeEvents;
|
258
|
+
(function (HealthStatusChangeEvents) {
|
259
|
+
HealthStatusChangeEvents["StatusChange"] = "health:change";
|
260
|
+
})(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
|
262
261
|
var HealthStatus;
|
263
262
|
(function (HealthStatus) {
|
264
263
|
HealthStatus["Unhealthy"] = "Unhealthy";
|
@@ -270,43 +269,55 @@ function isDefined(value) {
|
|
270
269
|
return Boolean(value);
|
271
270
|
}
|
272
271
|
|
273
|
-
|
272
|
+
/**
|
273
|
+
* Internal assertion helpers.
|
274
|
+
* @module
|
275
|
+
*/
|
276
|
+
/** Asserts something is positive integer. */
|
277
|
+
function anumber(n) {
|
274
278
|
if (!Number.isSafeInteger(n) || n < 0)
|
275
|
-
throw new Error(
|
279
|
+
throw new Error('positive integer expected, got ' + n);
|
276
280
|
}
|
277
|
-
|
281
|
+
/** Is number an Uint8Array? Copied from utils for perf. */
|
278
282
|
function isBytes$2(a) {
|
279
|
-
return
|
280
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
283
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
281
284
|
}
|
282
|
-
|
285
|
+
/** Asserts something is Uint8Array. */
|
286
|
+
function abytes$1(b, ...lengths) {
|
283
287
|
if (!isBytes$2(b))
|
284
288
|
throw new Error('Uint8Array expected');
|
285
289
|
if (lengths.length > 0 && !lengths.includes(b.length))
|
286
|
-
throw new Error(
|
290
|
+
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
|
287
291
|
}
|
288
|
-
|
292
|
+
/** Asserts something is hash */
|
293
|
+
function ahash(h) {
|
289
294
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
290
295
|
throw new Error('Hash should be wrapped by utils.wrapConstructor');
|
291
|
-
|
292
|
-
|
296
|
+
anumber(h.outputLen);
|
297
|
+
anumber(h.blockLen);
|
293
298
|
}
|
294
|
-
|
299
|
+
/** Asserts a hash instance has not been destroyed / finished */
|
300
|
+
function aexists(instance, checkFinished = true) {
|
295
301
|
if (instance.destroyed)
|
296
302
|
throw new Error('Hash instance has been destroyed');
|
297
303
|
if (checkFinished && instance.finished)
|
298
304
|
throw new Error('Hash#digest() has already been called');
|
299
305
|
}
|
300
|
-
|
301
|
-
|
306
|
+
/** Asserts output is properly-sized byte array */
|
307
|
+
function aoutput(out, instance) {
|
308
|
+
abytes$1(out);
|
302
309
|
const min = instance.outputLen;
|
303
310
|
if (out.length < min) {
|
304
|
-
throw new Error(
|
311
|
+
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
305
312
|
}
|
306
313
|
}
|
307
314
|
|
308
315
|
const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
309
316
|
|
317
|
+
/**
|
318
|
+
* Utilities for hex, bytes, CSPRNG.
|
319
|
+
* @module
|
320
|
+
*/
|
310
321
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
311
322
|
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
312
323
|
// node.js versions earlier than v19 don't declare it in global scope.
|
@@ -315,16 +326,20 @@ const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? glob
|
|
315
326
|
// Makes the utils un-importable in browsers without a bundler.
|
316
327
|
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
317
328
|
// Cast array to view
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
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
|
+
}
|
322
336
|
/**
|
337
|
+
* Convert JS string to byte array.
|
323
338
|
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
324
339
|
*/
|
325
340
|
function utf8ToBytes$2(str) {
|
326
341
|
if (typeof str !== 'string')
|
327
|
-
throw new Error(
|
342
|
+
throw new Error('utf8ToBytes expected string, got ' + typeof str);
|
328
343
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
329
344
|
}
|
330
345
|
/**
|
@@ -335,7 +350,7 @@ function utf8ToBytes$2(str) {
|
|
335
350
|
function toBytes$1(data) {
|
336
351
|
if (typeof data === 'string')
|
337
352
|
data = utf8ToBytes$2(data);
|
338
|
-
|
353
|
+
abytes$1(data);
|
339
354
|
return data;
|
340
355
|
}
|
341
356
|
/**
|
@@ -345,7 +360,7 @@ function concatBytes$2(...arrays) {
|
|
345
360
|
let sum = 0;
|
346
361
|
for (let i = 0; i < arrays.length; i++) {
|
347
362
|
const a = arrays[i];
|
348
|
-
|
363
|
+
abytes$1(a);
|
349
364
|
sum += a.length;
|
350
365
|
}
|
351
366
|
const res = new Uint8Array(sum);
|
@@ -356,13 +371,14 @@ function concatBytes$2(...arrays) {
|
|
356
371
|
}
|
357
372
|
return res;
|
358
373
|
}
|
359
|
-
|
374
|
+
/** For runtime check if class implements interface */
|
360
375
|
class Hash {
|
361
376
|
// Safe version that clones internal state
|
362
377
|
clone() {
|
363
378
|
return this._cloneInto();
|
364
379
|
}
|
365
380
|
}
|
381
|
+
/** Wraps hash function, creating an interface on top of it */
|
366
382
|
function wrapConstructor(hashCons) {
|
367
383
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
368
384
|
const tmp = hashCons();
|
@@ -371,9 +387,7 @@ function wrapConstructor(hashCons) {
|
|
371
387
|
hashC.create = () => hashCons();
|
372
388
|
return hashC;
|
373
389
|
}
|
374
|
-
/**
|
375
|
-
* Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
|
376
|
-
*/
|
390
|
+
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
|
377
391
|
function randomBytes(bytesLength = 32) {
|
378
392
|
if (crypto$2 && typeof crypto$2.getRandomValues === 'function') {
|
379
393
|
return crypto$2.getRandomValues(new Uint8Array(bytesLength));
|
@@ -386,8 +400,10 @@ function randomBytes(bytesLength = 32) {
|
|
386
400
|
}
|
387
401
|
|
388
402
|
/**
|
389
|
-
*
|
403
|
+
* Internal Merkle-Damgard hash utils.
|
404
|
+
* @module
|
390
405
|
*/
|
406
|
+
/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
|
391
407
|
function setBigUint64(view, byteOffset, value, isLE) {
|
392
408
|
if (typeof view.setBigUint64 === 'function')
|
393
409
|
return view.setBigUint64(byteOffset, value, isLE);
|
@@ -400,14 +416,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
400
416
|
view.setUint32(byteOffset + h, wh, isLE);
|
401
417
|
view.setUint32(byteOffset + l, wl, isLE);
|
402
418
|
}
|
403
|
-
/**
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
/**
|
408
|
-
|
409
|
-
|
410
|
-
|
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
|
+
}
|
411
427
|
/**
|
412
428
|
* Merkle-Damgard hash construction base class.
|
413
429
|
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
@@ -427,7 +443,7 @@ class HashMD extends Hash {
|
|
427
443
|
this.view = createView(this.buffer);
|
428
444
|
}
|
429
445
|
update(data) {
|
430
|
-
|
446
|
+
aexists(this);
|
431
447
|
const { view, buffer, blockLen } = this;
|
432
448
|
data = toBytes$1(data);
|
433
449
|
const len = data.length;
|
@@ -453,8 +469,8 @@ class HashMD extends Hash {
|
|
453
469
|
return this;
|
454
470
|
}
|
455
471
|
digestInto(out) {
|
456
|
-
|
457
|
-
|
472
|
+
aexists(this);
|
473
|
+
aoutput(out, this);
|
458
474
|
this.finished = true;
|
459
475
|
// Padding
|
460
476
|
// We can avoid allocation of buffer for padding completely if it
|
@@ -511,10 +527,16 @@ class HashMD extends Hash {
|
|
511
527
|
}
|
512
528
|
}
|
513
529
|
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
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). */
|
518
540
|
// prettier-ignore
|
519
541
|
const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
520
542
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
@@ -526,14 +548,15 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
526
548
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
527
549
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
528
550
|
]);
|
529
|
-
|
530
|
-
// 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. */
|
531
552
|
// prettier-ignore
|
532
553
|
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
533
554
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
534
555
|
]);
|
535
|
-
|
536
|
-
|
556
|
+
/**
|
557
|
+
* Temporary buffer, not used to store anything between runs.
|
558
|
+
* Named this way because it matches specification.
|
559
|
+
*/
|
537
560
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
538
561
|
class SHA256 extends HashMD {
|
539
562
|
constructor() {
|
@@ -610,10 +633,7 @@ class SHA256 extends HashMD {
|
|
610
633
|
this.buffer.fill(0);
|
611
634
|
}
|
612
635
|
}
|
613
|
-
/**
|
614
|
-
* SHA2-256 hash function
|
615
|
-
* @param message - data that would be hashed
|
616
|
-
*/
|
636
|
+
/** SHA2-256 hash function */
|
617
637
|
const sha256$1 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
618
638
|
|
619
639
|
function equals$2(aa, bb) {
|
@@ -1265,7 +1285,7 @@ new TextDecoder();
|
|
1265
1285
|
|
1266
1286
|
/* eslint-disable */
|
1267
1287
|
var encode_1 = encode$7;
|
1268
|
-
var MSB$1 = 0x80,
|
1288
|
+
var MSB$1 = 0x80, MSBALL = -128, INT = Math.pow(2, 31);
|
1269
1289
|
/**
|
1270
1290
|
* @param {number} num
|
1271
1291
|
* @param {number[]} out
|
@@ -1289,7 +1309,7 @@ function encode$7(num, out, offset) {
|
|
1289
1309
|
return out;
|
1290
1310
|
}
|
1291
1311
|
var decode$8 = read$1;
|
1292
|
-
var MSB$1$1 = 0x80, REST$1
|
1312
|
+
var MSB$1$1 = 0x80, REST$1 = 0x7F;
|
1293
1313
|
/**
|
1294
1314
|
* @param {string | any[]} buf
|
1295
1315
|
* @param {number} offset
|
@@ -1304,8 +1324,8 @@ function read$1(buf, offset) {
|
|
1304
1324
|
}
|
1305
1325
|
b = buf[counter++];
|
1306
1326
|
res += shift < 28
|
1307
|
-
? (b & REST$1
|
1308
|
-
: (b & REST$1
|
1327
|
+
? (b & REST$1) << shift
|
1328
|
+
: (b & REST$1) * Math.pow(2, shift);
|
1309
1329
|
shift += 7;
|
1310
1330
|
} while (b >= MSB$1$1);
|
1311
1331
|
// @ts-ignore
|
@@ -2350,24 +2370,62 @@ function setup(env) {
|
|
2350
2370
|
createDebug.names = [];
|
2351
2371
|
createDebug.skips = [];
|
2352
2372
|
|
2353
|
-
|
2354
|
-
|
2355
|
-
|
2373
|
+
const split = (typeof namespaces === 'string' ? namespaces : '')
|
2374
|
+
.trim()
|
2375
|
+
.replace(' ', ',')
|
2376
|
+
.split(',')
|
2377
|
+
.filter(Boolean);
|
2356
2378
|
|
2357
|
-
for (
|
2358
|
-
if (
|
2359
|
-
|
2360
|
-
|
2379
|
+
for (const ns of split) {
|
2380
|
+
if (ns[0] === '-') {
|
2381
|
+
createDebug.skips.push(ns.slice(1));
|
2382
|
+
} else {
|
2383
|
+
createDebug.names.push(ns);
|
2361
2384
|
}
|
2385
|
+
}
|
2386
|
+
}
|
2362
2387
|
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
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;
|
2367
2418
|
} else {
|
2368
|
-
|
2419
|
+
return false; // No match
|
2369
2420
|
}
|
2370
2421
|
}
|
2422
|
+
|
2423
|
+
// Handle trailing '*' in template
|
2424
|
+
while (templateIndex < template.length && template[templateIndex] === '*') {
|
2425
|
+
templateIndex++;
|
2426
|
+
}
|
2427
|
+
|
2428
|
+
return templateIndex === template.length;
|
2371
2429
|
}
|
2372
2430
|
|
2373
2431
|
/**
|
@@ -2378,8 +2436,8 @@ function setup(env) {
|
|
2378
2436
|
*/
|
2379
2437
|
function disable() {
|
2380
2438
|
const namespaces = [
|
2381
|
-
...createDebug.names
|
2382
|
-
...createDebug.skips.map(
|
2439
|
+
...createDebug.names,
|
2440
|
+
...createDebug.skips.map(namespace => '-' + namespace)
|
2383
2441
|
].join(',');
|
2384
2442
|
createDebug.enable('');
|
2385
2443
|
return namespaces;
|
@@ -2393,21 +2451,14 @@ function setup(env) {
|
|
2393
2451
|
* @api public
|
2394
2452
|
*/
|
2395
2453
|
function enabled(name) {
|
2396
|
-
|
2397
|
-
|
2398
|
-
}
|
2399
|
-
|
2400
|
-
let i;
|
2401
|
-
let len;
|
2402
|
-
|
2403
|
-
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
2404
|
-
if (createDebug.skips[i].test(name)) {
|
2454
|
+
for (const skip of createDebug.skips) {
|
2455
|
+
if (matchesTemplate(name, skip)) {
|
2405
2456
|
return false;
|
2406
2457
|
}
|
2407
2458
|
}
|
2408
2459
|
|
2409
|
-
for (
|
2410
|
-
if (
|
2460
|
+
for (const ns of createDebug.names) {
|
2461
|
+
if (matchesTemplate(name, ns)) {
|
2411
2462
|
return true;
|
2412
2463
|
}
|
2413
2464
|
}
|
@@ -2415,19 +2466,6 @@ function setup(env) {
|
|
2415
2466
|
return false;
|
2416
2467
|
}
|
2417
2468
|
|
2418
|
-
/**
|
2419
|
-
* Convert regexp to namespace
|
2420
|
-
*
|
2421
|
-
* @param {RegExp} regxep
|
2422
|
-
* @return {String} namespace
|
2423
|
-
* @api private
|
2424
|
-
*/
|
2425
|
-
function toNamespace(regexp) {
|
2426
|
-
return regexp.toString()
|
2427
|
-
.substring(2, regexp.toString().length - 2)
|
2428
|
-
.replace(/\.\*\?$/, '*');
|
2429
|
-
}
|
2430
|
-
|
2431
2469
|
/**
|
2432
2470
|
* Coerce `val`.
|
2433
2471
|
*
|
@@ -2589,6 +2627,7 @@ var common = setup;
|
|
2589
2627
|
|
2590
2628
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
2591
2629
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
2630
|
+
// eslint-disable-next-line no-return-assign
|
2592
2631
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
2593
2632
|
// Is firebug? http://stackoverflow.com/a/398120/376773
|
2594
2633
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
@@ -3029,10 +3068,10 @@ class JacobianPoint {
|
|
3029
3068
|
const cond1 = window % 2 !== 0;
|
3030
3069
|
const cond2 = wbits < 0;
|
3031
3070
|
if (wbits === 0) {
|
3032
|
-
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
3071
|
+
f = f.add(constTimeNegate$1(cond1, precomputes[offset1]));
|
3033
3072
|
}
|
3034
3073
|
else {
|
3035
|
-
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
3074
|
+
p = p.add(constTimeNegate$1(cond2, precomputes[offset2]));
|
3036
3075
|
}
|
3037
3076
|
}
|
3038
3077
|
return { p, f };
|
@@ -3045,8 +3084,8 @@ class JacobianPoint {
|
|
3045
3084
|
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
3046
3085
|
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
3047
3086
|
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
3048
|
-
k1p = constTimeNegate(k1neg, k1p);
|
3049
|
-
k2p = constTimeNegate(k2neg, k2p);
|
3087
|
+
k1p = constTimeNegate$1(k1neg, k1p);
|
3088
|
+
k2p = constTimeNegate$1(k2neg, k2p);
|
3050
3089
|
k2p = new JacobianPoint(mod$1(k2p.x * endo.beta), k2p.y, k2p.z);
|
3051
3090
|
point = k1p.add(k2p);
|
3052
3091
|
fake = f1p.add(f2p);
|
@@ -3078,7 +3117,7 @@ class JacobianPoint {
|
|
3078
3117
|
}
|
3079
3118
|
JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n$7);
|
3080
3119
|
JacobianPoint.ZERO = new JacobianPoint(_0n$5, _1n$7, _0n$5);
|
3081
|
-
function constTimeNegate(condition, item) {
|
3120
|
+
function constTimeNegate$1(condition, item) {
|
3082
3121
|
const neg = item.negate();
|
3083
3122
|
return condition ? neg : item;
|
3084
3123
|
}
|
@@ -4998,7 +5037,7 @@ function parseIPv6(input) {
|
|
4998
5037
|
return parser.new(input).parseWith(() => parser.readIPv6Addr());
|
4999
5038
|
}
|
5000
5039
|
/** Parse `input` into IPv4 or IPv6 bytes. */
|
5001
|
-
function parseIP(input) {
|
5040
|
+
function parseIP(input, mapIPv4ToIPv6 = false) {
|
5002
5041
|
// strip zone index if it is present
|
5003
5042
|
if (input.includes("%")) {
|
5004
5043
|
input = input.split("%")[0];
|
@@ -5006,7 +5045,14 @@ function parseIP(input) {
|
|
5006
5045
|
if (input.length > MAX_IPV6_LENGTH) {
|
5007
5046
|
return undefined;
|
5008
5047
|
}
|
5009
|
-
|
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;
|
5010
5056
|
}
|
5011
5057
|
|
5012
5058
|
/** Check if `input` is IPv4. */
|
@@ -5194,17 +5240,13 @@ function getProtocol(proto) {
|
|
5194
5240
|
throw new Error(`invalid protocol id type: ${typeof proto}`);
|
5195
5241
|
}
|
5196
5242
|
|
5197
|
-
/**
|
5198
|
-
* @packageDocumentation
|
5199
|
-
*
|
5200
|
-
* Provides methods for converting
|
5201
|
-
*/
|
5202
5243
|
getProtocol('ip4');
|
5203
5244
|
getProtocol('ip6');
|
5204
5245
|
getProtocol('ipcidr');
|
5205
5246
|
/**
|
5206
5247
|
* Convert [code,Uint8Array] to string
|
5207
5248
|
*/
|
5249
|
+
// eslint-disable-next-line complexity
|
5208
5250
|
function convertToString(proto, buf) {
|
5209
5251
|
const protocol = getProtocol(proto);
|
5210
5252
|
switch (protocol.code) {
|
@@ -5213,6 +5255,8 @@ function convertToString(proto, buf) {
|
|
5213
5255
|
return bytes2ip(buf);
|
5214
5256
|
case 42: // ipv6zone
|
5215
5257
|
return bytes2str(buf);
|
5258
|
+
case 43: // ipcidr
|
5259
|
+
return toString$6(buf, 'base10');
|
5216
5260
|
case 6: // tcp
|
5217
5261
|
case 273: // udp
|
5218
5262
|
case 33: // dccp
|
@@ -5240,6 +5284,7 @@ function convertToString(proto, buf) {
|
|
5240
5284
|
return toString$6(buf, 'base16'); // no clue. convert to hex
|
5241
5285
|
}
|
5242
5286
|
}
|
5287
|
+
// eslint-disable-next-line complexity
|
5243
5288
|
function convertToBytes(proto, str) {
|
5244
5289
|
const protocol = getProtocol(proto);
|
5245
5290
|
switch (protocol.code) {
|
@@ -5249,6 +5294,8 @@ function convertToBytes(proto, str) {
|
|
5249
5294
|
return ip2bytes(str);
|
5250
5295
|
case 42: // ipv6zone
|
5251
5296
|
return str2bytes(str);
|
5297
|
+
case 43: // ipcidr
|
5298
|
+
return fromString(str, 'base10');
|
5252
5299
|
case 6: // tcp
|
5253
5300
|
case 273: // udp
|
5254
5301
|
case 33: // dccp
|
@@ -5543,19 +5590,6 @@ function ParseError(str) {
|
|
5543
5590
|
return new Error('Error parsing address: ' + str);
|
5544
5591
|
}
|
5545
5592
|
|
5546
|
-
/**
|
5547
|
-
* @packageDocumentation
|
5548
|
-
*
|
5549
|
-
* An implementation of a Multiaddr in JavaScript
|
5550
|
-
*
|
5551
|
-
* @example
|
5552
|
-
*
|
5553
|
-
* ```js
|
5554
|
-
* import { multiaddr } from '@multiformats/multiaddr'
|
5555
|
-
*
|
5556
|
-
* const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
5557
|
-
* ```
|
5558
|
-
*/
|
5559
5593
|
const inspect$2 = Symbol.for('nodejs.util.inspect.custom');
|
5560
5594
|
const symbol$1 = Symbol.for('@multiformats/js-multiaddr/multiaddr');
|
5561
5595
|
const DNS_CODES = [
|
@@ -5667,10 +5701,20 @@ class Multiaddr {
|
|
5667
5701
|
return this.#tuples.map(([code]) => getProtocol(code).name);
|
5668
5702
|
}
|
5669
5703
|
tuples() {
|
5670
|
-
return this.#tuples
|
5704
|
+
return this.#tuples.map(([code, value]) => {
|
5705
|
+
if (value == null) {
|
5706
|
+
return [code];
|
5707
|
+
}
|
5708
|
+
return [code, value];
|
5709
|
+
});
|
5671
5710
|
}
|
5672
5711
|
stringTuples() {
|
5673
|
-
return this.#stringTuples
|
5712
|
+
return this.#stringTuples.map(([code, value]) => {
|
5713
|
+
if (value == null) {
|
5714
|
+
return [code];
|
5715
|
+
}
|
5716
|
+
return [code, value];
|
5717
|
+
});
|
5674
5718
|
}
|
5675
5719
|
encapsulate(addr) {
|
5676
5720
|
addr = new Multiaddr(addr);
|
@@ -5800,10 +5844,8 @@ class Multiaddr {
|
|
5800
5844
|
*
|
5801
5845
|
* ```TypeScript
|
5802
5846
|
* import { multiaddr } from '@multiformats/multiaddr'
|
5803
|
-
* const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
|
5804
|
-
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5805
5847
|
*
|
5806
|
-
* const addr = multiaddr(
|
5848
|
+
* const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
|
5807
5849
|
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5808
5850
|
*
|
5809
5851
|
* addr.bytes
|
@@ -5842,9 +5884,9 @@ class Multiaddr {
|
|
5842
5884
|
*
|
5843
5885
|
* ```TypeScript
|
5844
5886
|
* import { multiaddr, resolvers } from '@multiformats/multiaddr'
|
5845
|
-
* import {
|
5887
|
+
* import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
5846
5888
|
*
|
5847
|
-
* resolvers.set('dnsaddr',
|
5889
|
+
* resolvers.set('dnsaddr', dnsaddrResolver)
|
5848
5890
|
*
|
5849
5891
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
5850
5892
|
*
|
@@ -5853,7 +5895,7 @@ class Multiaddr {
|
|
5853
5895
|
* signal: AbortSignal.timeout(5000)
|
5854
5896
|
* })
|
5855
5897
|
*
|
5856
|
-
* console.info(
|
5898
|
+
* console.info(resolved)
|
5857
5899
|
* // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
|
5858
5900
|
* ```
|
5859
5901
|
*
|
@@ -5867,7 +5909,9 @@ class Multiaddr {
|
|
5867
5909
|
* import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
|
5868
5910
|
*
|
5869
5911
|
* const resolver = dns({
|
5870
|
-
*
|
5912
|
+
* resolvers: {
|
5913
|
+
* '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
|
5914
|
+
* }
|
5871
5915
|
* })
|
5872
5916
|
*
|
5873
5917
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
@@ -5953,9 +5997,13 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
|
|
5953
5997
|
return multiaddrFromFields(isIpv6 ? "ip6" : "ip4", protoName, ipVal, protoVal);
|
5954
5998
|
}
|
5955
5999
|
|
6000
|
+
/**
|
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
|
6004
|
+
*/
|
5956
6005
|
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
5957
6006
|
const _32n = /* @__PURE__ */ BigInt(32);
|
5958
|
-
// We are not using BigUint64Array, because they are extremely slow as per 2022
|
5959
6007
|
function fromBig(n, le = false) {
|
5960
6008
|
if (le)
|
5961
6009
|
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
@@ -6012,6 +6060,13 @@ const u64 = {
|
|
6012
6060
|
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
6013
6061
|
};
|
6014
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
|
+
*/
|
6015
6070
|
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
6016
6071
|
// prettier-ignore
|
6017
6072
|
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
@@ -6166,8 +6221,13 @@ class SHA512 extends HashMD {
|
|
6166
6221
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
6167
6222
|
}
|
6168
6223
|
}
|
6224
|
+
/** SHA2-512 hash function. */
|
6169
6225
|
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
6170
6226
|
|
6227
|
+
/**
|
6228
|
+
* Hex, bytes and number utilities.
|
6229
|
+
* @module
|
6230
|
+
*/
|
6171
6231
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6172
6232
|
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
6173
6233
|
// This is OK: `abstract` directory does not use noble-hashes.
|
@@ -6177,8 +6237,7 @@ const _0n$4 = /* @__PURE__ */ BigInt(0);
|
|
6177
6237
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
6178
6238
|
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
6179
6239
|
function isBytes$1(a) {
|
6180
|
-
return
|
6181
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
6240
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
6182
6241
|
}
|
6183
6242
|
function abytes(item) {
|
6184
6243
|
if (!isBytes$1(item))
|
@@ -6186,7 +6245,7 @@ function abytes(item) {
|
|
6186
6245
|
}
|
6187
6246
|
function abool(title, value) {
|
6188
6247
|
if (typeof value !== 'boolean')
|
6189
|
-
throw new Error(
|
6248
|
+
throw new Error(title + ' boolean expected, got ' + value);
|
6190
6249
|
}
|
6191
6250
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6192
6251
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
@@ -6204,23 +6263,22 @@ function bytesToHex(bytes) {
|
|
6204
6263
|
}
|
6205
6264
|
function numberToHexUnpadded(num) {
|
6206
6265
|
const hex = num.toString(16);
|
6207
|
-
return hex.length & 1 ?
|
6266
|
+
return hex.length & 1 ? '0' + hex : hex;
|
6208
6267
|
}
|
6209
6268
|
function hexToNumber(hex) {
|
6210
6269
|
if (typeof hex !== 'string')
|
6211
6270
|
throw new Error('hex string expected, got ' + typeof hex);
|
6212
|
-
// Big Endian
|
6213
|
-
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
6271
|
+
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
6214
6272
|
}
|
6215
6273
|
// We use optimized technique to convert hex string to byte array
|
6216
|
-
const asciis = { _0: 48, _9: 57,
|
6217
|
-
function asciiToBase16(
|
6218
|
-
if (
|
6219
|
-
return
|
6220
|
-
if (
|
6221
|
-
return
|
6222
|
-
if (
|
6223
|
-
return
|
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)
|
6224
6282
|
return;
|
6225
6283
|
}
|
6226
6284
|
/**
|
@@ -6232,7 +6290,7 @@ function hexToBytes(hex) {
|
|
6232
6290
|
const hl = hex.length;
|
6233
6291
|
const al = hl / 2;
|
6234
6292
|
if (hl % 2)
|
6235
|
-
throw new Error('
|
6293
|
+
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
6236
6294
|
const array = new Uint8Array(al);
|
6237
6295
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
6238
6296
|
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
@@ -6241,7 +6299,7 @@ function hexToBytes(hex) {
|
|
6241
6299
|
const char = hex[hi] + hex[hi + 1];
|
6242
6300
|
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
6243
6301
|
}
|
6244
|
-
array[ai] = n1 * 16 + n2;
|
6302
|
+
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
|
6245
6303
|
}
|
6246
6304
|
return array;
|
6247
6305
|
}
|
@@ -6279,7 +6337,7 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6279
6337
|
res = hexToBytes(hex);
|
6280
6338
|
}
|
6281
6339
|
catch (e) {
|
6282
|
-
throw new Error(
|
6340
|
+
throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
|
6283
6341
|
}
|
6284
6342
|
}
|
6285
6343
|
else if (isBytes$1(hex)) {
|
@@ -6288,11 +6346,11 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6288
6346
|
res = Uint8Array.from(hex);
|
6289
6347
|
}
|
6290
6348
|
else {
|
6291
|
-
throw new Error(
|
6349
|
+
throw new Error(title + ' must be hex string or Uint8Array');
|
6292
6350
|
}
|
6293
6351
|
const len = res.length;
|
6294
6352
|
if (typeof expectedLength === 'number' && len !== expectedLength)
|
6295
|
-
throw new Error(
|
6353
|
+
throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
|
6296
6354
|
return res;
|
6297
6355
|
}
|
6298
6356
|
/**
|
@@ -6327,7 +6385,7 @@ function equalBytes(a, b) {
|
|
6327
6385
|
*/
|
6328
6386
|
function utf8ToBytes(str) {
|
6329
6387
|
if (typeof str !== 'string')
|
6330
|
-
throw new Error(
|
6388
|
+
throw new Error('string expected');
|
6331
6389
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6332
6390
|
}
|
6333
6391
|
// Is positive bigint
|
@@ -6347,7 +6405,7 @@ function aInRange(title, n, min, max) {
|
|
6347
6405
|
// - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
|
6348
6406
|
// - our way is the cleanest: `inRange('x', x, 0n, P)
|
6349
6407
|
if (!inRange(n, min, max))
|
6350
|
-
throw new Error(
|
6408
|
+
throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);
|
6351
6409
|
}
|
6352
6410
|
// Bit operations
|
6353
6411
|
/**
|
@@ -6457,12 +6515,12 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6457
6515
|
const checkField = (fieldName, type, isOptional) => {
|
6458
6516
|
const checkVal = validatorFns[type];
|
6459
6517
|
if (typeof checkVal !== 'function')
|
6460
|
-
throw new Error(
|
6518
|
+
throw new Error('invalid validator function');
|
6461
6519
|
const val = object[fieldName];
|
6462
6520
|
if (isOptional && val === undefined)
|
6463
6521
|
return;
|
6464
6522
|
if (!checkVal(val, object)) {
|
6465
|
-
throw new Error(
|
6523
|
+
throw new Error('param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val);
|
6466
6524
|
}
|
6467
6525
|
};
|
6468
6526
|
for (const [fieldName, type] of Object.entries(validators))
|
@@ -6531,14 +6589,17 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6531
6589
|
validateObject: validateObject
|
6532
6590
|
});
|
6533
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
|
+
*/
|
6534
6598
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6535
|
-
// Utilities for modular arithmetics and finite fields
|
6536
6599
|
// prettier-ignore
|
6537
|
-
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
|
6600
|
+
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = /* @__PURE__ */ BigInt(2), _3n$1 = /* @__PURE__ */ BigInt(3);
|
6538
6601
|
// prettier-ignore
|
6539
|
-
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
|
6540
|
-
// prettier-ignore
|
6541
|
-
BigInt(9); BigInt(16);
|
6602
|
+
const _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _8n$2 = /* @__PURE__ */ BigInt(8);
|
6542
6603
|
// Calculates a modulo b
|
6543
6604
|
function mod(a, b) {
|
6544
6605
|
const result = a % b;
|
@@ -6547,13 +6608,15 @@ function mod(a, b) {
|
|
6547
6608
|
/**
|
6548
6609
|
* Efficiently raise num to power and do modular division.
|
6549
6610
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
6611
|
+
* @todo use field version && remove
|
6550
6612
|
* @example
|
6551
6613
|
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
6552
6614
|
*/
|
6553
|
-
// TODO: use field version && remove
|
6554
6615
|
function pow(num, power, modulo) {
|
6555
|
-
if (
|
6556
|
-
throw new Error('
|
6616
|
+
if (power < _0n$3)
|
6617
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6618
|
+
if (modulo <= _0n$3)
|
6619
|
+
throw new Error('invalid modulus');
|
6557
6620
|
if (modulo === _1n$5)
|
6558
6621
|
return _0n$3;
|
6559
6622
|
let res = _1n$5;
|
@@ -6565,7 +6628,7 @@ function pow(num, power, modulo) {
|
|
6565
6628
|
}
|
6566
6629
|
return res;
|
6567
6630
|
}
|
6568
|
-
|
6631
|
+
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
6569
6632
|
function pow2(x, power, modulo) {
|
6570
6633
|
let res = x;
|
6571
6634
|
while (power-- > _0n$3) {
|
@@ -6574,12 +6637,15 @@ function pow2(x, power, modulo) {
|
|
6574
6637
|
}
|
6575
6638
|
return res;
|
6576
6639
|
}
|
6577
|
-
|
6640
|
+
/**
|
6641
|
+
* Inverses number over modulo.
|
6642
|
+
* Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).
|
6643
|
+
*/
|
6578
6644
|
function invert(number, modulo) {
|
6579
|
-
if (number === _0n$3
|
6580
|
-
throw new Error(
|
6581
|
-
|
6582
|
-
|
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);
|
6583
6649
|
// Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
|
6584
6650
|
let a = mod(number, modulo);
|
6585
6651
|
let b = modulo;
|
@@ -6619,8 +6685,11 @@ function tonelliShanks(P) {
|
|
6619
6685
|
for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
|
6620
6686
|
;
|
6621
6687
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
6622
|
-
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++)
|
6623
|
-
|
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
|
+
}
|
6624
6693
|
// Fast-path
|
6625
6694
|
if (S === 1) {
|
6626
6695
|
const p1div4 = (P + _1n$5) / _4n;
|
@@ -6662,9 +6731,18 @@ function tonelliShanks(P) {
|
|
6662
6731
|
return x;
|
6663
6732
|
};
|
6664
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
|
+
*/
|
6665
6745
|
function FpSqrt(P) {
|
6666
|
-
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
6667
|
-
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
6668
6746
|
// P ≡ 3 (mod 4)
|
6669
6747
|
// √n = n^((P+1)/4)
|
6670
6748
|
if (P % _4n === _3n$1) {
|
@@ -6728,7 +6806,7 @@ function FpPow(f, num, power) {
|
|
6728
6806
|
// Should have same speed as pow for bigints
|
6729
6807
|
// TODO: benchmark!
|
6730
6808
|
if (power < _0n$3)
|
6731
|
-
throw new Error('
|
6809
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6732
6810
|
if (power === _0n$3)
|
6733
6811
|
return f.ONE;
|
6734
6812
|
if (power === _1n$5)
|
@@ -6775,15 +6853,15 @@ function nLength(n, nBitLength) {
|
|
6775
6853
|
return { nBitLength: _nBitLength, nByteLength };
|
6776
6854
|
}
|
6777
6855
|
/**
|
6778
|
-
* Initializes a finite field over prime.
|
6779
|
-
* Do not init in loop: slow. Very fragile: always run a benchmark on a change.
|
6856
|
+
* Initializes a finite field over prime.
|
6780
6857
|
* Major performance optimizations:
|
6781
6858
|
* * a) denormalized operations like mulN instead of mul
|
6782
6859
|
* * b) same object shape: never add or remove keys
|
6783
6860
|
* * c) Object.freeze
|
6784
|
-
*
|
6861
|
+
* Fragile: always run a benchmark on a change.
|
6862
|
+
* Security note: operations don't check 'isValid' for all elements for performance reasons,
|
6785
6863
|
* it is caller responsibility to check this.
|
6786
|
-
* 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.
|
6787
6865
|
* @param ORDER prime positive bigint
|
6788
6866
|
* @param bitLen how many bits the field consumes
|
6789
6867
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6791,13 +6869,14 @@ function nLength(n, nBitLength) {
|
|
6791
6869
|
*/
|
6792
6870
|
function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
6793
6871
|
if (ORDER <= _0n$3)
|
6794
|
-
throw new Error(
|
6872
|
+
throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
|
6795
6873
|
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
6796
6874
|
if (BYTES > 2048)
|
6797
|
-
throw new Error('
|
6798
|
-
|
6875
|
+
throw new Error('invalid field: expected ORDER of <= 2048 bytes');
|
6876
|
+
let sqrtP; // cached sqrtP
|
6799
6877
|
const f = Object.freeze({
|
6800
6878
|
ORDER,
|
6879
|
+
isLE,
|
6801
6880
|
BITS,
|
6802
6881
|
BYTES,
|
6803
6882
|
MASK: bitMask(BITS),
|
@@ -6806,7 +6885,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6806
6885
|
create: (num) => mod(num, ORDER),
|
6807
6886
|
isValid: (num) => {
|
6808
6887
|
if (typeof num !== 'bigint')
|
6809
|
-
throw new Error(
|
6888
|
+
throw new Error('invalid field element: expected bigint, got ' + typeof num);
|
6810
6889
|
return _0n$3 <= num && num < ORDER; // 0 is valid element, but it's not invertible
|
6811
6890
|
},
|
6812
6891
|
is0: (num) => num === _0n$3,
|
@@ -6825,7 +6904,12 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6825
6904
|
subN: (lhs, rhs) => lhs - rhs,
|
6826
6905
|
mulN: (lhs, rhs) => lhs * rhs,
|
6827
6906
|
inv: (num) => invert(num, ORDER),
|
6828
|
-
sqrt: redef.sqrt ||
|
6907
|
+
sqrt: redef.sqrt ||
|
6908
|
+
((n) => {
|
6909
|
+
if (!sqrtP)
|
6910
|
+
sqrtP = FpSqrt(ORDER);
|
6911
|
+
return sqrtP(f, n);
|
6912
|
+
}),
|
6829
6913
|
invertBatch: (lst) => FpInvertBatch(f, lst),
|
6830
6914
|
// TODO: do we really need constant cmov?
|
6831
6915
|
// We don't have const-time bigints anyway, so probably will be not very useful
|
@@ -6833,7 +6917,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6833
6917
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
6834
6918
|
fromBytes: (bytes) => {
|
6835
6919
|
if (bytes.length !== BYTES)
|
6836
|
-
throw new Error(
|
6920
|
+
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
6837
6921
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
6838
6922
|
},
|
6839
6923
|
});
|
@@ -6881,52 +6965,80 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6881
6965
|
const minLen = getMinHashLength(fieldOrder);
|
6882
6966
|
// No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.
|
6883
6967
|
if (len < 16 || len < minLen || len > 1024)
|
6884
|
-
throw new Error(
|
6885
|
-
const num = isLE ?
|
6968
|
+
throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
|
6969
|
+
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
6886
6970
|
// `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
|
6887
6971
|
const reduced = mod(num, fieldOrder - _1n$5) + _1n$5;
|
6888
6972
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
6889
6973
|
}
|
6890
6974
|
|
6975
|
+
/**
|
6976
|
+
* Methods for elliptic curve multiplication by scalars.
|
6977
|
+
* Contains wNAF, pippenger
|
6978
|
+
* @module
|
6979
|
+
*/
|
6891
6980
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6892
|
-
// Abelian group utilities
|
6893
6981
|
const _0n$2 = BigInt(0);
|
6894
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
|
+
}
|
6895
7013
|
// Since points in different groups cannot be equal (different object constructor),
|
6896
7014
|
// we can have single place to store precomputes
|
6897
7015
|
const pointPrecomputes = new WeakMap();
|
6898
7016
|
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
6899
|
-
|
6900
|
-
|
6901
|
-
|
6902
|
-
|
6903
|
-
|
6904
|
-
|
6905
|
-
|
6906
|
-
|
6907
|
-
|
6908
|
-
|
6909
|
-
|
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
|
+
*/
|
6910
7034
|
function wNAF(c, bits) {
|
6911
|
-
const constTimeNegate = (condition, item) => {
|
6912
|
-
const neg = item.negate();
|
6913
|
-
return condition ? neg : item;
|
6914
|
-
};
|
6915
|
-
const validateW = (W) => {
|
6916
|
-
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6917
|
-
throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
|
6918
|
-
};
|
6919
|
-
const opts = (W) => {
|
6920
|
-
validateW(W);
|
6921
|
-
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6922
|
-
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6923
|
-
return { windows, windowSize };
|
6924
|
-
};
|
6925
7035
|
return {
|
6926
7036
|
constTimeNegate,
|
7037
|
+
hasPrecomputes(elm) {
|
7038
|
+
return getW(elm) !== 1;
|
7039
|
+
},
|
6927
7040
|
// non-const time multiplication ladder
|
6928
|
-
unsafeLadder(elm, n) {
|
6929
|
-
let p = c.ZERO;
|
7041
|
+
unsafeLadder(elm, n, p = c.ZERO) {
|
6930
7042
|
let d = elm;
|
6931
7043
|
while (n > _0n$2) {
|
6932
7044
|
if (n & _1n$4)
|
@@ -6944,10 +7056,12 @@ function wNAF(c, bits) {
|
|
6944
7056
|
* - 𝑊 is the window size
|
6945
7057
|
* - 𝑛 is the bitlength of the curve order.
|
6946
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
|
6947
7061
|
* @returns precomputed point tables flattened to a single array
|
6948
7062
|
*/
|
6949
7063
|
precomputeWindow(elm, W) {
|
6950
|
-
const { windows, windowSize } =
|
7064
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6951
7065
|
const points = [];
|
6952
7066
|
let p = elm;
|
6953
7067
|
let base = p;
|
@@ -6973,7 +7087,7 @@ function wNAF(c, bits) {
|
|
6973
7087
|
wNAF(W, precomputes, n) {
|
6974
7088
|
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
6975
7089
|
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
6976
|
-
const { windows, windowSize } =
|
7090
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6977
7091
|
let p = c.ZERO;
|
6978
7092
|
let f = c.BASE;
|
6979
7093
|
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
@@ -7017,8 +7131,44 @@ function wNAF(c, bits) {
|
|
7017
7131
|
// which makes it less const-time: around 1 bigint multiply.
|
7018
7132
|
return { p, f };
|
7019
7133
|
},
|
7020
|
-
|
7021
|
-
|
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) {
|
7022
7172
|
// Calculate precomputes on a first run, reuse them after
|
7023
7173
|
let comp = pointPrecomputes.get(P);
|
7024
7174
|
if (!comp) {
|
@@ -7026,62 +7176,66 @@ function wNAF(c, bits) {
|
|
7026
7176
|
if (W !== 1)
|
7027
7177
|
pointPrecomputes.set(P, transform(comp));
|
7028
7178
|
}
|
7029
|
-
return
|
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);
|
7030
7190
|
},
|
7031
7191
|
// We calculate precomputes for elliptic curve point multiplication
|
7032
7192
|
// using windowed method. This specifies window size and
|
7033
7193
|
// stores precomputed values. Usually only base point would be precomputed.
|
7034
7194
|
setWindowSize(P, W) {
|
7035
|
-
validateW(W);
|
7195
|
+
validateW(W, bits);
|
7036
7196
|
pointWindowSizes.set(P, W);
|
7037
7197
|
pointPrecomputes.delete(P);
|
7038
7198
|
},
|
7039
7199
|
};
|
7040
7200
|
}
|
7041
7201
|
/**
|
7042
|
-
* Pippenger algorithm for multi-scalar multiplication (MSM).
|
7043
|
-
* MSM is basically (Pa + Qb + Rc + ...).
|
7202
|
+
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
7044
7203
|
* 30x faster vs naive addition on L=4096, 10x faster with precomputes.
|
7045
7204
|
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
7046
7205
|
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
7047
7206
|
* @param c Curve Point constructor
|
7048
|
-
* @param
|
7207
|
+
* @param fieldN field over CURVE.N - important that it's not over CURVE.P
|
7049
7208
|
* @param points array of L curve points
|
7050
7209
|
* @param scalars array of L scalars (aka private keys / bigints)
|
7051
7210
|
*/
|
7052
|
-
function pippenger(c,
|
7211
|
+
function pippenger(c, fieldN, points, scalars) {
|
7053
7212
|
// If we split scalars by some window (let's say 8 bits), every chunk will only
|
7054
7213
|
// take 256 buckets even if there are 4096 scalars, also re-uses double.
|
7055
7214
|
// TODO:
|
7056
7215
|
// - https://eprint.iacr.org/2024/750.pdf
|
7057
7216
|
// - https://tches.iacr.org/index.php/TCHES/article/view/10287
|
7058
7217
|
// 0 is accepted in scalars
|
7059
|
-
|
7218
|
+
validateMSMPoints(points, c);
|
7219
|
+
validateMSMScalars(scalars, fieldN);
|
7220
|
+
if (points.length !== scalars.length)
|
7060
7221
|
throw new Error('arrays of points and scalars must have equal length');
|
7061
|
-
|
7062
|
-
if (!field.isValid(s))
|
7063
|
-
throw new Error(`wrong scalar at index ${i}`);
|
7064
|
-
});
|
7065
|
-
points.forEach((p, i) => {
|
7066
|
-
if (!(p instanceof c))
|
7067
|
-
throw new Error(`wrong point at index ${i}`);
|
7068
|
-
});
|
7222
|
+
const zero = c.ZERO;
|
7069
7223
|
const wbits = bitLen(BigInt(points.length));
|
7070
7224
|
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
7071
7225
|
const MASK = (1 << windowSize) - 1;
|
7072
|
-
const buckets = new Array(MASK + 1).fill(
|
7073
|
-
const lastBits = Math.floor((
|
7074
|
-
let sum =
|
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;
|
7075
7229
|
for (let i = lastBits; i >= 0; i -= windowSize) {
|
7076
|
-
buckets.fill(
|
7230
|
+
buckets.fill(zero);
|
7077
7231
|
for (let j = 0; j < scalars.length; j++) {
|
7078
7232
|
const scalar = scalars[j];
|
7079
7233
|
const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
|
7080
7234
|
buckets[wbits] = buckets[wbits].add(points[j]);
|
7081
7235
|
}
|
7082
|
-
let resI =
|
7236
|
+
let resI = zero; // not using this will do small speed-up, but will lose ct
|
7083
7237
|
// Skip first bucket, because it is zero
|
7084
|
-
for (let j = buckets.length - 1, sumI =
|
7238
|
+
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
7085
7239
|
sumI = sumI.add(buckets[j]);
|
7086
7240
|
resI = resI.add(sumI);
|
7087
7241
|
}
|
@@ -7111,8 +7265,12 @@ function validateBasic(curve) {
|
|
7111
7265
|
});
|
7112
7266
|
}
|
7113
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
|
+
*/
|
7114
7273
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7115
|
-
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
7116
7274
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
7117
7275
|
// prettier-ignore
|
7118
7276
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -7144,6 +7302,10 @@ function validateOpts$1(curve) {
|
|
7144
7302
|
function twistedEdwards(curveDef) {
|
7145
7303
|
const CURVE = validateOpts$1(curveDef);
|
7146
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.
|
7147
7309
|
const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
|
7148
7310
|
const modP = Fp.create; // Function overrides
|
7149
7311
|
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
@@ -7357,16 +7519,15 @@ function twistedEdwards(curveDef) {
|
|
7357
7519
|
// It's faster, but should only be used when you don't care about
|
7358
7520
|
// an exposed private key e.g. sig verification.
|
7359
7521
|
// Does NOT allow scalars higher than CURVE.n.
|
7360
|
-
|
7522
|
+
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
7523
|
+
multiplyUnsafe(scalar, acc = Point.ZERO) {
|
7361
7524
|
const n = scalar;
|
7362
7525
|
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7363
7526
|
if (n === _0n$1)
|
7364
7527
|
return I;
|
7365
|
-
if (this.
|
7528
|
+
if (this.is0() || n === _1n$3)
|
7366
7529
|
return this;
|
7367
|
-
|
7368
|
-
return this.wNAF(n).p;
|
7369
|
-
return wnaf.unsafeLadder(this, n);
|
7530
|
+
return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
|
7370
7531
|
}
|
7371
7532
|
// Checks if point is of small order.
|
7372
7533
|
// If you add something to small order point, you will have "dirty"
|
@@ -7400,8 +7561,9 @@ function twistedEdwards(curveDef) {
|
|
7400
7561
|
abool('zip215', zip215);
|
7401
7562
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7402
7563
|
const lastByte = hex[len - 1]; // select last byte
|
7403
|
-
normed[len - 1] = lastByte &
|
7564
|
+
normed[len - 1] = lastByte & -129; // clear last bit
|
7404
7565
|
const y = bytesToNumberLE(normed);
|
7566
|
+
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
7405
7567
|
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
7406
7568
|
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7407
7569
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
@@ -7450,7 +7612,7 @@ function twistedEdwards(curveDef) {
|
|
7450
7612
|
}
|
7451
7613
|
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
7452
7614
|
function getExtendedPublicKey(key) {
|
7453
|
-
const len =
|
7615
|
+
const len = Fp.BYTES;
|
7454
7616
|
key = ensureBytes('private key', key, len);
|
7455
7617
|
// Hash private key with curve's hash function to produce uniformingly random input
|
7456
7618
|
// Check byte lengths: ensure(64, h(ensure(32, key)))
|
@@ -7483,23 +7645,29 @@ function twistedEdwards(curveDef) {
|
|
7483
7645
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7484
7646
|
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7485
7647
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7486
|
-
return ensureBytes('result', res,
|
7648
|
+
return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
|
7487
7649
|
}
|
7488
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
|
+
*/
|
7489
7655
|
function verify(sig, msg, publicKey, options = verifyOpts) {
|
7490
7656
|
const { context, zip215 } = options;
|
7491
7657
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7492
7658
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7493
7659
|
msg = ensureBytes('message', msg);
|
7660
|
+
publicKey = ensureBytes('publicKey', publicKey, len);
|
7494
7661
|
if (zip215 !== undefined)
|
7495
7662
|
abool('zip215', zip215);
|
7496
7663
|
if (prehash)
|
7497
7664
|
msg = prehash(msg); // for ed25519ph, etc
|
7498
7665
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
7499
|
-
// zip215: true is good for consensus-critical apps and allows points < 2^256
|
7500
|
-
// zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
|
7501
7666
|
let A, R, SB;
|
7502
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)
|
7503
7671
|
A = Point.fromHex(publicKey, zip215);
|
7504
7672
|
R = Point.fromHex(sig.slice(0, len), zip215);
|
7505
7673
|
SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
|
@@ -7511,6 +7679,7 @@ function twistedEdwards(curveDef) {
|
|
7511
7679
|
return false;
|
7512
7680
|
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
7513
7681
|
const RkA = R.add(A.multiplyUnsafe(k));
|
7682
|
+
// Extended group equation
|
7514
7683
|
// [8][S]B = [8]R + [8][k]A'
|
7515
7684
|
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
7516
7685
|
}
|
@@ -7541,13 +7710,14 @@ function twistedEdwards(curveDef) {
|
|
7541
7710
|
};
|
7542
7711
|
}
|
7543
7712
|
|
7544
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7545
7713
|
/**
|
7546
7714
|
* ed25519 Twisted Edwards curve with following addons:
|
7547
7715
|
* - X25519 ECDH
|
7548
7716
|
* - Ristretto cofactor elimination
|
7549
7717
|
* - Elligator hash-to-group / point indistinguishability
|
7718
|
+
* @module
|
7550
7719
|
*/
|
7720
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7551
7721
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7552
7722
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
7553
7723
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
@@ -7606,7 +7776,7 @@ function uvRatio(u, v) {
|
|
7606
7776
|
x = mod(-x, P);
|
7607
7777
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7608
7778
|
}
|
7609
|
-
const Fp
|
7779
|
+
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7610
7780
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7611
7781
|
// Param: a
|
7612
7782
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
@@ -7614,7 +7784,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7614
7784
|
// Negative number is P - number, and division is invert(number, P)
|
7615
7785
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
7616
7786
|
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
7617
|
-
Fp
|
7787
|
+
Fp,
|
7618
7788
|
// Subgroup order: how many points curve has
|
7619
7789
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7620
7790
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
@@ -7633,6 +7803,14 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7633
7803
|
}))();
|
7634
7804
|
/**
|
7635
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
|
7636
7814
|
*/
|
7637
7815
|
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7638
7816
|
|
@@ -9030,7 +9208,7 @@ var PrivateKey;
|
|
9030
9208
|
/*!
|
9031
9209
|
* MIT License
|
9032
9210
|
*
|
9033
|
-
* Copyright (c) 2017-
|
9211
|
+
* Copyright (c) 2017-2024 Peculiar Ventures, LLC
|
9034
9212
|
*
|
9035
9213
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9036
9214
|
* of this software and associated documentation files (the "Software"), to deal
|
@@ -9142,7 +9320,7 @@ class BufferSourceConverter {
|
|
9142
9320
|
}
|
9143
9321
|
|
9144
9322
|
const STRING_TYPE = "string";
|
9145
|
-
const HEX_REGEX = /^[0-9a-f]+$/i;
|
9323
|
+
const HEX_REGEX = /^[0-9a-f\s]+$/i;
|
9146
9324
|
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
9147
9325
|
const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
|
9148
9326
|
class Utf8Converter {
|
@@ -9376,7 +9554,7 @@ class Convert {
|
|
9376
9554
|
return base64;
|
9377
9555
|
}
|
9378
9556
|
static formatString(data) {
|
9379
|
-
return (data === null || data ===
|
9557
|
+
return (data === null || data === undefined ? undefined : data.replace(/[\n\r\t ]/g, "")) || "";
|
9380
9558
|
}
|
9381
9559
|
}
|
9382
9560
|
Convert.DEFAULT_UTF8_ENCODING = "utf8";
|
@@ -9632,7 +9810,7 @@ function HexBlock(BaseClass) {
|
|
9632
9810
|
var _a;
|
9633
9811
|
super(...args);
|
9634
9812
|
const params = args[0] || {};
|
9635
|
-
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !==
|
9813
|
+
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9636
9814
|
this.valueHexView = params.valueHex ? BufferSourceConverter_1.toUint8Array(params.valueHex) : EMPTY_VIEW;
|
9637
9815
|
}
|
9638
9816
|
get valueHex() {
|
@@ -9722,11 +9900,11 @@ class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
|
|
9722
9900
|
var _a, _b, _c, _d;
|
9723
9901
|
super();
|
9724
9902
|
if (idBlock) {
|
9725
|
-
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !==
|
9903
|
+
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9726
9904
|
this.valueHexView = idBlock.valueHex ? BufferSourceConverter_1.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
|
9727
|
-
this.tagClass = (_b = idBlock.tagClass) !== null && _b !==
|
9728
|
-
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !==
|
9729
|
-
this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !==
|
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;
|
9730
9908
|
}
|
9731
9909
|
else {
|
9732
9910
|
this.tagClass = -1;
|
@@ -9893,9 +10071,9 @@ class LocalLengthBlock extends LocalBaseBlock {
|
|
9893
10071
|
constructor({ lenBlock = {}, } = {}) {
|
9894
10072
|
var _a, _b, _c;
|
9895
10073
|
super();
|
9896
|
-
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !==
|
9897
|
-
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !==
|
9898
|
-
this.length = (_c = lenBlock.length) !== null && _c !==
|
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;
|
9899
10077
|
}
|
9900
10078
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
9901
10079
|
const view = BufferSourceConverter_1.toUint8Array(inputBuffer);
|
@@ -10667,7 +10845,7 @@ var _a$r;
|
|
10667
10845
|
class OctetString extends BaseBlock {
|
10668
10846
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
10669
10847
|
var _b, _c;
|
10670
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10848
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
10671
10849
|
super({
|
10672
10850
|
idBlock: {
|
10673
10851
|
isConstructed: parameters.isConstructed,
|
@@ -10828,7 +11006,7 @@ var _a$q;
|
|
10828
11006
|
class BitString extends BaseBlock {
|
10829
11007
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
10830
11008
|
var _b, _c;
|
10831
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
11009
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
10832
11010
|
super({
|
10833
11011
|
idBlock: {
|
10834
11012
|
isConstructed: parameters.isConstructed,
|
@@ -12030,7 +12208,7 @@ class GeneralizedTime extends UTCTime {
|
|
12030
12208
|
constructor(parameters = {}) {
|
12031
12209
|
var _b;
|
12032
12210
|
super(parameters);
|
12033
|
-
(_b = this.millisecond) !== null && _b !==
|
12211
|
+
(_b = this.millisecond) !== null && _b !== undefined ? _b : (this.millisecond = 0);
|
12034
12212
|
this.idBlock.tagClass = 1;
|
12035
12213
|
this.idBlock.tagNumber = 24;
|
12036
12214
|
}
|
@@ -12381,8 +12559,8 @@ function pkixToJwk(bytes) {
|
|
12381
12559
|
const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
|
12382
12560
|
return {
|
12383
12561
|
kty: 'RSA',
|
12384
|
-
n:
|
12385
|
-
e:
|
12562
|
+
n: asn1jsIntegerToBase64(values[0]),
|
12563
|
+
e: asn1jsIntegerToBase64(values[1])
|
12386
12564
|
};
|
12387
12565
|
}
|
12388
12566
|
/**
|
@@ -12418,21 +12596,13 @@ function jwkToPkix(jwk) {
|
|
12418
12596
|
const der = root.toBER();
|
12419
12597
|
return new Uint8Array(der, 0, der.byteLength);
|
12420
12598
|
}
|
12421
|
-
function
|
12422
|
-
let
|
12423
|
-
|
12424
|
-
|
12599
|
+
function asn1jsIntegerToBase64(int) {
|
12600
|
+
let buf = int.valueBlock.valueHexView;
|
12601
|
+
// chrome rejects values with leading 0s
|
12602
|
+
while (buf[0] === 0) {
|
12603
|
+
buf = buf.subarray(1);
|
12425
12604
|
}
|
12426
|
-
|
12427
|
-
const u8 = new Uint8Array(len);
|
12428
|
-
let i = 0;
|
12429
|
-
let j = 0;
|
12430
|
-
while (i < len) {
|
12431
|
-
u8[i] = parseInt(hex.slice(j, j + 2), 16);
|
12432
|
-
i += 1;
|
12433
|
-
j += 2;
|
12434
|
-
}
|
12435
|
-
return u8;
|
12605
|
+
return toString$6(buf, 'base64url');
|
12436
12606
|
}
|
12437
12607
|
function bufToBn(u8) {
|
12438
12608
|
const hex = [];
|
@@ -12461,15 +12631,18 @@ function pkixToRSAPublicKey(bytes) {
|
|
12461
12631
|
return new RSAPublicKey(jwk, digest);
|
12462
12632
|
}
|
12463
12633
|
|
12464
|
-
|
12634
|
+
/**
|
12635
|
+
* HMAC: RFC2104 message authentication code.
|
12636
|
+
* @module
|
12637
|
+
*/
|
12465
12638
|
class HMAC extends Hash {
|
12466
|
-
constructor(hash
|
12639
|
+
constructor(hash, _key) {
|
12467
12640
|
super();
|
12468
12641
|
this.finished = false;
|
12469
12642
|
this.destroyed = false;
|
12470
|
-
|
12643
|
+
ahash(hash);
|
12471
12644
|
const key = toBytes$1(_key);
|
12472
|
-
this.iHash = hash
|
12645
|
+
this.iHash = hash.create();
|
12473
12646
|
if (typeof this.iHash.update !== 'function')
|
12474
12647
|
throw new Error('Expected instance of class which extends utils.Hash');
|
12475
12648
|
this.blockLen = this.iHash.blockLen;
|
@@ -12477,12 +12650,12 @@ class HMAC extends Hash {
|
|
12477
12650
|
const blockLen = this.blockLen;
|
12478
12651
|
const pad = new Uint8Array(blockLen);
|
12479
12652
|
// blockLen can be bigger than outputLen
|
12480
|
-
pad.set(key.length > blockLen ? hash
|
12653
|
+
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
12481
12654
|
for (let i = 0; i < pad.length; i++)
|
12482
12655
|
pad[i] ^= 0x36;
|
12483
12656
|
this.iHash.update(pad);
|
12484
12657
|
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
12485
|
-
this.oHash = hash
|
12658
|
+
this.oHash = hash.create();
|
12486
12659
|
// Undo internal XOR && apply outer XOR
|
12487
12660
|
for (let i = 0; i < pad.length; i++)
|
12488
12661
|
pad[i] ^= 0x36 ^ 0x5c;
|
@@ -12490,13 +12663,13 @@ class HMAC extends Hash {
|
|
12490
12663
|
pad.fill(0);
|
12491
12664
|
}
|
12492
12665
|
update(buf) {
|
12493
|
-
|
12666
|
+
aexists(this);
|
12494
12667
|
this.iHash.update(buf);
|
12495
12668
|
return this;
|
12496
12669
|
}
|
12497
12670
|
digestInto(out) {
|
12498
|
-
|
12499
|
-
|
12671
|
+
aexists(this);
|
12672
|
+
abytes$1(out, this.outputLen);
|
12500
12673
|
this.finished = true;
|
12501
12674
|
this.iHash.digestInto(out);
|
12502
12675
|
this.oHash.update(out);
|
@@ -12540,8 +12713,33 @@ class HMAC extends Hash {
|
|
12540
12713
|
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
12541
12714
|
hmac.create = (hash, key) => new HMAC(hash, key);
|
12542
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
|
+
*/
|
12543
12742
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
12544
|
-
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
12545
12743
|
function validateSigVerOpts(opts) {
|
12546
12744
|
if (opts.lowS !== undefined)
|
12547
12745
|
abool('lowS', opts.lowS);
|
@@ -12565,17 +12763,22 @@ function validatePointOpts(curve) {
|
|
12565
12763
|
const { endo, Fp, a } = opts;
|
12566
12764
|
if (endo) {
|
12567
12765
|
if (!Fp.eql(a, Fp.ZERO)) {
|
12568
|
-
throw new Error('
|
12766
|
+
throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
|
12569
12767
|
}
|
12570
12768
|
if (typeof endo !== 'object' ||
|
12571
12769
|
typeof endo.beta !== 'bigint' ||
|
12572
12770
|
typeof endo.splitScalar !== 'function') {
|
12573
|
-
throw new Error('
|
12771
|
+
throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
|
12574
12772
|
}
|
12575
12773
|
}
|
12576
12774
|
return Object.freeze({ ...opts });
|
12577
12775
|
}
|
12578
12776
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
12777
|
+
class DERErr extends Error {
|
12778
|
+
constructor(m = '') {
|
12779
|
+
super(m);
|
12780
|
+
}
|
12781
|
+
}
|
12579
12782
|
/**
|
12580
12783
|
* ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
|
12581
12784
|
*
|
@@ -12585,11 +12788,7 @@ const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
|
12585
12788
|
*/
|
12586
12789
|
const DER = {
|
12587
12790
|
// asn.1 DER encoding utils
|
12588
|
-
Err:
|
12589
|
-
constructor(m = '') {
|
12590
|
-
super(m);
|
12591
|
-
}
|
12592
|
-
},
|
12791
|
+
Err: DERErr,
|
12593
12792
|
// Basic building block is TLV (Tag-Length-Value)
|
12594
12793
|
_tlv: {
|
12595
12794
|
encode: (tag, data) => {
|
@@ -12604,7 +12803,8 @@ const DER = {
|
|
12604
12803
|
throw new E('tlv.encode: long form length too big');
|
12605
12804
|
// length of length with long form flag
|
12606
12805
|
const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
|
12607
|
-
|
12806
|
+
const t = numberToHexUnpadded(tag);
|
12807
|
+
return t + lenLen + len + data;
|
12608
12808
|
},
|
12609
12809
|
// v - value, l - left bytes (unparsed)
|
12610
12810
|
decode(tag, data) {
|
@@ -12657,15 +12857,15 @@ const DER = {
|
|
12657
12857
|
if (Number.parseInt(hex[0], 16) & 0b1000)
|
12658
12858
|
hex = '00' + hex;
|
12659
12859
|
if (hex.length & 1)
|
12660
|
-
throw new E('unexpected assertion');
|
12860
|
+
throw new E('unexpected DER parsing assertion: unpadded hex');
|
12661
12861
|
return hex;
|
12662
12862
|
},
|
12663
12863
|
decode(data) {
|
12664
12864
|
const { Err: E } = DER;
|
12665
12865
|
if (data[0] & 128)
|
12666
|
-
throw new E('
|
12866
|
+
throw new E('invalid signature integer: negative');
|
12667
12867
|
if (data[0] === 0x00 && !(data[1] & 128))
|
12668
|
-
throw new E('
|
12868
|
+
throw new E('invalid signature integer: unnecessary leading zero');
|
12669
12869
|
return b2n(data);
|
12670
12870
|
},
|
12671
12871
|
},
|
@@ -12676,16 +12876,18 @@ const DER = {
|
|
12676
12876
|
abytes(data);
|
12677
12877
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
12678
12878
|
if (seqLeftBytes.length)
|
12679
|
-
throw new E('
|
12879
|
+
throw new E('invalid signature: left bytes after parsing');
|
12680
12880
|
const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
|
12681
12881
|
const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
|
12682
12882
|
if (sLeftBytes.length)
|
12683
|
-
throw new E('
|
12883
|
+
throw new E('invalid signature: left bytes after parsing');
|
12684
12884
|
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
12685
12885
|
},
|
12686
12886
|
hexFromSig(sig) {
|
12687
12887
|
const { _tlv: tlv, _int: int } = DER;
|
12688
|
-
const
|
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;
|
12689
12891
|
return tlv.encode(0x30, seq);
|
12690
12892
|
},
|
12691
12893
|
};
|
@@ -12739,7 +12941,7 @@ function weierstrassPoints(opts) {
|
|
12739
12941
|
key = bytesToHex(key);
|
12740
12942
|
// Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
|
12741
12943
|
if (typeof key !== 'string' || !lengths.includes(key.length))
|
12742
|
-
throw new Error('
|
12944
|
+
throw new Error('invalid private key');
|
12743
12945
|
key = key.padStart(nByteLength * 2, '0');
|
12744
12946
|
}
|
12745
12947
|
let num;
|
@@ -12750,7 +12952,7 @@ function weierstrassPoints(opts) {
|
|
12750
12952
|
: bytesToNumberBE(ensureBytes('private key', key, nByteLength));
|
12751
12953
|
}
|
12752
12954
|
catch (error) {
|
12753
|
-
throw new Error(
|
12955
|
+
throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
|
12754
12956
|
}
|
12755
12957
|
if (wrapPrivateKey)
|
12756
12958
|
num = mod(num, N); // disabled by default, enabled for BLS
|
@@ -12790,7 +12992,7 @@ function weierstrassPoints(opts) {
|
|
12790
12992
|
if (p.is0()) {
|
12791
12993
|
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
12792
12994
|
// In BLS, ZERO can be serialized, so we allow it.
|
12793
|
-
// (0, 0, 0) is
|
12995
|
+
// (0, 0, 0) is invalid representation of ZERO.
|
12794
12996
|
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
12795
12997
|
return;
|
12796
12998
|
throw new Error('bad point: ZERO');
|
@@ -13014,16 +13216,17 @@ function weierstrassPoints(opts) {
|
|
13014
13216
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
13015
13217
|
*/
|
13016
13218
|
multiplyUnsafe(sc) {
|
13017
|
-
|
13219
|
+
const { endo, n: N } = CURVE;
|
13220
|
+
aInRange('scalar', sc, _0n, N);
|
13018
13221
|
const I = Point.ZERO;
|
13019
13222
|
if (sc === _0n)
|
13020
13223
|
return I;
|
13021
|
-
if (sc === _1n$1)
|
13224
|
+
if (this.is0() || sc === _1n$1)
|
13022
13225
|
return this;
|
13023
|
-
|
13024
|
-
if (!endo)
|
13025
|
-
return wnaf.
|
13026
|
-
//
|
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
|
13027
13230
|
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
13028
13231
|
let k1p = I;
|
13029
13232
|
let k2p = I;
|
@@ -13209,7 +13412,9 @@ function weierstrass(curveDef) {
|
|
13209
13412
|
return { x, y };
|
13210
13413
|
}
|
13211
13414
|
else {
|
13212
|
-
|
13415
|
+
const cl = compressedLen;
|
13416
|
+
const ul = uncompressedLen;
|
13417
|
+
throw new Error('invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len);
|
13213
13418
|
}
|
13214
13419
|
},
|
13215
13420
|
});
|
@@ -13374,6 +13579,9 @@ function weierstrass(curveDef) {
|
|
13374
13579
|
// int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
|
13375
13580
|
const bits2int = CURVE.bits2int ||
|
13376
13581
|
function (bytes) {
|
13582
|
+
// Our custom check "just in case"
|
13583
|
+
if (bytes.length > 8192)
|
13584
|
+
throw new Error('input is too large');
|
13377
13585
|
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
13378
13586
|
// for some cases, since bytes.length * 8 is not actual bitLength.
|
13379
13587
|
const num = bytesToNumberBE(bytes); // check for == u8 done here
|
@@ -13390,15 +13598,15 @@ function weierstrass(curveDef) {
|
|
13390
13598
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13391
13599
|
*/
|
13392
13600
|
function int2octets(num) {
|
13393
|
-
aInRange(
|
13601
|
+
aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
|
13394
13602
|
// works with order, can have different size than numToField!
|
13395
13603
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13396
13604
|
}
|
13397
13605
|
// Steps A, D of RFC6979 3.2
|
13398
13606
|
// Creates RFC6979 seed; converts msg/privKey to numbers.
|
13399
13607
|
// Used only in sign, not in verify.
|
13400
|
-
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
|
13401
|
-
// 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
|
13402
13610
|
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
13403
13611
|
if (['recovered', 'canonical'].some((k) => k in opts))
|
13404
13612
|
throw new Error('sign() legacy options not supported');
|
@@ -13492,39 +13700,48 @@ function weierstrass(curveDef) {
|
|
13492
13700
|
const sg = signature;
|
13493
13701
|
msgHash = ensureBytes('msgHash', msgHash);
|
13494
13702
|
publicKey = ensureBytes('publicKey', publicKey);
|
13703
|
+
const { lowS, prehash, format } = opts;
|
13704
|
+
// Verify opts, deduce signature format
|
13705
|
+
validateSigVerOpts(opts);
|
13495
13706
|
if ('strict' in opts)
|
13496
13707
|
throw new Error('options.strict was renamed to lowS');
|
13497
|
-
|
13498
|
-
|
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');
|
13499
13719
|
let _sig = undefined;
|
13500
13720
|
let P;
|
13501
13721
|
try {
|
13502
|
-
if (
|
13722
|
+
if (isObj)
|
13723
|
+
_sig = new Signature(sg.r, sg.s);
|
13724
|
+
if (isHex) {
|
13503
13725
|
// Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
|
13504
13726
|
// Since DER can also be 2*nByteLength bytes, we check for it first.
|
13505
13727
|
try {
|
13506
|
-
|
13728
|
+
if (format !== 'compact')
|
13729
|
+
_sig = Signature.fromDER(sg);
|
13507
13730
|
}
|
13508
13731
|
catch (derError) {
|
13509
13732
|
if (!(derError instanceof DER.Err))
|
13510
13733
|
throw derError;
|
13511
|
-
_sig = Signature.fromCompact(sg);
|
13512
13734
|
}
|
13513
|
-
|
13514
|
-
|
13515
|
-
const { r, s } = sg;
|
13516
|
-
_sig = new Signature(r, s);
|
13517
|
-
}
|
13518
|
-
else {
|
13519
|
-
throw new Error('PARSE');
|
13735
|
+
if (!_sig && format !== 'der')
|
13736
|
+
_sig = Signature.fromCompact(sg);
|
13520
13737
|
}
|
13521
13738
|
P = Point.fromHex(publicKey);
|
13522
13739
|
}
|
13523
13740
|
catch (error) {
|
13524
|
-
if (error.message === 'PARSE')
|
13525
|
-
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
13526
13741
|
return false;
|
13527
13742
|
}
|
13743
|
+
if (!_sig)
|
13744
|
+
return false;
|
13528
13745
|
if (lowS && _sig.hasHighS())
|
13529
13746
|
return false;
|
13530
13747
|
if (prehash)
|
@@ -13552,8 +13769,12 @@ function weierstrass(curveDef) {
|
|
13552
13769
|
};
|
13553
13770
|
}
|
13554
13771
|
|
13772
|
+
/**
|
13773
|
+
* Utilities for short weierstrass curves, combined with noble-hashes.
|
13774
|
+
* @module
|
13775
|
+
*/
|
13555
13776
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13556
|
-
|
13777
|
+
/** connects noble-curves to noble-hashes */
|
13557
13778
|
function getHash(hash) {
|
13558
13779
|
return {
|
13559
13780
|
hash,
|
@@ -13563,9 +13784,21 @@ function getHash(hash) {
|
|
13563
13784
|
}
|
13564
13785
|
function createCurve(curveDef, defHash) {
|
13565
13786
|
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
13566
|
-
return
|
13787
|
+
return { ...create(defHash), create };
|
13567
13788
|
}
|
13568
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
|
+
*/
|
13569
13802
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13570
13803
|
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
13571
13804
|
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
@@ -13596,31 +13829,35 @@ function sqrtMod(y) {
|
|
13596
13829
|
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
13597
13830
|
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
13598
13831
|
const root = pow2(t2, _2n, P);
|
13599
|
-
if (!
|
13832
|
+
if (!Fpk1.eql(Fpk1.sqr(root), y))
|
13600
13833
|
throw new Error('Cannot find square root');
|
13601
13834
|
return root;
|
13602
13835
|
}
|
13603
|
-
const
|
13836
|
+
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
13604
13837
|
/**
|
13605
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;
|
13606
13848
|
*/
|
13607
13849
|
const secp256k1 = createCurve({
|
13608
13850
|
a: BigInt(0), // equation params: a, b
|
13609
|
-
b: BigInt(7),
|
13610
|
-
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
|
13611
13853
|
n: secp256k1N, // Curve order, total count of valid points in the field
|
13612
13854
|
// Base point (x, y) aka generator point
|
13613
13855
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
13614
13856
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
13615
13857
|
h: BigInt(1), // Cofactor
|
13616
13858
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
13617
|
-
/**
|
13618
|
-
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
13619
|
-
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
13620
|
-
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
13621
|
-
* Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
13622
|
-
*/
|
13623
13859
|
endo: {
|
13860
|
+
// Endomorphism, see above
|
13624
13861
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
13625
13862
|
splitScalar: (k) => {
|
13626
13863
|
const n = secp256k1N;
|
@@ -15634,9 +15871,9 @@ function _copyActual (source, target, targetStart, sourceStart, sourceEnd) {
|
|
15634
15871
|
const QUERY_FLAG = 0;
|
15635
15872
|
const RESPONSE_FLAG = 1 << 15;
|
15636
15873
|
const FLUSH_MASK = 1 << 15;
|
15637
|
-
const NOT_FLUSH_MASK =
|
15874
|
+
const NOT_FLUSH_MASK = -32769;
|
15638
15875
|
const QU_MASK = 1 << 15;
|
15639
|
-
const NOT_QU_MASK =
|
15876
|
+
const NOT_QU_MASK = -32769;
|
15640
15877
|
|
15641
15878
|
function codec ({ bytes = 0, encode, decode, encodingLength }) {
|
15642
15879
|
encode.bytes = bytes;
|
@@ -20043,36 +20280,36 @@ class StreamManager {
|
|
20043
20280
|
this.log = new Logger$1(`stream-manager:${multicodec}`);
|
20044
20281
|
this.addEventListener("peer:update", this.handlePeerUpdateStreamPool);
|
20045
20282
|
}
|
20046
|
-
async getStream(
|
20047
|
-
const
|
20048
|
-
const scheduledStream = this.streamPool.get(
|
20283
|
+
async getStream(peerId) {
|
20284
|
+
const peerIdStr = peerId.toString();
|
20285
|
+
const scheduledStream = this.streamPool.get(peerIdStr);
|
20049
20286
|
if (scheduledStream) {
|
20050
|
-
this.streamPool.delete(
|
20287
|
+
this.streamPool.delete(peerIdStr);
|
20051
20288
|
await scheduledStream;
|
20052
20289
|
}
|
20053
|
-
let stream = this.getOpenStreamForCodec(
|
20290
|
+
let stream = this.getOpenStreamForCodec(peerId);
|
20054
20291
|
if (stream) {
|
20055
|
-
this.log.info(`Found existing stream peerId=${
|
20056
|
-
this.lockStream(
|
20292
|
+
this.log.info(`Found existing stream peerId=${peerIdStr} multicodec=${this.multicodec}`);
|
20293
|
+
this.lockStream(peerIdStr, stream);
|
20057
20294
|
return stream;
|
20058
20295
|
}
|
20059
|
-
stream = await this.createStream(
|
20060
|
-
this.lockStream(
|
20296
|
+
stream = await this.createStream(peerId);
|
20297
|
+
this.lockStream(peerIdStr, stream);
|
20061
20298
|
return stream;
|
20062
20299
|
}
|
20063
|
-
async createStream(
|
20064
|
-
const connections = this.getConnections(
|
20300
|
+
async createStream(peerId, retries = 0) {
|
20301
|
+
const connections = this.getConnections(peerId);
|
20065
20302
|
const connection = selectOpenConnection(connections);
|
20066
20303
|
if (!connection) {
|
20067
|
-
throw new Error(`Failed to get a connection to the peer peerId=${
|
20304
|
+
throw new Error(`Failed to get a connection to the peer peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20068
20305
|
}
|
20069
20306
|
let lastError;
|
20070
20307
|
let stream;
|
20071
20308
|
for (let i = 0; i < retries + 1; i++) {
|
20072
20309
|
try {
|
20073
|
-
this.log.info(`Attempting to create a stream for peerId=${
|
20310
|
+
this.log.info(`Attempting to create a stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20074
20311
|
stream = await connection.newStream(this.multicodec);
|
20075
|
-
this.log.info(`Created stream for peerId=${
|
20312
|
+
this.log.info(`Created stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20076
20313
|
break;
|
20077
20314
|
}
|
20078
20315
|
catch (error) {
|
@@ -20080,8 +20317,7 @@ class StreamManager {
|
|
20080
20317
|
}
|
20081
20318
|
}
|
20082
20319
|
if (!stream) {
|
20083
|
-
throw new Error(`Failed to create a new stream for ${
|
20084
|
-
lastError);
|
20320
|
+
throw new Error(`Failed to create a new stream for ${peerId.toString()} -- ` + lastError);
|
20085
20321
|
}
|
20086
20322
|
return stream;
|
20087
20323
|
}
|
@@ -20093,7 +20329,7 @@ class StreamManager {
|
|
20093
20329
|
}
|
20094
20330
|
try {
|
20095
20331
|
this.ongoingCreation.add(peerId);
|
20096
|
-
await this.createStream(peer);
|
20332
|
+
await this.createStream(peer.id);
|
20097
20333
|
}
|
20098
20334
|
catch (error) {
|
20099
20335
|
this.log.error(`Failed to createStreamWithLock:`, error);
|
@@ -20166,8 +20402,8 @@ class BaseProtocol {
|
|
20166
20402
|
this.removeLibp2pEventListener = components.events.removeEventListener.bind(components.events);
|
20167
20403
|
this.streamManager = new StreamManager(multicodec, components.connectionManager.getConnections.bind(components.connectionManager), this.addLibp2pEventListener);
|
20168
20404
|
}
|
20169
|
-
async getStream(
|
20170
|
-
return this.streamManager.getStream(
|
20405
|
+
async getStream(peerId) {
|
20406
|
+
return this.streamManager.getStream(peerId);
|
20171
20407
|
}
|
20172
20408
|
}
|
20173
20409
|
|
@@ -23794,6 +24030,105 @@ var WakuMetadataResponse;
|
|
23794
24030
|
};
|
23795
24031
|
})(WakuMetadataResponse || (WakuMetadataResponse = {}));
|
23796
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
|
+
|
23797
24132
|
/**
|
23798
24133
|
* PeerExchangeRPC represents a message conforming to the Waku Peer Exchange protocol
|
23799
24134
|
*/
|
@@ -23863,7 +24198,7 @@ class WakuPeerExchange extends BaseProtocol {
|
|
23863
24198
|
}
|
23864
24199
|
let stream;
|
23865
24200
|
try {
|
23866
|
-
stream = await this.getStream(
|
24201
|
+
stream = await this.getStream(peerId);
|
23867
24202
|
}
|
23868
24203
|
catch (err) {
|
23869
24204
|
log$2.error("Failed to get stream", err);
|
@@ -24078,7 +24413,7 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
|
|
24078
24413
|
const existingShardInfoBytes = peer.metadata.get("shardInfo");
|
24079
24414
|
if (existingShardInfoBytes) {
|
24080
24415
|
const existingShardInfo = decodeRelayShard(existingShardInfoBytes);
|
24081
|
-
|
24416
|
+
{
|
24082
24417
|
hasShardDiff =
|
24083
24418
|
existingShardInfo.clusterId !== shardInfo?.clusterId ||
|
24084
24419
|
existingShardInfo.shards.some((shard) => !shardInfo?.shards.includes(shard));
|