@waku/discovery 0.0.6-2fe9875.0 → 0.0.6-426bfa4.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 +1067 -1555
- 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 +1 -1
- package/dist/peer-exchange/waku_peer_exchange.js.map +1 -1
- package/dist/peer-exchange/waku_peer_exchange_discovery.js +1 -1
- package/dist/peer-exchange/waku_peer_exchange_discovery.js.map +1 -1
- package/package.json +1 -1
- package/src/dns/dns_discovery.ts +0 -1
- package/src/local-peer-cache/index.ts +2 -3
- package/src/peer-exchange/waku_peer_exchange.ts +1 -1
- package/src/peer-exchange/waku_peer_exchange_discovery.ts +1 -1
package/bundle/index.js
CHANGED
@@ -19,31 +19,35 @@
|
|
19
19
|
*/
|
20
20
|
const peerDiscoverySymbol = Symbol.for('@libp2p/peer-discovery');
|
21
21
|
|
22
|
-
|
22
|
+
/**
|
23
|
+
* All PeerId implementations must use this symbol as the name of a property
|
24
|
+
* with a boolean `true` value
|
25
|
+
*/
|
26
|
+
const peerIdSymbol$1 = Symbol.for('@libp2p/peer-id');
|
23
27
|
|
24
28
|
/**
|
25
29
|
* When this error is thrown it means an operation was aborted,
|
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
|
+
let InvalidParametersError$1 = class InvalidParametersError extends Error {
|
37
|
+
static name = 'InvalidParametersError';
|
38
|
+
constructor(message = 'Invalid parameters') {
|
33
39
|
super(message);
|
34
|
-
this.
|
35
|
-
this.name = props?.name ?? 'CodeError';
|
36
|
-
this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
|
40
|
+
this.name = 'InvalidParametersError';
|
37
41
|
}
|
38
|
-
}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
this.
|
42
|
+
};
|
43
|
+
/**
|
44
|
+
* Thrown when an invalid multihash is encountered
|
45
|
+
*/
|
46
|
+
class InvalidMultihashError extends Error {
|
47
|
+
static name = 'InvalidMultihashError';
|
48
|
+
constructor(message = 'Invalid Multihash') {
|
49
|
+
super(message);
|
50
|
+
this.name = 'InvalidMultihashError';
|
47
51
|
}
|
48
52
|
}
|
49
53
|
|
@@ -114,7 +118,6 @@ class TypedEventEmitter extends EventTarget {
|
|
114
118
|
return this.dispatchEvent(new CustomEvent(type, detail));
|
115
119
|
}
|
116
120
|
}
|
117
|
-
const CustomEvent = globalThis.CustomEvent;
|
118
121
|
|
119
122
|
var Protocols;
|
120
123
|
(function (Protocols) {
|
@@ -292,23 +295,6 @@ const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLen
|
|
292
295
|
// The rotate right (circular right shift) operation for uint32
|
293
296
|
const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
|
294
297
|
new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
|
295
|
-
// There is no setImmediate in browser and setTimeout is slow.
|
296
|
-
// call of async fn will return Promise, which will be fullfiled only on
|
297
|
-
// next scheduler queue processing step and this is exactly what we need.
|
298
|
-
const nextTick = async () => { };
|
299
|
-
// Returns control to thread each 'tick' ms to avoid blocking
|
300
|
-
async function asyncLoop(iters, tick, cb) {
|
301
|
-
let ts = Date.now();
|
302
|
-
for (let i = 0; i < iters; i++) {
|
303
|
-
cb(i);
|
304
|
-
// Date.now() is not monotonic, so in case if clock goes backwards we return return control too
|
305
|
-
const diff = Date.now() - ts;
|
306
|
-
if (diff >= 0 && diff < tick)
|
307
|
-
continue;
|
308
|
-
await nextTick();
|
309
|
-
ts += diff;
|
310
|
-
}
|
311
|
-
}
|
312
298
|
/**
|
313
299
|
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
314
300
|
*/
|
@@ -353,13 +339,6 @@ class Hash {
|
|
353
339
|
return this._cloneInto();
|
354
340
|
}
|
355
341
|
}
|
356
|
-
const toStr = {}.toString;
|
357
|
-
function checkOpts(defaults, opts) {
|
358
|
-
if (opts !== undefined && toStr.call(opts) !== '[object Object]')
|
359
|
-
throw new Error('Options should be object or undefined');
|
360
|
-
const merged = Object.assign(defaults, opts);
|
361
|
-
return merged;
|
362
|
-
}
|
363
342
|
function wrapConstructor(hashCons) {
|
364
343
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
365
344
|
const tmp = hashCons();
|
@@ -371,14 +350,20 @@ function wrapConstructor(hashCons) {
|
|
371
350
|
/**
|
372
351
|
* Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
|
373
352
|
*/
|
374
|
-
function randomBytes
|
353
|
+
function randomBytes(bytesLength = 32) {
|
375
354
|
if (crypto$2 && typeof crypto$2.getRandomValues === 'function') {
|
376
355
|
return crypto$2.getRandomValues(new Uint8Array(bytesLength));
|
377
356
|
}
|
357
|
+
// Legacy Node.js compatibility
|
358
|
+
if (crypto$2 && typeof crypto$2.randomBytes === 'function') {
|
359
|
+
return crypto$2.randomBytes(bytesLength);
|
360
|
+
}
|
378
361
|
throw new Error('crypto.getRandomValues must be defined');
|
379
362
|
}
|
380
363
|
|
381
|
-
|
364
|
+
/**
|
365
|
+
* Polyfill for Safari 14
|
366
|
+
*/
|
382
367
|
function setBigUint64(view, byteOffset, value, isLE) {
|
383
368
|
if (typeof view.setBigUint64 === 'function')
|
384
369
|
return view.setBigUint64(byteOffset, value, isLE);
|
@@ -391,9 +376,13 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
391
376
|
view.setUint32(byteOffset + h, wh, isLE);
|
392
377
|
view.setUint32(byteOffset + l, wl, isLE);
|
393
378
|
}
|
394
|
-
|
379
|
+
/**
|
380
|
+
* Choice: a ? b : c
|
381
|
+
*/
|
395
382
|
const Chi = (a, b, c) => (a & b) ^ (~a & c);
|
396
|
-
|
383
|
+
/**
|
384
|
+
* Majority function, true if any two inputs is true
|
385
|
+
*/
|
397
386
|
const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
|
398
387
|
/**
|
399
388
|
* Merkle-Damgard hash construction base class.
|
@@ -838,11 +827,12 @@ class Decoder {
|
|
838
827
|
constructor(name, prefix, baseDecode) {
|
839
828
|
this.name = name;
|
840
829
|
this.prefix = prefix;
|
830
|
+
const prefixCodePoint = prefix.codePointAt(0);
|
841
831
|
/* c8 ignore next 3 */
|
842
|
-
if (
|
832
|
+
if (prefixCodePoint === undefined) {
|
843
833
|
throw new Error('Invalid prefix character');
|
844
834
|
}
|
845
|
-
this.prefixCodePoint =
|
835
|
+
this.prefixCodePoint = prefixCodePoint;
|
846
836
|
this.baseDecode = baseDecode;
|
847
837
|
}
|
848
838
|
decode(text) {
|
@@ -1046,7 +1036,14 @@ var base2$1 = /*#__PURE__*/Object.freeze({
|
|
1046
1036
|
|
1047
1037
|
const alphabet = Array.from('🚀🪐☄🛰🌌🌑🌒🌓🌔🌕🌖🌗🌘🌍🌏🌎🐉☀💻🖥💾💿😂❤😍🤣😊🙏💕😭😘👍😅👏😁🔥🥰💔💖💙😢🤔😆🙄💪😉☺👌🤗💜😔😎😇🌹🤦🎉💞✌✨🤷😱😌🌸🙌😋💗💚😏💛🙂💓🤩😄😀🖤😃💯🙈👇🎶😒🤭❣😜💋👀😪😑💥🙋😞😩😡🤪👊🥳😥🤤👉💃😳✋😚😝😴🌟😬🙃🍀🌷😻😓⭐✅🥺🌈😈🤘💦✔😣🏃💐☹🎊💘😠☝😕🌺🎂🌻😐🖕💝🙊😹🗣💫💀👑🎵🤞😛🔴😤🌼😫⚽🤙☕🏆🤫👈😮🙆🍻🍃🐶💁😲🌿🧡🎁⚡🌞🎈❌✊👋😰🤨😶🤝🚶💰🍓💢🤟🙁🚨💨🤬✈🎀🍺🤓😙💟🌱😖👶🥴▶➡❓💎💸⬇😨🌚🦋😷🕺⚠🙅😟😵👎🤲🤠🤧📌🔵💅🧐🐾🍒😗🤑🌊🤯🐷☎💧😯💆👆🎤🙇🍑❄🌴💣🐸💌📍🥀🤢👅💡💩👐📸👻🤐🤮🎼🥵🚩🍎🍊👼💍📣🥂');
|
1048
1038
|
const alphabetBytesToChars = (alphabet.reduce((p, c, i) => { p[i] = c; return p; }, ([])));
|
1049
|
-
const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => {
|
1039
|
+
const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => {
|
1040
|
+
const codePoint = c.codePointAt(0);
|
1041
|
+
if (codePoint == null) {
|
1042
|
+
throw new Error(`Invalid character: ${c}`);
|
1043
|
+
}
|
1044
|
+
p[codePoint] = i;
|
1045
|
+
return p;
|
1046
|
+
}, ([])));
|
1050
1047
|
function encode$8(data) {
|
1051
1048
|
return data.reduce((p, c) => {
|
1052
1049
|
p += alphabetBytesToChars[c];
|
@@ -1056,8 +1053,12 @@ function encode$8(data) {
|
|
1056
1053
|
function decode$9(str) {
|
1057
1054
|
const byts = [];
|
1058
1055
|
for (const char of str) {
|
1059
|
-
const
|
1060
|
-
if (
|
1056
|
+
const codePoint = char.codePointAt(0);
|
1057
|
+
if (codePoint == null) {
|
1058
|
+
throw new Error(`Invalid character: ${char}`);
|
1059
|
+
}
|
1060
|
+
const byt = alphabetCharsToBytes[codePoint];
|
1061
|
+
if (byt == null) {
|
1061
1062
|
throw new Error(`Non-base256emoji character: ${char}`);
|
1062
1063
|
}
|
1063
1064
|
byts.push(byt);
|
@@ -1330,7 +1331,7 @@ function encodingLength$3(int) {
|
|
1330
1331
|
/**
|
1331
1332
|
* Creates a multihash digest.
|
1332
1333
|
*/
|
1333
|
-
function create
|
1334
|
+
function create(code, digest) {
|
1334
1335
|
const size = digest.byteLength;
|
1335
1336
|
const sizeOffset = encodingLength$3(code);
|
1336
1337
|
const digestOffset = sizeOffset + encodingLength$3(size);
|
@@ -1389,7 +1390,7 @@ const code = 0x0;
|
|
1389
1390
|
const name$1 = 'identity';
|
1390
1391
|
const encode$6 = coerce;
|
1391
1392
|
function digest(input) {
|
1392
|
-
return create
|
1393
|
+
return create(code, encode$6(input));
|
1393
1394
|
}
|
1394
1395
|
const identity = { code, name: name$1, encode: encode$6, digest };
|
1395
1396
|
|
@@ -1413,9 +1414,9 @@ class Hasher {
|
|
1413
1414
|
if (input instanceof Uint8Array) {
|
1414
1415
|
const result = this.encode(input);
|
1415
1416
|
return result instanceof Uint8Array
|
1416
|
-
? create
|
1417
|
+
? create(this.code, result)
|
1417
1418
|
/* c8 ignore next 1 */
|
1418
|
-
: result.then(digest => create
|
1419
|
+
: result.then(digest => create(this.code, digest));
|
1419
1420
|
}
|
1420
1421
|
else {
|
1421
1422
|
throw Error('Unknown type, must be binary type');
|
@@ -1515,7 +1516,7 @@ class CID {
|
|
1515
1516
|
switch (this.version) {
|
1516
1517
|
case 0: {
|
1517
1518
|
const { code, digest } = this.multihash;
|
1518
|
-
const multihash = create
|
1519
|
+
const multihash = create(code, digest);
|
1519
1520
|
return (CID.createV1(this.code, multihash));
|
1520
1521
|
}
|
1521
1522
|
case 1: {
|
@@ -1745,9 +1746,13 @@ function parseCIDtoBytes(source, base) {
|
|
1745
1746
|
const decoder = base ?? base32$2;
|
1746
1747
|
return [base32$2.prefix, decoder.decode(source)];
|
1747
1748
|
}
|
1749
|
+
case base36.prefix: {
|
1750
|
+
const decoder = base ?? base36;
|
1751
|
+
return [base36.prefix, decoder.decode(source)];
|
1752
|
+
}
|
1748
1753
|
default: {
|
1749
1754
|
if (base == null) {
|
1750
|
-
throw Error('To parse non base32 or base58btc encoded CID multibase decoder must be provided');
|
1755
|
+
throw Error('To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided');
|
1751
1756
|
}
|
1752
1757
|
return [source[0], base.decode(source)];
|
1753
1758
|
}
|
@@ -1913,44 +1918,6 @@ const bytesToUtf8 = (b) => toString$6(b, "utf8");
|
|
1913
1918
|
*/
|
1914
1919
|
const utf8ToBytes$1 = (s) => fromString(s, "utf8");
|
1915
1920
|
|
1916
|
-
const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
|
1917
|
-
const parts = pubsubTopics.split("/");
|
1918
|
-
if (parts.length != 6 ||
|
1919
|
-
parts[1] !== "waku" ||
|
1920
|
-
parts[2] !== "2" ||
|
1921
|
-
parts[3] !== "rs")
|
1922
|
-
throw new Error("Invalid pubsub topic");
|
1923
|
-
const clusterId = parseInt(parts[4]);
|
1924
|
-
const shard = parseInt(parts[5]);
|
1925
|
-
if (isNaN(clusterId) || isNaN(shard))
|
1926
|
-
throw new Error("Invalid clusterId or shard");
|
1927
|
-
return {
|
1928
|
-
clusterId,
|
1929
|
-
shard
|
1930
|
-
};
|
1931
|
-
};
|
1932
|
-
const pubsubTopicsToShardInfo = (pubsubTopics) => {
|
1933
|
-
const shardInfoSet = new Set();
|
1934
|
-
const clusterIds = new Set();
|
1935
|
-
for (const topic of pubsubTopics) {
|
1936
|
-
const { clusterId, shard } = pubsubTopicToSingleShardInfo(topic);
|
1937
|
-
shardInfoSet.add(`${clusterId}:${shard}`);
|
1938
|
-
clusterIds.add(clusterId);
|
1939
|
-
}
|
1940
|
-
if (shardInfoSet.size === 0) {
|
1941
|
-
throw new Error("No valid pubsub topics provided");
|
1942
|
-
}
|
1943
|
-
if (clusterIds.size > 1) {
|
1944
|
-
throw new Error("Pubsub topics from multiple cluster IDs are not supported");
|
1945
|
-
}
|
1946
|
-
const clusterId = clusterIds.values().next().value;
|
1947
|
-
const shards = Array.from(shardInfoSet).map((info) => parseInt(info.split(":")[1]));
|
1948
|
-
return {
|
1949
|
-
clusterId,
|
1950
|
-
shards
|
1951
|
-
};
|
1952
|
-
};
|
1953
|
-
|
1954
1921
|
const decodeRelayShard = (bytes) => {
|
1955
1922
|
// explicitly converting to Uint8Array to avoid Buffer
|
1956
1923
|
// https://github.com/libp2p/js-libp2p/issues/2146
|
@@ -2052,7 +2019,7 @@ function requireMs () {
|
|
2052
2019
|
* @api public
|
2053
2020
|
*/
|
2054
2021
|
|
2055
|
-
ms = function(val, options) {
|
2022
|
+
ms = function (val, options) {
|
2056
2023
|
options = options || {};
|
2057
2024
|
var type = typeof val;
|
2058
2025
|
if (type === 'string' && val.length > 0) {
|
@@ -5565,7 +5532,7 @@ function ParseError(str) {
|
|
5565
5532
|
* const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
5566
5533
|
* ```
|
5567
5534
|
*/
|
5568
|
-
const inspect$
|
5535
|
+
const inspect$2 = Symbol.for('nodejs.util.inspect.custom');
|
5569
5536
|
const symbol$1 = Symbol.for('@multiformats/js-multiaddr/multiaddr');
|
5570
5537
|
const DNS_CODES = [
|
5571
5538
|
getProtocol('dns').code,
|
@@ -5573,6 +5540,12 @@ const DNS_CODES = [
|
|
5573
5540
|
getProtocol('dns6').code,
|
5574
5541
|
getProtocol('dnsaddr').code
|
5575
5542
|
];
|
5543
|
+
class NoAvailableResolverError extends Error {
|
5544
|
+
constructor(message = 'No available resolver') {
|
5545
|
+
super(message);
|
5546
|
+
this.name = 'NoAvailableResolverError';
|
5547
|
+
}
|
5548
|
+
}
|
5576
5549
|
/**
|
5577
5550
|
* Creates a {@link Multiaddr} from a {@link MultiaddrInput}
|
5578
5551
|
*/
|
@@ -5742,7 +5715,7 @@ class Multiaddr {
|
|
5742
5715
|
}
|
5743
5716
|
const resolver = resolvers$1.get(resolvableProto.name);
|
5744
5717
|
if (resolver == null) {
|
5745
|
-
throw new
|
5718
|
+
throw new NoAvailableResolverError(`no available resolver for ${resolvableProto.name}`);
|
5746
5719
|
}
|
5747
5720
|
const result = await resolver(this, options);
|
5748
5721
|
return result.map(str => multiaddr(str));
|
@@ -5783,7 +5756,7 @@ class Multiaddr {
|
|
5783
5756
|
* // 'Multiaddr(/ip4/127.0.0.1/tcp/4001)'
|
5784
5757
|
* ```
|
5785
5758
|
*/
|
5786
|
-
[inspect$
|
5759
|
+
[inspect$2]() {
|
5787
5760
|
return `Multiaddr(${this.#string})`;
|
5788
5761
|
}
|
5789
5762
|
}
|
@@ -5956,14 +5929,41 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
|
|
5956
5929
|
return multiaddrFromFields(isIpv6 ? "ip6" : "ip4", protoName, ipVal, protoVal);
|
5957
5930
|
}
|
5958
5931
|
|
5959
|
-
|
5960
|
-
|
5961
|
-
|
5932
|
+
/**
|
5933
|
+
* When this error is thrown it means an operation was aborted,
|
5934
|
+
* usually in response to the `abort` event being emitted by an
|
5935
|
+
* AbortSignal.
|
5936
|
+
*/
|
5937
|
+
/**
|
5938
|
+
* Thrown when invalid parameters are passed to a function or method call
|
5939
|
+
*/
|
5940
|
+
class InvalidParametersError extends Error {
|
5941
|
+
static name = 'InvalidParametersError';
|
5942
|
+
constructor(message = 'Invalid parameters') {
|
5943
|
+
super(message);
|
5944
|
+
this.name = 'InvalidParametersError';
|
5945
|
+
}
|
5946
|
+
}
|
5947
|
+
/**
|
5948
|
+
* Thrown when a public key is invalid
|
5949
|
+
*/
|
5950
|
+
class InvalidPublicKeyError extends Error {
|
5951
|
+
static name = 'InvalidPublicKeyError';
|
5952
|
+
constructor(message = 'Invalid public key') {
|
5953
|
+
super(message);
|
5954
|
+
this.name = 'InvalidPublicKeyError';
|
5962
5955
|
}
|
5963
|
-
return typeof thing.then === 'function' &&
|
5964
|
-
typeof thing.catch === 'function' &&
|
5965
|
-
typeof thing.finally === 'function';
|
5966
5956
|
}
|
5957
|
+
/**
|
5958
|
+
* Thrown when and attempt to operate on an unsupported key was made
|
5959
|
+
*/
|
5960
|
+
let UnsupportedKeyTypeError$1 = class UnsupportedKeyTypeError extends Error {
|
5961
|
+
static name = 'UnsupportedKeyTypeError';
|
5962
|
+
constructor(message = 'Unsupported key type') {
|
5963
|
+
super(message);
|
5964
|
+
this.name = 'UnsupportedKeyTypeError';
|
5965
|
+
}
|
5966
|
+
};
|
5967
5967
|
|
5968
5968
|
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
5969
5969
|
const _32n = /* @__PURE__ */ BigInt(32);
|
@@ -7050,6 +7050,60 @@ function wNAF(c, bits) {
|
|
7050
7050
|
},
|
7051
7051
|
};
|
7052
7052
|
}
|
7053
|
+
/**
|
7054
|
+
* Pippenger algorithm for multi-scalar multiplication (MSM).
|
7055
|
+
* MSM is basically (Pa + Qb + Rc + ...).
|
7056
|
+
* 30x faster vs naive addition on L=4096, 10x faster with precomputes.
|
7057
|
+
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
7058
|
+
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
7059
|
+
* @param c Curve Point constructor
|
7060
|
+
* @param field field over CURVE.N - important that it's not over CURVE.P
|
7061
|
+
* @param points array of L curve points
|
7062
|
+
* @param scalars array of L scalars (aka private keys / bigints)
|
7063
|
+
*/
|
7064
|
+
function pippenger(c, field, points, scalars) {
|
7065
|
+
// If we split scalars by some window (let's say 8 bits), every chunk will only
|
7066
|
+
// take 256 buckets even if there are 4096 scalars, also re-uses double.
|
7067
|
+
// TODO:
|
7068
|
+
// - https://eprint.iacr.org/2024/750.pdf
|
7069
|
+
// - https://tches.iacr.org/index.php/TCHES/article/view/10287
|
7070
|
+
// 0 is accepted in scalars
|
7071
|
+
if (!Array.isArray(points) || !Array.isArray(scalars) || scalars.length !== points.length)
|
7072
|
+
throw new Error('arrays of points and scalars must have equal length');
|
7073
|
+
scalars.forEach((s, i) => {
|
7074
|
+
if (!field.isValid(s))
|
7075
|
+
throw new Error(`wrong scalar at index ${i}`);
|
7076
|
+
});
|
7077
|
+
points.forEach((p, i) => {
|
7078
|
+
if (!(p instanceof c))
|
7079
|
+
throw new Error(`wrong point at index ${i}`);
|
7080
|
+
});
|
7081
|
+
const wbits = bitLen(BigInt(points.length));
|
7082
|
+
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
7083
|
+
const MASK = (1 << windowSize) - 1;
|
7084
|
+
const buckets = new Array(MASK + 1).fill(c.ZERO); // +1 for zero array
|
7085
|
+
const lastBits = Math.floor((field.BITS - 1) / windowSize) * windowSize;
|
7086
|
+
let sum = c.ZERO;
|
7087
|
+
for (let i = lastBits; i >= 0; i -= windowSize) {
|
7088
|
+
buckets.fill(c.ZERO);
|
7089
|
+
for (let j = 0; j < scalars.length; j++) {
|
7090
|
+
const scalar = scalars[j];
|
7091
|
+
const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
|
7092
|
+
buckets[wbits] = buckets[wbits].add(points[j]);
|
7093
|
+
}
|
7094
|
+
let resI = c.ZERO; // not using this will do small speed-up, but will lose ct
|
7095
|
+
// Skip first bucket, because it is zero
|
7096
|
+
for (let j = buckets.length - 1, sumI = c.ZERO; j > 0; j--) {
|
7097
|
+
sumI = sumI.add(buckets[j]);
|
7098
|
+
resI = resI.add(sumI);
|
7099
|
+
}
|
7100
|
+
sum = sum.add(resI);
|
7101
|
+
if (i !== 0)
|
7102
|
+
for (let j = 0; j < windowSize; j++)
|
7103
|
+
sum = sum.double();
|
7104
|
+
}
|
7105
|
+
return sum;
|
7106
|
+
}
|
7053
7107
|
function validateBasic(curve) {
|
7054
7108
|
validateField(curve.Fp);
|
7055
7109
|
validateObject(curve, {
|
@@ -7104,6 +7158,7 @@ function twistedEdwards(curveDef) {
|
|
7104
7158
|
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
7105
7159
|
const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
|
7106
7160
|
const modP = Fp.create; // Function overrides
|
7161
|
+
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
7107
7162
|
// sqrt(u/v)
|
7108
7163
|
const uvRatio = CURVE.uvRatio ||
|
7109
7164
|
((u, v) => {
|
@@ -7202,6 +7257,10 @@ function twistedEdwards(curveDef) {
|
|
7202
7257
|
const toInv = Fp.invertBatch(points.map((p) => p.ez));
|
7203
7258
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
7204
7259
|
}
|
7260
|
+
// Multiscalar Multiplication
|
7261
|
+
static msm(points, scalars) {
|
7262
|
+
return pippenger(Point, Fn, points, scalars);
|
7263
|
+
}
|
7205
7264
|
// "Private method", don't use it directly
|
7206
7265
|
_setWindowSize(windowSize) {
|
7207
7266
|
wnaf.setWindowSize(this, windowSize);
|
@@ -7577,7 +7636,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7577
7636
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
7578
7637
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
7579
7638
|
hash: sha512,
|
7580
|
-
randomBytes
|
7639
|
+
randomBytes,
|
7581
7640
|
adjustScalarBytes,
|
7582
7641
|
// dom2
|
7583
7642
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
@@ -7590,176 +7649,46 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7590
7649
|
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7591
7650
|
|
7592
7651
|
const PUBLIC_KEY_BYTE_LENGTH = 32;
|
7593
|
-
const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
7594
|
-
const KEYS_BYTE_LENGTH = 32;
|
7595
|
-
function generateKey$2() {
|
7596
|
-
// the actual private key (32 bytes)
|
7597
|
-
const privateKeyRaw = ed25519.utils.randomPrivateKey();
|
7598
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7599
|
-
// concatenated the public key to the private key
|
7600
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7601
|
-
return {
|
7602
|
-
privateKey,
|
7603
|
-
publicKey
|
7604
|
-
};
|
7605
|
-
}
|
7606
|
-
/**
|
7607
|
-
* Generate keypair from a 32 byte uint8array
|
7608
|
-
*/
|
7609
|
-
function generateKeyFromSeed(seed) {
|
7610
|
-
if (seed.length !== KEYS_BYTE_LENGTH) {
|
7611
|
-
throw new TypeError('"seed" must be 32 bytes in length.');
|
7612
|
-
}
|
7613
|
-
else if (!(seed instanceof Uint8Array)) {
|
7614
|
-
throw new TypeError('"seed" must be a node.js Buffer, or Uint8Array.');
|
7615
|
-
}
|
7616
|
-
// based on node forges algorithm, the seed is used directly as private key
|
7617
|
-
const privateKeyRaw = seed;
|
7618
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7619
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7620
|
-
return {
|
7621
|
-
privateKey,
|
7622
|
-
publicKey
|
7623
|
-
};
|
7624
|
-
}
|
7625
|
-
function hashAndSign$2(privateKey, msg) {
|
7626
|
-
const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH);
|
7627
|
-
return ed25519.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw);
|
7628
|
-
}
|
7629
7652
|
function hashAndVerify$2(publicKey, sig, msg) {
|
7630
7653
|
return ed25519.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey);
|
7631
7654
|
}
|
7632
|
-
function concatKeys(privateKeyRaw, publicKey) {
|
7633
|
-
const privateKey = new Uint8Array(PRIVATE_KEY_BYTE_LENGTH);
|
7634
|
-
for (let i = 0; i < KEYS_BYTE_LENGTH; i++) {
|
7635
|
-
privateKey[i] = privateKeyRaw[i];
|
7636
|
-
privateKey[KEYS_BYTE_LENGTH + i] = publicKey[i];
|
7637
|
-
}
|
7638
|
-
return privateKey;
|
7639
|
-
}
|
7640
7655
|
|
7641
|
-
|
7642
|
-
|
7643
|
-
|
7644
|
-
|
7645
|
-
|
7646
|
-
const nativeCrypto = win.crypto;
|
7647
|
-
if (nativeCrypto?.subtle == null) {
|
7648
|
-
throw Object.assign(new Error('Missing Web Crypto API. ' +
|
7649
|
-
'The most likely cause of this error is that this page is being accessed ' +
|
7650
|
-
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
7651
|
-
'possible resolutions see ' +
|
7652
|
-
'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api'), { code: 'ERR_MISSING_WEB_CRYPTO' });
|
7653
|
-
}
|
7654
|
-
return nativeCrypto;
|
7656
|
+
class Ed25519PublicKey {
|
7657
|
+
type = 'Ed25519';
|
7658
|
+
raw;
|
7659
|
+
constructor(key) {
|
7660
|
+
this.raw = ensureEd25519Key(key, PUBLIC_KEY_BYTE_LENGTH);
|
7655
7661
|
}
|
7656
|
-
|
7657
|
-
|
7658
|
-
// WebKit on Linux does not support deriving a key from an empty PBKDF2 key.
|
7659
|
-
// So, as a workaround, we provide the generated key as a constant. We test that
|
7660
|
-
// this generated key is accurate in test/workaround.spec.ts
|
7661
|
-
// Generated via:
|
7662
|
-
// await crypto.subtle.exportKey('jwk',
|
7663
|
-
// await crypto.subtle.deriveKey(
|
7664
|
-
// { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } },
|
7665
|
-
// await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']),
|
7666
|
-
// { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt'])
|
7667
|
-
// )
|
7668
|
-
const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
|
7669
|
-
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
|
7670
|
-
function create(opts) {
|
7671
|
-
const algorithm = 'AES-GCM';
|
7672
|
-
let keyLength = 16;
|
7673
|
-
const nonceLength = 12;
|
7674
|
-
const digest = 'SHA-256';
|
7675
|
-
const saltLength = 16;
|
7676
|
-
const iterations = 32767;
|
7677
|
-
const crypto = webcrypto.get();
|
7678
|
-
keyLength *= 8; // Browser crypto uses bits instead of bytes
|
7679
|
-
/**
|
7680
|
-
* Uses the provided password to derive a pbkdf2 key. The key
|
7681
|
-
* will then be used to encrypt the data.
|
7682
|
-
*/
|
7683
|
-
async function encrypt(data, password) {
|
7684
|
-
const salt = crypto.getRandomValues(new Uint8Array(saltLength));
|
7685
|
-
const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
|
7686
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7687
|
-
if (typeof password === 'string') {
|
7688
|
-
password = fromString(password);
|
7689
|
-
}
|
7690
|
-
let cryptoKey;
|
7691
|
-
if (password.length === 0) {
|
7692
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7693
|
-
try {
|
7694
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7695
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7696
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7697
|
-
}
|
7698
|
-
catch {
|
7699
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7700
|
-
}
|
7701
|
-
}
|
7702
|
-
else {
|
7703
|
-
// Derive a key using PBKDF2.
|
7704
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7705
|
-
const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7706
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7707
|
-
}
|
7708
|
-
// Encrypt the string.
|
7709
|
-
const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data);
|
7710
|
-
return concat$1([salt, aesGcm.iv, new Uint8Array(ciphertext)]);
|
7662
|
+
toMultihash() {
|
7663
|
+
return identity.digest(publicKeyToProtobuf(this));
|
7711
7664
|
}
|
7712
|
-
|
7713
|
-
|
7714
|
-
|
7715
|
-
|
7716
|
-
|
7717
|
-
|
7718
|
-
|
7719
|
-
|
7720
|
-
|
7721
|
-
const ciphertext = data.subarray(saltLength + nonceLength);
|
7722
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7723
|
-
if (typeof password === 'string') {
|
7724
|
-
password = fromString(password);
|
7725
|
-
}
|
7726
|
-
let cryptoKey;
|
7727
|
-
if (password.length === 0) {
|
7728
|
-
try {
|
7729
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7730
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7731
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['decrypt']);
|
7732
|
-
}
|
7733
|
-
catch {
|
7734
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']);
|
7735
|
-
}
|
7665
|
+
toCID() {
|
7666
|
+
return CID.createV1(114, this.toMultihash());
|
7667
|
+
}
|
7668
|
+
toString() {
|
7669
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
7670
|
+
}
|
7671
|
+
equals(key) {
|
7672
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
7673
|
+
return false;
|
7736
7674
|
}
|
7737
|
-
|
7738
|
-
|
7739
|
-
|
7740
|
-
|
7741
|
-
|
7742
|
-
}
|
7743
|
-
// Decrypt the string.
|
7744
|
-
const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext);
|
7745
|
-
return new Uint8Array(plaintext);
|
7746
|
-
}
|
7747
|
-
const cipher = {
|
7748
|
-
encrypt,
|
7749
|
-
decrypt
|
7750
|
-
};
|
7751
|
-
return cipher;
|
7675
|
+
return equals(this.raw, key.raw);
|
7676
|
+
}
|
7677
|
+
verify(data, sig) {
|
7678
|
+
return hashAndVerify$2(this.raw, sig, data);
|
7679
|
+
}
|
7752
7680
|
}
|
7753
7681
|
|
7754
|
-
|
7755
|
-
|
7756
|
-
|
7757
|
-
|
7758
|
-
|
7759
|
-
|
7760
|
-
|
7761
|
-
|
7762
|
-
|
7682
|
+
function unmarshalEd25519PublicKey(bytes) {
|
7683
|
+
bytes = ensureEd25519Key(bytes, PUBLIC_KEY_BYTE_LENGTH);
|
7684
|
+
return new Ed25519PublicKey(bytes);
|
7685
|
+
}
|
7686
|
+
function ensureEd25519Key(key, length) {
|
7687
|
+
key = Uint8Array.from(key ?? []);
|
7688
|
+
if (key.length !== length) {
|
7689
|
+
throw new InvalidParametersError(`Key must be a Uint8Array of length ${length}, got ${key.length}`);
|
7690
|
+
}
|
7691
|
+
return key;
|
7763
7692
|
}
|
7764
7693
|
|
7765
7694
|
const f32 = new Float32Array([-0]);
|
@@ -8992,13 +8921,13 @@ var KeyType;
|
|
8992
8921
|
(function (KeyType) {
|
8993
8922
|
KeyType["RSA"] = "RSA";
|
8994
8923
|
KeyType["Ed25519"] = "Ed25519";
|
8995
|
-
KeyType["
|
8924
|
+
KeyType["secp256k1"] = "secp256k1";
|
8996
8925
|
})(KeyType || (KeyType = {}));
|
8997
8926
|
var __KeyTypeValues;
|
8998
8927
|
(function (__KeyTypeValues) {
|
8999
8928
|
__KeyTypeValues[__KeyTypeValues["RSA"] = 0] = "RSA";
|
9000
8929
|
__KeyTypeValues[__KeyTypeValues["Ed25519"] = 1] = "Ed25519";
|
9001
|
-
__KeyTypeValues[__KeyTypeValues["
|
8930
|
+
__KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1";
|
9002
8931
|
})(__KeyTypeValues || (__KeyTypeValues = {}));
|
9003
8932
|
(function (KeyType) {
|
9004
8933
|
KeyType.codec = () => {
|
@@ -9025,21 +8954,24 @@ var PublicKey;
|
|
9025
8954
|
if (opts.lengthDelimited !== false) {
|
9026
8955
|
w.ldelim();
|
9027
8956
|
}
|
9028
|
-
}, (reader, length) => {
|
8957
|
+
}, (reader, length, opts = {}) => {
|
9029
8958
|
const obj = {};
|
9030
8959
|
const end = length == null ? reader.len : reader.pos + length;
|
9031
8960
|
while (reader.pos < end) {
|
9032
8961
|
const tag = reader.uint32();
|
9033
8962
|
switch (tag >>> 3) {
|
9034
|
-
case 1:
|
8963
|
+
case 1: {
|
9035
8964
|
obj.Type = KeyType.codec().decode(reader);
|
9036
8965
|
break;
|
9037
|
-
|
8966
|
+
}
|
8967
|
+
case 2: {
|
9038
8968
|
obj.Data = reader.bytes();
|
9039
8969
|
break;
|
9040
|
-
|
8970
|
+
}
|
8971
|
+
default: {
|
9041
8972
|
reader.skipType(tag & 7);
|
9042
8973
|
break;
|
8974
|
+
}
|
9043
8975
|
}
|
9044
8976
|
}
|
9045
8977
|
return obj;
|
@@ -9050,8 +8982,8 @@ var PublicKey;
|
|
9050
8982
|
PublicKey.encode = (obj) => {
|
9051
8983
|
return encodeMessage(obj, PublicKey.codec());
|
9052
8984
|
};
|
9053
|
-
PublicKey.decode = (buf) => {
|
9054
|
-
return decodeMessage(buf, PublicKey.codec());
|
8985
|
+
PublicKey.decode = (buf, opts) => {
|
8986
|
+
return decodeMessage(buf, PublicKey.codec(), opts);
|
9055
8987
|
};
|
9056
8988
|
})(PublicKey || (PublicKey = {}));
|
9057
8989
|
var PrivateKey;
|
@@ -9074,21 +9006,24 @@ var PrivateKey;
|
|
9074
9006
|
if (opts.lengthDelimited !== false) {
|
9075
9007
|
w.ldelim();
|
9076
9008
|
}
|
9077
|
-
}, (reader, length) => {
|
9009
|
+
}, (reader, length, opts = {}) => {
|
9078
9010
|
const obj = {};
|
9079
9011
|
const end = length == null ? reader.len : reader.pos + length;
|
9080
9012
|
while (reader.pos < end) {
|
9081
9013
|
const tag = reader.uint32();
|
9082
9014
|
switch (tag >>> 3) {
|
9083
|
-
case 1:
|
9015
|
+
case 1: {
|
9084
9016
|
obj.Type = KeyType.codec().decode(reader);
|
9085
9017
|
break;
|
9086
|
-
|
9018
|
+
}
|
9019
|
+
case 2: {
|
9087
9020
|
obj.Data = reader.bytes();
|
9088
9021
|
break;
|
9089
|
-
|
9022
|
+
}
|
9023
|
+
default: {
|
9090
9024
|
reader.skipType(tag & 7);
|
9091
9025
|
break;
|
9026
|
+
}
|
9092
9027
|
}
|
9093
9028
|
}
|
9094
9029
|
return obj;
|
@@ -9099,377 +9034,106 @@ var PrivateKey;
|
|
9099
9034
|
PrivateKey.encode = (obj) => {
|
9100
9035
|
return encodeMessage(obj, PrivateKey.codec());
|
9101
9036
|
};
|
9102
|
-
PrivateKey.decode = (buf) => {
|
9103
|
-
return decodeMessage(buf, PrivateKey.codec());
|
9037
|
+
PrivateKey.decode = (buf, opts) => {
|
9038
|
+
return decodeMessage(buf, PrivateKey.codec(), opts);
|
9104
9039
|
};
|
9105
9040
|
})(PrivateKey || (PrivateKey = {}));
|
9106
9041
|
|
9107
|
-
|
9108
|
-
|
9109
|
-
|
9110
|
-
|
9111
|
-
|
9112
|
-
|
9113
|
-
|
9114
|
-
|
9115
|
-
|
9116
|
-
|
9117
|
-
|
9118
|
-
|
9119
|
-
|
9120
|
-
|
9121
|
-
|
9122
|
-
|
9123
|
-
|
9124
|
-
|
9125
|
-
|
9042
|
+
/*!
|
9043
|
+
* MIT License
|
9044
|
+
*
|
9045
|
+
* Copyright (c) 2017-2022 Peculiar Ventures, LLC
|
9046
|
+
*
|
9047
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9048
|
+
* of this software and associated documentation files (the "Software"), to deal
|
9049
|
+
* in the Software without restriction, including without limitation the rights
|
9050
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9051
|
+
* copies of the Software, and to permit persons to whom the Software is
|
9052
|
+
* furnished to do so, subject to the following conditions:
|
9053
|
+
*
|
9054
|
+
* The above copyright notice and this permission notice shall be included in all
|
9055
|
+
* copies or substantial portions of the Software.
|
9056
|
+
*
|
9057
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
9058
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
9059
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
9060
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
9061
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
9062
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
9063
|
+
* SOFTWARE.
|
9064
|
+
*
|
9065
|
+
*/
|
9066
|
+
|
9067
|
+
const ARRAY_BUFFER_NAME = "[object ArrayBuffer]";
|
9068
|
+
class BufferSourceConverter {
|
9069
|
+
static isArrayBuffer(data) {
|
9070
|
+
return Object.prototype.toString.call(data) === ARRAY_BUFFER_NAME;
|
9126
9071
|
}
|
9127
|
-
|
9128
|
-
|
9129
|
-
|
9130
|
-
return p.then(({ bytes }) => bytes);
|
9072
|
+
static toArrayBuffer(data) {
|
9073
|
+
if (this.isArrayBuffer(data)) {
|
9074
|
+
return data;
|
9131
9075
|
}
|
9132
|
-
|
9133
|
-
|
9134
|
-
}
|
9135
|
-
|
9136
|
-
|
9137
|
-
|
9138
|
-
|
9139
|
-
|
9140
|
-
|
9141
|
-
this._key = ensureKey(key, PRIVATE_KEY_BYTE_LENGTH);
|
9142
|
-
this._publicKey = ensureKey(publicKey, PUBLIC_KEY_BYTE_LENGTH);
|
9143
|
-
}
|
9144
|
-
sign(message) {
|
9145
|
-
return hashAndSign$2(this._key, message);
|
9076
|
+
if (data.byteLength === data.buffer.byteLength) {
|
9077
|
+
return data.buffer;
|
9078
|
+
}
|
9079
|
+
if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
|
9080
|
+
return data.buffer;
|
9081
|
+
}
|
9082
|
+
return this.toUint8Array(data.buffer)
|
9083
|
+
.slice(data.byteOffset, data.byteOffset + data.byteLength)
|
9084
|
+
.buffer;
|
9146
9085
|
}
|
9147
|
-
|
9148
|
-
return
|
9086
|
+
static toUint8Array(data) {
|
9087
|
+
return this.toView(data, Uint8Array);
|
9149
9088
|
}
|
9150
|
-
|
9151
|
-
|
9089
|
+
static toView(data, type) {
|
9090
|
+
if (data.constructor === type) {
|
9091
|
+
return data;
|
9092
|
+
}
|
9093
|
+
if (this.isArrayBuffer(data)) {
|
9094
|
+
return new type(data);
|
9095
|
+
}
|
9096
|
+
if (this.isArrayBufferView(data)) {
|
9097
|
+
return new type(data.buffer, data.byteOffset, data.byteLength);
|
9098
|
+
}
|
9099
|
+
throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
|
9152
9100
|
}
|
9153
|
-
|
9154
|
-
return
|
9155
|
-
|
9156
|
-
Data: this.marshal()
|
9157
|
-
}).subarray();
|
9101
|
+
static isBufferSource(data) {
|
9102
|
+
return this.isArrayBufferView(data)
|
9103
|
+
|| this.isArrayBuffer(data);
|
9158
9104
|
}
|
9159
|
-
|
9160
|
-
return
|
9105
|
+
static isArrayBufferView(data) {
|
9106
|
+
return ArrayBuffer.isView(data)
|
9107
|
+
|| (data && this.isArrayBuffer(data.buffer));
|
9161
9108
|
}
|
9162
|
-
|
9163
|
-
const
|
9164
|
-
|
9165
|
-
if (
|
9166
|
-
|
9109
|
+
static isEqual(a, b) {
|
9110
|
+
const aView = BufferSourceConverter.toUint8Array(a);
|
9111
|
+
const bView = BufferSourceConverter.toUint8Array(b);
|
9112
|
+
if (aView.length !== bView.byteLength) {
|
9113
|
+
return false;
|
9167
9114
|
}
|
9168
|
-
|
9169
|
-
|
9115
|
+
for (let i = 0; i < aView.length; i++) {
|
9116
|
+
if (aView[i] !== bView[i]) {
|
9117
|
+
return false;
|
9118
|
+
}
|
9170
9119
|
}
|
9171
|
-
return
|
9172
|
-
}
|
9173
|
-
/**
|
9174
|
-
* Gets the ID of the key.
|
9175
|
-
*
|
9176
|
-
* The key id is the base58 encoding of the identity multihash containing its public key.
|
9177
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
9178
|
-
* of the PKCS SubjectPublicKeyInfo.
|
9179
|
-
*
|
9180
|
-
* @returns {Promise<string>}
|
9181
|
-
*/
|
9182
|
-
async id() {
|
9183
|
-
const encoding = identity.digest(this.public.bytes);
|
9184
|
-
return base58btc.encode(encoding.bytes).substring(1);
|
9120
|
+
return true;
|
9185
9121
|
}
|
9186
|
-
|
9187
|
-
|
9188
|
-
|
9189
|
-
|
9190
|
-
|
9191
|
-
|
9122
|
+
static concat(...args) {
|
9123
|
+
let buffers;
|
9124
|
+
if (Array.isArray(args[0]) && !(args[1] instanceof Function)) {
|
9125
|
+
buffers = args[0];
|
9126
|
+
}
|
9127
|
+
else if (Array.isArray(args[0]) && args[1] instanceof Function) {
|
9128
|
+
buffers = args[0];
|
9192
9129
|
}
|
9193
9130
|
else {
|
9194
|
-
|
9195
|
-
|
9196
|
-
|
9197
|
-
|
9198
|
-
|
9199
|
-
|
9200
|
-
if (bytes.length > PRIVATE_KEY_BYTE_LENGTH) {
|
9201
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH + PUBLIC_KEY_BYTE_LENGTH);
|
9202
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9203
|
-
const publicKeyBytes = bytes.subarray(PRIVATE_KEY_BYTE_LENGTH, bytes.length);
|
9204
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9205
|
-
}
|
9206
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH);
|
9207
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9208
|
-
const publicKeyBytes = bytes.subarray(PUBLIC_KEY_BYTE_LENGTH);
|
9209
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9210
|
-
}
|
9211
|
-
function unmarshalEd25519PublicKey(bytes) {
|
9212
|
-
bytes = ensureKey(bytes, PUBLIC_KEY_BYTE_LENGTH);
|
9213
|
-
return new Ed25519PublicKey(bytes);
|
9214
|
-
}
|
9215
|
-
async function generateKeyPair$2() {
|
9216
|
-
const { privateKey, publicKey } = generateKey$2();
|
9217
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9218
|
-
}
|
9219
|
-
async function generateKeyPairFromSeed(seed) {
|
9220
|
-
const { privateKey, publicKey } = generateKeyFromSeed(seed);
|
9221
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9222
|
-
}
|
9223
|
-
function ensureKey(key, length) {
|
9224
|
-
key = Uint8Array.from(key ?? []);
|
9225
|
-
if (key.length !== length) {
|
9226
|
-
throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
|
9227
|
-
}
|
9228
|
-
return key;
|
9229
|
-
}
|
9230
|
-
|
9231
|
-
var Ed25519 = /*#__PURE__*/Object.freeze({
|
9232
|
-
__proto__: null,
|
9233
|
-
Ed25519PrivateKey: Ed25519PrivateKey,
|
9234
|
-
Ed25519PublicKey: Ed25519PublicKey,
|
9235
|
-
generateKeyPair: generateKeyPair$2,
|
9236
|
-
generateKeyPairFromSeed: generateKeyPairFromSeed,
|
9237
|
-
unmarshalEd25519PrivateKey: unmarshalEd25519PrivateKey,
|
9238
|
-
unmarshalEd25519PublicKey: unmarshalEd25519PublicKey
|
9239
|
-
});
|
9240
|
-
|
9241
|
-
/**
|
9242
|
-
* Generates a Uint8Array with length `number` populated by random bytes
|
9243
|
-
*/
|
9244
|
-
function randomBytes(length) {
|
9245
|
-
if (isNaN(length) || length <= 0) {
|
9246
|
-
throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
|
9247
|
-
}
|
9248
|
-
return randomBytes$1(length);
|
9249
|
-
}
|
9250
|
-
|
9251
|
-
// HMAC (RFC 2104)
|
9252
|
-
class HMAC extends Hash {
|
9253
|
-
constructor(hash$1, _key) {
|
9254
|
-
super();
|
9255
|
-
this.finished = false;
|
9256
|
-
this.destroyed = false;
|
9257
|
-
hash(hash$1);
|
9258
|
-
const key = toBytes$1(_key);
|
9259
|
-
this.iHash = hash$1.create();
|
9260
|
-
if (typeof this.iHash.update !== 'function')
|
9261
|
-
throw new Error('Expected instance of class which extends utils.Hash');
|
9262
|
-
this.blockLen = this.iHash.blockLen;
|
9263
|
-
this.outputLen = this.iHash.outputLen;
|
9264
|
-
const blockLen = this.blockLen;
|
9265
|
-
const pad = new Uint8Array(blockLen);
|
9266
|
-
// blockLen can be bigger than outputLen
|
9267
|
-
pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
|
9268
|
-
for (let i = 0; i < pad.length; i++)
|
9269
|
-
pad[i] ^= 0x36;
|
9270
|
-
this.iHash.update(pad);
|
9271
|
-
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
9272
|
-
this.oHash = hash$1.create();
|
9273
|
-
// Undo internal XOR && apply outer XOR
|
9274
|
-
for (let i = 0; i < pad.length; i++)
|
9275
|
-
pad[i] ^= 0x36 ^ 0x5c;
|
9276
|
-
this.oHash.update(pad);
|
9277
|
-
pad.fill(0);
|
9278
|
-
}
|
9279
|
-
update(buf) {
|
9280
|
-
exists(this);
|
9281
|
-
this.iHash.update(buf);
|
9282
|
-
return this;
|
9283
|
-
}
|
9284
|
-
digestInto(out) {
|
9285
|
-
exists(this);
|
9286
|
-
bytes(out, this.outputLen);
|
9287
|
-
this.finished = true;
|
9288
|
-
this.iHash.digestInto(out);
|
9289
|
-
this.oHash.update(out);
|
9290
|
-
this.oHash.digestInto(out);
|
9291
|
-
this.destroy();
|
9292
|
-
}
|
9293
|
-
digest() {
|
9294
|
-
const out = new Uint8Array(this.oHash.outputLen);
|
9295
|
-
this.digestInto(out);
|
9296
|
-
return out;
|
9297
|
-
}
|
9298
|
-
_cloneInto(to) {
|
9299
|
-
// Create new instance without calling constructor since key already in state and we don't know it.
|
9300
|
-
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
9301
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
9302
|
-
to = to;
|
9303
|
-
to.finished = finished;
|
9304
|
-
to.destroyed = destroyed;
|
9305
|
-
to.blockLen = blockLen;
|
9306
|
-
to.outputLen = outputLen;
|
9307
|
-
to.oHash = oHash._cloneInto(to.oHash);
|
9308
|
-
to.iHash = iHash._cloneInto(to.iHash);
|
9309
|
-
return to;
|
9310
|
-
}
|
9311
|
-
destroy() {
|
9312
|
-
this.destroyed = true;
|
9313
|
-
this.oHash.destroy();
|
9314
|
-
this.iHash.destroy();
|
9315
|
-
}
|
9316
|
-
}
|
9317
|
-
/**
|
9318
|
-
* HMAC: RFC2104 message authentication code.
|
9319
|
-
* @param hash - function that would be used e.g. sha256
|
9320
|
-
* @param key - message key
|
9321
|
-
* @param message - message data
|
9322
|
-
*/
|
9323
|
-
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
9324
|
-
hmac.create = (hash, key) => new HMAC(hash, key);
|
9325
|
-
|
9326
|
-
// Common prologue and epilogue for sync/async functions
|
9327
|
-
function pbkdf2Init(hash$1, _password, _salt, _opts) {
|
9328
|
-
hash(hash$1);
|
9329
|
-
const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
|
9330
|
-
const { c, dkLen, asyncTick } = opts;
|
9331
|
-
number(c);
|
9332
|
-
number(dkLen);
|
9333
|
-
number(asyncTick);
|
9334
|
-
if (c < 1)
|
9335
|
-
throw new Error('PBKDF2: iterations (c) should be >= 1');
|
9336
|
-
const password = toBytes$1(_password);
|
9337
|
-
const salt = toBytes$1(_salt);
|
9338
|
-
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
|
9339
|
-
const DK = new Uint8Array(dkLen);
|
9340
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9341
|
-
const PRF = hmac.create(hash$1, password);
|
9342
|
-
const PRFSalt = PRF._cloneInto().update(salt);
|
9343
|
-
return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
|
9344
|
-
}
|
9345
|
-
function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
|
9346
|
-
PRF.destroy();
|
9347
|
-
PRFSalt.destroy();
|
9348
|
-
if (prfW)
|
9349
|
-
prfW.destroy();
|
9350
|
-
u.fill(0);
|
9351
|
-
return DK;
|
9352
|
-
}
|
9353
|
-
async function pbkdf2Async(hash, password, salt, opts) {
|
9354
|
-
const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
9355
|
-
let prfW; // Working copy
|
9356
|
-
const arr = new Uint8Array(4);
|
9357
|
-
const view = createView(arr);
|
9358
|
-
const u = new Uint8Array(PRF.outputLen);
|
9359
|
-
// DK = T1 + T2 + ⋯ + Tdklen/hlen
|
9360
|
-
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
9361
|
-
// Ti = F(Password, Salt, c, i)
|
9362
|
-
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
9363
|
-
view.setInt32(0, ti, false);
|
9364
|
-
// F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
|
9365
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9366
|
-
(prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
|
9367
|
-
Ti.set(u.subarray(0, Ti.length));
|
9368
|
-
await asyncLoop(c - 1, asyncTick, () => {
|
9369
|
-
// Uc = PRF(Password, Uc−1)
|
9370
|
-
PRF._cloneInto(prfW).update(u).digestInto(u);
|
9371
|
-
for (let i = 0; i < Ti.length; i++)
|
9372
|
-
Ti[i] ^= u[i];
|
9373
|
-
});
|
9374
|
-
}
|
9375
|
-
return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
|
9376
|
-
}
|
9377
|
-
|
9378
|
-
/*!
|
9379
|
-
* MIT License
|
9380
|
-
*
|
9381
|
-
* Copyright (c) 2017-2022 Peculiar Ventures, LLC
|
9382
|
-
*
|
9383
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9384
|
-
* of this software and associated documentation files (the "Software"), to deal
|
9385
|
-
* in the Software without restriction, including without limitation the rights
|
9386
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9387
|
-
* copies of the Software, and to permit persons to whom the Software is
|
9388
|
-
* furnished to do so, subject to the following conditions:
|
9389
|
-
*
|
9390
|
-
* The above copyright notice and this permission notice shall be included in all
|
9391
|
-
* copies or substantial portions of the Software.
|
9392
|
-
*
|
9393
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
9394
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
9395
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
9396
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
9397
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
9398
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
9399
|
-
* SOFTWARE.
|
9400
|
-
*
|
9401
|
-
*/
|
9402
|
-
|
9403
|
-
const ARRAY_BUFFER_NAME = "[object ArrayBuffer]";
|
9404
|
-
class BufferSourceConverter {
|
9405
|
-
static isArrayBuffer(data) {
|
9406
|
-
return Object.prototype.toString.call(data) === ARRAY_BUFFER_NAME;
|
9407
|
-
}
|
9408
|
-
static toArrayBuffer(data) {
|
9409
|
-
if (this.isArrayBuffer(data)) {
|
9410
|
-
return data;
|
9411
|
-
}
|
9412
|
-
if (data.byteLength === data.buffer.byteLength) {
|
9413
|
-
return data.buffer;
|
9414
|
-
}
|
9415
|
-
if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
|
9416
|
-
return data.buffer;
|
9417
|
-
}
|
9418
|
-
return this.toUint8Array(data.buffer)
|
9419
|
-
.slice(data.byteOffset, data.byteOffset + data.byteLength)
|
9420
|
-
.buffer;
|
9421
|
-
}
|
9422
|
-
static toUint8Array(data) {
|
9423
|
-
return this.toView(data, Uint8Array);
|
9424
|
-
}
|
9425
|
-
static toView(data, type) {
|
9426
|
-
if (data.constructor === type) {
|
9427
|
-
return data;
|
9428
|
-
}
|
9429
|
-
if (this.isArrayBuffer(data)) {
|
9430
|
-
return new type(data);
|
9431
|
-
}
|
9432
|
-
if (this.isArrayBufferView(data)) {
|
9433
|
-
return new type(data.buffer, data.byteOffset, data.byteLength);
|
9434
|
-
}
|
9435
|
-
throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
|
9436
|
-
}
|
9437
|
-
static isBufferSource(data) {
|
9438
|
-
return this.isArrayBufferView(data)
|
9439
|
-
|| this.isArrayBuffer(data);
|
9440
|
-
}
|
9441
|
-
static isArrayBufferView(data) {
|
9442
|
-
return ArrayBuffer.isView(data)
|
9443
|
-
|| (data && this.isArrayBuffer(data.buffer));
|
9444
|
-
}
|
9445
|
-
static isEqual(a, b) {
|
9446
|
-
const aView = BufferSourceConverter.toUint8Array(a);
|
9447
|
-
const bView = BufferSourceConverter.toUint8Array(b);
|
9448
|
-
if (aView.length !== bView.byteLength) {
|
9449
|
-
return false;
|
9450
|
-
}
|
9451
|
-
for (let i = 0; i < aView.length; i++) {
|
9452
|
-
if (aView[i] !== bView[i]) {
|
9453
|
-
return false;
|
9454
|
-
}
|
9455
|
-
}
|
9456
|
-
return true;
|
9457
|
-
}
|
9458
|
-
static concat(...args) {
|
9459
|
-
let buffers;
|
9460
|
-
if (Array.isArray(args[0]) && !(args[1] instanceof Function)) {
|
9461
|
-
buffers = args[0];
|
9462
|
-
}
|
9463
|
-
else if (Array.isArray(args[0]) && args[1] instanceof Function) {
|
9464
|
-
buffers = args[0];
|
9465
|
-
}
|
9466
|
-
else {
|
9467
|
-
if (args[args.length - 1] instanceof Function) {
|
9468
|
-
buffers = args.slice(0, args.length - 1);
|
9469
|
-
}
|
9470
|
-
else {
|
9471
|
-
buffers = args;
|
9472
|
-
}
|
9131
|
+
if (args[args.length - 1] instanceof Function) {
|
9132
|
+
buffers = args.slice(0, args.length - 1);
|
9133
|
+
}
|
9134
|
+
else {
|
9135
|
+
buffers = args;
|
9136
|
+
}
|
9473
9137
|
}
|
9474
9138
|
let size = 0;
|
9475
9139
|
for (const buffer of buffers) {
|
@@ -12626,272 +12290,44 @@ _a = TIME;
|
|
12626
12290
|
TIME.NAME = "TIME";
|
12627
12291
|
|
12628
12292
|
/**
|
12629
|
-
*
|
12293
|
+
* Signing a message failed
|
12630
12294
|
*/
|
12631
|
-
function pkcs1ToJwk(bytes) {
|
12632
|
-
const { result } = fromBER(bytes);
|
12633
|
-
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12634
|
-
// safe to have deeply property chains like this
|
12635
|
-
const values = result.valueBlock.value;
|
12636
|
-
const key = {
|
12637
|
-
n: toString$6(bnToBuf(values[1].toBigInt()), 'base64url'),
|
12638
|
-
e: toString$6(bnToBuf(values[2].toBigInt()), 'base64url'),
|
12639
|
-
d: toString$6(bnToBuf(values[3].toBigInt()), 'base64url'),
|
12640
|
-
p: toString$6(bnToBuf(values[4].toBigInt()), 'base64url'),
|
12641
|
-
q: toString$6(bnToBuf(values[5].toBigInt()), 'base64url'),
|
12642
|
-
dp: toString$6(bnToBuf(values[6].toBigInt()), 'base64url'),
|
12643
|
-
dq: toString$6(bnToBuf(values[7].toBigInt()), 'base64url'),
|
12644
|
-
qi: toString$6(bnToBuf(values[8].toBigInt()), 'base64url'),
|
12645
|
-
kty: 'RSA',
|
12646
|
-
alg: 'RS256'
|
12647
|
-
};
|
12648
|
-
return key;
|
12649
|
-
}
|
12650
12295
|
/**
|
12651
|
-
*
|
12296
|
+
* Verifying a message signature failed
|
12652
12297
|
*/
|
12653
|
-
|
12654
|
-
|
12655
|
-
|
12298
|
+
class VerificationError extends Error {
|
12299
|
+
constructor(message = 'An error occurred while verifying a message') {
|
12300
|
+
super(message);
|
12301
|
+
this.name = 'VerificationError';
|
12656
12302
|
}
|
12657
|
-
const root = new Sequence({
|
12658
|
-
value: [
|
12659
|
-
new Integer({ value: 0 }),
|
12660
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12661
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url'))),
|
12662
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.d, 'base64url'))),
|
12663
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.p, 'base64url'))),
|
12664
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.q, 'base64url'))),
|
12665
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dp, 'base64url'))),
|
12666
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dq, 'base64url'))),
|
12667
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.qi, 'base64url')))
|
12668
|
-
]
|
12669
|
-
});
|
12670
|
-
const der = root.toBER();
|
12671
|
-
return new Uint8Array(der, 0, der.byteLength);
|
12672
|
-
}
|
12673
|
-
/**
|
12674
|
-
* Convert a PKCIX in ASN1 DER format to a JWK key
|
12675
|
-
*/
|
12676
|
-
function pkixToJwk(bytes) {
|
12677
|
-
const { result } = fromBER(bytes);
|
12678
|
-
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12679
|
-
// safe to have deeply property chains like this
|
12680
|
-
const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
|
12681
|
-
return {
|
12682
|
-
kty: 'RSA',
|
12683
|
-
n: toString$6(bnToBuf(values[0].toBigInt()), 'base64url'),
|
12684
|
-
e: toString$6(bnToBuf(values[1].toBigInt()), 'base64url')
|
12685
|
-
};
|
12686
12303
|
}
|
12687
12304
|
/**
|
12688
|
-
*
|
12305
|
+
* WebCrypto was not available in the current context
|
12689
12306
|
*/
|
12690
|
-
|
12691
|
-
|
12692
|
-
|
12307
|
+
class WebCryptoMissingError extends Error {
|
12308
|
+
constructor(message = 'Missing Web Crypto API') {
|
12309
|
+
super(message);
|
12310
|
+
this.name = 'WebCryptoMissingError';
|
12693
12311
|
}
|
12694
|
-
const root = new Sequence({
|
12695
|
-
value: [
|
12696
|
-
new Sequence({
|
12697
|
-
value: [
|
12698
|
-
// rsaEncryption
|
12699
|
-
new ObjectIdentifier({
|
12700
|
-
value: '1.2.840.113549.1.1.1'
|
12701
|
-
}),
|
12702
|
-
new Null()
|
12703
|
-
]
|
12704
|
-
}),
|
12705
|
-
// this appears to be a bug in asn1js.js - this should really be a Sequence
|
12706
|
-
// and not a BitString but it generates the same bytes as node-forge so 🤷♂️
|
12707
|
-
new BitString({
|
12708
|
-
valueHex: new Sequence({
|
12709
|
-
value: [
|
12710
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12711
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url')))
|
12712
|
-
]
|
12713
|
-
}).toBER()
|
12714
|
-
})
|
12715
|
-
]
|
12716
|
-
});
|
12717
|
-
const der = root.toBER();
|
12718
|
-
return new Uint8Array(der, 0, der.byteLength);
|
12719
12312
|
}
|
12720
|
-
|
12721
|
-
|
12722
|
-
|
12723
|
-
|
12724
|
-
|
12725
|
-
|
12726
|
-
|
12727
|
-
|
12728
|
-
|
12729
|
-
|
12730
|
-
|
12731
|
-
|
12732
|
-
|
12733
|
-
}
|
12734
|
-
return u8;
|
12735
|
-
}
|
12736
|
-
function bufToBn(u8) {
|
12737
|
-
const hex = [];
|
12738
|
-
u8.forEach(function (i) {
|
12739
|
-
let h = i.toString(16);
|
12740
|
-
if (h.length % 2 > 0) {
|
12741
|
-
h = `0${h}`;
|
12313
|
+
|
12314
|
+
/* eslint-env browser */
|
12315
|
+
// Check native crypto exists and is enabled (In insecure context `self.crypto`
|
12316
|
+
// exists but `self.crypto.subtle` does not).
|
12317
|
+
var webcrypto = {
|
12318
|
+
get(win = globalThis) {
|
12319
|
+
const nativeCrypto = win.crypto;
|
12320
|
+
if (nativeCrypto?.subtle == null) {
|
12321
|
+
throw new WebCryptoMissingError('Missing Web Crypto API. ' +
|
12322
|
+
'The most likely cause of this error is that this page is being accessed ' +
|
12323
|
+
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
12324
|
+
'possible resolutions see ' +
|
12325
|
+
'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api');
|
12742
12326
|
}
|
12743
|
-
|
12744
|
-
}
|
12745
|
-
|
12746
|
-
}
|
12747
|
-
const SALT_LENGTH = 16;
|
12748
|
-
const KEY_SIZE = 32;
|
12749
|
-
const ITERATIONS = 10000;
|
12750
|
-
async function exportToPem(privateKey, password) {
|
12751
|
-
const crypto = webcrypto.get();
|
12752
|
-
// PrivateKeyInfo
|
12753
|
-
const keyWrapper = new Sequence({
|
12754
|
-
value: [
|
12755
|
-
// version (0)
|
12756
|
-
new Integer({ value: 0 }),
|
12757
|
-
// privateKeyAlgorithm
|
12758
|
-
new Sequence({
|
12759
|
-
value: [
|
12760
|
-
// rsaEncryption OID
|
12761
|
-
new ObjectIdentifier({
|
12762
|
-
value: '1.2.840.113549.1.1.1'
|
12763
|
-
}),
|
12764
|
-
new Null()
|
12765
|
-
]
|
12766
|
-
}),
|
12767
|
-
// PrivateKey
|
12768
|
-
new OctetString({
|
12769
|
-
valueHex: privateKey.marshal()
|
12770
|
-
})
|
12771
|
-
]
|
12772
|
-
});
|
12773
|
-
const keyBuf = keyWrapper.toBER();
|
12774
|
-
const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
|
12775
|
-
const salt = randomBytes(SALT_LENGTH);
|
12776
|
-
const encryptionKey = await pbkdf2Async(sha512, password, salt, {
|
12777
|
-
c: ITERATIONS,
|
12778
|
-
dkLen: KEY_SIZE
|
12779
|
-
});
|
12780
|
-
const iv = randomBytes(16);
|
12781
|
-
const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['encrypt']);
|
12782
|
-
const encrypted = await crypto.subtle.encrypt({
|
12783
|
-
name: 'AES-CBC',
|
12784
|
-
iv
|
12785
|
-
}, cryptoKey, keyArr);
|
12786
|
-
const pbkdf2Params = new Sequence({
|
12787
|
-
value: [
|
12788
|
-
// salt
|
12789
|
-
new OctetString({ valueHex: salt }),
|
12790
|
-
// iteration count
|
12791
|
-
new Integer({ value: ITERATIONS }),
|
12792
|
-
// key length
|
12793
|
-
new Integer({ value: KEY_SIZE }),
|
12794
|
-
// AlgorithmIdentifier
|
12795
|
-
new Sequence({
|
12796
|
-
value: [
|
12797
|
-
// hmacWithSHA512
|
12798
|
-
new ObjectIdentifier({ value: '1.2.840.113549.2.11' }),
|
12799
|
-
new Null()
|
12800
|
-
]
|
12801
|
-
})
|
12802
|
-
]
|
12803
|
-
});
|
12804
|
-
const encryptionAlgorithm = new Sequence({
|
12805
|
-
value: [
|
12806
|
-
// pkcs5PBES2
|
12807
|
-
new ObjectIdentifier({
|
12808
|
-
value: '1.2.840.113549.1.5.13'
|
12809
|
-
}),
|
12810
|
-
new Sequence({
|
12811
|
-
value: [
|
12812
|
-
// keyDerivationFunc
|
12813
|
-
new Sequence({
|
12814
|
-
value: [
|
12815
|
-
// pkcs5PBKDF2
|
12816
|
-
new ObjectIdentifier({
|
12817
|
-
value: '1.2.840.113549.1.5.12'
|
12818
|
-
}),
|
12819
|
-
// PBKDF2-params
|
12820
|
-
pbkdf2Params
|
12821
|
-
]
|
12822
|
-
}),
|
12823
|
-
// encryptionScheme
|
12824
|
-
new Sequence({
|
12825
|
-
value: [
|
12826
|
-
// aes256-CBC
|
12827
|
-
new ObjectIdentifier({
|
12828
|
-
value: '2.16.840.1.101.3.4.1.42'
|
12829
|
-
}),
|
12830
|
-
// iv
|
12831
|
-
new OctetString({
|
12832
|
-
valueHex: iv
|
12833
|
-
})
|
12834
|
-
]
|
12835
|
-
})
|
12836
|
-
]
|
12837
|
-
})
|
12838
|
-
]
|
12839
|
-
});
|
12840
|
-
const finalWrapper = new Sequence({
|
12841
|
-
value: [
|
12842
|
-
encryptionAlgorithm,
|
12843
|
-
new OctetString({ valueHex: encrypted })
|
12844
|
-
]
|
12845
|
-
});
|
12846
|
-
const finalWrapperBuf = finalWrapper.toBER();
|
12847
|
-
const finalWrapperArr = new Uint8Array(finalWrapperBuf, 0, finalWrapperBuf.byteLength);
|
12848
|
-
return [
|
12849
|
-
'-----BEGIN ENCRYPTED PRIVATE KEY-----',
|
12850
|
-
...toString$6(finalWrapperArr, 'base64pad').split(/(.{64})/).filter(Boolean),
|
12851
|
-
'-----END ENCRYPTED PRIVATE KEY-----'
|
12852
|
-
].join('\n');
|
12853
|
-
}
|
12327
|
+
return nativeCrypto;
|
12328
|
+
}
|
12329
|
+
};
|
12854
12330
|
|
12855
|
-
async function generateKey$1(bits) {
|
12856
|
-
const pair = await webcrypto.get().subtle.generateKey({
|
12857
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12858
|
-
modulusLength: bits,
|
12859
|
-
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
12860
|
-
hash: { name: 'SHA-256' }
|
12861
|
-
}, true, ['sign', 'verify']);
|
12862
|
-
const keys = await exportKey(pair);
|
12863
|
-
return {
|
12864
|
-
privateKey: keys[0],
|
12865
|
-
publicKey: keys[1]
|
12866
|
-
};
|
12867
|
-
}
|
12868
|
-
// Takes a jwk key
|
12869
|
-
async function unmarshalPrivateKey$1(key) {
|
12870
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12871
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12872
|
-
hash: { name: 'SHA-256' }
|
12873
|
-
}, true, ['sign']);
|
12874
|
-
const pair = [
|
12875
|
-
privateKey,
|
12876
|
-
await derivePublicFromPrivate(key)
|
12877
|
-
];
|
12878
|
-
const keys = await exportKey({
|
12879
|
-
privateKey: pair[0],
|
12880
|
-
publicKey: pair[1]
|
12881
|
-
});
|
12882
|
-
return {
|
12883
|
-
privateKey: keys[0],
|
12884
|
-
publicKey: keys[1]
|
12885
|
-
};
|
12886
|
-
}
|
12887
|
-
async function hashAndSign$1(key, msg) {
|
12888
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12889
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12890
|
-
hash: { name: 'SHA-256' }
|
12891
|
-
}, false, ['sign']);
|
12892
|
-
const sig = await webcrypto.get().subtle.sign({ name: 'RSASSA-PKCS1-v1_5' }, privateKey, msg instanceof Uint8Array ? msg : msg.subarray());
|
12893
|
-
return new Uint8Array(sig, 0, sig.byteLength);
|
12894
|
-
}
|
12895
12331
|
async function hashAndVerify$1(key, sig, msg) {
|
12896
12332
|
const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12897
12333
|
name: 'RSASSA-PKCS1-v1_5',
|
@@ -12899,173 +12335,222 @@ async function hashAndVerify$1(key, sig, msg) {
|
|
12899
12335
|
}, false, ['verify']);
|
12900
12336
|
return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
|
12901
12337
|
}
|
12902
|
-
|
12903
|
-
if (pair.privateKey == null || pair.publicKey == null) {
|
12904
|
-
throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
|
12905
|
-
}
|
12906
|
-
return Promise.all([
|
12907
|
-
webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
|
12908
|
-
webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
|
12909
|
-
]);
|
12910
|
-
}
|
12911
|
-
async function derivePublicFromPrivate(jwKey) {
|
12912
|
-
return webcrypto.get().subtle.importKey('jwk', {
|
12913
|
-
kty: jwKey.kty,
|
12914
|
-
n: jwKey.n,
|
12915
|
-
e: jwKey.e
|
12916
|
-
}, {
|
12917
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12918
|
-
hash: { name: 'SHA-256' }
|
12919
|
-
}, true, ['verify']);
|
12920
|
-
}
|
12921
|
-
function keySize(jwk) {
|
12338
|
+
function rsaKeySize(jwk) {
|
12922
12339
|
if (jwk.kty !== 'RSA') {
|
12923
|
-
throw new
|
12340
|
+
throw new InvalidParametersError('invalid key type');
|
12924
12341
|
}
|
12925
12342
|
else if (jwk.n == null) {
|
12926
|
-
throw new
|
12343
|
+
throw new InvalidParametersError('invalid key modulus');
|
12927
12344
|
}
|
12928
12345
|
const bytes = fromString(jwk.n, 'base64url');
|
12929
12346
|
return bytes.length * 8;
|
12930
12347
|
}
|
12931
12348
|
|
12932
|
-
|
12933
|
-
|
12349
|
+
class RSAPublicKey {
|
12350
|
+
type = 'RSA';
|
12934
12351
|
_key;
|
12935
|
-
|
12352
|
+
_raw;
|
12353
|
+
_multihash;
|
12354
|
+
constructor(key, digest) {
|
12936
12355
|
this._key = key;
|
12356
|
+
this._multihash = digest;
|
12937
12357
|
}
|
12938
|
-
|
12939
|
-
|
12940
|
-
|
12941
|
-
marshal() {
|
12942
|
-
return jwkToPkix(this._key);
|
12943
|
-
}
|
12944
|
-
get bytes() {
|
12945
|
-
return PublicKey.encode({
|
12946
|
-
Type: KeyType.RSA,
|
12947
|
-
Data: this.marshal()
|
12948
|
-
}).subarray();
|
12949
|
-
}
|
12950
|
-
equals(key) {
|
12951
|
-
return equals(this.bytes, key.bytes);
|
12952
|
-
}
|
12953
|
-
hash() {
|
12954
|
-
const p = sha256.digest(this.bytes);
|
12955
|
-
if (isPromise$1(p)) {
|
12956
|
-
return p.then(({ bytes }) => bytes);
|
12358
|
+
get raw() {
|
12359
|
+
if (this._raw == null) {
|
12360
|
+
this._raw = jwkToPkix(this._key);
|
12957
12361
|
}
|
12958
|
-
return
|
12959
|
-
}
|
12960
|
-
}
|
12961
|
-
class RsaPrivateKey {
|
12962
|
-
_key;
|
12963
|
-
_publicKey;
|
12964
|
-
constructor(key, publicKey) {
|
12965
|
-
this._key = key;
|
12966
|
-
this._publicKey = publicKey;
|
12967
|
-
}
|
12968
|
-
genSecret() {
|
12969
|
-
return randomBytes(16);
|
12362
|
+
return this._raw;
|
12970
12363
|
}
|
12971
|
-
|
12972
|
-
return
|
12364
|
+
toMultihash() {
|
12365
|
+
return this._multihash;
|
12973
12366
|
}
|
12974
|
-
|
12975
|
-
|
12976
|
-
throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
|
12977
|
-
}
|
12978
|
-
return new RsaPublicKey(this._publicKey);
|
12979
|
-
}
|
12980
|
-
marshal() {
|
12981
|
-
return jwkToPkcs1(this._key);
|
12367
|
+
toCID() {
|
12368
|
+
return CID.createV1(114, this._multihash);
|
12982
12369
|
}
|
12983
|
-
|
12984
|
-
return
|
12985
|
-
Type: KeyType.RSA,
|
12986
|
-
Data: this.marshal()
|
12987
|
-
}).subarray();
|
12370
|
+
toString() {
|
12371
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
12988
12372
|
}
|
12989
12373
|
equals(key) {
|
12990
|
-
|
12991
|
-
|
12992
|
-
hash() {
|
12993
|
-
const p = sha256.digest(this.bytes);
|
12994
|
-
if (isPromise$1(p)) {
|
12995
|
-
return p.then(({ bytes }) => bytes);
|
12374
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
12375
|
+
return false;
|
12996
12376
|
}
|
12997
|
-
return
|
12377
|
+
return equals(this.raw, key.raw);
|
12998
12378
|
}
|
12999
|
-
|
13000
|
-
|
13001
|
-
*
|
13002
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
13003
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
13004
|
-
* of the PKCS SubjectPublicKeyInfo.
|
13005
|
-
*/
|
13006
|
-
async id() {
|
13007
|
-
const hash = await this.public.hash();
|
13008
|
-
return toString$6(hash, 'base58btc');
|
12379
|
+
verify(data, sig) {
|
12380
|
+
return hashAndVerify$1(this._key, sig, data);
|
13009
12381
|
}
|
13010
|
-
|
13011
|
-
|
13012
|
-
|
13013
|
-
|
13014
|
-
|
13015
|
-
|
13016
|
-
|
13017
|
-
|
13018
|
-
|
13019
|
-
|
13020
|
-
|
13021
|
-
|
13022
|
-
|
13023
|
-
|
13024
|
-
|
13025
|
-
|
13026
|
-
|
12382
|
+
}
|
12383
|
+
|
12384
|
+
const MAX_RSA_KEY_SIZE = 8192;
|
12385
|
+
const SHA2_256_CODE = 0x12;
|
12386
|
+
/**
|
12387
|
+
* Convert a PKIX in ASN1 DER format to a JWK key
|
12388
|
+
*/
|
12389
|
+
function pkixToJwk(bytes) {
|
12390
|
+
const { result } = fromBER(bytes);
|
12391
|
+
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12392
|
+
// safe to have deeply property chains like this
|
12393
|
+
const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
|
12394
|
+
return {
|
12395
|
+
kty: 'RSA',
|
12396
|
+
n: toString$6(bnToBuf(values[0].toBigInt()), 'base64url'),
|
12397
|
+
e: toString$6(bnToBuf(values[1].toBigInt()), 'base64url')
|
12398
|
+
};
|
12399
|
+
}
|
12400
|
+
/**
|
12401
|
+
* Convert a JWK key to PKIX in ASN1 DER format
|
12402
|
+
*/
|
12403
|
+
function jwkToPkix(jwk) {
|
12404
|
+
if (jwk.n == null || jwk.e == null) {
|
12405
|
+
throw new InvalidParametersError('JWK was missing components');
|
13027
12406
|
}
|
12407
|
+
const root = new Sequence({
|
12408
|
+
value: [
|
12409
|
+
new Sequence({
|
12410
|
+
value: [
|
12411
|
+
// rsaEncryption
|
12412
|
+
new ObjectIdentifier({
|
12413
|
+
value: '1.2.840.113549.1.1.1'
|
12414
|
+
}),
|
12415
|
+
new Null()
|
12416
|
+
]
|
12417
|
+
}),
|
12418
|
+
// this appears to be a bug in asn1js.js - this should really be a Sequence
|
12419
|
+
// and not a BitString but it generates the same bytes as node-forge so 🤷♂️
|
12420
|
+
new BitString({
|
12421
|
+
valueHex: new Sequence({
|
12422
|
+
value: [
|
12423
|
+
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12424
|
+
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url')))
|
12425
|
+
]
|
12426
|
+
}).toBER()
|
12427
|
+
})
|
12428
|
+
]
|
12429
|
+
});
|
12430
|
+
const der = root.toBER();
|
12431
|
+
return new Uint8Array(der, 0, der.byteLength);
|
13028
12432
|
}
|
13029
|
-
|
13030
|
-
|
13031
|
-
if (
|
13032
|
-
|
12433
|
+
function bnToBuf(bn) {
|
12434
|
+
let hex = bn.toString(16);
|
12435
|
+
if (hex.length % 2 > 0) {
|
12436
|
+
hex = `0${hex}`;
|
13033
12437
|
}
|
13034
|
-
const
|
13035
|
-
|
12438
|
+
const len = hex.length / 2;
|
12439
|
+
const u8 = new Uint8Array(len);
|
12440
|
+
let i = 0;
|
12441
|
+
let j = 0;
|
12442
|
+
while (i < len) {
|
12443
|
+
u8[i] = parseInt(hex.slice(j, j + 2), 16);
|
12444
|
+
i += 1;
|
12445
|
+
j += 2;
|
12446
|
+
}
|
12447
|
+
return u8;
|
13036
12448
|
}
|
13037
|
-
function
|
12449
|
+
function bufToBn(u8) {
|
12450
|
+
const hex = [];
|
12451
|
+
u8.forEach(function (i) {
|
12452
|
+
let h = i.toString(16);
|
12453
|
+
if (h.length % 2 > 0) {
|
12454
|
+
h = `0${h}`;
|
12455
|
+
}
|
12456
|
+
hex.push(h);
|
12457
|
+
});
|
12458
|
+
return BigInt('0x' + hex.join(''));
|
12459
|
+
}
|
12460
|
+
/**
|
12461
|
+
* Turn PKIX bytes to a PublicKey
|
12462
|
+
*/
|
12463
|
+
function pkixToRSAPublicKey(bytes) {
|
13038
12464
|
const jwk = pkixToJwk(bytes);
|
13039
|
-
if (
|
13040
|
-
throw new
|
12465
|
+
if (rsaKeySize(jwk) > MAX_RSA_KEY_SIZE) {
|
12466
|
+
throw new InvalidPublicKeyError('Key size is too large');
|
13041
12467
|
}
|
13042
|
-
|
12468
|
+
const hash = sha256$1(PublicKey.encode({
|
12469
|
+
Type: KeyType.RSA,
|
12470
|
+
Data: bytes
|
12471
|
+
}));
|
12472
|
+
const digest = create(SHA2_256_CODE, hash);
|
12473
|
+
return new RSAPublicKey(jwk, digest);
|
13043
12474
|
}
|
13044
|
-
|
13045
|
-
|
13046
|
-
|
12475
|
+
|
12476
|
+
// HMAC (RFC 2104)
|
12477
|
+
class HMAC extends Hash {
|
12478
|
+
constructor(hash$1, _key) {
|
12479
|
+
super();
|
12480
|
+
this.finished = false;
|
12481
|
+
this.destroyed = false;
|
12482
|
+
hash(hash$1);
|
12483
|
+
const key = toBytes$1(_key);
|
12484
|
+
this.iHash = hash$1.create();
|
12485
|
+
if (typeof this.iHash.update !== 'function')
|
12486
|
+
throw new Error('Expected instance of class which extends utils.Hash');
|
12487
|
+
this.blockLen = this.iHash.blockLen;
|
12488
|
+
this.outputLen = this.iHash.outputLen;
|
12489
|
+
const blockLen = this.blockLen;
|
12490
|
+
const pad = new Uint8Array(blockLen);
|
12491
|
+
// blockLen can be bigger than outputLen
|
12492
|
+
pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
|
12493
|
+
for (let i = 0; i < pad.length; i++)
|
12494
|
+
pad[i] ^= 0x36;
|
12495
|
+
this.iHash.update(pad);
|
12496
|
+
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
12497
|
+
this.oHash = hash$1.create();
|
12498
|
+
// Undo internal XOR && apply outer XOR
|
12499
|
+
for (let i = 0; i < pad.length; i++)
|
12500
|
+
pad[i] ^= 0x36 ^ 0x5c;
|
12501
|
+
this.oHash.update(pad);
|
12502
|
+
pad.fill(0);
|
13047
12503
|
}
|
13048
|
-
|
13049
|
-
|
13050
|
-
|
13051
|
-
|
13052
|
-
|
13053
|
-
|
12504
|
+
update(buf) {
|
12505
|
+
exists(this);
|
12506
|
+
this.iHash.update(buf);
|
12507
|
+
return this;
|
12508
|
+
}
|
12509
|
+
digestInto(out) {
|
12510
|
+
exists(this);
|
12511
|
+
bytes(out, this.outputLen);
|
12512
|
+
this.finished = true;
|
12513
|
+
this.iHash.digestInto(out);
|
12514
|
+
this.oHash.update(out);
|
12515
|
+
this.oHash.digestInto(out);
|
12516
|
+
this.destroy();
|
12517
|
+
}
|
12518
|
+
digest() {
|
12519
|
+
const out = new Uint8Array(this.oHash.outputLen);
|
12520
|
+
this.digestInto(out);
|
12521
|
+
return out;
|
12522
|
+
}
|
12523
|
+
_cloneInto(to) {
|
12524
|
+
// Create new instance without calling constructor since key already in state and we don't know it.
|
12525
|
+
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
12526
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
12527
|
+
to = to;
|
12528
|
+
to.finished = finished;
|
12529
|
+
to.destroyed = destroyed;
|
12530
|
+
to.blockLen = blockLen;
|
12531
|
+
to.outputLen = outputLen;
|
12532
|
+
to.oHash = oHash._cloneInto(to.oHash);
|
12533
|
+
to.iHash = iHash._cloneInto(to.iHash);
|
12534
|
+
return to;
|
12535
|
+
}
|
12536
|
+
destroy() {
|
12537
|
+
this.destroyed = true;
|
12538
|
+
this.oHash.destroy();
|
12539
|
+
this.iHash.destroy();
|
13054
12540
|
}
|
13055
|
-
const keys = await generateKey$1(bits);
|
13056
|
-
return new RsaPrivateKey(keys.privateKey, keys.publicKey);
|
13057
12541
|
}
|
13058
|
-
|
13059
|
-
|
13060
|
-
|
13061
|
-
|
13062
|
-
|
13063
|
-
|
13064
|
-
|
13065
|
-
|
13066
|
-
|
13067
|
-
|
13068
|
-
|
12542
|
+
/**
|
12543
|
+
* HMAC: RFC2104 message authentication code.
|
12544
|
+
* @param hash - function that would be used e.g. sha256
|
12545
|
+
* @param key - message key
|
12546
|
+
* @param message - message data
|
12547
|
+
* @example
|
12548
|
+
* import { hmac } from '@noble/hashes/hmac';
|
12549
|
+
* import { sha256 } from '@noble/hashes/sha2';
|
12550
|
+
* const mac1 = hmac(sha256, 'key', 'message');
|
12551
|
+
*/
|
12552
|
+
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
12553
|
+
hmac.create = (hash, key) => new HMAC(hash, key);
|
13069
12554
|
|
13070
12555
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13071
12556
|
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
@@ -13102,8 +12587,14 @@ function validatePointOpts(curve) {
|
|
13102
12587
|
}
|
13103
12588
|
return Object.freeze({ ...opts });
|
13104
12589
|
}
|
13105
|
-
// ASN.1 DER encoding utilities
|
13106
12590
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
12591
|
+
/**
|
12592
|
+
* ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
|
12593
|
+
*
|
12594
|
+
* [0x30 (SEQUENCE), bytelength, 0x02 (INTEGER), intLength, R, 0x02 (INTEGER), intLength, S]
|
12595
|
+
*
|
12596
|
+
* Docs: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/, https://luca.ntop.org/Teaching/Appunti/asn1.html
|
12597
|
+
*/
|
13107
12598
|
const DER = {
|
13108
12599
|
// asn.1 DER encoding utils
|
13109
12600
|
Err: class DERErr extends Error {
|
@@ -13111,54 +12602,103 @@ const DER = {
|
|
13111
12602
|
super(m);
|
13112
12603
|
}
|
13113
12604
|
},
|
13114
|
-
|
13115
|
-
|
13116
|
-
|
13117
|
-
|
13118
|
-
|
13119
|
-
|
13120
|
-
|
13121
|
-
|
13122
|
-
|
13123
|
-
|
13124
|
-
|
13125
|
-
|
13126
|
-
|
13127
|
-
|
13128
|
-
|
13129
|
-
|
13130
|
-
|
12605
|
+
// Basic building block is TLV (Tag-Length-Value)
|
12606
|
+
_tlv: {
|
12607
|
+
encode: (tag, data) => {
|
12608
|
+
const { Err: E } = DER;
|
12609
|
+
if (tag < 0 || tag > 256)
|
12610
|
+
throw new E('tlv.encode: wrong tag');
|
12611
|
+
if (data.length & 1)
|
12612
|
+
throw new E('tlv.encode: unpadded data');
|
12613
|
+
const dataLen = data.length / 2;
|
12614
|
+
const len = numberToHexUnpadded(dataLen);
|
12615
|
+
if ((len.length / 2) & 128)
|
12616
|
+
throw new E('tlv.encode: long form length too big');
|
12617
|
+
// length of length with long form flag
|
12618
|
+
const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
|
12619
|
+
return `${numberToHexUnpadded(tag)}${lenLen}${len}${data}`;
|
12620
|
+
},
|
12621
|
+
// v - value, l - left bytes (unparsed)
|
12622
|
+
decode(tag, data) {
|
12623
|
+
const { Err: E } = DER;
|
12624
|
+
let pos = 0;
|
12625
|
+
if (tag < 0 || tag > 256)
|
12626
|
+
throw new E('tlv.encode: wrong tag');
|
12627
|
+
if (data.length < 2 || data[pos++] !== tag)
|
12628
|
+
throw new E('tlv.decode: wrong tlv');
|
12629
|
+
const first = data[pos++];
|
12630
|
+
const isLong = !!(first & 128); // First bit of first length byte is flag for short/long form
|
12631
|
+
let length = 0;
|
12632
|
+
if (!isLong)
|
12633
|
+
length = first;
|
12634
|
+
else {
|
12635
|
+
// Long form: [longFlag(1bit), lengthLength(7bit), length (BE)]
|
12636
|
+
const lenLen = first & 127;
|
12637
|
+
if (!lenLen)
|
12638
|
+
throw new E('tlv.decode(long): indefinite length not supported');
|
12639
|
+
if (lenLen > 4)
|
12640
|
+
throw new E('tlv.decode(long): byte length is too big'); // this will overflow u32 in js
|
12641
|
+
const lengthBytes = data.subarray(pos, pos + lenLen);
|
12642
|
+
if (lengthBytes.length !== lenLen)
|
12643
|
+
throw new E('tlv.decode: length bytes not complete');
|
12644
|
+
if (lengthBytes[0] === 0)
|
12645
|
+
throw new E('tlv.decode(long): zero leftmost byte');
|
12646
|
+
for (const b of lengthBytes)
|
12647
|
+
length = (length << 8) | b;
|
12648
|
+
pos += lenLen;
|
12649
|
+
if (length < 128)
|
12650
|
+
throw new E('tlv.decode(long): not minimal encoding');
|
12651
|
+
}
|
12652
|
+
const v = data.subarray(pos, pos + length);
|
12653
|
+
if (v.length !== length)
|
12654
|
+
throw new E('tlv.decode: wrong value length');
|
12655
|
+
return { v, l: data.subarray(pos + length) };
|
12656
|
+
},
|
12657
|
+
},
|
12658
|
+
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
12659
|
+
// since we always use positive integers here. It must always be empty:
|
12660
|
+
// - add zero byte if exists
|
12661
|
+
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
12662
|
+
_int: {
|
12663
|
+
encode(num) {
|
12664
|
+
const { Err: E } = DER;
|
12665
|
+
if (num < _0n)
|
12666
|
+
throw new E('integer: negative integers are not allowed');
|
12667
|
+
let hex = numberToHexUnpadded(num);
|
12668
|
+
// Pad with zero byte if negative flag is present
|
12669
|
+
if (Number.parseInt(hex[0], 16) & 0b1000)
|
12670
|
+
hex = '00' + hex;
|
12671
|
+
if (hex.length & 1)
|
12672
|
+
throw new E('unexpected assertion');
|
12673
|
+
return hex;
|
12674
|
+
},
|
12675
|
+
decode(data) {
|
12676
|
+
const { Err: E } = DER;
|
12677
|
+
if (data[0] & 128)
|
12678
|
+
throw new E('Invalid signature integer: negative');
|
12679
|
+
if (data[0] === 0x00 && !(data[1] & 128))
|
12680
|
+
throw new E('Invalid signature integer: unnecessary leading zero');
|
12681
|
+
return b2n(data);
|
12682
|
+
},
|
13131
12683
|
},
|
13132
12684
|
toSig(hex) {
|
13133
12685
|
// parse DER signature
|
13134
|
-
const { Err: E } = DER;
|
12686
|
+
const { Err: E, _int: int, _tlv: tlv } = DER;
|
13135
12687
|
const data = typeof hex === 'string' ? h2b(hex) : hex;
|
13136
12688
|
abytes(data);
|
13137
|
-
|
13138
|
-
if (
|
13139
|
-
throw new E('Invalid signature
|
13140
|
-
|
13141
|
-
|
13142
|
-
|
13143
|
-
const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);
|
13144
|
-
if (rBytesLeft.length)
|
12689
|
+
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
12690
|
+
if (seqLeftBytes.length)
|
12691
|
+
throw new E('Invalid signature: left bytes after parsing');
|
12692
|
+
const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
|
12693
|
+
const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
|
12694
|
+
if (sLeftBytes.length)
|
13145
12695
|
throw new E('Invalid signature: left bytes after parsing');
|
13146
|
-
return { r, s };
|
12696
|
+
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
13147
12697
|
},
|
13148
12698
|
hexFromSig(sig) {
|
13149
|
-
|
13150
|
-
const
|
13151
|
-
|
13152
|
-
const hex = num.toString(16);
|
13153
|
-
return hex.length & 1 ? `0${hex}` : hex;
|
13154
|
-
};
|
13155
|
-
const s = slice(h(sig.s));
|
13156
|
-
const r = slice(h(sig.r));
|
13157
|
-
const shl = s.length / 2;
|
13158
|
-
const rhl = r.length / 2;
|
13159
|
-
const sl = h(shl);
|
13160
|
-
const rl = h(rhl);
|
13161
|
-
return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
|
12699
|
+
const { _tlv: tlv, _int: int } = DER;
|
12700
|
+
const seq = `${tlv.encode(0x02, int.encode(sig.r))}${tlv.encode(0x02, int.encode(sig.s))}`;
|
12701
|
+
return tlv.encode(0x30, seq);
|
13162
12702
|
},
|
13163
12703
|
};
|
13164
12704
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
@@ -13167,6 +12707,7 @@ const _0n = BigInt(0), _1n$1 = BigInt(1); BigInt(2); const _3n = BigInt(3); BigI
|
|
13167
12707
|
function weierstrassPoints(opts) {
|
13168
12708
|
const CURVE = validatePointOpts(opts);
|
13169
12709
|
const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
|
12710
|
+
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
13170
12711
|
const toBytes = CURVE.toBytes ||
|
13171
12712
|
((_c, point, _isCompressed) => {
|
13172
12713
|
const a = point.toAffine();
|
@@ -13340,6 +12881,10 @@ function weierstrassPoints(opts) {
|
|
13340
12881
|
static fromPrivateKey(privateKey) {
|
13341
12882
|
return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
|
13342
12883
|
}
|
12884
|
+
// Multiscalar Multiplication
|
12885
|
+
static msm(points, scalars) {
|
12886
|
+
return pippenger(Point, Fn, points, scalars);
|
12887
|
+
}
|
13343
12888
|
// "Private method", don't use it directly
|
13344
12889
|
_setWindowSize(windowSize) {
|
13345
12890
|
wnaf.setWindowSize(this, windowSize);
|
@@ -14025,7 +13570,7 @@ function getHash(hash) {
|
|
14025
13570
|
return {
|
14026
13571
|
hash,
|
14027
13572
|
hmac: (key, ...msgs) => hmac(hash, key, concatBytes$2(...msgs)),
|
14028
|
-
randomBytes
|
13573
|
+
randomBytes,
|
14029
13574
|
};
|
14030
13575
|
}
|
14031
13576
|
function createCurve(curveDef, defHash) {
|
@@ -14118,27 +13663,15 @@ const secp256k1 = createCurve({
|
|
14118
13663
|
BigInt(0);
|
14119
13664
|
secp256k1.ProjectivePoint;
|
14120
13665
|
|
14121
|
-
function
|
14122
|
-
|
14123
|
-
|
14124
|
-
/**
|
14125
|
-
* Hash and sign message with private key
|
14126
|
-
*/
|
14127
|
-
function hashAndSign(key, msg) {
|
14128
|
-
const p = sha256.digest(msg instanceof Uint8Array ? msg : msg.subarray());
|
14129
|
-
if (isPromise$1(p)) {
|
14130
|
-
return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
|
14131
|
-
.catch(err => {
|
14132
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
14133
|
-
});
|
14134
|
-
}
|
14135
|
-
try {
|
14136
|
-
return secp256k1.sign(p.digest, key).toDERRawBytes();
|
14137
|
-
}
|
14138
|
-
catch (err) {
|
14139
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
13666
|
+
function isPromise$1(thing) {
|
13667
|
+
if (thing == null) {
|
13668
|
+
return false;
|
14140
13669
|
}
|
13670
|
+
return typeof thing.then === 'function' &&
|
13671
|
+
typeof thing.catch === 'function' &&
|
13672
|
+
typeof thing.finally === 'function';
|
14141
13673
|
}
|
13674
|
+
|
14142
13675
|
/**
|
14143
13676
|
* Hash message and verify signature with public key
|
14144
13677
|
*/
|
@@ -14147,231 +13680,134 @@ function hashAndVerify(key, sig, msg) {
|
|
14147
13680
|
if (isPromise$1(p)) {
|
14148
13681
|
return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
|
14149
13682
|
.catch(err => {
|
14150
|
-
throw new
|
13683
|
+
throw new VerificationError(String(err));
|
14151
13684
|
});
|
14152
13685
|
}
|
14153
13686
|
try {
|
14154
13687
|
return secp256k1.verify(sig, p.digest, key);
|
14155
13688
|
}
|
14156
13689
|
catch (err) {
|
14157
|
-
throw new
|
14158
|
-
}
|
14159
|
-
}
|
14160
|
-
function compressPublicKey(key) {
|
14161
|
-
const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
|
14162
|
-
return point;
|
14163
|
-
}
|
14164
|
-
function validatePrivateKey(key) {
|
14165
|
-
try {
|
14166
|
-
secp256k1.getPublicKey(key, true);
|
14167
|
-
}
|
14168
|
-
catch (err) {
|
14169
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
14170
|
-
}
|
14171
|
-
}
|
14172
|
-
function validatePublicKey(key) {
|
14173
|
-
try {
|
14174
|
-
secp256k1.ProjectivePoint.fromHex(key);
|
14175
|
-
}
|
14176
|
-
catch (err) {
|
14177
|
-
throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
|
14178
|
-
}
|
14179
|
-
}
|
14180
|
-
function computePublicKey(privateKey) {
|
14181
|
-
try {
|
14182
|
-
return secp256k1.getPublicKey(privateKey, true);
|
14183
|
-
}
|
14184
|
-
catch (err) {
|
14185
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
13690
|
+
throw new VerificationError(String(err));
|
14186
13691
|
}
|
14187
13692
|
}
|
14188
13693
|
|
14189
13694
|
class Secp256k1PublicKey {
|
13695
|
+
type = 'secp256k1';
|
13696
|
+
raw;
|
14190
13697
|
_key;
|
14191
13698
|
constructor(key) {
|
14192
|
-
|
14193
|
-
this.
|
13699
|
+
this._key = validateSecp256k1PublicKey(key);
|
13700
|
+
this.raw = compressSecp256k1PublicKey(this._key);
|
14194
13701
|
}
|
14195
|
-
|
14196
|
-
return
|
13702
|
+
toMultihash() {
|
13703
|
+
return identity.digest(publicKeyToProtobuf(this));
|
14197
13704
|
}
|
14198
|
-
|
14199
|
-
return
|
14200
|
-
}
|
14201
|
-
get bytes() {
|
14202
|
-
return PublicKey.encode({
|
14203
|
-
Type: KeyType.Secp256k1,
|
14204
|
-
Data: this.marshal()
|
14205
|
-
}).subarray();
|
14206
|
-
}
|
14207
|
-
equals(key) {
|
14208
|
-
return equals(this.bytes, key.bytes);
|
14209
|
-
}
|
14210
|
-
async hash() {
|
14211
|
-
const p = sha256.digest(this.bytes);
|
14212
|
-
let bytes;
|
14213
|
-
if (isPromise$1(p)) {
|
14214
|
-
({ bytes } = await p);
|
14215
|
-
}
|
14216
|
-
else {
|
14217
|
-
bytes = p.bytes;
|
14218
|
-
}
|
14219
|
-
return bytes;
|
14220
|
-
}
|
14221
|
-
}
|
14222
|
-
class Secp256k1PrivateKey {
|
14223
|
-
_key;
|
14224
|
-
_publicKey;
|
14225
|
-
constructor(key, publicKey) {
|
14226
|
-
this._key = key;
|
14227
|
-
this._publicKey = publicKey ?? computePublicKey(key);
|
14228
|
-
validatePrivateKey(this._key);
|
14229
|
-
validatePublicKey(this._publicKey);
|
14230
|
-
}
|
14231
|
-
sign(message) {
|
14232
|
-
return hashAndSign(this._key, message);
|
14233
|
-
}
|
14234
|
-
get public() {
|
14235
|
-
return new Secp256k1PublicKey(this._publicKey);
|
14236
|
-
}
|
14237
|
-
marshal() {
|
14238
|
-
return this._key;
|
13705
|
+
toCID() {
|
13706
|
+
return CID.createV1(114, this.toMultihash());
|
14239
13707
|
}
|
14240
|
-
|
14241
|
-
return
|
14242
|
-
Type: KeyType.Secp256k1,
|
14243
|
-
Data: this.marshal()
|
14244
|
-
}).subarray();
|
13708
|
+
toString() {
|
13709
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
14245
13710
|
}
|
14246
13711
|
equals(key) {
|
14247
|
-
|
14248
|
-
|
14249
|
-
hash() {
|
14250
|
-
const p = sha256.digest(this.bytes);
|
14251
|
-
if (isPromise$1(p)) {
|
14252
|
-
return p.then(({ bytes }) => bytes);
|
13712
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
13713
|
+
return false;
|
14253
13714
|
}
|
14254
|
-
return
|
14255
|
-
}
|
14256
|
-
/**
|
14257
|
-
* Gets the ID of the key.
|
14258
|
-
*
|
14259
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
14260
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
14261
|
-
* of the PKCS SubjectPublicKeyInfo.
|
14262
|
-
*/
|
14263
|
-
async id() {
|
14264
|
-
const hash = await this.public.hash();
|
14265
|
-
return toString$6(hash, 'base58btc');
|
13715
|
+
return equals(this.raw, key.raw);
|
14266
13716
|
}
|
14267
|
-
|
14268
|
-
|
14269
|
-
*/
|
14270
|
-
async export(password, format = 'libp2p-key') {
|
14271
|
-
if (format === 'libp2p-key') {
|
14272
|
-
return exporter(this.bytes, password);
|
14273
|
-
}
|
14274
|
-
else {
|
14275
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
14276
|
-
}
|
13717
|
+
verify(data, sig) {
|
13718
|
+
return hashAndVerify(this._key, sig, data);
|
14277
13719
|
}
|
14278
13720
|
}
|
14279
|
-
|
14280
|
-
return new Secp256k1PrivateKey(bytes);
|
14281
|
-
}
|
13721
|
+
|
14282
13722
|
function unmarshalSecp256k1PublicKey(bytes) {
|
14283
13723
|
return new Secp256k1PublicKey(bytes);
|
14284
13724
|
}
|
14285
|
-
|
14286
|
-
const
|
14287
|
-
return
|
13725
|
+
function compressSecp256k1PublicKey(key) {
|
13726
|
+
const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
|
13727
|
+
return point;
|
13728
|
+
}
|
13729
|
+
function validateSecp256k1PublicKey(key) {
|
13730
|
+
try {
|
13731
|
+
secp256k1.ProjectivePoint.fromHex(key);
|
13732
|
+
return key;
|
13733
|
+
}
|
13734
|
+
catch (err) {
|
13735
|
+
throw new InvalidPublicKeyError(String(err));
|
13736
|
+
}
|
14288
13737
|
}
|
14289
|
-
|
14290
|
-
var Secp256k1 = /*#__PURE__*/Object.freeze({
|
14291
|
-
__proto__: null,
|
14292
|
-
Secp256k1PrivateKey: Secp256k1PrivateKey,
|
14293
|
-
Secp256k1PublicKey: Secp256k1PublicKey,
|
14294
|
-
generateKeyPair: generateKeyPair,
|
14295
|
-
unmarshalSecp256k1PrivateKey: unmarshalSecp256k1PrivateKey,
|
14296
|
-
unmarshalSecp256k1PublicKey: unmarshalSecp256k1PublicKey
|
14297
|
-
});
|
14298
13738
|
|
14299
13739
|
/**
|
14300
13740
|
* @packageDocumentation
|
14301
13741
|
*
|
14302
|
-
*
|
14303
|
-
*
|
14304
|
-
* The {@link generateKeyPair}, {@link marshalPublicKey}, and {@link marshalPrivateKey} functions accept a string `type` argument.
|
13742
|
+
* ## Supported Key Types
|
14305
13743
|
*
|
14306
13744
|
* Currently the `'RSA'`, `'ed25519'`, and `secp256k1` types are supported, although ed25519 and secp256k1 keys support only signing and verification of messages.
|
14307
13745
|
*
|
14308
13746
|
* For encryption / decryption support, RSA keys should be used.
|
14309
13747
|
*/
|
14310
|
-
|
14311
|
-
|
14312
|
-
|
14313
|
-
|
14314
|
-
|
14315
|
-
|
14316
|
-
|
14317
|
-
|
14318
|
-
|
14319
|
-
|
14320
|
-
|
14321
|
-
|
14322
|
-
return supportedKeys[type];
|
13748
|
+
/**
|
13749
|
+
* Creates a public key from the raw key bytes
|
13750
|
+
*/
|
13751
|
+
function publicKeyFromRaw(buf) {
|
13752
|
+
if (buf.byteLength === 32) {
|
13753
|
+
return unmarshalEd25519PublicKey(buf);
|
13754
|
+
}
|
13755
|
+
else if (buf.byteLength === 33) {
|
13756
|
+
return unmarshalSecp256k1PublicKey(buf);
|
13757
|
+
}
|
13758
|
+
else {
|
13759
|
+
return pkixToRSAPublicKey(buf);
|
14323
13760
|
}
|
14324
|
-
throw unsupportedKey(type);
|
14325
13761
|
}
|
14326
13762
|
/**
|
14327
|
-
*
|
13763
|
+
* Creates a public key from an identity multihash which contains a protobuf
|
13764
|
+
* encoded Ed25519 or secp256k1 public key.
|
13765
|
+
*
|
13766
|
+
* RSA keys are not supported as in practice we they are not stored in identity
|
13767
|
+
* multihashes since the hash would be very large.
|
14328
13768
|
*/
|
14329
|
-
function
|
14330
|
-
const
|
14331
|
-
const data =
|
14332
|
-
switch (
|
14333
|
-
case KeyType.RSA:
|
14334
|
-
return supportedKeys.rsa.unmarshalRsaPublicKey(data);
|
13769
|
+
function publicKeyFromMultihash(digest) {
|
13770
|
+
const { Type, Data } = PublicKey.decode(digest.digest);
|
13771
|
+
const data = Data ?? new Uint8Array();
|
13772
|
+
switch (Type) {
|
14335
13773
|
case KeyType.Ed25519:
|
14336
|
-
return
|
14337
|
-
case KeyType.
|
14338
|
-
return
|
13774
|
+
return unmarshalEd25519PublicKey(data);
|
13775
|
+
case KeyType.secp256k1:
|
13776
|
+
return unmarshalSecp256k1PublicKey(data);
|
14339
13777
|
default:
|
14340
|
-
throw
|
13778
|
+
throw new UnsupportedKeyTypeError$1();
|
14341
13779
|
}
|
14342
13780
|
}
|
14343
13781
|
/**
|
14344
13782
|
* Converts a public key object into a protobuf serialized public key
|
14345
13783
|
*/
|
14346
|
-
function
|
14347
|
-
|
14348
|
-
|
14349
|
-
|
13784
|
+
function publicKeyToProtobuf(key) {
|
13785
|
+
return PublicKey.encode({
|
13786
|
+
Type: KeyType[key.type],
|
13787
|
+
Data: key.raw
|
13788
|
+
});
|
14350
13789
|
}
|
13790
|
+
|
14351
13791
|
/**
|
14352
|
-
*
|
13792
|
+
* All PeerId implementations must use this symbol as the name of a property
|
13793
|
+
* with a boolean `true` value
|
13794
|
+
*/
|
13795
|
+
const peerIdSymbol = Symbol.for('@libp2p/peer-id');
|
13796
|
+
|
13797
|
+
/**
|
13798
|
+
* When this error is thrown it means an operation was aborted,
|
13799
|
+
* usually in response to the `abort` event being emitted by an
|
13800
|
+
* AbortSignal.
|
14353
13801
|
*/
|
14354
|
-
async function unmarshalPrivateKey(buf) {
|
14355
|
-
const decoded = PrivateKey.decode(buf);
|
14356
|
-
const data = decoded.Data ?? new Uint8Array();
|
14357
|
-
switch (decoded.Type) {
|
14358
|
-
case KeyType.RSA:
|
14359
|
-
return supportedKeys.rsa.unmarshalRsaPrivateKey(data);
|
14360
|
-
case KeyType.Ed25519:
|
14361
|
-
return supportedKeys.ed25519.unmarshalEd25519PrivateKey(data);
|
14362
|
-
case KeyType.Secp256k1:
|
14363
|
-
return supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(data);
|
14364
|
-
default:
|
14365
|
-
throw unsupportedKey(decoded.Type ?? 'RSA');
|
14366
|
-
}
|
14367
|
-
}
|
14368
13802
|
/**
|
14369
|
-
*
|
13803
|
+
* Thrown when and attempt to operate on an unsupported key was made
|
14370
13804
|
*/
|
14371
|
-
|
14372
|
-
|
14373
|
-
|
14374
|
-
|
13805
|
+
class UnsupportedKeyTypeError extends Error {
|
13806
|
+
static name = 'UnsupportedKeyTypeError';
|
13807
|
+
constructor(message = 'Unsupported key type') {
|
13808
|
+
super(message);
|
13809
|
+
this.name = 'UnsupportedKeyTypeError';
|
13810
|
+
}
|
14375
13811
|
}
|
14376
13812
|
|
14377
13813
|
/**
|
@@ -14389,26 +13825,17 @@ function marshalPrivateKey(key, type) {
|
|
14389
13825
|
* console.log(peer.toString()) // "12D3K..."
|
14390
13826
|
* ```
|
14391
13827
|
*/
|
14392
|
-
const inspect = Symbol.for('nodejs.util.inspect.custom');
|
14393
|
-
const baseDecoder = Object
|
14394
|
-
.values(bases)
|
14395
|
-
.map(codec => codec.decoder)
|
14396
|
-
// @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
|
14397
|
-
.reduce((acc, curr) => acc.or(curr), bases.identity.decoder);
|
13828
|
+
const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
|
14398
13829
|
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14399
|
-
const LIBP2P_KEY_CODE = 0x72;
|
14400
|
-
|
14401
|
-
const MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH = 37;
|
14402
|
-
class PeerIdImpl {
|
13830
|
+
const LIBP2P_KEY_CODE$1 = 0x72;
|
13831
|
+
let PeerIdImpl$1 = class PeerIdImpl {
|
14403
13832
|
type;
|
14404
13833
|
multihash;
|
14405
|
-
privateKey;
|
14406
13834
|
publicKey;
|
14407
13835
|
string;
|
14408
13836
|
constructor(init) {
|
14409
13837
|
this.type = init.type;
|
14410
13838
|
this.multihash = init.multihash;
|
14411
|
-
this.privateKey = init.privateKey;
|
14412
13839
|
// mark string cache as non-enumerable
|
14413
13840
|
Object.defineProperty(this, 'string', {
|
14414
13841
|
enumerable: false,
|
@@ -14425,17 +13852,14 @@ class PeerIdImpl {
|
|
14425
13852
|
}
|
14426
13853
|
return this.string;
|
14427
13854
|
}
|
13855
|
+
toMultihash() {
|
13856
|
+
return this.multihash;
|
13857
|
+
}
|
14428
13858
|
// return self-describing String representation
|
14429
13859
|
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
14430
13860
|
toCID() {
|
14431
|
-
return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
|
14432
|
-
}
|
14433
|
-
toBytes() {
|
14434
|
-
return this.multihash.bytes;
|
13861
|
+
return CID.createV1(LIBP2P_KEY_CODE$1, this.multihash);
|
14435
13862
|
}
|
14436
|
-
/**
|
14437
|
-
* Returns Multiaddr as a JSON string
|
14438
|
-
*/
|
14439
13863
|
toJSON() {
|
14440
13864
|
return this.toString();
|
14441
13865
|
}
|
@@ -14450,10 +13874,10 @@ class PeerIdImpl {
|
|
14450
13874
|
return equals(this.multihash.bytes, id);
|
14451
13875
|
}
|
14452
13876
|
else if (typeof id === 'string') {
|
14453
|
-
return
|
13877
|
+
return this.toString() === id;
|
14454
13878
|
}
|
14455
|
-
else if (id?.
|
14456
|
-
return equals(this.multihash.bytes, id.
|
13879
|
+
else if (id?.toMultihash()?.bytes != null) {
|
13880
|
+
return equals(this.multihash.bytes, id.toMultihash().bytes);
|
14457
13881
|
}
|
14458
13882
|
else {
|
14459
13883
|
throw new Error('not valid Id');
|
@@ -14471,145 +13895,79 @@ class PeerIdImpl {
|
|
14471
13895
|
* // 'PeerId(QmFoo)'
|
14472
13896
|
* ```
|
14473
13897
|
*/
|
14474
|
-
[inspect]() {
|
13898
|
+
[inspect$1]() {
|
14475
13899
|
return `PeerId(${this.toString()})`;
|
14476
13900
|
}
|
14477
|
-
}
|
14478
|
-
class
|
14479
|
-
type = 'RSA';
|
14480
|
-
publicKey;
|
14481
|
-
constructor(init) {
|
14482
|
-
super({ ...init, type: 'RSA' });
|
14483
|
-
this.publicKey = init.publicKey;
|
14484
|
-
}
|
14485
|
-
}
|
14486
|
-
class Ed25519PeerIdImpl extends PeerIdImpl {
|
14487
|
-
type = 'Ed25519';
|
14488
|
-
publicKey;
|
14489
|
-
constructor(init) {
|
14490
|
-
super({ ...init, type: 'Ed25519' });
|
14491
|
-
this.publicKey = init.multihash.digest;
|
14492
|
-
}
|
14493
|
-
}
|
14494
|
-
class Secp256k1PeerIdImpl extends PeerIdImpl {
|
14495
|
-
type = 'secp256k1';
|
14496
|
-
publicKey;
|
14497
|
-
constructor(init) {
|
14498
|
-
super({ ...init, type: 'secp256k1' });
|
14499
|
-
this.publicKey = init.multihash.digest;
|
14500
|
-
}
|
14501
|
-
}
|
14502
|
-
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14503
|
-
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
14504
|
-
class URLPeerIdImpl {
|
14505
|
-
type = 'url';
|
14506
|
-
multihash;
|
14507
|
-
privateKey;
|
14508
|
-
publicKey;
|
14509
|
-
url;
|
14510
|
-
constructor(url) {
|
14511
|
-
this.url = url.toString();
|
14512
|
-
this.multihash = identity.digest(fromString(this.url));
|
14513
|
-
}
|
14514
|
-
[inspect]() {
|
14515
|
-
return `PeerId(${this.url})`;
|
14516
|
-
}
|
14517
|
-
[peerIdSymbol] = true;
|
14518
|
-
toString() {
|
14519
|
-
return this.toCID().toString();
|
14520
|
-
}
|
14521
|
-
toCID() {
|
14522
|
-
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
|
14523
|
-
}
|
14524
|
-
toBytes() {
|
14525
|
-
return this.toCID().bytes;
|
14526
|
-
}
|
14527
|
-
equals(other) {
|
14528
|
-
if (other == null) {
|
14529
|
-
return false;
|
14530
|
-
}
|
14531
|
-
if (other instanceof Uint8Array) {
|
14532
|
-
other = toString$6(other);
|
14533
|
-
}
|
14534
|
-
return other.toString() === this.toString();
|
14535
|
-
}
|
14536
|
-
}
|
14537
|
-
function peerIdFromString(str, decoder) {
|
14538
|
-
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
14539
|
-
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
14540
|
-
// rsa public key - base58btc encoded either way
|
14541
|
-
const multihash = decode$6(base58btc.decode(`z${str}`));
|
14542
|
-
if (str.startsWith('12D')) {
|
14543
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14544
|
-
}
|
14545
|
-
else if (str.startsWith('16U')) {
|
14546
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14547
|
-
}
|
14548
|
-
else {
|
14549
|
-
return new RSAPeerIdImpl({ multihash });
|
14550
|
-
}
|
14551
|
-
}
|
14552
|
-
return peerIdFromBytes(baseDecoder.decode(str));
|
14553
|
-
}
|
14554
|
-
function peerIdFromBytes(buf) {
|
14555
|
-
try {
|
14556
|
-
const multihash = decode$6(buf);
|
14557
|
-
if (multihash.code === identity.code) {
|
14558
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14559
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14560
|
-
}
|
14561
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14562
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14563
|
-
}
|
14564
|
-
}
|
14565
|
-
if (multihash.code === sha256.code) {
|
14566
|
-
return new RSAPeerIdImpl({ multihash });
|
14567
|
-
}
|
14568
|
-
}
|
14569
|
-
catch {
|
14570
|
-
return peerIdFromCID(CID.decode(buf));
|
14571
|
-
}
|
14572
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14573
|
-
}
|
14574
|
-
function peerIdFromCID(cid) {
|
14575
|
-
if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
|
14576
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14577
|
-
}
|
14578
|
-
if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
|
14579
|
-
const url = toString$6(cid.multihash.digest);
|
14580
|
-
return new URLPeerIdImpl(new URL(url));
|
13901
|
+
};
|
13902
|
+
let RSAPeerId$1 = class RSAPeerId extends PeerIdImpl$1 {
|
13903
|
+
type = 'RSA';
|
13904
|
+
publicKey;
|
13905
|
+
constructor(init) {
|
13906
|
+
super({ ...init, type: 'RSA' });
|
13907
|
+
this.publicKey = init.publicKey;
|
14581
13908
|
}
|
14582
|
-
|
14583
|
-
|
14584
|
-
|
13909
|
+
};
|
13910
|
+
let Ed25519PeerId$1 = class Ed25519PeerId extends PeerIdImpl$1 {
|
13911
|
+
type = 'Ed25519';
|
13912
|
+
publicKey;
|
13913
|
+
constructor(init) {
|
13914
|
+
super({ ...init, type: 'Ed25519' });
|
13915
|
+
this.publicKey = init.publicKey;
|
14585
13916
|
}
|
14586
|
-
|
14587
|
-
|
14588
|
-
|
14589
|
-
|
14590
|
-
|
14591
|
-
|
14592
|
-
|
13917
|
+
};
|
13918
|
+
let Secp256k1PeerId$1 = class Secp256k1PeerId extends PeerIdImpl$1 {
|
13919
|
+
type = 'secp256k1';
|
13920
|
+
publicKey;
|
13921
|
+
constructor(init) {
|
13922
|
+
super({ ...init, type: 'secp256k1' });
|
13923
|
+
this.publicKey = init.publicKey;
|
14593
13924
|
}
|
14594
|
-
|
14595
|
-
|
13925
|
+
};
|
13926
|
+
|
14596
13927
|
/**
|
14597
|
-
* @
|
14598
|
-
*
|
13928
|
+
* @packageDocumentation
|
13929
|
+
*
|
13930
|
+
* An implementation of a peer id
|
13931
|
+
*
|
13932
|
+
* @example
|
13933
|
+
*
|
13934
|
+
* ```TypeScript
|
13935
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
13936
|
+
* const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
|
13937
|
+
*
|
13938
|
+
* console.log(peer.toCID()) // CID(bafzaa...)
|
13939
|
+
* console.log(peer.toString()) // "12D3K..."
|
13940
|
+
* ```
|
14599
13941
|
*/
|
14600
|
-
|
14601
|
-
if (publicKey.
|
14602
|
-
return new
|
13942
|
+
function peerIdFromPublicKey(publicKey) {
|
13943
|
+
if (publicKey.type === 'Ed25519') {
|
13944
|
+
return new Ed25519PeerId$1({
|
13945
|
+
multihash: publicKey.toCID().multihash,
|
13946
|
+
publicKey
|
13947
|
+
});
|
13948
|
+
}
|
13949
|
+
else if (publicKey.type === 'secp256k1') {
|
13950
|
+
return new Secp256k1PeerId$1({
|
13951
|
+
multihash: publicKey.toCID().multihash,
|
13952
|
+
publicKey
|
13953
|
+
});
|
14603
13954
|
}
|
14604
|
-
if (publicKey.
|
14605
|
-
return new
|
13955
|
+
else if (publicKey.type === 'RSA') {
|
13956
|
+
return new RSAPeerId$1({
|
13957
|
+
multihash: publicKey.toCID().multihash,
|
13958
|
+
publicKey
|
13959
|
+
});
|
14606
13960
|
}
|
14607
|
-
|
13961
|
+
throw new UnsupportedKeyTypeError();
|
14608
13962
|
}
|
14609
13963
|
|
13964
|
+
const ERR_TYPE_NOT_IMPLEMENTED = "Keypair type not implemented";
|
14610
13965
|
function createPeerIdFromPublicKey(publicKey) {
|
14611
|
-
const
|
14612
|
-
|
13966
|
+
const pubKey = publicKeyFromRaw(publicKey);
|
13967
|
+
if (pubKey.type !== "secp256k1") {
|
13968
|
+
throw new Error(ERR_TYPE_NOT_IMPLEMENTED);
|
13969
|
+
}
|
13970
|
+
return peerIdFromPublicKey(pubKey);
|
14613
13971
|
}
|
14614
13972
|
|
14615
13973
|
function decodeMultiaddrs(bytes) {
|
@@ -14856,12 +14214,12 @@ var TransportProtocolPerIpVersion;
|
|
14856
14214
|
class ENR extends RawEnr {
|
14857
14215
|
static RECORD_PREFIX = "enr:";
|
14858
14216
|
peerId;
|
14859
|
-
static
|
14217
|
+
static create(kvs = {}, seq = BigInt(1), signature) {
|
14860
14218
|
const enr = new ENR(kvs, seq, signature);
|
14861
14219
|
try {
|
14862
14220
|
const publicKey = enr.publicKey;
|
14863
14221
|
if (publicKey) {
|
14864
|
-
enr.peerId =
|
14222
|
+
enr.peerId = createPeerIdFromPublicKey(publicKey);
|
14865
14223
|
}
|
14866
14224
|
}
|
14867
14225
|
catch (e) {
|
@@ -15626,7 +14984,7 @@ async function fromValues(values) {
|
|
15626
14984
|
}
|
15627
14985
|
}
|
15628
14986
|
const _seq = decodeSeq(seq);
|
15629
|
-
const enr =
|
14987
|
+
const enr = ENR.create(obj, _seq, signature);
|
15630
14988
|
checkSignature(seq, kvs, enr, signature);
|
15631
14989
|
return enr;
|
15632
14990
|
}
|
@@ -20739,28 +20097,6 @@ async function getPeersForProtocol(peerStore, protocols) {
|
|
20739
20097
|
});
|
20740
20098
|
return peers;
|
20741
20099
|
}
|
20742
|
-
async function getConnectedPeersForProtocolAndShard(connections, peerStore, protocols, shardInfo) {
|
20743
|
-
const openConnections = connections.filter((connection) => connection.status === "open");
|
20744
|
-
const peerPromises = openConnections.map(async (connection) => {
|
20745
|
-
const peer = await peerStore.get(connection.remotePeer);
|
20746
|
-
const supportsProtocol = protocols.some((protocol) => peer.protocols.includes(protocol));
|
20747
|
-
if (supportsProtocol) {
|
20748
|
-
if (shardInfo) {
|
20749
|
-
const encodedPeerShardInfo = peer.metadata.get("shardInfo");
|
20750
|
-
const peerShardInfo = encodedPeerShardInfo && decodeRelayShard(encodedPeerShardInfo);
|
20751
|
-
if (peerShardInfo && shardInfo.clusterId === peerShardInfo.clusterId) {
|
20752
|
-
return peer;
|
20753
|
-
}
|
20754
|
-
}
|
20755
|
-
else {
|
20756
|
-
return peer;
|
20757
|
-
}
|
20758
|
-
}
|
20759
|
-
return null;
|
20760
|
-
});
|
20761
|
-
const peersWithNulls = await Promise.all(peerPromises);
|
20762
|
-
return peersWithNulls.filter((peer) => peer !== null);
|
20763
|
-
}
|
20764
20100
|
|
20765
20101
|
/**
|
20766
20102
|
* Retrieves a list of peers based on the specified criteria:
|
@@ -20799,110 +20135,129 @@ function filterPeersByDiscovery(peers, numPeers, maxBootstrapPeers) {
|
|
20799
20135
|
return selectedPeers;
|
20800
20136
|
}
|
20801
20137
|
|
20802
|
-
function
|
20803
|
-
|
20804
|
-
|
20805
|
-
|
20806
|
-
|
20807
|
-
let latestConnection;
|
20808
|
-
connections.forEach((connection) => {
|
20809
|
-
if (connection.status === "open") {
|
20810
|
-
if (!latestConnection) {
|
20811
|
-
latestConnection = connection;
|
20812
|
-
}
|
20813
|
-
else if (connection.timeline.open > latestConnection.timeline.open) {
|
20814
|
-
latestConnection = connection;
|
20815
|
-
}
|
20816
|
-
}
|
20817
|
-
});
|
20818
|
-
return latestConnection;
|
20138
|
+
function selectOpenConnection(connections) {
|
20139
|
+
return connections
|
20140
|
+
.filter((c) => c.status === "open")
|
20141
|
+
.sort((left, right) => right.timeline.open - left.timeline.open)
|
20142
|
+
.at(0);
|
20819
20143
|
}
|
20820
20144
|
|
20821
|
-
const
|
20822
|
-
const RETRY_BACKOFF_BASE = 1_000;
|
20823
|
-
const MAX_RETRIES = 3;
|
20145
|
+
const STREAM_LOCK_KEY = "consumed";
|
20824
20146
|
class StreamManager {
|
20825
20147
|
multicodec;
|
20826
20148
|
getConnections;
|
20827
20149
|
addEventListener;
|
20828
|
-
streamPool;
|
20829
20150
|
log;
|
20151
|
+
ongoingCreation = new Set();
|
20152
|
+
streamPool = new Map();
|
20830
20153
|
constructor(multicodec, getConnections, addEventListener) {
|
20831
20154
|
this.multicodec = multicodec;
|
20832
20155
|
this.getConnections = getConnections;
|
20833
20156
|
this.addEventListener = addEventListener;
|
20834
20157
|
this.log = new Logger$1(`stream-manager:${multicodec}`);
|
20835
|
-
this.streamPool = new Map();
|
20836
20158
|
this.addEventListener("peer:update", this.handlePeerUpdateStreamPool);
|
20837
20159
|
}
|
20838
20160
|
async getStream(peer) {
|
20839
|
-
const
|
20840
|
-
const
|
20841
|
-
if (
|
20842
|
-
|
20161
|
+
const peerId = peer.id.toString();
|
20162
|
+
const scheduledStream = this.streamPool.get(peerId);
|
20163
|
+
if (scheduledStream) {
|
20164
|
+
this.streamPool.delete(peerId);
|
20165
|
+
await scheduledStream;
|
20166
|
+
}
|
20167
|
+
let stream = this.getOpenStreamForCodec(peer.id);
|
20168
|
+
if (stream) {
|
20169
|
+
this.log.info(`Found existing stream peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
20170
|
+
this.lockStream(peer.id.toString(), stream);
|
20171
|
+
return stream;
|
20172
|
+
}
|
20173
|
+
stream = await this.createStream(peer);
|
20174
|
+
this.lockStream(peer.id.toString(), stream);
|
20175
|
+
return stream;
|
20176
|
+
}
|
20177
|
+
async createStream(peer, retries = 0) {
|
20178
|
+
const connections = this.getConnections(peer.id);
|
20179
|
+
const connection = selectOpenConnection(connections);
|
20180
|
+
if (!connection) {
|
20181
|
+
throw new Error(`Failed to get a connection to the peer peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
20843
20182
|
}
|
20844
|
-
|
20845
|
-
|
20846
|
-
|
20847
|
-
|
20848
|
-
|
20849
|
-
|
20183
|
+
let lastError;
|
20184
|
+
let stream;
|
20185
|
+
for (let i = 0; i < retries + 1; i++) {
|
20186
|
+
try {
|
20187
|
+
this.log.info(`Attempting to create a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
20188
|
+
stream = await connection.newStream(this.multicodec);
|
20189
|
+
this.log.info(`Created stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
20190
|
+
break;
|
20191
|
+
}
|
20192
|
+
catch (error) {
|
20193
|
+
lastError = error;
|
20850
20194
|
}
|
20851
20195
|
}
|
20852
|
-
|
20853
|
-
|
20854
|
-
|
20196
|
+
if (!stream) {
|
20197
|
+
throw new Error(`Failed to create a new stream for ${peer.id.toString()} -- ` +
|
20198
|
+
lastError);
|
20855
20199
|
}
|
20856
|
-
return
|
20200
|
+
return stream;
|
20857
20201
|
}
|
20858
|
-
async
|
20859
|
-
const
|
20860
|
-
|
20861
|
-
|
20862
|
-
|
20202
|
+
async createStreamWithLock(peer) {
|
20203
|
+
const peerId = peer.id.toString();
|
20204
|
+
if (this.ongoingCreation.has(peerId)) {
|
20205
|
+
this.log.info(`Skipping creation of a stream due to lock for peerId=${peerId} multicodec=${this.multicodec}`);
|
20206
|
+
return;
|
20863
20207
|
}
|
20864
20208
|
try {
|
20865
|
-
|
20209
|
+
this.ongoingCreation.add(peerId);
|
20210
|
+
await this.createStream(peer);
|
20866
20211
|
}
|
20867
20212
|
catch (error) {
|
20868
|
-
|
20869
|
-
const backoff = RETRY_BACKOFF_BASE * Math.pow(2, retries);
|
20870
|
-
await new Promise((resolve) => setTimeout(resolve, backoff));
|
20871
|
-
return this.createStream(peer, retries + 1);
|
20872
|
-
}
|
20873
|
-
throw new Error(`Failed to create a new stream for ${peer.id.toString()} -- ` + error);
|
20213
|
+
this.log.error(`Failed to createStreamWithLock:`, error);
|
20874
20214
|
}
|
20875
|
-
|
20876
|
-
|
20877
|
-
|
20878
|
-
|
20879
|
-
this.createStream(peer),
|
20880
|
-
timeoutPromise.then(() => {
|
20881
|
-
throw new Error("Connection timeout");
|
20882
|
-
})
|
20883
|
-
]).catch((error) => {
|
20884
|
-
this.log.error(`Failed to prepare a new stream for ${peer.id.toString()} -- `, error);
|
20885
|
-
});
|
20886
|
-
this.streamPool.set(peer.id.toString(), streamPromise);
|
20215
|
+
finally {
|
20216
|
+
this.ongoingCreation.delete(peerId);
|
20217
|
+
}
|
20218
|
+
return;
|
20887
20219
|
}
|
20888
20220
|
handlePeerUpdateStreamPool = (evt) => {
|
20889
20221
|
const { peer } = evt.detail;
|
20890
|
-
if (peer.protocols.includes(this.multicodec)) {
|
20891
|
-
|
20892
|
-
if (isConnected) {
|
20893
|
-
this.log.info(`Preemptively opening a stream to ${peer.id.toString()}`);
|
20894
|
-
this.prepareStream(peer);
|
20895
|
-
}
|
20896
|
-
else {
|
20897
|
-
const peerIdStr = peer.id.toString();
|
20898
|
-
this.streamPool.delete(peerIdStr);
|
20899
|
-
this.log.info(`Removed pending stream for disconnected peer ${peerIdStr}`);
|
20900
|
-
}
|
20222
|
+
if (!peer.protocols.includes(this.multicodec)) {
|
20223
|
+
return;
|
20901
20224
|
}
|
20225
|
+
const stream = this.getOpenStreamForCodec(peer.id);
|
20226
|
+
if (stream) {
|
20227
|
+
return;
|
20228
|
+
}
|
20229
|
+
this.scheduleNewStream(peer);
|
20902
20230
|
};
|
20903
|
-
|
20231
|
+
scheduleNewStream(peer) {
|
20232
|
+
this.log.info(`Scheduling creation of a stream for peerId=${peer.id.toString()} multicodec=${this.multicodec}`);
|
20233
|
+
// abandon previous attempt
|
20234
|
+
if (this.streamPool.has(peer.id.toString())) {
|
20235
|
+
this.streamPool.delete(peer.id.toString());
|
20236
|
+
}
|
20237
|
+
this.streamPool.set(peer.id.toString(), this.createStreamWithLock(peer));
|
20238
|
+
}
|
20239
|
+
getOpenStreamForCodec(peerId) {
|
20904
20240
|
const connections = this.getConnections(peerId);
|
20905
|
-
|
20241
|
+
const connection = selectOpenConnection(connections);
|
20242
|
+
if (!connection) {
|
20243
|
+
return;
|
20244
|
+
}
|
20245
|
+
const stream = connection.streams.find((s) => s.protocol === this.multicodec);
|
20246
|
+
if (!stream) {
|
20247
|
+
return;
|
20248
|
+
}
|
20249
|
+
const isStreamUnusable = ["done", "closed", "closing"].includes(stream.writeStatus || "");
|
20250
|
+
if (isStreamUnusable || this.isStreamLocked(stream)) {
|
20251
|
+
return;
|
20252
|
+
}
|
20253
|
+
return stream;
|
20254
|
+
}
|
20255
|
+
lockStream(peerId, stream) {
|
20256
|
+
this.log.info(`Locking stream for peerId:${peerId}\tstreamId:${stream.id}`);
|
20257
|
+
stream.metadata[STREAM_LOCK_KEY] = true;
|
20258
|
+
}
|
20259
|
+
isStreamLocked(stream) {
|
20260
|
+
return !!stream.metadata[STREAM_LOCK_KEY];
|
20906
20261
|
}
|
20907
20262
|
}
|
20908
20263
|
|
@@ -20930,21 +20285,19 @@ class BaseProtocol {
|
|
20930
20285
|
async getStream(peer) {
|
20931
20286
|
return this.streamManager.getStream(peer);
|
20932
20287
|
}
|
20933
|
-
get peerStore() {
|
20934
|
-
return this.components.peerStore;
|
20935
|
-
}
|
20936
20288
|
/**
|
20937
20289
|
* Returns known peers from the address book (`libp2p.peerStore`) that support
|
20938
20290
|
* the class protocol. Waku may or may not be currently connected to these
|
20939
20291
|
* peers.
|
20940
20292
|
*/
|
20941
20293
|
async allPeers() {
|
20942
|
-
return getPeersForProtocol(this.peerStore, [this.multicodec]);
|
20294
|
+
return getPeersForProtocol(this.components.peerStore, [this.multicodec]);
|
20943
20295
|
}
|
20944
20296
|
async connectedPeers() {
|
20945
20297
|
const peers = await this.allPeers();
|
20946
20298
|
return peers.filter((peer) => {
|
20947
|
-
|
20299
|
+
const connections = this.components.connectionManager.getConnections(peer.id);
|
20300
|
+
return connections.length > 0;
|
20948
20301
|
});
|
20949
20302
|
}
|
20950
20303
|
/**
|
@@ -20952,19 +20305,18 @@ class BaseProtocol {
|
|
20952
20305
|
*
|
20953
20306
|
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned.
|
20954
20307
|
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
|
20955
|
-
|
20956
|
-
|
20957
|
-
*/
|
20308
|
+
* @returns A list of peers that support the protocol sorted by latency. By default, returns all peers available, including bootstrap.
|
20309
|
+
*/
|
20958
20310
|
async getPeers({ numPeers, maxBootstrapPeers } = {
|
20959
|
-
maxBootstrapPeers:
|
20311
|
+
maxBootstrapPeers: 0,
|
20960
20312
|
numPeers: 0
|
20961
20313
|
}) {
|
20962
20314
|
// Retrieve all connected peers that support the protocol & shard (if configured)
|
20963
|
-
const
|
20315
|
+
const allAvailableConnectedPeers = await this.connectedPeers();
|
20964
20316
|
// Filter the peers based on discovery & number of peers requested
|
20965
|
-
const filteredPeers = filterPeersByDiscovery(
|
20317
|
+
const filteredPeers = filterPeersByDiscovery(allAvailableConnectedPeers, numPeers, maxBootstrapPeers);
|
20966
20318
|
// Sort the peers by latency
|
20967
|
-
const sortedFilteredPeers = await sortPeersByLatency(this.peerStore, filteredPeers);
|
20319
|
+
const sortedFilteredPeers = await sortPeersByLatency(this.components.peerStore, filteredPeers);
|
20968
20320
|
if (sortedFilteredPeers.length === 0) {
|
20969
20321
|
this.log.warn("No peers found. Ensure you have a connection to the network.");
|
20970
20322
|
}
|
@@ -24658,7 +24010,7 @@ class WakuPeerExchange extends BaseProtocol {
|
|
24658
24010
|
const rpcQuery = PeerExchangeRPC.createRequest({
|
24659
24011
|
numPeers: BigInt(numPeers)
|
24660
24012
|
});
|
24661
|
-
const peer = await this.peerStore.get(peerId);
|
24013
|
+
const peer = await this.components.peerStore.get(peerId);
|
24662
24014
|
if (!peer) {
|
24663
24015
|
return {
|
24664
24016
|
peerInfos: null,
|
@@ -24898,50 +24250,210 @@ function wakuPeerExchangeDiscovery(pubsubTopics) {
|
|
24898
24250
|
/**
|
24899
24251
|
* @packageDocumentation
|
24900
24252
|
*
|
24901
|
-
*
|
24902
|
-
*
|
24903
|
-
* A Peer ID is the SHA-256 [multihash](https://github.com/multiformats/multihash) of a public key.
|
24904
|
-
*
|
24905
|
-
* 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.
|
24253
|
+
* An implementation of a peer id
|
24906
24254
|
*
|
24907
24255
|
* @example
|
24908
24256
|
*
|
24909
24257
|
* ```TypeScript
|
24910
|
-
* import {
|
24911
|
-
*
|
24912
|
-
* const peerId = await createEd25519PeerId()
|
24913
|
-
* console.log(peerId.toString())
|
24914
|
-
* ```
|
24258
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
24259
|
+
* const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
|
24915
24260
|
*
|
24916
|
-
*
|
24917
|
-
*
|
24261
|
+
* console.log(peer.toCID()) // CID(bafzaa...)
|
24262
|
+
* console.log(peer.toString()) // "12D3K..."
|
24918
24263
|
* ```
|
24919
24264
|
*/
|
24920
|
-
|
24921
|
-
|
24265
|
+
const inspect = Symbol.for('nodejs.util.inspect.custom');
|
24266
|
+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
24267
|
+
const LIBP2P_KEY_CODE = 0x72;
|
24268
|
+
class PeerIdImpl {
|
24269
|
+
type;
|
24270
|
+
multihash;
|
24271
|
+
publicKey;
|
24272
|
+
string;
|
24273
|
+
constructor(init) {
|
24274
|
+
this.type = init.type;
|
24275
|
+
this.multihash = init.multihash;
|
24276
|
+
// mark string cache as non-enumerable
|
24277
|
+
Object.defineProperty(this, 'string', {
|
24278
|
+
enumerable: false,
|
24279
|
+
writable: true
|
24280
|
+
});
|
24281
|
+
}
|
24282
|
+
get [Symbol.toStringTag]() {
|
24283
|
+
return `PeerId(${this.toString()})`;
|
24284
|
+
}
|
24285
|
+
[peerIdSymbol$1] = true;
|
24286
|
+
toString() {
|
24287
|
+
if (this.string == null) {
|
24288
|
+
this.string = base58btc.encode(this.multihash.bytes).slice(1);
|
24289
|
+
}
|
24290
|
+
return this.string;
|
24291
|
+
}
|
24292
|
+
toMultihash() {
|
24293
|
+
return this.multihash;
|
24294
|
+
}
|
24295
|
+
// return self-describing String representation
|
24296
|
+
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
24297
|
+
toCID() {
|
24298
|
+
return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
|
24299
|
+
}
|
24300
|
+
toJSON() {
|
24301
|
+
return this.toString();
|
24302
|
+
}
|
24303
|
+
/**
|
24304
|
+
* Checks the equality of `this` peer against a given PeerId
|
24305
|
+
*/
|
24306
|
+
equals(id) {
|
24307
|
+
if (id == null) {
|
24308
|
+
return false;
|
24309
|
+
}
|
24310
|
+
if (id instanceof Uint8Array) {
|
24311
|
+
return equals(this.multihash.bytes, id);
|
24312
|
+
}
|
24313
|
+
else if (typeof id === 'string') {
|
24314
|
+
return this.toString() === id;
|
24315
|
+
}
|
24316
|
+
else if (id?.toMultihash()?.bytes != null) {
|
24317
|
+
return equals(this.multihash.bytes, id.toMultihash().bytes);
|
24318
|
+
}
|
24319
|
+
else {
|
24320
|
+
throw new Error('not valid Id');
|
24321
|
+
}
|
24322
|
+
}
|
24323
|
+
/**
|
24324
|
+
* Returns PeerId as a human-readable string
|
24325
|
+
* https://nodejs.org/api/util.html#utilinspectcustom
|
24326
|
+
*
|
24327
|
+
* @example
|
24328
|
+
* ```TypeScript
|
24329
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
24330
|
+
*
|
24331
|
+
* console.info(peerIdFromString('QmFoo'))
|
24332
|
+
* // 'PeerId(QmFoo)'
|
24333
|
+
* ```
|
24334
|
+
*/
|
24335
|
+
[inspect]() {
|
24336
|
+
return `PeerId(${this.toString()})`;
|
24337
|
+
}
|
24338
|
+
}
|
24339
|
+
class RSAPeerId extends PeerIdImpl {
|
24340
|
+
type = 'RSA';
|
24341
|
+
publicKey;
|
24342
|
+
constructor(init) {
|
24343
|
+
super({ ...init, type: 'RSA' });
|
24344
|
+
this.publicKey = init.publicKey;
|
24345
|
+
}
|
24346
|
+
}
|
24347
|
+
class Ed25519PeerId extends PeerIdImpl {
|
24348
|
+
type = 'Ed25519';
|
24349
|
+
publicKey;
|
24350
|
+
constructor(init) {
|
24351
|
+
super({ ...init, type: 'Ed25519' });
|
24352
|
+
this.publicKey = init.publicKey;
|
24353
|
+
}
|
24922
24354
|
}
|
24923
|
-
|
24924
|
-
|
24355
|
+
class Secp256k1PeerId extends PeerIdImpl {
|
24356
|
+
type = 'secp256k1';
|
24357
|
+
publicKey;
|
24358
|
+
constructor(init) {
|
24359
|
+
super({ ...init, type: 'secp256k1' });
|
24360
|
+
this.publicKey = init.publicKey;
|
24361
|
+
}
|
24925
24362
|
}
|
24926
|
-
|
24927
|
-
|
24363
|
+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
24364
|
+
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
24365
|
+
class URLPeerId {
|
24366
|
+
type = 'url';
|
24367
|
+
multihash;
|
24368
|
+
publicKey;
|
24369
|
+
url;
|
24370
|
+
constructor(url) {
|
24371
|
+
this.url = url.toString();
|
24372
|
+
this.multihash = identity.digest(fromString(this.url));
|
24373
|
+
}
|
24374
|
+
[inspect]() {
|
24375
|
+
return `PeerId(${this.url})`;
|
24376
|
+
}
|
24377
|
+
[peerIdSymbol$1] = true;
|
24378
|
+
toString() {
|
24379
|
+
return this.toCID().toString();
|
24380
|
+
}
|
24381
|
+
toMultihash() {
|
24382
|
+
return this.multihash;
|
24383
|
+
}
|
24384
|
+
toCID() {
|
24385
|
+
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.toMultihash());
|
24386
|
+
}
|
24387
|
+
toJSON() {
|
24388
|
+
return this.toString();
|
24389
|
+
}
|
24390
|
+
equals(other) {
|
24391
|
+
if (other == null) {
|
24392
|
+
return false;
|
24393
|
+
}
|
24394
|
+
if (other instanceof Uint8Array) {
|
24395
|
+
other = toString$6(other);
|
24396
|
+
}
|
24397
|
+
return other.toString() === this.toString();
|
24398
|
+
}
|
24928
24399
|
}
|
24929
|
-
|
24930
|
-
|
24931
|
-
|
24932
|
-
|
24400
|
+
|
24401
|
+
/**
|
24402
|
+
* @packageDocumentation
|
24403
|
+
*
|
24404
|
+
* An implementation of a peer id
|
24405
|
+
*
|
24406
|
+
* @example
|
24407
|
+
*
|
24408
|
+
* ```TypeScript
|
24409
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
24410
|
+
* const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
|
24411
|
+
*
|
24412
|
+
* console.log(peer.toCID()) // CID(bafzaa...)
|
24413
|
+
* console.log(peer.toString()) // "12D3K..."
|
24414
|
+
* ```
|
24415
|
+
*/
|
24416
|
+
function peerIdFromString(str, decoder) {
|
24417
|
+
let multihash;
|
24418
|
+
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
24419
|
+
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
24420
|
+
// rsa public key - base58btc encoded either way
|
24421
|
+
multihash = decode$6(base58btc.decode(`z${str}`));
|
24422
|
+
}
|
24423
|
+
else {
|
24424
|
+
{
|
24425
|
+
throw new InvalidParametersError$1('Please pass a multibase decoder for strings that do not start with "1" or "Q"');
|
24426
|
+
}
|
24933
24427
|
}
|
24934
|
-
|
24935
|
-
|
24936
|
-
|
24428
|
+
return peerIdFromMultihash(multihash);
|
24429
|
+
}
|
24430
|
+
function peerIdFromMultihash(multihash) {
|
24431
|
+
if (isSha256Multihash(multihash)) {
|
24432
|
+
return new RSAPeerId({ multihash });
|
24937
24433
|
}
|
24938
|
-
|
24939
|
-
|
24940
|
-
|
24941
|
-
|
24942
|
-
|
24434
|
+
else if (isIdentityMultihash(multihash)) {
|
24435
|
+
try {
|
24436
|
+
const publicKey = publicKeyFromMultihash(multihash);
|
24437
|
+
if (publicKey.type === 'Ed25519') {
|
24438
|
+
return new Ed25519PeerId({ multihash, publicKey });
|
24439
|
+
}
|
24440
|
+
else if (publicKey.type === 'secp256k1') {
|
24441
|
+
return new Secp256k1PeerId({ multihash, publicKey });
|
24442
|
+
}
|
24443
|
+
}
|
24444
|
+
catch (err) {
|
24445
|
+
// was not Ed or secp key, try URL
|
24446
|
+
const url = toString$6(multihash.digest);
|
24447
|
+
return new URLPeerId(new URL(url));
|
24448
|
+
}
|
24943
24449
|
}
|
24944
|
-
|
24450
|
+
throw new InvalidMultihashError('Supplied PeerID Multihash is invalid');
|
24451
|
+
}
|
24452
|
+
function isIdentityMultihash(multihash) {
|
24453
|
+
return multihash.code === identity.code;
|
24454
|
+
}
|
24455
|
+
function isSha256Multihash(multihash) {
|
24456
|
+
return multihash.code === sha256.code;
|
24945
24457
|
}
|
24946
24458
|
|
24947
24459
|
const log = new Logger$1("peer-exchange-discovery");
|
@@ -24969,7 +24481,7 @@ class LocalPeerCacheDiscovery extends TypedEventEmitter {
|
|
24969
24481
|
log.info("Starting Local Storage Discovery");
|
24970
24482
|
this.components.events.addEventListener("peer:identify", this.handleNewPeers);
|
24971
24483
|
for (const { id: idStr, address } of this.peers) {
|
24972
|
-
const peerId =
|
24484
|
+
const peerId = peerIdFromString(idStr);
|
24973
24485
|
if (await this.components.peerStore.has(peerId))
|
24974
24486
|
continue;
|
24975
24487
|
await this.components.peerStore.save(peerId, {
|