@waku/discovery 0.0.6 → 0.0.7-00f2e75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.js +1362 -1772
- 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 -101
- 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,21 +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
|
-
|
36
|
-
|
40
|
+
this.name = 'InvalidParametersError';
|
41
|
+
}
|
42
|
+
}
|
43
|
+
/**
|
44
|
+
* Thrown when a public key is invalid
|
45
|
+
*/
|
46
|
+
class InvalidPublicKeyError extends Error {
|
47
|
+
static name = 'InvalidPublicKeyError';
|
48
|
+
constructor(message = 'Invalid public key') {
|
49
|
+
super(message);
|
50
|
+
this.name = 'InvalidPublicKeyError';
|
51
|
+
}
|
52
|
+
}
|
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';
|
37
71
|
}
|
38
72
|
}
|
39
73
|
|
40
|
-
/**
|
74
|
+
/**
|
75
|
+
* Noop for browser compatibility
|
76
|
+
*/
|
41
77
|
function setMaxListeners$1() { }
|
42
78
|
|
43
|
-
|
79
|
+
/**
|
80
|
+
* Create a setMaxListeners that doesn't break browser usage
|
81
|
+
*/
|
44
82
|
const setMaxListeners = (n, ...eventTargets) => {
|
45
83
|
try {
|
46
84
|
setMaxListeners$1(n, ...eventTargets);
|
@@ -104,7 +142,6 @@ class TypedEventEmitter extends EventTarget {
|
|
104
142
|
return this.dispatchEvent(new CustomEvent(type, detail));
|
105
143
|
}
|
106
144
|
}
|
107
|
-
const CustomEvent = globalThis.CustomEvent;
|
108
145
|
|
109
146
|
var Protocols;
|
110
147
|
(function (Protocols) {
|
@@ -115,43 +152,24 @@ var Protocols;
|
|
115
152
|
})(Protocols || (Protocols = {}));
|
116
153
|
var ProtocolError;
|
117
154
|
(function (ProtocolError) {
|
118
|
-
|
155
|
+
//
|
156
|
+
// GENERAL ERRORS SECTION
|
157
|
+
//
|
158
|
+
/**
|
159
|
+
* Could not determine the origin of the fault. Best to check connectivity and try again
|
160
|
+
* */
|
119
161
|
ProtocolError["GENERIC_FAIL"] = "Generic error";
|
120
162
|
/**
|
121
|
-
*
|
122
|
-
*
|
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.
|
123
166
|
*/
|
124
|
-
ProtocolError["
|
167
|
+
ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
125
168
|
/**
|
126
169
|
* Failure to protobuf decode the message. May be due to a remote peer issue,
|
127
170
|
* ensuring that messages are sent via several peer enable mitigation of this error.
|
128
171
|
*/
|
129
172
|
ProtocolError["DECODE_FAILED"] = "Failed to decode";
|
130
|
-
/**
|
131
|
-
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
132
|
-
* payload is set on the outgoing message.
|
133
|
-
*/
|
134
|
-
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
135
|
-
/**
|
136
|
-
* The message size is above the maximum message size allowed on the Waku Network.
|
137
|
-
* Compressing the message or using an alternative strategy for large messages is recommended.
|
138
|
-
*/
|
139
|
-
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
140
|
-
/**
|
141
|
-
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
142
|
-
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
143
|
-
*/
|
144
|
-
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
145
|
-
/**
|
146
|
-
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
147
|
-
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
148
|
-
*/
|
149
|
-
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
150
|
-
/**
|
151
|
-
* The topics passed in the decoders do not match each other, or don't exist at all.
|
152
|
-
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
153
|
-
*/
|
154
|
-
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
155
173
|
/**
|
156
174
|
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
157
175
|
* Mitigation can be: retrying after a given time period, display connectivity issue
|
@@ -169,37 +187,51 @@ var ProtocolError;
|
|
169
187
|
* or `DECODE_FAILED` can be used.
|
170
188
|
*/
|
171
189
|
ProtocolError["NO_RESPONSE"] = "No response received";
|
190
|
+
//
|
191
|
+
// SEND ERRORS SECTION
|
192
|
+
//
|
172
193
|
/**
|
173
|
-
*
|
174
|
-
*
|
175
|
-
* or `DECODE_FAILED` can be used.
|
194
|
+
* Failure to protobuf encode the message. This is not recoverable and needs
|
195
|
+
* further investigation.
|
176
196
|
*/
|
177
|
-
ProtocolError["
|
197
|
+
ProtocolError["ENCODE_FAILED"] = "Failed to encode";
|
178
198
|
/**
|
179
|
-
* The
|
180
|
-
*
|
199
|
+
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
200
|
+
* payload is set on the outgoing message.
|
181
201
|
*/
|
182
|
-
ProtocolError["
|
202
|
+
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
183
203
|
/**
|
184
|
-
*
|
185
|
-
*
|
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.
|
186
206
|
*/
|
187
|
-
ProtocolError["
|
207
|
+
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
188
208
|
/**
|
189
|
-
*
|
190
|
-
*
|
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.
|
191
211
|
*/
|
192
|
-
ProtocolError["
|
212
|
+
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
193
213
|
/**
|
194
|
-
*
|
195
|
-
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
|
214
|
+
* Fails when
|
196
215
|
*/
|
197
|
-
ProtocolError["
|
216
|
+
ProtocolError["STREAM_ABORTED"] = "Stream aborted";
|
198
217
|
/**
|
199
218
|
* General proof generation error message.
|
200
219
|
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
|
201
220
|
*/
|
202
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";
|
203
235
|
})(ProtocolError || (ProtocolError = {}));
|
204
236
|
|
205
237
|
var Tags;
|
@@ -222,6 +254,10 @@ var EConnectionStateEvents;
|
|
222
254
|
|
223
255
|
const DNS_DISCOVERY_TAG = "@waku/bootstrap";
|
224
256
|
|
257
|
+
var HealthStatusChangeEvents;
|
258
|
+
(function (HealthStatusChangeEvents) {
|
259
|
+
HealthStatusChangeEvents["StatusChange"] = "health:change";
|
260
|
+
})(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
|
225
261
|
var HealthStatus;
|
226
262
|
(function (HealthStatus) {
|
227
263
|
HealthStatus["Unhealthy"] = "Unhealthy";
|
@@ -233,43 +269,55 @@ function isDefined(value) {
|
|
233
269
|
return Boolean(value);
|
234
270
|
}
|
235
271
|
|
236
|
-
|
272
|
+
/**
|
273
|
+
* Internal assertion helpers.
|
274
|
+
* @module
|
275
|
+
*/
|
276
|
+
/** Asserts something is positive integer. */
|
277
|
+
function anumber(n) {
|
237
278
|
if (!Number.isSafeInteger(n) || n < 0)
|
238
|
-
throw new Error(
|
279
|
+
throw new Error('positive integer expected, got ' + n);
|
239
280
|
}
|
240
|
-
|
281
|
+
/** Is number an Uint8Array? Copied from utils for perf. */
|
241
282
|
function isBytes$2(a) {
|
242
|
-
return
|
243
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
283
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
244
284
|
}
|
245
|
-
|
285
|
+
/** Asserts something is Uint8Array. */
|
286
|
+
function abytes$1(b, ...lengths) {
|
246
287
|
if (!isBytes$2(b))
|
247
288
|
throw new Error('Uint8Array expected');
|
248
289
|
if (lengths.length > 0 && !lengths.includes(b.length))
|
249
|
-
throw new Error(
|
290
|
+
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
|
250
291
|
}
|
251
|
-
|
292
|
+
/** Asserts something is hash */
|
293
|
+
function ahash(h) {
|
252
294
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
253
295
|
throw new Error('Hash should be wrapped by utils.wrapConstructor');
|
254
|
-
|
255
|
-
|
296
|
+
anumber(h.outputLen);
|
297
|
+
anumber(h.blockLen);
|
256
298
|
}
|
257
|
-
|
299
|
+
/** Asserts a hash instance has not been destroyed / finished */
|
300
|
+
function aexists(instance, checkFinished = true) {
|
258
301
|
if (instance.destroyed)
|
259
302
|
throw new Error('Hash instance has been destroyed');
|
260
303
|
if (checkFinished && instance.finished)
|
261
304
|
throw new Error('Hash#digest() has already been called');
|
262
305
|
}
|
263
|
-
|
264
|
-
|
306
|
+
/** Asserts output is properly-sized byte array */
|
307
|
+
function aoutput(out, instance) {
|
308
|
+
abytes$1(out);
|
265
309
|
const min = instance.outputLen;
|
266
310
|
if (out.length < min) {
|
267
|
-
throw new Error(
|
311
|
+
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
268
312
|
}
|
269
313
|
}
|
270
314
|
|
271
315
|
const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
272
316
|
|
317
|
+
/**
|
318
|
+
* Utilities for hex, bytes, CSPRNG.
|
319
|
+
* @module
|
320
|
+
*/
|
273
321
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
274
322
|
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
275
323
|
// node.js versions earlier than v19 don't declare it in global scope.
|
@@ -278,33 +326,20 @@ const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? glob
|
|
278
326
|
// Makes the utils un-importable in browsers without a bundler.
|
279
327
|
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
280
328
|
// Cast array to view
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
// next scheduler queue processing step and this is exactly what we need.
|
288
|
-
const nextTick = async () => { };
|
289
|
-
// Returns control to thread each 'tick' ms to avoid blocking
|
290
|
-
async function asyncLoop(iters, tick, cb) {
|
291
|
-
let ts = Date.now();
|
292
|
-
for (let i = 0; i < iters; i++) {
|
293
|
-
cb(i);
|
294
|
-
// Date.now() is not monotonic, so in case if clock goes backwards we return return control too
|
295
|
-
const diff = Date.now() - ts;
|
296
|
-
if (diff >= 0 && diff < tick)
|
297
|
-
continue;
|
298
|
-
await nextTick();
|
299
|
-
ts += diff;
|
300
|
-
}
|
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);
|
301
335
|
}
|
302
336
|
/**
|
337
|
+
* Convert JS string to byte array.
|
303
338
|
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
304
339
|
*/
|
305
340
|
function utf8ToBytes$2(str) {
|
306
341
|
if (typeof str !== 'string')
|
307
|
-
throw new Error(
|
342
|
+
throw new Error('utf8ToBytes expected string, got ' + typeof str);
|
308
343
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
309
344
|
}
|
310
345
|
/**
|
@@ -315,7 +350,7 @@ function utf8ToBytes$2(str) {
|
|
315
350
|
function toBytes$1(data) {
|
316
351
|
if (typeof data === 'string')
|
317
352
|
data = utf8ToBytes$2(data);
|
318
|
-
|
353
|
+
abytes$1(data);
|
319
354
|
return data;
|
320
355
|
}
|
321
356
|
/**
|
@@ -325,7 +360,7 @@ function concatBytes$2(...arrays) {
|
|
325
360
|
let sum = 0;
|
326
361
|
for (let i = 0; i < arrays.length; i++) {
|
327
362
|
const a = arrays[i];
|
328
|
-
|
363
|
+
abytes$1(a);
|
329
364
|
sum += a.length;
|
330
365
|
}
|
331
366
|
const res = new Uint8Array(sum);
|
@@ -336,20 +371,14 @@ function concatBytes$2(...arrays) {
|
|
336
371
|
}
|
337
372
|
return res;
|
338
373
|
}
|
339
|
-
|
374
|
+
/** For runtime check if class implements interface */
|
340
375
|
class Hash {
|
341
376
|
// Safe version that clones internal state
|
342
377
|
clone() {
|
343
378
|
return this._cloneInto();
|
344
379
|
}
|
345
380
|
}
|
346
|
-
|
347
|
-
function checkOpts(defaults, opts) {
|
348
|
-
if (opts !== undefined && toStr.call(opts) !== '[object Object]')
|
349
|
-
throw new Error('Options should be object or undefined');
|
350
|
-
const merged = Object.assign(defaults, opts);
|
351
|
-
return merged;
|
352
|
-
}
|
381
|
+
/** Wraps hash function, creating an interface on top of it */
|
353
382
|
function wrapConstructor(hashCons) {
|
354
383
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
355
384
|
const tmp = hashCons();
|
@@ -358,10 +387,8 @@ function wrapConstructor(hashCons) {
|
|
358
387
|
hashC.create = () => hashCons();
|
359
388
|
return hashC;
|
360
389
|
}
|
361
|
-
/**
|
362
|
-
|
363
|
-
*/
|
364
|
-
function randomBytes$1(bytesLength = 32) {
|
390
|
+
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
|
391
|
+
function randomBytes(bytesLength = 32) {
|
365
392
|
if (crypto$2 && typeof crypto$2.getRandomValues === 'function') {
|
366
393
|
return crypto$2.getRandomValues(new Uint8Array(bytesLength));
|
367
394
|
}
|
@@ -373,8 +400,10 @@ function randomBytes$1(bytesLength = 32) {
|
|
373
400
|
}
|
374
401
|
|
375
402
|
/**
|
376
|
-
*
|
403
|
+
* Internal Merkle-Damgard hash utils.
|
404
|
+
* @module
|
377
405
|
*/
|
406
|
+
/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
|
378
407
|
function setBigUint64(view, byteOffset, value, isLE) {
|
379
408
|
if (typeof view.setBigUint64 === 'function')
|
380
409
|
return view.setBigUint64(byteOffset, value, isLE);
|
@@ -387,14 +416,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
387
416
|
view.setUint32(byteOffset + h, wh, isLE);
|
388
417
|
view.setUint32(byteOffset + l, wl, isLE);
|
389
418
|
}
|
390
|
-
/**
|
391
|
-
|
392
|
-
|
393
|
-
|
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) {
|
@@ -1252,7 +1285,7 @@ new TextDecoder();
|
|
1252
1285
|
|
1253
1286
|
/* eslint-disable */
|
1254
1287
|
var encode_1 = encode$7;
|
1255
|
-
var MSB$1 = 0x80,
|
1288
|
+
var MSB$1 = 0x80, MSBALL = -128, INT = Math.pow(2, 31);
|
1256
1289
|
/**
|
1257
1290
|
* @param {number} num
|
1258
1291
|
* @param {number[]} out
|
@@ -1276,7 +1309,7 @@ function encode$7(num, out, offset) {
|
|
1276
1309
|
return out;
|
1277
1310
|
}
|
1278
1311
|
var decode$8 = read$1;
|
1279
|
-
var MSB$1$1 = 0x80, REST$1
|
1312
|
+
var MSB$1$1 = 0x80, REST$1 = 0x7F;
|
1280
1313
|
/**
|
1281
1314
|
* @param {string | any[]} buf
|
1282
1315
|
* @param {number} offset
|
@@ -1291,8 +1324,8 @@ function read$1(buf, offset) {
|
|
1291
1324
|
}
|
1292
1325
|
b = buf[counter++];
|
1293
1326
|
res += shift < 28
|
1294
|
-
? (b & REST$1
|
1295
|
-
: (b & REST$1
|
1327
|
+
? (b & REST$1) << shift
|
1328
|
+
: (b & REST$1) * Math.pow(2, shift);
|
1296
1329
|
shift += 7;
|
1297
1330
|
} while (b >= MSB$1$1);
|
1298
1331
|
// @ts-ignore
|
@@ -1342,7 +1375,7 @@ function encodingLength$3(int) {
|
|
1342
1375
|
/**
|
1343
1376
|
* Creates a multihash digest.
|
1344
1377
|
*/
|
1345
|
-
function create
|
1378
|
+
function create(code, digest) {
|
1346
1379
|
const size = digest.byteLength;
|
1347
1380
|
const sizeOffset = encodingLength$3(code);
|
1348
1381
|
const digestOffset = sizeOffset + encodingLength$3(size);
|
@@ -1401,7 +1434,7 @@ const code = 0x0;
|
|
1401
1434
|
const name$1 = 'identity';
|
1402
1435
|
const encode$6 = coerce;
|
1403
1436
|
function digest(input) {
|
1404
|
-
return create
|
1437
|
+
return create(code, encode$6(input));
|
1405
1438
|
}
|
1406
1439
|
const identity = { code, name: name$1, encode: encode$6, digest };
|
1407
1440
|
|
@@ -1425,9 +1458,9 @@ class Hasher {
|
|
1425
1458
|
if (input instanceof Uint8Array) {
|
1426
1459
|
const result = this.encode(input);
|
1427
1460
|
return result instanceof Uint8Array
|
1428
|
-
? create
|
1461
|
+
? create(this.code, result)
|
1429
1462
|
/* c8 ignore next 1 */
|
1430
|
-
: result.then(digest => create
|
1463
|
+
: result.then(digest => create(this.code, digest));
|
1431
1464
|
}
|
1432
1465
|
else {
|
1433
1466
|
throw Error('Unknown type, must be binary type');
|
@@ -1527,7 +1560,7 @@ class CID {
|
|
1527
1560
|
switch (this.version) {
|
1528
1561
|
case 0: {
|
1529
1562
|
const { code, digest } = this.multihash;
|
1530
|
-
const multihash = create
|
1563
|
+
const multihash = create(code, digest);
|
1531
1564
|
return (CID.createV1(this.code, multihash));
|
1532
1565
|
}
|
1533
1566
|
case 1: {
|
@@ -2337,24 +2370,62 @@ function setup(env) {
|
|
2337
2370
|
createDebug.names = [];
|
2338
2371
|
createDebug.skips = [];
|
2339
2372
|
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2373
|
+
const split = (typeof namespaces === 'string' ? namespaces : '')
|
2374
|
+
.trim()
|
2375
|
+
.replace(' ', ',')
|
2376
|
+
.split(',')
|
2377
|
+
.filter(Boolean);
|
2343
2378
|
|
2344
|
-
for (
|
2345
|
-
if (
|
2346
|
-
|
2347
|
-
|
2379
|
+
for (const ns of split) {
|
2380
|
+
if (ns[0] === '-') {
|
2381
|
+
createDebug.skips.push(ns.slice(1));
|
2382
|
+
} else {
|
2383
|
+
createDebug.names.push(ns);
|
2348
2384
|
}
|
2385
|
+
}
|
2386
|
+
}
|
2349
2387
|
|
2350
|
-
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
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;
|
2354
2418
|
} else {
|
2355
|
-
|
2419
|
+
return false; // No match
|
2356
2420
|
}
|
2357
2421
|
}
|
2422
|
+
|
2423
|
+
// Handle trailing '*' in template
|
2424
|
+
while (templateIndex < template.length && template[templateIndex] === '*') {
|
2425
|
+
templateIndex++;
|
2426
|
+
}
|
2427
|
+
|
2428
|
+
return templateIndex === template.length;
|
2358
2429
|
}
|
2359
2430
|
|
2360
2431
|
/**
|
@@ -2365,8 +2436,8 @@ function setup(env) {
|
|
2365
2436
|
*/
|
2366
2437
|
function disable() {
|
2367
2438
|
const namespaces = [
|
2368
|
-
...createDebug.names
|
2369
|
-
...createDebug.skips.map(
|
2439
|
+
...createDebug.names,
|
2440
|
+
...createDebug.skips.map(namespace => '-' + namespace)
|
2370
2441
|
].join(',');
|
2371
2442
|
createDebug.enable('');
|
2372
2443
|
return namespaces;
|
@@ -2380,21 +2451,14 @@ function setup(env) {
|
|
2380
2451
|
* @api public
|
2381
2452
|
*/
|
2382
2453
|
function enabled(name) {
|
2383
|
-
|
2384
|
-
|
2385
|
-
}
|
2386
|
-
|
2387
|
-
let i;
|
2388
|
-
let len;
|
2389
|
-
|
2390
|
-
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
2391
|
-
if (createDebug.skips[i].test(name)) {
|
2454
|
+
for (const skip of createDebug.skips) {
|
2455
|
+
if (matchesTemplate(name, skip)) {
|
2392
2456
|
return false;
|
2393
2457
|
}
|
2394
2458
|
}
|
2395
2459
|
|
2396
|
-
for (
|
2397
|
-
if (
|
2460
|
+
for (const ns of createDebug.names) {
|
2461
|
+
if (matchesTemplate(name, ns)) {
|
2398
2462
|
return true;
|
2399
2463
|
}
|
2400
2464
|
}
|
@@ -2402,19 +2466,6 @@ function setup(env) {
|
|
2402
2466
|
return false;
|
2403
2467
|
}
|
2404
2468
|
|
2405
|
-
/**
|
2406
|
-
* Convert regexp to namespace
|
2407
|
-
*
|
2408
|
-
* @param {RegExp} regxep
|
2409
|
-
* @return {String} namespace
|
2410
|
-
* @api private
|
2411
|
-
*/
|
2412
|
-
function toNamespace(regexp) {
|
2413
|
-
return regexp.toString()
|
2414
|
-
.substring(2, regexp.toString().length - 2)
|
2415
|
-
.replace(/\.\*\?$/, '*');
|
2416
|
-
}
|
2417
|
-
|
2418
2469
|
/**
|
2419
2470
|
* Coerce `val`.
|
2420
2471
|
*
|
@@ -2576,6 +2627,7 @@ var common = setup;
|
|
2576
2627
|
|
2577
2628
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
2578
2629
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
2630
|
+
// eslint-disable-next-line no-return-assign
|
2579
2631
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
2580
2632
|
// Is firebug? http://stackoverflow.com/a/398120/376773
|
2581
2633
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
@@ -3016,10 +3068,10 @@ class JacobianPoint {
|
|
3016
3068
|
const cond1 = window % 2 !== 0;
|
3017
3069
|
const cond2 = wbits < 0;
|
3018
3070
|
if (wbits === 0) {
|
3019
|
-
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
3071
|
+
f = f.add(constTimeNegate$1(cond1, precomputes[offset1]));
|
3020
3072
|
}
|
3021
3073
|
else {
|
3022
|
-
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
3074
|
+
p = p.add(constTimeNegate$1(cond2, precomputes[offset2]));
|
3023
3075
|
}
|
3024
3076
|
}
|
3025
3077
|
return { p, f };
|
@@ -3032,8 +3084,8 @@ class JacobianPoint {
|
|
3032
3084
|
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
3033
3085
|
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
3034
3086
|
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
3035
|
-
k1p = constTimeNegate(k1neg, k1p);
|
3036
|
-
k2p = constTimeNegate(k2neg, k2p);
|
3087
|
+
k1p = constTimeNegate$1(k1neg, k1p);
|
3088
|
+
k2p = constTimeNegate$1(k2neg, k2p);
|
3037
3089
|
k2p = new JacobianPoint(mod$1(k2p.x * endo.beta), k2p.y, k2p.z);
|
3038
3090
|
point = k1p.add(k2p);
|
3039
3091
|
fake = f1p.add(f2p);
|
@@ -3065,7 +3117,7 @@ class JacobianPoint {
|
|
3065
3117
|
}
|
3066
3118
|
JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n$7);
|
3067
3119
|
JacobianPoint.ZERO = new JacobianPoint(_0n$5, _1n$7, _0n$5);
|
3068
|
-
function constTimeNegate(condition, item) {
|
3120
|
+
function constTimeNegate$1(condition, item) {
|
3069
3121
|
const neg = item.negate();
|
3070
3122
|
return condition ? neg : item;
|
3071
3123
|
}
|
@@ -4985,7 +5037,7 @@ function parseIPv6(input) {
|
|
4985
5037
|
return parser.new(input).parseWith(() => parser.readIPv6Addr());
|
4986
5038
|
}
|
4987
5039
|
/** Parse `input` into IPv4 or IPv6 bytes. */
|
4988
|
-
function parseIP(input) {
|
5040
|
+
function parseIP(input, mapIPv4ToIPv6 = false) {
|
4989
5041
|
// strip zone index if it is present
|
4990
5042
|
if (input.includes("%")) {
|
4991
5043
|
input = input.split("%")[0];
|
@@ -4993,7 +5045,14 @@ function parseIP(input) {
|
|
4993
5045
|
if (input.length > MAX_IPV6_LENGTH) {
|
4994
5046
|
return undefined;
|
4995
5047
|
}
|
4996
|
-
|
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;
|
4997
5056
|
}
|
4998
5057
|
|
4999
5058
|
/** Check if `input` is IPv4. */
|
@@ -5181,17 +5240,13 @@ function getProtocol(proto) {
|
|
5181
5240
|
throw new Error(`invalid protocol id type: ${typeof proto}`);
|
5182
5241
|
}
|
5183
5242
|
|
5184
|
-
/**
|
5185
|
-
* @packageDocumentation
|
5186
|
-
*
|
5187
|
-
* Provides methods for converting
|
5188
|
-
*/
|
5189
5243
|
getProtocol('ip4');
|
5190
5244
|
getProtocol('ip6');
|
5191
5245
|
getProtocol('ipcidr');
|
5192
5246
|
/**
|
5193
5247
|
* Convert [code,Uint8Array] to string
|
5194
5248
|
*/
|
5249
|
+
// eslint-disable-next-line complexity
|
5195
5250
|
function convertToString(proto, buf) {
|
5196
5251
|
const protocol = getProtocol(proto);
|
5197
5252
|
switch (protocol.code) {
|
@@ -5200,6 +5255,8 @@ function convertToString(proto, buf) {
|
|
5200
5255
|
return bytes2ip(buf);
|
5201
5256
|
case 42: // ipv6zone
|
5202
5257
|
return bytes2str(buf);
|
5258
|
+
case 43: // ipcidr
|
5259
|
+
return toString$6(buf, 'base10');
|
5203
5260
|
case 6: // tcp
|
5204
5261
|
case 273: // udp
|
5205
5262
|
case 33: // dccp
|
@@ -5227,6 +5284,7 @@ function convertToString(proto, buf) {
|
|
5227
5284
|
return toString$6(buf, 'base16'); // no clue. convert to hex
|
5228
5285
|
}
|
5229
5286
|
}
|
5287
|
+
// eslint-disable-next-line complexity
|
5230
5288
|
function convertToBytes(proto, str) {
|
5231
5289
|
const protocol = getProtocol(proto);
|
5232
5290
|
switch (protocol.code) {
|
@@ -5236,6 +5294,8 @@ function convertToBytes(proto, str) {
|
|
5236
5294
|
return ip2bytes(str);
|
5237
5295
|
case 42: // ipv6zone
|
5238
5296
|
return str2bytes(str);
|
5297
|
+
case 43: // ipcidr
|
5298
|
+
return fromString(str, 'base10');
|
5239
5299
|
case 6: // tcp
|
5240
5300
|
case 273: // udp
|
5241
5301
|
case 33: // dccp
|
@@ -5530,20 +5590,7 @@ function ParseError(str) {
|
|
5530
5590
|
return new Error('Error parsing address: ' + str);
|
5531
5591
|
}
|
5532
5592
|
|
5533
|
-
|
5534
|
-
* @packageDocumentation
|
5535
|
-
*
|
5536
|
-
* An implementation of a Multiaddr in JavaScript
|
5537
|
-
*
|
5538
|
-
* @example
|
5539
|
-
*
|
5540
|
-
* ```js
|
5541
|
-
* import { multiaddr } from '@multiformats/multiaddr'
|
5542
|
-
*
|
5543
|
-
* const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
5544
|
-
* ```
|
5545
|
-
*/
|
5546
|
-
const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
|
5593
|
+
const inspect$2 = Symbol.for('nodejs.util.inspect.custom');
|
5547
5594
|
const symbol$1 = Symbol.for('@multiformats/js-multiaddr/multiaddr');
|
5548
5595
|
const DNS_CODES = [
|
5549
5596
|
getProtocol('dns').code,
|
@@ -5654,10 +5701,20 @@ class Multiaddr {
|
|
5654
5701
|
return this.#tuples.map(([code]) => getProtocol(code).name);
|
5655
5702
|
}
|
5656
5703
|
tuples() {
|
5657
|
-
return this.#tuples
|
5704
|
+
return this.#tuples.map(([code, value]) => {
|
5705
|
+
if (value == null) {
|
5706
|
+
return [code];
|
5707
|
+
}
|
5708
|
+
return [code, value];
|
5709
|
+
});
|
5658
5710
|
}
|
5659
5711
|
stringTuples() {
|
5660
|
-
return this.#stringTuples
|
5712
|
+
return this.#stringTuples.map(([code, value]) => {
|
5713
|
+
if (value == null) {
|
5714
|
+
return [code];
|
5715
|
+
}
|
5716
|
+
return [code, value];
|
5717
|
+
});
|
5661
5718
|
}
|
5662
5719
|
encapsulate(addr) {
|
5663
5720
|
addr = new Multiaddr(addr);
|
@@ -5767,7 +5824,7 @@ class Multiaddr {
|
|
5767
5824
|
* // 'Multiaddr(/ip4/127.0.0.1/tcp/4001)'
|
5768
5825
|
* ```
|
5769
5826
|
*/
|
5770
|
-
[inspect$
|
5827
|
+
[inspect$2]() {
|
5771
5828
|
return `Multiaddr(${this.#string})`;
|
5772
5829
|
}
|
5773
5830
|
}
|
@@ -5787,10 +5844,8 @@ class Multiaddr {
|
|
5787
5844
|
*
|
5788
5845
|
* ```TypeScript
|
5789
5846
|
* import { multiaddr } from '@multiformats/multiaddr'
|
5790
|
-
* const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
|
5791
|
-
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5792
5847
|
*
|
5793
|
-
* const addr = multiaddr(
|
5848
|
+
* const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
|
5794
5849
|
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5795
5850
|
*
|
5796
5851
|
* addr.bytes
|
@@ -5829,9 +5884,9 @@ class Multiaddr {
|
|
5829
5884
|
*
|
5830
5885
|
* ```TypeScript
|
5831
5886
|
* import { multiaddr, resolvers } from '@multiformats/multiaddr'
|
5832
|
-
* import {
|
5887
|
+
* import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
5833
5888
|
*
|
5834
|
-
* resolvers.set('dnsaddr',
|
5889
|
+
* resolvers.set('dnsaddr', dnsaddrResolver)
|
5835
5890
|
*
|
5836
5891
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
5837
5892
|
*
|
@@ -5840,7 +5895,7 @@ class Multiaddr {
|
|
5840
5895
|
* signal: AbortSignal.timeout(5000)
|
5841
5896
|
* })
|
5842
5897
|
*
|
5843
|
-
* console.info(
|
5898
|
+
* console.info(resolved)
|
5844
5899
|
* // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
|
5845
5900
|
* ```
|
5846
5901
|
*
|
@@ -5854,7 +5909,9 @@ class Multiaddr {
|
|
5854
5909
|
* import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
|
5855
5910
|
*
|
5856
5911
|
* const resolver = dns({
|
5857
|
-
*
|
5912
|
+
* resolvers: {
|
5913
|
+
* '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
|
5914
|
+
* }
|
5858
5915
|
* })
|
5859
5916
|
*
|
5860
5917
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
@@ -5940,18 +5997,13 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
|
|
5940
5997
|
return multiaddrFromFields(isIpv6 ? "ip6" : "ip4", protoName, ipVal, protoVal);
|
5941
5998
|
}
|
5942
5999
|
|
5943
|
-
|
5944
|
-
|
5945
|
-
|
5946
|
-
|
5947
|
-
|
5948
|
-
typeof thing.catch === 'function' &&
|
5949
|
-
typeof thing.finally === 'function';
|
5950
|
-
}
|
5951
|
-
|
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
|
+
*/
|
5952
6005
|
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
5953
6006
|
const _32n = /* @__PURE__ */ BigInt(32);
|
5954
|
-
// We are not using BigUint64Array, because they are extremely slow as per 2022
|
5955
6007
|
function fromBig(n, le = false) {
|
5956
6008
|
if (le)
|
5957
6009
|
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
@@ -6008,6 +6060,13 @@ const u64 = {
|
|
6008
6060
|
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
6009
6061
|
};
|
6010
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
|
+
*/
|
6011
6070
|
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
6012
6071
|
// prettier-ignore
|
6013
6072
|
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
@@ -6162,8 +6221,13 @@ class SHA512 extends HashMD {
|
|
6162
6221
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
6163
6222
|
}
|
6164
6223
|
}
|
6224
|
+
/** SHA2-512 hash function. */
|
6165
6225
|
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
6166
6226
|
|
6227
|
+
/**
|
6228
|
+
* Hex, bytes and number utilities.
|
6229
|
+
* @module
|
6230
|
+
*/
|
6167
6231
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6168
6232
|
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
6169
6233
|
// This is OK: `abstract` directory does not use noble-hashes.
|
@@ -6173,8 +6237,7 @@ const _0n$4 = /* @__PURE__ */ BigInt(0);
|
|
6173
6237
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
6174
6238
|
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
6175
6239
|
function isBytes$1(a) {
|
6176
|
-
return
|
6177
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
6240
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
6178
6241
|
}
|
6179
6242
|
function abytes(item) {
|
6180
6243
|
if (!isBytes$1(item))
|
@@ -6182,7 +6245,7 @@ function abytes(item) {
|
|
6182
6245
|
}
|
6183
6246
|
function abool(title, value) {
|
6184
6247
|
if (typeof value !== 'boolean')
|
6185
|
-
throw new Error(
|
6248
|
+
throw new Error(title + ' boolean expected, got ' + value);
|
6186
6249
|
}
|
6187
6250
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6188
6251
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
@@ -6200,23 +6263,22 @@ function bytesToHex(bytes) {
|
|
6200
6263
|
}
|
6201
6264
|
function numberToHexUnpadded(num) {
|
6202
6265
|
const hex = num.toString(16);
|
6203
|
-
return hex.length & 1 ?
|
6266
|
+
return hex.length & 1 ? '0' + hex : hex;
|
6204
6267
|
}
|
6205
6268
|
function hexToNumber(hex) {
|
6206
6269
|
if (typeof hex !== 'string')
|
6207
6270
|
throw new Error('hex string expected, got ' + typeof hex);
|
6208
|
-
// Big Endian
|
6209
|
-
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
6271
|
+
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
6210
6272
|
}
|
6211
6273
|
// We use optimized technique to convert hex string to byte array
|
6212
|
-
const asciis = { _0: 48, _9: 57,
|
6213
|
-
function asciiToBase16(
|
6214
|
-
if (
|
6215
|
-
return
|
6216
|
-
if (
|
6217
|
-
return
|
6218
|
-
if (
|
6219
|
-
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)
|
6220
6282
|
return;
|
6221
6283
|
}
|
6222
6284
|
/**
|
@@ -6228,7 +6290,7 @@ function hexToBytes(hex) {
|
|
6228
6290
|
const hl = hex.length;
|
6229
6291
|
const al = hl / 2;
|
6230
6292
|
if (hl % 2)
|
6231
|
-
throw new Error('
|
6293
|
+
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
6232
6294
|
const array = new Uint8Array(al);
|
6233
6295
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
6234
6296
|
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
@@ -6237,7 +6299,7 @@ function hexToBytes(hex) {
|
|
6237
6299
|
const char = hex[hi] + hex[hi + 1];
|
6238
6300
|
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
6239
6301
|
}
|
6240
|
-
array[ai] = n1 * 16 + n2;
|
6302
|
+
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
|
6241
6303
|
}
|
6242
6304
|
return array;
|
6243
6305
|
}
|
@@ -6275,7 +6337,7 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6275
6337
|
res = hexToBytes(hex);
|
6276
6338
|
}
|
6277
6339
|
catch (e) {
|
6278
|
-
throw new Error(
|
6340
|
+
throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
|
6279
6341
|
}
|
6280
6342
|
}
|
6281
6343
|
else if (isBytes$1(hex)) {
|
@@ -6284,11 +6346,11 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6284
6346
|
res = Uint8Array.from(hex);
|
6285
6347
|
}
|
6286
6348
|
else {
|
6287
|
-
throw new Error(
|
6349
|
+
throw new Error(title + ' must be hex string or Uint8Array');
|
6288
6350
|
}
|
6289
6351
|
const len = res.length;
|
6290
6352
|
if (typeof expectedLength === 'number' && len !== expectedLength)
|
6291
|
-
throw new Error(
|
6353
|
+
throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
|
6292
6354
|
return res;
|
6293
6355
|
}
|
6294
6356
|
/**
|
@@ -6323,7 +6385,7 @@ function equalBytes(a, b) {
|
|
6323
6385
|
*/
|
6324
6386
|
function utf8ToBytes(str) {
|
6325
6387
|
if (typeof str !== 'string')
|
6326
|
-
throw new Error(
|
6388
|
+
throw new Error('string expected');
|
6327
6389
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6328
6390
|
}
|
6329
6391
|
// Is positive bigint
|
@@ -6343,7 +6405,7 @@ function aInRange(title, n, min, max) {
|
|
6343
6405
|
// - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
|
6344
6406
|
// - our way is the cleanest: `inRange('x', x, 0n, P)
|
6345
6407
|
if (!inRange(n, min, max))
|
6346
|
-
throw new Error(
|
6408
|
+
throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);
|
6347
6409
|
}
|
6348
6410
|
// Bit operations
|
6349
6411
|
/**
|
@@ -6453,12 +6515,12 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6453
6515
|
const checkField = (fieldName, type, isOptional) => {
|
6454
6516
|
const checkVal = validatorFns[type];
|
6455
6517
|
if (typeof checkVal !== 'function')
|
6456
|
-
throw new Error(
|
6518
|
+
throw new Error('invalid validator function');
|
6457
6519
|
const val = object[fieldName];
|
6458
6520
|
if (isOptional && val === undefined)
|
6459
6521
|
return;
|
6460
6522
|
if (!checkVal(val, object)) {
|
6461
|
-
throw new Error(
|
6523
|
+
throw new Error('param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val);
|
6462
6524
|
}
|
6463
6525
|
};
|
6464
6526
|
for (const [fieldName, type] of Object.entries(validators))
|
@@ -6527,14 +6589,17 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6527
6589
|
validateObject: validateObject
|
6528
6590
|
});
|
6529
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
|
+
*/
|
6530
6598
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6531
|
-
// Utilities for modular arithmetics and finite fields
|
6532
|
-
// prettier-ignore
|
6533
|
-
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
|
6534
6599
|
// prettier-ignore
|
6535
|
-
const
|
6600
|
+
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = /* @__PURE__ */ BigInt(2), _3n$1 = /* @__PURE__ */ BigInt(3);
|
6536
6601
|
// prettier-ignore
|
6537
|
-
BigInt(
|
6602
|
+
const _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _8n$2 = /* @__PURE__ */ BigInt(8);
|
6538
6603
|
// Calculates a modulo b
|
6539
6604
|
function mod(a, b) {
|
6540
6605
|
const result = a % b;
|
@@ -6543,13 +6608,15 @@ function mod(a, b) {
|
|
6543
6608
|
/**
|
6544
6609
|
* Efficiently raise num to power and do modular division.
|
6545
6610
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
6611
|
+
* @todo use field version && remove
|
6546
6612
|
* @example
|
6547
6613
|
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
6548
6614
|
*/
|
6549
|
-
// TODO: use field version && remove
|
6550
6615
|
function pow(num, power, modulo) {
|
6551
|
-
if (
|
6552
|
-
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');
|
6553
6620
|
if (modulo === _1n$5)
|
6554
6621
|
return _0n$3;
|
6555
6622
|
let res = _1n$5;
|
@@ -6561,7 +6628,7 @@ function pow(num, power, modulo) {
|
|
6561
6628
|
}
|
6562
6629
|
return res;
|
6563
6630
|
}
|
6564
|
-
|
6631
|
+
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
6565
6632
|
function pow2(x, power, modulo) {
|
6566
6633
|
let res = x;
|
6567
6634
|
while (power-- > _0n$3) {
|
@@ -6570,12 +6637,15 @@ function pow2(x, power, modulo) {
|
|
6570
6637
|
}
|
6571
6638
|
return res;
|
6572
6639
|
}
|
6573
|
-
|
6640
|
+
/**
|
6641
|
+
* Inverses number over modulo.
|
6642
|
+
* Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).
|
6643
|
+
*/
|
6574
6644
|
function invert(number, modulo) {
|
6575
|
-
if (number === _0n$3
|
6576
|
-
throw new Error(
|
6577
|
-
|
6578
|
-
|
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);
|
6579
6649
|
// Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
|
6580
6650
|
let a = mod(number, modulo);
|
6581
6651
|
let b = modulo;
|
@@ -6615,8 +6685,11 @@ function tonelliShanks(P) {
|
|
6615
6685
|
for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
|
6616
6686
|
;
|
6617
6687
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
6618
|
-
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++)
|
6619
|
-
|
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
|
+
}
|
6620
6693
|
// Fast-path
|
6621
6694
|
if (S === 1) {
|
6622
6695
|
const p1div4 = (P + _1n$5) / _4n;
|
@@ -6658,9 +6731,18 @@ function tonelliShanks(P) {
|
|
6658
6731
|
return x;
|
6659
6732
|
};
|
6660
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
|
+
*/
|
6661
6745
|
function FpSqrt(P) {
|
6662
|
-
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
6663
|
-
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
6664
6746
|
// P ≡ 3 (mod 4)
|
6665
6747
|
// √n = n^((P+1)/4)
|
6666
6748
|
if (P % _4n === _3n$1) {
|
@@ -6724,7 +6806,7 @@ function FpPow(f, num, power) {
|
|
6724
6806
|
// Should have same speed as pow for bigints
|
6725
6807
|
// TODO: benchmark!
|
6726
6808
|
if (power < _0n$3)
|
6727
|
-
throw new Error('
|
6809
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6728
6810
|
if (power === _0n$3)
|
6729
6811
|
return f.ONE;
|
6730
6812
|
if (power === _1n$5)
|
@@ -6771,15 +6853,15 @@ function nLength(n, nBitLength) {
|
|
6771
6853
|
return { nBitLength: _nBitLength, nByteLength };
|
6772
6854
|
}
|
6773
6855
|
/**
|
6774
|
-
* Initializes a finite field over prime.
|
6775
|
-
* Do not init in loop: slow. Very fragile: always run a benchmark on a change.
|
6856
|
+
* Initializes a finite field over prime.
|
6776
6857
|
* Major performance optimizations:
|
6777
6858
|
* * a) denormalized operations like mulN instead of mul
|
6778
6859
|
* * b) same object shape: never add or remove keys
|
6779
6860
|
* * c) Object.freeze
|
6780
|
-
*
|
6861
|
+
* Fragile: always run a benchmark on a change.
|
6862
|
+
* Security note: operations don't check 'isValid' for all elements for performance reasons,
|
6781
6863
|
* it is caller responsibility to check this.
|
6782
|
-
* 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.
|
6783
6865
|
* @param ORDER prime positive bigint
|
6784
6866
|
* @param bitLen how many bits the field consumes
|
6785
6867
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6787,13 +6869,14 @@ function nLength(n, nBitLength) {
|
|
6787
6869
|
*/
|
6788
6870
|
function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
6789
6871
|
if (ORDER <= _0n$3)
|
6790
|
-
throw new Error(
|
6872
|
+
throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
|
6791
6873
|
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
6792
6874
|
if (BYTES > 2048)
|
6793
|
-
throw new Error('
|
6794
|
-
|
6875
|
+
throw new Error('invalid field: expected ORDER of <= 2048 bytes');
|
6876
|
+
let sqrtP; // cached sqrtP
|
6795
6877
|
const f = Object.freeze({
|
6796
6878
|
ORDER,
|
6879
|
+
isLE,
|
6797
6880
|
BITS,
|
6798
6881
|
BYTES,
|
6799
6882
|
MASK: bitMask(BITS),
|
@@ -6802,7 +6885,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6802
6885
|
create: (num) => mod(num, ORDER),
|
6803
6886
|
isValid: (num) => {
|
6804
6887
|
if (typeof num !== 'bigint')
|
6805
|
-
throw new Error(
|
6888
|
+
throw new Error('invalid field element: expected bigint, got ' + typeof num);
|
6806
6889
|
return _0n$3 <= num && num < ORDER; // 0 is valid element, but it's not invertible
|
6807
6890
|
},
|
6808
6891
|
is0: (num) => num === _0n$3,
|
@@ -6821,7 +6904,12 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6821
6904
|
subN: (lhs, rhs) => lhs - rhs,
|
6822
6905
|
mulN: (lhs, rhs) => lhs * rhs,
|
6823
6906
|
inv: (num) => invert(num, ORDER),
|
6824
|
-
sqrt: redef.sqrt ||
|
6907
|
+
sqrt: redef.sqrt ||
|
6908
|
+
((n) => {
|
6909
|
+
if (!sqrtP)
|
6910
|
+
sqrtP = FpSqrt(ORDER);
|
6911
|
+
return sqrtP(f, n);
|
6912
|
+
}),
|
6825
6913
|
invertBatch: (lst) => FpInvertBatch(f, lst),
|
6826
6914
|
// TODO: do we really need constant cmov?
|
6827
6915
|
// We don't have const-time bigints anyway, so probably will be not very useful
|
@@ -6829,7 +6917,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6829
6917
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
6830
6918
|
fromBytes: (bytes) => {
|
6831
6919
|
if (bytes.length !== BYTES)
|
6832
|
-
throw new Error(
|
6920
|
+
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
6833
6921
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
6834
6922
|
},
|
6835
6923
|
});
|
@@ -6877,52 +6965,80 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6877
6965
|
const minLen = getMinHashLength(fieldOrder);
|
6878
6966
|
// No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.
|
6879
6967
|
if (len < 16 || len < minLen || len > 1024)
|
6880
|
-
throw new Error(
|
6881
|
-
const num = isLE ?
|
6968
|
+
throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
|
6969
|
+
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
6882
6970
|
// `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
|
6883
6971
|
const reduced = mod(num, fieldOrder - _1n$5) + _1n$5;
|
6884
6972
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
6885
6973
|
}
|
6886
6974
|
|
6975
|
+
/**
|
6976
|
+
* Methods for elliptic curve multiplication by scalars.
|
6977
|
+
* Contains wNAF, pippenger
|
6978
|
+
* @module
|
6979
|
+
*/
|
6887
6980
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6888
|
-
// Abelian group utilities
|
6889
6981
|
const _0n$2 = BigInt(0);
|
6890
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
|
+
}
|
6891
7013
|
// Since points in different groups cannot be equal (different object constructor),
|
6892
7014
|
// we can have single place to store precomputes
|
6893
7015
|
const pointPrecomputes = new WeakMap();
|
6894
7016
|
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
6895
|
-
|
6896
|
-
|
6897
|
-
|
6898
|
-
|
6899
|
-
|
6900
|
-
|
6901
|
-
|
6902
|
-
|
6903
|
-
|
6904
|
-
|
6905
|
-
|
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
|
+
*/
|
6906
7034
|
function wNAF(c, bits) {
|
6907
|
-
const constTimeNegate = (condition, item) => {
|
6908
|
-
const neg = item.negate();
|
6909
|
-
return condition ? neg : item;
|
6910
|
-
};
|
6911
|
-
const validateW = (W) => {
|
6912
|
-
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6913
|
-
throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
|
6914
|
-
};
|
6915
|
-
const opts = (W) => {
|
6916
|
-
validateW(W);
|
6917
|
-
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6918
|
-
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6919
|
-
return { windows, windowSize };
|
6920
|
-
};
|
6921
7035
|
return {
|
6922
7036
|
constTimeNegate,
|
7037
|
+
hasPrecomputes(elm) {
|
7038
|
+
return getW(elm) !== 1;
|
7039
|
+
},
|
6923
7040
|
// non-const time multiplication ladder
|
6924
|
-
unsafeLadder(elm, n) {
|
6925
|
-
let p = c.ZERO;
|
7041
|
+
unsafeLadder(elm, n, p = c.ZERO) {
|
6926
7042
|
let d = elm;
|
6927
7043
|
while (n > _0n$2) {
|
6928
7044
|
if (n & _1n$4)
|
@@ -6940,10 +7056,12 @@ function wNAF(c, bits) {
|
|
6940
7056
|
* - 𝑊 is the window size
|
6941
7057
|
* - 𝑛 is the bitlength of the curve order.
|
6942
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
|
6943
7061
|
* @returns precomputed point tables flattened to a single array
|
6944
7062
|
*/
|
6945
7063
|
precomputeWindow(elm, W) {
|
6946
|
-
const { windows, windowSize } =
|
7064
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6947
7065
|
const points = [];
|
6948
7066
|
let p = elm;
|
6949
7067
|
let base = p;
|
@@ -6969,7 +7087,7 @@ function wNAF(c, bits) {
|
|
6969
7087
|
wNAF(W, precomputes, n) {
|
6970
7088
|
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
6971
7089
|
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
6972
|
-
const { windows, windowSize } =
|
7090
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6973
7091
|
let p = c.ZERO;
|
6974
7092
|
let f = c.BASE;
|
6975
7093
|
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
@@ -7013,8 +7131,44 @@ function wNAF(c, bits) {
|
|
7013
7131
|
// which makes it less const-time: around 1 bigint multiply.
|
7014
7132
|
return { p, f };
|
7015
7133
|
},
|
7016
|
-
|
7017
|
-
|
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) {
|
7018
7172
|
// Calculate precomputes on a first run, reuse them after
|
7019
7173
|
let comp = pointPrecomputes.get(P);
|
7020
7174
|
if (!comp) {
|
@@ -7022,62 +7176,66 @@ function wNAF(c, bits) {
|
|
7022
7176
|
if (W !== 1)
|
7023
7177
|
pointPrecomputes.set(P, transform(comp));
|
7024
7178
|
}
|
7025
|
-
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);
|
7026
7190
|
},
|
7027
7191
|
// We calculate precomputes for elliptic curve point multiplication
|
7028
7192
|
// using windowed method. This specifies window size and
|
7029
7193
|
// stores precomputed values. Usually only base point would be precomputed.
|
7030
7194
|
setWindowSize(P, W) {
|
7031
|
-
validateW(W);
|
7195
|
+
validateW(W, bits);
|
7032
7196
|
pointWindowSizes.set(P, W);
|
7033
7197
|
pointPrecomputes.delete(P);
|
7034
7198
|
},
|
7035
7199
|
};
|
7036
7200
|
}
|
7037
7201
|
/**
|
7038
|
-
* Pippenger algorithm for multi-scalar multiplication (MSM).
|
7039
|
-
* MSM is basically (Pa + Qb + Rc + ...).
|
7202
|
+
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
7040
7203
|
* 30x faster vs naive addition on L=4096, 10x faster with precomputes.
|
7041
7204
|
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
7042
7205
|
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
7043
7206
|
* @param c Curve Point constructor
|
7044
|
-
* @param
|
7207
|
+
* @param fieldN field over CURVE.N - important that it's not over CURVE.P
|
7045
7208
|
* @param points array of L curve points
|
7046
7209
|
* @param scalars array of L scalars (aka private keys / bigints)
|
7047
7210
|
*/
|
7048
|
-
function pippenger(c,
|
7211
|
+
function pippenger(c, fieldN, points, scalars) {
|
7049
7212
|
// If we split scalars by some window (let's say 8 bits), every chunk will only
|
7050
7213
|
// take 256 buckets even if there are 4096 scalars, also re-uses double.
|
7051
7214
|
// TODO:
|
7052
7215
|
// - https://eprint.iacr.org/2024/750.pdf
|
7053
7216
|
// - https://tches.iacr.org/index.php/TCHES/article/view/10287
|
7054
7217
|
// 0 is accepted in scalars
|
7055
|
-
|
7218
|
+
validateMSMPoints(points, c);
|
7219
|
+
validateMSMScalars(scalars, fieldN);
|
7220
|
+
if (points.length !== scalars.length)
|
7056
7221
|
throw new Error('arrays of points and scalars must have equal length');
|
7057
|
-
|
7058
|
-
if (!field.isValid(s))
|
7059
|
-
throw new Error(`wrong scalar at index ${i}`);
|
7060
|
-
});
|
7061
|
-
points.forEach((p, i) => {
|
7062
|
-
if (!(p instanceof c))
|
7063
|
-
throw new Error(`wrong point at index ${i}`);
|
7064
|
-
});
|
7222
|
+
const zero = c.ZERO;
|
7065
7223
|
const wbits = bitLen(BigInt(points.length));
|
7066
7224
|
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
7067
7225
|
const MASK = (1 << windowSize) - 1;
|
7068
|
-
const buckets = new Array(MASK + 1).fill(
|
7069
|
-
const lastBits = Math.floor((
|
7070
|
-
let sum =
|
7226
|
+
const buckets = new Array(MASK + 1).fill(zero); // +1 for zero array
|
7227
|
+
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
7228
|
+
let sum = zero;
|
7071
7229
|
for (let i = lastBits; i >= 0; i -= windowSize) {
|
7072
|
-
buckets.fill(
|
7230
|
+
buckets.fill(zero);
|
7073
7231
|
for (let j = 0; j < scalars.length; j++) {
|
7074
7232
|
const scalar = scalars[j];
|
7075
7233
|
const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
|
7076
7234
|
buckets[wbits] = buckets[wbits].add(points[j]);
|
7077
7235
|
}
|
7078
|
-
let resI =
|
7236
|
+
let resI = zero; // not using this will do small speed-up, but will lose ct
|
7079
7237
|
// Skip first bucket, because it is zero
|
7080
|
-
for (let j = buckets.length - 1, sumI =
|
7238
|
+
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
7081
7239
|
sumI = sumI.add(buckets[j]);
|
7082
7240
|
resI = resI.add(sumI);
|
7083
7241
|
}
|
@@ -7107,8 +7265,12 @@ function validateBasic(curve) {
|
|
7107
7265
|
});
|
7108
7266
|
}
|
7109
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
|
+
*/
|
7110
7273
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7111
|
-
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
7112
7274
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
7113
7275
|
// prettier-ignore
|
7114
7276
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -7140,6 +7302,10 @@ function validateOpts$1(curve) {
|
|
7140
7302
|
function twistedEdwards(curveDef) {
|
7141
7303
|
const CURVE = validateOpts$1(curveDef);
|
7142
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.
|
7143
7309
|
const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
|
7144
7310
|
const modP = Fp.create; // Function overrides
|
7145
7311
|
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
@@ -7353,16 +7519,15 @@ function twistedEdwards(curveDef) {
|
|
7353
7519
|
// It's faster, but should only be used when you don't care about
|
7354
7520
|
// an exposed private key e.g. sig verification.
|
7355
7521
|
// Does NOT allow scalars higher than CURVE.n.
|
7356
|
-
|
7522
|
+
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
7523
|
+
multiplyUnsafe(scalar, acc = Point.ZERO) {
|
7357
7524
|
const n = scalar;
|
7358
7525
|
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7359
7526
|
if (n === _0n$1)
|
7360
7527
|
return I;
|
7361
|
-
if (this.
|
7528
|
+
if (this.is0() || n === _1n$3)
|
7362
7529
|
return this;
|
7363
|
-
|
7364
|
-
return this.wNAF(n).p;
|
7365
|
-
return wnaf.unsafeLadder(this, n);
|
7530
|
+
return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
|
7366
7531
|
}
|
7367
7532
|
// Checks if point is of small order.
|
7368
7533
|
// If you add something to small order point, you will have "dirty"
|
@@ -7396,8 +7561,9 @@ function twistedEdwards(curveDef) {
|
|
7396
7561
|
abool('zip215', zip215);
|
7397
7562
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7398
7563
|
const lastByte = hex[len - 1]; // select last byte
|
7399
|
-
normed[len - 1] = lastByte &
|
7564
|
+
normed[len - 1] = lastByte & -129; // clear last bit
|
7400
7565
|
const y = bytesToNumberLE(normed);
|
7566
|
+
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
7401
7567
|
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
7402
7568
|
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7403
7569
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
@@ -7446,7 +7612,7 @@ function twistedEdwards(curveDef) {
|
|
7446
7612
|
}
|
7447
7613
|
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
7448
7614
|
function getExtendedPublicKey(key) {
|
7449
|
-
const len =
|
7615
|
+
const len = Fp.BYTES;
|
7450
7616
|
key = ensureBytes('private key', key, len);
|
7451
7617
|
// Hash private key with curve's hash function to produce uniformingly random input
|
7452
7618
|
// Check byte lengths: ensure(64, h(ensure(32, key)))
|
@@ -7479,23 +7645,29 @@ function twistedEdwards(curveDef) {
|
|
7479
7645
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7480
7646
|
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7481
7647
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7482
|
-
return ensureBytes('result', res,
|
7648
|
+
return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
|
7483
7649
|
}
|
7484
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
|
+
*/
|
7485
7655
|
function verify(sig, msg, publicKey, options = verifyOpts) {
|
7486
7656
|
const { context, zip215 } = options;
|
7487
7657
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7488
7658
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7489
7659
|
msg = ensureBytes('message', msg);
|
7660
|
+
publicKey = ensureBytes('publicKey', publicKey, len);
|
7490
7661
|
if (zip215 !== undefined)
|
7491
7662
|
abool('zip215', zip215);
|
7492
7663
|
if (prehash)
|
7493
7664
|
msg = prehash(msg); // for ed25519ph, etc
|
7494
7665
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
7495
|
-
// zip215: true is good for consensus-critical apps and allows points < 2^256
|
7496
|
-
// zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
|
7497
7666
|
let A, R, SB;
|
7498
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)
|
7499
7671
|
A = Point.fromHex(publicKey, zip215);
|
7500
7672
|
R = Point.fromHex(sig.slice(0, len), zip215);
|
7501
7673
|
SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
|
@@ -7507,6 +7679,7 @@ function twistedEdwards(curveDef) {
|
|
7507
7679
|
return false;
|
7508
7680
|
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
7509
7681
|
const RkA = R.add(A.multiplyUnsafe(k));
|
7682
|
+
// Extended group equation
|
7510
7683
|
// [8][S]B = [8]R + [8][k]A'
|
7511
7684
|
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
7512
7685
|
}
|
@@ -7537,13 +7710,14 @@ function twistedEdwards(curveDef) {
|
|
7537
7710
|
};
|
7538
7711
|
}
|
7539
7712
|
|
7540
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7541
7713
|
/**
|
7542
7714
|
* ed25519 Twisted Edwards curve with following addons:
|
7543
7715
|
* - X25519 ECDH
|
7544
7716
|
* - Ristretto cofactor elimination
|
7545
7717
|
* - Elligator hash-to-group / point indistinguishability
|
7718
|
+
* @module
|
7546
7719
|
*/
|
7720
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7547
7721
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7548
7722
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
7549
7723
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
@@ -7602,7 +7776,7 @@ function uvRatio(u, v) {
|
|
7602
7776
|
x = mod(-x, P);
|
7603
7777
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7604
7778
|
}
|
7605
|
-
const Fp
|
7779
|
+
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7606
7780
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7607
7781
|
// Param: a
|
7608
7782
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
@@ -7610,7 +7784,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7610
7784
|
// Negative number is P - number, and division is invert(number, P)
|
7611
7785
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
7612
7786
|
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
7613
|
-
Fp
|
7787
|
+
Fp,
|
7614
7788
|
// Subgroup order: how many points curve has
|
7615
7789
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7616
7790
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
@@ -7620,7 +7794,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7620
7794
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
7621
7795
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
7622
7796
|
hash: sha512,
|
7623
|
-
randomBytes
|
7797
|
+
randomBytes,
|
7624
7798
|
adjustScalarBytes,
|
7625
7799
|
// dom2
|
7626
7800
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
@@ -7629,180 +7803,58 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7629
7803
|
}))();
|
7630
7804
|
/**
|
7631
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
|
7632
7814
|
*/
|
7633
7815
|
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7634
7816
|
|
7635
7817
|
const PUBLIC_KEY_BYTE_LENGTH = 32;
|
7636
|
-
const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
7637
|
-
const KEYS_BYTE_LENGTH = 32;
|
7638
|
-
function generateKey$2() {
|
7639
|
-
// the actual private key (32 bytes)
|
7640
|
-
const privateKeyRaw = ed25519.utils.randomPrivateKey();
|
7641
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7642
|
-
// concatenated the public key to the private key
|
7643
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7644
|
-
return {
|
7645
|
-
privateKey,
|
7646
|
-
publicKey
|
7647
|
-
};
|
7648
|
-
}
|
7649
|
-
/**
|
7650
|
-
* Generate keypair from a 32 byte uint8array
|
7651
|
-
*/
|
7652
|
-
function generateKeyFromSeed(seed) {
|
7653
|
-
if (seed.length !== KEYS_BYTE_LENGTH) {
|
7654
|
-
throw new TypeError('"seed" must be 32 bytes in length.');
|
7655
|
-
}
|
7656
|
-
else if (!(seed instanceof Uint8Array)) {
|
7657
|
-
throw new TypeError('"seed" must be a node.js Buffer, or Uint8Array.');
|
7658
|
-
}
|
7659
|
-
// based on node forges algorithm, the seed is used directly as private key
|
7660
|
-
const privateKeyRaw = seed;
|
7661
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7662
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7663
|
-
return {
|
7664
|
-
privateKey,
|
7665
|
-
publicKey
|
7666
|
-
};
|
7667
|
-
}
|
7668
|
-
function hashAndSign$2(privateKey, msg) {
|
7669
|
-
const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH);
|
7670
|
-
return ed25519.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw);
|
7671
|
-
}
|
7672
7818
|
function hashAndVerify$2(publicKey, sig, msg) {
|
7673
7819
|
return ed25519.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey);
|
7674
7820
|
}
|
7675
|
-
function concatKeys(privateKeyRaw, publicKey) {
|
7676
|
-
const privateKey = new Uint8Array(PRIVATE_KEY_BYTE_LENGTH);
|
7677
|
-
for (let i = 0; i < KEYS_BYTE_LENGTH; i++) {
|
7678
|
-
privateKey[i] = privateKeyRaw[i];
|
7679
|
-
privateKey[KEYS_BYTE_LENGTH + i] = publicKey[i];
|
7680
|
-
}
|
7681
|
-
return privateKey;
|
7682
|
-
}
|
7683
7821
|
|
7684
|
-
|
7685
|
-
|
7686
|
-
|
7687
|
-
|
7688
|
-
|
7689
|
-
const nativeCrypto = win.crypto;
|
7690
|
-
if (nativeCrypto?.subtle == null) {
|
7691
|
-
throw Object.assign(new Error('Missing Web Crypto API. ' +
|
7692
|
-
'The most likely cause of this error is that this page is being accessed ' +
|
7693
|
-
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
7694
|
-
'possible resolutions see ' +
|
7695
|
-
'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api'), { code: 'ERR_MISSING_WEB_CRYPTO' });
|
7696
|
-
}
|
7697
|
-
return nativeCrypto;
|
7822
|
+
class Ed25519PublicKey {
|
7823
|
+
type = 'Ed25519';
|
7824
|
+
raw;
|
7825
|
+
constructor(key) {
|
7826
|
+
this.raw = ensureEd25519Key(key, PUBLIC_KEY_BYTE_LENGTH);
|
7698
7827
|
}
|
7699
|
-
|
7700
|
-
|
7701
|
-
// WebKit on Linux does not support deriving a key from an empty PBKDF2 key.
|
7702
|
-
// So, as a workaround, we provide the generated key as a constant. We test that
|
7703
|
-
// this generated key is accurate in test/workaround.spec.ts
|
7704
|
-
// Generated via:
|
7705
|
-
// await crypto.subtle.exportKey('jwk',
|
7706
|
-
// await crypto.subtle.deriveKey(
|
7707
|
-
// { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } },
|
7708
|
-
// await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']),
|
7709
|
-
// { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt'])
|
7710
|
-
// )
|
7711
|
-
const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
|
7712
|
-
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
|
7713
|
-
function create(opts) {
|
7714
|
-
const algorithm = 'AES-GCM';
|
7715
|
-
let keyLength = 16;
|
7716
|
-
const nonceLength = 12;
|
7717
|
-
const digest = 'SHA-256';
|
7718
|
-
const saltLength = 16;
|
7719
|
-
const iterations = 32767;
|
7720
|
-
const crypto = webcrypto.get();
|
7721
|
-
keyLength *= 8; // Browser crypto uses bits instead of bytes
|
7722
|
-
/**
|
7723
|
-
* Uses the provided password to derive a pbkdf2 key. The key
|
7724
|
-
* will then be used to encrypt the data.
|
7725
|
-
*/
|
7726
|
-
async function encrypt(data, password) {
|
7727
|
-
const salt = crypto.getRandomValues(new Uint8Array(saltLength));
|
7728
|
-
const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
|
7729
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7730
|
-
if (typeof password === 'string') {
|
7731
|
-
password = fromString(password);
|
7732
|
-
}
|
7733
|
-
let cryptoKey;
|
7734
|
-
if (password.length === 0) {
|
7735
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7736
|
-
try {
|
7737
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7738
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7739
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7740
|
-
}
|
7741
|
-
catch {
|
7742
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7743
|
-
}
|
7744
|
-
}
|
7745
|
-
else {
|
7746
|
-
// Derive a key using PBKDF2.
|
7747
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7748
|
-
const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7749
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7750
|
-
}
|
7751
|
-
// Encrypt the string.
|
7752
|
-
const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data);
|
7753
|
-
return concat$1([salt, aesGcm.iv, new Uint8Array(ciphertext)]);
|
7828
|
+
toMultihash() {
|
7829
|
+
return identity.digest(publicKeyToProtobuf(this));
|
7754
7830
|
}
|
7755
|
-
|
7756
|
-
|
7757
|
-
|
7758
|
-
|
7759
|
-
|
7760
|
-
|
7761
|
-
|
7762
|
-
|
7763
|
-
|
7764
|
-
const ciphertext = data.subarray(saltLength + nonceLength);
|
7765
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7766
|
-
if (typeof password === 'string') {
|
7767
|
-
password = fromString(password);
|
7768
|
-
}
|
7769
|
-
let cryptoKey;
|
7770
|
-
if (password.length === 0) {
|
7771
|
-
try {
|
7772
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7773
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7774
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['decrypt']);
|
7775
|
-
}
|
7776
|
-
catch {
|
7777
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']);
|
7778
|
-
}
|
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;
|
7779
7840
|
}
|
7780
|
-
|
7781
|
-
|
7782
|
-
|
7783
|
-
|
7784
|
-
|
7785
|
-
}
|
7786
|
-
// Decrypt the string.
|
7787
|
-
const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext);
|
7788
|
-
return new Uint8Array(plaintext);
|
7789
|
-
}
|
7790
|
-
const cipher = {
|
7791
|
-
encrypt,
|
7792
|
-
decrypt
|
7793
|
-
};
|
7794
|
-
return cipher;
|
7841
|
+
return equals(this.raw, key.raw);
|
7842
|
+
}
|
7843
|
+
verify(data, sig) {
|
7844
|
+
return hashAndVerify$2(this.raw, sig, data);
|
7845
|
+
}
|
7795
7846
|
}
|
7796
7847
|
|
7797
|
-
|
7798
|
-
|
7799
|
-
|
7800
|
-
|
7801
|
-
|
7802
|
-
|
7803
|
-
|
7804
|
-
|
7805
|
-
|
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;
|
7806
7858
|
}
|
7807
7859
|
|
7808
7860
|
const f32 = new Float32Array([-0]);
|
@@ -9035,13 +9087,13 @@ var KeyType;
|
|
9035
9087
|
(function (KeyType) {
|
9036
9088
|
KeyType["RSA"] = "RSA";
|
9037
9089
|
KeyType["Ed25519"] = "Ed25519";
|
9038
|
-
KeyType["
|
9090
|
+
KeyType["secp256k1"] = "secp256k1";
|
9039
9091
|
})(KeyType || (KeyType = {}));
|
9040
9092
|
var __KeyTypeValues;
|
9041
9093
|
(function (__KeyTypeValues) {
|
9042
9094
|
__KeyTypeValues[__KeyTypeValues["RSA"] = 0] = "RSA";
|
9043
9095
|
__KeyTypeValues[__KeyTypeValues["Ed25519"] = 1] = "Ed25519";
|
9044
|
-
__KeyTypeValues[__KeyTypeValues["
|
9096
|
+
__KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1";
|
9045
9097
|
})(__KeyTypeValues || (__KeyTypeValues = {}));
|
9046
9098
|
(function (KeyType) {
|
9047
9099
|
KeyType.codec = () => {
|
@@ -9068,21 +9120,24 @@ var PublicKey;
|
|
9068
9120
|
if (opts.lengthDelimited !== false) {
|
9069
9121
|
w.ldelim();
|
9070
9122
|
}
|
9071
|
-
}, (reader, length) => {
|
9123
|
+
}, (reader, length, opts = {}) => {
|
9072
9124
|
const obj = {};
|
9073
9125
|
const end = length == null ? reader.len : reader.pos + length;
|
9074
9126
|
while (reader.pos < end) {
|
9075
9127
|
const tag = reader.uint32();
|
9076
9128
|
switch (tag >>> 3) {
|
9077
|
-
case 1:
|
9129
|
+
case 1: {
|
9078
9130
|
obj.Type = KeyType.codec().decode(reader);
|
9079
9131
|
break;
|
9080
|
-
|
9132
|
+
}
|
9133
|
+
case 2: {
|
9081
9134
|
obj.Data = reader.bytes();
|
9082
9135
|
break;
|
9083
|
-
|
9136
|
+
}
|
9137
|
+
default: {
|
9084
9138
|
reader.skipType(tag & 7);
|
9085
9139
|
break;
|
9140
|
+
}
|
9086
9141
|
}
|
9087
9142
|
}
|
9088
9143
|
return obj;
|
@@ -9093,8 +9148,8 @@ var PublicKey;
|
|
9093
9148
|
PublicKey.encode = (obj) => {
|
9094
9149
|
return encodeMessage(obj, PublicKey.codec());
|
9095
9150
|
};
|
9096
|
-
PublicKey.decode = (buf) => {
|
9097
|
-
return decodeMessage(buf, PublicKey.codec());
|
9151
|
+
PublicKey.decode = (buf, opts) => {
|
9152
|
+
return decodeMessage(buf, PublicKey.codec(), opts);
|
9098
9153
|
};
|
9099
9154
|
})(PublicKey || (PublicKey = {}));
|
9100
9155
|
var PrivateKey;
|
@@ -9117,21 +9172,24 @@ var PrivateKey;
|
|
9117
9172
|
if (opts.lengthDelimited !== false) {
|
9118
9173
|
w.ldelim();
|
9119
9174
|
}
|
9120
|
-
}, (reader, length) => {
|
9175
|
+
}, (reader, length, opts = {}) => {
|
9121
9176
|
const obj = {};
|
9122
9177
|
const end = length == null ? reader.len : reader.pos + length;
|
9123
9178
|
while (reader.pos < end) {
|
9124
9179
|
const tag = reader.uint32();
|
9125
9180
|
switch (tag >>> 3) {
|
9126
|
-
case 1:
|
9181
|
+
case 1: {
|
9127
9182
|
obj.Type = KeyType.codec().decode(reader);
|
9128
9183
|
break;
|
9129
|
-
|
9184
|
+
}
|
9185
|
+
case 2: {
|
9130
9186
|
obj.Data = reader.bytes();
|
9131
9187
|
break;
|
9132
|
-
|
9188
|
+
}
|
9189
|
+
default: {
|
9133
9190
|
reader.skipType(tag & 7);
|
9134
9191
|
break;
|
9192
|
+
}
|
9135
9193
|
}
|
9136
9194
|
}
|
9137
9195
|
return obj;
|
@@ -9142,290 +9200,15 @@ var PrivateKey;
|
|
9142
9200
|
PrivateKey.encode = (obj) => {
|
9143
9201
|
return encodeMessage(obj, PrivateKey.codec());
|
9144
9202
|
};
|
9145
|
-
PrivateKey.decode = (buf) => {
|
9146
|
-
return decodeMessage(buf, PrivateKey.codec());
|
9203
|
+
PrivateKey.decode = (buf, opts) => {
|
9204
|
+
return decodeMessage(buf, PrivateKey.codec(), opts);
|
9147
9205
|
};
|
9148
9206
|
})(PrivateKey || (PrivateKey = {}));
|
9149
9207
|
|
9150
|
-
class Ed25519PublicKey {
|
9151
|
-
_key;
|
9152
|
-
constructor(key) {
|
9153
|
-
this._key = ensureKey(key, PUBLIC_KEY_BYTE_LENGTH);
|
9154
|
-
}
|
9155
|
-
verify(data, sig) {
|
9156
|
-
return hashAndVerify$2(this._key, sig, data);
|
9157
|
-
}
|
9158
|
-
marshal() {
|
9159
|
-
return this._key;
|
9160
|
-
}
|
9161
|
-
get bytes() {
|
9162
|
-
return PublicKey.encode({
|
9163
|
-
Type: KeyType.Ed25519,
|
9164
|
-
Data: this.marshal()
|
9165
|
-
}).subarray();
|
9166
|
-
}
|
9167
|
-
equals(key) {
|
9168
|
-
return equals(this.bytes, key.bytes);
|
9169
|
-
}
|
9170
|
-
hash() {
|
9171
|
-
const p = sha256.digest(this.bytes);
|
9172
|
-
if (isPromise$1(p)) {
|
9173
|
-
return p.then(({ bytes }) => bytes);
|
9174
|
-
}
|
9175
|
-
return p.bytes;
|
9176
|
-
}
|
9177
|
-
}
|
9178
|
-
class Ed25519PrivateKey {
|
9179
|
-
_key;
|
9180
|
-
_publicKey;
|
9181
|
-
// key - 64 byte Uint8Array containing private key
|
9182
|
-
// publicKey - 32 byte Uint8Array containing public key
|
9183
|
-
constructor(key, publicKey) {
|
9184
|
-
this._key = ensureKey(key, PRIVATE_KEY_BYTE_LENGTH);
|
9185
|
-
this._publicKey = ensureKey(publicKey, PUBLIC_KEY_BYTE_LENGTH);
|
9186
|
-
}
|
9187
|
-
sign(message) {
|
9188
|
-
return hashAndSign$2(this._key, message);
|
9189
|
-
}
|
9190
|
-
get public() {
|
9191
|
-
return new Ed25519PublicKey(this._publicKey);
|
9192
|
-
}
|
9193
|
-
marshal() {
|
9194
|
-
return this._key;
|
9195
|
-
}
|
9196
|
-
get bytes() {
|
9197
|
-
return PrivateKey.encode({
|
9198
|
-
Type: KeyType.Ed25519,
|
9199
|
-
Data: this.marshal()
|
9200
|
-
}).subarray();
|
9201
|
-
}
|
9202
|
-
equals(key) {
|
9203
|
-
return equals(this.bytes, key.bytes);
|
9204
|
-
}
|
9205
|
-
async hash() {
|
9206
|
-
const p = sha256.digest(this.bytes);
|
9207
|
-
let bytes;
|
9208
|
-
if (isPromise$1(p)) {
|
9209
|
-
({ bytes } = await p);
|
9210
|
-
}
|
9211
|
-
else {
|
9212
|
-
bytes = p.bytes;
|
9213
|
-
}
|
9214
|
-
return bytes;
|
9215
|
-
}
|
9216
|
-
/**
|
9217
|
-
* Gets the ID of the key.
|
9218
|
-
*
|
9219
|
-
* The key id is the base58 encoding of the identity multihash containing its public key.
|
9220
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
9221
|
-
* of the PKCS SubjectPublicKeyInfo.
|
9222
|
-
*
|
9223
|
-
* @returns {Promise<string>}
|
9224
|
-
*/
|
9225
|
-
async id() {
|
9226
|
-
const encoding = identity.digest(this.public.bytes);
|
9227
|
-
return base58btc.encode(encoding.bytes).substring(1);
|
9228
|
-
}
|
9229
|
-
/**
|
9230
|
-
* Exports the key into a password protected `format`
|
9231
|
-
*/
|
9232
|
-
async export(password, format = 'libp2p-key') {
|
9233
|
-
if (format === 'libp2p-key') {
|
9234
|
-
return exporter(this.bytes, password);
|
9235
|
-
}
|
9236
|
-
else {
|
9237
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
9238
|
-
}
|
9239
|
-
}
|
9240
|
-
}
|
9241
|
-
function unmarshalEd25519PrivateKey(bytes) {
|
9242
|
-
// Try the old, redundant public key version
|
9243
|
-
if (bytes.length > PRIVATE_KEY_BYTE_LENGTH) {
|
9244
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH + PUBLIC_KEY_BYTE_LENGTH);
|
9245
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9246
|
-
const publicKeyBytes = bytes.subarray(PRIVATE_KEY_BYTE_LENGTH, bytes.length);
|
9247
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9248
|
-
}
|
9249
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH);
|
9250
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9251
|
-
const publicKeyBytes = bytes.subarray(PUBLIC_KEY_BYTE_LENGTH);
|
9252
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9253
|
-
}
|
9254
|
-
function unmarshalEd25519PublicKey(bytes) {
|
9255
|
-
bytes = ensureKey(bytes, PUBLIC_KEY_BYTE_LENGTH);
|
9256
|
-
return new Ed25519PublicKey(bytes);
|
9257
|
-
}
|
9258
|
-
async function generateKeyPair$2() {
|
9259
|
-
const { privateKey, publicKey } = generateKey$2();
|
9260
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9261
|
-
}
|
9262
|
-
async function generateKeyPairFromSeed(seed) {
|
9263
|
-
const { privateKey, publicKey } = generateKeyFromSeed(seed);
|
9264
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9265
|
-
}
|
9266
|
-
function ensureKey(key, length) {
|
9267
|
-
key = Uint8Array.from(key ?? []);
|
9268
|
-
if (key.length !== length) {
|
9269
|
-
throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
|
9270
|
-
}
|
9271
|
-
return key;
|
9272
|
-
}
|
9273
|
-
|
9274
|
-
var Ed25519 = /*#__PURE__*/Object.freeze({
|
9275
|
-
__proto__: null,
|
9276
|
-
Ed25519PrivateKey: Ed25519PrivateKey,
|
9277
|
-
Ed25519PublicKey: Ed25519PublicKey,
|
9278
|
-
generateKeyPair: generateKeyPair$2,
|
9279
|
-
generateKeyPairFromSeed: generateKeyPairFromSeed,
|
9280
|
-
unmarshalEd25519PrivateKey: unmarshalEd25519PrivateKey,
|
9281
|
-
unmarshalEd25519PublicKey: unmarshalEd25519PublicKey
|
9282
|
-
});
|
9283
|
-
|
9284
|
-
/**
|
9285
|
-
* Generates a Uint8Array with length `number` populated by random bytes
|
9286
|
-
*/
|
9287
|
-
function randomBytes(length) {
|
9288
|
-
if (isNaN(length) || length <= 0) {
|
9289
|
-
throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
|
9290
|
-
}
|
9291
|
-
return randomBytes$1(length);
|
9292
|
-
}
|
9293
|
-
|
9294
|
-
// HMAC (RFC 2104)
|
9295
|
-
class HMAC extends Hash {
|
9296
|
-
constructor(hash$1, _key) {
|
9297
|
-
super();
|
9298
|
-
this.finished = false;
|
9299
|
-
this.destroyed = false;
|
9300
|
-
hash(hash$1);
|
9301
|
-
const key = toBytes$1(_key);
|
9302
|
-
this.iHash = hash$1.create();
|
9303
|
-
if (typeof this.iHash.update !== 'function')
|
9304
|
-
throw new Error('Expected instance of class which extends utils.Hash');
|
9305
|
-
this.blockLen = this.iHash.blockLen;
|
9306
|
-
this.outputLen = this.iHash.outputLen;
|
9307
|
-
const blockLen = this.blockLen;
|
9308
|
-
const pad = new Uint8Array(blockLen);
|
9309
|
-
// blockLen can be bigger than outputLen
|
9310
|
-
pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
|
9311
|
-
for (let i = 0; i < pad.length; i++)
|
9312
|
-
pad[i] ^= 0x36;
|
9313
|
-
this.iHash.update(pad);
|
9314
|
-
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
9315
|
-
this.oHash = hash$1.create();
|
9316
|
-
// Undo internal XOR && apply outer XOR
|
9317
|
-
for (let i = 0; i < pad.length; i++)
|
9318
|
-
pad[i] ^= 0x36 ^ 0x5c;
|
9319
|
-
this.oHash.update(pad);
|
9320
|
-
pad.fill(0);
|
9321
|
-
}
|
9322
|
-
update(buf) {
|
9323
|
-
exists(this);
|
9324
|
-
this.iHash.update(buf);
|
9325
|
-
return this;
|
9326
|
-
}
|
9327
|
-
digestInto(out) {
|
9328
|
-
exists(this);
|
9329
|
-
bytes(out, this.outputLen);
|
9330
|
-
this.finished = true;
|
9331
|
-
this.iHash.digestInto(out);
|
9332
|
-
this.oHash.update(out);
|
9333
|
-
this.oHash.digestInto(out);
|
9334
|
-
this.destroy();
|
9335
|
-
}
|
9336
|
-
digest() {
|
9337
|
-
const out = new Uint8Array(this.oHash.outputLen);
|
9338
|
-
this.digestInto(out);
|
9339
|
-
return out;
|
9340
|
-
}
|
9341
|
-
_cloneInto(to) {
|
9342
|
-
// Create new instance without calling constructor since key already in state and we don't know it.
|
9343
|
-
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
9344
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
9345
|
-
to = to;
|
9346
|
-
to.finished = finished;
|
9347
|
-
to.destroyed = destroyed;
|
9348
|
-
to.blockLen = blockLen;
|
9349
|
-
to.outputLen = outputLen;
|
9350
|
-
to.oHash = oHash._cloneInto(to.oHash);
|
9351
|
-
to.iHash = iHash._cloneInto(to.iHash);
|
9352
|
-
return to;
|
9353
|
-
}
|
9354
|
-
destroy() {
|
9355
|
-
this.destroyed = true;
|
9356
|
-
this.oHash.destroy();
|
9357
|
-
this.iHash.destroy();
|
9358
|
-
}
|
9359
|
-
}
|
9360
|
-
/**
|
9361
|
-
* HMAC: RFC2104 message authentication code.
|
9362
|
-
* @param hash - function that would be used e.g. sha256
|
9363
|
-
* @param key - message key
|
9364
|
-
* @param message - message data
|
9365
|
-
* @example
|
9366
|
-
* import { hmac } from '@noble/hashes/hmac';
|
9367
|
-
* import { sha256 } from '@noble/hashes/sha2';
|
9368
|
-
* const mac1 = hmac(sha256, 'key', 'message');
|
9369
|
-
*/
|
9370
|
-
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
9371
|
-
hmac.create = (hash, key) => new HMAC(hash, key);
|
9372
|
-
|
9373
|
-
// Common prologue and epilogue for sync/async functions
|
9374
|
-
function pbkdf2Init(hash$1, _password, _salt, _opts) {
|
9375
|
-
hash(hash$1);
|
9376
|
-
const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
|
9377
|
-
const { c, dkLen, asyncTick } = opts;
|
9378
|
-
number(c);
|
9379
|
-
number(dkLen);
|
9380
|
-
number(asyncTick);
|
9381
|
-
if (c < 1)
|
9382
|
-
throw new Error('PBKDF2: iterations (c) should be >= 1');
|
9383
|
-
const password = toBytes$1(_password);
|
9384
|
-
const salt = toBytes$1(_salt);
|
9385
|
-
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
|
9386
|
-
const DK = new Uint8Array(dkLen);
|
9387
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9388
|
-
const PRF = hmac.create(hash$1, password);
|
9389
|
-
const PRFSalt = PRF._cloneInto().update(salt);
|
9390
|
-
return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
|
9391
|
-
}
|
9392
|
-
function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
|
9393
|
-
PRF.destroy();
|
9394
|
-
PRFSalt.destroy();
|
9395
|
-
if (prfW)
|
9396
|
-
prfW.destroy();
|
9397
|
-
u.fill(0);
|
9398
|
-
return DK;
|
9399
|
-
}
|
9400
|
-
async function pbkdf2Async(hash, password, salt, opts) {
|
9401
|
-
const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
9402
|
-
let prfW; // Working copy
|
9403
|
-
const arr = new Uint8Array(4);
|
9404
|
-
const view = createView(arr);
|
9405
|
-
const u = new Uint8Array(PRF.outputLen);
|
9406
|
-
// DK = T1 + T2 + ⋯ + Tdklen/hlen
|
9407
|
-
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
9408
|
-
// Ti = F(Password, Salt, c, i)
|
9409
|
-
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
9410
|
-
view.setInt32(0, ti, false);
|
9411
|
-
// F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
|
9412
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9413
|
-
(prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
|
9414
|
-
Ti.set(u.subarray(0, Ti.length));
|
9415
|
-
await asyncLoop(c - 1, asyncTick, () => {
|
9416
|
-
// Uc = PRF(Password, Uc−1)
|
9417
|
-
PRF._cloneInto(prfW).update(u).digestInto(u);
|
9418
|
-
for (let i = 0; i < Ti.length; i++)
|
9419
|
-
Ti[i] ^= u[i];
|
9420
|
-
});
|
9421
|
-
}
|
9422
|
-
return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
|
9423
|
-
}
|
9424
|
-
|
9425
9208
|
/*!
|
9426
9209
|
* MIT License
|
9427
9210
|
*
|
9428
|
-
* Copyright (c) 2017-
|
9211
|
+
* Copyright (c) 2017-2024 Peculiar Ventures, LLC
|
9429
9212
|
*
|
9430
9213
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9431
9214
|
* of this software and associated documentation files (the "Software"), to deal
|
@@ -9537,7 +9320,7 @@ class BufferSourceConverter {
|
|
9537
9320
|
}
|
9538
9321
|
|
9539
9322
|
const STRING_TYPE = "string";
|
9540
|
-
const HEX_REGEX = /^[0-9a-f]+$/i;
|
9323
|
+
const HEX_REGEX = /^[0-9a-f\s]+$/i;
|
9541
9324
|
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
9542
9325
|
const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
|
9543
9326
|
class Utf8Converter {
|
@@ -9771,7 +9554,7 @@ class Convert {
|
|
9771
9554
|
return base64;
|
9772
9555
|
}
|
9773
9556
|
static formatString(data) {
|
9774
|
-
return (data === null || data ===
|
9557
|
+
return (data === null || data === undefined ? undefined : data.replace(/[\n\r\t ]/g, "")) || "";
|
9775
9558
|
}
|
9776
9559
|
}
|
9777
9560
|
Convert.DEFAULT_UTF8_ENCODING = "utf8";
|
@@ -10027,7 +9810,7 @@ function HexBlock(BaseClass) {
|
|
10027
9810
|
var _a;
|
10028
9811
|
super(...args);
|
10029
9812
|
const params = args[0] || {};
|
10030
|
-
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !==
|
9813
|
+
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== undefined ? _a : false;
|
10031
9814
|
this.valueHexView = params.valueHex ? BufferSourceConverter_1.toUint8Array(params.valueHex) : EMPTY_VIEW;
|
10032
9815
|
}
|
10033
9816
|
get valueHex() {
|
@@ -10117,11 +9900,11 @@ class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
|
|
10117
9900
|
var _a, _b, _c, _d;
|
10118
9901
|
super();
|
10119
9902
|
if (idBlock) {
|
10120
|
-
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !==
|
9903
|
+
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== undefined ? _a : false;
|
10121
9904
|
this.valueHexView = idBlock.valueHex ? BufferSourceConverter_1.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
|
10122
|
-
this.tagClass = (_b = idBlock.tagClass) !== null && _b !==
|
10123
|
-
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !==
|
10124
|
-
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;
|
10125
9908
|
}
|
10126
9909
|
else {
|
10127
9910
|
this.tagClass = -1;
|
@@ -10288,9 +10071,9 @@ class LocalLengthBlock extends LocalBaseBlock {
|
|
10288
10071
|
constructor({ lenBlock = {}, } = {}) {
|
10289
10072
|
var _a, _b, _c;
|
10290
10073
|
super();
|
10291
|
-
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !==
|
10292
|
-
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !==
|
10293
|
-
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;
|
10294
10077
|
}
|
10295
10078
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
10296
10079
|
const view = BufferSourceConverter_1.toUint8Array(inputBuffer);
|
@@ -11062,7 +10845,7 @@ var _a$r;
|
|
11062
10845
|
class OctetString extends BaseBlock {
|
11063
10846
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
11064
10847
|
var _b, _c;
|
11065
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10848
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
11066
10849
|
super({
|
11067
10850
|
idBlock: {
|
11068
10851
|
isConstructed: parameters.isConstructed,
|
@@ -11223,7 +11006,7 @@ var _a$q;
|
|
11223
11006
|
class BitString extends BaseBlock {
|
11224
11007
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
11225
11008
|
var _b, _c;
|
11226
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
11009
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
11227
11010
|
super({
|
11228
11011
|
idBlock: {
|
11229
11012
|
isConstructed: parameters.isConstructed,
|
@@ -12425,7 +12208,7 @@ class GeneralizedTime extends UTCTime {
|
|
12425
12208
|
constructor(parameters = {}) {
|
12426
12209
|
var _b;
|
12427
12210
|
super(parameters);
|
12428
|
-
(_b = this.millisecond) !== null && _b !==
|
12211
|
+
(_b = this.millisecond) !== null && _b !== undefined ? _b : (this.millisecond = 0);
|
12429
12212
|
this.idBlock.tagClass = 1;
|
12430
12213
|
this.idBlock.tagNumber = 24;
|
12431
12214
|
}
|
@@ -12673,73 +12456,122 @@ _a = TIME;
|
|
12673
12456
|
TIME.NAME = "TIME";
|
12674
12457
|
|
12675
12458
|
/**
|
12676
|
-
*
|
12459
|
+
* Signing a message failed
|
12677
12460
|
*/
|
12678
|
-
function pkcs1ToJwk(bytes) {
|
12679
|
-
const { result } = fromBER(bytes);
|
12680
|
-
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12681
|
-
// safe to have deeply property chains like this
|
12682
|
-
const values = result.valueBlock.value;
|
12683
|
-
const key = {
|
12684
|
-
n: toString$6(bnToBuf(values[1].toBigInt()), 'base64url'),
|
12685
|
-
e: toString$6(bnToBuf(values[2].toBigInt()), 'base64url'),
|
12686
|
-
d: toString$6(bnToBuf(values[3].toBigInt()), 'base64url'),
|
12687
|
-
p: toString$6(bnToBuf(values[4].toBigInt()), 'base64url'),
|
12688
|
-
q: toString$6(bnToBuf(values[5].toBigInt()), 'base64url'),
|
12689
|
-
dp: toString$6(bnToBuf(values[6].toBigInt()), 'base64url'),
|
12690
|
-
dq: toString$6(bnToBuf(values[7].toBigInt()), 'base64url'),
|
12691
|
-
qi: toString$6(bnToBuf(values[8].toBigInt()), 'base64url'),
|
12692
|
-
kty: 'RSA',
|
12693
|
-
alg: 'RS256'
|
12694
|
-
};
|
12695
|
-
return key;
|
12696
|
-
}
|
12697
12461
|
/**
|
12698
|
-
*
|
12462
|
+
* Verifying a message signature failed
|
12699
12463
|
*/
|
12700
|
-
|
12701
|
-
|
12702
|
-
|
12464
|
+
class VerificationError extends Error {
|
12465
|
+
constructor(message = 'An error occurred while verifying a message') {
|
12466
|
+
super(message);
|
12467
|
+
this.name = 'VerificationError';
|
12703
12468
|
}
|
12704
|
-
const root = new Sequence({
|
12705
|
-
value: [
|
12706
|
-
new Integer({ value: 0 }),
|
12707
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12708
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url'))),
|
12709
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.d, 'base64url'))),
|
12710
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.p, 'base64url'))),
|
12711
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.q, 'base64url'))),
|
12712
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dp, 'base64url'))),
|
12713
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dq, 'base64url'))),
|
12714
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.qi, 'base64url')))
|
12715
|
-
]
|
12716
|
-
});
|
12717
|
-
const der = root.toBER();
|
12718
|
-
return new Uint8Array(der, 0, der.byteLength);
|
12719
12469
|
}
|
12720
12470
|
/**
|
12721
|
-
*
|
12471
|
+
* WebCrypto was not available in the current context
|
12722
12472
|
*/
|
12723
|
-
|
12724
|
-
|
12725
|
-
|
12726
|
-
|
12727
|
-
|
12728
|
-
return {
|
12729
|
-
kty: 'RSA',
|
12730
|
-
n: toString$6(bnToBuf(values[0].toBigInt()), 'base64url'),
|
12731
|
-
e: toString$6(bnToBuf(values[1].toBigInt()), 'base64url')
|
12732
|
-
};
|
12473
|
+
class WebCryptoMissingError extends Error {
|
12474
|
+
constructor(message = 'Missing Web Crypto API') {
|
12475
|
+
super(message);
|
12476
|
+
this.name = 'WebCryptoMissingError';
|
12477
|
+
}
|
12733
12478
|
}
|
12734
|
-
|
12735
|
-
|
12736
|
-
|
12737
|
-
|
12738
|
-
|
12739
|
-
|
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;
|
12740
12494
|
}
|
12741
|
-
|
12742
|
-
|
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: [
|
12743
12575
|
new Sequence({
|
12744
12576
|
value: [
|
12745
12577
|
// rsaEncryption
|
@@ -12764,21 +12596,13 @@ function jwkToPkix(jwk) {
|
|
12764
12596
|
const der = root.toBER();
|
12765
12597
|
return new Uint8Array(der, 0, der.byteLength);
|
12766
12598
|
}
|
12767
|
-
function
|
12768
|
-
let
|
12769
|
-
|
12770
|
-
|
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);
|
12771
12604
|
}
|
12772
|
-
|
12773
|
-
const u8 = new Uint8Array(len);
|
12774
|
-
let i = 0;
|
12775
|
-
let j = 0;
|
12776
|
-
while (i < len) {
|
12777
|
-
u8[i] = parseInt(hex.slice(j, j + 2), 16);
|
12778
|
-
i += 1;
|
12779
|
-
j += 2;
|
12780
|
-
}
|
12781
|
-
return u8;
|
12605
|
+
return toString$6(buf, 'base64url');
|
12782
12606
|
}
|
12783
12607
|
function bufToBn(u8) {
|
12784
12608
|
const hex = [];
|
@@ -12791,331 +12615,131 @@ function bufToBn(u8) {
|
|
12791
12615
|
});
|
12792
12616
|
return BigInt('0x' + hex.join(''));
|
12793
12617
|
}
|
12794
|
-
|
12795
|
-
|
12796
|
-
|
12797
|
-
|
12798
|
-
const
|
12799
|
-
|
12800
|
-
|
12801
|
-
value: [
|
12802
|
-
// version (0)
|
12803
|
-
new Integer({ value: 0 }),
|
12804
|
-
// privateKeyAlgorithm
|
12805
|
-
new Sequence({
|
12806
|
-
value: [
|
12807
|
-
// rsaEncryption OID
|
12808
|
-
new ObjectIdentifier({
|
12809
|
-
value: '1.2.840.113549.1.1.1'
|
12810
|
-
}),
|
12811
|
-
new Null()
|
12812
|
-
]
|
12813
|
-
}),
|
12814
|
-
// PrivateKey
|
12815
|
-
new OctetString({
|
12816
|
-
valueHex: privateKey.marshal()
|
12817
|
-
})
|
12818
|
-
]
|
12819
|
-
});
|
12820
|
-
const keyBuf = keyWrapper.toBER();
|
12821
|
-
const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
|
12822
|
-
const salt = randomBytes(SALT_LENGTH);
|
12823
|
-
const encryptionKey = await pbkdf2Async(sha512, password, salt, {
|
12824
|
-
c: ITERATIONS,
|
12825
|
-
dkLen: KEY_SIZE
|
12826
|
-
});
|
12827
|
-
const iv = randomBytes(16);
|
12828
|
-
const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['encrypt']);
|
12829
|
-
const encrypted = await crypto.subtle.encrypt({
|
12830
|
-
name: 'AES-CBC',
|
12831
|
-
iv
|
12832
|
-
}, cryptoKey, keyArr);
|
12833
|
-
const pbkdf2Params = new Sequence({
|
12834
|
-
value: [
|
12835
|
-
// salt
|
12836
|
-
new OctetString({ valueHex: salt }),
|
12837
|
-
// iteration count
|
12838
|
-
new Integer({ value: ITERATIONS }),
|
12839
|
-
// key length
|
12840
|
-
new Integer({ value: KEY_SIZE }),
|
12841
|
-
// AlgorithmIdentifier
|
12842
|
-
new Sequence({
|
12843
|
-
value: [
|
12844
|
-
// hmacWithSHA512
|
12845
|
-
new ObjectIdentifier({ value: '1.2.840.113549.2.11' }),
|
12846
|
-
new Null()
|
12847
|
-
]
|
12848
|
-
})
|
12849
|
-
]
|
12850
|
-
});
|
12851
|
-
const encryptionAlgorithm = new Sequence({
|
12852
|
-
value: [
|
12853
|
-
// pkcs5PBES2
|
12854
|
-
new ObjectIdentifier({
|
12855
|
-
value: '1.2.840.113549.1.5.13'
|
12856
|
-
}),
|
12857
|
-
new Sequence({
|
12858
|
-
value: [
|
12859
|
-
// keyDerivationFunc
|
12860
|
-
new Sequence({
|
12861
|
-
value: [
|
12862
|
-
// pkcs5PBKDF2
|
12863
|
-
new ObjectIdentifier({
|
12864
|
-
value: '1.2.840.113549.1.5.12'
|
12865
|
-
}),
|
12866
|
-
// PBKDF2-params
|
12867
|
-
pbkdf2Params
|
12868
|
-
]
|
12869
|
-
}),
|
12870
|
-
// encryptionScheme
|
12871
|
-
new Sequence({
|
12872
|
-
value: [
|
12873
|
-
// aes256-CBC
|
12874
|
-
new ObjectIdentifier({
|
12875
|
-
value: '2.16.840.1.101.3.4.1.42'
|
12876
|
-
}),
|
12877
|
-
// iv
|
12878
|
-
new OctetString({
|
12879
|
-
valueHex: iv
|
12880
|
-
})
|
12881
|
-
]
|
12882
|
-
})
|
12883
|
-
]
|
12884
|
-
})
|
12885
|
-
]
|
12886
|
-
});
|
12887
|
-
const finalWrapper = new Sequence({
|
12888
|
-
value: [
|
12889
|
-
encryptionAlgorithm,
|
12890
|
-
new OctetString({ valueHex: encrypted })
|
12891
|
-
]
|
12892
|
-
});
|
12893
|
-
const finalWrapperBuf = finalWrapper.toBER();
|
12894
|
-
const finalWrapperArr = new Uint8Array(finalWrapperBuf, 0, finalWrapperBuf.byteLength);
|
12895
|
-
return [
|
12896
|
-
'-----BEGIN ENCRYPTED PRIVATE KEY-----',
|
12897
|
-
...toString$6(finalWrapperArr, 'base64pad').split(/(.{64})/).filter(Boolean),
|
12898
|
-
'-----END ENCRYPTED PRIVATE KEY-----'
|
12899
|
-
].join('\n');
|
12900
|
-
}
|
12901
|
-
|
12902
|
-
async function generateKey$1(bits) {
|
12903
|
-
const pair = await webcrypto.get().subtle.generateKey({
|
12904
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12905
|
-
modulusLength: bits,
|
12906
|
-
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
12907
|
-
hash: { name: 'SHA-256' }
|
12908
|
-
}, true, ['sign', 'verify']);
|
12909
|
-
const keys = await exportKey(pair);
|
12910
|
-
return {
|
12911
|
-
privateKey: keys[0],
|
12912
|
-
publicKey: keys[1]
|
12913
|
-
};
|
12914
|
-
}
|
12915
|
-
// Takes a jwk key
|
12916
|
-
async function unmarshalPrivateKey$1(key) {
|
12917
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12918
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12919
|
-
hash: { name: 'SHA-256' }
|
12920
|
-
}, true, ['sign']);
|
12921
|
-
const pair = [
|
12922
|
-
privateKey,
|
12923
|
-
await derivePublicFromPrivate(key)
|
12924
|
-
];
|
12925
|
-
const keys = await exportKey({
|
12926
|
-
privateKey: pair[0],
|
12927
|
-
publicKey: pair[1]
|
12928
|
-
});
|
12929
|
-
return {
|
12930
|
-
privateKey: keys[0],
|
12931
|
-
publicKey: keys[1]
|
12932
|
-
};
|
12933
|
-
}
|
12934
|
-
async function hashAndSign$1(key, msg) {
|
12935
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12936
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12937
|
-
hash: { name: 'SHA-256' }
|
12938
|
-
}, false, ['sign']);
|
12939
|
-
const sig = await webcrypto.get().subtle.sign({ name: 'RSASSA-PKCS1-v1_5' }, privateKey, msg instanceof Uint8Array ? msg : msg.subarray());
|
12940
|
-
return new Uint8Array(sig, 0, sig.byteLength);
|
12941
|
-
}
|
12942
|
-
async function hashAndVerify$1(key, sig, msg) {
|
12943
|
-
const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12944
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12945
|
-
hash: { name: 'SHA-256' }
|
12946
|
-
}, false, ['verify']);
|
12947
|
-
return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
|
12948
|
-
}
|
12949
|
-
async function exportKey(pair) {
|
12950
|
-
if (pair.privateKey == null || pair.publicKey == null) {
|
12951
|
-
throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
|
12952
|
-
}
|
12953
|
-
return Promise.all([
|
12954
|
-
webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
|
12955
|
-
webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
|
12956
|
-
]);
|
12957
|
-
}
|
12958
|
-
async function derivePublicFromPrivate(jwKey) {
|
12959
|
-
return webcrypto.get().subtle.importKey('jwk', {
|
12960
|
-
kty: jwKey.kty,
|
12961
|
-
n: jwKey.n,
|
12962
|
-
e: jwKey.e
|
12963
|
-
}, {
|
12964
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12965
|
-
hash: { name: 'SHA-256' }
|
12966
|
-
}, true, ['verify']);
|
12967
|
-
}
|
12968
|
-
function keySize(jwk) {
|
12969
|
-
if (jwk.kty !== 'RSA') {
|
12970
|
-
throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
|
12971
|
-
}
|
12972
|
-
else if (jwk.n == null) {
|
12973
|
-
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');
|
12974
12625
|
}
|
12975
|
-
const
|
12976
|
-
|
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);
|
12977
12632
|
}
|
12978
12633
|
|
12979
|
-
|
12980
|
-
|
12981
|
-
|
12982
|
-
|
12983
|
-
|
12984
|
-
|
12985
|
-
|
12986
|
-
|
12987
|
-
|
12988
|
-
|
12989
|
-
|
12990
|
-
|
12991
|
-
|
12992
|
-
|
12993
|
-
|
12994
|
-
|
12995
|
-
|
12996
|
-
|
12997
|
-
|
12998
|
-
|
12999
|
-
|
13000
|
-
|
13001
|
-
|
13002
|
-
|
13003
|
-
|
13004
|
-
|
13005
|
-
|
13006
|
-
|
13007
|
-
|
13008
|
-
|
13009
|
-
_key;
|
13010
|
-
_publicKey;
|
13011
|
-
constructor(key, publicKey) {
|
13012
|
-
this._key = key;
|
13013
|
-
this._publicKey = publicKey;
|
13014
|
-
}
|
13015
|
-
genSecret() {
|
13016
|
-
return randomBytes(16);
|
13017
|
-
}
|
13018
|
-
sign(message) {
|
13019
|
-
return hashAndSign$1(this._key, message);
|
13020
|
-
}
|
13021
|
-
get public() {
|
13022
|
-
if (this._publicKey == null) {
|
13023
|
-
throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
|
13024
|
-
}
|
13025
|
-
return new RsaPublicKey(this._publicKey);
|
13026
|
-
}
|
13027
|
-
marshal() {
|
13028
|
-
return jwkToPkcs1(this._key);
|
13029
|
-
}
|
13030
|
-
get bytes() {
|
13031
|
-
return PrivateKey.encode({
|
13032
|
-
Type: KeyType.RSA,
|
13033
|
-
Data: this.marshal()
|
13034
|
-
}).subarray();
|
13035
|
-
}
|
13036
|
-
equals(key) {
|
13037
|
-
return equals(this.bytes, key.bytes);
|
13038
|
-
}
|
13039
|
-
hash() {
|
13040
|
-
const p = sha256.digest(this.bytes);
|
13041
|
-
if (isPromise$1(p)) {
|
13042
|
-
return p.then(({ bytes }) => bytes);
|
13043
|
-
}
|
13044
|
-
return p.bytes;
|
13045
|
-
}
|
13046
|
-
/**
|
13047
|
-
* Gets the ID of the key.
|
13048
|
-
*
|
13049
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
13050
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
13051
|
-
* of the PKCS SubjectPublicKeyInfo.
|
13052
|
-
*/
|
13053
|
-
async id() {
|
13054
|
-
const hash = await this.public.hash();
|
13055
|
-
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);
|
13056
12664
|
}
|
13057
|
-
|
13058
|
-
|
13059
|
-
|
13060
|
-
|
13061
|
-
* To export it as a password protected PEM file, please use the `exportPEM`
|
13062
|
-
* function from `@libp2p/rsa`.
|
13063
|
-
*/
|
13064
|
-
async export(password, format = 'pkcs-8') {
|
13065
|
-
if (format === 'pkcs-8') {
|
13066
|
-
return exportToPem(this, password);
|
13067
|
-
}
|
13068
|
-
else if (format === 'libp2p-key') {
|
13069
|
-
return exporter(this.bytes, password);
|
13070
|
-
}
|
13071
|
-
else {
|
13072
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
13073
|
-
}
|
12665
|
+
update(buf) {
|
12666
|
+
aexists(this);
|
12667
|
+
this.iHash.update(buf);
|
12668
|
+
return this;
|
13074
12669
|
}
|
13075
|
-
|
13076
|
-
|
13077
|
-
|
13078
|
-
|
13079
|
-
|
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();
|
13080
12678
|
}
|
13081
|
-
|
13082
|
-
|
13083
|
-
|
13084
|
-
|
13085
|
-
const jwk = pkixToJwk(bytes);
|
13086
|
-
if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
|
13087
|
-
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;
|
13088
12683
|
}
|
13089
|
-
|
13090
|
-
|
13091
|
-
|
13092
|
-
|
13093
|
-
|
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;
|
13094
12696
|
}
|
13095
|
-
|
13096
|
-
|
13097
|
-
|
13098
|
-
|
13099
|
-
if (bits > MAX_RSA_KEY_SIZE) {
|
13100
|
-
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();
|
13101
12701
|
}
|
13102
|
-
const keys = await generateKey$1(bits);
|
13103
|
-
return new RsaPrivateKey(keys.privateKey, keys.publicKey);
|
13104
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);
|
13105
12715
|
|
13106
|
-
|
13107
|
-
|
13108
|
-
|
13109
|
-
|
13110
|
-
|
13111
|
-
|
13112
|
-
|
13113
|
-
|
13114
|
-
|
13115
|
-
|
13116
|
-
|
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
|
+
*/
|
13117
12742
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13118
|
-
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
13119
12743
|
function validateSigVerOpts(opts) {
|
13120
12744
|
if (opts.lowS !== undefined)
|
13121
12745
|
abool('lowS', opts.lowS);
|
@@ -13139,17 +12763,22 @@ function validatePointOpts(curve) {
|
|
13139
12763
|
const { endo, Fp, a } = opts;
|
13140
12764
|
if (endo) {
|
13141
12765
|
if (!Fp.eql(a, Fp.ZERO)) {
|
13142
|
-
throw new Error('
|
12766
|
+
throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
|
13143
12767
|
}
|
13144
12768
|
if (typeof endo !== 'object' ||
|
13145
12769
|
typeof endo.beta !== 'bigint' ||
|
13146
12770
|
typeof endo.splitScalar !== 'function') {
|
13147
|
-
throw new Error('
|
12771
|
+
throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
|
13148
12772
|
}
|
13149
12773
|
}
|
13150
12774
|
return Object.freeze({ ...opts });
|
13151
12775
|
}
|
13152
12776
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
12777
|
+
class DERErr extends Error {
|
12778
|
+
constructor(m = '') {
|
12779
|
+
super(m);
|
12780
|
+
}
|
12781
|
+
}
|
13153
12782
|
/**
|
13154
12783
|
* ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
|
13155
12784
|
*
|
@@ -13159,11 +12788,7 @@ const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
|
13159
12788
|
*/
|
13160
12789
|
const DER = {
|
13161
12790
|
// asn.1 DER encoding utils
|
13162
|
-
Err:
|
13163
|
-
constructor(m = '') {
|
13164
|
-
super(m);
|
13165
|
-
}
|
13166
|
-
},
|
12791
|
+
Err: DERErr,
|
13167
12792
|
// Basic building block is TLV (Tag-Length-Value)
|
13168
12793
|
_tlv: {
|
13169
12794
|
encode: (tag, data) => {
|
@@ -13178,7 +12803,8 @@ const DER = {
|
|
13178
12803
|
throw new E('tlv.encode: long form length too big');
|
13179
12804
|
// length of length with long form flag
|
13180
12805
|
const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
|
13181
|
-
|
12806
|
+
const t = numberToHexUnpadded(tag);
|
12807
|
+
return t + lenLen + len + data;
|
13182
12808
|
},
|
13183
12809
|
// v - value, l - left bytes (unparsed)
|
13184
12810
|
decode(tag, data) {
|
@@ -13231,15 +12857,15 @@ const DER = {
|
|
13231
12857
|
if (Number.parseInt(hex[0], 16) & 0b1000)
|
13232
12858
|
hex = '00' + hex;
|
13233
12859
|
if (hex.length & 1)
|
13234
|
-
throw new E('unexpected assertion');
|
12860
|
+
throw new E('unexpected DER parsing assertion: unpadded hex');
|
13235
12861
|
return hex;
|
13236
12862
|
},
|
13237
12863
|
decode(data) {
|
13238
12864
|
const { Err: E } = DER;
|
13239
12865
|
if (data[0] & 128)
|
13240
|
-
throw new E('
|
12866
|
+
throw new E('invalid signature integer: negative');
|
13241
12867
|
if (data[0] === 0x00 && !(data[1] & 128))
|
13242
|
-
throw new E('
|
12868
|
+
throw new E('invalid signature integer: unnecessary leading zero');
|
13243
12869
|
return b2n(data);
|
13244
12870
|
},
|
13245
12871
|
},
|
@@ -13250,16 +12876,18 @@ const DER = {
|
|
13250
12876
|
abytes(data);
|
13251
12877
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
13252
12878
|
if (seqLeftBytes.length)
|
13253
|
-
throw new E('
|
12879
|
+
throw new E('invalid signature: left bytes after parsing');
|
13254
12880
|
const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
|
13255
12881
|
const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
|
13256
12882
|
if (sLeftBytes.length)
|
13257
|
-
throw new E('
|
12883
|
+
throw new E('invalid signature: left bytes after parsing');
|
13258
12884
|
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
13259
12885
|
},
|
13260
12886
|
hexFromSig(sig) {
|
13261
12887
|
const { _tlv: tlv, _int: int } = DER;
|
13262
|
-
const
|
12888
|
+
const rs = tlv.encode(0x02, int.encode(sig.r));
|
12889
|
+
const ss = tlv.encode(0x02, int.encode(sig.s));
|
12890
|
+
const seq = rs + ss;
|
13263
12891
|
return tlv.encode(0x30, seq);
|
13264
12892
|
},
|
13265
12893
|
};
|
@@ -13313,7 +12941,7 @@ function weierstrassPoints(opts) {
|
|
13313
12941
|
key = bytesToHex(key);
|
13314
12942
|
// Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
|
13315
12943
|
if (typeof key !== 'string' || !lengths.includes(key.length))
|
13316
|
-
throw new Error('
|
12944
|
+
throw new Error('invalid private key');
|
13317
12945
|
key = key.padStart(nByteLength * 2, '0');
|
13318
12946
|
}
|
13319
12947
|
let num;
|
@@ -13324,7 +12952,7 @@ function weierstrassPoints(opts) {
|
|
13324
12952
|
: bytesToNumberBE(ensureBytes('private key', key, nByteLength));
|
13325
12953
|
}
|
13326
12954
|
catch (error) {
|
13327
|
-
throw new Error(
|
12955
|
+
throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
|
13328
12956
|
}
|
13329
12957
|
if (wrapPrivateKey)
|
13330
12958
|
num = mod(num, N); // disabled by default, enabled for BLS
|
@@ -13364,7 +12992,7 @@ function weierstrassPoints(opts) {
|
|
13364
12992
|
if (p.is0()) {
|
13365
12993
|
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13366
12994
|
// In BLS, ZERO can be serialized, so we allow it.
|
13367
|
-
// (0, 0, 0) is
|
12995
|
+
// (0, 0, 0) is invalid representation of ZERO.
|
13368
12996
|
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
13369
12997
|
return;
|
13370
12998
|
throw new Error('bad point: ZERO');
|
@@ -13588,16 +13216,17 @@ function weierstrassPoints(opts) {
|
|
13588
13216
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
13589
13217
|
*/
|
13590
13218
|
multiplyUnsafe(sc) {
|
13591
|
-
|
13219
|
+
const { endo, n: N } = CURVE;
|
13220
|
+
aInRange('scalar', sc, _0n, N);
|
13592
13221
|
const I = Point.ZERO;
|
13593
13222
|
if (sc === _0n)
|
13594
13223
|
return I;
|
13595
|
-
if (sc === _1n$1)
|
13224
|
+
if (this.is0() || sc === _1n$1)
|
13596
13225
|
return this;
|
13597
|
-
|
13598
|
-
if (!endo)
|
13599
|
-
return wnaf.
|
13600
|
-
//
|
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
|
13601
13230
|
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
13602
13231
|
let k1p = I;
|
13603
13232
|
let k2p = I;
|
@@ -13783,7 +13412,9 @@ function weierstrass(curveDef) {
|
|
13783
13412
|
return { x, y };
|
13784
13413
|
}
|
13785
13414
|
else {
|
13786
|
-
|
13415
|
+
const cl = compressedLen;
|
13416
|
+
const ul = uncompressedLen;
|
13417
|
+
throw new Error('invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len);
|
13787
13418
|
}
|
13788
13419
|
},
|
13789
13420
|
});
|
@@ -13948,6 +13579,9 @@ function weierstrass(curveDef) {
|
|
13948
13579
|
// int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
|
13949
13580
|
const bits2int = CURVE.bits2int ||
|
13950
13581
|
function (bytes) {
|
13582
|
+
// Our custom check "just in case"
|
13583
|
+
if (bytes.length > 8192)
|
13584
|
+
throw new Error('input is too large');
|
13951
13585
|
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
13952
13586
|
// for some cases, since bytes.length * 8 is not actual bitLength.
|
13953
13587
|
const num = bytesToNumberBE(bytes); // check for == u8 done here
|
@@ -13964,15 +13598,15 @@ function weierstrass(curveDef) {
|
|
13964
13598
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13965
13599
|
*/
|
13966
13600
|
function int2octets(num) {
|
13967
|
-
aInRange(
|
13601
|
+
aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
|
13968
13602
|
// works with order, can have different size than numToField!
|
13969
13603
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13970
13604
|
}
|
13971
13605
|
// Steps A, D of RFC6979 3.2
|
13972
13606
|
// Creates RFC6979 seed; converts msg/privKey to numbers.
|
13973
13607
|
// Used only in sign, not in verify.
|
13974
|
-
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
|
13975
|
-
// 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
|
13976
13610
|
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
13977
13611
|
if (['recovered', 'canonical'].some((k) => k in opts))
|
13978
13612
|
throw new Error('sign() legacy options not supported');
|
@@ -14066,39 +13700,48 @@ function weierstrass(curveDef) {
|
|
14066
13700
|
const sg = signature;
|
14067
13701
|
msgHash = ensureBytes('msgHash', msgHash);
|
14068
13702
|
publicKey = ensureBytes('publicKey', publicKey);
|
13703
|
+
const { lowS, prehash, format } = opts;
|
13704
|
+
// Verify opts, deduce signature format
|
13705
|
+
validateSigVerOpts(opts);
|
14069
13706
|
if ('strict' in opts)
|
14070
13707
|
throw new Error('options.strict was renamed to lowS');
|
14071
|
-
|
14072
|
-
|
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');
|
14073
13719
|
let _sig = undefined;
|
14074
13720
|
let P;
|
14075
13721
|
try {
|
14076
|
-
if (
|
13722
|
+
if (isObj)
|
13723
|
+
_sig = new Signature(sg.r, sg.s);
|
13724
|
+
if (isHex) {
|
14077
13725
|
// Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
|
14078
13726
|
// Since DER can also be 2*nByteLength bytes, we check for it first.
|
14079
13727
|
try {
|
14080
|
-
|
13728
|
+
if (format !== 'compact')
|
13729
|
+
_sig = Signature.fromDER(sg);
|
14081
13730
|
}
|
14082
13731
|
catch (derError) {
|
14083
13732
|
if (!(derError instanceof DER.Err))
|
14084
13733
|
throw derError;
|
14085
|
-
_sig = Signature.fromCompact(sg);
|
14086
13734
|
}
|
14087
|
-
|
14088
|
-
|
14089
|
-
const { r, s } = sg;
|
14090
|
-
_sig = new Signature(r, s);
|
14091
|
-
}
|
14092
|
-
else {
|
14093
|
-
throw new Error('PARSE');
|
13735
|
+
if (!_sig && format !== 'der')
|
13736
|
+
_sig = Signature.fromCompact(sg);
|
14094
13737
|
}
|
14095
13738
|
P = Point.fromHex(publicKey);
|
14096
13739
|
}
|
14097
13740
|
catch (error) {
|
14098
|
-
if (error.message === 'PARSE')
|
14099
|
-
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
14100
13741
|
return false;
|
14101
13742
|
}
|
13743
|
+
if (!_sig)
|
13744
|
+
return false;
|
14102
13745
|
if (lowS && _sig.hasHighS())
|
14103
13746
|
return false;
|
14104
13747
|
if (prehash)
|
@@ -14126,20 +13769,36 @@ function weierstrass(curveDef) {
|
|
14126
13769
|
};
|
14127
13770
|
}
|
14128
13771
|
|
13772
|
+
/**
|
13773
|
+
* Utilities for short weierstrass curves, combined with noble-hashes.
|
13774
|
+
* @module
|
13775
|
+
*/
|
14129
13776
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
14130
|
-
|
13777
|
+
/** connects noble-curves to noble-hashes */
|
14131
13778
|
function getHash(hash) {
|
14132
13779
|
return {
|
14133
13780
|
hash,
|
14134
13781
|
hmac: (key, ...msgs) => hmac(hash, key, concatBytes$2(...msgs)),
|
14135
|
-
randomBytes
|
13782
|
+
randomBytes,
|
14136
13783
|
};
|
14137
13784
|
}
|
14138
13785
|
function createCurve(curveDef, defHash) {
|
14139
13786
|
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
14140
|
-
return
|
13787
|
+
return { ...create(defHash), create };
|
14141
13788
|
}
|
14142
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
|
+
*/
|
14143
13802
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
14144
13803
|
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
14145
13804
|
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
@@ -14170,31 +13829,35 @@ function sqrtMod(y) {
|
|
14170
13829
|
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
14171
13830
|
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
14172
13831
|
const root = pow2(t2, _2n, P);
|
14173
|
-
if (!
|
13832
|
+
if (!Fpk1.eql(Fpk1.sqr(root), y))
|
14174
13833
|
throw new Error('Cannot find square root');
|
14175
13834
|
return root;
|
14176
13835
|
}
|
14177
|
-
const
|
13836
|
+
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
14178
13837
|
/**
|
14179
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;
|
14180
13848
|
*/
|
14181
13849
|
const secp256k1 = createCurve({
|
14182
13850
|
a: BigInt(0), // equation params: a, b
|
14183
|
-
b: BigInt(7),
|
14184
|
-
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
|
14185
13853
|
n: secp256k1N, // Curve order, total count of valid points in the field
|
14186
13854
|
// Base point (x, y) aka generator point
|
14187
13855
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
14188
13856
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
14189
13857
|
h: BigInt(1), // Cofactor
|
14190
13858
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
14191
|
-
/**
|
14192
|
-
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
14193
|
-
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
14194
|
-
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
14195
|
-
* Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
14196
|
-
*/
|
14197
13859
|
endo: {
|
13860
|
+
// Endomorphism, see above
|
14198
13861
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
14199
13862
|
splitScalar: (k) => {
|
14200
13863
|
const n = secp256k1N;
|
@@ -14225,27 +13888,15 @@ const secp256k1 = createCurve({
|
|
14225
13888
|
BigInt(0);
|
14226
13889
|
secp256k1.ProjectivePoint;
|
14227
13890
|
|
14228
|
-
function
|
14229
|
-
|
14230
|
-
|
14231
|
-
/**
|
14232
|
-
* Hash and sign message with private key
|
14233
|
-
*/
|
14234
|
-
function hashAndSign(key, msg) {
|
14235
|
-
const p = sha256.digest(msg instanceof Uint8Array ? msg : msg.subarray());
|
14236
|
-
if (isPromise$1(p)) {
|
14237
|
-
return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
|
14238
|
-
.catch(err => {
|
14239
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
14240
|
-
});
|
14241
|
-
}
|
14242
|
-
try {
|
14243
|
-
return secp256k1.sign(p.digest, key).toDERRawBytes();
|
14244
|
-
}
|
14245
|
-
catch (err) {
|
14246
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
13891
|
+
function isPromise$1(thing) {
|
13892
|
+
if (thing == null) {
|
13893
|
+
return false;
|
14247
13894
|
}
|
13895
|
+
return typeof thing.then === 'function' &&
|
13896
|
+
typeof thing.catch === 'function' &&
|
13897
|
+
typeof thing.finally === 'function';
|
14248
13898
|
}
|
13899
|
+
|
14249
13900
|
/**
|
14250
13901
|
* Hash message and verify signature with public key
|
14251
13902
|
*/
|
@@ -14254,231 +13905,112 @@ function hashAndVerify(key, sig, msg) {
|
|
14254
13905
|
if (isPromise$1(p)) {
|
14255
13906
|
return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
|
14256
13907
|
.catch(err => {
|
14257
|
-
throw new
|
13908
|
+
throw new VerificationError(String(err));
|
14258
13909
|
});
|
14259
13910
|
}
|
14260
13911
|
try {
|
14261
13912
|
return secp256k1.verify(sig, p.digest, key);
|
14262
13913
|
}
|
14263
13914
|
catch (err) {
|
14264
|
-
throw new
|
14265
|
-
}
|
14266
|
-
}
|
14267
|
-
function compressPublicKey(key) {
|
14268
|
-
const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
|
14269
|
-
return point;
|
14270
|
-
}
|
14271
|
-
function validatePrivateKey(key) {
|
14272
|
-
try {
|
14273
|
-
secp256k1.getPublicKey(key, true);
|
14274
|
-
}
|
14275
|
-
catch (err) {
|
14276
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
14277
|
-
}
|
14278
|
-
}
|
14279
|
-
function validatePublicKey(key) {
|
14280
|
-
try {
|
14281
|
-
secp256k1.ProjectivePoint.fromHex(key);
|
14282
|
-
}
|
14283
|
-
catch (err) {
|
14284
|
-
throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
|
14285
|
-
}
|
14286
|
-
}
|
14287
|
-
function computePublicKey(privateKey) {
|
14288
|
-
try {
|
14289
|
-
return secp256k1.getPublicKey(privateKey, true);
|
14290
|
-
}
|
14291
|
-
catch (err) {
|
14292
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
13915
|
+
throw new VerificationError(String(err));
|
14293
13916
|
}
|
14294
13917
|
}
|
14295
13918
|
|
14296
13919
|
class Secp256k1PublicKey {
|
13920
|
+
type = 'secp256k1';
|
13921
|
+
raw;
|
14297
13922
|
_key;
|
14298
13923
|
constructor(key) {
|
14299
|
-
|
14300
|
-
this.
|
13924
|
+
this._key = validateSecp256k1PublicKey(key);
|
13925
|
+
this.raw = compressSecp256k1PublicKey(this._key);
|
14301
13926
|
}
|
14302
|
-
|
14303
|
-
return
|
14304
|
-
}
|
14305
|
-
marshal() {
|
14306
|
-
return compressPublicKey(this._key);
|
14307
|
-
}
|
14308
|
-
get bytes() {
|
14309
|
-
return PublicKey.encode({
|
14310
|
-
Type: KeyType.Secp256k1,
|
14311
|
-
Data: this.marshal()
|
14312
|
-
}).subarray();
|
14313
|
-
}
|
14314
|
-
equals(key) {
|
14315
|
-
return equals(this.bytes, key.bytes);
|
14316
|
-
}
|
14317
|
-
async hash() {
|
14318
|
-
const p = sha256.digest(this.bytes);
|
14319
|
-
let bytes;
|
14320
|
-
if (isPromise$1(p)) {
|
14321
|
-
({ bytes } = await p);
|
14322
|
-
}
|
14323
|
-
else {
|
14324
|
-
bytes = p.bytes;
|
14325
|
-
}
|
14326
|
-
return bytes;
|
14327
|
-
}
|
14328
|
-
}
|
14329
|
-
class Secp256k1PrivateKey {
|
14330
|
-
_key;
|
14331
|
-
_publicKey;
|
14332
|
-
constructor(key, publicKey) {
|
14333
|
-
this._key = key;
|
14334
|
-
this._publicKey = publicKey ?? computePublicKey(key);
|
14335
|
-
validatePrivateKey(this._key);
|
14336
|
-
validatePublicKey(this._publicKey);
|
14337
|
-
}
|
14338
|
-
sign(message) {
|
14339
|
-
return hashAndSign(this._key, message);
|
14340
|
-
}
|
14341
|
-
get public() {
|
14342
|
-
return new Secp256k1PublicKey(this._publicKey);
|
13927
|
+
toMultihash() {
|
13928
|
+
return identity.digest(publicKeyToProtobuf(this));
|
14343
13929
|
}
|
14344
|
-
|
14345
|
-
return this.
|
13930
|
+
toCID() {
|
13931
|
+
return CID.createV1(114, this.toMultihash());
|
14346
13932
|
}
|
14347
|
-
|
14348
|
-
return
|
14349
|
-
Type: KeyType.Secp256k1,
|
14350
|
-
Data: this.marshal()
|
14351
|
-
}).subarray();
|
13933
|
+
toString() {
|
13934
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
14352
13935
|
}
|
14353
13936
|
equals(key) {
|
14354
|
-
|
14355
|
-
|
14356
|
-
hash() {
|
14357
|
-
const p = sha256.digest(this.bytes);
|
14358
|
-
if (isPromise$1(p)) {
|
14359
|
-
return p.then(({ bytes }) => bytes);
|
13937
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
13938
|
+
return false;
|
14360
13939
|
}
|
14361
|
-
return
|
14362
|
-
}
|
14363
|
-
/**
|
14364
|
-
* Gets the ID of the key.
|
14365
|
-
*
|
14366
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
14367
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
14368
|
-
* of the PKCS SubjectPublicKeyInfo.
|
14369
|
-
*/
|
14370
|
-
async id() {
|
14371
|
-
const hash = await this.public.hash();
|
14372
|
-
return toString$6(hash, 'base58btc');
|
13940
|
+
return equals(this.raw, key.raw);
|
14373
13941
|
}
|
14374
|
-
|
14375
|
-
|
14376
|
-
*/
|
14377
|
-
async export(password, format = 'libp2p-key') {
|
14378
|
-
if (format === 'libp2p-key') {
|
14379
|
-
return exporter(this.bytes, password);
|
14380
|
-
}
|
14381
|
-
else {
|
14382
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
14383
|
-
}
|
13942
|
+
verify(data, sig) {
|
13943
|
+
return hashAndVerify(this._key, sig, data);
|
14384
13944
|
}
|
14385
13945
|
}
|
14386
|
-
|
14387
|
-
return new Secp256k1PrivateKey(bytes);
|
14388
|
-
}
|
13946
|
+
|
14389
13947
|
function unmarshalSecp256k1PublicKey(bytes) {
|
14390
13948
|
return new Secp256k1PublicKey(bytes);
|
14391
13949
|
}
|
14392
|
-
|
14393
|
-
const
|
14394
|
-
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
|
+
}
|
14395
13962
|
}
|
14396
|
-
|
14397
|
-
var Secp256k1 = /*#__PURE__*/Object.freeze({
|
14398
|
-
__proto__: null,
|
14399
|
-
Secp256k1PrivateKey: Secp256k1PrivateKey,
|
14400
|
-
Secp256k1PublicKey: Secp256k1PublicKey,
|
14401
|
-
generateKeyPair: generateKeyPair,
|
14402
|
-
unmarshalSecp256k1PrivateKey: unmarshalSecp256k1PrivateKey,
|
14403
|
-
unmarshalSecp256k1PublicKey: unmarshalSecp256k1PublicKey
|
14404
|
-
});
|
14405
13963
|
|
14406
13964
|
/**
|
14407
13965
|
* @packageDocumentation
|
14408
13966
|
*
|
14409
|
-
*
|
14410
|
-
*
|
14411
|
-
* The {@link generateKeyPair}, {@link marshalPublicKey}, and {@link marshalPrivateKey} functions accept a string `type` argument.
|
13967
|
+
* ## Supported Key Types
|
14412
13968
|
*
|
14413
13969
|
* Currently the `'RSA'`, `'ed25519'`, and `secp256k1` types are supported, although ed25519 and secp256k1 keys support only signing and verification of messages.
|
14414
13970
|
*
|
14415
13971
|
* For encryption / decryption support, RSA keys should be used.
|
14416
13972
|
*/
|
14417
|
-
const supportedKeys = {
|
14418
|
-
rsa: RSA,
|
14419
|
-
ed25519: Ed25519,
|
14420
|
-
secp256k1: Secp256k1
|
14421
|
-
};
|
14422
|
-
function unsupportedKey(type) {
|
14423
|
-
const supported = Object.keys(supportedKeys).join(' / ');
|
14424
|
-
return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
|
14425
|
-
}
|
14426
|
-
function typeToKey(type) {
|
14427
|
-
type = type.toLowerCase();
|
14428
|
-
if (type === 'rsa' || type === 'ed25519' || type === 'secp256k1') {
|
14429
|
-
return supportedKeys[type];
|
14430
|
-
}
|
14431
|
-
throw unsupportedKey(type);
|
14432
|
-
}
|
14433
13973
|
/**
|
14434
|
-
*
|
13974
|
+
* Creates a public key from the raw key bytes
|
14435
13975
|
*/
|
14436
|
-
function
|
14437
|
-
|
14438
|
-
|
14439
|
-
|
14440
|
-
|
14441
|
-
|
14442
|
-
|
14443
|
-
|
14444
|
-
|
14445
|
-
return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data);
|
14446
|
-
default:
|
14447
|
-
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);
|
14448
13985
|
}
|
14449
13986
|
}
|
14450
13987
|
/**
|
14451
|
-
*
|
14452
|
-
|
14453
|
-
|
14454
|
-
|
14455
|
-
|
14456
|
-
return key.bytes;
|
14457
|
-
}
|
14458
|
-
/**
|
14459
|
-
* 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.
|
14460
13993
|
*/
|
14461
|
-
|
14462
|
-
const
|
14463
|
-
const data =
|
14464
|
-
switch (
|
14465
|
-
case KeyType.RSA:
|
14466
|
-
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) {
|
14467
13998
|
case KeyType.Ed25519:
|
14468
|
-
return
|
14469
|
-
case KeyType.
|
14470
|
-
return
|
13999
|
+
return unmarshalEd25519PublicKey(data);
|
14000
|
+
case KeyType.secp256k1:
|
14001
|
+
return unmarshalSecp256k1PublicKey(data);
|
14471
14002
|
default:
|
14472
|
-
throw
|
14003
|
+
throw new UnsupportedKeyTypeError();
|
14473
14004
|
}
|
14474
14005
|
}
|
14475
14006
|
/**
|
14476
|
-
* Converts a
|
14007
|
+
* Converts a public key object into a protobuf serialized public key
|
14477
14008
|
*/
|
14478
|
-
function
|
14479
|
-
|
14480
|
-
|
14481
|
-
|
14009
|
+
function publicKeyToProtobuf(key) {
|
14010
|
+
return PublicKey.encode({
|
14011
|
+
Type: KeyType[key.type],
|
14012
|
+
Data: key.raw
|
14013
|
+
});
|
14482
14014
|
}
|
14483
14015
|
|
14484
14016
|
/**
|
@@ -14496,26 +14028,17 @@ function marshalPrivateKey(key, type) {
|
|
14496
14028
|
* console.log(peer.toString()) // "12D3K..."
|
14497
14029
|
* ```
|
14498
14030
|
*/
|
14499
|
-
const inspect = Symbol.for('nodejs.util.inspect.custom');
|
14500
|
-
const baseDecoder = Object
|
14501
|
-
.values(bases)
|
14502
|
-
.map(codec => codec.decoder)
|
14503
|
-
// @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
|
14504
|
-
.reduce((acc, curr) => acc.or(curr), bases.identity.decoder);
|
14031
|
+
const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
|
14505
14032
|
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14506
|
-
const LIBP2P_KEY_CODE = 0x72;
|
14507
|
-
|
14508
|
-
const MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH = 37;
|
14509
|
-
class PeerIdImpl {
|
14033
|
+
const LIBP2P_KEY_CODE$1 = 0x72;
|
14034
|
+
let PeerIdImpl$1 = class PeerIdImpl {
|
14510
14035
|
type;
|
14511
14036
|
multihash;
|
14512
|
-
privateKey;
|
14513
14037
|
publicKey;
|
14514
14038
|
string;
|
14515
14039
|
constructor(init) {
|
14516
14040
|
this.type = init.type;
|
14517
14041
|
this.multihash = init.multihash;
|
14518
|
-
this.privateKey = init.privateKey;
|
14519
14042
|
// mark string cache as non-enumerable
|
14520
14043
|
Object.defineProperty(this, 'string', {
|
14521
14044
|
enumerable: false,
|
@@ -14532,17 +14055,14 @@ class PeerIdImpl {
|
|
14532
14055
|
}
|
14533
14056
|
return this.string;
|
14534
14057
|
}
|
14058
|
+
toMultihash() {
|
14059
|
+
return this.multihash;
|
14060
|
+
}
|
14535
14061
|
// return self-describing String representation
|
14536
14062
|
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
14537
14063
|
toCID() {
|
14538
|
-
return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
|
14539
|
-
}
|
14540
|
-
toBytes() {
|
14541
|
-
return this.multihash.bytes;
|
14064
|
+
return CID.createV1(LIBP2P_KEY_CODE$1, this.multihash);
|
14542
14065
|
}
|
14543
|
-
/**
|
14544
|
-
* Returns Multiaddr as a JSON string
|
14545
|
-
*/
|
14546
14066
|
toJSON() {
|
14547
14067
|
return this.toString();
|
14548
14068
|
}
|
@@ -14557,10 +14077,10 @@ class PeerIdImpl {
|
|
14557
14077
|
return equals(this.multihash.bytes, id);
|
14558
14078
|
}
|
14559
14079
|
else if (typeof id === 'string') {
|
14560
|
-
return
|
14080
|
+
return this.toString() === id;
|
14561
14081
|
}
|
14562
|
-
else if (id?.
|
14563
|
-
return equals(this.multihash.bytes, id.
|
14082
|
+
else if (id?.toMultihash()?.bytes != null) {
|
14083
|
+
return equals(this.multihash.bytes, id.toMultihash().bytes);
|
14564
14084
|
}
|
14565
14085
|
else {
|
14566
14086
|
throw new Error('not valid Id');
|
@@ -14578,145 +14098,79 @@ class PeerIdImpl {
|
|
14578
14098
|
* // 'PeerId(QmFoo)'
|
14579
14099
|
* ```
|
14580
14100
|
*/
|
14581
|
-
[inspect]() {
|
14101
|
+
[inspect$1]() {
|
14582
14102
|
return `PeerId(${this.toString()})`;
|
14583
14103
|
}
|
14584
|
-
}
|
14585
|
-
class
|
14104
|
+
};
|
14105
|
+
let RSAPeerId$1 = class RSAPeerId extends PeerIdImpl$1 {
|
14586
14106
|
type = 'RSA';
|
14587
14107
|
publicKey;
|
14588
14108
|
constructor(init) {
|
14589
14109
|
super({ ...init, type: 'RSA' });
|
14590
14110
|
this.publicKey = init.publicKey;
|
14591
14111
|
}
|
14592
|
-
}
|
14593
|
-
class
|
14112
|
+
};
|
14113
|
+
let Ed25519PeerId$1 = class Ed25519PeerId extends PeerIdImpl$1 {
|
14594
14114
|
type = 'Ed25519';
|
14595
14115
|
publicKey;
|
14596
14116
|
constructor(init) {
|
14597
14117
|
super({ ...init, type: 'Ed25519' });
|
14598
|
-
this.publicKey = init.
|
14118
|
+
this.publicKey = init.publicKey;
|
14599
14119
|
}
|
14600
|
-
}
|
14601
|
-
class
|
14120
|
+
};
|
14121
|
+
let Secp256k1PeerId$1 = class Secp256k1PeerId extends PeerIdImpl$1 {
|
14602
14122
|
type = 'secp256k1';
|
14603
14123
|
publicKey;
|
14604
14124
|
constructor(init) {
|
14605
14125
|
super({ ...init, type: 'secp256k1' });
|
14606
|
-
this.publicKey = init.
|
14607
|
-
}
|
14608
|
-
}
|
14609
|
-
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14610
|
-
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
14611
|
-
class URLPeerIdImpl {
|
14612
|
-
type = 'url';
|
14613
|
-
multihash;
|
14614
|
-
privateKey;
|
14615
|
-
publicKey;
|
14616
|
-
url;
|
14617
|
-
constructor(url) {
|
14618
|
-
this.url = url.toString();
|
14619
|
-
this.multihash = identity.digest(fromString(this.url));
|
14620
|
-
}
|
14621
|
-
[inspect]() {
|
14622
|
-
return `PeerId(${this.url})`;
|
14623
|
-
}
|
14624
|
-
[peerIdSymbol] = true;
|
14625
|
-
toString() {
|
14626
|
-
return this.toCID().toString();
|
14627
|
-
}
|
14628
|
-
toCID() {
|
14629
|
-
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
|
14630
|
-
}
|
14631
|
-
toBytes() {
|
14632
|
-
return this.toCID().bytes;
|
14633
|
-
}
|
14634
|
-
equals(other) {
|
14635
|
-
if (other == null) {
|
14636
|
-
return false;
|
14637
|
-
}
|
14638
|
-
if (other instanceof Uint8Array) {
|
14639
|
-
other = toString$6(other);
|
14640
|
-
}
|
14641
|
-
return other.toString() === this.toString();
|
14642
|
-
}
|
14643
|
-
}
|
14644
|
-
function peerIdFromString(str, decoder) {
|
14645
|
-
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
14646
|
-
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
14647
|
-
// rsa public key - base58btc encoded either way
|
14648
|
-
const multihash = decode$6(base58btc.decode(`z${str}`));
|
14649
|
-
if (str.startsWith('12D')) {
|
14650
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14651
|
-
}
|
14652
|
-
else if (str.startsWith('16U')) {
|
14653
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14654
|
-
}
|
14655
|
-
else {
|
14656
|
-
return new RSAPeerIdImpl({ multihash });
|
14657
|
-
}
|
14658
|
-
}
|
14659
|
-
return peerIdFromBytes(baseDecoder.decode(str));
|
14660
|
-
}
|
14661
|
-
function peerIdFromBytes(buf) {
|
14662
|
-
try {
|
14663
|
-
const multihash = decode$6(buf);
|
14664
|
-
if (multihash.code === identity.code) {
|
14665
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14666
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14667
|
-
}
|
14668
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14669
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14670
|
-
}
|
14671
|
-
}
|
14672
|
-
if (multihash.code === sha256.code) {
|
14673
|
-
return new RSAPeerIdImpl({ multihash });
|
14674
|
-
}
|
14675
|
-
}
|
14676
|
-
catch {
|
14677
|
-
return peerIdFromCID(CID.decode(buf));
|
14678
|
-
}
|
14679
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14680
|
-
}
|
14681
|
-
function peerIdFromCID(cid) {
|
14682
|
-
if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
|
14683
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14684
|
-
}
|
14685
|
-
if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
|
14686
|
-
const url = toString$6(cid.multihash.digest);
|
14687
|
-
return new URLPeerIdImpl(new URL(url));
|
14688
|
-
}
|
14689
|
-
const multihash = cid.multihash;
|
14690
|
-
if (multihash.code === sha256.code) {
|
14691
|
-
return new RSAPeerIdImpl({ multihash: cid.multihash });
|
14692
|
-
}
|
14693
|
-
else if (multihash.code === identity.code) {
|
14694
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14695
|
-
return new Ed25519PeerIdImpl({ multihash: cid.multihash });
|
14696
|
-
}
|
14697
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14698
|
-
return new Secp256k1PeerIdImpl({ multihash: cid.multihash });
|
14699
|
-
}
|
14126
|
+
this.publicKey = init.publicKey;
|
14700
14127
|
}
|
14701
|
-
|
14702
|
-
|
14128
|
+
};
|
14129
|
+
|
14703
14130
|
/**
|
14704
|
-
* @
|
14705
|
-
*
|
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
|
+
* ```
|
14706
14144
|
*/
|
14707
|
-
|
14708
|
-
if (publicKey.
|
14709
|
-
return new
|
14145
|
+
function peerIdFromPublicKey(publicKey) {
|
14146
|
+
if (publicKey.type === 'Ed25519') {
|
14147
|
+
return new Ed25519PeerId$1({
|
14148
|
+
multihash: publicKey.toCID().multihash,
|
14149
|
+
publicKey
|
14150
|
+
});
|
14710
14151
|
}
|
14711
|
-
if (publicKey.
|
14712
|
-
return new
|
14152
|
+
else if (publicKey.type === 'secp256k1') {
|
14153
|
+
return new Secp256k1PeerId$1({
|
14154
|
+
multihash: publicKey.toCID().multihash,
|
14155
|
+
publicKey
|
14156
|
+
});
|
14157
|
+
}
|
14158
|
+
else if (publicKey.type === 'RSA') {
|
14159
|
+
return new RSAPeerId$1({
|
14160
|
+
multihash: publicKey.toCID().multihash,
|
14161
|
+
publicKey
|
14162
|
+
});
|
14713
14163
|
}
|
14714
|
-
|
14164
|
+
throw new UnsupportedKeyTypeError();
|
14715
14165
|
}
|
14716
14166
|
|
14167
|
+
const ERR_TYPE_NOT_IMPLEMENTED = "Keypair type not implemented";
|
14717
14168
|
function createPeerIdFromPublicKey(publicKey) {
|
14718
|
-
const
|
14719
|
-
|
14169
|
+
const pubKey = publicKeyFromRaw(publicKey);
|
14170
|
+
if (pubKey.type !== "secp256k1") {
|
14171
|
+
throw new Error(ERR_TYPE_NOT_IMPLEMENTED);
|
14172
|
+
}
|
14173
|
+
return peerIdFromPublicKey(pubKey);
|
14720
14174
|
}
|
14721
14175
|
|
14722
14176
|
function decodeMultiaddrs(bytes) {
|
@@ -14963,12 +14417,12 @@ var TransportProtocolPerIpVersion;
|
|
14963
14417
|
class ENR extends RawEnr {
|
14964
14418
|
static RECORD_PREFIX = "enr:";
|
14965
14419
|
peerId;
|
14966
|
-
static
|
14420
|
+
static create(kvs = {}, seq = BigInt(1), signature) {
|
14967
14421
|
const enr = new ENR(kvs, seq, signature);
|
14968
14422
|
try {
|
14969
14423
|
const publicKey = enr.publicKey;
|
14970
14424
|
if (publicKey) {
|
14971
|
-
enr.peerId =
|
14425
|
+
enr.peerId = createPeerIdFromPublicKey(publicKey);
|
14972
14426
|
}
|
14973
14427
|
}
|
14974
14428
|
catch (e) {
|
@@ -15733,7 +15187,7 @@ async function fromValues(values) {
|
|
15733
15187
|
}
|
15734
15188
|
}
|
15735
15189
|
const _seq = decodeSeq(seq);
|
15736
|
-
const enr =
|
15190
|
+
const enr = ENR.create(obj, _seq, signature);
|
15737
15191
|
checkSignature(seq, kvs, enr, signature);
|
15738
15192
|
return enr;
|
15739
15193
|
}
|
@@ -16417,9 +15871,9 @@ function _copyActual (source, target, targetStart, sourceStart, sourceEnd) {
|
|
16417
15871
|
const QUERY_FLAG = 0;
|
16418
15872
|
const RESPONSE_FLAG = 1 << 15;
|
16419
15873
|
const FLUSH_MASK = 1 << 15;
|
16420
|
-
const NOT_FLUSH_MASK =
|
15874
|
+
const NOT_FLUSH_MASK = -32769;
|
16421
15875
|
const QU_MASK = 1 << 15;
|
16422
|
-
const NOT_QU_MASK =
|
15876
|
+
const NOT_QU_MASK = -32769;
|
16423
15877
|
|
16424
15878
|
function codec ({ bytes = 0, encode, decode, encodingLength }) {
|
16425
15879
|
encode.bytes = bytes;
|
@@ -20791,97 +20245,17 @@ class PeerDiscoveryDns extends TypedEventEmitter {
|
|
20791
20245
|
* Stop emitting events
|
20792
20246
|
*/
|
20793
20247
|
stop() {
|
20794
|
-
this._started = false;
|
20795
|
-
}
|
20796
|
-
get [peerDiscoverySymbol]() {
|
20797
|
-
return true;
|
20798
|
-
}
|
20799
|
-
get [Symbol.toStringTag]() {
|
20800
|
-
return DNS_DISCOVERY_TAG;
|
20801
|
-
}
|
20802
|
-
}
|
20803
|
-
function wakuDnsDiscovery(enrUrls, wantedNodeCapabilityCount = DEFAULT_NODE_REQUIREMENTS) {
|
20804
|
-
return (components) => new PeerDiscoveryDns(components, { enrUrls, wantedNodeCapabilityCount });
|
20805
|
-
}
|
20806
|
-
|
20807
|
-
/**
|
20808
|
-
* Function to sort peers by latency from lowest to highest
|
20809
|
-
* @param peerStore - The Libp2p PeerStore
|
20810
|
-
* @param peers - The list of peers to choose from
|
20811
|
-
* @returns Sorted array of peers by latency
|
20812
|
-
*/
|
20813
|
-
async function sortPeersByLatency(peerStore, peers) {
|
20814
|
-
if (peers.length === 0)
|
20815
|
-
return [];
|
20816
|
-
const results = await Promise.all(peers.map(async (peer) => {
|
20817
|
-
try {
|
20818
|
-
const pingBytes = (await peerStore.get(peer.id)).metadata.get("ping");
|
20819
|
-
if (!pingBytes)
|
20820
|
-
return { peer, ping: Infinity };
|
20821
|
-
const ping = Number(bytesToUtf8(pingBytes));
|
20822
|
-
return { peer, ping };
|
20823
|
-
}
|
20824
|
-
catch (error) {
|
20825
|
-
return { peer, ping: Infinity };
|
20826
|
-
}
|
20827
|
-
}));
|
20828
|
-
// filter out null values
|
20829
|
-
const validResults = results.filter((result) => result !== null);
|
20830
|
-
return validResults
|
20831
|
-
.sort((a, b) => a.ping - b.ping)
|
20832
|
-
.map((result) => result.peer);
|
20833
|
-
}
|
20834
|
-
/**
|
20835
|
-
* Returns the list of peers that supports the given protocol.
|
20836
|
-
*/
|
20837
|
-
async function getPeersForProtocol(peerStore, protocols) {
|
20838
|
-
const peers = [];
|
20839
|
-
await peerStore.forEach((peer) => {
|
20840
|
-
for (let i = 0; i < protocols.length; i++) {
|
20841
|
-
if (peer.protocols.includes(protocols[i])) {
|
20842
|
-
peers.push(peer);
|
20843
|
-
break;
|
20844
|
-
}
|
20845
|
-
}
|
20846
|
-
});
|
20847
|
-
return peers;
|
20248
|
+
this._started = false;
|
20249
|
+
}
|
20250
|
+
get [peerDiscoverySymbol]() {
|
20251
|
+
return true;
|
20252
|
+
}
|
20253
|
+
get [Symbol.toStringTag]() {
|
20254
|
+
return DNS_DISCOVERY_TAG;
|
20255
|
+
}
|
20848
20256
|
}
|
20849
|
-
|
20850
|
-
|
20851
|
-
* Retrieves a list of peers based on the specified criteria:
|
20852
|
-
* 1. If numPeers is 0, return all peers
|
20853
|
-
* 2. Bootstrap peers are prioritized
|
20854
|
-
* 3. Non-bootstrap peers are randomly selected to fill up to numPeers
|
20855
|
-
*
|
20856
|
-
* @param peers - The list of peers to filter from.
|
20857
|
-
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned, irrespective of `maxBootstrapPeers`.
|
20858
|
-
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
|
20859
|
-
* @returns An array of peers based on the specified criteria.
|
20860
|
-
*/
|
20861
|
-
function filterPeersByDiscovery(peers, numPeers, maxBootstrapPeers) {
|
20862
|
-
// Collect the bootstrap peers up to the specified maximum
|
20863
|
-
let bootstrapPeers = peers
|
20864
|
-
.filter((peer) => peer.tags.has(Tags.BOOTSTRAP))
|
20865
|
-
.slice(0, maxBootstrapPeers);
|
20866
|
-
// If numPeers is less than the number of bootstrap peers, adjust the bootstrapPeers array
|
20867
|
-
if (numPeers > 0 && numPeers < bootstrapPeers.length) {
|
20868
|
-
bootstrapPeers = bootstrapPeers.slice(0, numPeers);
|
20869
|
-
}
|
20870
|
-
// Collect non-bootstrap peers
|
20871
|
-
const nonBootstrapPeers = peers.filter((peer) => !peer.tags.has(Tags.BOOTSTRAP));
|
20872
|
-
// If numPeers is 0, return all peers
|
20873
|
-
if (numPeers === 0) {
|
20874
|
-
return [...bootstrapPeers, ...nonBootstrapPeers];
|
20875
|
-
}
|
20876
|
-
// Initialize the list of selected peers with the bootstrap peers
|
20877
|
-
const selectedPeers = [...bootstrapPeers];
|
20878
|
-
// Fill up to numPeers with remaining random peers if needed
|
20879
|
-
while (selectedPeers.length < numPeers && nonBootstrapPeers.length > 0) {
|
20880
|
-
const randomIndex = Math.floor(Math.random() * nonBootstrapPeers.length);
|
20881
|
-
const randomPeer = nonBootstrapPeers.splice(randomIndex, 1)[0];
|
20882
|
-
selectedPeers.push(randomPeer);
|
20883
|
-
}
|
20884
|
-
return selectedPeers;
|
20257
|
+
function wakuDnsDiscovery(enrUrls, wantedNodeCapabilityCount = DEFAULT_NODE_REQUIREMENTS) {
|
20258
|
+
return (components) => new PeerDiscoveryDns(components, { enrUrls, wantedNodeCapabilityCount });
|
20885
20259
|
}
|
20886
20260
|
|
20887
20261
|
function selectOpenConnection(connections) {
|
@@ -20906,36 +20280,36 @@ class StreamManager {
|
|
20906
20280
|
this.log = new Logger$1(`stream-manager:${multicodec}`);
|
20907
20281
|
this.addEventListener("peer:update", this.handlePeerUpdateStreamPool);
|
20908
20282
|
}
|
20909
|
-
async getStream(
|
20910
|
-
const
|
20911
|
-
const scheduledStream = this.streamPool.get(
|
20283
|
+
async getStream(peerId) {
|
20284
|
+
const peerIdStr = peerId.toString();
|
20285
|
+
const scheduledStream = this.streamPool.get(peerIdStr);
|
20912
20286
|
if (scheduledStream) {
|
20913
|
-
this.streamPool.delete(
|
20287
|
+
this.streamPool.delete(peerIdStr);
|
20914
20288
|
await scheduledStream;
|
20915
20289
|
}
|
20916
|
-
let stream = this.getOpenStreamForCodec(
|
20290
|
+
let stream = this.getOpenStreamForCodec(peerId);
|
20917
20291
|
if (stream) {
|
20918
|
-
this.log.info(`Found existing stream peerId=${
|
20919
|
-
this.lockStream(
|
20292
|
+
this.log.info(`Found existing stream peerId=${peerIdStr} multicodec=${this.multicodec}`);
|
20293
|
+
this.lockStream(peerIdStr, stream);
|
20920
20294
|
return stream;
|
20921
20295
|
}
|
20922
|
-
stream = await this.createStream(
|
20923
|
-
this.lockStream(
|
20296
|
+
stream = await this.createStream(peerId);
|
20297
|
+
this.lockStream(peerIdStr, stream);
|
20924
20298
|
return stream;
|
20925
20299
|
}
|
20926
|
-
async createStream(
|
20927
|
-
const connections = this.getConnections(
|
20300
|
+
async createStream(peerId, retries = 0) {
|
20301
|
+
const connections = this.getConnections(peerId);
|
20928
20302
|
const connection = selectOpenConnection(connections);
|
20929
20303
|
if (!connection) {
|
20930
|
-
throw new Error(`Failed to get a connection to the peer peerId=${
|
20304
|
+
throw new Error(`Failed to get a connection to the peer peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20931
20305
|
}
|
20932
20306
|
let lastError;
|
20933
20307
|
let stream;
|
20934
20308
|
for (let i = 0; i < retries + 1; i++) {
|
20935
20309
|
try {
|
20936
|
-
this.log.info(`Attempting to create a stream for peerId=${
|
20310
|
+
this.log.info(`Attempting to create a stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20937
20311
|
stream = await connection.newStream(this.multicodec);
|
20938
|
-
this.log.info(`Created stream for peerId=${
|
20312
|
+
this.log.info(`Created stream for peerId=${peerId.toString()} multicodec=${this.multicodec}`);
|
20939
20313
|
break;
|
20940
20314
|
}
|
20941
20315
|
catch (error) {
|
@@ -20943,8 +20317,7 @@ class StreamManager {
|
|
20943
20317
|
}
|
20944
20318
|
}
|
20945
20319
|
if (!stream) {
|
20946
|
-
throw new Error(`Failed to create a new stream for ${
|
20947
|
-
lastError);
|
20320
|
+
throw new Error(`Failed to create a new stream for ${peerId.toString()} -- ` + lastError);
|
20948
20321
|
}
|
20949
20322
|
return stream;
|
20950
20323
|
}
|
@@ -20956,7 +20329,7 @@ class StreamManager {
|
|
20956
20329
|
}
|
20957
20330
|
try {
|
20958
20331
|
this.ongoingCreation.add(peerId);
|
20959
|
-
await this.createStream(peer);
|
20332
|
+
await this.createStream(peer.id);
|
20960
20333
|
}
|
20961
20334
|
catch (error) {
|
20962
20335
|
this.log.error(`Failed to createStreamWithLock:`, error);
|
@@ -21017,62 +20390,20 @@ class StreamManager {
|
|
21017
20390
|
class BaseProtocol {
|
21018
20391
|
multicodec;
|
21019
20392
|
components;
|
21020
|
-
log;
|
21021
20393
|
pubsubTopics;
|
21022
20394
|
addLibp2pEventListener;
|
21023
20395
|
removeLibp2pEventListener;
|
21024
20396
|
streamManager;
|
21025
|
-
constructor(multicodec, components,
|
20397
|
+
constructor(multicodec, components, pubsubTopics) {
|
21026
20398
|
this.multicodec = multicodec;
|
21027
20399
|
this.components = components;
|
21028
|
-
this.log = log;
|
21029
20400
|
this.pubsubTopics = pubsubTopics;
|
21030
20401
|
this.addLibp2pEventListener = components.events.addEventListener.bind(components.events);
|
21031
20402
|
this.removeLibp2pEventListener = components.events.removeEventListener.bind(components.events);
|
21032
20403
|
this.streamManager = new StreamManager(multicodec, components.connectionManager.getConnections.bind(components.connectionManager), this.addLibp2pEventListener);
|
21033
20404
|
}
|
21034
|
-
async getStream(
|
21035
|
-
return this.streamManager.getStream(
|
21036
|
-
}
|
21037
|
-
/**
|
21038
|
-
* Returns known peers from the address book (`libp2p.peerStore`) that support
|
21039
|
-
* the class protocol. Waku may or may not be currently connected to these
|
21040
|
-
* peers.
|
21041
|
-
*/
|
21042
|
-
async allPeers() {
|
21043
|
-
return getPeersForProtocol(this.components.peerStore, [this.multicodec]);
|
21044
|
-
}
|
21045
|
-
async connectedPeers() {
|
21046
|
-
const peers = await this.allPeers();
|
21047
|
-
return peers.filter((peer) => {
|
21048
|
-
const connections = this.components.connectionManager.getConnections(peer.id);
|
21049
|
-
return connections.length > 0;
|
21050
|
-
});
|
21051
|
-
}
|
21052
|
-
/**
|
21053
|
-
* Retrieves a list of connected peers that support the protocol. The list is sorted by latency.
|
21054
|
-
*
|
21055
|
-
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned.
|
21056
|
-
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
|
21057
|
-
* @returns A list of peers that support the protocol sorted by latency. By default, returns all peers available, including bootstrap.
|
21058
|
-
*/
|
21059
|
-
async getPeers({ numPeers, maxBootstrapPeers } = {
|
21060
|
-
maxBootstrapPeers: 0,
|
21061
|
-
numPeers: 0
|
21062
|
-
}) {
|
21063
|
-
// Retrieve all connected peers that support the protocol & shard (if configured)
|
21064
|
-
const allAvailableConnectedPeers = await this.connectedPeers();
|
21065
|
-
// Filter the peers based on discovery & number of peers requested
|
21066
|
-
const filteredPeers = filterPeersByDiscovery(allAvailableConnectedPeers, numPeers, maxBootstrapPeers);
|
21067
|
-
// Sort the peers by latency
|
21068
|
-
const sortedFilteredPeers = await sortPeersByLatency(this.components.peerStore, filteredPeers);
|
21069
|
-
if (sortedFilteredPeers.length === 0) {
|
21070
|
-
this.log.warn("No peers found. Ensure you have a connection to the network.");
|
21071
|
-
}
|
21072
|
-
if (sortedFilteredPeers.length < numPeers) {
|
21073
|
-
this.log.warn(`Only ${sortedFilteredPeers.length} peers found. Requested ${numPeers}.`);
|
21074
|
-
}
|
21075
|
-
return sortedFilteredPeers;
|
20405
|
+
async getStream(peerId) {
|
20406
|
+
return this.streamManager.getStream(peerId);
|
21076
20407
|
}
|
21077
20408
|
}
|
21078
20409
|
|
@@ -24699,6 +24030,105 @@ var WakuMetadataResponse;
|
|
24699
24030
|
};
|
24700
24031
|
})(WakuMetadataResponse || (WakuMetadataResponse = {}));
|
24701
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
|
+
|
24702
24132
|
/**
|
24703
24133
|
* PeerExchangeRPC represents a message conforming to the Waku Peer Exchange protocol
|
24704
24134
|
*/
|
@@ -24749,7 +24179,7 @@ class WakuPeerExchange extends BaseProtocol {
|
|
24749
24179
|
* @param components - libp2p components
|
24750
24180
|
*/
|
24751
24181
|
constructor(components, pubsubTopics) {
|
24752
|
-
super(PeerExchangeCodec, components,
|
24182
|
+
super(PeerExchangeCodec, components, pubsubTopics);
|
24753
24183
|
}
|
24754
24184
|
/**
|
24755
24185
|
* Make a peer exchange query to a peer
|
@@ -24768,7 +24198,7 @@ class WakuPeerExchange extends BaseProtocol {
|
|
24768
24198
|
}
|
24769
24199
|
let stream;
|
24770
24200
|
try {
|
24771
|
-
stream = await this.getStream(
|
24201
|
+
stream = await this.getStream(peerId);
|
24772
24202
|
}
|
24773
24203
|
catch (err) {
|
24774
24204
|
log$2.error("Failed to get stream", err);
|
@@ -24983,7 +24413,7 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
|
|
24983
24413
|
const existingShardInfoBytes = peer.metadata.get("shardInfo");
|
24984
24414
|
if (existingShardInfoBytes) {
|
24985
24415
|
const existingShardInfo = decodeRelayShard(existingShardInfoBytes);
|
24986
|
-
|
24416
|
+
{
|
24987
24417
|
hasShardDiff =
|
24988
24418
|
existingShardInfo.clusterId !== shardInfo?.clusterId ||
|
24989
24419
|
existingShardInfo.shards.some((shard) => !shardInfo?.shards.includes(shard));
|
@@ -24999,50 +24429,210 @@ function wakuPeerExchangeDiscovery(pubsubTopics) {
|
|
24999
24429
|
/**
|
25000
24430
|
* @packageDocumentation
|
25001
24431
|
*
|
25002
|
-
*
|
25003
|
-
*
|
25004
|
-
* A Peer ID is the SHA-256 [multihash](https://github.com/multiformats/multihash) of a public key.
|
25005
|
-
*
|
25006
|
-
* 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
|
25007
24433
|
*
|
25008
24434
|
* @example
|
25009
24435
|
*
|
25010
24436
|
* ```TypeScript
|
25011
|
-
* import {
|
25012
|
-
*
|
25013
|
-
* const peerId = await createEd25519PeerId()
|
25014
|
-
* console.log(peerId.toString())
|
25015
|
-
* ```
|
24437
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
24438
|
+
* const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
|
25016
24439
|
*
|
25017
|
-
*
|
25018
|
-
*
|
24440
|
+
* console.log(peer.toCID()) // CID(bafzaa...)
|
24441
|
+
* console.log(peer.toString()) // "12D3K..."
|
25019
24442
|
* ```
|
25020
24443
|
*/
|
25021
|
-
|
25022
|
-
|
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
|
+
}
|
25023
24533
|
}
|
25024
|
-
|
25025
|
-
|
24534
|
+
class Secp256k1PeerId extends PeerIdImpl {
|
24535
|
+
type = 'secp256k1';
|
24536
|
+
publicKey;
|
24537
|
+
constructor(init) {
|
24538
|
+
super({ ...init, type: 'secp256k1' });
|
24539
|
+
this.publicKey = init.publicKey;
|
24540
|
+
}
|
25026
24541
|
}
|
25027
|
-
|
25028
|
-
|
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
|
+
}
|
25029
24578
|
}
|
25030
|
-
|
25031
|
-
|
25032
|
-
|
25033
|
-
|
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
|
+
}
|
25034
24606
|
}
|
25035
|
-
|
25036
|
-
|
25037
|
-
|
24607
|
+
return peerIdFromMultihash(multihash);
|
24608
|
+
}
|
24609
|
+
function peerIdFromMultihash(multihash) {
|
24610
|
+
if (isSha256Multihash(multihash)) {
|
24611
|
+
return new RSAPeerId({ multihash });
|
25038
24612
|
}
|
25039
|
-
|
25040
|
-
|
25041
|
-
|
25042
|
-
|
25043
|
-
|
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
|
+
}
|
25044
24628
|
}
|
25045
|
-
|
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;
|
25046
24636
|
}
|
25047
24637
|
|
25048
24638
|
const log = new Logger$1("peer-exchange-discovery");
|
@@ -25070,7 +24660,7 @@ class LocalPeerCacheDiscovery extends TypedEventEmitter {
|
|
25070
24660
|
log.info("Starting Local Storage Discovery");
|
25071
24661
|
this.components.events.addEventListener("peer:identify", this.handleNewPeers);
|
25072
24662
|
for (const { id: idStr, address } of this.peers) {
|
25073
|
-
const peerId =
|
24663
|
+
const peerId = peerIdFromString(idStr);
|
25074
24664
|
if (await this.components.peerStore.has(peerId))
|
25075
24665
|
continue;
|
25076
24666
|
await this.components.peerStore.save(peerId, {
|