@waku/discovery 0.0.6-f599932.0 → 0.0.7-09108d9.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/CHANGELOG.md +17 -0
- package/bundle/index.js +1605 -1860
- package/dist/.tsbuildinfo +1 -1
- package/dist/dns/dns_discovery.js +1 -1
- package/dist/dns/dns_discovery.js.map +1 -1
- package/dist/local-peer-cache/index.js +2 -3
- package/dist/local-peer-cache/index.js.map +1 -1
- package/dist/peer-exchange/waku_peer_exchange.js +2 -2
- package/dist/peer-exchange/waku_peer_exchange.js.map +1 -1
- package/dist/peer-exchange/waku_peer_exchange_discovery.js +1 -1
- package/dist/peer-exchange/waku_peer_exchange_discovery.js.map +1 -1
- package/package.json +1 -1
- package/src/dns/dns_discovery.ts +0 -1
- package/src/local-peer-cache/index.ts +2 -3
- package/src/peer-exchange/waku_peer_exchange.ts +2 -2
- package/src/peer-exchange/waku_peer_exchange_discovery.ts +1 -1
package/bundle/index.js
CHANGED
@@ -19,6 +19,10 @@
|
|
19
19
|
*/
|
20
20
|
const peerDiscoverySymbol = Symbol.for('@libp2p/peer-discovery');
|
21
21
|
|
22
|
+
/**
|
23
|
+
* All PeerId implementations must use this symbol as the name of a property
|
24
|
+
* with a boolean `true` value
|
25
|
+
*/
|
22
26
|
const peerIdSymbol = Symbol.for('@libp2p/peer-id');
|
23
27
|
|
24
28
|
/**
|
@@ -26,31 +30,55 @@ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
|
|
26
30
|
* usually in response to the `abort` event being emitted by an
|
27
31
|
* AbortSignal.
|
28
32
|
*/
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
/**
|
34
|
+
* Thrown when invalid parameters are passed to a function or method call
|
35
|
+
*/
|
36
|
+
class InvalidParametersError extends Error {
|
37
|
+
static name = 'InvalidParametersError';
|
38
|
+
constructor(message = 'Invalid parameters') {
|
33
39
|
super(message);
|
34
|
-
this.
|
35
|
-
this.name = props?.name ?? 'CodeError';
|
36
|
-
this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
|
40
|
+
this.name = 'InvalidParametersError';
|
37
41
|
}
|
38
42
|
}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
this.
|
43
|
+
/**
|
44
|
+
* Thrown when a public key is invalid
|
45
|
+
*/
|
46
|
+
class InvalidPublicKeyError extends Error {
|
47
|
+
static name = 'InvalidPublicKeyError';
|
48
|
+
constructor(message = 'Invalid public key') {
|
49
|
+
super(message);
|
50
|
+
this.name = 'InvalidPublicKeyError';
|
51
|
+
}
|
52
|
+
}
|
53
|
+
/**
|
54
|
+
* Thrown when an invalid multihash is encountered
|
55
|
+
*/
|
56
|
+
class InvalidMultihashError extends Error {
|
57
|
+
static name = 'InvalidMultihashError';
|
58
|
+
constructor(message = 'Invalid Multihash') {
|
59
|
+
super(message);
|
60
|
+
this.name = 'InvalidMultihashError';
|
61
|
+
}
|
62
|
+
}
|
63
|
+
/**
|
64
|
+
* Thrown when and attempt to operate on an unsupported key was made
|
65
|
+
*/
|
66
|
+
class UnsupportedKeyTypeError extends Error {
|
67
|
+
static name = 'UnsupportedKeyTypeError';
|
68
|
+
constructor(message = 'Unsupported key type') {
|
69
|
+
super(message);
|
70
|
+
this.name = 'UnsupportedKeyTypeError';
|
47
71
|
}
|
48
72
|
}
|
49
73
|
|
50
|
-
/**
|
74
|
+
/**
|
75
|
+
* Noop for browser compatibility
|
76
|
+
*/
|
51
77
|
function setMaxListeners$1() { }
|
52
78
|
|
53
|
-
|
79
|
+
/**
|
80
|
+
* Create a setMaxListeners that doesn't break browser usage
|
81
|
+
*/
|
54
82
|
const setMaxListeners = (n, ...eventTargets) => {
|
55
83
|
try {
|
56
84
|
setMaxListeners$1(n, ...eventTargets);
|
@@ -114,7 +142,6 @@ class TypedEventEmitter extends EventTarget {
|
|
114
142
|
return this.dispatchEvent(new CustomEvent(type, detail));
|
115
143
|
}
|
116
144
|
}
|
117
|
-
const CustomEvent = globalThis.CustomEvent;
|
118
145
|
|
119
146
|
var Protocols;
|
120
147
|
(function (Protocols) {
|
@@ -125,43 +152,24 @@ var Protocols;
|
|
125
152
|
})(Protocols || (Protocols = {}));
|
126
153
|
var ProtocolError;
|
127
154
|
(function (ProtocolError) {
|
128
|
-
|
155
|
+
//
|
156
|
+
// GENERAL ERRORS SECTION
|
157
|
+
//
|
158
|
+
/**
|
159
|
+
* Could not determine the origin of the fault. Best to check connectivity and try again
|
160
|
+
* */
|
129
161
|
ProtocolError["GENERIC_FAIL"] = "Generic error";
|
130
162
|
/**
|
131
|
-
*
|
132
|
-
*
|
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.
|
133
166
|
*/
|
134
|
-
ProtocolError["
|
167
|
+
ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
135
168
|
/**
|
136
169
|
* Failure to protobuf decode the message. May be due to a remote peer issue,
|
137
170
|
* ensuring that messages are sent via several peer enable mitigation of this error.
|
138
171
|
*/
|
139
172
|
ProtocolError["DECODE_FAILED"] = "Failed to decode";
|
140
|
-
/**
|
141
|
-
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
142
|
-
* payload is set on the outgoing message.
|
143
|
-
*/
|
144
|
-
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
145
|
-
/**
|
146
|
-
* The message size is above the maximum message size allowed on the Waku Network.
|
147
|
-
* Compressing the message or using an alternative strategy for large messages is recommended.
|
148
|
-
*/
|
149
|
-
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
150
|
-
/**
|
151
|
-
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
152
|
-
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
153
|
-
*/
|
154
|
-
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
155
|
-
/**
|
156
|
-
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
157
|
-
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
158
|
-
*/
|
159
|
-
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
160
|
-
/**
|
161
|
-
* The topics passed in the decoders do not match each other, or don't exist at all.
|
162
|
-
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
163
|
-
*/
|
164
|
-
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
165
173
|
/**
|
166
174
|
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
167
175
|
* Mitigation can be: retrying after a given time period, display connectivity issue
|
@@ -179,37 +187,51 @@ var ProtocolError;
|
|
179
187
|
* or `DECODE_FAILED` can be used.
|
180
188
|
*/
|
181
189
|
ProtocolError["NO_RESPONSE"] = "No response received";
|
190
|
+
//
|
191
|
+
// SEND ERRORS SECTION
|
192
|
+
//
|
182
193
|
/**
|
183
|
-
*
|
184
|
-
*
|
185
|
-
* or `DECODE_FAILED` can be used.
|
194
|
+
* Failure to protobuf encode the message. This is not recoverable and needs
|
195
|
+
* further investigation.
|
186
196
|
*/
|
187
|
-
ProtocolError["
|
197
|
+
ProtocolError["ENCODE_FAILED"] = "Failed to encode";
|
188
198
|
/**
|
189
|
-
* The
|
190
|
-
*
|
199
|
+
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
200
|
+
* payload is set on the outgoing message.
|
191
201
|
*/
|
192
|
-
ProtocolError["
|
202
|
+
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
193
203
|
/**
|
194
|
-
*
|
195
|
-
*
|
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.
|
196
206
|
*/
|
197
|
-
ProtocolError["
|
207
|
+
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
198
208
|
/**
|
199
|
-
*
|
200
|
-
*
|
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.
|
201
211
|
*/
|
202
|
-
ProtocolError["
|
212
|
+
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
203
213
|
/**
|
204
|
-
*
|
205
|
-
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
|
214
|
+
* Fails when
|
206
215
|
*/
|
207
|
-
ProtocolError["
|
216
|
+
ProtocolError["STREAM_ABORTED"] = "Stream aborted";
|
208
217
|
/**
|
209
218
|
* General proof generation error message.
|
210
219
|
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
|
211
220
|
*/
|
212
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";
|
213
235
|
})(ProtocolError || (ProtocolError = {}));
|
214
236
|
|
215
237
|
var Tags;
|
@@ -232,6 +254,10 @@ var EConnectionStateEvents;
|
|
232
254
|
|
233
255
|
const DNS_DISCOVERY_TAG = "@waku/bootstrap";
|
234
256
|
|
257
|
+
var HealthStatusChangeEvents;
|
258
|
+
(function (HealthStatusChangeEvents) {
|
259
|
+
HealthStatusChangeEvents["StatusChange"] = "health:change";
|
260
|
+
})(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
|
235
261
|
var HealthStatus;
|
236
262
|
(function (HealthStatus) {
|
237
263
|
HealthStatus["Unhealthy"] = "Unhealthy";
|
@@ -243,43 +269,55 @@ function isDefined(value) {
|
|
243
269
|
return Boolean(value);
|
244
270
|
}
|
245
271
|
|
246
|
-
|
272
|
+
/**
|
273
|
+
* Internal assertion helpers.
|
274
|
+
* @module
|
275
|
+
*/
|
276
|
+
/** Asserts something is positive integer. */
|
277
|
+
function anumber(n) {
|
247
278
|
if (!Number.isSafeInteger(n) || n < 0)
|
248
|
-
throw new Error(
|
279
|
+
throw new Error('positive integer expected, got ' + n);
|
249
280
|
}
|
250
|
-
|
281
|
+
/** Is number an Uint8Array? Copied from utils for perf. */
|
251
282
|
function isBytes$2(a) {
|
252
|
-
return
|
253
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
283
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
254
284
|
}
|
255
|
-
|
285
|
+
/** Asserts something is Uint8Array. */
|
286
|
+
function abytes$1(b, ...lengths) {
|
256
287
|
if (!isBytes$2(b))
|
257
288
|
throw new Error('Uint8Array expected');
|
258
289
|
if (lengths.length > 0 && !lengths.includes(b.length))
|
259
|
-
throw new Error(
|
290
|
+
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
|
260
291
|
}
|
261
|
-
|
292
|
+
/** Asserts something is hash */
|
293
|
+
function ahash(h) {
|
262
294
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
263
295
|
throw new Error('Hash should be wrapped by utils.wrapConstructor');
|
264
|
-
|
265
|
-
|
296
|
+
anumber(h.outputLen);
|
297
|
+
anumber(h.blockLen);
|
266
298
|
}
|
267
|
-
|
299
|
+
/** Asserts a hash instance has not been destroyed / finished */
|
300
|
+
function aexists(instance, checkFinished = true) {
|
268
301
|
if (instance.destroyed)
|
269
302
|
throw new Error('Hash instance has been destroyed');
|
270
303
|
if (checkFinished && instance.finished)
|
271
304
|
throw new Error('Hash#digest() has already been called');
|
272
305
|
}
|
273
|
-
|
274
|
-
|
306
|
+
/** Asserts output is properly-sized byte array */
|
307
|
+
function aoutput(out, instance) {
|
308
|
+
abytes$1(out);
|
275
309
|
const min = instance.outputLen;
|
276
310
|
if (out.length < min) {
|
277
|
-
throw new Error(
|
311
|
+
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
278
312
|
}
|
279
313
|
}
|
280
314
|
|
281
315
|
const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
282
316
|
|
317
|
+
/**
|
318
|
+
* Utilities for hex, bytes, CSPRNG.
|
319
|
+
* @module
|
320
|
+
*/
|
283
321
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
284
322
|
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
285
323
|
// node.js versions earlier than v19 don't declare it in global scope.
|
@@ -288,33 +326,20 @@ const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? glob
|
|
288
326
|
// Makes the utils un-importable in browsers without a bundler.
|
289
327
|
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
290
328
|
// Cast array to view
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
// next scheduler queue processing step and this is exactly what we need.
|
298
|
-
const nextTick = async () => { };
|
299
|
-
// Returns control to thread each 'tick' ms to avoid blocking
|
300
|
-
async function asyncLoop(iters, tick, cb) {
|
301
|
-
let ts = Date.now();
|
302
|
-
for (let i = 0; i < iters; i++) {
|
303
|
-
cb(i);
|
304
|
-
// Date.now() is not monotonic, so in case if clock goes backwards we return return control too
|
305
|
-
const diff = Date.now() - ts;
|
306
|
-
if (diff >= 0 && diff < tick)
|
307
|
-
continue;
|
308
|
-
await nextTick();
|
309
|
-
ts += diff;
|
310
|
-
}
|
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);
|
311
335
|
}
|
312
336
|
/**
|
337
|
+
* Convert JS string to byte array.
|
313
338
|
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
314
339
|
*/
|
315
340
|
function utf8ToBytes$2(str) {
|
316
341
|
if (typeof str !== 'string')
|
317
|
-
throw new Error(
|
342
|
+
throw new Error('utf8ToBytes expected string, got ' + typeof str);
|
318
343
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
319
344
|
}
|
320
345
|
/**
|
@@ -325,7 +350,7 @@ function utf8ToBytes$2(str) {
|
|
325
350
|
function toBytes$1(data) {
|
326
351
|
if (typeof data === 'string')
|
327
352
|
data = utf8ToBytes$2(data);
|
328
|
-
|
353
|
+
abytes$1(data);
|
329
354
|
return data;
|
330
355
|
}
|
331
356
|
/**
|
@@ -335,7 +360,7 @@ function concatBytes$2(...arrays) {
|
|
335
360
|
let sum = 0;
|
336
361
|
for (let i = 0; i < arrays.length; i++) {
|
337
362
|
const a = arrays[i];
|
338
|
-
|
363
|
+
abytes$1(a);
|
339
364
|
sum += a.length;
|
340
365
|
}
|
341
366
|
const res = new Uint8Array(sum);
|
@@ -346,20 +371,14 @@ function concatBytes$2(...arrays) {
|
|
346
371
|
}
|
347
372
|
return res;
|
348
373
|
}
|
349
|
-
|
374
|
+
/** For runtime check if class implements interface */
|
350
375
|
class Hash {
|
351
376
|
// Safe version that clones internal state
|
352
377
|
clone() {
|
353
378
|
return this._cloneInto();
|
354
379
|
}
|
355
380
|
}
|
356
|
-
|
357
|
-
function checkOpts(defaults, opts) {
|
358
|
-
if (opts !== undefined && toStr.call(opts) !== '[object Object]')
|
359
|
-
throw new Error('Options should be object or undefined');
|
360
|
-
const merged = Object.assign(defaults, opts);
|
361
|
-
return merged;
|
362
|
-
}
|
381
|
+
/** Wraps hash function, creating an interface on top of it */
|
363
382
|
function wrapConstructor(hashCons) {
|
364
383
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
365
384
|
const tmp = hashCons();
|
@@ -368,17 +387,23 @@ function wrapConstructor(hashCons) {
|
|
368
387
|
hashC.create = () => hashCons();
|
369
388
|
return hashC;
|
370
389
|
}
|
371
|
-
/**
|
372
|
-
|
373
|
-
*/
|
374
|
-
function randomBytes$1(bytesLength = 32) {
|
390
|
+
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
|
391
|
+
function randomBytes(bytesLength = 32) {
|
375
392
|
if (crypto$2 && typeof crypto$2.getRandomValues === 'function') {
|
376
393
|
return crypto$2.getRandomValues(new Uint8Array(bytesLength));
|
377
394
|
}
|
395
|
+
// Legacy Node.js compatibility
|
396
|
+
if (crypto$2 && typeof crypto$2.randomBytes === 'function') {
|
397
|
+
return crypto$2.randomBytes(bytesLength);
|
398
|
+
}
|
378
399
|
throw new Error('crypto.getRandomValues must be defined');
|
379
400
|
}
|
380
401
|
|
381
|
-
|
402
|
+
/**
|
403
|
+
* Internal Merkle-Damgard hash utils.
|
404
|
+
* @module
|
405
|
+
*/
|
406
|
+
/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
|
382
407
|
function setBigUint64(view, byteOffset, value, isLE) {
|
383
408
|
if (typeof view.setBigUint64 === 'function')
|
384
409
|
return view.setBigUint64(byteOffset, value, isLE);
|
@@ -391,10 +416,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
391
416
|
view.setUint32(byteOffset + h, wh, isLE);
|
392
417
|
view.setUint32(byteOffset + l, wl, isLE);
|
393
418
|
}
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
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
|
+
}
|
398
427
|
/**
|
399
428
|
* Merkle-Damgard hash construction base class.
|
400
429
|
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
@@ -414,7 +443,7 @@ class HashMD extends Hash {
|
|
414
443
|
this.view = createView(this.buffer);
|
415
444
|
}
|
416
445
|
update(data) {
|
417
|
-
|
446
|
+
aexists(this);
|
418
447
|
const { view, buffer, blockLen } = this;
|
419
448
|
data = toBytes$1(data);
|
420
449
|
const len = data.length;
|
@@ -440,8 +469,8 @@ class HashMD extends Hash {
|
|
440
469
|
return this;
|
441
470
|
}
|
442
471
|
digestInto(out) {
|
443
|
-
|
444
|
-
|
472
|
+
aexists(this);
|
473
|
+
aoutput(out, this);
|
445
474
|
this.finished = true;
|
446
475
|
// Padding
|
447
476
|
// We can avoid allocation of buffer for padding completely if it
|
@@ -498,10 +527,16 @@ class HashMD extends Hash {
|
|
498
527
|
}
|
499
528
|
}
|
500
529
|
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
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). */
|
505
540
|
// prettier-ignore
|
506
541
|
const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
507
542
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
@@ -513,14 +548,15 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
513
548
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
514
549
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
515
550
|
]);
|
516
|
-
|
517
|
-
// 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. */
|
518
552
|
// prettier-ignore
|
519
553
|
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
520
554
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
521
555
|
]);
|
522
|
-
|
523
|
-
|
556
|
+
/**
|
557
|
+
* Temporary buffer, not used to store anything between runs.
|
558
|
+
* Named this way because it matches specification.
|
559
|
+
*/
|
524
560
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
525
561
|
class SHA256 extends HashMD {
|
526
562
|
constructor() {
|
@@ -597,10 +633,7 @@ class SHA256 extends HashMD {
|
|
597
633
|
this.buffer.fill(0);
|
598
634
|
}
|
599
635
|
}
|
600
|
-
/**
|
601
|
-
* SHA2-256 hash function
|
602
|
-
* @param message - data that would be hashed
|
603
|
-
*/
|
636
|
+
/** SHA2-256 hash function */
|
604
637
|
const sha256$1 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
605
638
|
|
606
639
|
function equals$2(aa, bb) {
|
@@ -838,11 +871,12 @@ class Decoder {
|
|
838
871
|
constructor(name, prefix, baseDecode) {
|
839
872
|
this.name = name;
|
840
873
|
this.prefix = prefix;
|
874
|
+
const prefixCodePoint = prefix.codePointAt(0);
|
841
875
|
/* c8 ignore next 3 */
|
842
|
-
if (
|
876
|
+
if (prefixCodePoint === undefined) {
|
843
877
|
throw new Error('Invalid prefix character');
|
844
878
|
}
|
845
|
-
this.prefixCodePoint =
|
879
|
+
this.prefixCodePoint = prefixCodePoint;
|
846
880
|
this.baseDecode = baseDecode;
|
847
881
|
}
|
848
882
|
decode(text) {
|
@@ -1046,7 +1080,14 @@ var base2$1 = /*#__PURE__*/Object.freeze({
|
|
1046
1080
|
|
1047
1081
|
const alphabet = Array.from('🚀🪐☄🛰🌌🌑🌒🌓🌔🌕🌖🌗🌘🌍🌏🌎🐉☀💻🖥💾💿😂❤😍🤣😊🙏💕😭😘👍😅👏😁🔥🥰💔💖💙😢🤔😆🙄💪😉☺👌🤗💜😔😎😇🌹🤦🎉💞✌✨🤷😱😌🌸🙌😋💗💚😏💛🙂💓🤩😄😀🖤😃💯🙈👇🎶😒🤭❣😜💋👀😪😑💥🙋😞😩😡🤪👊🥳😥🤤👉💃😳✋😚😝😴🌟😬🙃🍀🌷😻😓⭐✅🥺🌈😈🤘💦✔😣🏃💐☹🎊💘😠☝😕🌺🎂🌻😐🖕💝🙊😹🗣💫💀👑🎵🤞😛🔴😤🌼😫⚽🤙☕🏆🤫👈😮🙆🍻🍃🐶💁😲🌿🧡🎁⚡🌞🎈❌✊👋😰🤨😶🤝🚶💰🍓💢🤟🙁🚨💨🤬✈🎀🍺🤓😙💟🌱😖👶🥴▶➡❓💎💸⬇😨🌚🦋😷🕺⚠🙅😟😵👎🤲🤠🤧📌🔵💅🧐🐾🍒😗🤑🌊🤯🐷☎💧😯💆👆🎤🙇🍑❄🌴💣🐸💌📍🥀🤢👅💡💩👐📸👻🤐🤮🎼🥵🚩🍎🍊👼💍📣🥂');
|
1048
1082
|
const alphabetBytesToChars = (alphabet.reduce((p, c, i) => { p[i] = c; return p; }, ([])));
|
1049
|
-
const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => {
|
1083
|
+
const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => {
|
1084
|
+
const codePoint = c.codePointAt(0);
|
1085
|
+
if (codePoint == null) {
|
1086
|
+
throw new Error(`Invalid character: ${c}`);
|
1087
|
+
}
|
1088
|
+
p[codePoint] = i;
|
1089
|
+
return p;
|
1090
|
+
}, ([])));
|
1050
1091
|
function encode$8(data) {
|
1051
1092
|
return data.reduce((p, c) => {
|
1052
1093
|
p += alphabetBytesToChars[c];
|
@@ -1056,8 +1097,12 @@ function encode$8(data) {
|
|
1056
1097
|
function decode$9(str) {
|
1057
1098
|
const byts = [];
|
1058
1099
|
for (const char of str) {
|
1059
|
-
const
|
1060
|
-
if (
|
1100
|
+
const codePoint = char.codePointAt(0);
|
1101
|
+
if (codePoint == null) {
|
1102
|
+
throw new Error(`Invalid character: ${char}`);
|
1103
|
+
}
|
1104
|
+
const byt = alphabetCharsToBytes[codePoint];
|
1105
|
+
if (byt == null) {
|
1061
1106
|
throw new Error(`Non-base256emoji character: ${char}`);
|
1062
1107
|
}
|
1063
1108
|
byts.push(byt);
|
@@ -1240,7 +1285,7 @@ new TextDecoder();
|
|
1240
1285
|
|
1241
1286
|
/* eslint-disable */
|
1242
1287
|
var encode_1 = encode$7;
|
1243
|
-
var MSB$1 = 0x80,
|
1288
|
+
var MSB$1 = 0x80, MSBALL = -128, INT = Math.pow(2, 31);
|
1244
1289
|
/**
|
1245
1290
|
* @param {number} num
|
1246
1291
|
* @param {number[]} out
|
@@ -1264,7 +1309,7 @@ function encode$7(num, out, offset) {
|
|
1264
1309
|
return out;
|
1265
1310
|
}
|
1266
1311
|
var decode$8 = read$1;
|
1267
|
-
var MSB$1$1 = 0x80, REST$1
|
1312
|
+
var MSB$1$1 = 0x80, REST$1 = 0x7F;
|
1268
1313
|
/**
|
1269
1314
|
* @param {string | any[]} buf
|
1270
1315
|
* @param {number} offset
|
@@ -1279,8 +1324,8 @@ function read$1(buf, offset) {
|
|
1279
1324
|
}
|
1280
1325
|
b = buf[counter++];
|
1281
1326
|
res += shift < 28
|
1282
|
-
? (b & REST$1
|
1283
|
-
: (b & REST$1
|
1327
|
+
? (b & REST$1) << shift
|
1328
|
+
: (b & REST$1) * Math.pow(2, shift);
|
1284
1329
|
shift += 7;
|
1285
1330
|
} while (b >= MSB$1$1);
|
1286
1331
|
// @ts-ignore
|
@@ -1330,7 +1375,7 @@ function encodingLength$3(int) {
|
|
1330
1375
|
/**
|
1331
1376
|
* Creates a multihash digest.
|
1332
1377
|
*/
|
1333
|
-
function create
|
1378
|
+
function create(code, digest) {
|
1334
1379
|
const size = digest.byteLength;
|
1335
1380
|
const sizeOffset = encodingLength$3(code);
|
1336
1381
|
const digestOffset = sizeOffset + encodingLength$3(size);
|
@@ -1389,7 +1434,7 @@ const code = 0x0;
|
|
1389
1434
|
const name$1 = 'identity';
|
1390
1435
|
const encode$6 = coerce;
|
1391
1436
|
function digest(input) {
|
1392
|
-
return create
|
1437
|
+
return create(code, encode$6(input));
|
1393
1438
|
}
|
1394
1439
|
const identity = { code, name: name$1, encode: encode$6, digest };
|
1395
1440
|
|
@@ -1413,9 +1458,9 @@ class Hasher {
|
|
1413
1458
|
if (input instanceof Uint8Array) {
|
1414
1459
|
const result = this.encode(input);
|
1415
1460
|
return result instanceof Uint8Array
|
1416
|
-
? create
|
1461
|
+
? create(this.code, result)
|
1417
1462
|
/* c8 ignore next 1 */
|
1418
|
-
: result.then(digest => create
|
1463
|
+
: result.then(digest => create(this.code, digest));
|
1419
1464
|
}
|
1420
1465
|
else {
|
1421
1466
|
throw Error('Unknown type, must be binary type');
|
@@ -1515,7 +1560,7 @@ class CID {
|
|
1515
1560
|
switch (this.version) {
|
1516
1561
|
case 0: {
|
1517
1562
|
const { code, digest } = this.multihash;
|
1518
|
-
const multihash = create
|
1563
|
+
const multihash = create(code, digest);
|
1519
1564
|
return (CID.createV1(this.code, multihash));
|
1520
1565
|
}
|
1521
1566
|
case 1: {
|
@@ -1745,9 +1790,13 @@ function parseCIDtoBytes(source, base) {
|
|
1745
1790
|
const decoder = base ?? base32$2;
|
1746
1791
|
return [base32$2.prefix, decoder.decode(source)];
|
1747
1792
|
}
|
1793
|
+
case base36.prefix: {
|
1794
|
+
const decoder = base ?? base36;
|
1795
|
+
return [base36.prefix, decoder.decode(source)];
|
1796
|
+
}
|
1748
1797
|
default: {
|
1749
1798
|
if (base == null) {
|
1750
|
-
throw Error('To parse non base32 or base58btc encoded CID multibase decoder must be provided');
|
1799
|
+
throw Error('To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided');
|
1751
1800
|
}
|
1752
1801
|
return [source[0], base.decode(source)];
|
1753
1802
|
}
|
@@ -2014,7 +2063,7 @@ function requireMs () {
|
|
2014
2063
|
* @api public
|
2015
2064
|
*/
|
2016
2065
|
|
2017
|
-
ms = function(val, options) {
|
2066
|
+
ms = function (val, options) {
|
2018
2067
|
options = options || {};
|
2019
2068
|
var type = typeof val;
|
2020
2069
|
if (type === 'string' && val.length > 0) {
|
@@ -2321,24 +2370,62 @@ function setup(env) {
|
|
2321
2370
|
createDebug.names = [];
|
2322
2371
|
createDebug.skips = [];
|
2323
2372
|
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2373
|
+
const split = (typeof namespaces === 'string' ? namespaces : '')
|
2374
|
+
.trim()
|
2375
|
+
.replace(' ', ',')
|
2376
|
+
.split(',')
|
2377
|
+
.filter(Boolean);
|
2327
2378
|
|
2328
|
-
for (
|
2329
|
-
if (
|
2330
|
-
|
2331
|
-
|
2379
|
+
for (const ns of split) {
|
2380
|
+
if (ns[0] === '-') {
|
2381
|
+
createDebug.skips.push(ns.slice(1));
|
2382
|
+
} else {
|
2383
|
+
createDebug.names.push(ns);
|
2332
2384
|
}
|
2385
|
+
}
|
2386
|
+
}
|
2333
2387
|
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
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;
|
2338
2418
|
} else {
|
2339
|
-
|
2419
|
+
return false; // No match
|
2340
2420
|
}
|
2341
2421
|
}
|
2422
|
+
|
2423
|
+
// Handle trailing '*' in template
|
2424
|
+
while (templateIndex < template.length && template[templateIndex] === '*') {
|
2425
|
+
templateIndex++;
|
2426
|
+
}
|
2427
|
+
|
2428
|
+
return templateIndex === template.length;
|
2342
2429
|
}
|
2343
2430
|
|
2344
2431
|
/**
|
@@ -2349,8 +2436,8 @@ function setup(env) {
|
|
2349
2436
|
*/
|
2350
2437
|
function disable() {
|
2351
2438
|
const namespaces = [
|
2352
|
-
...createDebug.names
|
2353
|
-
...createDebug.skips.map(
|
2439
|
+
...createDebug.names,
|
2440
|
+
...createDebug.skips.map(namespace => '-' + namespace)
|
2354
2441
|
].join(',');
|
2355
2442
|
createDebug.enable('');
|
2356
2443
|
return namespaces;
|
@@ -2364,21 +2451,14 @@ function setup(env) {
|
|
2364
2451
|
* @api public
|
2365
2452
|
*/
|
2366
2453
|
function enabled(name) {
|
2367
|
-
|
2368
|
-
|
2369
|
-
}
|
2370
|
-
|
2371
|
-
let i;
|
2372
|
-
let len;
|
2373
|
-
|
2374
|
-
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
2375
|
-
if (createDebug.skips[i].test(name)) {
|
2454
|
+
for (const skip of createDebug.skips) {
|
2455
|
+
if (matchesTemplate(name, skip)) {
|
2376
2456
|
return false;
|
2377
2457
|
}
|
2378
2458
|
}
|
2379
2459
|
|
2380
|
-
for (
|
2381
|
-
if (
|
2460
|
+
for (const ns of createDebug.names) {
|
2461
|
+
if (matchesTemplate(name, ns)) {
|
2382
2462
|
return true;
|
2383
2463
|
}
|
2384
2464
|
}
|
@@ -2386,19 +2466,6 @@ function setup(env) {
|
|
2386
2466
|
return false;
|
2387
2467
|
}
|
2388
2468
|
|
2389
|
-
/**
|
2390
|
-
* Convert regexp to namespace
|
2391
|
-
*
|
2392
|
-
* @param {RegExp} regxep
|
2393
|
-
* @return {String} namespace
|
2394
|
-
* @api private
|
2395
|
-
*/
|
2396
|
-
function toNamespace(regexp) {
|
2397
|
-
return regexp.toString()
|
2398
|
-
.substring(2, regexp.toString().length - 2)
|
2399
|
-
.replace(/\.\*\?$/, '*');
|
2400
|
-
}
|
2401
|
-
|
2402
2469
|
/**
|
2403
2470
|
* Coerce `val`.
|
2404
2471
|
*
|
@@ -2560,6 +2627,7 @@ var common = setup;
|
|
2560
2627
|
|
2561
2628
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
2562
2629
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
2630
|
+
// eslint-disable-next-line no-return-assign
|
2563
2631
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
2564
2632
|
// Is firebug? http://stackoverflow.com/a/398120/376773
|
2565
2633
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
@@ -2707,7 +2775,6 @@ var debug = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
|
|
2707
2775
|
|
2708
2776
|
const APP_NAME = "waku";
|
2709
2777
|
let Logger$1 = class Logger {
|
2710
|
-
_debug;
|
2711
2778
|
_info;
|
2712
2779
|
_warn;
|
2713
2780
|
_error;
|
@@ -2715,14 +2782,10 @@ let Logger$1 = class Logger {
|
|
2715
2782
|
return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
|
2716
2783
|
}
|
2717
2784
|
constructor(prefix) {
|
2718
|
-
this._debug = debug(Logger.createDebugNamespace("debug", prefix));
|
2719
2785
|
this._info = debug(Logger.createDebugNamespace("info", prefix));
|
2720
2786
|
this._warn = debug(Logger.createDebugNamespace("warn", prefix));
|
2721
2787
|
this._error = debug(Logger.createDebugNamespace("error", prefix));
|
2722
2788
|
}
|
2723
|
-
get debug() {
|
2724
|
-
return this._debug;
|
2725
|
-
}
|
2726
2789
|
get info() {
|
2727
2790
|
return this._info;
|
2728
2791
|
}
|
@@ -3005,10 +3068,10 @@ class JacobianPoint {
|
|
3005
3068
|
const cond1 = window % 2 !== 0;
|
3006
3069
|
const cond2 = wbits < 0;
|
3007
3070
|
if (wbits === 0) {
|
3008
|
-
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
3071
|
+
f = f.add(constTimeNegate$1(cond1, precomputes[offset1]));
|
3009
3072
|
}
|
3010
3073
|
else {
|
3011
|
-
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
3074
|
+
p = p.add(constTimeNegate$1(cond2, precomputes[offset2]));
|
3012
3075
|
}
|
3013
3076
|
}
|
3014
3077
|
return { p, f };
|
@@ -3021,8 +3084,8 @@ class JacobianPoint {
|
|
3021
3084
|
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
3022
3085
|
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
3023
3086
|
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
3024
|
-
k1p = constTimeNegate(k1neg, k1p);
|
3025
|
-
k2p = constTimeNegate(k2neg, k2p);
|
3087
|
+
k1p = constTimeNegate$1(k1neg, k1p);
|
3088
|
+
k2p = constTimeNegate$1(k2neg, k2p);
|
3026
3089
|
k2p = new JacobianPoint(mod$1(k2p.x * endo.beta), k2p.y, k2p.z);
|
3027
3090
|
point = k1p.add(k2p);
|
3028
3091
|
fake = f1p.add(f2p);
|
@@ -3054,7 +3117,7 @@ class JacobianPoint {
|
|
3054
3117
|
}
|
3055
3118
|
JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n$7);
|
3056
3119
|
JacobianPoint.ZERO = new JacobianPoint(_0n$5, _1n$7, _0n$5);
|
3057
|
-
function constTimeNegate(condition, item) {
|
3120
|
+
function constTimeNegate$1(condition, item) {
|
3058
3121
|
const neg = item.negate();
|
3059
3122
|
return condition ? neg : item;
|
3060
3123
|
}
|
@@ -4974,7 +5037,7 @@ function parseIPv6(input) {
|
|
4974
5037
|
return parser.new(input).parseWith(() => parser.readIPv6Addr());
|
4975
5038
|
}
|
4976
5039
|
/** Parse `input` into IPv4 or IPv6 bytes. */
|
4977
|
-
function parseIP(input) {
|
5040
|
+
function parseIP(input, mapIPv4ToIPv6 = false) {
|
4978
5041
|
// strip zone index if it is present
|
4979
5042
|
if (input.includes("%")) {
|
4980
5043
|
input = input.split("%")[0];
|
@@ -4982,7 +5045,14 @@ function parseIP(input) {
|
|
4982
5045
|
if (input.length > MAX_IPV6_LENGTH) {
|
4983
5046
|
return undefined;
|
4984
5047
|
}
|
4985
|
-
|
5048
|
+
const addr = parser.new(input).parseWith(() => parser.readIPAddr());
|
5049
|
+
if (!addr) {
|
5050
|
+
return undefined;
|
5051
|
+
}
|
5052
|
+
if (mapIPv4ToIPv6 && addr.length === 4) {
|
5053
|
+
return Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, addr[0], addr[1], addr[2], addr[3]]);
|
5054
|
+
}
|
5055
|
+
return addr;
|
4986
5056
|
}
|
4987
5057
|
|
4988
5058
|
/** Check if `input` is IPv4. */
|
@@ -5170,17 +5240,13 @@ function getProtocol(proto) {
|
|
5170
5240
|
throw new Error(`invalid protocol id type: ${typeof proto}`);
|
5171
5241
|
}
|
5172
5242
|
|
5173
|
-
/**
|
5174
|
-
* @packageDocumentation
|
5175
|
-
*
|
5176
|
-
* Provides methods for converting
|
5177
|
-
*/
|
5178
5243
|
getProtocol('ip4');
|
5179
5244
|
getProtocol('ip6');
|
5180
5245
|
getProtocol('ipcidr');
|
5181
5246
|
/**
|
5182
5247
|
* Convert [code,Uint8Array] to string
|
5183
5248
|
*/
|
5249
|
+
// eslint-disable-next-line complexity
|
5184
5250
|
function convertToString(proto, buf) {
|
5185
5251
|
const protocol = getProtocol(proto);
|
5186
5252
|
switch (protocol.code) {
|
@@ -5189,6 +5255,8 @@ function convertToString(proto, buf) {
|
|
5189
5255
|
return bytes2ip(buf);
|
5190
5256
|
case 42: // ipv6zone
|
5191
5257
|
return bytes2str(buf);
|
5258
|
+
case 43: // ipcidr
|
5259
|
+
return toString$6(buf, 'base10');
|
5192
5260
|
case 6: // tcp
|
5193
5261
|
case 273: // udp
|
5194
5262
|
case 33: // dccp
|
@@ -5216,6 +5284,7 @@ function convertToString(proto, buf) {
|
|
5216
5284
|
return toString$6(buf, 'base16'); // no clue. convert to hex
|
5217
5285
|
}
|
5218
5286
|
}
|
5287
|
+
// eslint-disable-next-line complexity
|
5219
5288
|
function convertToBytes(proto, str) {
|
5220
5289
|
const protocol = getProtocol(proto);
|
5221
5290
|
switch (protocol.code) {
|
@@ -5225,6 +5294,8 @@ function convertToBytes(proto, str) {
|
|
5225
5294
|
return ip2bytes(str);
|
5226
5295
|
case 42: // ipv6zone
|
5227
5296
|
return str2bytes(str);
|
5297
|
+
case 43: // ipcidr
|
5298
|
+
return fromString(str, 'base10');
|
5228
5299
|
case 6: // tcp
|
5229
5300
|
case 273: // udp
|
5230
5301
|
case 33: // dccp
|
@@ -5519,20 +5590,7 @@ function ParseError(str) {
|
|
5519
5590
|
return new Error('Error parsing address: ' + str);
|
5520
5591
|
}
|
5521
5592
|
|
5522
|
-
|
5523
|
-
* @packageDocumentation
|
5524
|
-
*
|
5525
|
-
* An implementation of a Multiaddr in JavaScript
|
5526
|
-
*
|
5527
|
-
* @example
|
5528
|
-
*
|
5529
|
-
* ```js
|
5530
|
-
* import { multiaddr } from '@multiformats/multiaddr'
|
5531
|
-
*
|
5532
|
-
* const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
5533
|
-
* ```
|
5534
|
-
*/
|
5535
|
-
const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
|
5593
|
+
const inspect$2 = Symbol.for('nodejs.util.inspect.custom');
|
5536
5594
|
const symbol$1 = Symbol.for('@multiformats/js-multiaddr/multiaddr');
|
5537
5595
|
const DNS_CODES = [
|
5538
5596
|
getProtocol('dns').code,
|
@@ -5540,6 +5598,12 @@ const DNS_CODES = [
|
|
5540
5598
|
getProtocol('dns6').code,
|
5541
5599
|
getProtocol('dnsaddr').code
|
5542
5600
|
];
|
5601
|
+
class NoAvailableResolverError extends Error {
|
5602
|
+
constructor(message = 'No available resolver') {
|
5603
|
+
super(message);
|
5604
|
+
this.name = 'NoAvailableResolverError';
|
5605
|
+
}
|
5606
|
+
}
|
5543
5607
|
/**
|
5544
5608
|
* Creates a {@link Multiaddr} from a {@link MultiaddrInput}
|
5545
5609
|
*/
|
@@ -5637,10 +5701,20 @@ class Multiaddr {
|
|
5637
5701
|
return this.#tuples.map(([code]) => getProtocol(code).name);
|
5638
5702
|
}
|
5639
5703
|
tuples() {
|
5640
|
-
return this.#tuples
|
5704
|
+
return this.#tuples.map(([code, value]) => {
|
5705
|
+
if (value == null) {
|
5706
|
+
return [code];
|
5707
|
+
}
|
5708
|
+
return [code, value];
|
5709
|
+
});
|
5641
5710
|
}
|
5642
5711
|
stringTuples() {
|
5643
|
-
return this.#stringTuples
|
5712
|
+
return this.#stringTuples.map(([code, value]) => {
|
5713
|
+
if (value == null) {
|
5714
|
+
return [code];
|
5715
|
+
}
|
5716
|
+
return [code, value];
|
5717
|
+
});
|
5644
5718
|
}
|
5645
5719
|
encapsulate(addr) {
|
5646
5720
|
addr = new Multiaddr(addr);
|
@@ -5709,7 +5783,7 @@ class Multiaddr {
|
|
5709
5783
|
}
|
5710
5784
|
const resolver = resolvers$1.get(resolvableProto.name);
|
5711
5785
|
if (resolver == null) {
|
5712
|
-
throw new
|
5786
|
+
throw new NoAvailableResolverError(`no available resolver for ${resolvableProto.name}`);
|
5713
5787
|
}
|
5714
5788
|
const result = await resolver(this, options);
|
5715
5789
|
return result.map(str => multiaddr(str));
|
@@ -5750,7 +5824,7 @@ class Multiaddr {
|
|
5750
5824
|
* // 'Multiaddr(/ip4/127.0.0.1/tcp/4001)'
|
5751
5825
|
* ```
|
5752
5826
|
*/
|
5753
|
-
[inspect$
|
5827
|
+
[inspect$2]() {
|
5754
5828
|
return `Multiaddr(${this.#string})`;
|
5755
5829
|
}
|
5756
5830
|
}
|
@@ -5770,10 +5844,8 @@ class Multiaddr {
|
|
5770
5844
|
*
|
5771
5845
|
* ```TypeScript
|
5772
5846
|
* import { multiaddr } from '@multiformats/multiaddr'
|
5773
|
-
* const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
|
5774
|
-
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5775
5847
|
*
|
5776
|
-
* const addr = multiaddr(
|
5848
|
+
* const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
|
5777
5849
|
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5778
5850
|
*
|
5779
5851
|
* addr.bytes
|
@@ -5812,9 +5884,9 @@ class Multiaddr {
|
|
5812
5884
|
*
|
5813
5885
|
* ```TypeScript
|
5814
5886
|
* import { multiaddr, resolvers } from '@multiformats/multiaddr'
|
5815
|
-
* import {
|
5887
|
+
* import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
5816
5888
|
*
|
5817
|
-
* resolvers.set('dnsaddr',
|
5889
|
+
* resolvers.set('dnsaddr', dnsaddrResolver)
|
5818
5890
|
*
|
5819
5891
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
5820
5892
|
*
|
@@ -5823,7 +5895,7 @@ class Multiaddr {
|
|
5823
5895
|
* signal: AbortSignal.timeout(5000)
|
5824
5896
|
* })
|
5825
5897
|
*
|
5826
|
-
* console.info(
|
5898
|
+
* console.info(resolved)
|
5827
5899
|
* // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
|
5828
5900
|
* ```
|
5829
5901
|
*
|
@@ -5837,7 +5909,9 @@ class Multiaddr {
|
|
5837
5909
|
* import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
|
5838
5910
|
*
|
5839
5911
|
* const resolver = dns({
|
5840
|
-
*
|
5912
|
+
* resolvers: {
|
5913
|
+
* '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
|
5914
|
+
* }
|
5841
5915
|
* })
|
5842
5916
|
*
|
5843
5917
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
@@ -5923,18 +5997,13 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
|
|
5923
5997
|
return multiaddrFromFields(isIpv6 ? "ip6" : "ip4", protoName, ipVal, protoVal);
|
5924
5998
|
}
|
5925
5999
|
|
5926
|
-
|
5927
|
-
|
5928
|
-
|
5929
|
-
|
5930
|
-
|
5931
|
-
typeof thing.catch === 'function' &&
|
5932
|
-
typeof thing.finally === 'function';
|
5933
|
-
}
|
5934
|
-
|
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
|
+
*/
|
5935
6005
|
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
5936
6006
|
const _32n = /* @__PURE__ */ BigInt(32);
|
5937
|
-
// We are not using BigUint64Array, because they are extremely slow as per 2022
|
5938
6007
|
function fromBig(n, le = false) {
|
5939
6008
|
if (le)
|
5940
6009
|
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
@@ -5991,6 +6060,13 @@ const u64 = {
|
|
5991
6060
|
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
5992
6061
|
};
|
5993
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
|
+
*/
|
5994
6070
|
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
5995
6071
|
// prettier-ignore
|
5996
6072
|
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
@@ -6145,8 +6221,13 @@ class SHA512 extends HashMD {
|
|
6145
6221
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
6146
6222
|
}
|
6147
6223
|
}
|
6224
|
+
/** SHA2-512 hash function. */
|
6148
6225
|
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
6149
6226
|
|
6227
|
+
/**
|
6228
|
+
* Hex, bytes and number utilities.
|
6229
|
+
* @module
|
6230
|
+
*/
|
6150
6231
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6151
6232
|
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
6152
6233
|
// This is OK: `abstract` directory does not use noble-hashes.
|
@@ -6156,8 +6237,7 @@ const _0n$4 = /* @__PURE__ */ BigInt(0);
|
|
6156
6237
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
6157
6238
|
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
6158
6239
|
function isBytes$1(a) {
|
6159
|
-
return
|
6160
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
6240
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
6161
6241
|
}
|
6162
6242
|
function abytes(item) {
|
6163
6243
|
if (!isBytes$1(item))
|
@@ -6165,7 +6245,7 @@ function abytes(item) {
|
|
6165
6245
|
}
|
6166
6246
|
function abool(title, value) {
|
6167
6247
|
if (typeof value !== 'boolean')
|
6168
|
-
throw new Error(
|
6248
|
+
throw new Error(title + ' boolean expected, got ' + value);
|
6169
6249
|
}
|
6170
6250
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6171
6251
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
@@ -6183,23 +6263,22 @@ function bytesToHex(bytes) {
|
|
6183
6263
|
}
|
6184
6264
|
function numberToHexUnpadded(num) {
|
6185
6265
|
const hex = num.toString(16);
|
6186
|
-
return hex.length & 1 ?
|
6266
|
+
return hex.length & 1 ? '0' + hex : hex;
|
6187
6267
|
}
|
6188
6268
|
function hexToNumber(hex) {
|
6189
6269
|
if (typeof hex !== 'string')
|
6190
6270
|
throw new Error('hex string expected, got ' + typeof hex);
|
6191
|
-
// Big Endian
|
6192
|
-
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
6271
|
+
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
6193
6272
|
}
|
6194
6273
|
// We use optimized technique to convert hex string to byte array
|
6195
|
-
const asciis = { _0: 48, _9: 57,
|
6196
|
-
function asciiToBase16(
|
6197
|
-
if (
|
6198
|
-
return
|
6199
|
-
if (
|
6200
|
-
return
|
6201
|
-
if (
|
6202
|
-
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)
|
6203
6282
|
return;
|
6204
6283
|
}
|
6205
6284
|
/**
|
@@ -6211,7 +6290,7 @@ function hexToBytes(hex) {
|
|
6211
6290
|
const hl = hex.length;
|
6212
6291
|
const al = hl / 2;
|
6213
6292
|
if (hl % 2)
|
6214
|
-
throw new Error('
|
6293
|
+
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
6215
6294
|
const array = new Uint8Array(al);
|
6216
6295
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
6217
6296
|
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
@@ -6220,7 +6299,7 @@ function hexToBytes(hex) {
|
|
6220
6299
|
const char = hex[hi] + hex[hi + 1];
|
6221
6300
|
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
6222
6301
|
}
|
6223
|
-
array[ai] = n1 * 16 + n2;
|
6302
|
+
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
|
6224
6303
|
}
|
6225
6304
|
return array;
|
6226
6305
|
}
|
@@ -6258,7 +6337,7 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6258
6337
|
res = hexToBytes(hex);
|
6259
6338
|
}
|
6260
6339
|
catch (e) {
|
6261
|
-
throw new Error(
|
6340
|
+
throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
|
6262
6341
|
}
|
6263
6342
|
}
|
6264
6343
|
else if (isBytes$1(hex)) {
|
@@ -6267,11 +6346,11 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6267
6346
|
res = Uint8Array.from(hex);
|
6268
6347
|
}
|
6269
6348
|
else {
|
6270
|
-
throw new Error(
|
6349
|
+
throw new Error(title + ' must be hex string or Uint8Array');
|
6271
6350
|
}
|
6272
6351
|
const len = res.length;
|
6273
6352
|
if (typeof expectedLength === 'number' && len !== expectedLength)
|
6274
|
-
throw new Error(
|
6353
|
+
throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
|
6275
6354
|
return res;
|
6276
6355
|
}
|
6277
6356
|
/**
|
@@ -6306,7 +6385,7 @@ function equalBytes(a, b) {
|
|
6306
6385
|
*/
|
6307
6386
|
function utf8ToBytes(str) {
|
6308
6387
|
if (typeof str !== 'string')
|
6309
|
-
throw new Error(
|
6388
|
+
throw new Error('string expected');
|
6310
6389
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6311
6390
|
}
|
6312
6391
|
// Is positive bigint
|
@@ -6326,7 +6405,7 @@ function aInRange(title, n, min, max) {
|
|
6326
6405
|
// - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
|
6327
6406
|
// - our way is the cleanest: `inRange('x', x, 0n, P)
|
6328
6407
|
if (!inRange(n, min, max))
|
6329
|
-
throw new Error(
|
6408
|
+
throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);
|
6330
6409
|
}
|
6331
6410
|
// Bit operations
|
6332
6411
|
/**
|
@@ -6436,12 +6515,12 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6436
6515
|
const checkField = (fieldName, type, isOptional) => {
|
6437
6516
|
const checkVal = validatorFns[type];
|
6438
6517
|
if (typeof checkVal !== 'function')
|
6439
|
-
throw new Error(
|
6518
|
+
throw new Error('invalid validator function');
|
6440
6519
|
const val = object[fieldName];
|
6441
6520
|
if (isOptional && val === undefined)
|
6442
6521
|
return;
|
6443
6522
|
if (!checkVal(val, object)) {
|
6444
|
-
throw new Error(
|
6523
|
+
throw new Error('param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val);
|
6445
6524
|
}
|
6446
6525
|
};
|
6447
6526
|
for (const [fieldName, type] of Object.entries(validators))
|
@@ -6510,14 +6589,17 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6510
6589
|
validateObject: validateObject
|
6511
6590
|
});
|
6512
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
|
+
*/
|
6513
6598
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6514
|
-
// Utilities for modular arithmetics and finite fields
|
6515
6599
|
// prettier-ignore
|
6516
|
-
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);
|
6517
6601
|
// prettier-ignore
|
6518
|
-
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
|
6519
|
-
// prettier-ignore
|
6520
|
-
BigInt(9); BigInt(16);
|
6602
|
+
const _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _8n$2 = /* @__PURE__ */ BigInt(8);
|
6521
6603
|
// Calculates a modulo b
|
6522
6604
|
function mod(a, b) {
|
6523
6605
|
const result = a % b;
|
@@ -6526,13 +6608,15 @@ function mod(a, b) {
|
|
6526
6608
|
/**
|
6527
6609
|
* Efficiently raise num to power and do modular division.
|
6528
6610
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
6611
|
+
* @todo use field version && remove
|
6529
6612
|
* @example
|
6530
6613
|
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
6531
6614
|
*/
|
6532
|
-
// TODO: use field version && remove
|
6533
6615
|
function pow(num, power, modulo) {
|
6534
|
-
if (
|
6535
|
-
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');
|
6536
6620
|
if (modulo === _1n$5)
|
6537
6621
|
return _0n$3;
|
6538
6622
|
let res = _1n$5;
|
@@ -6544,7 +6628,7 @@ function pow(num, power, modulo) {
|
|
6544
6628
|
}
|
6545
6629
|
return res;
|
6546
6630
|
}
|
6547
|
-
|
6631
|
+
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
6548
6632
|
function pow2(x, power, modulo) {
|
6549
6633
|
let res = x;
|
6550
6634
|
while (power-- > _0n$3) {
|
@@ -6553,12 +6637,15 @@ function pow2(x, power, modulo) {
|
|
6553
6637
|
}
|
6554
6638
|
return res;
|
6555
6639
|
}
|
6556
|
-
|
6640
|
+
/**
|
6641
|
+
* Inverses number over modulo.
|
6642
|
+
* Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).
|
6643
|
+
*/
|
6557
6644
|
function invert(number, modulo) {
|
6558
|
-
if (number === _0n$3
|
6559
|
-
throw new Error(
|
6560
|
-
|
6561
|
-
|
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);
|
6562
6649
|
// Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
|
6563
6650
|
let a = mod(number, modulo);
|
6564
6651
|
let b = modulo;
|
@@ -6598,8 +6685,11 @@ function tonelliShanks(P) {
|
|
6598
6685
|
for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
|
6599
6686
|
;
|
6600
6687
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
6601
|
-
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++)
|
6602
|
-
|
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
|
+
}
|
6603
6693
|
// Fast-path
|
6604
6694
|
if (S === 1) {
|
6605
6695
|
const p1div4 = (P + _1n$5) / _4n;
|
@@ -6641,9 +6731,18 @@ function tonelliShanks(P) {
|
|
6641
6731
|
return x;
|
6642
6732
|
};
|
6643
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
|
+
*/
|
6644
6745
|
function FpSqrt(P) {
|
6645
|
-
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
6646
|
-
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
6647
6746
|
// P ≡ 3 (mod 4)
|
6648
6747
|
// √n = n^((P+1)/4)
|
6649
6748
|
if (P % _4n === _3n$1) {
|
@@ -6707,7 +6806,7 @@ function FpPow(f, num, power) {
|
|
6707
6806
|
// Should have same speed as pow for bigints
|
6708
6807
|
// TODO: benchmark!
|
6709
6808
|
if (power < _0n$3)
|
6710
|
-
throw new Error('
|
6809
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6711
6810
|
if (power === _0n$3)
|
6712
6811
|
return f.ONE;
|
6713
6812
|
if (power === _1n$5)
|
@@ -6754,15 +6853,15 @@ function nLength(n, nBitLength) {
|
|
6754
6853
|
return { nBitLength: _nBitLength, nByteLength };
|
6755
6854
|
}
|
6756
6855
|
/**
|
6757
|
-
* Initializes a finite field over prime.
|
6758
|
-
* Do not init in loop: slow. Very fragile: always run a benchmark on a change.
|
6856
|
+
* Initializes a finite field over prime.
|
6759
6857
|
* Major performance optimizations:
|
6760
6858
|
* * a) denormalized operations like mulN instead of mul
|
6761
6859
|
* * b) same object shape: never add or remove keys
|
6762
6860
|
* * c) Object.freeze
|
6763
|
-
*
|
6861
|
+
* Fragile: always run a benchmark on a change.
|
6862
|
+
* Security note: operations don't check 'isValid' for all elements for performance reasons,
|
6764
6863
|
* it is caller responsibility to check this.
|
6765
|
-
* 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.
|
6766
6865
|
* @param ORDER prime positive bigint
|
6767
6866
|
* @param bitLen how many bits the field consumes
|
6768
6867
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6770,13 +6869,14 @@ function nLength(n, nBitLength) {
|
|
6770
6869
|
*/
|
6771
6870
|
function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
6772
6871
|
if (ORDER <= _0n$3)
|
6773
|
-
throw new Error(
|
6872
|
+
throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
|
6774
6873
|
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
6775
6874
|
if (BYTES > 2048)
|
6776
|
-
throw new Error('
|
6777
|
-
|
6875
|
+
throw new Error('invalid field: expected ORDER of <= 2048 bytes');
|
6876
|
+
let sqrtP; // cached sqrtP
|
6778
6877
|
const f = Object.freeze({
|
6779
6878
|
ORDER,
|
6879
|
+
isLE,
|
6780
6880
|
BITS,
|
6781
6881
|
BYTES,
|
6782
6882
|
MASK: bitMask(BITS),
|
@@ -6785,7 +6885,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6785
6885
|
create: (num) => mod(num, ORDER),
|
6786
6886
|
isValid: (num) => {
|
6787
6887
|
if (typeof num !== 'bigint')
|
6788
|
-
throw new Error(
|
6888
|
+
throw new Error('invalid field element: expected bigint, got ' + typeof num);
|
6789
6889
|
return _0n$3 <= num && num < ORDER; // 0 is valid element, but it's not invertible
|
6790
6890
|
},
|
6791
6891
|
is0: (num) => num === _0n$3,
|
@@ -6804,7 +6904,12 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6804
6904
|
subN: (lhs, rhs) => lhs - rhs,
|
6805
6905
|
mulN: (lhs, rhs) => lhs * rhs,
|
6806
6906
|
inv: (num) => invert(num, ORDER),
|
6807
|
-
sqrt: redef.sqrt ||
|
6907
|
+
sqrt: redef.sqrt ||
|
6908
|
+
((n) => {
|
6909
|
+
if (!sqrtP)
|
6910
|
+
sqrtP = FpSqrt(ORDER);
|
6911
|
+
return sqrtP(f, n);
|
6912
|
+
}),
|
6808
6913
|
invertBatch: (lst) => FpInvertBatch(f, lst),
|
6809
6914
|
// TODO: do we really need constant cmov?
|
6810
6915
|
// We don't have const-time bigints anyway, so probably will be not very useful
|
@@ -6812,7 +6917,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6812
6917
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
6813
6918
|
fromBytes: (bytes) => {
|
6814
6919
|
if (bytes.length !== BYTES)
|
6815
|
-
throw new Error(
|
6920
|
+
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
6816
6921
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
6817
6922
|
},
|
6818
6923
|
});
|
@@ -6860,52 +6965,80 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6860
6965
|
const minLen = getMinHashLength(fieldOrder);
|
6861
6966
|
// No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.
|
6862
6967
|
if (len < 16 || len < minLen || len > 1024)
|
6863
|
-
throw new Error(
|
6864
|
-
const num = isLE ?
|
6968
|
+
throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
|
6969
|
+
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
6865
6970
|
// `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
|
6866
6971
|
const reduced = mod(num, fieldOrder - _1n$5) + _1n$5;
|
6867
6972
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
6868
6973
|
}
|
6869
6974
|
|
6975
|
+
/**
|
6976
|
+
* Methods for elliptic curve multiplication by scalars.
|
6977
|
+
* Contains wNAF, pippenger
|
6978
|
+
* @module
|
6979
|
+
*/
|
6870
6980
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6871
|
-
// Abelian group utilities
|
6872
6981
|
const _0n$2 = BigInt(0);
|
6873
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
|
+
}
|
6874
7013
|
// Since points in different groups cannot be equal (different object constructor),
|
6875
7014
|
// we can have single place to store precomputes
|
6876
7015
|
const pointPrecomputes = new WeakMap();
|
6877
7016
|
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
6878
|
-
|
6879
|
-
|
6880
|
-
|
6881
|
-
|
6882
|
-
|
6883
|
-
|
6884
|
-
|
6885
|
-
|
6886
|
-
|
6887
|
-
|
6888
|
-
|
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
|
+
*/
|
6889
7034
|
function wNAF(c, bits) {
|
6890
|
-
const constTimeNegate = (condition, item) => {
|
6891
|
-
const neg = item.negate();
|
6892
|
-
return condition ? neg : item;
|
6893
|
-
};
|
6894
|
-
const validateW = (W) => {
|
6895
|
-
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6896
|
-
throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
|
6897
|
-
};
|
6898
|
-
const opts = (W) => {
|
6899
|
-
validateW(W);
|
6900
|
-
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6901
|
-
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6902
|
-
return { windows, windowSize };
|
6903
|
-
};
|
6904
7035
|
return {
|
6905
7036
|
constTimeNegate,
|
7037
|
+
hasPrecomputes(elm) {
|
7038
|
+
return getW(elm) !== 1;
|
7039
|
+
},
|
6906
7040
|
// non-const time multiplication ladder
|
6907
|
-
unsafeLadder(elm, n) {
|
6908
|
-
let p = c.ZERO;
|
7041
|
+
unsafeLadder(elm, n, p = c.ZERO) {
|
6909
7042
|
let d = elm;
|
6910
7043
|
while (n > _0n$2) {
|
6911
7044
|
if (n & _1n$4)
|
@@ -6923,10 +7056,12 @@ function wNAF(c, bits) {
|
|
6923
7056
|
* - 𝑊 is the window size
|
6924
7057
|
* - 𝑛 is the bitlength of the curve order.
|
6925
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
|
6926
7061
|
* @returns precomputed point tables flattened to a single array
|
6927
7062
|
*/
|
6928
7063
|
precomputeWindow(elm, W) {
|
6929
|
-
const { windows, windowSize } =
|
7064
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6930
7065
|
const points = [];
|
6931
7066
|
let p = elm;
|
6932
7067
|
let base = p;
|
@@ -6952,7 +7087,7 @@ function wNAF(c, bits) {
|
|
6952
7087
|
wNAF(W, precomputes, n) {
|
6953
7088
|
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
6954
7089
|
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
6955
|
-
const { windows, windowSize } =
|
7090
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6956
7091
|
let p = c.ZERO;
|
6957
7092
|
let f = c.BASE;
|
6958
7093
|
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
@@ -6996,8 +7131,44 @@ function wNAF(c, bits) {
|
|
6996
7131
|
// which makes it less const-time: around 1 bigint multiply.
|
6997
7132
|
return { p, f };
|
6998
7133
|
},
|
6999
|
-
|
7000
|
-
|
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) {
|
7001
7172
|
// Calculate precomputes on a first run, reuse them after
|
7002
7173
|
let comp = pointPrecomputes.get(P);
|
7003
7174
|
if (!comp) {
|
@@ -7005,18 +7176,76 @@ function wNAF(c, bits) {
|
|
7005
7176
|
if (W !== 1)
|
7006
7177
|
pointPrecomputes.set(P, transform(comp));
|
7007
7178
|
}
|
7008
|
-
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);
|
7009
7190
|
},
|
7010
7191
|
// We calculate precomputes for elliptic curve point multiplication
|
7011
7192
|
// using windowed method. This specifies window size and
|
7012
7193
|
// stores precomputed values. Usually only base point would be precomputed.
|
7013
7194
|
setWindowSize(P, W) {
|
7014
|
-
validateW(W);
|
7195
|
+
validateW(W, bits);
|
7015
7196
|
pointWindowSizes.set(P, W);
|
7016
7197
|
pointPrecomputes.delete(P);
|
7017
7198
|
},
|
7018
7199
|
};
|
7019
7200
|
}
|
7201
|
+
/**
|
7202
|
+
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
7203
|
+
* 30x faster vs naive addition on L=4096, 10x faster with precomputes.
|
7204
|
+
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
7205
|
+
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
7206
|
+
* @param c Curve Point constructor
|
7207
|
+
* @param fieldN field over CURVE.N - important that it's not over CURVE.P
|
7208
|
+
* @param points array of L curve points
|
7209
|
+
* @param scalars array of L scalars (aka private keys / bigints)
|
7210
|
+
*/
|
7211
|
+
function pippenger(c, fieldN, points, scalars) {
|
7212
|
+
// If we split scalars by some window (let's say 8 bits), every chunk will only
|
7213
|
+
// take 256 buckets even if there are 4096 scalars, also re-uses double.
|
7214
|
+
// TODO:
|
7215
|
+
// - https://eprint.iacr.org/2024/750.pdf
|
7216
|
+
// - https://tches.iacr.org/index.php/TCHES/article/view/10287
|
7217
|
+
// 0 is accepted in scalars
|
7218
|
+
validateMSMPoints(points, c);
|
7219
|
+
validateMSMScalars(scalars, fieldN);
|
7220
|
+
if (points.length !== scalars.length)
|
7221
|
+
throw new Error('arrays of points and scalars must have equal length');
|
7222
|
+
const zero = c.ZERO;
|
7223
|
+
const wbits = bitLen(BigInt(points.length));
|
7224
|
+
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
7225
|
+
const MASK = (1 << windowSize) - 1;
|
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;
|
7229
|
+
for (let i = lastBits; i >= 0; i -= windowSize) {
|
7230
|
+
buckets.fill(zero);
|
7231
|
+
for (let j = 0; j < scalars.length; j++) {
|
7232
|
+
const scalar = scalars[j];
|
7233
|
+
const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
|
7234
|
+
buckets[wbits] = buckets[wbits].add(points[j]);
|
7235
|
+
}
|
7236
|
+
let resI = zero; // not using this will do small speed-up, but will lose ct
|
7237
|
+
// Skip first bucket, because it is zero
|
7238
|
+
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
7239
|
+
sumI = sumI.add(buckets[j]);
|
7240
|
+
resI = resI.add(sumI);
|
7241
|
+
}
|
7242
|
+
sum = sum.add(resI);
|
7243
|
+
if (i !== 0)
|
7244
|
+
for (let j = 0; j < windowSize; j++)
|
7245
|
+
sum = sum.double();
|
7246
|
+
}
|
7247
|
+
return sum;
|
7248
|
+
}
|
7020
7249
|
function validateBasic(curve) {
|
7021
7250
|
validateField(curve.Fp);
|
7022
7251
|
validateObject(curve, {
|
@@ -7036,8 +7265,12 @@ function validateBasic(curve) {
|
|
7036
7265
|
});
|
7037
7266
|
}
|
7038
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
|
+
*/
|
7039
7273
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7040
|
-
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
7041
7274
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
7042
7275
|
// prettier-ignore
|
7043
7276
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -7069,8 +7302,13 @@ function validateOpts$1(curve) {
|
|
7069
7302
|
function twistedEdwards(curveDef) {
|
7070
7303
|
const CURVE = validateOpts$1(curveDef);
|
7071
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.
|
7072
7309
|
const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
|
7073
7310
|
const modP = Fp.create; // Function overrides
|
7311
|
+
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
7074
7312
|
// sqrt(u/v)
|
7075
7313
|
const uvRatio = CURVE.uvRatio ||
|
7076
7314
|
((u, v) => {
|
@@ -7169,6 +7407,10 @@ function twistedEdwards(curveDef) {
|
|
7169
7407
|
const toInv = Fp.invertBatch(points.map((p) => p.ez));
|
7170
7408
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
7171
7409
|
}
|
7410
|
+
// Multiscalar Multiplication
|
7411
|
+
static msm(points, scalars) {
|
7412
|
+
return pippenger(Point, Fn, points, scalars);
|
7413
|
+
}
|
7172
7414
|
// "Private method", don't use it directly
|
7173
7415
|
_setWindowSize(windowSize) {
|
7174
7416
|
wnaf.setWindowSize(this, windowSize);
|
@@ -7277,16 +7519,15 @@ function twistedEdwards(curveDef) {
|
|
7277
7519
|
// It's faster, but should only be used when you don't care about
|
7278
7520
|
// an exposed private key e.g. sig verification.
|
7279
7521
|
// Does NOT allow scalars higher than CURVE.n.
|
7280
|
-
|
7522
|
+
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
7523
|
+
multiplyUnsafe(scalar, acc = Point.ZERO) {
|
7281
7524
|
const n = scalar;
|
7282
7525
|
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7283
7526
|
if (n === _0n$1)
|
7284
7527
|
return I;
|
7285
|
-
if (this.
|
7528
|
+
if (this.is0() || n === _1n$3)
|
7286
7529
|
return this;
|
7287
|
-
|
7288
|
-
return this.wNAF(n).p;
|
7289
|
-
return wnaf.unsafeLadder(this, n);
|
7530
|
+
return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
|
7290
7531
|
}
|
7291
7532
|
// Checks if point is of small order.
|
7292
7533
|
// If you add something to small order point, you will have "dirty"
|
@@ -7320,8 +7561,9 @@ function twistedEdwards(curveDef) {
|
|
7320
7561
|
abool('zip215', zip215);
|
7321
7562
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7322
7563
|
const lastByte = hex[len - 1]; // select last byte
|
7323
|
-
normed[len - 1] = lastByte &
|
7564
|
+
normed[len - 1] = lastByte & -129; // clear last bit
|
7324
7565
|
const y = bytesToNumberLE(normed);
|
7566
|
+
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
7325
7567
|
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
7326
7568
|
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7327
7569
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
@@ -7370,7 +7612,7 @@ function twistedEdwards(curveDef) {
|
|
7370
7612
|
}
|
7371
7613
|
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
7372
7614
|
function getExtendedPublicKey(key) {
|
7373
|
-
const len =
|
7615
|
+
const len = Fp.BYTES;
|
7374
7616
|
key = ensureBytes('private key', key, len);
|
7375
7617
|
// Hash private key with curve's hash function to produce uniformingly random input
|
7376
7618
|
// Check byte lengths: ensure(64, h(ensure(32, key)))
|
@@ -7403,23 +7645,29 @@ function twistedEdwards(curveDef) {
|
|
7403
7645
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7404
7646
|
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7405
7647
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7406
|
-
return ensureBytes('result', res,
|
7648
|
+
return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
|
7407
7649
|
}
|
7408
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
|
+
*/
|
7409
7655
|
function verify(sig, msg, publicKey, options = verifyOpts) {
|
7410
7656
|
const { context, zip215 } = options;
|
7411
7657
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7412
7658
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7413
7659
|
msg = ensureBytes('message', msg);
|
7660
|
+
publicKey = ensureBytes('publicKey', publicKey, len);
|
7414
7661
|
if (zip215 !== undefined)
|
7415
7662
|
abool('zip215', zip215);
|
7416
7663
|
if (prehash)
|
7417
7664
|
msg = prehash(msg); // for ed25519ph, etc
|
7418
7665
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
7419
|
-
// zip215: true is good for consensus-critical apps and allows points < 2^256
|
7420
|
-
// zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
|
7421
7666
|
let A, R, SB;
|
7422
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)
|
7423
7671
|
A = Point.fromHex(publicKey, zip215);
|
7424
7672
|
R = Point.fromHex(sig.slice(0, len), zip215);
|
7425
7673
|
SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
|
@@ -7431,6 +7679,7 @@ function twistedEdwards(curveDef) {
|
|
7431
7679
|
return false;
|
7432
7680
|
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
7433
7681
|
const RkA = R.add(A.multiplyUnsafe(k));
|
7682
|
+
// Extended group equation
|
7434
7683
|
// [8][S]B = [8]R + [8][k]A'
|
7435
7684
|
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
7436
7685
|
}
|
@@ -7461,13 +7710,14 @@ function twistedEdwards(curveDef) {
|
|
7461
7710
|
};
|
7462
7711
|
}
|
7463
7712
|
|
7464
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7465
7713
|
/**
|
7466
7714
|
* ed25519 Twisted Edwards curve with following addons:
|
7467
7715
|
* - X25519 ECDH
|
7468
7716
|
* - Ristretto cofactor elimination
|
7469
7717
|
* - Elligator hash-to-group / point indistinguishability
|
7718
|
+
* @module
|
7470
7719
|
*/
|
7720
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7471
7721
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7472
7722
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
7473
7723
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
@@ -7526,7 +7776,7 @@ function uvRatio(u, v) {
|
|
7526
7776
|
x = mod(-x, P);
|
7527
7777
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7528
7778
|
}
|
7529
|
-
const Fp
|
7779
|
+
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7530
7780
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7531
7781
|
// Param: a
|
7532
7782
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
@@ -7534,7 +7784,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7534
7784
|
// Negative number is P - number, and division is invert(number, P)
|
7535
7785
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
7536
7786
|
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
7537
|
-
Fp
|
7787
|
+
Fp,
|
7538
7788
|
// Subgroup order: how many points curve has
|
7539
7789
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7540
7790
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
@@ -7544,7 +7794,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7544
7794
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
7545
7795
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
7546
7796
|
hash: sha512,
|
7547
|
-
randomBytes
|
7797
|
+
randomBytes,
|
7548
7798
|
adjustScalarBytes,
|
7549
7799
|
// dom2
|
7550
7800
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
@@ -7553,180 +7803,58 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7553
7803
|
}))();
|
7554
7804
|
/**
|
7555
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
|
7556
7814
|
*/
|
7557
7815
|
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7558
7816
|
|
7559
7817
|
const PUBLIC_KEY_BYTE_LENGTH = 32;
|
7560
|
-
const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
7561
|
-
const KEYS_BYTE_LENGTH = 32;
|
7562
|
-
function generateKey$2() {
|
7563
|
-
// the actual private key (32 bytes)
|
7564
|
-
const privateKeyRaw = ed25519.utils.randomPrivateKey();
|
7565
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7566
|
-
// concatenated the public key to the private key
|
7567
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7568
|
-
return {
|
7569
|
-
privateKey,
|
7570
|
-
publicKey
|
7571
|
-
};
|
7572
|
-
}
|
7573
|
-
/**
|
7574
|
-
* Generate keypair from a 32 byte uint8array
|
7575
|
-
*/
|
7576
|
-
function generateKeyFromSeed(seed) {
|
7577
|
-
if (seed.length !== KEYS_BYTE_LENGTH) {
|
7578
|
-
throw new TypeError('"seed" must be 32 bytes in length.');
|
7579
|
-
}
|
7580
|
-
else if (!(seed instanceof Uint8Array)) {
|
7581
|
-
throw new TypeError('"seed" must be a node.js Buffer, or Uint8Array.');
|
7582
|
-
}
|
7583
|
-
// based on node forges algorithm, the seed is used directly as private key
|
7584
|
-
const privateKeyRaw = seed;
|
7585
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7586
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7587
|
-
return {
|
7588
|
-
privateKey,
|
7589
|
-
publicKey
|
7590
|
-
};
|
7591
|
-
}
|
7592
|
-
function hashAndSign$2(privateKey, msg) {
|
7593
|
-
const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH);
|
7594
|
-
return ed25519.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw);
|
7595
|
-
}
|
7596
7818
|
function hashAndVerify$2(publicKey, sig, msg) {
|
7597
7819
|
return ed25519.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey);
|
7598
7820
|
}
|
7599
|
-
function concatKeys(privateKeyRaw, publicKey) {
|
7600
|
-
const privateKey = new Uint8Array(PRIVATE_KEY_BYTE_LENGTH);
|
7601
|
-
for (let i = 0; i < KEYS_BYTE_LENGTH; i++) {
|
7602
|
-
privateKey[i] = privateKeyRaw[i];
|
7603
|
-
privateKey[KEYS_BYTE_LENGTH + i] = publicKey[i];
|
7604
|
-
}
|
7605
|
-
return privateKey;
|
7606
|
-
}
|
7607
7821
|
|
7608
|
-
|
7609
|
-
|
7610
|
-
|
7611
|
-
|
7612
|
-
|
7613
|
-
const nativeCrypto = win.crypto;
|
7614
|
-
if (nativeCrypto?.subtle == null) {
|
7615
|
-
throw Object.assign(new Error('Missing Web Crypto API. ' +
|
7616
|
-
'The most likely cause of this error is that this page is being accessed ' +
|
7617
|
-
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
7618
|
-
'possible resolutions see ' +
|
7619
|
-
'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api'), { code: 'ERR_MISSING_WEB_CRYPTO' });
|
7620
|
-
}
|
7621
|
-
return nativeCrypto;
|
7822
|
+
class Ed25519PublicKey {
|
7823
|
+
type = 'Ed25519';
|
7824
|
+
raw;
|
7825
|
+
constructor(key) {
|
7826
|
+
this.raw = ensureEd25519Key(key, PUBLIC_KEY_BYTE_LENGTH);
|
7622
7827
|
}
|
7623
|
-
|
7624
|
-
|
7625
|
-
// WebKit on Linux does not support deriving a key from an empty PBKDF2 key.
|
7626
|
-
// So, as a workaround, we provide the generated key as a constant. We test that
|
7627
|
-
// this generated key is accurate in test/workaround.spec.ts
|
7628
|
-
// Generated via:
|
7629
|
-
// await crypto.subtle.exportKey('jwk',
|
7630
|
-
// await crypto.subtle.deriveKey(
|
7631
|
-
// { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } },
|
7632
|
-
// await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']),
|
7633
|
-
// { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt'])
|
7634
|
-
// )
|
7635
|
-
const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
|
7636
|
-
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
|
7637
|
-
function create(opts) {
|
7638
|
-
const algorithm = 'AES-GCM';
|
7639
|
-
let keyLength = 16;
|
7640
|
-
const nonceLength = 12;
|
7641
|
-
const digest = 'SHA-256';
|
7642
|
-
const saltLength = 16;
|
7643
|
-
const iterations = 32767;
|
7644
|
-
const crypto = webcrypto.get();
|
7645
|
-
keyLength *= 8; // Browser crypto uses bits instead of bytes
|
7646
|
-
/**
|
7647
|
-
* Uses the provided password to derive a pbkdf2 key. The key
|
7648
|
-
* will then be used to encrypt the data.
|
7649
|
-
*/
|
7650
|
-
async function encrypt(data, password) {
|
7651
|
-
const salt = crypto.getRandomValues(new Uint8Array(saltLength));
|
7652
|
-
const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
|
7653
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7654
|
-
if (typeof password === 'string') {
|
7655
|
-
password = fromString(password);
|
7656
|
-
}
|
7657
|
-
let cryptoKey;
|
7658
|
-
if (password.length === 0) {
|
7659
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7660
|
-
try {
|
7661
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7662
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7663
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7664
|
-
}
|
7665
|
-
catch {
|
7666
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7667
|
-
}
|
7668
|
-
}
|
7669
|
-
else {
|
7670
|
-
// Derive a key using PBKDF2.
|
7671
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7672
|
-
const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7673
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7674
|
-
}
|
7675
|
-
// Encrypt the string.
|
7676
|
-
const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data);
|
7677
|
-
return concat$1([salt, aesGcm.iv, new Uint8Array(ciphertext)]);
|
7828
|
+
toMultihash() {
|
7829
|
+
return identity.digest(publicKeyToProtobuf(this));
|
7678
7830
|
}
|
7679
|
-
|
7680
|
-
|
7681
|
-
|
7682
|
-
|
7683
|
-
|
7684
|
-
|
7685
|
-
|
7686
|
-
|
7687
|
-
|
7688
|
-
const ciphertext = data.subarray(saltLength + nonceLength);
|
7689
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7690
|
-
if (typeof password === 'string') {
|
7691
|
-
password = fromString(password);
|
7692
|
-
}
|
7693
|
-
let cryptoKey;
|
7694
|
-
if (password.length === 0) {
|
7695
|
-
try {
|
7696
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7697
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7698
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['decrypt']);
|
7699
|
-
}
|
7700
|
-
catch {
|
7701
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']);
|
7702
|
-
}
|
7831
|
+
toCID() {
|
7832
|
+
return CID.createV1(114, this.toMultihash());
|
7833
|
+
}
|
7834
|
+
toString() {
|
7835
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
7836
|
+
}
|
7837
|
+
equals(key) {
|
7838
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
7839
|
+
return false;
|
7703
7840
|
}
|
7704
|
-
|
7705
|
-
|
7706
|
-
|
7707
|
-
|
7708
|
-
|
7709
|
-
}
|
7710
|
-
// Decrypt the string.
|
7711
|
-
const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext);
|
7712
|
-
return new Uint8Array(plaintext);
|
7713
|
-
}
|
7714
|
-
const cipher = {
|
7715
|
-
encrypt,
|
7716
|
-
decrypt
|
7717
|
-
};
|
7718
|
-
return cipher;
|
7841
|
+
return equals(this.raw, key.raw);
|
7842
|
+
}
|
7843
|
+
verify(data, sig) {
|
7844
|
+
return hashAndVerify$2(this.raw, sig, data);
|
7845
|
+
}
|
7719
7846
|
}
|
7720
7847
|
|
7721
|
-
|
7722
|
-
|
7723
|
-
|
7724
|
-
|
7725
|
-
|
7726
|
-
|
7727
|
-
|
7728
|
-
|
7729
|
-
|
7848
|
+
function unmarshalEd25519PublicKey(bytes) {
|
7849
|
+
bytes = ensureEd25519Key(bytes, PUBLIC_KEY_BYTE_LENGTH);
|
7850
|
+
return new Ed25519PublicKey(bytes);
|
7851
|
+
}
|
7852
|
+
function ensureEd25519Key(key, length) {
|
7853
|
+
key = Uint8Array.from(key ?? []);
|
7854
|
+
if (key.length !== length) {
|
7855
|
+
throw new InvalidParametersError(`Key must be a Uint8Array of length ${length}, got ${key.length}`);
|
7856
|
+
}
|
7857
|
+
return key;
|
7730
7858
|
}
|
7731
7859
|
|
7732
7860
|
const f32 = new Float32Array([-0]);
|
@@ -8959,13 +9087,13 @@ var KeyType;
|
|
8959
9087
|
(function (KeyType) {
|
8960
9088
|
KeyType["RSA"] = "RSA";
|
8961
9089
|
KeyType["Ed25519"] = "Ed25519";
|
8962
|
-
KeyType["
|
9090
|
+
KeyType["secp256k1"] = "secp256k1";
|
8963
9091
|
})(KeyType || (KeyType = {}));
|
8964
9092
|
var __KeyTypeValues;
|
8965
9093
|
(function (__KeyTypeValues) {
|
8966
9094
|
__KeyTypeValues[__KeyTypeValues["RSA"] = 0] = "RSA";
|
8967
9095
|
__KeyTypeValues[__KeyTypeValues["Ed25519"] = 1] = "Ed25519";
|
8968
|
-
__KeyTypeValues[__KeyTypeValues["
|
9096
|
+
__KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1";
|
8969
9097
|
})(__KeyTypeValues || (__KeyTypeValues = {}));
|
8970
9098
|
(function (KeyType) {
|
8971
9099
|
KeyType.codec = () => {
|
@@ -8992,21 +9120,24 @@ var PublicKey;
|
|
8992
9120
|
if (opts.lengthDelimited !== false) {
|
8993
9121
|
w.ldelim();
|
8994
9122
|
}
|
8995
|
-
}, (reader, length) => {
|
9123
|
+
}, (reader, length, opts = {}) => {
|
8996
9124
|
const obj = {};
|
8997
9125
|
const end = length == null ? reader.len : reader.pos + length;
|
8998
9126
|
while (reader.pos < end) {
|
8999
9127
|
const tag = reader.uint32();
|
9000
9128
|
switch (tag >>> 3) {
|
9001
|
-
case 1:
|
9129
|
+
case 1: {
|
9002
9130
|
obj.Type = KeyType.codec().decode(reader);
|
9003
9131
|
break;
|
9004
|
-
|
9132
|
+
}
|
9133
|
+
case 2: {
|
9005
9134
|
obj.Data = reader.bytes();
|
9006
9135
|
break;
|
9007
|
-
|
9136
|
+
}
|
9137
|
+
default: {
|
9008
9138
|
reader.skipType(tag & 7);
|
9009
9139
|
break;
|
9140
|
+
}
|
9010
9141
|
}
|
9011
9142
|
}
|
9012
9143
|
return obj;
|
@@ -9017,8 +9148,8 @@ var PublicKey;
|
|
9017
9148
|
PublicKey.encode = (obj) => {
|
9018
9149
|
return encodeMessage(obj, PublicKey.codec());
|
9019
9150
|
};
|
9020
|
-
PublicKey.decode = (buf) => {
|
9021
|
-
return decodeMessage(buf, PublicKey.codec());
|
9151
|
+
PublicKey.decode = (buf, opts) => {
|
9152
|
+
return decodeMessage(buf, PublicKey.codec(), opts);
|
9022
9153
|
};
|
9023
9154
|
})(PublicKey || (PublicKey = {}));
|
9024
9155
|
var PrivateKey;
|
@@ -9041,21 +9172,24 @@ var PrivateKey;
|
|
9041
9172
|
if (opts.lengthDelimited !== false) {
|
9042
9173
|
w.ldelim();
|
9043
9174
|
}
|
9044
|
-
}, (reader, length) => {
|
9175
|
+
}, (reader, length, opts = {}) => {
|
9045
9176
|
const obj = {};
|
9046
9177
|
const end = length == null ? reader.len : reader.pos + length;
|
9047
9178
|
while (reader.pos < end) {
|
9048
9179
|
const tag = reader.uint32();
|
9049
9180
|
switch (tag >>> 3) {
|
9050
|
-
case 1:
|
9181
|
+
case 1: {
|
9051
9182
|
obj.Type = KeyType.codec().decode(reader);
|
9052
9183
|
break;
|
9053
|
-
|
9184
|
+
}
|
9185
|
+
case 2: {
|
9054
9186
|
obj.Data = reader.bytes();
|
9055
9187
|
break;
|
9056
|
-
|
9188
|
+
}
|
9189
|
+
default: {
|
9057
9190
|
reader.skipType(tag & 7);
|
9058
9191
|
break;
|
9192
|
+
}
|
9059
9193
|
}
|
9060
9194
|
}
|
9061
9195
|
return obj;
|
@@ -9066,286 +9200,15 @@ var PrivateKey;
|
|
9066
9200
|
PrivateKey.encode = (obj) => {
|
9067
9201
|
return encodeMessage(obj, PrivateKey.codec());
|
9068
9202
|
};
|
9069
|
-
PrivateKey.decode = (buf) => {
|
9070
|
-
return decodeMessage(buf, PrivateKey.codec());
|
9203
|
+
PrivateKey.decode = (buf, opts) => {
|
9204
|
+
return decodeMessage(buf, PrivateKey.codec(), opts);
|
9071
9205
|
};
|
9072
9206
|
})(PrivateKey || (PrivateKey = {}));
|
9073
9207
|
|
9074
|
-
class Ed25519PublicKey {
|
9075
|
-
_key;
|
9076
|
-
constructor(key) {
|
9077
|
-
this._key = ensureKey(key, PUBLIC_KEY_BYTE_LENGTH);
|
9078
|
-
}
|
9079
|
-
verify(data, sig) {
|
9080
|
-
return hashAndVerify$2(this._key, sig, data);
|
9081
|
-
}
|
9082
|
-
marshal() {
|
9083
|
-
return this._key;
|
9084
|
-
}
|
9085
|
-
get bytes() {
|
9086
|
-
return PublicKey.encode({
|
9087
|
-
Type: KeyType.Ed25519,
|
9088
|
-
Data: this.marshal()
|
9089
|
-
}).subarray();
|
9090
|
-
}
|
9091
|
-
equals(key) {
|
9092
|
-
return equals(this.bytes, key.bytes);
|
9093
|
-
}
|
9094
|
-
hash() {
|
9095
|
-
const p = sha256.digest(this.bytes);
|
9096
|
-
if (isPromise$1(p)) {
|
9097
|
-
return p.then(({ bytes }) => bytes);
|
9098
|
-
}
|
9099
|
-
return p.bytes;
|
9100
|
-
}
|
9101
|
-
}
|
9102
|
-
class Ed25519PrivateKey {
|
9103
|
-
_key;
|
9104
|
-
_publicKey;
|
9105
|
-
// key - 64 byte Uint8Array containing private key
|
9106
|
-
// publicKey - 32 byte Uint8Array containing public key
|
9107
|
-
constructor(key, publicKey) {
|
9108
|
-
this._key = ensureKey(key, PRIVATE_KEY_BYTE_LENGTH);
|
9109
|
-
this._publicKey = ensureKey(publicKey, PUBLIC_KEY_BYTE_LENGTH);
|
9110
|
-
}
|
9111
|
-
sign(message) {
|
9112
|
-
return hashAndSign$2(this._key, message);
|
9113
|
-
}
|
9114
|
-
get public() {
|
9115
|
-
return new Ed25519PublicKey(this._publicKey);
|
9116
|
-
}
|
9117
|
-
marshal() {
|
9118
|
-
return this._key;
|
9119
|
-
}
|
9120
|
-
get bytes() {
|
9121
|
-
return PrivateKey.encode({
|
9122
|
-
Type: KeyType.Ed25519,
|
9123
|
-
Data: this.marshal()
|
9124
|
-
}).subarray();
|
9125
|
-
}
|
9126
|
-
equals(key) {
|
9127
|
-
return equals(this.bytes, key.bytes);
|
9128
|
-
}
|
9129
|
-
async hash() {
|
9130
|
-
const p = sha256.digest(this.bytes);
|
9131
|
-
let bytes;
|
9132
|
-
if (isPromise$1(p)) {
|
9133
|
-
({ bytes } = await p);
|
9134
|
-
}
|
9135
|
-
else {
|
9136
|
-
bytes = p.bytes;
|
9137
|
-
}
|
9138
|
-
return bytes;
|
9139
|
-
}
|
9140
|
-
/**
|
9141
|
-
* Gets the ID of the key.
|
9142
|
-
*
|
9143
|
-
* The key id is the base58 encoding of the identity multihash containing its public key.
|
9144
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
9145
|
-
* of the PKCS SubjectPublicKeyInfo.
|
9146
|
-
*
|
9147
|
-
* @returns {Promise<string>}
|
9148
|
-
*/
|
9149
|
-
async id() {
|
9150
|
-
const encoding = identity.digest(this.public.bytes);
|
9151
|
-
return base58btc.encode(encoding.bytes).substring(1);
|
9152
|
-
}
|
9153
|
-
/**
|
9154
|
-
* Exports the key into a password protected `format`
|
9155
|
-
*/
|
9156
|
-
async export(password, format = 'libp2p-key') {
|
9157
|
-
if (format === 'libp2p-key') {
|
9158
|
-
return exporter(this.bytes, password);
|
9159
|
-
}
|
9160
|
-
else {
|
9161
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
9162
|
-
}
|
9163
|
-
}
|
9164
|
-
}
|
9165
|
-
function unmarshalEd25519PrivateKey(bytes) {
|
9166
|
-
// Try the old, redundant public key version
|
9167
|
-
if (bytes.length > PRIVATE_KEY_BYTE_LENGTH) {
|
9168
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH + PUBLIC_KEY_BYTE_LENGTH);
|
9169
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9170
|
-
const publicKeyBytes = bytes.subarray(PRIVATE_KEY_BYTE_LENGTH, bytes.length);
|
9171
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9172
|
-
}
|
9173
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH);
|
9174
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9175
|
-
const publicKeyBytes = bytes.subarray(PUBLIC_KEY_BYTE_LENGTH);
|
9176
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9177
|
-
}
|
9178
|
-
function unmarshalEd25519PublicKey(bytes) {
|
9179
|
-
bytes = ensureKey(bytes, PUBLIC_KEY_BYTE_LENGTH);
|
9180
|
-
return new Ed25519PublicKey(bytes);
|
9181
|
-
}
|
9182
|
-
async function generateKeyPair$2() {
|
9183
|
-
const { privateKey, publicKey } = generateKey$2();
|
9184
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9185
|
-
}
|
9186
|
-
async function generateKeyPairFromSeed(seed) {
|
9187
|
-
const { privateKey, publicKey } = generateKeyFromSeed(seed);
|
9188
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9189
|
-
}
|
9190
|
-
function ensureKey(key, length) {
|
9191
|
-
key = Uint8Array.from(key ?? []);
|
9192
|
-
if (key.length !== length) {
|
9193
|
-
throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
|
9194
|
-
}
|
9195
|
-
return key;
|
9196
|
-
}
|
9197
|
-
|
9198
|
-
var Ed25519 = /*#__PURE__*/Object.freeze({
|
9199
|
-
__proto__: null,
|
9200
|
-
Ed25519PrivateKey: Ed25519PrivateKey,
|
9201
|
-
Ed25519PublicKey: Ed25519PublicKey,
|
9202
|
-
generateKeyPair: generateKeyPair$2,
|
9203
|
-
generateKeyPairFromSeed: generateKeyPairFromSeed,
|
9204
|
-
unmarshalEd25519PrivateKey: unmarshalEd25519PrivateKey,
|
9205
|
-
unmarshalEd25519PublicKey: unmarshalEd25519PublicKey
|
9206
|
-
});
|
9207
|
-
|
9208
|
-
/**
|
9209
|
-
* Generates a Uint8Array with length `number` populated by random bytes
|
9210
|
-
*/
|
9211
|
-
function randomBytes(length) {
|
9212
|
-
if (isNaN(length) || length <= 0) {
|
9213
|
-
throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
|
9214
|
-
}
|
9215
|
-
return randomBytes$1(length);
|
9216
|
-
}
|
9217
|
-
|
9218
|
-
// HMAC (RFC 2104)
|
9219
|
-
class HMAC extends Hash {
|
9220
|
-
constructor(hash$1, _key) {
|
9221
|
-
super();
|
9222
|
-
this.finished = false;
|
9223
|
-
this.destroyed = false;
|
9224
|
-
hash(hash$1);
|
9225
|
-
const key = toBytes$1(_key);
|
9226
|
-
this.iHash = hash$1.create();
|
9227
|
-
if (typeof this.iHash.update !== 'function')
|
9228
|
-
throw new Error('Expected instance of class which extends utils.Hash');
|
9229
|
-
this.blockLen = this.iHash.blockLen;
|
9230
|
-
this.outputLen = this.iHash.outputLen;
|
9231
|
-
const blockLen = this.blockLen;
|
9232
|
-
const pad = new Uint8Array(blockLen);
|
9233
|
-
// blockLen can be bigger than outputLen
|
9234
|
-
pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
|
9235
|
-
for (let i = 0; i < pad.length; i++)
|
9236
|
-
pad[i] ^= 0x36;
|
9237
|
-
this.iHash.update(pad);
|
9238
|
-
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
9239
|
-
this.oHash = hash$1.create();
|
9240
|
-
// Undo internal XOR && apply outer XOR
|
9241
|
-
for (let i = 0; i < pad.length; i++)
|
9242
|
-
pad[i] ^= 0x36 ^ 0x5c;
|
9243
|
-
this.oHash.update(pad);
|
9244
|
-
pad.fill(0);
|
9245
|
-
}
|
9246
|
-
update(buf) {
|
9247
|
-
exists(this);
|
9248
|
-
this.iHash.update(buf);
|
9249
|
-
return this;
|
9250
|
-
}
|
9251
|
-
digestInto(out) {
|
9252
|
-
exists(this);
|
9253
|
-
bytes(out, this.outputLen);
|
9254
|
-
this.finished = true;
|
9255
|
-
this.iHash.digestInto(out);
|
9256
|
-
this.oHash.update(out);
|
9257
|
-
this.oHash.digestInto(out);
|
9258
|
-
this.destroy();
|
9259
|
-
}
|
9260
|
-
digest() {
|
9261
|
-
const out = new Uint8Array(this.oHash.outputLen);
|
9262
|
-
this.digestInto(out);
|
9263
|
-
return out;
|
9264
|
-
}
|
9265
|
-
_cloneInto(to) {
|
9266
|
-
// Create new instance without calling constructor since key already in state and we don't know it.
|
9267
|
-
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
9268
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
9269
|
-
to = to;
|
9270
|
-
to.finished = finished;
|
9271
|
-
to.destroyed = destroyed;
|
9272
|
-
to.blockLen = blockLen;
|
9273
|
-
to.outputLen = outputLen;
|
9274
|
-
to.oHash = oHash._cloneInto(to.oHash);
|
9275
|
-
to.iHash = iHash._cloneInto(to.iHash);
|
9276
|
-
return to;
|
9277
|
-
}
|
9278
|
-
destroy() {
|
9279
|
-
this.destroyed = true;
|
9280
|
-
this.oHash.destroy();
|
9281
|
-
this.iHash.destroy();
|
9282
|
-
}
|
9283
|
-
}
|
9284
|
-
/**
|
9285
|
-
* HMAC: RFC2104 message authentication code.
|
9286
|
-
* @param hash - function that would be used e.g. sha256
|
9287
|
-
* @param key - message key
|
9288
|
-
* @param message - message data
|
9289
|
-
*/
|
9290
|
-
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
9291
|
-
hmac.create = (hash, key) => new HMAC(hash, key);
|
9292
|
-
|
9293
|
-
// Common prologue and epilogue for sync/async functions
|
9294
|
-
function pbkdf2Init(hash$1, _password, _salt, _opts) {
|
9295
|
-
hash(hash$1);
|
9296
|
-
const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
|
9297
|
-
const { c, dkLen, asyncTick } = opts;
|
9298
|
-
number(c);
|
9299
|
-
number(dkLen);
|
9300
|
-
number(asyncTick);
|
9301
|
-
if (c < 1)
|
9302
|
-
throw new Error('PBKDF2: iterations (c) should be >= 1');
|
9303
|
-
const password = toBytes$1(_password);
|
9304
|
-
const salt = toBytes$1(_salt);
|
9305
|
-
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
|
9306
|
-
const DK = new Uint8Array(dkLen);
|
9307
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9308
|
-
const PRF = hmac.create(hash$1, password);
|
9309
|
-
const PRFSalt = PRF._cloneInto().update(salt);
|
9310
|
-
return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
|
9311
|
-
}
|
9312
|
-
function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
|
9313
|
-
PRF.destroy();
|
9314
|
-
PRFSalt.destroy();
|
9315
|
-
if (prfW)
|
9316
|
-
prfW.destroy();
|
9317
|
-
u.fill(0);
|
9318
|
-
return DK;
|
9319
|
-
}
|
9320
|
-
async function pbkdf2Async(hash, password, salt, opts) {
|
9321
|
-
const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
9322
|
-
let prfW; // Working copy
|
9323
|
-
const arr = new Uint8Array(4);
|
9324
|
-
const view = createView(arr);
|
9325
|
-
const u = new Uint8Array(PRF.outputLen);
|
9326
|
-
// DK = T1 + T2 + ⋯ + Tdklen/hlen
|
9327
|
-
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
9328
|
-
// Ti = F(Password, Salt, c, i)
|
9329
|
-
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
9330
|
-
view.setInt32(0, ti, false);
|
9331
|
-
// F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
|
9332
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9333
|
-
(prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
|
9334
|
-
Ti.set(u.subarray(0, Ti.length));
|
9335
|
-
await asyncLoop(c - 1, asyncTick, () => {
|
9336
|
-
// Uc = PRF(Password, Uc−1)
|
9337
|
-
PRF._cloneInto(prfW).update(u).digestInto(u);
|
9338
|
-
for (let i = 0; i < Ti.length; i++)
|
9339
|
-
Ti[i] ^= u[i];
|
9340
|
-
});
|
9341
|
-
}
|
9342
|
-
return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
|
9343
|
-
}
|
9344
|
-
|
9345
9208
|
/*!
|
9346
9209
|
* MIT License
|
9347
9210
|
*
|
9348
|
-
* Copyright (c) 2017-
|
9211
|
+
* Copyright (c) 2017-2024 Peculiar Ventures, LLC
|
9349
9212
|
*
|
9350
9213
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9351
9214
|
* of this software and associated documentation files (the "Software"), to deal
|
@@ -9457,7 +9320,7 @@ class BufferSourceConverter {
|
|
9457
9320
|
}
|
9458
9321
|
|
9459
9322
|
const STRING_TYPE = "string";
|
9460
|
-
const HEX_REGEX = /^[0-9a-f]+$/i;
|
9323
|
+
const HEX_REGEX = /^[0-9a-f\s]+$/i;
|
9461
9324
|
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
9462
9325
|
const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
|
9463
9326
|
class Utf8Converter {
|
@@ -9691,7 +9554,7 @@ class Convert {
|
|
9691
9554
|
return base64;
|
9692
9555
|
}
|
9693
9556
|
static formatString(data) {
|
9694
|
-
return (data === null || data ===
|
9557
|
+
return (data === null || data === undefined ? undefined : data.replace(/[\n\r\t ]/g, "")) || "";
|
9695
9558
|
}
|
9696
9559
|
}
|
9697
9560
|
Convert.DEFAULT_UTF8_ENCODING = "utf8";
|
@@ -9947,7 +9810,7 @@ function HexBlock(BaseClass) {
|
|
9947
9810
|
var _a;
|
9948
9811
|
super(...args);
|
9949
9812
|
const params = args[0] || {};
|
9950
|
-
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !==
|
9813
|
+
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9951
9814
|
this.valueHexView = params.valueHex ? BufferSourceConverter_1.toUint8Array(params.valueHex) : EMPTY_VIEW;
|
9952
9815
|
}
|
9953
9816
|
get valueHex() {
|
@@ -10037,11 +9900,11 @@ class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
|
|
10037
9900
|
var _a, _b, _c, _d;
|
10038
9901
|
super();
|
10039
9902
|
if (idBlock) {
|
10040
|
-
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !==
|
9903
|
+
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== undefined ? _a : false;
|
10041
9904
|
this.valueHexView = idBlock.valueHex ? BufferSourceConverter_1.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
|
10042
|
-
this.tagClass = (_b = idBlock.tagClass) !== null && _b !==
|
10043
|
-
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !==
|
10044
|
-
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;
|
10045
9908
|
}
|
10046
9909
|
else {
|
10047
9910
|
this.tagClass = -1;
|
@@ -10208,9 +10071,9 @@ class LocalLengthBlock extends LocalBaseBlock {
|
|
10208
10071
|
constructor({ lenBlock = {}, } = {}) {
|
10209
10072
|
var _a, _b, _c;
|
10210
10073
|
super();
|
10211
|
-
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !==
|
10212
|
-
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !==
|
10213
|
-
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;
|
10214
10077
|
}
|
10215
10078
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
10216
10079
|
const view = BufferSourceConverter_1.toUint8Array(inputBuffer);
|
@@ -10982,7 +10845,7 @@ var _a$r;
|
|
10982
10845
|
class OctetString extends BaseBlock {
|
10983
10846
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
10984
10847
|
var _b, _c;
|
10985
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10848
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
10986
10849
|
super({
|
10987
10850
|
idBlock: {
|
10988
10851
|
isConstructed: parameters.isConstructed,
|
@@ -11143,7 +11006,7 @@ var _a$q;
|
|
11143
11006
|
class BitString extends BaseBlock {
|
11144
11007
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
11145
11008
|
var _b, _c;
|
11146
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
11009
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
11147
11010
|
super({
|
11148
11011
|
idBlock: {
|
11149
11012
|
isConstructed: parameters.isConstructed,
|
@@ -12345,7 +12208,7 @@ class GeneralizedTime extends UTCTime {
|
|
12345
12208
|
constructor(parameters = {}) {
|
12346
12209
|
var _b;
|
12347
12210
|
super(parameters);
|
12348
|
-
(_b = this.millisecond) !== null && _b !==
|
12211
|
+
(_b = this.millisecond) !== null && _b !== undefined ? _b : (this.millisecond = 0);
|
12349
12212
|
this.idBlock.tagClass = 1;
|
12350
12213
|
this.idBlock.tagNumber = 24;
|
12351
12214
|
}
|
@@ -12593,78 +12456,127 @@ _a = TIME;
|
|
12593
12456
|
TIME.NAME = "TIME";
|
12594
12457
|
|
12595
12458
|
/**
|
12596
|
-
*
|
12459
|
+
* Signing a message failed
|
12597
12460
|
*/
|
12598
|
-
function pkcs1ToJwk(bytes) {
|
12599
|
-
const { result } = fromBER(bytes);
|
12600
|
-
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12601
|
-
// safe to have deeply property chains like this
|
12602
|
-
const values = result.valueBlock.value;
|
12603
|
-
const key = {
|
12604
|
-
n: toString$6(bnToBuf(values[1].toBigInt()), 'base64url'),
|
12605
|
-
e: toString$6(bnToBuf(values[2].toBigInt()), 'base64url'),
|
12606
|
-
d: toString$6(bnToBuf(values[3].toBigInt()), 'base64url'),
|
12607
|
-
p: toString$6(bnToBuf(values[4].toBigInt()), 'base64url'),
|
12608
|
-
q: toString$6(bnToBuf(values[5].toBigInt()), 'base64url'),
|
12609
|
-
dp: toString$6(bnToBuf(values[6].toBigInt()), 'base64url'),
|
12610
|
-
dq: toString$6(bnToBuf(values[7].toBigInt()), 'base64url'),
|
12611
|
-
qi: toString$6(bnToBuf(values[8].toBigInt()), 'base64url'),
|
12612
|
-
kty: 'RSA',
|
12613
|
-
alg: 'RS256'
|
12614
|
-
};
|
12615
|
-
return key;
|
12616
|
-
}
|
12617
12461
|
/**
|
12618
|
-
*
|
12462
|
+
* Verifying a message signature failed
|
12619
12463
|
*/
|
12620
|
-
|
12621
|
-
|
12622
|
-
|
12464
|
+
class VerificationError extends Error {
|
12465
|
+
constructor(message = 'An error occurred while verifying a message') {
|
12466
|
+
super(message);
|
12467
|
+
this.name = 'VerificationError';
|
12623
12468
|
}
|
12624
|
-
const root = new Sequence({
|
12625
|
-
value: [
|
12626
|
-
new Integer({ value: 0 }),
|
12627
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12628
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url'))),
|
12629
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.d, 'base64url'))),
|
12630
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.p, 'base64url'))),
|
12631
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.q, 'base64url'))),
|
12632
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dp, 'base64url'))),
|
12633
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dq, 'base64url'))),
|
12634
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.qi, 'base64url')))
|
12635
|
-
]
|
12636
|
-
});
|
12637
|
-
const der = root.toBER();
|
12638
|
-
return new Uint8Array(der, 0, der.byteLength);
|
12639
12469
|
}
|
12640
12470
|
/**
|
12641
|
-
*
|
12471
|
+
* WebCrypto was not available in the current context
|
12642
12472
|
*/
|
12643
|
-
|
12644
|
-
|
12645
|
-
|
12646
|
-
|
12647
|
-
|
12648
|
-
return {
|
12649
|
-
kty: 'RSA',
|
12650
|
-
n: toString$6(bnToBuf(values[0].toBigInt()), 'base64url'),
|
12651
|
-
e: toString$6(bnToBuf(values[1].toBigInt()), 'base64url')
|
12652
|
-
};
|
12473
|
+
class WebCryptoMissingError extends Error {
|
12474
|
+
constructor(message = 'Missing Web Crypto API') {
|
12475
|
+
super(message);
|
12476
|
+
this.name = 'WebCryptoMissingError';
|
12477
|
+
}
|
12653
12478
|
}
|
12654
|
-
|
12655
|
-
|
12656
|
-
|
12657
|
-
|
12658
|
-
|
12659
|
-
|
12479
|
+
|
12480
|
+
/* eslint-env browser */
|
12481
|
+
// Check native crypto exists and is enabled (In insecure context `self.crypto`
|
12482
|
+
// exists but `self.crypto.subtle` does not).
|
12483
|
+
var webcrypto = {
|
12484
|
+
get(win = globalThis) {
|
12485
|
+
const nativeCrypto = win.crypto;
|
12486
|
+
if (nativeCrypto?.subtle == null) {
|
12487
|
+
throw new WebCryptoMissingError('Missing Web Crypto API. ' +
|
12488
|
+
'The most likely cause of this error is that this page is being accessed ' +
|
12489
|
+
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
12490
|
+
'possible resolutions see ' +
|
12491
|
+
'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api');
|
12492
|
+
}
|
12493
|
+
return nativeCrypto;
|
12660
12494
|
}
|
12661
|
-
|
12662
|
-
|
12663
|
-
|
12664
|
-
|
12665
|
-
|
12666
|
-
|
12667
|
-
|
12495
|
+
};
|
12496
|
+
|
12497
|
+
async function hashAndVerify$1(key, sig, msg) {
|
12498
|
+
const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12499
|
+
name: 'RSASSA-PKCS1-v1_5',
|
12500
|
+
hash: { name: 'SHA-256' }
|
12501
|
+
}, false, ['verify']);
|
12502
|
+
return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
|
12503
|
+
}
|
12504
|
+
function rsaKeySize(jwk) {
|
12505
|
+
if (jwk.kty !== 'RSA') {
|
12506
|
+
throw new InvalidParametersError('invalid key type');
|
12507
|
+
}
|
12508
|
+
else if (jwk.n == null) {
|
12509
|
+
throw new InvalidParametersError('invalid key modulus');
|
12510
|
+
}
|
12511
|
+
const bytes = fromString(jwk.n, 'base64url');
|
12512
|
+
return bytes.length * 8;
|
12513
|
+
}
|
12514
|
+
|
12515
|
+
class RSAPublicKey {
|
12516
|
+
type = 'RSA';
|
12517
|
+
_key;
|
12518
|
+
_raw;
|
12519
|
+
_multihash;
|
12520
|
+
constructor(key, digest) {
|
12521
|
+
this._key = key;
|
12522
|
+
this._multihash = digest;
|
12523
|
+
}
|
12524
|
+
get raw() {
|
12525
|
+
if (this._raw == null) {
|
12526
|
+
this._raw = jwkToPkix(this._key);
|
12527
|
+
}
|
12528
|
+
return this._raw;
|
12529
|
+
}
|
12530
|
+
toMultihash() {
|
12531
|
+
return this._multihash;
|
12532
|
+
}
|
12533
|
+
toCID() {
|
12534
|
+
return CID.createV1(114, this._multihash);
|
12535
|
+
}
|
12536
|
+
toString() {
|
12537
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
12538
|
+
}
|
12539
|
+
equals(key) {
|
12540
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
12541
|
+
return false;
|
12542
|
+
}
|
12543
|
+
return equals(this.raw, key.raw);
|
12544
|
+
}
|
12545
|
+
verify(data, sig) {
|
12546
|
+
return hashAndVerify$1(this._key, sig, data);
|
12547
|
+
}
|
12548
|
+
}
|
12549
|
+
|
12550
|
+
const MAX_RSA_KEY_SIZE = 8192;
|
12551
|
+
const SHA2_256_CODE = 0x12;
|
12552
|
+
/**
|
12553
|
+
* Convert a PKIX in ASN1 DER format to a JWK key
|
12554
|
+
*/
|
12555
|
+
function pkixToJwk(bytes) {
|
12556
|
+
const { result } = fromBER(bytes);
|
12557
|
+
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12558
|
+
// safe to have deeply property chains like this
|
12559
|
+
const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
|
12560
|
+
return {
|
12561
|
+
kty: 'RSA',
|
12562
|
+
n: asn1jsIntegerToBase64(values[0]),
|
12563
|
+
e: asn1jsIntegerToBase64(values[1])
|
12564
|
+
};
|
12565
|
+
}
|
12566
|
+
/**
|
12567
|
+
* Convert a JWK key to PKIX in ASN1 DER format
|
12568
|
+
*/
|
12569
|
+
function jwkToPkix(jwk) {
|
12570
|
+
if (jwk.n == null || jwk.e == null) {
|
12571
|
+
throw new InvalidParametersError('JWK was missing components');
|
12572
|
+
}
|
12573
|
+
const root = new Sequence({
|
12574
|
+
value: [
|
12575
|
+
new Sequence({
|
12576
|
+
value: [
|
12577
|
+
// rsaEncryption
|
12578
|
+
new ObjectIdentifier({
|
12579
|
+
value: '1.2.840.113549.1.1.1'
|
12668
12580
|
}),
|
12669
12581
|
new Null()
|
12670
12582
|
]
|
@@ -12684,21 +12596,13 @@ function jwkToPkix(jwk) {
|
|
12684
12596
|
const der = root.toBER();
|
12685
12597
|
return new Uint8Array(der, 0, der.byteLength);
|
12686
12598
|
}
|
12687
|
-
function
|
12688
|
-
let
|
12689
|
-
|
12690
|
-
|
12691
|
-
|
12692
|
-
const len = hex.length / 2;
|
12693
|
-
const u8 = new Uint8Array(len);
|
12694
|
-
let i = 0;
|
12695
|
-
let j = 0;
|
12696
|
-
while (i < len) {
|
12697
|
-
u8[i] = parseInt(hex.slice(j, j + 2), 16);
|
12698
|
-
i += 1;
|
12699
|
-
j += 2;
|
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);
|
12700
12604
|
}
|
12701
|
-
return
|
12605
|
+
return toString$6(buf, 'base64url');
|
12702
12606
|
}
|
12703
12607
|
function bufToBn(u8) {
|
12704
12608
|
const hex = [];
|
@@ -12711,331 +12615,131 @@ function bufToBn(u8) {
|
|
12711
12615
|
});
|
12712
12616
|
return BigInt('0x' + hex.join(''));
|
12713
12617
|
}
|
12714
|
-
|
12715
|
-
|
12716
|
-
|
12717
|
-
|
12718
|
-
const
|
12719
|
-
|
12720
|
-
|
12721
|
-
value: [
|
12722
|
-
// version (0)
|
12723
|
-
new Integer({ value: 0 }),
|
12724
|
-
// privateKeyAlgorithm
|
12725
|
-
new Sequence({
|
12726
|
-
value: [
|
12727
|
-
// rsaEncryption OID
|
12728
|
-
new ObjectIdentifier({
|
12729
|
-
value: '1.2.840.113549.1.1.1'
|
12730
|
-
}),
|
12731
|
-
new Null()
|
12732
|
-
]
|
12733
|
-
}),
|
12734
|
-
// PrivateKey
|
12735
|
-
new OctetString({
|
12736
|
-
valueHex: privateKey.marshal()
|
12737
|
-
})
|
12738
|
-
]
|
12739
|
-
});
|
12740
|
-
const keyBuf = keyWrapper.toBER();
|
12741
|
-
const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
|
12742
|
-
const salt = randomBytes(SALT_LENGTH);
|
12743
|
-
const encryptionKey = await pbkdf2Async(sha512, password, salt, {
|
12744
|
-
c: ITERATIONS,
|
12745
|
-
dkLen: KEY_SIZE
|
12746
|
-
});
|
12747
|
-
const iv = randomBytes(16);
|
12748
|
-
const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['encrypt']);
|
12749
|
-
const encrypted = await crypto.subtle.encrypt({
|
12750
|
-
name: 'AES-CBC',
|
12751
|
-
iv
|
12752
|
-
}, cryptoKey, keyArr);
|
12753
|
-
const pbkdf2Params = new Sequence({
|
12754
|
-
value: [
|
12755
|
-
// salt
|
12756
|
-
new OctetString({ valueHex: salt }),
|
12757
|
-
// iteration count
|
12758
|
-
new Integer({ value: ITERATIONS }),
|
12759
|
-
// key length
|
12760
|
-
new Integer({ value: KEY_SIZE }),
|
12761
|
-
// AlgorithmIdentifier
|
12762
|
-
new Sequence({
|
12763
|
-
value: [
|
12764
|
-
// hmacWithSHA512
|
12765
|
-
new ObjectIdentifier({ value: '1.2.840.113549.2.11' }),
|
12766
|
-
new Null()
|
12767
|
-
]
|
12768
|
-
})
|
12769
|
-
]
|
12770
|
-
});
|
12771
|
-
const encryptionAlgorithm = new Sequence({
|
12772
|
-
value: [
|
12773
|
-
// pkcs5PBES2
|
12774
|
-
new ObjectIdentifier({
|
12775
|
-
value: '1.2.840.113549.1.5.13'
|
12776
|
-
}),
|
12777
|
-
new Sequence({
|
12778
|
-
value: [
|
12779
|
-
// keyDerivationFunc
|
12780
|
-
new Sequence({
|
12781
|
-
value: [
|
12782
|
-
// pkcs5PBKDF2
|
12783
|
-
new ObjectIdentifier({
|
12784
|
-
value: '1.2.840.113549.1.5.12'
|
12785
|
-
}),
|
12786
|
-
// PBKDF2-params
|
12787
|
-
pbkdf2Params
|
12788
|
-
]
|
12789
|
-
}),
|
12790
|
-
// encryptionScheme
|
12791
|
-
new Sequence({
|
12792
|
-
value: [
|
12793
|
-
// aes256-CBC
|
12794
|
-
new ObjectIdentifier({
|
12795
|
-
value: '2.16.840.1.101.3.4.1.42'
|
12796
|
-
}),
|
12797
|
-
// iv
|
12798
|
-
new OctetString({
|
12799
|
-
valueHex: iv
|
12800
|
-
})
|
12801
|
-
]
|
12802
|
-
})
|
12803
|
-
]
|
12804
|
-
})
|
12805
|
-
]
|
12806
|
-
});
|
12807
|
-
const finalWrapper = new Sequence({
|
12808
|
-
value: [
|
12809
|
-
encryptionAlgorithm,
|
12810
|
-
new OctetString({ valueHex: encrypted })
|
12811
|
-
]
|
12812
|
-
});
|
12813
|
-
const finalWrapperBuf = finalWrapper.toBER();
|
12814
|
-
const finalWrapperArr = new Uint8Array(finalWrapperBuf, 0, finalWrapperBuf.byteLength);
|
12815
|
-
return [
|
12816
|
-
'-----BEGIN ENCRYPTED PRIVATE KEY-----',
|
12817
|
-
...toString$6(finalWrapperArr, 'base64pad').split(/(.{64})/).filter(Boolean),
|
12818
|
-
'-----END ENCRYPTED PRIVATE KEY-----'
|
12819
|
-
].join('\n');
|
12820
|
-
}
|
12821
|
-
|
12822
|
-
async function generateKey$1(bits) {
|
12823
|
-
const pair = await webcrypto.get().subtle.generateKey({
|
12824
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12825
|
-
modulusLength: bits,
|
12826
|
-
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
12827
|
-
hash: { name: 'SHA-256' }
|
12828
|
-
}, true, ['sign', 'verify']);
|
12829
|
-
const keys = await exportKey(pair);
|
12830
|
-
return {
|
12831
|
-
privateKey: keys[0],
|
12832
|
-
publicKey: keys[1]
|
12833
|
-
};
|
12834
|
-
}
|
12835
|
-
// Takes a jwk key
|
12836
|
-
async function unmarshalPrivateKey$1(key) {
|
12837
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12838
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12839
|
-
hash: { name: 'SHA-256' }
|
12840
|
-
}, true, ['sign']);
|
12841
|
-
const pair = [
|
12842
|
-
privateKey,
|
12843
|
-
await derivePublicFromPrivate(key)
|
12844
|
-
];
|
12845
|
-
const keys = await exportKey({
|
12846
|
-
privateKey: pair[0],
|
12847
|
-
publicKey: pair[1]
|
12848
|
-
});
|
12849
|
-
return {
|
12850
|
-
privateKey: keys[0],
|
12851
|
-
publicKey: keys[1]
|
12852
|
-
};
|
12853
|
-
}
|
12854
|
-
async function hashAndSign$1(key, msg) {
|
12855
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12856
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12857
|
-
hash: { name: 'SHA-256' }
|
12858
|
-
}, false, ['sign']);
|
12859
|
-
const sig = await webcrypto.get().subtle.sign({ name: 'RSASSA-PKCS1-v1_5' }, privateKey, msg instanceof Uint8Array ? msg : msg.subarray());
|
12860
|
-
return new Uint8Array(sig, 0, sig.byteLength);
|
12861
|
-
}
|
12862
|
-
async function hashAndVerify$1(key, sig, msg) {
|
12863
|
-
const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12864
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12865
|
-
hash: { name: 'SHA-256' }
|
12866
|
-
}, false, ['verify']);
|
12867
|
-
return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
|
12868
|
-
}
|
12869
|
-
async function exportKey(pair) {
|
12870
|
-
if (pair.privateKey == null || pair.publicKey == null) {
|
12871
|
-
throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
|
12872
|
-
}
|
12873
|
-
return Promise.all([
|
12874
|
-
webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
|
12875
|
-
webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
|
12876
|
-
]);
|
12877
|
-
}
|
12878
|
-
async function derivePublicFromPrivate(jwKey) {
|
12879
|
-
return webcrypto.get().subtle.importKey('jwk', {
|
12880
|
-
kty: jwKey.kty,
|
12881
|
-
n: jwKey.n,
|
12882
|
-
e: jwKey.e
|
12883
|
-
}, {
|
12884
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12885
|
-
hash: { name: 'SHA-256' }
|
12886
|
-
}, true, ['verify']);
|
12887
|
-
}
|
12888
|
-
function keySize(jwk) {
|
12889
|
-
if (jwk.kty !== 'RSA') {
|
12890
|
-
throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
|
12891
|
-
}
|
12892
|
-
else if (jwk.n == null) {
|
12893
|
-
throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
|
12618
|
+
/**
|
12619
|
+
* Turn PKIX bytes to a PublicKey
|
12620
|
+
*/
|
12621
|
+
function pkixToRSAPublicKey(bytes) {
|
12622
|
+
const jwk = pkixToJwk(bytes);
|
12623
|
+
if (rsaKeySize(jwk) > MAX_RSA_KEY_SIZE) {
|
12624
|
+
throw new InvalidPublicKeyError('Key size is too large');
|
12894
12625
|
}
|
12895
|
-
const
|
12896
|
-
|
12626
|
+
const hash = sha256$1(PublicKey.encode({
|
12627
|
+
Type: KeyType.RSA,
|
12628
|
+
Data: bytes
|
12629
|
+
}));
|
12630
|
+
const digest = create(SHA2_256_CODE, hash);
|
12631
|
+
return new RSAPublicKey(jwk, digest);
|
12897
12632
|
}
|
12898
12633
|
|
12899
|
-
|
12900
|
-
|
12901
|
-
|
12902
|
-
|
12903
|
-
|
12904
|
-
|
12905
|
-
|
12906
|
-
|
12907
|
-
|
12908
|
-
|
12909
|
-
|
12910
|
-
|
12911
|
-
|
12912
|
-
|
12913
|
-
|
12914
|
-
|
12915
|
-
|
12916
|
-
|
12917
|
-
|
12918
|
-
|
12919
|
-
|
12920
|
-
|
12921
|
-
|
12922
|
-
|
12923
|
-
|
12924
|
-
|
12925
|
-
|
12926
|
-
|
12927
|
-
|
12928
|
-
|
12929
|
-
_key;
|
12930
|
-
_publicKey;
|
12931
|
-
constructor(key, publicKey) {
|
12932
|
-
this._key = key;
|
12933
|
-
this._publicKey = publicKey;
|
12934
|
-
}
|
12935
|
-
genSecret() {
|
12936
|
-
return randomBytes(16);
|
12937
|
-
}
|
12938
|
-
sign(message) {
|
12939
|
-
return hashAndSign$1(this._key, message);
|
12940
|
-
}
|
12941
|
-
get public() {
|
12942
|
-
if (this._publicKey == null) {
|
12943
|
-
throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
|
12944
|
-
}
|
12945
|
-
return new RsaPublicKey(this._publicKey);
|
12946
|
-
}
|
12947
|
-
marshal() {
|
12948
|
-
return jwkToPkcs1(this._key);
|
12949
|
-
}
|
12950
|
-
get bytes() {
|
12951
|
-
return PrivateKey.encode({
|
12952
|
-
Type: KeyType.RSA,
|
12953
|
-
Data: this.marshal()
|
12954
|
-
}).subarray();
|
12955
|
-
}
|
12956
|
-
equals(key) {
|
12957
|
-
return equals(this.bytes, key.bytes);
|
12958
|
-
}
|
12959
|
-
hash() {
|
12960
|
-
const p = sha256.digest(this.bytes);
|
12961
|
-
if (isPromise$1(p)) {
|
12962
|
-
return p.then(({ bytes }) => bytes);
|
12963
|
-
}
|
12964
|
-
return p.bytes;
|
12965
|
-
}
|
12966
|
-
/**
|
12967
|
-
* Gets the ID of the key.
|
12968
|
-
*
|
12969
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
12970
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
12971
|
-
* of the PKCS SubjectPublicKeyInfo.
|
12972
|
-
*/
|
12973
|
-
async id() {
|
12974
|
-
const hash = await this.public.hash();
|
12975
|
-
return toString$6(hash, 'base58btc');
|
12634
|
+
/**
|
12635
|
+
* HMAC: RFC2104 message authentication code.
|
12636
|
+
* @module
|
12637
|
+
*/
|
12638
|
+
class HMAC extends Hash {
|
12639
|
+
constructor(hash, _key) {
|
12640
|
+
super();
|
12641
|
+
this.finished = false;
|
12642
|
+
this.destroyed = false;
|
12643
|
+
ahash(hash);
|
12644
|
+
const key = toBytes$1(_key);
|
12645
|
+
this.iHash = hash.create();
|
12646
|
+
if (typeof this.iHash.update !== 'function')
|
12647
|
+
throw new Error('Expected instance of class which extends utils.Hash');
|
12648
|
+
this.blockLen = this.iHash.blockLen;
|
12649
|
+
this.outputLen = this.iHash.outputLen;
|
12650
|
+
const blockLen = this.blockLen;
|
12651
|
+
const pad = new Uint8Array(blockLen);
|
12652
|
+
// blockLen can be bigger than outputLen
|
12653
|
+
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
12654
|
+
for (let i = 0; i < pad.length; i++)
|
12655
|
+
pad[i] ^= 0x36;
|
12656
|
+
this.iHash.update(pad);
|
12657
|
+
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
12658
|
+
this.oHash = hash.create();
|
12659
|
+
// Undo internal XOR && apply outer XOR
|
12660
|
+
for (let i = 0; i < pad.length; i++)
|
12661
|
+
pad[i] ^= 0x36 ^ 0x5c;
|
12662
|
+
this.oHash.update(pad);
|
12663
|
+
pad.fill(0);
|
12976
12664
|
}
|
12977
|
-
|
12978
|
-
|
12979
|
-
|
12980
|
-
|
12981
|
-
* To export it as a password protected PEM file, please use the `exportPEM`
|
12982
|
-
* function from `@libp2p/rsa`.
|
12983
|
-
*/
|
12984
|
-
async export(password, format = 'pkcs-8') {
|
12985
|
-
if (format === 'pkcs-8') {
|
12986
|
-
return exportToPem(this, password);
|
12987
|
-
}
|
12988
|
-
else if (format === 'libp2p-key') {
|
12989
|
-
return exporter(this.bytes, password);
|
12990
|
-
}
|
12991
|
-
else {
|
12992
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
12993
|
-
}
|
12665
|
+
update(buf) {
|
12666
|
+
aexists(this);
|
12667
|
+
this.iHash.update(buf);
|
12668
|
+
return this;
|
12994
12669
|
}
|
12995
|
-
|
12996
|
-
|
12997
|
-
|
12998
|
-
|
12999
|
-
|
12670
|
+
digestInto(out) {
|
12671
|
+
aexists(this);
|
12672
|
+
abytes$1(out, this.outputLen);
|
12673
|
+
this.finished = true;
|
12674
|
+
this.iHash.digestInto(out);
|
12675
|
+
this.oHash.update(out);
|
12676
|
+
this.oHash.digestInto(out);
|
12677
|
+
this.destroy();
|
13000
12678
|
}
|
13001
|
-
|
13002
|
-
|
13003
|
-
|
13004
|
-
|
13005
|
-
const jwk = pkixToJwk(bytes);
|
13006
|
-
if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
|
13007
|
-
throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
|
12679
|
+
digest() {
|
12680
|
+
const out = new Uint8Array(this.oHash.outputLen);
|
12681
|
+
this.digestInto(out);
|
12682
|
+
return out;
|
13008
12683
|
}
|
13009
|
-
|
13010
|
-
|
13011
|
-
|
13012
|
-
|
13013
|
-
|
12684
|
+
_cloneInto(to) {
|
12685
|
+
// Create new instance without calling constructor since key already in state and we don't know it.
|
12686
|
+
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
12687
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
12688
|
+
to = to;
|
12689
|
+
to.finished = finished;
|
12690
|
+
to.destroyed = destroyed;
|
12691
|
+
to.blockLen = blockLen;
|
12692
|
+
to.outputLen = outputLen;
|
12693
|
+
to.oHash = oHash._cloneInto(to.oHash);
|
12694
|
+
to.iHash = iHash._cloneInto(to.iHash);
|
12695
|
+
return to;
|
13014
12696
|
}
|
13015
|
-
|
13016
|
-
|
13017
|
-
|
13018
|
-
|
13019
|
-
if (bits > MAX_RSA_KEY_SIZE) {
|
13020
|
-
throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
|
12697
|
+
destroy() {
|
12698
|
+
this.destroyed = true;
|
12699
|
+
this.oHash.destroy();
|
12700
|
+
this.iHash.destroy();
|
13021
12701
|
}
|
13022
|
-
const keys = await generateKey$1(bits);
|
13023
|
-
return new RsaPrivateKey(keys.privateKey, keys.publicKey);
|
13024
12702
|
}
|
12703
|
+
/**
|
12704
|
+
* HMAC: RFC2104 message authentication code.
|
12705
|
+
* @param hash - function that would be used e.g. sha256
|
12706
|
+
* @param key - message key
|
12707
|
+
* @param message - message data
|
12708
|
+
* @example
|
12709
|
+
* import { hmac } from '@noble/hashes/hmac';
|
12710
|
+
* import { sha256 } from '@noble/hashes/sha2';
|
12711
|
+
* const mac1 = hmac(sha256, 'key', 'message');
|
12712
|
+
*/
|
12713
|
+
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
12714
|
+
hmac.create = (hash, key) => new HMAC(hash, key);
|
13025
12715
|
|
13026
|
-
|
13027
|
-
|
13028
|
-
|
13029
|
-
|
13030
|
-
|
13031
|
-
|
13032
|
-
|
13033
|
-
|
13034
|
-
|
13035
|
-
|
13036
|
-
|
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
|
+
*/
|
13037
12742
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13038
|
-
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
13039
12743
|
function validateSigVerOpts(opts) {
|
13040
12744
|
if (opts.lowS !== undefined)
|
13041
12745
|
abool('lowS', opts.lowS);
|
@@ -13059,73 +12763,132 @@ function validatePointOpts(curve) {
|
|
13059
12763
|
const { endo, Fp, a } = opts;
|
13060
12764
|
if (endo) {
|
13061
12765
|
if (!Fp.eql(a, Fp.ZERO)) {
|
13062
|
-
throw new Error('
|
12766
|
+
throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
|
13063
12767
|
}
|
13064
12768
|
if (typeof endo !== 'object' ||
|
13065
12769
|
typeof endo.beta !== 'bigint' ||
|
13066
12770
|
typeof endo.splitScalar !== 'function') {
|
13067
|
-
throw new Error('
|
12771
|
+
throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
|
13068
12772
|
}
|
13069
12773
|
}
|
13070
12774
|
return Object.freeze({ ...opts });
|
13071
12775
|
}
|
13072
|
-
// ASN.1 DER encoding utilities
|
13073
12776
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
12777
|
+
class DERErr extends Error {
|
12778
|
+
constructor(m = '') {
|
12779
|
+
super(m);
|
12780
|
+
}
|
12781
|
+
}
|
12782
|
+
/**
|
12783
|
+
* ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
|
12784
|
+
*
|
12785
|
+
* [0x30 (SEQUENCE), bytelength, 0x02 (INTEGER), intLength, R, 0x02 (INTEGER), intLength, S]
|
12786
|
+
*
|
12787
|
+
* Docs: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/, https://luca.ntop.org/Teaching/Appunti/asn1.html
|
12788
|
+
*/
|
13074
12789
|
const DER = {
|
13075
12790
|
// asn.1 DER encoding utils
|
13076
|
-
Err:
|
13077
|
-
|
13078
|
-
|
13079
|
-
|
12791
|
+
Err: DERErr,
|
12792
|
+
// Basic building block is TLV (Tag-Length-Value)
|
12793
|
+
_tlv: {
|
12794
|
+
encode: (tag, data) => {
|
12795
|
+
const { Err: E } = DER;
|
12796
|
+
if (tag < 0 || tag > 256)
|
12797
|
+
throw new E('tlv.encode: wrong tag');
|
12798
|
+
if (data.length & 1)
|
12799
|
+
throw new E('tlv.encode: unpadded data');
|
12800
|
+
const dataLen = data.length / 2;
|
12801
|
+
const len = numberToHexUnpadded(dataLen);
|
12802
|
+
if ((len.length / 2) & 128)
|
12803
|
+
throw new E('tlv.encode: long form length too big');
|
12804
|
+
// length of length with long form flag
|
12805
|
+
const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
|
12806
|
+
const t = numberToHexUnpadded(tag);
|
12807
|
+
return t + lenLen + len + data;
|
12808
|
+
},
|
12809
|
+
// v - value, l - left bytes (unparsed)
|
12810
|
+
decode(tag, data) {
|
12811
|
+
const { Err: E } = DER;
|
12812
|
+
let pos = 0;
|
12813
|
+
if (tag < 0 || tag > 256)
|
12814
|
+
throw new E('tlv.encode: wrong tag');
|
12815
|
+
if (data.length < 2 || data[pos++] !== tag)
|
12816
|
+
throw new E('tlv.decode: wrong tlv');
|
12817
|
+
const first = data[pos++];
|
12818
|
+
const isLong = !!(first & 128); // First bit of first length byte is flag for short/long form
|
12819
|
+
let length = 0;
|
12820
|
+
if (!isLong)
|
12821
|
+
length = first;
|
12822
|
+
else {
|
12823
|
+
// Long form: [longFlag(1bit), lengthLength(7bit), length (BE)]
|
12824
|
+
const lenLen = first & 127;
|
12825
|
+
if (!lenLen)
|
12826
|
+
throw new E('tlv.decode(long): indefinite length not supported');
|
12827
|
+
if (lenLen > 4)
|
12828
|
+
throw new E('tlv.decode(long): byte length is too big'); // this will overflow u32 in js
|
12829
|
+
const lengthBytes = data.subarray(pos, pos + lenLen);
|
12830
|
+
if (lengthBytes.length !== lenLen)
|
12831
|
+
throw new E('tlv.decode: length bytes not complete');
|
12832
|
+
if (lengthBytes[0] === 0)
|
12833
|
+
throw new E('tlv.decode(long): zero leftmost byte');
|
12834
|
+
for (const b of lengthBytes)
|
12835
|
+
length = (length << 8) | b;
|
12836
|
+
pos += lenLen;
|
12837
|
+
if (length < 128)
|
12838
|
+
throw new E('tlv.decode(long): not minimal encoding');
|
12839
|
+
}
|
12840
|
+
const v = data.subarray(pos, pos + length);
|
12841
|
+
if (v.length !== length)
|
12842
|
+
throw new E('tlv.decode: wrong value length');
|
12843
|
+
return { v, l: data.subarray(pos + length) };
|
12844
|
+
},
|
13080
12845
|
},
|
13081
|
-
|
13082
|
-
|
13083
|
-
|
13084
|
-
|
13085
|
-
|
13086
|
-
|
13087
|
-
|
13088
|
-
|
13089
|
-
|
13090
|
-
|
13091
|
-
|
13092
|
-
|
13093
|
-
|
13094
|
-
|
13095
|
-
|
13096
|
-
|
13097
|
-
|
12846
|
+
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
12847
|
+
// since we always use positive integers here. It must always be empty:
|
12848
|
+
// - add zero byte if exists
|
12849
|
+
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
12850
|
+
_int: {
|
12851
|
+
encode(num) {
|
12852
|
+
const { Err: E } = DER;
|
12853
|
+
if (num < _0n)
|
12854
|
+
throw new E('integer: negative integers are not allowed');
|
12855
|
+
let hex = numberToHexUnpadded(num);
|
12856
|
+
// Pad with zero byte if negative flag is present
|
12857
|
+
if (Number.parseInt(hex[0], 16) & 0b1000)
|
12858
|
+
hex = '00' + hex;
|
12859
|
+
if (hex.length & 1)
|
12860
|
+
throw new E('unexpected DER parsing assertion: unpadded hex');
|
12861
|
+
return hex;
|
12862
|
+
},
|
12863
|
+
decode(data) {
|
12864
|
+
const { Err: E } = DER;
|
12865
|
+
if (data[0] & 128)
|
12866
|
+
throw new E('invalid signature integer: negative');
|
12867
|
+
if (data[0] === 0x00 && !(data[1] & 128))
|
12868
|
+
throw new E('invalid signature integer: unnecessary leading zero');
|
12869
|
+
return b2n(data);
|
12870
|
+
},
|
13098
12871
|
},
|
13099
12872
|
toSig(hex) {
|
13100
12873
|
// parse DER signature
|
13101
|
-
const { Err: E } = DER;
|
12874
|
+
const { Err: E, _int: int, _tlv: tlv } = DER;
|
13102
12875
|
const data = typeof hex === 'string' ? h2b(hex) : hex;
|
13103
12876
|
abytes(data);
|
13104
|
-
|
13105
|
-
if (
|
13106
|
-
throw new E('
|
13107
|
-
|
13108
|
-
|
13109
|
-
|
13110
|
-
|
13111
|
-
|
13112
|
-
throw new E('Invalid signature: left bytes after parsing');
|
13113
|
-
return { r, s };
|
12877
|
+
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
12878
|
+
if (seqLeftBytes.length)
|
12879
|
+
throw new E('invalid signature: left bytes after parsing');
|
12880
|
+
const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
|
12881
|
+
const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
|
12882
|
+
if (sLeftBytes.length)
|
12883
|
+
throw new E('invalid signature: left bytes after parsing');
|
12884
|
+
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
13114
12885
|
},
|
13115
12886
|
hexFromSig(sig) {
|
13116
|
-
|
13117
|
-
const
|
13118
|
-
const
|
13119
|
-
|
13120
|
-
|
13121
|
-
};
|
13122
|
-
const s = slice(h(sig.s));
|
13123
|
-
const r = slice(h(sig.r));
|
13124
|
-
const shl = s.length / 2;
|
13125
|
-
const rhl = r.length / 2;
|
13126
|
-
const sl = h(shl);
|
13127
|
-
const rl = h(rhl);
|
13128
|
-
return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
|
12887
|
+
const { _tlv: tlv, _int: int } = DER;
|
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;
|
12891
|
+
return tlv.encode(0x30, seq);
|
13129
12892
|
},
|
13130
12893
|
};
|
13131
12894
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
@@ -13134,6 +12897,7 @@ const _0n = BigInt(0), _1n$1 = BigInt(1); BigInt(2); const _3n = BigInt(3); BigI
|
|
13134
12897
|
function weierstrassPoints(opts) {
|
13135
12898
|
const CURVE = validatePointOpts(opts);
|
13136
12899
|
const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
|
12900
|
+
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
13137
12901
|
const toBytes = CURVE.toBytes ||
|
13138
12902
|
((_c, point, _isCompressed) => {
|
13139
12903
|
const a = point.toAffine();
|
@@ -13177,7 +12941,7 @@ function weierstrassPoints(opts) {
|
|
13177
12941
|
key = bytesToHex(key);
|
13178
12942
|
// Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
|
13179
12943
|
if (typeof key !== 'string' || !lengths.includes(key.length))
|
13180
|
-
throw new Error('
|
12944
|
+
throw new Error('invalid private key');
|
13181
12945
|
key = key.padStart(nByteLength * 2, '0');
|
13182
12946
|
}
|
13183
12947
|
let num;
|
@@ -13188,7 +12952,7 @@ function weierstrassPoints(opts) {
|
|
13188
12952
|
: bytesToNumberBE(ensureBytes('private key', key, nByteLength));
|
13189
12953
|
}
|
13190
12954
|
catch (error) {
|
13191
|
-
throw new Error(
|
12955
|
+
throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
|
13192
12956
|
}
|
13193
12957
|
if (wrapPrivateKey)
|
13194
12958
|
num = mod(num, N); // disabled by default, enabled for BLS
|
@@ -13228,7 +12992,7 @@ function weierstrassPoints(opts) {
|
|
13228
12992
|
if (p.is0()) {
|
13229
12993
|
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13230
12994
|
// In BLS, ZERO can be serialized, so we allow it.
|
13231
|
-
// (0, 0, 0) is
|
12995
|
+
// (0, 0, 0) is invalid representation of ZERO.
|
13232
12996
|
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
13233
12997
|
return;
|
13234
12998
|
throw new Error('bad point: ZERO');
|
@@ -13307,6 +13071,10 @@ function weierstrassPoints(opts) {
|
|
13307
13071
|
static fromPrivateKey(privateKey) {
|
13308
13072
|
return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
|
13309
13073
|
}
|
13074
|
+
// Multiscalar Multiplication
|
13075
|
+
static msm(points, scalars) {
|
13076
|
+
return pippenger(Point, Fn, points, scalars);
|
13077
|
+
}
|
13310
13078
|
// "Private method", don't use it directly
|
13311
13079
|
_setWindowSize(windowSize) {
|
13312
13080
|
wnaf.setWindowSize(this, windowSize);
|
@@ -13448,16 +13216,17 @@ function weierstrassPoints(opts) {
|
|
13448
13216
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
13449
13217
|
*/
|
13450
13218
|
multiplyUnsafe(sc) {
|
13451
|
-
|
13219
|
+
const { endo, n: N } = CURVE;
|
13220
|
+
aInRange('scalar', sc, _0n, N);
|
13452
13221
|
const I = Point.ZERO;
|
13453
13222
|
if (sc === _0n)
|
13454
13223
|
return I;
|
13455
|
-
if (sc === _1n$1)
|
13224
|
+
if (this.is0() || sc === _1n$1)
|
13456
13225
|
return this;
|
13457
|
-
|
13458
|
-
if (!endo)
|
13459
|
-
return wnaf.
|
13460
|
-
//
|
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
|
13461
13230
|
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
13462
13231
|
let k1p = I;
|
13463
13232
|
let k2p = I;
|
@@ -13643,7 +13412,9 @@ function weierstrass(curveDef) {
|
|
13643
13412
|
return { x, y };
|
13644
13413
|
}
|
13645
13414
|
else {
|
13646
|
-
|
13415
|
+
const cl = compressedLen;
|
13416
|
+
const ul = uncompressedLen;
|
13417
|
+
throw new Error('invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len);
|
13647
13418
|
}
|
13648
13419
|
},
|
13649
13420
|
});
|
@@ -13808,6 +13579,9 @@ function weierstrass(curveDef) {
|
|
13808
13579
|
// int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
|
13809
13580
|
const bits2int = CURVE.bits2int ||
|
13810
13581
|
function (bytes) {
|
13582
|
+
// Our custom check "just in case"
|
13583
|
+
if (bytes.length > 8192)
|
13584
|
+
throw new Error('input is too large');
|
13811
13585
|
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
13812
13586
|
// for some cases, since bytes.length * 8 is not actual bitLength.
|
13813
13587
|
const num = bytesToNumberBE(bytes); // check for == u8 done here
|
@@ -13824,15 +13598,15 @@ function weierstrass(curveDef) {
|
|
13824
13598
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13825
13599
|
*/
|
13826
13600
|
function int2octets(num) {
|
13827
|
-
aInRange(
|
13601
|
+
aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
|
13828
13602
|
// works with order, can have different size than numToField!
|
13829
13603
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13830
13604
|
}
|
13831
13605
|
// Steps A, D of RFC6979 3.2
|
13832
13606
|
// Creates RFC6979 seed; converts msg/privKey to numbers.
|
13833
13607
|
// Used only in sign, not in verify.
|
13834
|
-
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
|
13835
|
-
// 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
|
13836
13610
|
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
13837
13611
|
if (['recovered', 'canonical'].some((k) => k in opts))
|
13838
13612
|
throw new Error('sign() legacy options not supported');
|
@@ -13926,39 +13700,48 @@ function weierstrass(curveDef) {
|
|
13926
13700
|
const sg = signature;
|
13927
13701
|
msgHash = ensureBytes('msgHash', msgHash);
|
13928
13702
|
publicKey = ensureBytes('publicKey', publicKey);
|
13703
|
+
const { lowS, prehash, format } = opts;
|
13704
|
+
// Verify opts, deduce signature format
|
13705
|
+
validateSigVerOpts(opts);
|
13929
13706
|
if ('strict' in opts)
|
13930
13707
|
throw new Error('options.strict was renamed to lowS');
|
13931
|
-
|
13932
|
-
|
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');
|
13933
13719
|
let _sig = undefined;
|
13934
13720
|
let P;
|
13935
13721
|
try {
|
13936
|
-
if (
|
13722
|
+
if (isObj)
|
13723
|
+
_sig = new Signature(sg.r, sg.s);
|
13724
|
+
if (isHex) {
|
13937
13725
|
// Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
|
13938
13726
|
// Since DER can also be 2*nByteLength bytes, we check for it first.
|
13939
13727
|
try {
|
13940
|
-
|
13728
|
+
if (format !== 'compact')
|
13729
|
+
_sig = Signature.fromDER(sg);
|
13941
13730
|
}
|
13942
13731
|
catch (derError) {
|
13943
13732
|
if (!(derError instanceof DER.Err))
|
13944
13733
|
throw derError;
|
13945
|
-
_sig = Signature.fromCompact(sg);
|
13946
13734
|
}
|
13947
|
-
|
13948
|
-
|
13949
|
-
const { r, s } = sg;
|
13950
|
-
_sig = new Signature(r, s);
|
13951
|
-
}
|
13952
|
-
else {
|
13953
|
-
throw new Error('PARSE');
|
13735
|
+
if (!_sig && format !== 'der')
|
13736
|
+
_sig = Signature.fromCompact(sg);
|
13954
13737
|
}
|
13955
13738
|
P = Point.fromHex(publicKey);
|
13956
13739
|
}
|
13957
13740
|
catch (error) {
|
13958
|
-
if (error.message === 'PARSE')
|
13959
|
-
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
13960
13741
|
return false;
|
13961
13742
|
}
|
13743
|
+
if (!_sig)
|
13744
|
+
return false;
|
13962
13745
|
if (lowS && _sig.hasHighS())
|
13963
13746
|
return false;
|
13964
13747
|
if (prehash)
|
@@ -13986,20 +13769,36 @@ function weierstrass(curveDef) {
|
|
13986
13769
|
};
|
13987
13770
|
}
|
13988
13771
|
|
13772
|
+
/**
|
13773
|
+
* Utilities for short weierstrass curves, combined with noble-hashes.
|
13774
|
+
* @module
|
13775
|
+
*/
|
13989
13776
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13990
|
-
|
13777
|
+
/** connects noble-curves to noble-hashes */
|
13991
13778
|
function getHash(hash) {
|
13992
13779
|
return {
|
13993
13780
|
hash,
|
13994
13781
|
hmac: (key, ...msgs) => hmac(hash, key, concatBytes$2(...msgs)),
|
13995
|
-
randomBytes
|
13782
|
+
randomBytes,
|
13996
13783
|
};
|
13997
13784
|
}
|
13998
13785
|
function createCurve(curveDef, defHash) {
|
13999
13786
|
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
14000
|
-
return
|
13787
|
+
return { ...create(defHash), create };
|
14001
13788
|
}
|
14002
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
|
+
*/
|
14003
13802
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
14004
13803
|
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
14005
13804
|
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
@@ -14030,31 +13829,35 @@ function sqrtMod(y) {
|
|
14030
13829
|
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
14031
13830
|
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
14032
13831
|
const root = pow2(t2, _2n, P);
|
14033
|
-
if (!
|
13832
|
+
if (!Fpk1.eql(Fpk1.sqr(root), y))
|
14034
13833
|
throw new Error('Cannot find square root');
|
14035
13834
|
return root;
|
14036
13835
|
}
|
14037
|
-
const
|
13836
|
+
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
14038
13837
|
/**
|
14039
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;
|
14040
13848
|
*/
|
14041
13849
|
const secp256k1 = createCurve({
|
14042
13850
|
a: BigInt(0), // equation params: a, b
|
14043
|
-
b: BigInt(7),
|
14044
|
-
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
|
14045
13853
|
n: secp256k1N, // Curve order, total count of valid points in the field
|
14046
13854
|
// Base point (x, y) aka generator point
|
14047
13855
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
14048
13856
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
14049
13857
|
h: BigInt(1), // Cofactor
|
14050
13858
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
14051
|
-
/**
|
14052
|
-
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
14053
|
-
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
14054
|
-
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
14055
|
-
* Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
14056
|
-
*/
|
14057
13859
|
endo: {
|
13860
|
+
// Endomorphism, see above
|
14058
13861
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
14059
13862
|
splitScalar: (k) => {
|
14060
13863
|
const n = secp256k1N;
|
@@ -14085,27 +13888,15 @@ const secp256k1 = createCurve({
|
|
14085
13888
|
BigInt(0);
|
14086
13889
|
secp256k1.ProjectivePoint;
|
14087
13890
|
|
14088
|
-
function
|
14089
|
-
|
14090
|
-
|
14091
|
-
/**
|
14092
|
-
* Hash and sign message with private key
|
14093
|
-
*/
|
14094
|
-
function hashAndSign(key, msg) {
|
14095
|
-
const p = sha256.digest(msg instanceof Uint8Array ? msg : msg.subarray());
|
14096
|
-
if (isPromise$1(p)) {
|
14097
|
-
return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
|
14098
|
-
.catch(err => {
|
14099
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
14100
|
-
});
|
14101
|
-
}
|
14102
|
-
try {
|
14103
|
-
return secp256k1.sign(p.digest, key).toDERRawBytes();
|
14104
|
-
}
|
14105
|
-
catch (err) {
|
14106
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
13891
|
+
function isPromise$1(thing) {
|
13892
|
+
if (thing == null) {
|
13893
|
+
return false;
|
14107
13894
|
}
|
13895
|
+
return typeof thing.then === 'function' &&
|
13896
|
+
typeof thing.catch === 'function' &&
|
13897
|
+
typeof thing.finally === 'function';
|
14108
13898
|
}
|
13899
|
+
|
14109
13900
|
/**
|
14110
13901
|
* Hash message and verify signature with public key
|
14111
13902
|
*/
|
@@ -14114,231 +13905,112 @@ function hashAndVerify(key, sig, msg) {
|
|
14114
13905
|
if (isPromise$1(p)) {
|
14115
13906
|
return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
|
14116
13907
|
.catch(err => {
|
14117
|
-
throw new
|
13908
|
+
throw new VerificationError(String(err));
|
14118
13909
|
});
|
14119
13910
|
}
|
14120
13911
|
try {
|
14121
13912
|
return secp256k1.verify(sig, p.digest, key);
|
14122
13913
|
}
|
14123
13914
|
catch (err) {
|
14124
|
-
throw new
|
14125
|
-
}
|
14126
|
-
}
|
14127
|
-
function compressPublicKey(key) {
|
14128
|
-
const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
|
14129
|
-
return point;
|
14130
|
-
}
|
14131
|
-
function validatePrivateKey(key) {
|
14132
|
-
try {
|
14133
|
-
secp256k1.getPublicKey(key, true);
|
14134
|
-
}
|
14135
|
-
catch (err) {
|
14136
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
14137
|
-
}
|
14138
|
-
}
|
14139
|
-
function validatePublicKey(key) {
|
14140
|
-
try {
|
14141
|
-
secp256k1.ProjectivePoint.fromHex(key);
|
14142
|
-
}
|
14143
|
-
catch (err) {
|
14144
|
-
throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
|
14145
|
-
}
|
14146
|
-
}
|
14147
|
-
function computePublicKey(privateKey) {
|
14148
|
-
try {
|
14149
|
-
return secp256k1.getPublicKey(privateKey, true);
|
14150
|
-
}
|
14151
|
-
catch (err) {
|
14152
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
13915
|
+
throw new VerificationError(String(err));
|
14153
13916
|
}
|
14154
13917
|
}
|
14155
13918
|
|
14156
13919
|
class Secp256k1PublicKey {
|
13920
|
+
type = 'secp256k1';
|
13921
|
+
raw;
|
14157
13922
|
_key;
|
14158
13923
|
constructor(key) {
|
14159
|
-
|
14160
|
-
this.
|
14161
|
-
}
|
14162
|
-
verify(data, sig) {
|
14163
|
-
return hashAndVerify(this._key, sig, data);
|
14164
|
-
}
|
14165
|
-
marshal() {
|
14166
|
-
return compressPublicKey(this._key);
|
13924
|
+
this._key = validateSecp256k1PublicKey(key);
|
13925
|
+
this.raw = compressSecp256k1PublicKey(this._key);
|
14167
13926
|
}
|
14168
|
-
|
14169
|
-
return
|
14170
|
-
Type: KeyType.Secp256k1,
|
14171
|
-
Data: this.marshal()
|
14172
|
-
}).subarray();
|
13927
|
+
toMultihash() {
|
13928
|
+
return identity.digest(publicKeyToProtobuf(this));
|
14173
13929
|
}
|
14174
|
-
|
14175
|
-
return
|
14176
|
-
}
|
14177
|
-
async hash() {
|
14178
|
-
const p = sha256.digest(this.bytes);
|
14179
|
-
let bytes;
|
14180
|
-
if (isPromise$1(p)) {
|
14181
|
-
({ bytes } = await p);
|
14182
|
-
}
|
14183
|
-
else {
|
14184
|
-
bytes = p.bytes;
|
14185
|
-
}
|
14186
|
-
return bytes;
|
14187
|
-
}
|
14188
|
-
}
|
14189
|
-
class Secp256k1PrivateKey {
|
14190
|
-
_key;
|
14191
|
-
_publicKey;
|
14192
|
-
constructor(key, publicKey) {
|
14193
|
-
this._key = key;
|
14194
|
-
this._publicKey = publicKey ?? computePublicKey(key);
|
14195
|
-
validatePrivateKey(this._key);
|
14196
|
-
validatePublicKey(this._publicKey);
|
14197
|
-
}
|
14198
|
-
sign(message) {
|
14199
|
-
return hashAndSign(this._key, message);
|
14200
|
-
}
|
14201
|
-
get public() {
|
14202
|
-
return new Secp256k1PublicKey(this._publicKey);
|
14203
|
-
}
|
14204
|
-
marshal() {
|
14205
|
-
return this._key;
|
13930
|
+
toCID() {
|
13931
|
+
return CID.createV1(114, this.toMultihash());
|
14206
13932
|
}
|
14207
|
-
|
14208
|
-
return
|
14209
|
-
Type: KeyType.Secp256k1,
|
14210
|
-
Data: this.marshal()
|
14211
|
-
}).subarray();
|
13933
|
+
toString() {
|
13934
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
14212
13935
|
}
|
14213
13936
|
equals(key) {
|
14214
|
-
|
14215
|
-
|
14216
|
-
hash() {
|
14217
|
-
const p = sha256.digest(this.bytes);
|
14218
|
-
if (isPromise$1(p)) {
|
14219
|
-
return p.then(({ bytes }) => bytes);
|
13937
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
13938
|
+
return false;
|
14220
13939
|
}
|
14221
|
-
return
|
14222
|
-
}
|
14223
|
-
/**
|
14224
|
-
* Gets the ID of the key.
|
14225
|
-
*
|
14226
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
14227
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
14228
|
-
* of the PKCS SubjectPublicKeyInfo.
|
14229
|
-
*/
|
14230
|
-
async id() {
|
14231
|
-
const hash = await this.public.hash();
|
14232
|
-
return toString$6(hash, 'base58btc');
|
13940
|
+
return equals(this.raw, key.raw);
|
14233
13941
|
}
|
14234
|
-
|
14235
|
-
|
14236
|
-
*/
|
14237
|
-
async export(password, format = 'libp2p-key') {
|
14238
|
-
if (format === 'libp2p-key') {
|
14239
|
-
return exporter(this.bytes, password);
|
14240
|
-
}
|
14241
|
-
else {
|
14242
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
14243
|
-
}
|
13942
|
+
verify(data, sig) {
|
13943
|
+
return hashAndVerify(this._key, sig, data);
|
14244
13944
|
}
|
14245
13945
|
}
|
14246
|
-
|
14247
|
-
return new Secp256k1PrivateKey(bytes);
|
14248
|
-
}
|
13946
|
+
|
14249
13947
|
function unmarshalSecp256k1PublicKey(bytes) {
|
14250
13948
|
return new Secp256k1PublicKey(bytes);
|
14251
13949
|
}
|
14252
|
-
|
14253
|
-
const
|
14254
|
-
return
|
13950
|
+
function compressSecp256k1PublicKey(key) {
|
13951
|
+
const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
|
13952
|
+
return point;
|
13953
|
+
}
|
13954
|
+
function validateSecp256k1PublicKey(key) {
|
13955
|
+
try {
|
13956
|
+
secp256k1.ProjectivePoint.fromHex(key);
|
13957
|
+
return key;
|
13958
|
+
}
|
13959
|
+
catch (err) {
|
13960
|
+
throw new InvalidPublicKeyError(String(err));
|
13961
|
+
}
|
14255
13962
|
}
|
14256
13963
|
|
14257
|
-
var Secp256k1 = /*#__PURE__*/Object.freeze({
|
14258
|
-
__proto__: null,
|
14259
|
-
Secp256k1PrivateKey: Secp256k1PrivateKey,
|
14260
|
-
Secp256k1PublicKey: Secp256k1PublicKey,
|
14261
|
-
generateKeyPair: generateKeyPair,
|
14262
|
-
unmarshalSecp256k1PrivateKey: unmarshalSecp256k1PrivateKey,
|
14263
|
-
unmarshalSecp256k1PublicKey: unmarshalSecp256k1PublicKey
|
14264
|
-
});
|
14265
|
-
|
14266
13964
|
/**
|
14267
13965
|
* @packageDocumentation
|
14268
13966
|
*
|
14269
|
-
*
|
14270
|
-
*
|
14271
|
-
* The {@link generateKeyPair}, {@link marshalPublicKey}, and {@link marshalPrivateKey} functions accept a string `type` argument.
|
13967
|
+
* ## Supported Key Types
|
14272
13968
|
*
|
14273
13969
|
* Currently the `'RSA'`, `'ed25519'`, and `secp256k1` types are supported, although ed25519 and secp256k1 keys support only signing and verification of messages.
|
14274
13970
|
*
|
14275
13971
|
* For encryption / decryption support, RSA keys should be used.
|
14276
13972
|
*/
|
14277
|
-
const supportedKeys = {
|
14278
|
-
rsa: RSA,
|
14279
|
-
ed25519: Ed25519,
|
14280
|
-
secp256k1: Secp256k1
|
14281
|
-
};
|
14282
|
-
function unsupportedKey(type) {
|
14283
|
-
const supported = Object.keys(supportedKeys).join(' / ');
|
14284
|
-
return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
|
14285
|
-
}
|
14286
|
-
function typeToKey(type) {
|
14287
|
-
type = type.toLowerCase();
|
14288
|
-
if (type === 'rsa' || type === 'ed25519' || type === 'secp256k1') {
|
14289
|
-
return supportedKeys[type];
|
14290
|
-
}
|
14291
|
-
throw unsupportedKey(type);
|
14292
|
-
}
|
14293
13973
|
/**
|
14294
|
-
*
|
13974
|
+
* Creates a public key from the raw key bytes
|
14295
13975
|
*/
|
14296
|
-
function
|
14297
|
-
|
14298
|
-
|
14299
|
-
|
14300
|
-
|
14301
|
-
|
14302
|
-
|
14303
|
-
|
14304
|
-
|
14305
|
-
return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data);
|
14306
|
-
default:
|
14307
|
-
throw unsupportedKey(decoded.Type ?? 'unknown');
|
13976
|
+
function publicKeyFromRaw(buf) {
|
13977
|
+
if (buf.byteLength === 32) {
|
13978
|
+
return unmarshalEd25519PublicKey(buf);
|
13979
|
+
}
|
13980
|
+
else if (buf.byteLength === 33) {
|
13981
|
+
return unmarshalSecp256k1PublicKey(buf);
|
13982
|
+
}
|
13983
|
+
else {
|
13984
|
+
return pkixToRSAPublicKey(buf);
|
14308
13985
|
}
|
14309
13986
|
}
|
14310
13987
|
/**
|
14311
|
-
*
|
14312
|
-
|
14313
|
-
|
14314
|
-
|
14315
|
-
|
14316
|
-
return key.bytes;
|
14317
|
-
}
|
14318
|
-
/**
|
14319
|
-
* Converts a protobuf serialized private key into its representative object
|
13988
|
+
* Creates a public key from an identity multihash which contains a protobuf
|
13989
|
+
* encoded Ed25519 or secp256k1 public key.
|
13990
|
+
*
|
13991
|
+
* RSA keys are not supported as in practice we they are not stored in identity
|
13992
|
+
* multihashes since the hash would be very large.
|
14320
13993
|
*/
|
14321
|
-
|
14322
|
-
const
|
14323
|
-
const data =
|
14324
|
-
switch (
|
14325
|
-
case KeyType.RSA:
|
14326
|
-
return supportedKeys.rsa.unmarshalRsaPrivateKey(data);
|
13994
|
+
function publicKeyFromMultihash(digest) {
|
13995
|
+
const { Type, Data } = PublicKey.decode(digest.digest);
|
13996
|
+
const data = Data ?? new Uint8Array();
|
13997
|
+
switch (Type) {
|
14327
13998
|
case KeyType.Ed25519:
|
14328
|
-
return
|
14329
|
-
case KeyType.
|
14330
|
-
return
|
13999
|
+
return unmarshalEd25519PublicKey(data);
|
14000
|
+
case KeyType.secp256k1:
|
14001
|
+
return unmarshalSecp256k1PublicKey(data);
|
14331
14002
|
default:
|
14332
|
-
throw
|
14003
|
+
throw new UnsupportedKeyTypeError();
|
14333
14004
|
}
|
14334
14005
|
}
|
14335
14006
|
/**
|
14336
|
-
* Converts a
|
14007
|
+
* Converts a public key object into a protobuf serialized public key
|
14337
14008
|
*/
|
14338
|
-
function
|
14339
|
-
|
14340
|
-
|
14341
|
-
|
14009
|
+
function publicKeyToProtobuf(key) {
|
14010
|
+
return PublicKey.encode({
|
14011
|
+
Type: KeyType[key.type],
|
14012
|
+
Data: key.raw
|
14013
|
+
});
|
14342
14014
|
}
|
14343
14015
|
|
14344
14016
|
/**
|
@@ -14356,26 +14028,17 @@ function marshalPrivateKey(key, type) {
|
|
14356
14028
|
* console.log(peer.toString()) // "12D3K..."
|
14357
14029
|
* ```
|
14358
14030
|
*/
|
14359
|
-
const inspect = Symbol.for('nodejs.util.inspect.custom');
|
14360
|
-
const baseDecoder = Object
|
14361
|
-
.values(bases)
|
14362
|
-
.map(codec => codec.decoder)
|
14363
|
-
// @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
|
14364
|
-
.reduce((acc, curr) => acc.or(curr), bases.identity.decoder);
|
14031
|
+
const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
|
14365
14032
|
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14366
|
-
const LIBP2P_KEY_CODE = 0x72;
|
14367
|
-
|
14368
|
-
const MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH = 37;
|
14369
|
-
class PeerIdImpl {
|
14033
|
+
const LIBP2P_KEY_CODE$1 = 0x72;
|
14034
|
+
let PeerIdImpl$1 = class PeerIdImpl {
|
14370
14035
|
type;
|
14371
14036
|
multihash;
|
14372
|
-
privateKey;
|
14373
14037
|
publicKey;
|
14374
14038
|
string;
|
14375
14039
|
constructor(init) {
|
14376
14040
|
this.type = init.type;
|
14377
14041
|
this.multihash = init.multihash;
|
14378
|
-
this.privateKey = init.privateKey;
|
14379
14042
|
// mark string cache as non-enumerable
|
14380
14043
|
Object.defineProperty(this, 'string', {
|
14381
14044
|
enumerable: false,
|
@@ -14392,17 +14055,14 @@ class PeerIdImpl {
|
|
14392
14055
|
}
|
14393
14056
|
return this.string;
|
14394
14057
|
}
|
14058
|
+
toMultihash() {
|
14059
|
+
return this.multihash;
|
14060
|
+
}
|
14395
14061
|
// return self-describing String representation
|
14396
14062
|
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
14397
14063
|
toCID() {
|
14398
|
-
return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
|
14064
|
+
return CID.createV1(LIBP2P_KEY_CODE$1, this.multihash);
|
14399
14065
|
}
|
14400
|
-
toBytes() {
|
14401
|
-
return this.multihash.bytes;
|
14402
|
-
}
|
14403
|
-
/**
|
14404
|
-
* Returns Multiaddr as a JSON string
|
14405
|
-
*/
|
14406
14066
|
toJSON() {
|
14407
14067
|
return this.toString();
|
14408
14068
|
}
|
@@ -14417,10 +14077,10 @@ class PeerIdImpl {
|
|
14417
14077
|
return equals(this.multihash.bytes, id);
|
14418
14078
|
}
|
14419
14079
|
else if (typeof id === 'string') {
|
14420
|
-
return
|
14080
|
+
return this.toString() === id;
|
14421
14081
|
}
|
14422
|
-
else if (id?.
|
14423
|
-
return equals(this.multihash.bytes, id.
|
14082
|
+
else if (id?.toMultihash()?.bytes != null) {
|
14083
|
+
return equals(this.multihash.bytes, id.toMultihash().bytes);
|
14424
14084
|
}
|
14425
14085
|
else {
|
14426
14086
|
throw new Error('not valid Id');
|
@@ -14438,145 +14098,79 @@ class PeerIdImpl {
|
|
14438
14098
|
* // 'PeerId(QmFoo)'
|
14439
14099
|
* ```
|
14440
14100
|
*/
|
14441
|
-
[inspect]() {
|
14101
|
+
[inspect$1]() {
|
14442
14102
|
return `PeerId(${this.toString()})`;
|
14443
14103
|
}
|
14444
|
-
}
|
14445
|
-
class
|
14104
|
+
};
|
14105
|
+
let RSAPeerId$1 = class RSAPeerId extends PeerIdImpl$1 {
|
14446
14106
|
type = 'RSA';
|
14447
14107
|
publicKey;
|
14448
14108
|
constructor(init) {
|
14449
14109
|
super({ ...init, type: 'RSA' });
|
14450
14110
|
this.publicKey = init.publicKey;
|
14451
14111
|
}
|
14452
|
-
}
|
14453
|
-
class
|
14112
|
+
};
|
14113
|
+
let Ed25519PeerId$1 = class Ed25519PeerId extends PeerIdImpl$1 {
|
14454
14114
|
type = 'Ed25519';
|
14455
14115
|
publicKey;
|
14456
14116
|
constructor(init) {
|
14457
14117
|
super({ ...init, type: 'Ed25519' });
|
14458
|
-
this.publicKey = init.
|
14118
|
+
this.publicKey = init.publicKey;
|
14459
14119
|
}
|
14460
|
-
}
|
14461
|
-
class
|
14120
|
+
};
|
14121
|
+
let Secp256k1PeerId$1 = class Secp256k1PeerId extends PeerIdImpl$1 {
|
14462
14122
|
type = 'secp256k1';
|
14463
14123
|
publicKey;
|
14464
14124
|
constructor(init) {
|
14465
14125
|
super({ ...init, type: 'secp256k1' });
|
14466
|
-
this.publicKey = init.
|
14467
|
-
}
|
14468
|
-
}
|
14469
|
-
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14470
|
-
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
14471
|
-
class URLPeerIdImpl {
|
14472
|
-
type = 'url';
|
14473
|
-
multihash;
|
14474
|
-
privateKey;
|
14475
|
-
publicKey;
|
14476
|
-
url;
|
14477
|
-
constructor(url) {
|
14478
|
-
this.url = url.toString();
|
14479
|
-
this.multihash = identity.digest(fromString(this.url));
|
14480
|
-
}
|
14481
|
-
[inspect]() {
|
14482
|
-
return `PeerId(${this.url})`;
|
14483
|
-
}
|
14484
|
-
[peerIdSymbol] = true;
|
14485
|
-
toString() {
|
14486
|
-
return this.toCID().toString();
|
14487
|
-
}
|
14488
|
-
toCID() {
|
14489
|
-
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
|
14490
|
-
}
|
14491
|
-
toBytes() {
|
14492
|
-
return this.toCID().bytes;
|
14493
|
-
}
|
14494
|
-
equals(other) {
|
14495
|
-
if (other == null) {
|
14496
|
-
return false;
|
14497
|
-
}
|
14498
|
-
if (other instanceof Uint8Array) {
|
14499
|
-
other = toString$6(other);
|
14500
|
-
}
|
14501
|
-
return other.toString() === this.toString();
|
14502
|
-
}
|
14503
|
-
}
|
14504
|
-
function peerIdFromString(str, decoder) {
|
14505
|
-
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
14506
|
-
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
14507
|
-
// rsa public key - base58btc encoded either way
|
14508
|
-
const multihash = decode$6(base58btc.decode(`z${str}`));
|
14509
|
-
if (str.startsWith('12D')) {
|
14510
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14511
|
-
}
|
14512
|
-
else if (str.startsWith('16U')) {
|
14513
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14514
|
-
}
|
14515
|
-
else {
|
14516
|
-
return new RSAPeerIdImpl({ multihash });
|
14517
|
-
}
|
14518
|
-
}
|
14519
|
-
return peerIdFromBytes(baseDecoder.decode(str));
|
14520
|
-
}
|
14521
|
-
function peerIdFromBytes(buf) {
|
14522
|
-
try {
|
14523
|
-
const multihash = decode$6(buf);
|
14524
|
-
if (multihash.code === identity.code) {
|
14525
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14526
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14527
|
-
}
|
14528
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14529
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14530
|
-
}
|
14531
|
-
}
|
14532
|
-
if (multihash.code === sha256.code) {
|
14533
|
-
return new RSAPeerIdImpl({ multihash });
|
14534
|
-
}
|
14535
|
-
}
|
14536
|
-
catch {
|
14537
|
-
return peerIdFromCID(CID.decode(buf));
|
14538
|
-
}
|
14539
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14540
|
-
}
|
14541
|
-
function peerIdFromCID(cid) {
|
14542
|
-
if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
|
14543
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14544
|
-
}
|
14545
|
-
if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
|
14546
|
-
const url = toString$6(cid.multihash.digest);
|
14547
|
-
return new URLPeerIdImpl(new URL(url));
|
14548
|
-
}
|
14549
|
-
const multihash = cid.multihash;
|
14550
|
-
if (multihash.code === sha256.code) {
|
14551
|
-
return new RSAPeerIdImpl({ multihash: cid.multihash });
|
14552
|
-
}
|
14553
|
-
else if (multihash.code === identity.code) {
|
14554
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14555
|
-
return new Ed25519PeerIdImpl({ multihash: cid.multihash });
|
14556
|
-
}
|
14557
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14558
|
-
return new Secp256k1PeerIdImpl({ multihash: cid.multihash });
|
14559
|
-
}
|
14126
|
+
this.publicKey = init.publicKey;
|
14560
14127
|
}
|
14561
|
-
|
14562
|
-
|
14128
|
+
};
|
14129
|
+
|
14563
14130
|
/**
|
14564
|
-
* @
|
14565
|
-
*
|
14131
|
+
* @packageDocumentation
|
14132
|
+
*
|
14133
|
+
* An implementation of a peer id
|
14134
|
+
*
|
14135
|
+
* @example
|
14136
|
+
*
|
14137
|
+
* ```TypeScript
|
14138
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
14139
|
+
* const peer = peerIdFromString('12D3KooWKnDdG3iXw9eTFijk3EWSunZcFi54Zka4wmtqtt6rPxc8')
|
14140
|
+
*
|
14141
|
+
* console.log(peer.toCID()) // CID(bafzaa...)
|
14142
|
+
* console.log(peer.toString()) // "12D3K..."
|
14143
|
+
* ```
|
14566
14144
|
*/
|
14567
|
-
|
14568
|
-
if (publicKey.
|
14569
|
-
return new
|
14145
|
+
function peerIdFromPublicKey(publicKey) {
|
14146
|
+
if (publicKey.type === 'Ed25519') {
|
14147
|
+
return new Ed25519PeerId$1({
|
14148
|
+
multihash: publicKey.toCID().multihash,
|
14149
|
+
publicKey
|
14150
|
+
});
|
14151
|
+
}
|
14152
|
+
else if (publicKey.type === 'secp256k1') {
|
14153
|
+
return new Secp256k1PeerId$1({
|
14154
|
+
multihash: publicKey.toCID().multihash,
|
14155
|
+
publicKey
|
14156
|
+
});
|
14570
14157
|
}
|
14571
|
-
if (publicKey.
|
14572
|
-
return new
|
14158
|
+
else if (publicKey.type === 'RSA') {
|
14159
|
+
return new RSAPeerId$1({
|
14160
|
+
multihash: publicKey.toCID().multihash,
|
14161
|
+
publicKey
|
14162
|
+
});
|
14573
14163
|
}
|
14574
|
-
|
14164
|
+
throw new UnsupportedKeyTypeError();
|
14575
14165
|
}
|
14576
14166
|
|
14167
|
+
const ERR_TYPE_NOT_IMPLEMENTED = "Keypair type not implemented";
|
14577
14168
|
function createPeerIdFromPublicKey(publicKey) {
|
14578
|
-
const
|
14579
|
-
|
14169
|
+
const pubKey = publicKeyFromRaw(publicKey);
|
14170
|
+
if (pubKey.type !== "secp256k1") {
|
14171
|
+
throw new Error(ERR_TYPE_NOT_IMPLEMENTED);
|
14172
|
+
}
|
14173
|
+
return peerIdFromPublicKey(pubKey);
|
14580
14174
|
}
|
14581
14175
|
|
14582
14176
|
function decodeMultiaddrs(bytes) {
|
@@ -14823,12 +14417,12 @@ var TransportProtocolPerIpVersion;
|
|
14823
14417
|
class ENR extends RawEnr {
|
14824
14418
|
static RECORD_PREFIX = "enr:";
|
14825
14419
|
peerId;
|
14826
|
-
static
|
14420
|
+
static create(kvs = {}, seq = BigInt(1), signature) {
|
14827
14421
|
const enr = new ENR(kvs, seq, signature);
|
14828
14422
|
try {
|
14829
14423
|
const publicKey = enr.publicKey;
|
14830
14424
|
if (publicKey) {
|
14831
|
-
enr.peerId =
|
14425
|
+
enr.peerId = createPeerIdFromPublicKey(publicKey);
|
14832
14426
|
}
|
14833
14427
|
}
|
14834
14428
|
catch (e) {
|
@@ -15593,7 +15187,7 @@ async function fromValues(values) {
|
|
15593
15187
|
}
|
15594
15188
|
}
|
15595
15189
|
const _seq = decodeSeq(seq);
|
15596
|
-
const enr =
|
15190
|
+
const enr = ENR.create(obj, _seq, signature);
|
15597
15191
|
checkSignature(seq, kvs, enr, signature);
|
15598
15192
|
return enr;
|
15599
15193
|
}
|
@@ -16277,9 +15871,9 @@ function _copyActual (source, target, targetStart, sourceStart, sourceEnd) {
|
|
16277
15871
|
const QUERY_FLAG = 0;
|
16278
15872
|
const RESPONSE_FLAG = 1 << 15;
|
16279
15873
|
const FLUSH_MASK = 1 << 15;
|
16280
|
-
const NOT_FLUSH_MASK =
|
15874
|
+
const NOT_FLUSH_MASK = -32769;
|
16281
15875
|
const QU_MASK = 1 << 15;
|
16282
|
-
const NOT_QU_MASK =
|
15876
|
+
const NOT_QU_MASK = -32769;
|
16283
15877
|
|
16284
15878
|
function codec ({ bytes = 0, encode, decode, encodingLength }) {
|
16285
15879
|
encode.bytes = bytes;
|
@@ -20664,190 +20258,128 @@ function wakuDnsDiscovery(enrUrls, wantedNodeCapabilityCount = DEFAULT_NODE_REQU
|
|
20664
20258
|
return (components) => new PeerDiscoveryDns(components, { enrUrls, wantedNodeCapabilityCount });
|
20665
20259
|
}
|
20666
20260
|
|
20667
|
-
|
20668
|
-
|
20669
|
-
|
20670
|
-
|
20671
|
-
|
20672
|
-
*/
|
20673
|
-
async function sortPeersByLatency(peerStore, peers) {
|
20674
|
-
if (peers.length === 0)
|
20675
|
-
return [];
|
20676
|
-
const results = await Promise.all(peers.map(async (peer) => {
|
20677
|
-
try {
|
20678
|
-
const pingBytes = (await peerStore.get(peer.id)).metadata.get("ping");
|
20679
|
-
if (!pingBytes)
|
20680
|
-
return { peer, ping: Infinity };
|
20681
|
-
const ping = Number(bytesToUtf8(pingBytes));
|
20682
|
-
return { peer, ping };
|
20683
|
-
}
|
20684
|
-
catch (error) {
|
20685
|
-
return { peer, ping: Infinity };
|
20686
|
-
}
|
20687
|
-
}));
|
20688
|
-
// filter out null values
|
20689
|
-
const validResults = results.filter((result) => result !== null);
|
20690
|
-
return validResults
|
20691
|
-
.sort((a, b) => a.ping - b.ping)
|
20692
|
-
.map((result) => result.peer);
|
20693
|
-
}
|
20694
|
-
/**
|
20695
|
-
* Returns the list of peers that supports the given protocol.
|
20696
|
-
*/
|
20697
|
-
async function getPeersForProtocol(peerStore, protocols) {
|
20698
|
-
const peers = [];
|
20699
|
-
await peerStore.forEach((peer) => {
|
20700
|
-
for (let i = 0; i < protocols.length; i++) {
|
20701
|
-
if (peer.protocols.includes(protocols[i])) {
|
20702
|
-
peers.push(peer);
|
20703
|
-
break;
|
20704
|
-
}
|
20705
|
-
}
|
20706
|
-
});
|
20707
|
-
return peers;
|
20708
|
-
}
|
20709
|
-
|
20710
|
-
/**
|
20711
|
-
* Retrieves a list of peers based on the specified criteria:
|
20712
|
-
* 1. If numPeers is 0, return all peers
|
20713
|
-
* 2. Bootstrap peers are prioritized
|
20714
|
-
* 3. Non-bootstrap peers are randomly selected to fill up to numPeers
|
20715
|
-
*
|
20716
|
-
* @param peers - The list of peers to filter from.
|
20717
|
-
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned, irrespective of `maxBootstrapPeers`.
|
20718
|
-
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
|
20719
|
-
* @returns An array of peers based on the specified criteria.
|
20720
|
-
*/
|
20721
|
-
function filterPeersByDiscovery(peers, numPeers, maxBootstrapPeers) {
|
20722
|
-
// Collect the bootstrap peers up to the specified maximum
|
20723
|
-
let bootstrapPeers = peers
|
20724
|
-
.filter((peer) => peer.tags.has(Tags.BOOTSTRAP))
|
20725
|
-
.slice(0, maxBootstrapPeers);
|
20726
|
-
// If numPeers is less than the number of bootstrap peers, adjust the bootstrapPeers array
|
20727
|
-
if (numPeers > 0 && numPeers < bootstrapPeers.length) {
|
20728
|
-
bootstrapPeers = bootstrapPeers.slice(0, numPeers);
|
20729
|
-
}
|
20730
|
-
// Collect non-bootstrap peers
|
20731
|
-
const nonBootstrapPeers = peers.filter((peer) => !peer.tags.has(Tags.BOOTSTRAP));
|
20732
|
-
// If numPeers is 0, return all peers
|
20733
|
-
if (numPeers === 0) {
|
20734
|
-
return [...bootstrapPeers, ...nonBootstrapPeers];
|
20735
|
-
}
|
20736
|
-
// Initialize the list of selected peers with the bootstrap peers
|
20737
|
-
const selectedPeers = [...bootstrapPeers];
|
20738
|
-
// Fill up to numPeers with remaining random peers if needed
|
20739
|
-
while (selectedPeers.length < numPeers && nonBootstrapPeers.length > 0) {
|
20740
|
-
const randomIndex = Math.floor(Math.random() * nonBootstrapPeers.length);
|
20741
|
-
const randomPeer = nonBootstrapPeers.splice(randomIndex, 1)[0];
|
20742
|
-
selectedPeers.push(randomPeer);
|
20743
|
-
}
|
20744
|
-
return selectedPeers;
|
20745
|
-
}
|
20746
|
-
|
20747
|
-
function selectConnection(connections) {
|
20748
|
-
if (!connections.length)
|
20749
|
-
return;
|
20750
|
-
if (connections.length === 1)
|
20751
|
-
return connections[0];
|
20752
|
-
let latestConnection;
|
20753
|
-
connections.forEach((connection) => {
|
20754
|
-
if (connection.status === "open") {
|
20755
|
-
if (!latestConnection) {
|
20756
|
-
latestConnection = connection;
|
20757
|
-
}
|
20758
|
-
else if (connection.timeline.open > latestConnection.timeline.open) {
|
20759
|
-
latestConnection = connection;
|
20760
|
-
}
|
20761
|
-
}
|
20762
|
-
});
|
20763
|
-
return latestConnection;
|
20261
|
+
function selectOpenConnection(connections) {
|
20262
|
+
return connections
|
20263
|
+
.filter((c) => c.status === "open")
|
20264
|
+
.sort((left, right) => right.timeline.open - left.timeline.open)
|
20265
|
+
.at(0);
|
20764
20266
|
}
|
20765
20267
|
|
20766
|
-
const
|
20767
|
-
const RETRY_BACKOFF_BASE = 1_000;
|
20768
|
-
const MAX_RETRIES = 3;
|
20268
|
+
const STREAM_LOCK_KEY = "consumed";
|
20769
20269
|
class StreamManager {
|
20770
20270
|
multicodec;
|
20771
20271
|
getConnections;
|
20772
20272
|
addEventListener;
|
20773
|
-
streamPool;
|
20774
20273
|
log;
|
20274
|
+
ongoingCreation = new Set();
|
20275
|
+
streamPool = new Map();
|
20775
20276
|
constructor(multicodec, getConnections, addEventListener) {
|
20776
20277
|
this.multicodec = multicodec;
|
20777
20278
|
this.getConnections = getConnections;
|
20778
20279
|
this.addEventListener = addEventListener;
|
20779
20280
|
this.log = new Logger$1(`stream-manager:${multicodec}`);
|
20780
|
-
this.streamPool = new Map();
|
20781
20281
|
this.addEventListener("peer:update", this.handlePeerUpdateStreamPool);
|
20782
20282
|
}
|
20783
|
-
async getStream(
|
20784
|
-
const peerIdStr =
|
20785
|
-
const
|
20786
|
-
if (
|
20787
|
-
|
20283
|
+
async getStream(peerId) {
|
20284
|
+
const peerIdStr = peerId.toString();
|
20285
|
+
const scheduledStream = this.streamPool.get(peerIdStr);
|
20286
|
+
if (scheduledStream) {
|
20287
|
+
this.streamPool.delete(peerIdStr);
|
20288
|
+
await scheduledStream;
|
20289
|
+
}
|
20290
|
+
let stream = this.getOpenStreamForCodec(peerId);
|
20291
|
+
if (stream) {
|
20292
|
+
this.log.info(`Found existing stream peerId=${peerIdStr} multicodec=${this.multicodec}`);
|
20293
|
+
this.lockStream(peerIdStr, stream);
|
20294
|
+
return stream;
|
20295
|
+
}
|
20296
|
+
stream = await this.createStream(peerId);
|
20297
|
+
this.lockStream(peerIdStr, stream);
|
20298
|
+
return stream;
|
20299
|
+
}
|
20300
|
+
async createStream(peerId, retries = 0) {
|
20301
|
+
const connections = this.getConnections(peerId);
|
20302
|
+
const connection = selectOpenConnection(connections);
|
20303
|
+
if (!connection) {
|
20304
|
+
throw new Error(`Failed to get a connection to the peer peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20788
20305
|
}
|
20789
|
-
|
20790
|
-
|
20791
|
-
|
20792
|
-
|
20793
|
-
|
20794
|
-
|
20306
|
+
let lastError;
|
20307
|
+
let stream;
|
20308
|
+
for (let i = 0; i < retries + 1; i++) {
|
20309
|
+
try {
|
20310
|
+
this.log.info(`Attempting to create a stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20311
|
+
stream = await connection.newStream(this.multicodec);
|
20312
|
+
this.log.info(`Created stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20313
|
+
break;
|
20314
|
+
}
|
20315
|
+
catch (error) {
|
20316
|
+
lastError = error;
|
20795
20317
|
}
|
20796
20318
|
}
|
20319
|
+
if (!stream) {
|
20320
|
+
throw new Error(`Failed to create a new stream for ${peerId.toString()} -- ` + lastError);
|
20321
|
+
}
|
20322
|
+
return stream;
|
20323
|
+
}
|
20324
|
+
async createStreamWithLock(peer) {
|
20325
|
+
const peerId = peer.id.toString();
|
20326
|
+
if (this.ongoingCreation.has(peerId)) {
|
20327
|
+
this.log.info(`Skipping creation of a stream due to lock for peerId=${peerId} multicodec=${this.multicodec}`);
|
20328
|
+
return;
|
20329
|
+
}
|
20330
|
+
try {
|
20331
|
+
this.ongoingCreation.add(peerId);
|
20332
|
+
await this.createStream(peer.id);
|
20333
|
+
}
|
20797
20334
|
catch (error) {
|
20798
|
-
this.log.
|
20799
|
-
|
20335
|
+
this.log.error(`Failed to createStreamWithLock:`, error);
|
20336
|
+
}
|
20337
|
+
finally {
|
20338
|
+
this.ongoingCreation.delete(peerId);
|
20339
|
+
}
|
20340
|
+
return;
|
20341
|
+
}
|
20342
|
+
handlePeerUpdateStreamPool = (evt) => {
|
20343
|
+
const { peer } = evt.detail;
|
20344
|
+
if (!peer.protocols.includes(this.multicodec)) {
|
20345
|
+
return;
|
20346
|
+
}
|
20347
|
+
const stream = this.getOpenStreamForCodec(peer.id);
|
20348
|
+
if (stream) {
|
20349
|
+
return;
|
20350
|
+
}
|
20351
|
+
this.scheduleNewStream(peer);
|
20352
|
+
};
|
20353
|
+
scheduleNewStream(peer) {
|
20354
|
+
this.log.info(`Scheduling creation of a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
20355
|
+
// abandon previous attempt
|
20356
|
+
if (this.streamPool.has(peer.id.toString())) {
|
20357
|
+
this.streamPool.delete(peer.id.toString());
|
20800
20358
|
}
|
20801
|
-
|
20359
|
+
this.streamPool.set(peer.id.toString(), this.createStreamWithLock(peer));
|
20802
20360
|
}
|
20803
|
-
|
20804
|
-
const connections = this.getConnections(
|
20805
|
-
const connection =
|
20361
|
+
getOpenStreamForCodec(peerId) {
|
20362
|
+
const connections = this.getConnections(peerId);
|
20363
|
+
const connection = selectOpenConnection(connections);
|
20806
20364
|
if (!connection) {
|
20807
|
-
|
20365
|
+
return;
|
20808
20366
|
}
|
20809
|
-
|
20810
|
-
|
20367
|
+
const stream = connection.streams.find((s) => s.protocol === this.multicodec);
|
20368
|
+
if (!stream) {
|
20369
|
+
return;
|
20811
20370
|
}
|
20812
|
-
|
20813
|
-
|
20814
|
-
|
20815
|
-
await new Promise((resolve) => setTimeout(resolve, backoff));
|
20816
|
-
return this.createStream(peer, retries + 1);
|
20817
|
-
}
|
20818
|
-
throw new Error(`Failed to create a new stream for ${peer.id.toString()} -- ` + error);
|
20371
|
+
const isStreamUnusable = ["done", "closed", "closing"].includes(stream.writeStatus || "");
|
20372
|
+
if (isStreamUnusable || this.isStreamLocked(stream)) {
|
20373
|
+
return;
|
20819
20374
|
}
|
20375
|
+
return stream;
|
20820
20376
|
}
|
20821
|
-
|
20822
|
-
|
20823
|
-
|
20824
|
-
this.createStream(peer),
|
20825
|
-
timeoutPromise.then(() => {
|
20826
|
-
throw new Error("Connection timeout");
|
20827
|
-
})
|
20828
|
-
]).catch((error) => {
|
20829
|
-
this.log.error(`Failed to prepare a new stream for ${peer.id.toString()} -- `, error);
|
20830
|
-
});
|
20831
|
-
this.streamPool.set(peer.id.toString(), streamPromise);
|
20377
|
+
lockStream(peerId, stream) {
|
20378
|
+
this.log.info(`Locking stream for peerId:${peerId}\tstreamId:${stream.id}`);
|
20379
|
+
stream.metadata[STREAM_LOCK_KEY] = true;
|
20832
20380
|
}
|
20833
|
-
|
20834
|
-
|
20835
|
-
if (peer.protocols.includes(this.multicodec)) {
|
20836
|
-
const isConnected = this.isConnectedTo(peer.id);
|
20837
|
-
if (isConnected) {
|
20838
|
-
this.log.info(`Preemptively opening a stream to ${peer.id.toString()}`);
|
20839
|
-
this.prepareStream(peer);
|
20840
|
-
}
|
20841
|
-
else {
|
20842
|
-
const peerIdStr = peer.id.toString();
|
20843
|
-
this.streamPool.delete(peerIdStr);
|
20844
|
-
this.log.info(`Removed pending stream for disconnected peer ${peerIdStr}`);
|
20845
|
-
}
|
20846
|
-
}
|
20847
|
-
};
|
20848
|
-
isConnectedTo(peerId) {
|
20849
|
-
const connections = this.getConnections(peerId);
|
20850
|
-
return connections.some((connection) => connection.status === "open");
|
20381
|
+
isStreamLocked(stream) {
|
20382
|
+
return !!stream.metadata[STREAM_LOCK_KEY];
|
20851
20383
|
}
|
20852
20384
|
}
|
20853
20385
|
|
@@ -20858,66 +20390,20 @@ class StreamManager {
|
|
20858
20390
|
class BaseProtocol {
|
20859
20391
|
multicodec;
|
20860
20392
|
components;
|
20861
|
-
log;
|
20862
20393
|
pubsubTopics;
|
20863
20394
|
addLibp2pEventListener;
|
20864
20395
|
removeLibp2pEventListener;
|
20865
20396
|
streamManager;
|
20866
|
-
constructor(multicodec, components,
|
20397
|
+
constructor(multicodec, components, pubsubTopics) {
|
20867
20398
|
this.multicodec = multicodec;
|
20868
20399
|
this.components = components;
|
20869
|
-
this.log = log;
|
20870
20400
|
this.pubsubTopics = pubsubTopics;
|
20871
20401
|
this.addLibp2pEventListener = components.events.addEventListener.bind(components.events);
|
20872
20402
|
this.removeLibp2pEventListener = components.events.removeEventListener.bind(components.events);
|
20873
20403
|
this.streamManager = new StreamManager(multicodec, components.connectionManager.getConnections.bind(components.connectionManager), this.addLibp2pEventListener);
|
20874
20404
|
}
|
20875
|
-
async getStream(
|
20876
|
-
return this.streamManager.getStream(
|
20877
|
-
}
|
20878
|
-
//TODO: move to SDK
|
20879
|
-
/**
|
20880
|
-
* Returns known peers from the address book (`libp2p.peerStore`) that support
|
20881
|
-
* the class protocol. Waku may or may not be currently connected to these
|
20882
|
-
* peers.
|
20883
|
-
*/
|
20884
|
-
async allPeers() {
|
20885
|
-
return getPeersForProtocol(this.components.peerStore, [this.multicodec]);
|
20886
|
-
}
|
20887
|
-
async connectedPeers(withOpenStreams = false) {
|
20888
|
-
const peers = await this.allPeers();
|
20889
|
-
return peers.filter((peer) => {
|
20890
|
-
const connections = this.components.connectionManager.getConnections(peer.id);
|
20891
|
-
if (withOpenStreams) {
|
20892
|
-
return connections.some((c) => c.streams.some((s) => s.protocol === this.multicodec));
|
20893
|
-
}
|
20894
|
-
return connections.length > 0;
|
20895
|
-
});
|
20896
|
-
}
|
20897
|
-
/**
|
20898
|
-
* Retrieves a list of connected peers that support the protocol. The list is sorted by latency.
|
20899
|
-
*
|
20900
|
-
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned.
|
20901
|
-
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
|
20902
|
-
* @returns A list of peers that support the protocol sorted by latency. By default, returns all peers available, including bootstrap.
|
20903
|
-
*/
|
20904
|
-
async getPeers({ numPeers, maxBootstrapPeers } = {
|
20905
|
-
maxBootstrapPeers: 0,
|
20906
|
-
numPeers: 0
|
20907
|
-
}) {
|
20908
|
-
// Retrieve all connected peers that support the protocol & shard (if configured)
|
20909
|
-
const allAvailableConnectedPeers = await this.connectedPeers();
|
20910
|
-
// Filter the peers based on discovery & number of peers requested
|
20911
|
-
const filteredPeers = filterPeersByDiscovery(allAvailableConnectedPeers, numPeers, maxBootstrapPeers);
|
20912
|
-
// Sort the peers by latency
|
20913
|
-
const sortedFilteredPeers = await sortPeersByLatency(this.components.peerStore, filteredPeers);
|
20914
|
-
if (sortedFilteredPeers.length === 0) {
|
20915
|
-
this.log.warn("No peers found. Ensure you have a connection to the network.");
|
20916
|
-
}
|
20917
|
-
if (sortedFilteredPeers.length < numPeers) {
|
20918
|
-
this.log.warn(`Only ${sortedFilteredPeers.length} peers found. Requested ${numPeers}.`);
|
20919
|
-
}
|
20920
|
-
return sortedFilteredPeers;
|
20405
|
+
async getStream(peerId) {
|
20406
|
+
return this.streamManager.getStream(peerId);
|
20921
20407
|
}
|
20922
20408
|
}
|
20923
20409
|
|
@@ -24544,6 +24030,105 @@ var WakuMetadataResponse;
|
|
24544
24030
|
};
|
24545
24031
|
})(WakuMetadataResponse || (WakuMetadataResponse = {}));
|
24546
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
|
+
|
24547
24132
|
/**
|
24548
24133
|
* PeerExchangeRPC represents a message conforming to the Waku Peer Exchange protocol
|
24549
24134
|
*/
|
@@ -24594,7 +24179,7 @@ class WakuPeerExchange extends BaseProtocol {
|
|
24594
24179
|
* @param components - libp2p components
|
24595
24180
|
*/
|
24596
24181
|
constructor(components, pubsubTopics) {
|
24597
|
-
super(PeerExchangeCodec, components,
|
24182
|
+
super(PeerExchangeCodec, components, pubsubTopics);
|
24598
24183
|
}
|
24599
24184
|
/**
|
24600
24185
|
* Make a peer exchange query to a peer
|
@@ -24613,7 +24198,7 @@ class WakuPeerExchange extends BaseProtocol {
|
|
24613
24198
|
}
|
24614
24199
|
let stream;
|
24615
24200
|
try {
|
24616
|
-
stream = await this.getStream(
|
24201
|
+
stream = await this.getStream(peerId);
|
24617
24202
|
}
|
24618
24203
|
catch (err) {
|
24619
24204
|
log$2.error("Failed to get stream", err);
|
@@ -24828,7 +24413,7 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
|
|
24828
24413
|
const existingShardInfoBytes = peer.metadata.get("shardInfo");
|
24829
24414
|
if (existingShardInfoBytes) {
|
24830
24415
|
const existingShardInfo = decodeRelayShard(existingShardInfoBytes);
|
24831
|
-
|
24416
|
+
{
|
24832
24417
|
hasShardDiff =
|
24833
24418
|
existingShardInfo.clusterId !== shardInfo?.clusterId ||
|
24834
24419
|
existingShardInfo.shards.some((shard) => !shardInfo?.shards.includes(shard));
|
@@ -24844,50 +24429,210 @@ function wakuPeerExchangeDiscovery(pubsubTopics) {
|
|
24844
24429
|
/**
|
24845
24430
|
* @packageDocumentation
|
24846
24431
|
*
|
24847
|
-
*
|
24848
|
-
*
|
24849
|
-
* A Peer ID is the SHA-256 [multihash](https://github.com/multiformats/multihash) of a public key.
|
24850
|
-
*
|
24851
|
-
* The public key is a base64 encoded string of a protobuf containing an RSA DER buffer. This uses a node buffer to pass the base64 encoded public key protobuf to the multihash for ID generation.
|
24432
|
+
* An implementation of a peer id
|
24852
24433
|
*
|
24853
24434
|
* @example
|
24854
24435
|
*
|
24855
24436
|
* ```TypeScript
|
24856
|
-
* import {
|
24857
|
-
*
|
24858
|
-
* const peerId = await createEd25519PeerId()
|
24859
|
-
* console.log(peerId.toString())
|
24860
|
-
* ```
|
24437
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
24438
|
+
* const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
|
24861
24439
|
*
|
24862
|
-
*
|
24863
|
-
*
|
24440
|
+
* console.log(peer.toCID()) // CID(bafzaa...)
|
24441
|
+
* console.log(peer.toString()) // "12D3K..."
|
24864
24442
|
* ```
|
24865
24443
|
*/
|
24866
|
-
|
24867
|
-
|
24444
|
+
const inspect = Symbol.for('nodejs.util.inspect.custom');
|
24445
|
+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
24446
|
+
const LIBP2P_KEY_CODE = 0x72;
|
24447
|
+
class PeerIdImpl {
|
24448
|
+
type;
|
24449
|
+
multihash;
|
24450
|
+
publicKey;
|
24451
|
+
string;
|
24452
|
+
constructor(init) {
|
24453
|
+
this.type = init.type;
|
24454
|
+
this.multihash = init.multihash;
|
24455
|
+
// mark string cache as non-enumerable
|
24456
|
+
Object.defineProperty(this, 'string', {
|
24457
|
+
enumerable: false,
|
24458
|
+
writable: true
|
24459
|
+
});
|
24460
|
+
}
|
24461
|
+
get [Symbol.toStringTag]() {
|
24462
|
+
return `PeerId(${this.toString()})`;
|
24463
|
+
}
|
24464
|
+
[peerIdSymbol] = true;
|
24465
|
+
toString() {
|
24466
|
+
if (this.string == null) {
|
24467
|
+
this.string = base58btc.encode(this.multihash.bytes).slice(1);
|
24468
|
+
}
|
24469
|
+
return this.string;
|
24470
|
+
}
|
24471
|
+
toMultihash() {
|
24472
|
+
return this.multihash;
|
24473
|
+
}
|
24474
|
+
// return self-describing String representation
|
24475
|
+
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
24476
|
+
toCID() {
|
24477
|
+
return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
|
24478
|
+
}
|
24479
|
+
toJSON() {
|
24480
|
+
return this.toString();
|
24481
|
+
}
|
24482
|
+
/**
|
24483
|
+
* Checks the equality of `this` peer against a given PeerId
|
24484
|
+
*/
|
24485
|
+
equals(id) {
|
24486
|
+
if (id == null) {
|
24487
|
+
return false;
|
24488
|
+
}
|
24489
|
+
if (id instanceof Uint8Array) {
|
24490
|
+
return equals(this.multihash.bytes, id);
|
24491
|
+
}
|
24492
|
+
else if (typeof id === 'string') {
|
24493
|
+
return this.toString() === id;
|
24494
|
+
}
|
24495
|
+
else if (id?.toMultihash()?.bytes != null) {
|
24496
|
+
return equals(this.multihash.bytes, id.toMultihash().bytes);
|
24497
|
+
}
|
24498
|
+
else {
|
24499
|
+
throw new Error('not valid Id');
|
24500
|
+
}
|
24501
|
+
}
|
24502
|
+
/**
|
24503
|
+
* Returns PeerId as a human-readable string
|
24504
|
+
* https://nodejs.org/api/util.html#utilinspectcustom
|
24505
|
+
*
|
24506
|
+
* @example
|
24507
|
+
* ```TypeScript
|
24508
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
24509
|
+
*
|
24510
|
+
* console.info(peerIdFromString('QmFoo'))
|
24511
|
+
* // 'PeerId(QmFoo)'
|
24512
|
+
* ```
|
24513
|
+
*/
|
24514
|
+
[inspect]() {
|
24515
|
+
return `PeerId(${this.toString()})`;
|
24516
|
+
}
|
24517
|
+
}
|
24518
|
+
class RSAPeerId extends PeerIdImpl {
|
24519
|
+
type = 'RSA';
|
24520
|
+
publicKey;
|
24521
|
+
constructor(init) {
|
24522
|
+
super({ ...init, type: 'RSA' });
|
24523
|
+
this.publicKey = init.publicKey;
|
24524
|
+
}
|
24525
|
+
}
|
24526
|
+
class Ed25519PeerId extends PeerIdImpl {
|
24527
|
+
type = 'Ed25519';
|
24528
|
+
publicKey;
|
24529
|
+
constructor(init) {
|
24530
|
+
super({ ...init, type: 'Ed25519' });
|
24531
|
+
this.publicKey = init.publicKey;
|
24532
|
+
}
|
24868
24533
|
}
|
24869
|
-
|
24870
|
-
|
24534
|
+
class Secp256k1PeerId extends PeerIdImpl {
|
24535
|
+
type = 'secp256k1';
|
24536
|
+
publicKey;
|
24537
|
+
constructor(init) {
|
24538
|
+
super({ ...init, type: 'secp256k1' });
|
24539
|
+
this.publicKey = init.publicKey;
|
24540
|
+
}
|
24871
24541
|
}
|
24872
|
-
|
24873
|
-
|
24542
|
+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
24543
|
+
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
24544
|
+
class URLPeerId {
|
24545
|
+
type = 'url';
|
24546
|
+
multihash;
|
24547
|
+
publicKey;
|
24548
|
+
url;
|
24549
|
+
constructor(url) {
|
24550
|
+
this.url = url.toString();
|
24551
|
+
this.multihash = identity.digest(fromString(this.url));
|
24552
|
+
}
|
24553
|
+
[inspect]() {
|
24554
|
+
return `PeerId(${this.url})`;
|
24555
|
+
}
|
24556
|
+
[peerIdSymbol] = true;
|
24557
|
+
toString() {
|
24558
|
+
return this.toCID().toString();
|
24559
|
+
}
|
24560
|
+
toMultihash() {
|
24561
|
+
return this.multihash;
|
24562
|
+
}
|
24563
|
+
toCID() {
|
24564
|
+
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.toMultihash());
|
24565
|
+
}
|
24566
|
+
toJSON() {
|
24567
|
+
return this.toString();
|
24568
|
+
}
|
24569
|
+
equals(other) {
|
24570
|
+
if (other == null) {
|
24571
|
+
return false;
|
24572
|
+
}
|
24573
|
+
if (other instanceof Uint8Array) {
|
24574
|
+
other = toString$6(other);
|
24575
|
+
}
|
24576
|
+
return other.toString() === this.toString();
|
24577
|
+
}
|
24874
24578
|
}
|
24875
|
-
|
24876
|
-
|
24877
|
-
|
24878
|
-
|
24579
|
+
|
24580
|
+
/**
|
24581
|
+
* @packageDocumentation
|
24582
|
+
*
|
24583
|
+
* An implementation of a peer id
|
24584
|
+
*
|
24585
|
+
* @example
|
24586
|
+
*
|
24587
|
+
* ```TypeScript
|
24588
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
24589
|
+
* const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
|
24590
|
+
*
|
24591
|
+
* console.log(peer.toCID()) // CID(bafzaa...)
|
24592
|
+
* console.log(peer.toString()) // "12D3K..."
|
24593
|
+
* ```
|
24594
|
+
*/
|
24595
|
+
function peerIdFromString(str, decoder) {
|
24596
|
+
let multihash;
|
24597
|
+
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
24598
|
+
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
24599
|
+
// rsa public key - base58btc encoded either way
|
24600
|
+
multihash = decode$6(base58btc.decode(`z${str}`));
|
24601
|
+
}
|
24602
|
+
else {
|
24603
|
+
{
|
24604
|
+
throw new InvalidParametersError('Please pass a multibase decoder for strings that do not start with "1" or "Q"');
|
24605
|
+
}
|
24879
24606
|
}
|
24880
|
-
|
24881
|
-
|
24882
|
-
|
24607
|
+
return peerIdFromMultihash(multihash);
|
24608
|
+
}
|
24609
|
+
function peerIdFromMultihash(multihash) {
|
24610
|
+
if (isSha256Multihash(multihash)) {
|
24611
|
+
return new RSAPeerId({ multihash });
|
24883
24612
|
}
|
24884
|
-
|
24885
|
-
|
24886
|
-
|
24887
|
-
|
24888
|
-
|
24613
|
+
else if (isIdentityMultihash(multihash)) {
|
24614
|
+
try {
|
24615
|
+
const publicKey = publicKeyFromMultihash(multihash);
|
24616
|
+
if (publicKey.type === 'Ed25519') {
|
24617
|
+
return new Ed25519PeerId({ multihash, publicKey });
|
24618
|
+
}
|
24619
|
+
else if (publicKey.type === 'secp256k1') {
|
24620
|
+
return new Secp256k1PeerId({ multihash, publicKey });
|
24621
|
+
}
|
24622
|
+
}
|
24623
|
+
catch (err) {
|
24624
|
+
// was not Ed or secp key, try URL
|
24625
|
+
const url = toString$6(multihash.digest);
|
24626
|
+
return new URLPeerId(new URL(url));
|
24627
|
+
}
|
24889
24628
|
}
|
24890
|
-
|
24629
|
+
throw new InvalidMultihashError('Supplied PeerID Multihash is invalid');
|
24630
|
+
}
|
24631
|
+
function isIdentityMultihash(multihash) {
|
24632
|
+
return multihash.code === identity.code;
|
24633
|
+
}
|
24634
|
+
function isSha256Multihash(multihash) {
|
24635
|
+
return multihash.code === sha256.code;
|
24891
24636
|
}
|
24892
24637
|
|
24893
24638
|
const log = new Logger$1("peer-exchange-discovery");
|
@@ -24915,7 +24660,7 @@ class LocalPeerCacheDiscovery extends TypedEventEmitter {
|
|
24915
24660
|
log.info("Starting Local Storage Discovery");
|
24916
24661
|
this.components.events.addEventListener("peer:identify", this.handleNewPeers);
|
24917
24662
|
for (const { id: idStr, address } of this.peers) {
|
24918
|
-
const peerId =
|
24663
|
+
const peerId = peerIdFromString(idStr);
|
24919
24664
|
if (await this.components.peerStore.has(peerId))
|
24920
24665
|
continue;
|
24921
24666
|
await this.components.peerStore.save(peerId, {
|