@waku/discovery 0.0.4-1887f4f.0 → 0.0.4-409642d.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 +622 -785
- package/dist/.tsbuildinfo +1 -1
- package/dist/peer-exchange/waku_peer_exchange.js +2 -2
- package/dist/peer-exchange/waku_peer_exchange.js.map +1 -1
- package/dist/peer-exchange/waku_peer_exchange_discovery.d.ts +1 -0
- package/dist/peer-exchange/waku_peer_exchange_discovery.js +47 -2
- package/dist/peer-exchange/waku_peer_exchange_discovery.js.map +1 -1
- package/package.json +1 -1
- package/src/peer-exchange/waku_peer_exchange.ts +3 -2
- package/src/peer-exchange/waku_peer_exchange_discovery.ts +78 -2
package/bundle/index.js
CHANGED
@@ -26,7 +26,7 @@ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
|
|
26
26
|
* usually in response to the `abort` event being emitted by an
|
27
27
|
* AbortSignal.
|
28
28
|
*/
|
29
|
-
|
29
|
+
class CodeError extends Error {
|
30
30
|
code;
|
31
31
|
props;
|
32
32
|
constructor(message, code, props) {
|
@@ -35,7 +35,7 @@ let CodeError$1 = class CodeError extends Error {
|
|
35
35
|
this.name = props?.name ?? 'CodeError';
|
36
36
|
this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
|
37
37
|
}
|
38
|
-
}
|
38
|
+
}
|
39
39
|
class AggregateCodeError extends AggregateError {
|
40
40
|
code;
|
41
41
|
props;
|
@@ -537,6 +537,11 @@ var ProtocolError;
|
|
537
537
|
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
538
538
|
*/
|
539
539
|
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
540
|
+
/**
|
541
|
+
* The topics passed in the decoders do not match each other, or don't exist at all.
|
542
|
+
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
543
|
+
*/
|
544
|
+
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
540
545
|
/**
|
541
546
|
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
542
547
|
* Mitigation can be: retrying after a given time period, display connectivity issue
|
@@ -567,12 +572,6 @@ var ProtocolError;
|
|
567
572
|
ProtocolError["REQUEST_TIMEOUT"] = "Request timeout";
|
568
573
|
})(ProtocolError || (ProtocolError = {}));
|
569
574
|
|
570
|
-
var PageDirection;
|
571
|
-
(function (PageDirection) {
|
572
|
-
PageDirection["BACKWARD"] = "backward";
|
573
|
-
PageDirection["FORWARD"] = "forward";
|
574
|
-
})(PageDirection || (PageDirection = {}));
|
575
|
-
|
576
575
|
var Tags;
|
577
576
|
(function (Tags) {
|
578
577
|
Tags["BOOTSTRAP"] = "bootstrap";
|
@@ -591,10 +590,12 @@ var EConnectionStateEvents;
|
|
591
590
|
EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
|
592
591
|
})(EConnectionStateEvents || (EConnectionStateEvents = {}));
|
593
592
|
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
593
|
+
var HealthStatus;
|
594
|
+
(function (HealthStatus) {
|
595
|
+
HealthStatus["Unhealthy"] = "Unhealthy";
|
596
|
+
HealthStatus["MinimallyHealthy"] = "MinimallyHealthy";
|
597
|
+
HealthStatus["SufficientlyHealthy"] = "SufficientlyHealthy";
|
598
|
+
})(HealthStatus || (HealthStatus = {}));
|
598
599
|
|
599
600
|
function equals$2(aa, bb) {
|
600
601
|
if (aa === bb)
|
@@ -1905,41 +1906,7 @@ const bytesToUtf8 = (b) => toString$6(b, "utf8");
|
|
1905
1906
|
* Encode utf-8 string to byte array.
|
1906
1907
|
*/
|
1907
1908
|
const utf8ToBytes$1 = (s) => fromString(s, "utf8");
|
1908
|
-
/**
|
1909
|
-
* Concatenate using Uint8Arrays as `Buffer` has a different behavior with `DataView`
|
1910
|
-
*/
|
1911
|
-
function concat$2(byteArrays, totalLength) {
|
1912
|
-
const len = totalLength ?? byteArrays.reduce((acc, curr) => acc + curr.length, 0);
|
1913
|
-
const res = new Uint8Array(len);
|
1914
|
-
let offset = 0;
|
1915
|
-
for (const bytes of byteArrays) {
|
1916
|
-
res.set(bytes, offset);
|
1917
|
-
offset += bytes.length;
|
1918
|
-
}
|
1919
|
-
return res;
|
1920
|
-
}
|
1921
1909
|
|
1922
|
-
const shardInfoToPubsubTopics = (shardInfo) => {
|
1923
|
-
if ("contentTopics" in shardInfo && shardInfo.contentTopics) {
|
1924
|
-
// Autosharding: explicitly defined content topics
|
1925
|
-
return Array.from(new Set(shardInfo.contentTopics.map((contentTopic) => contentTopicToPubsubTopic(contentTopic, shardInfo.clusterId))));
|
1926
|
-
}
|
1927
|
-
else if ("shards" in shardInfo) {
|
1928
|
-
// Static sharding
|
1929
|
-
if (shardInfo.shards === undefined)
|
1930
|
-
throw new Error("Invalid shard");
|
1931
|
-
return Array.from(new Set(shardInfo.shards.map((index) => `/waku/2/rs/${shardInfo.clusterId ?? DEFAULT_CLUSTER_ID}/${index}`)));
|
1932
|
-
}
|
1933
|
-
else if ("application" in shardInfo && "version" in shardInfo) {
|
1934
|
-
// Autosharding: single shard from application and version
|
1935
|
-
return [
|
1936
|
-
contentTopicToPubsubTopic(`/${shardInfo.application}/${shardInfo.version}/default/default`, shardInfo.clusterId)
|
1937
|
-
];
|
1938
|
-
}
|
1939
|
-
else {
|
1940
|
-
throw new Error("Missing required configuration in shard parameters");
|
1941
|
-
}
|
1942
|
-
};
|
1943
1910
|
const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
|
1944
1911
|
const parts = pubsubTopics.split("/");
|
1945
1912
|
if (parts.length != 6 ||
|
@@ -1956,112 +1923,26 @@ const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
|
|
1956
1923
|
shard
|
1957
1924
|
};
|
1958
1925
|
};
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
}
|
1976
|
-
if (generation > 0) {
|
1977
|
-
throw new Error("Generation greater than 0 is not supported");
|
1978
|
-
}
|
1979
|
-
}
|
1980
|
-
// Validate remaining fields
|
1981
|
-
const fields = parts.splice(-4);
|
1982
|
-
// Validate application field
|
1983
|
-
if (fields[0].length == 0) {
|
1984
|
-
throw new Error("Application field cannot be empty");
|
1985
|
-
}
|
1986
|
-
// Validate version field
|
1987
|
-
if (fields[1].length == 0) {
|
1988
|
-
throw new Error("Version field cannot be empty");
|
1989
|
-
}
|
1990
|
-
// Validate topic name field
|
1991
|
-
if (fields[2].length == 0) {
|
1992
|
-
throw new Error("Topic name field cannot be empty");
|
1993
|
-
}
|
1994
|
-
// Validate encoding field
|
1995
|
-
if (fields[3].length == 0) {
|
1996
|
-
throw new Error("Encoding field cannot be empty");
|
1997
|
-
}
|
1926
|
+
const pubsubTopicsToShardInfo = (pubsubTopics) => {
|
1927
|
+
const shardInfoSet = new Set();
|
1928
|
+
const clusterIds = new Set();
|
1929
|
+
for (const topic of pubsubTopics) {
|
1930
|
+
const { clusterId, shard } = pubsubTopicToSingleShardInfo(topic);
|
1931
|
+
shardInfoSet.add(`${clusterId}:${shard}`);
|
1932
|
+
clusterIds.add(clusterId);
|
1933
|
+
}
|
1934
|
+
if (shardInfoSet.size === 0) {
|
1935
|
+
throw new Error("No valid pubsub topics provided");
|
1936
|
+
}
|
1937
|
+
if (clusterIds.size > 1) {
|
1938
|
+
throw new Error("Pubsub topics from multiple cluster IDs are not supported");
|
1939
|
+
}
|
1940
|
+
const clusterId = clusterIds.values().next().value;
|
1941
|
+
const shards = Array.from(shardInfoSet).map((info) => parseInt(info.split(":")[1]));
|
1998
1942
|
return {
|
1999
|
-
|
2000
|
-
|
2001
|
-
version: fields[1],
|
2002
|
-
topicName: fields[2],
|
2003
|
-
encoding: fields[3]
|
1943
|
+
clusterId,
|
1944
|
+
shards
|
2004
1945
|
};
|
2005
|
-
}
|
2006
|
-
/**
|
2007
|
-
* Given a string, determines which autoshard index to use for its pubsub topic.
|
2008
|
-
* Based on the algorithm described in the RFC: https://rfc.vac.dev/spec/51//#algorithm
|
2009
|
-
*/
|
2010
|
-
function contentTopicToShardIndex(contentTopic, networkShards = 8) {
|
2011
|
-
const { application, version } = ensureValidContentTopic(contentTopic);
|
2012
|
-
const digest = sha256$1(concat$2([utf8ToBytes$1(application), utf8ToBytes$1(version)]));
|
2013
|
-
const dataview = new DataView(digest.buffer.slice(-8));
|
2014
|
-
return Number(dataview.getBigUint64(0, false) % BigInt(networkShards));
|
2015
|
-
}
|
2016
|
-
function contentTopicToPubsubTopic(contentTopic, clusterId = DEFAULT_CLUSTER_ID, networkShards = 8) {
|
2017
|
-
if (!contentTopic) {
|
2018
|
-
throw Error("Content topic must be specified");
|
2019
|
-
}
|
2020
|
-
const shardIndex = contentTopicToShardIndex(contentTopic, networkShards);
|
2021
|
-
return `/waku/2/rs/${clusterId}/${shardIndex}`;
|
2022
|
-
}
|
2023
|
-
/**
|
2024
|
-
* Validates sharding configuration and sets defaults where possible.
|
2025
|
-
* @returns Validated sharding parameters, with any missing values set to defaults
|
2026
|
-
*/
|
2027
|
-
const ensureShardingConfigured = (shardInfo) => {
|
2028
|
-
const clusterId = shardInfo.clusterId ?? DEFAULT_CLUSTER_ID;
|
2029
|
-
const shards = "shards" in shardInfo ? shardInfo.shards : [];
|
2030
|
-
const contentTopics = "contentTopics" in shardInfo ? shardInfo.contentTopics : [];
|
2031
|
-
const [application, version] = "application" in shardInfo && "version" in shardInfo
|
2032
|
-
? [shardInfo.application, shardInfo.version]
|
2033
|
-
: [undefined, undefined];
|
2034
|
-
const isShardsConfigured = shards && shards.length > 0;
|
2035
|
-
const isContentTopicsConfigured = contentTopics && contentTopics.length > 0;
|
2036
|
-
const isApplicationVersionConfigured = application && version;
|
2037
|
-
if (isShardsConfigured) {
|
2038
|
-
return {
|
2039
|
-
shardingParams: { clusterId, shards },
|
2040
|
-
shardInfo: { clusterId, shards },
|
2041
|
-
pubsubTopics: shardInfoToPubsubTopics({ clusterId, shards })
|
2042
|
-
};
|
2043
|
-
}
|
2044
|
-
if (isContentTopicsConfigured) {
|
2045
|
-
const pubsubTopics = Array.from(new Set(contentTopics.map((topic) => contentTopicToPubsubTopic(topic, clusterId))));
|
2046
|
-
const shards = Array.from(new Set(contentTopics.map((topic) => contentTopicToShardIndex(topic))));
|
2047
|
-
return {
|
2048
|
-
shardingParams: { clusterId, contentTopics },
|
2049
|
-
shardInfo: { clusterId, shards },
|
2050
|
-
pubsubTopics
|
2051
|
-
};
|
2052
|
-
}
|
2053
|
-
if (isApplicationVersionConfigured) {
|
2054
|
-
const pubsubTopic = contentTopicToPubsubTopic(`/${application}/${version}/default/default`, clusterId);
|
2055
|
-
return {
|
2056
|
-
shardingParams: { clusterId, application, version },
|
2057
|
-
shardInfo: {
|
2058
|
-
clusterId,
|
2059
|
-
shards: [pubsubTopicToSingleShardInfo(pubsubTopic).shard]
|
2060
|
-
},
|
2061
|
-
pubsubTopics: [pubsubTopic]
|
2062
|
-
};
|
2063
|
-
}
|
2064
|
-
throw new Error("Missing minimum required configuration options for static sharding or autosharding.");
|
2065
1946
|
};
|
2066
1947
|
|
2067
1948
|
const decodeRelayShard = (bytes) => {
|
@@ -2707,6 +2588,8 @@ var common = setup;
|
|
2707
2588
|
return false;
|
2708
2589
|
}
|
2709
2590
|
|
2591
|
+
let m;
|
2592
|
+
|
2710
2593
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
2711
2594
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
2712
2595
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
@@ -2714,7 +2597,7 @@ var common = setup;
|
|
2714
2597
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
2715
2598
|
// Is firefox >= v31?
|
2716
2599
|
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
2717
|
-
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(
|
2600
|
+
(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
|
2718
2601
|
// Double check webkit in userAgent just in case we are in a worker
|
2719
2602
|
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
2720
2603
|
}
|
@@ -2917,7 +2800,7 @@ const _0n$5 = BigInt(0);
|
|
2917
2800
|
const _1n$7 = BigInt(1);
|
2918
2801
|
const _2n$5 = BigInt(2);
|
2919
2802
|
const _3n$2 = BigInt(3);
|
2920
|
-
const _8n$
|
2803
|
+
const _8n$3 = BigInt(8);
|
2921
2804
|
const CURVE = Object.freeze({
|
2922
2805
|
a: _0n$5,
|
2923
2806
|
b: BigInt(7),
|
@@ -3021,7 +2904,7 @@ class JacobianPoint {
|
|
3021
2904
|
const E = mod$1(_3n$2 * A);
|
3022
2905
|
const F = mod$1(E * E);
|
3023
2906
|
const X3 = mod$1(F - _2n$5 * D);
|
3024
|
-
const Y3 = mod$1(E * (D - X3) - _8n$
|
2907
|
+
const Y3 = mod$1(E * (D - X3) - _8n$3 * C);
|
3025
2908
|
const Z3 = mod$1(_2n$5 * Y1 * Z1);
|
3026
2909
|
return new JacobianPoint(X3, Y3, Z3);
|
3027
2910
|
}
|
@@ -3121,12 +3004,12 @@ class JacobianPoint {
|
|
3121
3004
|
if (256 % W) {
|
3122
3005
|
throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
|
3123
3006
|
}
|
3124
|
-
let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
|
3007
|
+
let precomputes = affinePoint && pointPrecomputes$1.get(affinePoint);
|
3125
3008
|
if (!precomputes) {
|
3126
3009
|
precomputes = this.precomputeWindow(W);
|
3127
3010
|
if (affinePoint && W !== 1) {
|
3128
3011
|
precomputes = JacobianPoint.normalizeZ(precomputes);
|
3129
|
-
pointPrecomputes.set(affinePoint, precomputes);
|
3012
|
+
pointPrecomputes$1.set(affinePoint, precomputes);
|
3130
3013
|
}
|
3131
3014
|
}
|
3132
3015
|
let p = JacobianPoint.ZERO;
|
@@ -3182,7 +3065,7 @@ class JacobianPoint {
|
|
3182
3065
|
const { x, y, z } = this;
|
3183
3066
|
const is0 = this.equals(JacobianPoint.ZERO);
|
3184
3067
|
if (invZ == null)
|
3185
|
-
invZ = is0 ? _8n$
|
3068
|
+
invZ = is0 ? _8n$3 : invert$1(z);
|
3186
3069
|
const iz1 = invZ;
|
3187
3070
|
const iz2 = mod$1(iz1 * iz1);
|
3188
3071
|
const iz3 = mod$1(iz2 * iz1);
|
@@ -3202,7 +3085,7 @@ function constTimeNegate(condition, item) {
|
|
3202
3085
|
const neg = item.negate();
|
3203
3086
|
return condition ? neg : item;
|
3204
3087
|
}
|
3205
|
-
const pointPrecomputes = new WeakMap();
|
3088
|
+
const pointPrecomputes$1 = new WeakMap();
|
3206
3089
|
class Point {
|
3207
3090
|
constructor(x, y) {
|
3208
3091
|
this.x = x;
|
@@ -3210,7 +3093,7 @@ class Point {
|
|
3210
3093
|
}
|
3211
3094
|
_setWindowSize(windowSize) {
|
3212
3095
|
this._WINDOW_SIZE = windowSize;
|
3213
|
-
pointPrecomputes.delete(this);
|
3096
|
+
pointPrecomputes$1.delete(this);
|
3214
3097
|
}
|
3215
3098
|
hasEvenY() {
|
3216
3099
|
return this.y % _2n$5 === _0n$5;
|
@@ -5268,6 +5151,7 @@ const table = [
|
|
5268
5151
|
[478, 0, 'wss'],
|
5269
5152
|
[479, 0, 'p2p-websocket-star'],
|
5270
5153
|
[480, 0, 'http'],
|
5154
|
+
[481, V, 'http-path'],
|
5271
5155
|
[777, V, 'memory']
|
5272
5156
|
];
|
5273
5157
|
// populate tables
|
@@ -5353,6 +5237,8 @@ function convertToString(proto, buf) {
|
|
5353
5237
|
return bytes2onion(buf);
|
5354
5238
|
case 466: // certhash
|
5355
5239
|
return bytes2mb(buf);
|
5240
|
+
case 481: // http-path
|
5241
|
+
return globalThis.encodeURIComponent(bytes2str(buf));
|
5356
5242
|
default:
|
5357
5243
|
return toString$6(buf, 'base16'); // no clue. convert to hex
|
5358
5244
|
}
|
@@ -5387,6 +5273,8 @@ function convertToBytes(proto, str) {
|
|
5387
5273
|
return onion32bytes(str);
|
5388
5274
|
case 466: // certhash
|
5389
5275
|
return mb2bytes(str);
|
5276
|
+
case 481: // http-path
|
5277
|
+
return str2bytes(globalThis.decodeURIComponent(str));
|
5390
5278
|
default:
|
5391
5279
|
return fromString(str, 'base16'); // no clue. convert from hex
|
5392
5280
|
}
|
@@ -5848,7 +5736,7 @@ class Multiaddr {
|
|
5848
5736
|
}
|
5849
5737
|
const resolver = resolvers$1.get(resolvableProto.name);
|
5850
5738
|
if (resolver == null) {
|
5851
|
-
throw new CodeError
|
5739
|
+
throw new CodeError(`no available resolver for ${resolvableProto.name}`, 'ERR_NO_AVAILABLE_RESOLVER');
|
5852
5740
|
}
|
5853
5741
|
const result = await resolver(this, options);
|
5854
5742
|
return result.map(str => multiaddr(str));
|
@@ -6291,9 +6179,9 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
|
6291
6179
|
// This is OK: `abstract` directory does not use noble-hashes.
|
6292
6180
|
// User may opt-in into using different hashing library. This way, noble-hashes
|
6293
6181
|
// won't be included into their bundle.
|
6294
|
-
const _0n$4 = BigInt(0);
|
6295
|
-
const _1n$6 = BigInt(1);
|
6296
|
-
const _2n$4 = BigInt(2);
|
6182
|
+
const _0n$4 = /* @__PURE__ */ BigInt(0);
|
6183
|
+
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
6184
|
+
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
6297
6185
|
function isBytes$1(a) {
|
6298
6186
|
return (a instanceof Uint8Array ||
|
6299
6187
|
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
@@ -6302,6 +6190,10 @@ function abytes(item) {
|
|
6302
6190
|
if (!isBytes$1(item))
|
6303
6191
|
throw new Error('Uint8Array expected');
|
6304
6192
|
}
|
6193
|
+
function abool(title, value) {
|
6194
|
+
if (typeof value !== 'boolean')
|
6195
|
+
throw new Error(`${title} must be valid boolean, got "${value}".`);
|
6196
|
+
}
|
6305
6197
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6306
6198
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
6307
6199
|
/**
|
@@ -6444,6 +6336,25 @@ function utf8ToBytes(str) {
|
|
6444
6336
|
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
6445
6337
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6446
6338
|
}
|
6339
|
+
// Is positive bigint
|
6340
|
+
const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
|
6341
|
+
function inRange(n, min, max) {
|
6342
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
6343
|
+
}
|
6344
|
+
/**
|
6345
|
+
* Asserts min <= n < max. NOTE: It's < max and not <= max.
|
6346
|
+
* @example
|
6347
|
+
* aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)
|
6348
|
+
*/
|
6349
|
+
function aInRange(title, n, min, max) {
|
6350
|
+
// Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?
|
6351
|
+
// consider P=256n, min=0n, max=P
|
6352
|
+
// - a for min=0 would require -1: `inRange('x', x, -1n, P)`
|
6353
|
+
// - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
|
6354
|
+
// - our way is the cleanest: `inRange('x', x, 0n, P)
|
6355
|
+
if (!inRange(n, min, max))
|
6356
|
+
throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
|
6357
|
+
}
|
6447
6358
|
// Bit operations
|
6448
6359
|
/**
|
6449
6360
|
* Calculates amount of bits in a bigint.
|
@@ -6574,9 +6485,32 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6574
6485
|
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
6575
6486
|
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
6576
6487
|
// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
|
6488
|
+
/**
|
6489
|
+
* throws not implemented error
|
6490
|
+
*/
|
6491
|
+
const notImplemented = () => {
|
6492
|
+
throw new Error('not implemented');
|
6493
|
+
};
|
6494
|
+
/**
|
6495
|
+
* Memoizes (caches) computation result.
|
6496
|
+
* Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
|
6497
|
+
*/
|
6498
|
+
function memoized(fn) {
|
6499
|
+
const map = new WeakMap();
|
6500
|
+
return (arg, ...args) => {
|
6501
|
+
const val = map.get(arg);
|
6502
|
+
if (val !== undefined)
|
6503
|
+
return val;
|
6504
|
+
const computed = fn(arg, ...args);
|
6505
|
+
map.set(arg, computed);
|
6506
|
+
return computed;
|
6507
|
+
};
|
6508
|
+
}
|
6577
6509
|
|
6578
6510
|
var ut = /*#__PURE__*/Object.freeze({
|
6579
6511
|
__proto__: null,
|
6512
|
+
aInRange: aInRange,
|
6513
|
+
abool: abool,
|
6580
6514
|
abytes: abytes,
|
6581
6515
|
bitGet: bitGet,
|
6582
6516
|
bitLen: bitLen,
|
@@ -6591,7 +6525,10 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6591
6525
|
equalBytes: equalBytes,
|
6592
6526
|
hexToBytes: hexToBytes,
|
6593
6527
|
hexToNumber: hexToNumber,
|
6528
|
+
inRange: inRange,
|
6594
6529
|
isBytes: isBytes$1,
|
6530
|
+
memoized: memoized,
|
6531
|
+
notImplemented: notImplemented,
|
6595
6532
|
numberToBytesBE: numberToBytesBE,
|
6596
6533
|
numberToBytesLE: numberToBytesLE,
|
6597
6534
|
numberToHexUnpadded: numberToHexUnpadded,
|
@@ -6605,7 +6542,7 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6605
6542
|
// prettier-ignore
|
6606
6543
|
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
|
6607
6544
|
// prettier-ignore
|
6608
|
-
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$
|
6545
|
+
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
|
6609
6546
|
// prettier-ignore
|
6610
6547
|
BigInt(9); BigInt(16);
|
6611
6548
|
// Calculates a modulo b
|
@@ -6751,8 +6688,8 @@ function FpSqrt(P) {
|
|
6751
6688
|
};
|
6752
6689
|
}
|
6753
6690
|
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
6754
|
-
if (P % _8n$
|
6755
|
-
const c1 = (P - _5n$1) / _8n$
|
6691
|
+
if (P % _8n$2 === _5n$1) {
|
6692
|
+
const c1 = (P - _5n$1) / _8n$2;
|
6756
6693
|
return function sqrt5mod8(Fp, n) {
|
6757
6694
|
const n2 = Fp.mul(n, _2n$3);
|
6758
6695
|
const v = Fp.pow(n2, c1);
|
@@ -6850,6 +6787,9 @@ function nLength(n, nBitLength) {
|
|
6850
6787
|
* * a) denormalized operations like mulN instead of mul
|
6851
6788
|
* * b) same object shape: never add or remove keys
|
6852
6789
|
* * c) Object.freeze
|
6790
|
+
* NOTE: operations don't check 'isValid' for all elements for performance reasons,
|
6791
|
+
* it is caller responsibility to check this.
|
6792
|
+
* This is low-level code, please make sure you know what you doing.
|
6853
6793
|
* @param ORDER prime positive bigint
|
6854
6794
|
* @param bitLen how many bits the field consumes
|
6855
6795
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6905,12 +6845,6 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6905
6845
|
});
|
6906
6846
|
return Object.freeze(f);
|
6907
6847
|
}
|
6908
|
-
function FpSqrtEven(Fp, elm) {
|
6909
|
-
if (!Fp.isOdd)
|
6910
|
-
throw new Error(`Field doesn't have isOdd`);
|
6911
|
-
const root = Fp.sqrt(elm);
|
6912
|
-
return Fp.isOdd(root) ? Fp.neg(root) : root;
|
6913
|
-
}
|
6914
6848
|
/**
|
6915
6849
|
* Returns total number of bytes consumed by the field element.
|
6916
6850
|
* For example, 32 bytes for usual 256-bit weierstrass curve.
|
@@ -6964,6 +6898,10 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6964
6898
|
// Abelian group utilities
|
6965
6899
|
const _0n$2 = BigInt(0);
|
6966
6900
|
const _1n$4 = BigInt(1);
|
6901
|
+
// Since points in different groups cannot be equal (different object constructor),
|
6902
|
+
// we can have single place to store precomputes
|
6903
|
+
const pointPrecomputes = new WeakMap();
|
6904
|
+
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
6967
6905
|
// Elliptic curve multiplication of Point by scalar. Fragile.
|
6968
6906
|
// Scalars should always be less than curve order: this should be checked inside of a curve itself.
|
6969
6907
|
// Creates precomputation tables for fast multiplication:
|
@@ -6980,7 +6918,12 @@ function wNAF(c, bits) {
|
|
6980
6918
|
const neg = item.negate();
|
6981
6919
|
return condition ? neg : item;
|
6982
6920
|
};
|
6921
|
+
const validateW = (W) => {
|
6922
|
+
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6923
|
+
throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
|
6924
|
+
};
|
6983
6925
|
const opts = (W) => {
|
6926
|
+
validateW(W);
|
6984
6927
|
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6985
6928
|
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6986
6929
|
return { windows, windowSize };
|
@@ -7080,19 +7023,25 @@ function wNAF(c, bits) {
|
|
7080
7023
|
// which makes it less const-time: around 1 bigint multiply.
|
7081
7024
|
return { p, f };
|
7082
7025
|
},
|
7083
|
-
wNAFCached(P,
|
7084
|
-
|
7085
|
-
const W = P._WINDOW_SIZE || 1;
|
7026
|
+
wNAFCached(P, n, transform) {
|
7027
|
+
const W = pointWindowSizes.get(P) || 1;
|
7086
7028
|
// Calculate precomputes on a first run, reuse them after
|
7087
|
-
let comp =
|
7029
|
+
let comp = pointPrecomputes.get(P);
|
7088
7030
|
if (!comp) {
|
7089
7031
|
comp = this.precomputeWindow(P, W);
|
7090
|
-
if (W !== 1)
|
7091
|
-
|
7092
|
-
}
|
7032
|
+
if (W !== 1)
|
7033
|
+
pointPrecomputes.set(P, transform(comp));
|
7093
7034
|
}
|
7094
7035
|
return this.wNAF(W, comp, n);
|
7095
7036
|
},
|
7037
|
+
// We calculate precomputes for elliptic curve point multiplication
|
7038
|
+
// using windowed method. This specifies window size and
|
7039
|
+
// stores precomputed values. Usually only base point would be precomputed.
|
7040
|
+
setWindowSize(P, W) {
|
7041
|
+
validateW(W);
|
7042
|
+
pointWindowSizes.set(P, W);
|
7043
|
+
pointPrecomputes.delete(P);
|
7044
|
+
},
|
7096
7045
|
};
|
7097
7046
|
}
|
7098
7047
|
function validateBasic(curve) {
|
@@ -7118,7 +7067,7 @@ function validateBasic(curve) {
|
|
7118
7067
|
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
7119
7068
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
7120
7069
|
// prettier-ignore
|
7121
|
-
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n = BigInt(8);
|
7070
|
+
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
7122
7071
|
// verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
|
7123
7072
|
const VERIFY_DEFAULT = { zip215: true };
|
7124
7073
|
function validateOpts$1(curve) {
|
@@ -7137,7 +7086,13 @@ function validateOpts$1(curve) {
|
|
7137
7086
|
// Set defaults
|
7138
7087
|
return Object.freeze({ ...opts });
|
7139
7088
|
}
|
7140
|
-
|
7089
|
+
/**
|
7090
|
+
* Creates Twisted Edwards curve with EdDSA signatures.
|
7091
|
+
* @example
|
7092
|
+
* import { Field } from '@noble/curves/abstract/modular';
|
7093
|
+
* // Before that, define BigInt-s: a, d, p, n, Gx, Gy, h
|
7094
|
+
* const curve = twistedEdwards({ a, d, Fp: Field(p), n, Gx, Gy, h })
|
7095
|
+
*/
|
7141
7096
|
function twistedEdwards(curveDef) {
|
7142
7097
|
const CURVE = validateOpts$1(curveDef);
|
7143
7098
|
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
@@ -7156,28 +7111,59 @@ function twistedEdwards(curveDef) {
|
|
7156
7111
|
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
|
7157
7112
|
const domain = CURVE.domain ||
|
7158
7113
|
((data, ctx, phflag) => {
|
7114
|
+
abool('phflag', phflag);
|
7159
7115
|
if (ctx.length || phflag)
|
7160
7116
|
throw new Error('Contexts/pre-hash are not supported');
|
7161
7117
|
return data;
|
7162
7118
|
}); // NOOP
|
7163
|
-
|
7164
|
-
|
7165
|
-
|
7166
|
-
|
7167
|
-
|
7168
|
-
|
7169
|
-
return n;
|
7170
|
-
throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
|
7171
|
-
}
|
7172
|
-
function assertGE0(n) {
|
7173
|
-
// n in [0..CURVE_ORDER-1]
|
7174
|
-
return n === _0n$1 ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
|
7175
|
-
}
|
7176
|
-
const pointPrecomputes = new Map();
|
7177
|
-
function isPoint(other) {
|
7119
|
+
// 0 <= n < MASK
|
7120
|
+
// Coordinates larger than Fp.ORDER are allowed for zip215
|
7121
|
+
function aCoordinate(title, n) {
|
7122
|
+
aInRange('coordinate ' + title, n, _0n$1, MASK);
|
7123
|
+
}
|
7124
|
+
function assertPoint(other) {
|
7178
7125
|
if (!(other instanceof Point))
|
7179
7126
|
throw new Error('ExtendedPoint expected');
|
7180
7127
|
}
|
7128
|
+
// Converts Extended point to default (x, y) coordinates.
|
7129
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
7130
|
+
const toAffineMemo = memoized((p, iz) => {
|
7131
|
+
const { ex: x, ey: y, ez: z } = p;
|
7132
|
+
const is0 = p.is0();
|
7133
|
+
if (iz == null)
|
7134
|
+
iz = is0 ? _8n$1 : Fp.inv(z); // 8 was chosen arbitrarily
|
7135
|
+
const ax = modP(x * iz);
|
7136
|
+
const ay = modP(y * iz);
|
7137
|
+
const zz = modP(z * iz);
|
7138
|
+
if (is0)
|
7139
|
+
return { x: _0n$1, y: _1n$3 };
|
7140
|
+
if (zz !== _1n$3)
|
7141
|
+
throw new Error('invZ was invalid');
|
7142
|
+
return { x: ax, y: ay };
|
7143
|
+
});
|
7144
|
+
const assertValidMemo = memoized((p) => {
|
7145
|
+
const { a, d } = CURVE;
|
7146
|
+
if (p.is0())
|
7147
|
+
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
7148
|
+
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
7149
|
+
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
7150
|
+
const { ex: X, ey: Y, ez: Z, et: T } = p;
|
7151
|
+
const X2 = modP(X * X); // X²
|
7152
|
+
const Y2 = modP(Y * Y); // Y²
|
7153
|
+
const Z2 = modP(Z * Z); // Z²
|
7154
|
+
const Z4 = modP(Z2 * Z2); // Z⁴
|
7155
|
+
const aX2 = modP(X2 * a); // aX²
|
7156
|
+
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
7157
|
+
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
7158
|
+
if (left !== right)
|
7159
|
+
throw new Error('bad point: equation left != right (1)');
|
7160
|
+
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
7161
|
+
const XY = modP(X * Y);
|
7162
|
+
const ZT = modP(Z * T);
|
7163
|
+
if (XY !== ZT)
|
7164
|
+
throw new Error('bad point: equation left != right (2)');
|
7165
|
+
return true;
|
7166
|
+
});
|
7181
7167
|
// Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
|
7182
7168
|
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
7183
7169
|
class Point {
|
@@ -7186,14 +7172,11 @@ function twistedEdwards(curveDef) {
|
|
7186
7172
|
this.ey = ey;
|
7187
7173
|
this.ez = ez;
|
7188
7174
|
this.et = et;
|
7189
|
-
|
7190
|
-
|
7191
|
-
|
7192
|
-
|
7193
|
-
|
7194
|
-
throw new Error('z required');
|
7195
|
-
if (!in0MaskRange(et))
|
7196
|
-
throw new Error('t required');
|
7175
|
+
aCoordinate('x', ex);
|
7176
|
+
aCoordinate('y', ey);
|
7177
|
+
aCoordinate('z', ez);
|
7178
|
+
aCoordinate('t', et);
|
7179
|
+
Object.freeze(this);
|
7197
7180
|
}
|
7198
7181
|
get x() {
|
7199
7182
|
return this.toAffine().x;
|
@@ -7205,8 +7188,8 @@ function twistedEdwards(curveDef) {
|
|
7205
7188
|
if (p instanceof Point)
|
7206
7189
|
throw new Error('extended point not allowed');
|
7207
7190
|
const { x, y } = p || {};
|
7208
|
-
|
7209
|
-
|
7191
|
+
aCoordinate('x', x);
|
7192
|
+
aCoordinate('y', y);
|
7210
7193
|
return new Point(x, y, _1n$3, modP(x * y));
|
7211
7194
|
}
|
7212
7195
|
static normalizeZ(points) {
|
@@ -7215,36 +7198,16 @@ function twistedEdwards(curveDef) {
|
|
7215
7198
|
}
|
7216
7199
|
// "Private method", don't use it directly
|
7217
7200
|
_setWindowSize(windowSize) {
|
7218
|
-
this
|
7219
|
-
pointPrecomputes.delete(this);
|
7201
|
+
wnaf.setWindowSize(this, windowSize);
|
7220
7202
|
}
|
7221
7203
|
// Not required for fromHex(), which always creates valid points.
|
7222
7204
|
// Could be useful for fromAffine().
|
7223
7205
|
assertValidity() {
|
7224
|
-
|
7225
|
-
if (this.is0())
|
7226
|
-
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
7227
|
-
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
7228
|
-
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
7229
|
-
const { ex: X, ey: Y, ez: Z, et: T } = this;
|
7230
|
-
const X2 = modP(X * X); // X²
|
7231
|
-
const Y2 = modP(Y * Y); // Y²
|
7232
|
-
const Z2 = modP(Z * Z); // Z²
|
7233
|
-
const Z4 = modP(Z2 * Z2); // Z⁴
|
7234
|
-
const aX2 = modP(X2 * a); // aX²
|
7235
|
-
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
7236
|
-
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
7237
|
-
if (left !== right)
|
7238
|
-
throw new Error('bad point: equation left != right (1)');
|
7239
|
-
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
7240
|
-
const XY = modP(X * Y);
|
7241
|
-
const ZT = modP(Z * T);
|
7242
|
-
if (XY !== ZT)
|
7243
|
-
throw new Error('bad point: equation left != right (2)');
|
7206
|
+
assertValidMemo(this);
|
7244
7207
|
}
|
7245
7208
|
// Compare one point to another.
|
7246
7209
|
equals(other) {
|
7247
|
-
|
7210
|
+
assertPoint(other);
|
7248
7211
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
7249
7212
|
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
7250
7213
|
const X1Z2 = modP(X1 * Z2);
|
@@ -7285,7 +7248,7 @@ function twistedEdwards(curveDef) {
|
|
7285
7248
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
7286
7249
|
// Cost: 9M + 1*a + 1*d + 7add.
|
7287
7250
|
add(other) {
|
7288
|
-
|
7251
|
+
assertPoint(other);
|
7289
7252
|
const { a, d } = CURVE;
|
7290
7253
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
7291
7254
|
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
@@ -7328,11 +7291,13 @@ function twistedEdwards(curveDef) {
|
|
7328
7291
|
return this.add(other.negate());
|
7329
7292
|
}
|
7330
7293
|
wNAF(n) {
|
7331
|
-
return wnaf.wNAFCached(this,
|
7294
|
+
return wnaf.wNAFCached(this, n, Point.normalizeZ);
|
7332
7295
|
}
|
7333
7296
|
// Constant-time multiplication.
|
7334
7297
|
multiply(scalar) {
|
7335
|
-
const
|
7298
|
+
const n = scalar;
|
7299
|
+
aInRange('scalar', n, _1n$3, CURVE_ORDER); // 1 <= scalar < L
|
7300
|
+
const { p, f } = this.wNAF(n);
|
7336
7301
|
return Point.normalizeZ([p, f])[0];
|
7337
7302
|
}
|
7338
7303
|
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
@@ -7340,7 +7305,8 @@ function twistedEdwards(curveDef) {
|
|
7340
7305
|
// an exposed private key e.g. sig verification.
|
7341
7306
|
// Does NOT allow scalars higher than CURVE.n.
|
7342
7307
|
multiplyUnsafe(scalar) {
|
7343
|
-
|
7308
|
+
const n = scalar;
|
7309
|
+
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7344
7310
|
if (n === _0n$1)
|
7345
7311
|
return I;
|
7346
7312
|
if (this.equals(I) || n === _1n$3)
|
@@ -7364,18 +7330,7 @@ function twistedEdwards(curveDef) {
|
|
7364
7330
|
// Converts Extended point to default (x, y) coordinates.
|
7365
7331
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
7366
7332
|
toAffine(iz) {
|
7367
|
-
|
7368
|
-
const is0 = this.is0();
|
7369
|
-
if (iz == null)
|
7370
|
-
iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
|
7371
|
-
const ax = modP(x * iz);
|
7372
|
-
const ay = modP(y * iz);
|
7373
|
-
const zz = modP(z * iz);
|
7374
|
-
if (is0)
|
7375
|
-
return { x: _0n$1, y: _1n$3 };
|
7376
|
-
if (zz !== _1n$3)
|
7377
|
-
throw new Error('invZ was invalid');
|
7378
|
-
return { x: ax, y: ay };
|
7333
|
+
return toAffineMemo(this, iz);
|
7379
7334
|
}
|
7380
7335
|
clearCofactor() {
|
7381
7336
|
const { h: cofactor } = CURVE;
|
@@ -7389,18 +7344,16 @@ function twistedEdwards(curveDef) {
|
|
7389
7344
|
const { d, a } = CURVE;
|
7390
7345
|
const len = Fp.BYTES;
|
7391
7346
|
hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
|
7347
|
+
abool('zip215', zip215);
|
7392
7348
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7393
7349
|
const lastByte = hex[len - 1]; // select last byte
|
7394
7350
|
normed[len - 1] = lastByte & ~0x80; // clear last bit
|
7395
7351
|
const y = bytesToNumberLE(normed);
|
7396
|
-
|
7397
|
-
|
7398
|
-
|
7399
|
-
|
7400
|
-
|
7401
|
-
else
|
7402
|
-
assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
|
7403
|
-
}
|
7352
|
+
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
7353
|
+
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7354
|
+
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
7355
|
+
const max = zip215 ? MASK : Fp.ORDER;
|
7356
|
+
aInRange('pointHex.y', y, _0n$1, max);
|
7404
7357
|
// Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
|
7405
7358
|
// ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
|
7406
7359
|
const y2 = modP(y * y); // denominator is always non-0 mod p.
|
@@ -7475,7 +7428,7 @@ function twistedEdwards(curveDef) {
|
|
7475
7428
|
const R = G.multiply(r).toRawBytes(); // R = rG
|
7476
7429
|
const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
|
7477
7430
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7478
|
-
|
7431
|
+
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7479
7432
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7480
7433
|
return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
|
7481
7434
|
}
|
@@ -7485,6 +7438,8 @@ function twistedEdwards(curveDef) {
|
|
7485
7438
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7486
7439
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7487
7440
|
msg = ensureBytes('message', msg);
|
7441
|
+
if (zip215 !== undefined)
|
7442
|
+
abool('zip215', zip215);
|
7488
7443
|
if (prehash)
|
7489
7444
|
msg = prehash(msg); // for ed25519ph, etc
|
7490
7445
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
@@ -7542,12 +7497,14 @@ function twistedEdwards(curveDef) {
|
|
7542
7497
|
*/
|
7543
7498
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7544
7499
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
7545
|
-
const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
7500
|
+
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
7546
7501
|
// prettier-ignore
|
7547
|
-
BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2)
|
7502
|
+
BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
|
7548
7503
|
// prettier-ignore
|
7549
|
-
const
|
7504
|
+
const _5n = BigInt(5), _8n = BigInt(8);
|
7550
7505
|
function ed25519_pow_2_252_3(x) {
|
7506
|
+
// prettier-ignore
|
7507
|
+
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
7551
7508
|
const P = ED25519_P;
|
7552
7509
|
const x2 = (x * x) % P;
|
7553
7510
|
const b2 = (x2 * x) % P; // x^3, 11
|
@@ -7596,8 +7553,8 @@ function uvRatio(u, v) {
|
|
7596
7553
|
x = mod(-x, P);
|
7597
7554
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7598
7555
|
}
|
7599
|
-
const Fp$1 = Field(ED25519_P, undefined, true);
|
7600
|
-
const ed25519Defaults = {
|
7556
|
+
const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7557
|
+
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7601
7558
|
// Param: a
|
7602
7559
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
7603
7560
|
// d is equal to -121665/121666 over finite field.
|
@@ -7609,7 +7566,7 @@ const ed25519Defaults = {
|
|
7609
7566
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7610
7567
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
7611
7568
|
// Cofactor
|
7612
|
-
h:
|
7569
|
+
h: _8n,
|
7613
7570
|
// Base point (x, y) aka generator point
|
7614
7571
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
7615
7572
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
@@ -7620,40 +7577,11 @@ const ed25519Defaults = {
|
|
7620
7577
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
7621
7578
|
// Constant-time, u/√v
|
7622
7579
|
uvRatio,
|
7623
|
-
};
|
7624
|
-
|
7625
|
-
|
7626
|
-
|
7627
|
-
|
7628
|
-
return concatBytes$2(utf8ToBytes$2('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
|
7629
|
-
}
|
7630
|
-
/* @__PURE__ */ twistedEdwards({
|
7631
|
-
...ed25519Defaults,
|
7632
|
-
domain: ed25519_domain,
|
7633
|
-
});
|
7634
|
-
/* @__PURE__ */ twistedEdwards({
|
7635
|
-
...ed25519Defaults,
|
7636
|
-
domain: ed25519_domain,
|
7637
|
-
prehash: sha512,
|
7638
|
-
});
|
7639
|
-
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
7640
|
-
// NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
|
7641
|
-
// SageMath returns different root first and everything falls apart
|
7642
|
-
const ELL2_C1 = (Fp$1.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
|
7643
|
-
Fp$1.pow(_2n$1, ELL2_C1); // 2. c2 = 2^c1
|
7644
|
-
Fp$1.sqrt(Fp$1.neg(Fp$1.ONE)); // 3. c3 = sqrt(-1)
|
7645
|
-
(Fp$1.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
|
7646
|
-
BigInt(486662);
|
7647
|
-
FpSqrtEven(Fp$1, Fp$1.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
|
7648
|
-
// √(ad - 1)
|
7649
|
-
BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
7650
|
-
// 1 / √(a-d)
|
7651
|
-
BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
7652
|
-
// 1-d²
|
7653
|
-
BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
7654
|
-
// (d-1)²
|
7655
|
-
BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
7656
|
-
BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
7580
|
+
}))();
|
7581
|
+
/**
|
7582
|
+
* ed25519 curve with EdDSA signatures.
|
7583
|
+
*/
|
7584
|
+
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7657
7585
|
|
7658
7586
|
const PUBLIC_KEY_BYTE_LENGTH = 32;
|
7659
7587
|
const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
@@ -7710,7 +7638,7 @@ function concatKeys(privateKeyRaw, publicKey) {
|
|
7710
7638
|
var webcrypto = {
|
7711
7639
|
get(win = globalThis) {
|
7712
7640
|
const nativeCrypto = win.crypto;
|
7713
|
-
if (nativeCrypto
|
7641
|
+
if (nativeCrypto?.subtle == null) {
|
7714
7642
|
throw Object.assign(new Error('Missing Web Crypto API. ' +
|
7715
7643
|
'The most likely cause of this error is that this page is being accessed ' +
|
7716
7644
|
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
@@ -7734,12 +7662,12 @@ var webcrypto = {
|
|
7734
7662
|
const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
|
7735
7663
|
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
|
7736
7664
|
function create(opts) {
|
7737
|
-
const algorithm =
|
7738
|
-
let keyLength =
|
7739
|
-
const nonceLength =
|
7740
|
-
const digest =
|
7741
|
-
const saltLength =
|
7742
|
-
const iterations =
|
7665
|
+
const algorithm = 'AES-GCM';
|
7666
|
+
let keyLength = 16;
|
7667
|
+
const nonceLength = 12;
|
7668
|
+
const digest = 'SHA-256';
|
7669
|
+
const saltLength = 16;
|
7670
|
+
const iterations = 32767;
|
7743
7671
|
const crypto = webcrypto.get();
|
7744
7672
|
keyLength *= 8; // Browser crypto uses bits instead of bytes
|
7745
7673
|
/**
|
@@ -8523,7 +8451,7 @@ function decodeMessage(buf, codec, opts) {
|
|
8523
8451
|
* A general purpose buffer pool
|
8524
8452
|
*/
|
8525
8453
|
function pool(size) {
|
8526
|
-
const SIZE =
|
8454
|
+
const SIZE = 8192;
|
8527
8455
|
const MAX = SIZE >>> 1;
|
8528
8456
|
let slab;
|
8529
8457
|
let offset = SIZE;
|
@@ -9036,12 +8964,17 @@ function message(encode, decode) {
|
|
9036
8964
|
* npm i protons-runtime
|
9037
8965
|
* ```
|
9038
8966
|
*/
|
9039
|
-
|
9040
|
-
|
9041
|
-
|
9042
|
-
|
9043
|
-
|
9044
|
-
|
8967
|
+
/**
|
8968
|
+
* Thrown when a repeated field has too many elements
|
8969
|
+
*/
|
8970
|
+
class MaxLengthError extends Error {
|
8971
|
+
/**
|
8972
|
+
* This will be removed in a future release
|
8973
|
+
*
|
8974
|
+
* @deprecated use the `.name` property instead
|
8975
|
+
*/
|
8976
|
+
code = 'ERR_MAX_LENGTH';
|
8977
|
+
name = 'MaxLengthError';
|
9045
8978
|
}
|
9046
8979
|
|
9047
8980
|
/* eslint-disable import/export */
|
@@ -9252,7 +9185,7 @@ class Ed25519PrivateKey {
|
|
9252
9185
|
return exporter(this.bytes, password);
|
9253
9186
|
}
|
9254
9187
|
else {
|
9255
|
-
throw new CodeError
|
9188
|
+
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
9256
9189
|
}
|
9257
9190
|
}
|
9258
9191
|
}
|
@@ -9284,7 +9217,7 @@ async function generateKeyPairFromSeed(seed) {
|
|
9284
9217
|
function ensureKey(key, length) {
|
9285
9218
|
key = Uint8Array.from(key ?? []);
|
9286
9219
|
if (key.length !== length) {
|
9287
|
-
throw new CodeError
|
9220
|
+
throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
|
9288
9221
|
}
|
9289
9222
|
return key;
|
9290
9223
|
}
|
@@ -9304,7 +9237,7 @@ var Ed25519 = /*#__PURE__*/Object.freeze({
|
|
9304
9237
|
*/
|
9305
9238
|
function randomBytes(length) {
|
9306
9239
|
if (isNaN(length) || length <= 0) {
|
9307
|
-
throw new CodeError
|
9240
|
+
throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
|
9308
9241
|
}
|
9309
9242
|
return randomBytes$1(length);
|
9310
9243
|
}
|
@@ -12713,7 +12646,7 @@ function pkcs1ToJwk(bytes) {
|
|
12713
12646
|
*/
|
12714
12647
|
function jwkToPkcs1(jwk) {
|
12715
12648
|
if (jwk.n == null || jwk.e == null || jwk.d == null || jwk.p == null || jwk.q == null || jwk.dp == null || jwk.dq == null || jwk.qi == null) {
|
12716
|
-
throw new CodeError
|
12649
|
+
throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
|
12717
12650
|
}
|
12718
12651
|
const root = new Sequence({
|
12719
12652
|
value: [
|
@@ -12750,7 +12683,7 @@ function pkixToJwk(bytes) {
|
|
12750
12683
|
*/
|
12751
12684
|
function jwkToPkix(jwk) {
|
12752
12685
|
if (jwk.n == null || jwk.e == null) {
|
12753
|
-
throw new CodeError
|
12686
|
+
throw new CodeError('JWK was missing components', 'ERR_INVALID_PARAMETERS');
|
12754
12687
|
}
|
12755
12688
|
const root = new Sequence({
|
12756
12689
|
value: [
|
@@ -12962,7 +12895,7 @@ async function hashAndVerify$1(key, sig, msg) {
|
|
12962
12895
|
}
|
12963
12896
|
async function exportKey(pair) {
|
12964
12897
|
if (pair.privateKey == null || pair.publicKey == null) {
|
12965
|
-
throw new CodeError
|
12898
|
+
throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
|
12966
12899
|
}
|
12967
12900
|
return Promise.all([
|
12968
12901
|
webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
|
@@ -12981,10 +12914,10 @@ async function derivePublicFromPrivate(jwKey) {
|
|
12981
12914
|
}
|
12982
12915
|
function keySize(jwk) {
|
12983
12916
|
if (jwk.kty !== 'RSA') {
|
12984
|
-
throw new CodeError
|
12917
|
+
throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
|
12985
12918
|
}
|
12986
12919
|
else if (jwk.n == null) {
|
12987
|
-
throw new CodeError
|
12920
|
+
throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
|
12988
12921
|
}
|
12989
12922
|
const bytes = fromString(jwk.n, 'base64url');
|
12990
12923
|
return bytes.length * 8;
|
@@ -13034,7 +12967,7 @@ class RsaPrivateKey {
|
|
13034
12967
|
}
|
13035
12968
|
get public() {
|
13036
12969
|
if (this._publicKey == null) {
|
13037
|
-
throw new CodeError
|
12970
|
+
throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
|
13038
12971
|
}
|
13039
12972
|
return new RsaPublicKey(this._publicKey);
|
13040
12973
|
}
|
@@ -13083,14 +13016,14 @@ class RsaPrivateKey {
|
|
13083
13016
|
return exporter(this.bytes, password);
|
13084
13017
|
}
|
13085
13018
|
else {
|
13086
|
-
throw new CodeError
|
13019
|
+
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
13087
13020
|
}
|
13088
13021
|
}
|
13089
13022
|
}
|
13090
13023
|
async function unmarshalRsaPrivateKey(bytes) {
|
13091
13024
|
const jwk = pkcs1ToJwk(bytes);
|
13092
13025
|
if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
|
13093
|
-
throw new CodeError
|
13026
|
+
throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
|
13094
13027
|
}
|
13095
13028
|
const keys = await unmarshalPrivateKey$1(jwk);
|
13096
13029
|
return new RsaPrivateKey(keys.privateKey, keys.publicKey);
|
@@ -13098,20 +13031,20 @@ async function unmarshalRsaPrivateKey(bytes) {
|
|
13098
13031
|
function unmarshalRsaPublicKey(bytes) {
|
13099
13032
|
const jwk = pkixToJwk(bytes);
|
13100
13033
|
if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
|
13101
|
-
throw new CodeError
|
13034
|
+
throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
|
13102
13035
|
}
|
13103
13036
|
return new RsaPublicKey(jwk);
|
13104
13037
|
}
|
13105
13038
|
async function fromJwk(jwk) {
|
13106
13039
|
if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
|
13107
|
-
throw new CodeError
|
13040
|
+
throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
|
13108
13041
|
}
|
13109
13042
|
const keys = await unmarshalPrivateKey$1(jwk);
|
13110
13043
|
return new RsaPrivateKey(keys.privateKey, keys.publicKey);
|
13111
13044
|
}
|
13112
13045
|
async function generateKeyPair$1(bits) {
|
13113
13046
|
if (bits > MAX_RSA_KEY_SIZE) {
|
13114
|
-
throw new CodeError
|
13047
|
+
throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
|
13115
13048
|
}
|
13116
13049
|
const keys = await generateKey$1(bits);
|
13117
13050
|
return new RsaPrivateKey(keys.privateKey, keys.publicKey);
|
@@ -13130,6 +13063,12 @@ var RSA = /*#__PURE__*/Object.freeze({
|
|
13130
13063
|
|
13131
13064
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13132
13065
|
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
13066
|
+
function validateSigVerOpts(opts) {
|
13067
|
+
if (opts.lowS !== undefined)
|
13068
|
+
abool('lowS', opts.lowS);
|
13069
|
+
if (opts.prehash !== undefined)
|
13070
|
+
abool('prehash', opts.prehash);
|
13071
|
+
}
|
13133
13072
|
function validatePointOpts(curve) {
|
13134
13073
|
const opts = validateBasic(curve);
|
13135
13074
|
validateObject(opts, {
|
@@ -13254,16 +13193,12 @@ function weierstrassPoints(opts) {
|
|
13254
13193
|
throw new Error('bad generator point: equation left != right');
|
13255
13194
|
// Valid group elements reside in range 1..n-1
|
13256
13195
|
function isWithinCurveOrder(num) {
|
13257
|
-
return
|
13258
|
-
}
|
13259
|
-
function assertGE(num) {
|
13260
|
-
if (!isWithinCurveOrder(num))
|
13261
|
-
throw new Error('Expected valid bigint: 0 < bigint < curve.n');
|
13196
|
+
return inRange(num, _1n$1, CURVE.n);
|
13262
13197
|
}
|
13263
13198
|
// Validates if priv key is valid and converts it to bigint.
|
13264
13199
|
// Supports options allowedPrivateKeyLengths and wrapPrivateKey.
|
13265
13200
|
function normPrivateKeyToScalar(key) {
|
13266
|
-
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
|
13201
|
+
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
|
13267
13202
|
if (lengths && typeof key !== 'bigint') {
|
13268
13203
|
if (isBytes$1(key))
|
13269
13204
|
key = bytesToHex(key);
|
@@ -13283,15 +13218,61 @@ function weierstrassPoints(opts) {
|
|
13283
13218
|
throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
|
13284
13219
|
}
|
13285
13220
|
if (wrapPrivateKey)
|
13286
|
-
num = mod(num,
|
13287
|
-
|
13221
|
+
num = mod(num, N); // disabled by default, enabled for BLS
|
13222
|
+
aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
|
13288
13223
|
return num;
|
13289
13224
|
}
|
13290
|
-
const pointPrecomputes = new Map();
|
13291
13225
|
function assertPrjPoint(other) {
|
13292
13226
|
if (!(other instanceof Point))
|
13293
13227
|
throw new Error('ProjectivePoint expected');
|
13294
13228
|
}
|
13229
|
+
// Memoized toAffine / validity check. They are heavy. Points are immutable.
|
13230
|
+
// Converts Projective point to affine (x, y) coordinates.
|
13231
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
13232
|
+
// (x, y, z) ∋ (x=x/z, y=y/z)
|
13233
|
+
const toAffineMemo = memoized((p, iz) => {
|
13234
|
+
const { px: x, py: y, pz: z } = p;
|
13235
|
+
// Fast-path for normalized points
|
13236
|
+
if (Fp.eql(z, Fp.ONE))
|
13237
|
+
return { x, y };
|
13238
|
+
const is0 = p.is0();
|
13239
|
+
// If invZ was 0, we return zero point. However we still want to execute
|
13240
|
+
// all operations, so we replace invZ with a random number, 1.
|
13241
|
+
if (iz == null)
|
13242
|
+
iz = is0 ? Fp.ONE : Fp.inv(z);
|
13243
|
+
const ax = Fp.mul(x, iz);
|
13244
|
+
const ay = Fp.mul(y, iz);
|
13245
|
+
const zz = Fp.mul(z, iz);
|
13246
|
+
if (is0)
|
13247
|
+
return { x: Fp.ZERO, y: Fp.ZERO };
|
13248
|
+
if (!Fp.eql(zz, Fp.ONE))
|
13249
|
+
throw new Error('invZ was invalid');
|
13250
|
+
return { x: ax, y: ay };
|
13251
|
+
});
|
13252
|
+
// NOTE: on exception this will crash 'cached' and no value will be set.
|
13253
|
+
// Otherwise true will be return
|
13254
|
+
const assertValidMemo = memoized((p) => {
|
13255
|
+
if (p.is0()) {
|
13256
|
+
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13257
|
+
// In BLS, ZERO can be serialized, so we allow it.
|
13258
|
+
// (0, 0, 0) is wrong representation of ZERO and is always invalid.
|
13259
|
+
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
13260
|
+
return;
|
13261
|
+
throw new Error('bad point: ZERO');
|
13262
|
+
}
|
13263
|
+
// Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
|
13264
|
+
const { x, y } = p.toAffine();
|
13265
|
+
// Check if x, y are valid field elements
|
13266
|
+
if (!Fp.isValid(x) || !Fp.isValid(y))
|
13267
|
+
throw new Error('bad point: x or y not FE');
|
13268
|
+
const left = Fp.sqr(y); // y²
|
13269
|
+
const right = weierstrassEquation(x); // x³ + ax + b
|
13270
|
+
if (!Fp.eql(left, right))
|
13271
|
+
throw new Error('bad point: equation left != right');
|
13272
|
+
if (!p.isTorsionFree())
|
13273
|
+
throw new Error('bad point: not in prime-order subgroup');
|
13274
|
+
return true;
|
13275
|
+
});
|
13295
13276
|
/**
|
13296
13277
|
* Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
|
13297
13278
|
* Default Point works in 2d / affine coordinates: (x, y)
|
@@ -13308,6 +13289,7 @@ function weierstrassPoints(opts) {
|
|
13308
13289
|
throw new Error('y required');
|
13309
13290
|
if (pz == null || !Fp.isValid(pz))
|
13310
13291
|
throw new Error('z required');
|
13292
|
+
Object.freeze(this);
|
13311
13293
|
}
|
13312
13294
|
// Does not validate if the point is on-curve.
|
13313
13295
|
// Use fromHex instead, or call assertValidity() later.
|
@@ -13354,30 +13336,11 @@ function weierstrassPoints(opts) {
|
|
13354
13336
|
}
|
13355
13337
|
// "Private method", don't use it directly
|
13356
13338
|
_setWindowSize(windowSize) {
|
13357
|
-
this
|
13358
|
-
pointPrecomputes.delete(this);
|
13339
|
+
wnaf.setWindowSize(this, windowSize);
|
13359
13340
|
}
|
13360
13341
|
// A point on curve is valid if it conforms to equation.
|
13361
13342
|
assertValidity() {
|
13362
|
-
|
13363
|
-
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13364
|
-
// In BLS, ZERO can be serialized, so we allow it.
|
13365
|
-
// (0, 0, 0) is wrong representation of ZERO and is always invalid.
|
13366
|
-
if (CURVE.allowInfinityPoint && !Fp.is0(this.py))
|
13367
|
-
return;
|
13368
|
-
throw new Error('bad point: ZERO');
|
13369
|
-
}
|
13370
|
-
// Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
|
13371
|
-
const { x, y } = this.toAffine();
|
13372
|
-
// Check if x, y are valid field elements
|
13373
|
-
if (!Fp.isValid(x) || !Fp.isValid(y))
|
13374
|
-
throw new Error('bad point: x or y not FE');
|
13375
|
-
const left = Fp.sqr(y); // y²
|
13376
|
-
const right = weierstrassEquation(x); // x³ + ax + b
|
13377
|
-
if (!Fp.eql(left, right))
|
13378
|
-
throw new Error('bad point: equation left != right');
|
13379
|
-
if (!this.isTorsionFree())
|
13380
|
-
throw new Error('bad point: not in prime-order subgroup');
|
13343
|
+
assertValidMemo(this);
|
13381
13344
|
}
|
13382
13345
|
hasEvenY() {
|
13383
13346
|
const { y } = this.toAffine();
|
@@ -13504,28 +13467,25 @@ function weierstrassPoints(opts) {
|
|
13504
13467
|
return this.equals(Point.ZERO);
|
13505
13468
|
}
|
13506
13469
|
wNAF(n) {
|
13507
|
-
return wnaf.wNAFCached(this,
|
13508
|
-
const toInv = Fp.invertBatch(comp.map((p) => p.pz));
|
13509
|
-
return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
13510
|
-
});
|
13470
|
+
return wnaf.wNAFCached(this, n, Point.normalizeZ);
|
13511
13471
|
}
|
13512
13472
|
/**
|
13513
13473
|
* Non-constant-time multiplication. Uses double-and-add algorithm.
|
13514
13474
|
* It's faster, but should only be used when you don't care about
|
13515
13475
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
13516
13476
|
*/
|
13517
|
-
multiplyUnsafe(
|
13477
|
+
multiplyUnsafe(sc) {
|
13478
|
+
aInRange('scalar', sc, _0n, CURVE.n);
|
13518
13479
|
const I = Point.ZERO;
|
13519
|
-
if (
|
13480
|
+
if (sc === _0n)
|
13520
13481
|
return I;
|
13521
|
-
|
13522
|
-
if (n === _1n$1)
|
13482
|
+
if (sc === _1n$1)
|
13523
13483
|
return this;
|
13524
13484
|
const { endo } = CURVE;
|
13525
13485
|
if (!endo)
|
13526
|
-
return wnaf.unsafeLadder(this,
|
13486
|
+
return wnaf.unsafeLadder(this, sc);
|
13527
13487
|
// Apply endomorphism
|
13528
|
-
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(
|
13488
|
+
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
13529
13489
|
let k1p = I;
|
13530
13490
|
let k2p = I;
|
13531
13491
|
let d = this;
|
@@ -13555,12 +13515,11 @@ function weierstrassPoints(opts) {
|
|
13555
13515
|
* @returns New point
|
13556
13516
|
*/
|
13557
13517
|
multiply(scalar) {
|
13558
|
-
|
13559
|
-
|
13518
|
+
const { endo, n: N } = CURVE;
|
13519
|
+
aInRange('scalar', scalar, _1n$1, N);
|
13560
13520
|
let point, fake; // Fake point is used to const-time mult
|
13561
|
-
const { endo } = CURVE;
|
13562
13521
|
if (endo) {
|
13563
|
-
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(
|
13522
|
+
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
|
13564
13523
|
let { p: k1p, f: f1p } = this.wNAF(k1);
|
13565
13524
|
let { p: k2p, f: f2p } = this.wNAF(k2);
|
13566
13525
|
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
@@ -13570,7 +13529,7 @@ function weierstrassPoints(opts) {
|
|
13570
13529
|
fake = f1p.add(f2p);
|
13571
13530
|
}
|
13572
13531
|
else {
|
13573
|
-
const { p, f } = this.wNAF(
|
13532
|
+
const { p, f } = this.wNAF(scalar);
|
13574
13533
|
point = p;
|
13575
13534
|
fake = f;
|
13576
13535
|
}
|
@@ -13594,20 +13553,7 @@ function weierstrassPoints(opts) {
|
|
13594
13553
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
13595
13554
|
// (x, y, z) ∋ (x=x/z, y=y/z)
|
13596
13555
|
toAffine(iz) {
|
13597
|
-
|
13598
|
-
const is0 = this.is0();
|
13599
|
-
// If invZ was 0, we return zero point. However we still want to execute
|
13600
|
-
// all operations, so we replace invZ with a random number, 1.
|
13601
|
-
if (iz == null)
|
13602
|
-
iz = is0 ? Fp.ONE : Fp.inv(z);
|
13603
|
-
const ax = Fp.mul(x, iz);
|
13604
|
-
const ay = Fp.mul(y, iz);
|
13605
|
-
const zz = Fp.mul(z, iz);
|
13606
|
-
if (is0)
|
13607
|
-
return { x: Fp.ZERO, y: Fp.ZERO };
|
13608
|
-
if (!Fp.eql(zz, Fp.ONE))
|
13609
|
-
throw new Error('invZ was invalid');
|
13610
|
-
return { x: ax, y: ay };
|
13556
|
+
return toAffineMemo(this, iz);
|
13611
13557
|
}
|
13612
13558
|
isTorsionFree() {
|
13613
13559
|
const { h: cofactor, isTorsionFree } = CURVE;
|
@@ -13626,10 +13572,12 @@ function weierstrassPoints(opts) {
|
|
13626
13572
|
return this.multiplyUnsafe(CURVE.h);
|
13627
13573
|
}
|
13628
13574
|
toRawBytes(isCompressed = true) {
|
13575
|
+
abool('isCompressed', isCompressed);
|
13629
13576
|
this.assertValidity();
|
13630
13577
|
return toBytes(Point, this, isCompressed);
|
13631
13578
|
}
|
13632
13579
|
toHex(isCompressed = true) {
|
13580
|
+
abool('isCompressed', isCompressed);
|
13633
13581
|
return bytesToHex(this.toRawBytes(isCompressed));
|
13634
13582
|
}
|
13635
13583
|
}
|
@@ -13659,14 +13607,18 @@ function validateOpts(curve) {
|
|
13659
13607
|
});
|
13660
13608
|
return Object.freeze({ lowS: true, ...opts });
|
13661
13609
|
}
|
13610
|
+
/**
|
13611
|
+
* Creates short weierstrass curve and ECDSA signature methods for it.
|
13612
|
+
* @example
|
13613
|
+
* import { Field } from '@noble/curves/abstract/modular';
|
13614
|
+
* // Before that, define BigInt-s: a, b, p, n, Gx, Gy
|
13615
|
+
* const curve = weierstrass({ a, b, Fp: Field(p), n, Gx, Gy, h: 1n })
|
13616
|
+
*/
|
13662
13617
|
function weierstrass(curveDef) {
|
13663
13618
|
const CURVE = validateOpts(curveDef);
|
13664
13619
|
const { Fp, n: CURVE_ORDER } = CURVE;
|
13665
13620
|
const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
|
13666
13621
|
const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
|
13667
|
-
function isValidFieldElement(num) {
|
13668
|
-
return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE
|
13669
|
-
}
|
13670
13622
|
function modN(a) {
|
13671
13623
|
return mod(a, CURVE_ORDER);
|
13672
13624
|
}
|
@@ -13679,6 +13631,7 @@ function weierstrass(curveDef) {
|
|
13679
13631
|
const a = point.toAffine();
|
13680
13632
|
const x = Fp.toBytes(a.x);
|
13681
13633
|
const cat = concatBytes;
|
13634
|
+
abool('isCompressed', isCompressed);
|
13682
13635
|
if (isCompressed) {
|
13683
13636
|
return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
|
13684
13637
|
}
|
@@ -13693,7 +13646,7 @@ function weierstrass(curveDef) {
|
|
13693
13646
|
// this.assertValidity() is done inside of fromHex
|
13694
13647
|
if (len === compressedLen && (head === 0x02 || head === 0x03)) {
|
13695
13648
|
const x = bytesToNumberBE(tail);
|
13696
|
-
if (!
|
13649
|
+
if (!inRange(x, _1n$1, Fp.ORDER))
|
13697
13650
|
throw new Error('Point is not on curve');
|
13698
13651
|
const y2 = weierstrassEquation(x); // y² = x³ + ax + b
|
13699
13652
|
let y;
|
@@ -13754,11 +13707,8 @@ function weierstrass(curveDef) {
|
|
13754
13707
|
return new Signature(r, s);
|
13755
13708
|
}
|
13756
13709
|
assertValidity() {
|
13757
|
-
//
|
13758
|
-
|
13759
|
-
throw new Error('r must be 0 < r < CURVE.n');
|
13760
|
-
if (!isWithinCurveOrder(this.s))
|
13761
|
-
throw new Error('s must be 0 < s < CURVE.n');
|
13710
|
+
aInRange('r', this.r, _1n$1, CURVE_ORDER); // r in [1..N]
|
13711
|
+
aInRange('s', this.s, _1n$1, CURVE_ORDER); // s in [1..N]
|
13762
13712
|
}
|
13763
13713
|
addRecoveryBit(recovery) {
|
13764
13714
|
return new Signature(this.r, this.s, recovery);
|
@@ -13901,10 +13851,7 @@ function weierstrass(curveDef) {
|
|
13901
13851
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13902
13852
|
*/
|
13903
13853
|
function int2octets(num) {
|
13904
|
-
|
13905
|
-
throw new Error('bigint expected');
|
13906
|
-
if (!(_0n <= num && num < ORDER_MASK))
|
13907
|
-
throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
|
13854
|
+
aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
|
13908
13855
|
// works with order, can have different size than numToField!
|
13909
13856
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13910
13857
|
}
|
@@ -13921,6 +13868,7 @@ function weierstrass(curveDef) {
|
|
13921
13868
|
if (lowS == null)
|
13922
13869
|
lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
|
13923
13870
|
msgHash = ensureBytes('msgHash', msgHash);
|
13871
|
+
validateSigVerOpts(opts);
|
13924
13872
|
if (prehash)
|
13925
13873
|
msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
|
13926
13874
|
// We can't later call bits2octets, since nested bits2int is broken for curves
|
@@ -14007,6 +13955,7 @@ function weierstrass(curveDef) {
|
|
14007
13955
|
publicKey = ensureBytes('publicKey', publicKey);
|
14008
13956
|
if ('strict' in opts)
|
14009
13957
|
throw new Error('options.strict was renamed to lowS');
|
13958
|
+
validateSigVerOpts(opts);
|
14010
13959
|
const { lowS, prehash } = opts;
|
14011
13960
|
let _sig = undefined;
|
14012
13961
|
let P;
|
@@ -14113,6 +14062,9 @@ function sqrtMod(y) {
|
|
14113
14062
|
return root;
|
14114
14063
|
}
|
14115
14064
|
const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
14065
|
+
/**
|
14066
|
+
* secp256k1 short weierstrass curve and ECDSA signatures over it.
|
14067
|
+
*/
|
14116
14068
|
const secp256k1 = createCurve({
|
14117
14069
|
a: BigInt(0), // equation params: a, b
|
14118
14070
|
b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
|
@@ -14171,14 +14123,14 @@ function hashAndSign(key, msg) {
|
|
14171
14123
|
if (isPromise$1(p)) {
|
14172
14124
|
return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
|
14173
14125
|
.catch(err => {
|
14174
|
-
throw new CodeError
|
14126
|
+
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
14175
14127
|
});
|
14176
14128
|
}
|
14177
14129
|
try {
|
14178
14130
|
return secp256k1.sign(p.digest, key).toDERRawBytes();
|
14179
14131
|
}
|
14180
14132
|
catch (err) {
|
14181
|
-
throw new CodeError
|
14133
|
+
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
14182
14134
|
}
|
14183
14135
|
}
|
14184
14136
|
/**
|
@@ -14189,14 +14141,14 @@ function hashAndVerify(key, sig, msg) {
|
|
14189
14141
|
if (isPromise$1(p)) {
|
14190
14142
|
return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
|
14191
14143
|
.catch(err => {
|
14192
|
-
throw new CodeError
|
14144
|
+
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
14193
14145
|
});
|
14194
14146
|
}
|
14195
14147
|
try {
|
14196
14148
|
return secp256k1.verify(sig, p.digest, key);
|
14197
14149
|
}
|
14198
14150
|
catch (err) {
|
14199
|
-
throw new CodeError
|
14151
|
+
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
14200
14152
|
}
|
14201
14153
|
}
|
14202
14154
|
function compressPublicKey(key) {
|
@@ -14208,7 +14160,7 @@ function validatePrivateKey(key) {
|
|
14208
14160
|
secp256k1.getPublicKey(key, true);
|
14209
14161
|
}
|
14210
14162
|
catch (err) {
|
14211
|
-
throw new CodeError
|
14163
|
+
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
14212
14164
|
}
|
14213
14165
|
}
|
14214
14166
|
function validatePublicKey(key) {
|
@@ -14216,7 +14168,7 @@ function validatePublicKey(key) {
|
|
14216
14168
|
secp256k1.ProjectivePoint.fromHex(key);
|
14217
14169
|
}
|
14218
14170
|
catch (err) {
|
14219
|
-
throw new CodeError
|
14171
|
+
throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
|
14220
14172
|
}
|
14221
14173
|
}
|
14222
14174
|
function computePublicKey(privateKey) {
|
@@ -14224,7 +14176,7 @@ function computePublicKey(privateKey) {
|
|
14224
14176
|
return secp256k1.getPublicKey(privateKey, true);
|
14225
14177
|
}
|
14226
14178
|
catch (err) {
|
14227
|
-
throw new CodeError
|
14179
|
+
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
14228
14180
|
}
|
14229
14181
|
}
|
14230
14182
|
|
@@ -14314,7 +14266,7 @@ class Secp256k1PrivateKey {
|
|
14314
14266
|
return exporter(this.bytes, password);
|
14315
14267
|
}
|
14316
14268
|
else {
|
14317
|
-
throw new CodeError
|
14269
|
+
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
14318
14270
|
}
|
14319
14271
|
}
|
14320
14272
|
}
|
@@ -14356,7 +14308,7 @@ const supportedKeys = {
|
|
14356
14308
|
};
|
14357
14309
|
function unsupportedKey(type) {
|
14358
14310
|
const supported = Object.keys(supportedKeys).join(' / ');
|
14359
|
-
return new CodeError
|
14311
|
+
return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
|
14360
14312
|
}
|
14361
14313
|
function typeToKey(type) {
|
14362
14314
|
type = type.toLowerCase();
|
@@ -14541,6 +14493,41 @@ class Secp256k1PeerIdImpl extends PeerIdImpl {
|
|
14541
14493
|
this.publicKey = init.multihash.digest;
|
14542
14494
|
}
|
14543
14495
|
}
|
14496
|
+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14497
|
+
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
14498
|
+
class URLPeerIdImpl {
|
14499
|
+
type = 'url';
|
14500
|
+
multihash;
|
14501
|
+
privateKey;
|
14502
|
+
publicKey;
|
14503
|
+
url;
|
14504
|
+
constructor(url) {
|
14505
|
+
this.url = url.toString();
|
14506
|
+
this.multihash = identity.digest(fromString(this.url));
|
14507
|
+
}
|
14508
|
+
[inspect]() {
|
14509
|
+
return `PeerId(${this.url})`;
|
14510
|
+
}
|
14511
|
+
[peerIdSymbol] = true;
|
14512
|
+
toString() {
|
14513
|
+
return this.toCID().toString();
|
14514
|
+
}
|
14515
|
+
toCID() {
|
14516
|
+
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
|
14517
|
+
}
|
14518
|
+
toBytes() {
|
14519
|
+
return this.toCID().bytes;
|
14520
|
+
}
|
14521
|
+
equals(other) {
|
14522
|
+
if (other == null) {
|
14523
|
+
return false;
|
14524
|
+
}
|
14525
|
+
if (other instanceof Uint8Array) {
|
14526
|
+
other = toString$6(other);
|
14527
|
+
}
|
14528
|
+
return other.toString() === this.toString();
|
14529
|
+
}
|
14530
|
+
}
|
14544
14531
|
function peerIdFromString(str, decoder) {
|
14545
14532
|
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
14546
14533
|
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
@@ -14579,9 +14566,13 @@ function peerIdFromBytes(buf) {
|
|
14579
14566
|
throw new Error('Supplied PeerID CID is invalid');
|
14580
14567
|
}
|
14581
14568
|
function peerIdFromCID(cid) {
|
14582
|
-
if (cid == null || cid.
|
14569
|
+
if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
|
14583
14570
|
throw new Error('Supplied PeerID CID is invalid');
|
14584
14571
|
}
|
14572
|
+
if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
|
14573
|
+
const url = toString$6(cid.multihash.digest);
|
14574
|
+
return new URLPeerIdImpl(new URL(url));
|
14575
|
+
}
|
14585
14576
|
const multihash = cid.multihash;
|
14586
14577
|
if (multihash.code === sha256.code) {
|
14587
14578
|
return new RSAPeerIdImpl({ multihash: cid.multihash });
|
@@ -15427,9 +15418,6 @@ function isHexString(value, length) {
|
|
15427
15418
|
if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
|
15428
15419
|
return false;
|
15429
15420
|
}
|
15430
|
-
if (length && value.length !== 2 + 2 * length) {
|
15431
|
-
return false;
|
15432
|
-
}
|
15433
15421
|
return true;
|
15434
15422
|
}
|
15435
15423
|
const HexCharacters = "0123456789abcdef";
|
@@ -17853,7 +17841,7 @@ if (!AbortError$1) {
|
|
17853
17841
|
AbortError$1.prototype.name = 'AbortError';
|
17854
17842
|
AbortError$1.prototype.code = 'ABORT_ERR';
|
17855
17843
|
|
17856
|
-
const URL = (typeof globalThis !== 'undefined' && globalThis.URL) || require('url').URL;
|
17844
|
+
const URL$1 = (typeof globalThis !== 'undefined' && globalThis.URL) || require('url').URL;
|
17857
17845
|
|
17858
17846
|
class HTTPStatusError extends Error {
|
17859
17847
|
constructor (uri, code, method) {
|
@@ -18102,7 +18090,7 @@ class HTTPEndpoint extends BaseEndpoint {
|
|
18102
18090
|
}
|
18103
18091
|
const url = `${this.protocol}//${safeHost(this.host)}:${this.port}${this.path}`;
|
18104
18092
|
try {
|
18105
|
-
this.url = new URL(url);
|
18093
|
+
this.url = new URL$1(url);
|
18106
18094
|
} catch (err) {
|
18107
18095
|
throw new Error(err.message + ` [${url}]`)
|
18108
18096
|
}
|
@@ -18184,7 +18172,7 @@ async function loadJSON (url, cache, timeout, abortSignal) {
|
|
18184
18172
|
|
18185
18173
|
function requestRaw (url, method, data, timeout, abortSignal) {
|
18186
18174
|
return new Promise((resolve, reject) => {
|
18187
|
-
const target = new URL(url);
|
18175
|
+
const target = new URL$1(url);
|
18188
18176
|
if (method === 'GET' && data) {
|
18189
18177
|
target.search = '?dns=' + base64URL.decode(data);
|
18190
18178
|
}
|
@@ -19563,7 +19551,7 @@ function queryDoh (endpoint, query, timeout, abortSignal) {
|
|
19563
19551
|
)
|
19564
19552
|
}
|
19565
19553
|
|
19566
|
-
const UPDATE_URL = new URL('https://martinheidegger.github.io/dns-query/resolvers.json');
|
19554
|
+
const UPDATE_URL = new URL$1('https://martinheidegger.github.io/dns-query/resolvers.json');
|
19567
19555
|
|
19568
19556
|
function isNameString (entry) {
|
19569
19557
|
return /^@/.test(entry)
|
@@ -20918,16 +20906,14 @@ class BaseProtocol {
|
|
20918
20906
|
components;
|
20919
20907
|
log;
|
20920
20908
|
pubsubTopics;
|
20921
|
-
options;
|
20922
20909
|
addLibp2pEventListener;
|
20923
20910
|
removeLibp2pEventListener;
|
20924
20911
|
streamManager;
|
20925
|
-
constructor(multicodec, components, log, pubsubTopics
|
20912
|
+
constructor(multicodec, components, log, pubsubTopics) {
|
20926
20913
|
this.multicodec = multicodec;
|
20927
20914
|
this.components = components;
|
20928
20915
|
this.log = log;
|
20929
20916
|
this.pubsubTopics = pubsubTopics;
|
20930
|
-
this.options = options;
|
20931
20917
|
this.addLibp2pEventListener = components.events.addEventListener.bind(components.events);
|
20932
20918
|
this.removeLibp2pEventListener = components.events.removeEventListener.bind(components.events);
|
20933
20919
|
this.streamManager = new StreamManager(multicodec, components.connectionManager.getConnections.bind(components.connectionManager), this.addLibp2pEventListener);
|
@@ -20965,9 +20951,7 @@ class BaseProtocol {
|
|
20965
20951
|
numPeers: 0
|
20966
20952
|
}) {
|
20967
20953
|
// Retrieve all connected peers that support the protocol & shard (if configured)
|
20968
|
-
const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], this.
|
20969
|
-
? ensureShardingConfigured(this.options.shardInfo).shardInfo
|
20970
|
-
: undefined);
|
20954
|
+
const connectedPeersForProtocolAndShard = await getConnectedPeersForProtocolAndShard(this.components.connectionManager.getConnections(), this.peerStore, [this.multicodec], pubsubTopicsToShardInfo(this.pubsubTopics));
|
20971
20955
|
// Filter the peers based on discovery & number of peers requested
|
20972
20956
|
const filteredPeers = filterPeersByDiscovery(connectedPeersForProtocolAndShard, numPeers, maxBootstrapPeers);
|
20973
20957
|
// Sort the peers by latency
|
@@ -21657,74 +21641,35 @@ encode.single = (chunk, options) => {
|
|
21657
21641
|
};
|
21658
21642
|
|
21659
21643
|
/**
|
21660
|
-
*
|
21661
|
-
* @typedef {Error} Err
|
21662
|
-
* @property {string} message
|
21644
|
+
* The reported length of the next data message was not a positive integer
|
21663
21645
|
*/
|
21664
|
-
|
21646
|
+
class InvalidMessageLengthError extends Error {
|
21647
|
+
name = 'InvalidMessageLengthError';
|
21648
|
+
code = 'ERR_INVALID_MSG_LENGTH';
|
21649
|
+
}
|
21665
21650
|
/**
|
21666
|
-
*
|
21667
|
-
*
|
21668
|
-
* @param {Extensions} props
|
21669
|
-
* @returns {Error & Extensions}
|
21651
|
+
* The reported length of the next data message was larger than the configured
|
21652
|
+
* max allowable value
|
21670
21653
|
*/
|
21671
|
-
|
21672
|
-
|
21673
|
-
|
21674
|
-
value: props[key],
|
21675
|
-
enumerable: true,
|
21676
|
-
configurable: true,
|
21677
|
-
});
|
21678
|
-
}
|
21679
|
-
|
21680
|
-
return obj;
|
21654
|
+
class InvalidDataLengthError extends Error {
|
21655
|
+
name = 'InvalidDataLengthError';
|
21656
|
+
code = 'ERR_MSG_DATA_TOO_LONG';
|
21681
21657
|
}
|
21682
|
-
|
21683
21658
|
/**
|
21684
|
-
*
|
21685
|
-
*
|
21686
|
-
* @param {string|Extensions} code - A string code or props to set on the error
|
21687
|
-
* @param {Extensions} [props] - Props to set on the error
|
21688
|
-
* @returns {Error & Extensions}
|
21659
|
+
* The varint used to specify the length of the next data message contained more
|
21660
|
+
* bytes than the configured max allowable value
|
21689
21661
|
*/
|
21690
|
-
|
21691
|
-
|
21692
|
-
|
21693
|
-
|
21694
|
-
|
21695
|
-
|
21696
|
-
|
21697
|
-
|
21698
|
-
|
21699
|
-
|
21700
|
-
props = code;
|
21701
|
-
code = '';
|
21702
|
-
}
|
21703
|
-
|
21704
|
-
if (code) {
|
21705
|
-
props.code = code;
|
21706
|
-
}
|
21707
|
-
|
21708
|
-
try {
|
21709
|
-
return assign(err, props);
|
21710
|
-
} catch (_) {
|
21711
|
-
props.message = err.message;
|
21712
|
-
props.stack = err.stack;
|
21713
|
-
|
21714
|
-
const ErrClass = function () {};
|
21715
|
-
|
21716
|
-
ErrClass.prototype = Object.create(Object.getPrototypeOf(err));
|
21717
|
-
|
21718
|
-
// @ts-ignore
|
21719
|
-
const output = assign(new ErrClass(), props);
|
21720
|
-
|
21721
|
-
return output;
|
21722
|
-
}
|
21662
|
+
class InvalidDataLengthLengthError extends Error {
|
21663
|
+
name = 'InvalidDataLengthLengthError';
|
21664
|
+
code = 'ERR_MSG_LENGTH_TOO_LONG';
|
21665
|
+
}
|
21666
|
+
/**
|
21667
|
+
* The incoming stream ended before the expected number of bytes were read
|
21668
|
+
*/
|
21669
|
+
class UnexpectedEOFError extends Error {
|
21670
|
+
name = 'UnexpectedEOFError';
|
21671
|
+
code = 'ERR_UNEXPECTED_EOF';
|
21723
21672
|
}
|
21724
|
-
|
21725
|
-
var errCode = createError;
|
21726
|
-
|
21727
|
-
var errCode$1 = /*@__PURE__*/getDefaultExportFromCjs(errCode);
|
21728
21673
|
|
21729
21674
|
/* eslint max-depth: ["error", 6] */
|
21730
21675
|
// Maximum length of the length section of the message
|
@@ -21756,10 +21701,10 @@ function decode(source, options) {
|
|
21756
21701
|
try {
|
21757
21702
|
dataLength = lengthDecoder(buffer);
|
21758
21703
|
if (dataLength < 0) {
|
21759
|
-
throw
|
21704
|
+
throw new InvalidMessageLengthError('Invalid message length');
|
21760
21705
|
}
|
21761
21706
|
if (dataLength > maxDataLength) {
|
21762
|
-
throw
|
21707
|
+
throw new InvalidDataLengthError('Message length too long');
|
21763
21708
|
}
|
21764
21709
|
const dataLengthLength = lengthDecoder.bytes;
|
21765
21710
|
buffer.consume(dataLengthLength);
|
@@ -21771,7 +21716,7 @@ function decode(source, options) {
|
|
21771
21716
|
catch (err) {
|
21772
21717
|
if (err instanceof RangeError) {
|
21773
21718
|
if (buffer.byteLength > maxLengthLength) {
|
21774
|
-
throw
|
21719
|
+
throw new InvalidDataLengthLengthError('Message length length too long');
|
21775
21720
|
}
|
21776
21721
|
break;
|
21777
21722
|
}
|
@@ -21800,7 +21745,7 @@ function decode(source, options) {
|
|
21800
21745
|
yield* maybeYield();
|
21801
21746
|
}
|
21802
21747
|
if (buffer.byteLength > 0) {
|
21803
|
-
throw
|
21748
|
+
throw new UnexpectedEOFError('Unexpected end of input');
|
21804
21749
|
}
|
21805
21750
|
})();
|
21806
21751
|
}
|
@@ -21810,7 +21755,7 @@ function decode(source, options) {
|
|
21810
21755
|
yield* maybeYield();
|
21811
21756
|
}
|
21812
21757
|
if (buffer.byteLength > 0) {
|
21813
|
-
throw
|
21758
|
+
throw new UnexpectedEOFError('Unexpected end of input');
|
21814
21759
|
}
|
21815
21760
|
})();
|
21816
21761
|
}
|
@@ -22645,7 +22590,7 @@ var FilterRequest;
|
|
22645
22590
|
}
|
22646
22591
|
case 3: {
|
22647
22592
|
if (opts.limits?.contentFilters != null && obj.contentFilters.length === opts.limits.contentFilters) {
|
22648
|
-
throw new
|
22593
|
+
throw new MaxLengthError('Decode error - map field "contentFilters" had too many elements');
|
22649
22594
|
}
|
22650
22595
|
obj.contentFilters.push(FilterRequest.ContentFilter.codec().decode(reader, reader.uint32(), {
|
22651
22596
|
limits: opts.limits?.contentFilters$
|
@@ -22698,7 +22643,7 @@ var MessagePush$1;
|
|
22698
22643
|
switch (tag >>> 3) {
|
22699
22644
|
case 1: {
|
22700
22645
|
if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
|
22701
|
-
throw new
|
22646
|
+
throw new MaxLengthError('Decode error - map field "messages" had too many elements');
|
22702
22647
|
}
|
22703
22648
|
obj.messages.push(WakuMessage$3.codec().decode(reader, reader.uint32(), {
|
22704
22649
|
limits: opts.limits?.messages$
|
@@ -23117,7 +23062,7 @@ var FilterSubscribeRequest;
|
|
23117
23062
|
}
|
23118
23063
|
case 11: {
|
23119
23064
|
if (opts.limits?.contentTopics != null && obj.contentTopics.length === opts.limits.contentTopics) {
|
23120
|
-
throw new
|
23065
|
+
throw new MaxLengthError('Decode error - map field "contentTopics" had too many elements');
|
23121
23066
|
}
|
23122
23067
|
obj.contentTopics.push(reader.string());
|
23123
23068
|
break;
|
@@ -23839,113 +23784,26 @@ var WakuMessage$1;
|
|
23839
23784
|
/* eslint-disable @typescript-eslint/no-namespace */
|
23840
23785
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
23841
23786
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
23842
|
-
var
|
23843
|
-
(function (
|
23787
|
+
var WakuMessageKeyValue;
|
23788
|
+
(function (WakuMessageKeyValue) {
|
23844
23789
|
let _codec;
|
23845
|
-
|
23790
|
+
WakuMessageKeyValue.codec = () => {
|
23846
23791
|
if (_codec == null) {
|
23847
23792
|
_codec = message((obj, w, opts = {}) => {
|
23848
23793
|
if (opts.lengthDelimited !== false) {
|
23849
23794
|
w.fork();
|
23850
23795
|
}
|
23851
|
-
if (
|
23796
|
+
if (obj.messageHash != null) {
|
23852
23797
|
w.uint32(10);
|
23853
|
-
w.bytes(obj.
|
23798
|
+
w.bytes(obj.messageHash);
|
23854
23799
|
}
|
23855
|
-
if (
|
23856
|
-
w.uint32(16);
|
23857
|
-
w.sint64(obj.receiverTime);
|
23858
|
-
}
|
23859
|
-
if ((obj.senderTime != null && obj.senderTime !== 0n)) {
|
23860
|
-
w.uint32(24);
|
23861
|
-
w.sint64(obj.senderTime);
|
23862
|
-
}
|
23863
|
-
if ((obj.pubsubTopic != null && obj.pubsubTopic !== '')) {
|
23864
|
-
w.uint32(34);
|
23865
|
-
w.string(obj.pubsubTopic);
|
23866
|
-
}
|
23867
|
-
if (opts.lengthDelimited !== false) {
|
23868
|
-
w.ldelim();
|
23869
|
-
}
|
23870
|
-
}, (reader, length, opts = {}) => {
|
23871
|
-
const obj = {
|
23872
|
-
digest: alloc$2(0),
|
23873
|
-
receiverTime: 0n,
|
23874
|
-
senderTime: 0n,
|
23875
|
-
pubsubTopic: ''
|
23876
|
-
};
|
23877
|
-
const end = length == null ? reader.len : reader.pos + length;
|
23878
|
-
while (reader.pos < end) {
|
23879
|
-
const tag = reader.uint32();
|
23880
|
-
switch (tag >>> 3) {
|
23881
|
-
case 1: {
|
23882
|
-
obj.digest = reader.bytes();
|
23883
|
-
break;
|
23884
|
-
}
|
23885
|
-
case 2: {
|
23886
|
-
obj.receiverTime = reader.sint64();
|
23887
|
-
break;
|
23888
|
-
}
|
23889
|
-
case 3: {
|
23890
|
-
obj.senderTime = reader.sint64();
|
23891
|
-
break;
|
23892
|
-
}
|
23893
|
-
case 4: {
|
23894
|
-
obj.pubsubTopic = reader.string();
|
23895
|
-
break;
|
23896
|
-
}
|
23897
|
-
default: {
|
23898
|
-
reader.skipType(tag & 7);
|
23899
|
-
break;
|
23900
|
-
}
|
23901
|
-
}
|
23902
|
-
}
|
23903
|
-
return obj;
|
23904
|
-
});
|
23905
|
-
}
|
23906
|
-
return _codec;
|
23907
|
-
};
|
23908
|
-
Index.encode = (obj) => {
|
23909
|
-
return encodeMessage(obj, Index.codec());
|
23910
|
-
};
|
23911
|
-
Index.decode = (buf, opts) => {
|
23912
|
-
return decodeMessage(buf, Index.codec(), opts);
|
23913
|
-
};
|
23914
|
-
})(Index || (Index = {}));
|
23915
|
-
var PagingInfo;
|
23916
|
-
(function (PagingInfo) {
|
23917
|
-
(function (Direction) {
|
23918
|
-
Direction["BACKWARD"] = "BACKWARD";
|
23919
|
-
Direction["FORWARD"] = "FORWARD";
|
23920
|
-
})(PagingInfo.Direction || (PagingInfo.Direction = {}));
|
23921
|
-
let __DirectionValues;
|
23922
|
-
(function (__DirectionValues) {
|
23923
|
-
__DirectionValues[__DirectionValues["BACKWARD"] = 0] = "BACKWARD";
|
23924
|
-
__DirectionValues[__DirectionValues["FORWARD"] = 1] = "FORWARD";
|
23925
|
-
})(__DirectionValues || (__DirectionValues = {}));
|
23926
|
-
(function (Direction) {
|
23927
|
-
Direction.codec = () => {
|
23928
|
-
return enumeration(__DirectionValues);
|
23929
|
-
};
|
23930
|
-
})(PagingInfo.Direction || (PagingInfo.Direction = {}));
|
23931
|
-
let _codec;
|
23932
|
-
PagingInfo.codec = () => {
|
23933
|
-
if (_codec == null) {
|
23934
|
-
_codec = message((obj, w, opts = {}) => {
|
23935
|
-
if (opts.lengthDelimited !== false) {
|
23936
|
-
w.fork();
|
23937
|
-
}
|
23938
|
-
if (obj.pageSize != null) {
|
23939
|
-
w.uint32(8);
|
23940
|
-
w.uint64(obj.pageSize);
|
23941
|
-
}
|
23942
|
-
if (obj.cursor != null) {
|
23800
|
+
if (obj.message != null) {
|
23943
23801
|
w.uint32(18);
|
23944
|
-
|
23802
|
+
WakuMessage.codec().encode(obj.message, w);
|
23945
23803
|
}
|
23946
|
-
if (obj.
|
23947
|
-
w.uint32(
|
23948
|
-
|
23804
|
+
if (obj.pubsubTopic != null) {
|
23805
|
+
w.uint32(26);
|
23806
|
+
w.string(obj.pubsubTopic);
|
23949
23807
|
}
|
23950
23808
|
if (opts.lengthDelimited !== false) {
|
23951
23809
|
w.ldelim();
|
@@ -23957,17 +23815,17 @@ var PagingInfo;
|
|
23957
23815
|
const tag = reader.uint32();
|
23958
23816
|
switch (tag >>> 3) {
|
23959
23817
|
case 1: {
|
23960
|
-
obj.
|
23818
|
+
obj.messageHash = reader.bytes();
|
23961
23819
|
break;
|
23962
23820
|
}
|
23963
23821
|
case 2: {
|
23964
|
-
obj.
|
23965
|
-
limits: opts.limits?.
|
23822
|
+
obj.message = WakuMessage.codec().decode(reader, reader.uint32(), {
|
23823
|
+
limits: opts.limits?.message
|
23966
23824
|
});
|
23967
23825
|
break;
|
23968
23826
|
}
|
23969
23827
|
case 3: {
|
23970
|
-
obj.
|
23828
|
+
obj.pubsubTopic = reader.string();
|
23971
23829
|
break;
|
23972
23830
|
}
|
23973
23831
|
default: {
|
@@ -23981,217 +23839,125 @@ var PagingInfo;
|
|
23981
23839
|
}
|
23982
23840
|
return _codec;
|
23983
23841
|
};
|
23984
|
-
|
23985
|
-
return encodeMessage(obj,
|
23842
|
+
WakuMessageKeyValue.encode = (obj) => {
|
23843
|
+
return encodeMessage(obj, WakuMessageKeyValue.codec());
|
23986
23844
|
};
|
23987
|
-
|
23988
|
-
return decodeMessage(buf,
|
23845
|
+
WakuMessageKeyValue.decode = (buf, opts) => {
|
23846
|
+
return decodeMessage(buf, WakuMessageKeyValue.codec(), opts);
|
23989
23847
|
};
|
23990
|
-
})(
|
23991
|
-
var
|
23992
|
-
(function (
|
23848
|
+
})(WakuMessageKeyValue || (WakuMessageKeyValue = {}));
|
23849
|
+
var StoreQueryRequest;
|
23850
|
+
(function (StoreQueryRequest) {
|
23993
23851
|
let _codec;
|
23994
|
-
|
23852
|
+
StoreQueryRequest.codec = () => {
|
23995
23853
|
if (_codec == null) {
|
23996
23854
|
_codec = message((obj, w, opts = {}) => {
|
23997
23855
|
if (opts.lengthDelimited !== false) {
|
23998
23856
|
w.fork();
|
23999
23857
|
}
|
24000
|
-
if ((obj.
|
23858
|
+
if ((obj.requestId != null && obj.requestId !== '')) {
|
24001
23859
|
w.uint32(10);
|
24002
|
-
w.string(obj.
|
23860
|
+
w.string(obj.requestId);
|
24003
23861
|
}
|
24004
|
-
if (
|
24005
|
-
w.
|
23862
|
+
if ((obj.includeData != null && obj.includeData !== false)) {
|
23863
|
+
w.uint32(16);
|
23864
|
+
w.bool(obj.includeData);
|
24006
23865
|
}
|
24007
|
-
|
24008
|
-
|
24009
|
-
|
24010
|
-
}
|
24011
|
-
|
24012
|
-
|
24013
|
-
|
24014
|
-
|
24015
|
-
case 1: {
|
24016
|
-
obj.contentTopic = reader.string();
|
24017
|
-
break;
|
24018
|
-
}
|
24019
|
-
default: {
|
24020
|
-
reader.skipType(tag & 7);
|
24021
|
-
break;
|
24022
|
-
}
|
23866
|
+
if (obj.pubsubTopic != null) {
|
23867
|
+
w.uint32(82);
|
23868
|
+
w.string(obj.pubsubTopic);
|
23869
|
+
}
|
23870
|
+
if (obj.contentTopics != null) {
|
23871
|
+
for (const value of obj.contentTopics) {
|
23872
|
+
w.uint32(90);
|
23873
|
+
w.string(value);
|
24023
23874
|
}
|
24024
23875
|
}
|
24025
|
-
|
24026
|
-
|
24027
|
-
|
24028
|
-
return _codec;
|
24029
|
-
};
|
24030
|
-
ContentFilter.encode = (obj) => {
|
24031
|
-
return encodeMessage(obj, ContentFilter.codec());
|
24032
|
-
};
|
24033
|
-
ContentFilter.decode = (buf, opts) => {
|
24034
|
-
return decodeMessage(buf, ContentFilter.codec(), opts);
|
24035
|
-
};
|
24036
|
-
})(ContentFilter || (ContentFilter = {}));
|
24037
|
-
var HistoryQuery;
|
24038
|
-
(function (HistoryQuery) {
|
24039
|
-
let _codec;
|
24040
|
-
HistoryQuery.codec = () => {
|
24041
|
-
if (_codec == null) {
|
24042
|
-
_codec = message((obj, w, opts = {}) => {
|
24043
|
-
if (opts.lengthDelimited !== false) {
|
24044
|
-
w.fork();
|
23876
|
+
if (obj.timeStart != null) {
|
23877
|
+
w.uint32(96);
|
23878
|
+
w.sint64(obj.timeStart);
|
24045
23879
|
}
|
24046
|
-
if (obj.
|
24047
|
-
w.uint32(
|
24048
|
-
w.
|
23880
|
+
if (obj.timeEnd != null) {
|
23881
|
+
w.uint32(104);
|
23882
|
+
w.sint64(obj.timeEnd);
|
24049
23883
|
}
|
24050
|
-
if (obj.
|
24051
|
-
for (const value of obj.
|
24052
|
-
w.uint32(
|
24053
|
-
|
23884
|
+
if (obj.messageHashes != null) {
|
23885
|
+
for (const value of obj.messageHashes) {
|
23886
|
+
w.uint32(162);
|
23887
|
+
w.bytes(value);
|
24054
23888
|
}
|
24055
23889
|
}
|
24056
|
-
if (obj.
|
24057
|
-
w.uint32(
|
24058
|
-
|
23890
|
+
if (obj.paginationCursor != null) {
|
23891
|
+
w.uint32(410);
|
23892
|
+
w.bytes(obj.paginationCursor);
|
24059
23893
|
}
|
24060
|
-
if (obj.
|
24061
|
-
w.uint32(
|
24062
|
-
w.
|
23894
|
+
if ((obj.paginationForward != null && obj.paginationForward !== false)) {
|
23895
|
+
w.uint32(416);
|
23896
|
+
w.bool(obj.paginationForward);
|
24063
23897
|
}
|
24064
|
-
if (obj.
|
24065
|
-
w.uint32(
|
24066
|
-
w.
|
23898
|
+
if (obj.paginationLimit != null) {
|
23899
|
+
w.uint32(424);
|
23900
|
+
w.uint64(obj.paginationLimit);
|
24067
23901
|
}
|
24068
23902
|
if (opts.lengthDelimited !== false) {
|
24069
23903
|
w.ldelim();
|
24070
23904
|
}
|
24071
23905
|
}, (reader, length, opts = {}) => {
|
24072
23906
|
const obj = {
|
24073
|
-
|
23907
|
+
requestId: '',
|
23908
|
+
includeData: false,
|
23909
|
+
contentTopics: [],
|
23910
|
+
messageHashes: [],
|
23911
|
+
paginationForward: false
|
24074
23912
|
};
|
24075
23913
|
const end = length == null ? reader.len : reader.pos + length;
|
24076
23914
|
while (reader.pos < end) {
|
24077
23915
|
const tag = reader.uint32();
|
24078
23916
|
switch (tag >>> 3) {
|
24079
|
-
case
|
24080
|
-
obj.
|
23917
|
+
case 1: {
|
23918
|
+
obj.requestId = reader.string();
|
24081
23919
|
break;
|
24082
23920
|
}
|
24083
|
-
case
|
24084
|
-
|
24085
|
-
throw new CodeError('decode error - map field "contentFilters" had too many elements', 'ERR_MAX_LENGTH');
|
24086
|
-
}
|
24087
|
-
obj.contentFilters.push(ContentFilter.codec().decode(reader, reader.uint32(), {
|
24088
|
-
limits: opts.limits?.contentFilters$
|
24089
|
-
}));
|
23921
|
+
case 2: {
|
23922
|
+
obj.includeData = reader.bool();
|
24090
23923
|
break;
|
24091
23924
|
}
|
24092
|
-
case
|
24093
|
-
obj.
|
24094
|
-
limits: opts.limits?.pagingInfo
|
24095
|
-
});
|
23925
|
+
case 10: {
|
23926
|
+
obj.pubsubTopic = reader.string();
|
24096
23927
|
break;
|
24097
23928
|
}
|
24098
|
-
case
|
24099
|
-
obj.
|
23929
|
+
case 11: {
|
23930
|
+
if (opts.limits?.contentTopics != null && obj.contentTopics.length === opts.limits.contentTopics) {
|
23931
|
+
throw new MaxLengthError('Decode error - map field "contentTopics" had too many elements');
|
23932
|
+
}
|
23933
|
+
obj.contentTopics.push(reader.string());
|
24100
23934
|
break;
|
24101
23935
|
}
|
24102
|
-
case
|
24103
|
-
obj.
|
23936
|
+
case 12: {
|
23937
|
+
obj.timeStart = reader.sint64();
|
24104
23938
|
break;
|
24105
23939
|
}
|
24106
|
-
|
24107
|
-
reader.
|
23940
|
+
case 13: {
|
23941
|
+
obj.timeEnd = reader.sint64();
|
24108
23942
|
break;
|
24109
23943
|
}
|
24110
|
-
|
24111
|
-
|
24112
|
-
|
24113
|
-
});
|
24114
|
-
}
|
24115
|
-
return _codec;
|
24116
|
-
};
|
24117
|
-
HistoryQuery.encode = (obj) => {
|
24118
|
-
return encodeMessage(obj, HistoryQuery.codec());
|
24119
|
-
};
|
24120
|
-
HistoryQuery.decode = (buf, opts) => {
|
24121
|
-
return decodeMessage(buf, HistoryQuery.codec(), opts);
|
24122
|
-
};
|
24123
|
-
})(HistoryQuery || (HistoryQuery = {}));
|
24124
|
-
var HistoryResponse;
|
24125
|
-
(function (HistoryResponse) {
|
24126
|
-
let HistoryError;
|
24127
|
-
(function (HistoryError) {
|
24128
|
-
HistoryError["NONE"] = "NONE";
|
24129
|
-
HistoryError["INVALID_CURSOR"] = "INVALID_CURSOR";
|
24130
|
-
HistoryError["TOO_MANY_REQUESTS"] = "TOO_MANY_REQUESTS";
|
24131
|
-
HistoryError["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
|
24132
|
-
})(HistoryError = HistoryResponse.HistoryError || (HistoryResponse.HistoryError = {}));
|
24133
|
-
let __HistoryErrorValues;
|
24134
|
-
(function (__HistoryErrorValues) {
|
24135
|
-
__HistoryErrorValues[__HistoryErrorValues["NONE"] = 0] = "NONE";
|
24136
|
-
__HistoryErrorValues[__HistoryErrorValues["INVALID_CURSOR"] = 1] = "INVALID_CURSOR";
|
24137
|
-
__HistoryErrorValues[__HistoryErrorValues["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
|
24138
|
-
__HistoryErrorValues[__HistoryErrorValues["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
|
24139
|
-
})(__HistoryErrorValues || (__HistoryErrorValues = {}));
|
24140
|
-
(function (HistoryError) {
|
24141
|
-
HistoryError.codec = () => {
|
24142
|
-
return enumeration(__HistoryErrorValues);
|
24143
|
-
};
|
24144
|
-
})(HistoryError = HistoryResponse.HistoryError || (HistoryResponse.HistoryError = {}));
|
24145
|
-
let _codec;
|
24146
|
-
HistoryResponse.codec = () => {
|
24147
|
-
if (_codec == null) {
|
24148
|
-
_codec = message((obj, w, opts = {}) => {
|
24149
|
-
if (opts.lengthDelimited !== false) {
|
24150
|
-
w.fork();
|
24151
|
-
}
|
24152
|
-
if (obj.messages != null) {
|
24153
|
-
for (const value of obj.messages) {
|
24154
|
-
w.uint32(18);
|
24155
|
-
WakuMessage.codec().encode(value, w);
|
24156
|
-
}
|
24157
|
-
}
|
24158
|
-
if (obj.pagingInfo != null) {
|
24159
|
-
w.uint32(26);
|
24160
|
-
PagingInfo.codec().encode(obj.pagingInfo, w);
|
24161
|
-
}
|
24162
|
-
if (obj.error != null && __HistoryErrorValues[obj.error] !== 0) {
|
24163
|
-
w.uint32(32);
|
24164
|
-
HistoryResponse.HistoryError.codec().encode(obj.error, w);
|
24165
|
-
}
|
24166
|
-
if (opts.lengthDelimited !== false) {
|
24167
|
-
w.ldelim();
|
24168
|
-
}
|
24169
|
-
}, (reader, length, opts = {}) => {
|
24170
|
-
const obj = {
|
24171
|
-
messages: [],
|
24172
|
-
error: HistoryError.NONE
|
24173
|
-
};
|
24174
|
-
const end = length == null ? reader.len : reader.pos + length;
|
24175
|
-
while (reader.pos < end) {
|
24176
|
-
const tag = reader.uint32();
|
24177
|
-
switch (tag >>> 3) {
|
24178
|
-
case 2: {
|
24179
|
-
if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
|
24180
|
-
throw new CodeError('decode error - map field "messages" had too many elements', 'ERR_MAX_LENGTH');
|
23944
|
+
case 20: {
|
23945
|
+
if (opts.limits?.messageHashes != null && obj.messageHashes.length === opts.limits.messageHashes) {
|
23946
|
+
throw new MaxLengthError('Decode error - map field "messageHashes" had too many elements');
|
24181
23947
|
}
|
24182
|
-
obj.
|
24183
|
-
limits: opts.limits?.messages$
|
24184
|
-
}));
|
23948
|
+
obj.messageHashes.push(reader.bytes());
|
24185
23949
|
break;
|
24186
23950
|
}
|
24187
|
-
case
|
24188
|
-
obj.
|
24189
|
-
limits: opts.limits?.pagingInfo
|
24190
|
-
});
|
23951
|
+
case 51: {
|
23952
|
+
obj.paginationCursor = reader.bytes();
|
24191
23953
|
break;
|
24192
23954
|
}
|
24193
|
-
case
|
24194
|
-
obj.
|
23955
|
+
case 52: {
|
23956
|
+
obj.paginationForward = reader.bool();
|
23957
|
+
break;
|
23958
|
+
}
|
23959
|
+
case 53: {
|
23960
|
+
obj.paginationLimit = reader.uint64();
|
24195
23961
|
break;
|
24196
23962
|
}
|
24197
23963
|
default: {
|
@@ -24205,17 +23971,17 @@ var HistoryResponse;
|
|
24205
23971
|
}
|
24206
23972
|
return _codec;
|
24207
23973
|
};
|
24208
|
-
|
24209
|
-
return encodeMessage(obj,
|
23974
|
+
StoreQueryRequest.encode = (obj) => {
|
23975
|
+
return encodeMessage(obj, StoreQueryRequest.codec());
|
24210
23976
|
};
|
24211
|
-
|
24212
|
-
return decodeMessage(buf,
|
23977
|
+
StoreQueryRequest.decode = (buf, opts) => {
|
23978
|
+
return decodeMessage(buf, StoreQueryRequest.codec(), opts);
|
24213
23979
|
};
|
24214
|
-
})(
|
24215
|
-
var
|
24216
|
-
(function (
|
23980
|
+
})(StoreQueryRequest || (StoreQueryRequest = {}));
|
23981
|
+
var StoreQueryResponse;
|
23982
|
+
(function (StoreQueryResponse) {
|
24217
23983
|
let _codec;
|
24218
|
-
|
23984
|
+
StoreQueryResponse.codec = () => {
|
24219
23985
|
if (_codec == null) {
|
24220
23986
|
_codec = message((obj, w, opts = {}) => {
|
24221
23987
|
if (opts.lengthDelimited !== false) {
|
@@ -24225,20 +23991,31 @@ var HistoryRpc;
|
|
24225
23991
|
w.uint32(10);
|
24226
23992
|
w.string(obj.requestId);
|
24227
23993
|
}
|
24228
|
-
if (obj.
|
24229
|
-
w.uint32(
|
24230
|
-
|
23994
|
+
if (obj.statusCode != null) {
|
23995
|
+
w.uint32(80);
|
23996
|
+
w.uint32(obj.statusCode);
|
24231
23997
|
}
|
24232
|
-
if (obj.
|
24233
|
-
w.uint32(
|
24234
|
-
|
23998
|
+
if (obj.statusDesc != null) {
|
23999
|
+
w.uint32(90);
|
24000
|
+
w.string(obj.statusDesc);
|
24001
|
+
}
|
24002
|
+
if (obj.messages != null) {
|
24003
|
+
for (const value of obj.messages) {
|
24004
|
+
w.uint32(162);
|
24005
|
+
WakuMessageKeyValue.codec().encode(value, w);
|
24006
|
+
}
|
24007
|
+
}
|
24008
|
+
if (obj.paginationCursor != null) {
|
24009
|
+
w.uint32(410);
|
24010
|
+
w.bytes(obj.paginationCursor);
|
24235
24011
|
}
|
24236
24012
|
if (opts.lengthDelimited !== false) {
|
24237
24013
|
w.ldelim();
|
24238
24014
|
}
|
24239
24015
|
}, (reader, length, opts = {}) => {
|
24240
24016
|
const obj = {
|
24241
|
-
requestId: ''
|
24017
|
+
requestId: '',
|
24018
|
+
messages: []
|
24242
24019
|
};
|
24243
24020
|
const end = length == null ? reader.len : reader.pos + length;
|
24244
24021
|
while (reader.pos < end) {
|
@@ -24248,16 +24025,25 @@ var HistoryRpc;
|
|
24248
24025
|
obj.requestId = reader.string();
|
24249
24026
|
break;
|
24250
24027
|
}
|
24251
|
-
case
|
24252
|
-
obj.
|
24253
|
-
limits: opts.limits?.query
|
24254
|
-
});
|
24028
|
+
case 10: {
|
24029
|
+
obj.statusCode = reader.uint32();
|
24255
24030
|
break;
|
24256
24031
|
}
|
24257
|
-
case
|
24258
|
-
obj.
|
24259
|
-
|
24260
|
-
|
24032
|
+
case 11: {
|
24033
|
+
obj.statusDesc = reader.string();
|
24034
|
+
break;
|
24035
|
+
}
|
24036
|
+
case 20: {
|
24037
|
+
if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
|
24038
|
+
throw new MaxLengthError('Decode error - map field "messages" had too many elements');
|
24039
|
+
}
|
24040
|
+
obj.messages.push(WakuMessageKeyValue.codec().decode(reader, reader.uint32(), {
|
24041
|
+
limits: opts.limits?.messages$
|
24042
|
+
}));
|
24043
|
+
break;
|
24044
|
+
}
|
24045
|
+
case 51: {
|
24046
|
+
obj.paginationCursor = reader.bytes();
|
24261
24047
|
break;
|
24262
24048
|
}
|
24263
24049
|
default: {
|
@@ -24271,13 +24057,13 @@ var HistoryRpc;
|
|
24271
24057
|
}
|
24272
24058
|
return _codec;
|
24273
24059
|
};
|
24274
|
-
|
24275
|
-
return encodeMessage(obj,
|
24060
|
+
StoreQueryResponse.encode = (obj) => {
|
24061
|
+
return encodeMessage(obj, StoreQueryResponse.codec());
|
24276
24062
|
};
|
24277
|
-
|
24278
|
-
return decodeMessage(buf,
|
24063
|
+
StoreQueryResponse.decode = (buf, opts) => {
|
24064
|
+
return decodeMessage(buf, StoreQueryResponse.codec(), opts);
|
24279
24065
|
};
|
24280
|
-
})(
|
24066
|
+
})(StoreQueryResponse || (StoreQueryResponse = {}));
|
24281
24067
|
var RateLimitProof;
|
24282
24068
|
(function (RateLimitProof) {
|
24283
24069
|
let _codec;
|
@@ -24597,7 +24383,7 @@ var PeerExchangeResponse;
|
|
24597
24383
|
switch (tag >>> 3) {
|
24598
24384
|
case 1: {
|
24599
24385
|
if (opts.limits?.peerInfos != null && obj.peerInfos.length === opts.limits.peerInfos) {
|
24600
|
-
throw new
|
24386
|
+
throw new MaxLengthError('Decode error - map field "peerInfos" had too many elements');
|
24601
24387
|
}
|
24602
24388
|
obj.peerInfos.push(PeerInfo.codec().decode(reader, reader.uint32(), {
|
24603
24389
|
limits: opts.limits?.peerInfos$
|
@@ -24720,7 +24506,7 @@ var WakuMetadataRequest;
|
|
24720
24506
|
}
|
24721
24507
|
case 2: {
|
24722
24508
|
if (opts.limits?.shards != null && obj.shards.length === opts.limits.shards) {
|
24723
|
-
throw new
|
24509
|
+
throw new MaxLengthError('Decode error - map field "shards" had too many elements');
|
24724
24510
|
}
|
24725
24511
|
obj.shards.push(reader.uint32());
|
24726
24512
|
break;
|
@@ -24779,7 +24565,7 @@ var WakuMetadataResponse;
|
|
24779
24565
|
}
|
24780
24566
|
case 2: {
|
24781
24567
|
if (opts.limits?.shards != null && obj.shards.length === opts.limits.shards) {
|
24782
|
-
throw new
|
24568
|
+
throw new MaxLengthError('Decode error - map field "shards" had too many elements');
|
24783
24569
|
}
|
24784
24570
|
obj.shards.push(reader.uint32());
|
24785
24571
|
break;
|
@@ -24859,11 +24645,11 @@ class WakuPeerExchange extends BaseProtocol {
|
|
24859
24645
|
* Make a peer exchange query to a peer
|
24860
24646
|
*/
|
24861
24647
|
async query(params) {
|
24862
|
-
const { numPeers } = params;
|
24648
|
+
const { numPeers, peerId } = params;
|
24863
24649
|
const rpcQuery = PeerExchangeRPC.createRequest({
|
24864
24650
|
numPeers: BigInt(numPeers)
|
24865
24651
|
});
|
24866
|
-
const peer = await this.peerStore.get(
|
24652
|
+
const peer = await this.peerStore.get(peerId);
|
24867
24653
|
if (!peer) {
|
24868
24654
|
return {
|
24869
24655
|
peerInfos: null,
|
@@ -25019,7 +24805,31 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
|
|
25019
24805
|
}
|
25020
24806
|
const hasPeer = await this.components.peerStore.has(peerId);
|
25021
24807
|
if (hasPeer) {
|
25022
|
-
|
24808
|
+
const { hasMultiaddrDiff, hasShardDiff } = await this.checkPeerInfoDiff(peerInfo, shardInfo);
|
24809
|
+
if (hasMultiaddrDiff || hasShardDiff) {
|
24810
|
+
log$1.info(`Peer ${peerId.toString()} has updated multiaddrs or shardInfo, updating`);
|
24811
|
+
if (hasMultiaddrDiff) {
|
24812
|
+
log$1.info(`Peer ${peerId.toString()} has updated multiaddrs, updating`);
|
24813
|
+
await this.components.peerStore.patch(peerId, {
|
24814
|
+
multiaddrs: peerInfo.multiaddrs
|
24815
|
+
});
|
24816
|
+
}
|
24817
|
+
if (hasShardDiff && shardInfo) {
|
24818
|
+
log$1.info(`Peer ${peerId.toString()} has updated shardInfo, updating`);
|
24819
|
+
await this.components.peerStore.merge(peerId, {
|
24820
|
+
metadata: {
|
24821
|
+
shardInfo: encodeRelayShard(shardInfo)
|
24822
|
+
}
|
24823
|
+
});
|
24824
|
+
this.dispatchEvent(new CustomEvent("peer", {
|
24825
|
+
detail: {
|
24826
|
+
id: peerId,
|
24827
|
+
multiaddrs: peerInfo.multiaddrs
|
24828
|
+
}
|
24829
|
+
}));
|
24830
|
+
}
|
24831
|
+
continue;
|
24832
|
+
}
|
25023
24833
|
}
|
25024
24834
|
// update the tags for the peer
|
25025
24835
|
await this.components.peerStore.save(peerId, {
|
@@ -25033,6 +24843,9 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
|
|
25033
24843
|
metadata: {
|
25034
24844
|
shardInfo: encodeRelayShard(shardInfo)
|
25035
24845
|
}
|
24846
|
+
}),
|
24847
|
+
...(peerInfo.multiaddrs && {
|
24848
|
+
multiaddrs: peerInfo.multiaddrs
|
25036
24849
|
})
|
25037
24850
|
});
|
25038
24851
|
log$1.info(`Discovered peer: ${peerId.toString()}`);
|
@@ -25050,6 +24863,24 @@ class PeerExchangeDiscovery extends TypedEventEmitter {
|
|
25050
24863
|
this.queryingPeers.delete(peerIdStr);
|
25051
24864
|
this.queryAttempts.delete(peerIdStr);
|
25052
24865
|
}
|
24866
|
+
async checkPeerInfoDiff(peerInfo, shardInfo) {
|
24867
|
+
const { id: peerId } = peerInfo;
|
24868
|
+
const peer = await this.components.peerStore.get(peerId);
|
24869
|
+
const existingMultiaddrs = peer.addresses.map((a) => a.multiaddr.toString());
|
24870
|
+
const newMultiaddrs = peerInfo.multiaddrs.map((ma) => ma.toString());
|
24871
|
+
const hasMultiaddrDiff = existingMultiaddrs.some((ma) => !newMultiaddrs.includes(ma));
|
24872
|
+
let hasShardDiff = false;
|
24873
|
+
const existingShardInfoBytes = peer.metadata.get("shardInfo");
|
24874
|
+
if (existingShardInfoBytes) {
|
24875
|
+
const existingShardInfo = decodeRelayShard(existingShardInfoBytes);
|
24876
|
+
if (existingShardInfo || shardInfo) {
|
24877
|
+
hasShardDiff =
|
24878
|
+
existingShardInfo.clusterId !== shardInfo?.clusterId ||
|
24879
|
+
existingShardInfo.shards.some((shard) => !shardInfo?.shards.includes(shard));
|
24880
|
+
}
|
24881
|
+
}
|
24882
|
+
return { hasMultiaddrDiff, hasShardDiff };
|
24883
|
+
}
|
25053
24884
|
}
|
25054
24885
|
function wakuPeerExchangeDiscovery(pubsubTopics) {
|
25055
24886
|
return (components) => new PeerExchangeDiscovery(components, pubsubTopics);
|
@@ -25095,7 +24926,13 @@ async function createFromParts(multihash, privKey, pubKey) {
|
|
25095
24926
|
const key = unmarshalPublicKey(pubKey);
|
25096
24927
|
return createFromPubKey(key);
|
25097
24928
|
}
|
25098
|
-
|
24929
|
+
const peerId = peerIdFromBytes(multihash);
|
24930
|
+
if (peerId.type !== 'Ed25519' && peerId.type !== 'secp256k1' && peerId.type !== 'RSA') {
|
24931
|
+
// should not be possible since `multihash` is derived from keys and these
|
24932
|
+
// are the cryptographic peer id types
|
24933
|
+
throw new Error('Supplied PeerID is invalid');
|
24934
|
+
}
|
24935
|
+
return peerId;
|
25099
24936
|
}
|
25100
24937
|
|
25101
24938
|
const log = new Logger$1("peer-exchange-discovery");
|