@waku/enr 0.0.25-ce62600.0 → 0.0.25-f387f59.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 +343 -232
- package/dist/.tsbuildinfo +1 -1
- package/dist/creator.js.map +1 -1
- package/dist/decoder.js.map +1 -1
- package/dist/encoder.js.map +1 -1
- package/dist/enr.js.map +1 -1
- package/dist/peer_id.js +3 -0
- package/dist/peer_id.js.map +1 -1
- package/dist/raw_enr.js.map +1 -1
- package/package.json +1 -1
- package/src/creator.ts +2 -2
- package/src/decoder.ts +2 -2
- package/src/encoder.ts +9 -3
- package/src/enr.ts +14 -11
- package/src/peer_id.ts +4 -0
- package/src/raw_enr.ts +21 -21
package/bundle/index.js
CHANGED
@@ -1338,7 +1338,7 @@ const _0n$5 = BigInt(0);
|
|
1338
1338
|
const _1n$7 = BigInt(1);
|
1339
1339
|
const _2n$5 = BigInt(2);
|
1340
1340
|
const _3n$2 = BigInt(3);
|
1341
|
-
const _8n$
|
1341
|
+
const _8n$3 = BigInt(8);
|
1342
1342
|
const CURVE = Object.freeze({
|
1343
1343
|
a: _0n$5,
|
1344
1344
|
b: BigInt(7),
|
@@ -1442,7 +1442,7 @@ class JacobianPoint {
|
|
1442
1442
|
const E = mod$1(_3n$2 * A);
|
1443
1443
|
const F = mod$1(E * E);
|
1444
1444
|
const X3 = mod$1(F - _2n$5 * D);
|
1445
|
-
const Y3 = mod$1(E * (D - X3) - _8n$
|
1445
|
+
const Y3 = mod$1(E * (D - X3) - _8n$3 * C);
|
1446
1446
|
const Z3 = mod$1(_2n$5 * Y1 * Z1);
|
1447
1447
|
return new JacobianPoint(X3, Y3, Z3);
|
1448
1448
|
}
|
@@ -1542,12 +1542,12 @@ class JacobianPoint {
|
|
1542
1542
|
if (256 % W) {
|
1543
1543
|
throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
|
1544
1544
|
}
|
1545
|
-
let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
|
1545
|
+
let precomputes = affinePoint && pointPrecomputes$1.get(affinePoint);
|
1546
1546
|
if (!precomputes) {
|
1547
1547
|
precomputes = this.precomputeWindow(W);
|
1548
1548
|
if (affinePoint && W !== 1) {
|
1549
1549
|
precomputes = JacobianPoint.normalizeZ(precomputes);
|
1550
|
-
pointPrecomputes.set(affinePoint, precomputes);
|
1550
|
+
pointPrecomputes$1.set(affinePoint, precomputes);
|
1551
1551
|
}
|
1552
1552
|
}
|
1553
1553
|
let p = JacobianPoint.ZERO;
|
@@ -1603,7 +1603,7 @@ class JacobianPoint {
|
|
1603
1603
|
const { x, y, z } = this;
|
1604
1604
|
const is0 = this.equals(JacobianPoint.ZERO);
|
1605
1605
|
if (invZ == null)
|
1606
|
-
invZ = is0 ? _8n$
|
1606
|
+
invZ = is0 ? _8n$3 : invert$1(z);
|
1607
1607
|
const iz1 = invZ;
|
1608
1608
|
const iz2 = mod$1(iz1 * iz1);
|
1609
1609
|
const iz3 = mod$1(iz2 * iz1);
|
@@ -1623,7 +1623,7 @@ function constTimeNegate(condition, item) {
|
|
1623
1623
|
const neg = item.negate();
|
1624
1624
|
return condition ? neg : item;
|
1625
1625
|
}
|
1626
|
-
const pointPrecomputes = new WeakMap();
|
1626
|
+
const pointPrecomputes$1 = new WeakMap();
|
1627
1627
|
class Point {
|
1628
1628
|
constructor(x, y) {
|
1629
1629
|
this.x = x;
|
@@ -1631,7 +1631,7 @@ class Point {
|
|
1631
1631
|
}
|
1632
1632
|
_setWindowSize(windowSize) {
|
1633
1633
|
this._WINDOW_SIZE = windowSize;
|
1634
|
-
pointPrecomputes.delete(this);
|
1634
|
+
pointPrecomputes$1.delete(this);
|
1635
1635
|
}
|
1636
1636
|
hasEvenY() {
|
1637
1637
|
return this.y % _2n$5 === _0n$5;
|
@@ -3477,6 +3477,11 @@ var ProtocolError;
|
|
3477
3477
|
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
3478
3478
|
*/
|
3479
3479
|
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
3480
|
+
/**
|
3481
|
+
* The topics passed in the decoders do not match each other, or don't exist at all.
|
3482
|
+
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
3483
|
+
*/
|
3484
|
+
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
3480
3485
|
/**
|
3481
3486
|
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
3482
3487
|
* Mitigation can be: retrying after a given time period, display connectivity issue
|
@@ -3507,12 +3512,6 @@ var ProtocolError;
|
|
3507
3512
|
ProtocolError["REQUEST_TIMEOUT"] = "Request timeout";
|
3508
3513
|
})(ProtocolError || (ProtocolError = {}));
|
3509
3514
|
|
3510
|
-
var PageDirection;
|
3511
|
-
(function (PageDirection) {
|
3512
|
-
PageDirection["BACKWARD"] = "backward";
|
3513
|
-
PageDirection["FORWARD"] = "forward";
|
3514
|
-
})(PageDirection || (PageDirection = {}));
|
3515
|
-
|
3516
3515
|
var Tags;
|
3517
3516
|
(function (Tags) {
|
3518
3517
|
Tags["BOOTSTRAP"] = "bootstrap";
|
@@ -3531,6 +3530,13 @@ var EConnectionStateEvents;
|
|
3531
3530
|
EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
|
3532
3531
|
})(EConnectionStateEvents || (EConnectionStateEvents = {}));
|
3533
3532
|
|
3533
|
+
var HealthStatus;
|
3534
|
+
(function (HealthStatus) {
|
3535
|
+
HealthStatus["Unhealthy"] = "Unhealthy";
|
3536
|
+
HealthStatus["MinimallyHealthy"] = "MinimallyHealthy";
|
3537
|
+
HealthStatus["SufficientlyHealthy"] = "SufficientlyHealthy";
|
3538
|
+
})(HealthStatus || (HealthStatus = {}));
|
3539
|
+
|
3534
3540
|
const decodeRelayShard = (bytes) => {
|
3535
3541
|
// explicitly converting to Uint8Array to avoid Buffer
|
3536
3542
|
// https://github.com/libp2p/js-libp2p/issues/2146
|
@@ -4137,6 +4143,8 @@ var common = setup;
|
|
4137
4143
|
return false;
|
4138
4144
|
}
|
4139
4145
|
|
4146
|
+
let m;
|
4147
|
+
|
4140
4148
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
4141
4149
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
4142
4150
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
@@ -4144,7 +4152,7 @@ var common = setup;
|
|
4144
4152
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
4145
4153
|
// Is firefox >= v31?
|
4146
4154
|
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
4147
|
-
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(
|
4155
|
+
(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
|
4148
4156
|
// Double check webkit in userAgent just in case we are in a worker
|
4149
4157
|
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
4150
4158
|
}
|
@@ -4981,6 +4989,7 @@ const table = [
|
|
4981
4989
|
[478, 0, 'wss'],
|
4982
4990
|
[479, 0, 'p2p-websocket-star'],
|
4983
4991
|
[480, 0, 'http'],
|
4992
|
+
[481, V, 'http-path'],
|
4984
4993
|
[777, V, 'memory']
|
4985
4994
|
];
|
4986
4995
|
// populate tables
|
@@ -5066,6 +5075,8 @@ function convertToString(proto, buf) {
|
|
5066
5075
|
return bytes2onion(buf);
|
5067
5076
|
case 466: // certhash
|
5068
5077
|
return bytes2mb(buf);
|
5078
|
+
case 481: // http-path
|
5079
|
+
return globalThis.encodeURIComponent(bytes2str(buf));
|
5069
5080
|
default:
|
5070
5081
|
return toString$1(buf, 'base16'); // no clue. convert to hex
|
5071
5082
|
}
|
@@ -5100,6 +5111,8 @@ function convertToBytes(proto, str) {
|
|
5100
5111
|
return onion32bytes(str);
|
5101
5112
|
case 466: // certhash
|
5102
5113
|
return mb2bytes(str);
|
5114
|
+
case 481: // http-path
|
5115
|
+
return str2bytes(globalThis.decodeURIComponent(str));
|
5103
5116
|
default:
|
5104
5117
|
return fromString(str, 'base16'); // no clue. convert from hex
|
5105
5118
|
}
|
@@ -6004,9 +6017,9 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
|
6004
6017
|
// This is OK: `abstract` directory does not use noble-hashes.
|
6005
6018
|
// User may opt-in into using different hashing library. This way, noble-hashes
|
6006
6019
|
// won't be included into their bundle.
|
6007
|
-
const _0n$4 = BigInt(0);
|
6008
|
-
const _1n$6 = BigInt(1);
|
6009
|
-
const _2n$4 = BigInt(2);
|
6020
|
+
const _0n$4 = /* @__PURE__ */ BigInt(0);
|
6021
|
+
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
6022
|
+
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
6010
6023
|
function isBytes$1(a) {
|
6011
6024
|
return (a instanceof Uint8Array ||
|
6012
6025
|
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
@@ -6015,6 +6028,10 @@ function abytes(item) {
|
|
6015
6028
|
if (!isBytes$1(item))
|
6016
6029
|
throw new Error('Uint8Array expected');
|
6017
6030
|
}
|
6031
|
+
function abool(title, value) {
|
6032
|
+
if (typeof value !== 'boolean')
|
6033
|
+
throw new Error(`${title} must be valid boolean, got "${value}".`);
|
6034
|
+
}
|
6018
6035
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6019
6036
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
6020
6037
|
/**
|
@@ -6157,6 +6174,25 @@ function utf8ToBytes(str) {
|
|
6157
6174
|
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
6158
6175
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6159
6176
|
}
|
6177
|
+
// Is positive bigint
|
6178
|
+
const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
|
6179
|
+
function inRange(n, min, max) {
|
6180
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
6181
|
+
}
|
6182
|
+
/**
|
6183
|
+
* Asserts min <= n < max. NOTE: It's < max and not <= max.
|
6184
|
+
* @example
|
6185
|
+
* aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)
|
6186
|
+
*/
|
6187
|
+
function aInRange(title, n, min, max) {
|
6188
|
+
// Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?
|
6189
|
+
// consider P=256n, min=0n, max=P
|
6190
|
+
// - a for min=0 would require -1: `inRange('x', x, -1n, P)`
|
6191
|
+
// - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
|
6192
|
+
// - our way is the cleanest: `inRange('x', x, 0n, P)
|
6193
|
+
if (!inRange(n, min, max))
|
6194
|
+
throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
|
6195
|
+
}
|
6160
6196
|
// Bit operations
|
6161
6197
|
/**
|
6162
6198
|
* Calculates amount of bits in a bigint.
|
@@ -6287,9 +6323,32 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6287
6323
|
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
6288
6324
|
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
6289
6325
|
// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
|
6326
|
+
/**
|
6327
|
+
* throws not implemented error
|
6328
|
+
*/
|
6329
|
+
const notImplemented = () => {
|
6330
|
+
throw new Error('not implemented');
|
6331
|
+
};
|
6332
|
+
/**
|
6333
|
+
* Memoizes (caches) computation result.
|
6334
|
+
* Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
|
6335
|
+
*/
|
6336
|
+
function memoized(fn) {
|
6337
|
+
const map = new WeakMap();
|
6338
|
+
return (arg, ...args) => {
|
6339
|
+
const val = map.get(arg);
|
6340
|
+
if (val !== undefined)
|
6341
|
+
return val;
|
6342
|
+
const computed = fn(arg, ...args);
|
6343
|
+
map.set(arg, computed);
|
6344
|
+
return computed;
|
6345
|
+
};
|
6346
|
+
}
|
6290
6347
|
|
6291
6348
|
var ut = /*#__PURE__*/Object.freeze({
|
6292
6349
|
__proto__: null,
|
6350
|
+
aInRange: aInRange,
|
6351
|
+
abool: abool,
|
6293
6352
|
abytes: abytes,
|
6294
6353
|
bitGet: bitGet,
|
6295
6354
|
bitLen: bitLen,
|
@@ -6304,7 +6363,10 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6304
6363
|
equalBytes: equalBytes,
|
6305
6364
|
hexToBytes: hexToBytes,
|
6306
6365
|
hexToNumber: hexToNumber,
|
6366
|
+
inRange: inRange,
|
6307
6367
|
isBytes: isBytes$1,
|
6368
|
+
memoized: memoized,
|
6369
|
+
notImplemented: notImplemented,
|
6308
6370
|
numberToBytesBE: numberToBytesBE,
|
6309
6371
|
numberToBytesLE: numberToBytesLE,
|
6310
6372
|
numberToHexUnpadded: numberToHexUnpadded,
|
@@ -6318,7 +6380,7 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6318
6380
|
// prettier-ignore
|
6319
6381
|
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
|
6320
6382
|
// prettier-ignore
|
6321
|
-
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$
|
6383
|
+
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
|
6322
6384
|
// prettier-ignore
|
6323
6385
|
BigInt(9); BigInt(16);
|
6324
6386
|
// Calculates a modulo b
|
@@ -6464,8 +6526,8 @@ function FpSqrt(P) {
|
|
6464
6526
|
};
|
6465
6527
|
}
|
6466
6528
|
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
6467
|
-
if (P % _8n$
|
6468
|
-
const c1 = (P - _5n$1) / _8n$
|
6529
|
+
if (P % _8n$2 === _5n$1) {
|
6530
|
+
const c1 = (P - _5n$1) / _8n$2;
|
6469
6531
|
return function sqrt5mod8(Fp, n) {
|
6470
6532
|
const n2 = Fp.mul(n, _2n$3);
|
6471
6533
|
const v = Fp.pow(n2, c1);
|
@@ -6563,6 +6625,9 @@ function nLength(n, nBitLength) {
|
|
6563
6625
|
* * a) denormalized operations like mulN instead of mul
|
6564
6626
|
* * b) same object shape: never add or remove keys
|
6565
6627
|
* * c) Object.freeze
|
6628
|
+
* NOTE: operations don't check 'isValid' for all elements for performance reasons,
|
6629
|
+
* it is caller responsibility to check this.
|
6630
|
+
* This is low-level code, please make sure you know what you doing.
|
6566
6631
|
* @param ORDER prime positive bigint
|
6567
6632
|
* @param bitLen how many bits the field consumes
|
6568
6633
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6618,12 +6683,6 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6618
6683
|
});
|
6619
6684
|
return Object.freeze(f);
|
6620
6685
|
}
|
6621
|
-
function FpSqrtEven(Fp, elm) {
|
6622
|
-
if (!Fp.isOdd)
|
6623
|
-
throw new Error(`Field doesn't have isOdd`);
|
6624
|
-
const root = Fp.sqrt(elm);
|
6625
|
-
return Fp.isOdd(root) ? Fp.neg(root) : root;
|
6626
|
-
}
|
6627
6686
|
/**
|
6628
6687
|
* Returns total number of bytes consumed by the field element.
|
6629
6688
|
* For example, 32 bytes for usual 256-bit weierstrass curve.
|
@@ -6677,6 +6736,10 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6677
6736
|
// Abelian group utilities
|
6678
6737
|
const _0n$2 = BigInt(0);
|
6679
6738
|
const _1n$4 = BigInt(1);
|
6739
|
+
// Since points in different groups cannot be equal (different object constructor),
|
6740
|
+
// we can have single place to store precomputes
|
6741
|
+
const pointPrecomputes = new WeakMap();
|
6742
|
+
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
6680
6743
|
// Elliptic curve multiplication of Point by scalar. Fragile.
|
6681
6744
|
// Scalars should always be less than curve order: this should be checked inside of a curve itself.
|
6682
6745
|
// Creates precomputation tables for fast multiplication:
|
@@ -6693,7 +6756,12 @@ function wNAF(c, bits) {
|
|
6693
6756
|
const neg = item.negate();
|
6694
6757
|
return condition ? neg : item;
|
6695
6758
|
};
|
6759
|
+
const validateW = (W) => {
|
6760
|
+
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6761
|
+
throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
|
6762
|
+
};
|
6696
6763
|
const opts = (W) => {
|
6764
|
+
validateW(W);
|
6697
6765
|
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6698
6766
|
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6699
6767
|
return { windows, windowSize };
|
@@ -6793,19 +6861,25 @@ function wNAF(c, bits) {
|
|
6793
6861
|
// which makes it less const-time: around 1 bigint multiply.
|
6794
6862
|
return { p, f };
|
6795
6863
|
},
|
6796
|
-
wNAFCached(P,
|
6797
|
-
|
6798
|
-
const W = P._WINDOW_SIZE || 1;
|
6864
|
+
wNAFCached(P, n, transform) {
|
6865
|
+
const W = pointWindowSizes.get(P) || 1;
|
6799
6866
|
// Calculate precomputes on a first run, reuse them after
|
6800
|
-
let comp =
|
6867
|
+
let comp = pointPrecomputes.get(P);
|
6801
6868
|
if (!comp) {
|
6802
6869
|
comp = this.precomputeWindow(P, W);
|
6803
|
-
if (W !== 1)
|
6804
|
-
|
6805
|
-
}
|
6870
|
+
if (W !== 1)
|
6871
|
+
pointPrecomputes.set(P, transform(comp));
|
6806
6872
|
}
|
6807
6873
|
return this.wNAF(W, comp, n);
|
6808
6874
|
},
|
6875
|
+
// We calculate precomputes for elliptic curve point multiplication
|
6876
|
+
// using windowed method. This specifies window size and
|
6877
|
+
// stores precomputed values. Usually only base point would be precomputed.
|
6878
|
+
setWindowSize(P, W) {
|
6879
|
+
validateW(W);
|
6880
|
+
pointWindowSizes.set(P, W);
|
6881
|
+
pointPrecomputes.delete(P);
|
6882
|
+
},
|
6809
6883
|
};
|
6810
6884
|
}
|
6811
6885
|
function validateBasic(curve) {
|
@@ -6831,7 +6905,7 @@ function validateBasic(curve) {
|
|
6831
6905
|
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
6832
6906
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
6833
6907
|
// prettier-ignore
|
6834
|
-
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n = BigInt(8);
|
6908
|
+
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
6835
6909
|
// verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
|
6836
6910
|
const VERIFY_DEFAULT = { zip215: true };
|
6837
6911
|
function validateOpts$1(curve) {
|
@@ -6850,7 +6924,13 @@ function validateOpts$1(curve) {
|
|
6850
6924
|
// Set defaults
|
6851
6925
|
return Object.freeze({ ...opts });
|
6852
6926
|
}
|
6853
|
-
|
6927
|
+
/**
|
6928
|
+
* Creates Twisted Edwards curve with EdDSA signatures.
|
6929
|
+
* @example
|
6930
|
+
* import { Field } from '@noble/curves/abstract/modular';
|
6931
|
+
* // Before that, define BigInt-s: a, d, p, n, Gx, Gy, h
|
6932
|
+
* const curve = twistedEdwards({ a, d, Fp: Field(p), n, Gx, Gy, h })
|
6933
|
+
*/
|
6854
6934
|
function twistedEdwards(curveDef) {
|
6855
6935
|
const CURVE = validateOpts$1(curveDef);
|
6856
6936
|
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
@@ -6869,28 +6949,59 @@ function twistedEdwards(curveDef) {
|
|
6869
6949
|
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
|
6870
6950
|
const domain = CURVE.domain ||
|
6871
6951
|
((data, ctx, phflag) => {
|
6952
|
+
abool('phflag', phflag);
|
6872
6953
|
if (ctx.length || phflag)
|
6873
6954
|
throw new Error('Contexts/pre-hash are not supported');
|
6874
6955
|
return data;
|
6875
6956
|
}); // NOOP
|
6876
|
-
|
6877
|
-
|
6878
|
-
|
6879
|
-
|
6880
|
-
|
6881
|
-
|
6882
|
-
return n;
|
6883
|
-
throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
|
6884
|
-
}
|
6885
|
-
function assertGE0(n) {
|
6886
|
-
// n in [0..CURVE_ORDER-1]
|
6887
|
-
return n === _0n$1 ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
|
6888
|
-
}
|
6889
|
-
const pointPrecomputes = new Map();
|
6890
|
-
function isPoint(other) {
|
6957
|
+
// 0 <= n < MASK
|
6958
|
+
// Coordinates larger than Fp.ORDER are allowed for zip215
|
6959
|
+
function aCoordinate(title, n) {
|
6960
|
+
aInRange('coordinate ' + title, n, _0n$1, MASK);
|
6961
|
+
}
|
6962
|
+
function assertPoint(other) {
|
6891
6963
|
if (!(other instanceof Point))
|
6892
6964
|
throw new Error('ExtendedPoint expected');
|
6893
6965
|
}
|
6966
|
+
// Converts Extended point to default (x, y) coordinates.
|
6967
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
6968
|
+
const toAffineMemo = memoized((p, iz) => {
|
6969
|
+
const { ex: x, ey: y, ez: z } = p;
|
6970
|
+
const is0 = p.is0();
|
6971
|
+
if (iz == null)
|
6972
|
+
iz = is0 ? _8n$1 : Fp.inv(z); // 8 was chosen arbitrarily
|
6973
|
+
const ax = modP(x * iz);
|
6974
|
+
const ay = modP(y * iz);
|
6975
|
+
const zz = modP(z * iz);
|
6976
|
+
if (is0)
|
6977
|
+
return { x: _0n$1, y: _1n$3 };
|
6978
|
+
if (zz !== _1n$3)
|
6979
|
+
throw new Error('invZ was invalid');
|
6980
|
+
return { x: ax, y: ay };
|
6981
|
+
});
|
6982
|
+
const assertValidMemo = memoized((p) => {
|
6983
|
+
const { a, d } = CURVE;
|
6984
|
+
if (p.is0())
|
6985
|
+
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
6986
|
+
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
6987
|
+
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
6988
|
+
const { ex: X, ey: Y, ez: Z, et: T } = p;
|
6989
|
+
const X2 = modP(X * X); // X²
|
6990
|
+
const Y2 = modP(Y * Y); // Y²
|
6991
|
+
const Z2 = modP(Z * Z); // Z²
|
6992
|
+
const Z4 = modP(Z2 * Z2); // Z⁴
|
6993
|
+
const aX2 = modP(X2 * a); // aX²
|
6994
|
+
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
6995
|
+
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
6996
|
+
if (left !== right)
|
6997
|
+
throw new Error('bad point: equation left != right (1)');
|
6998
|
+
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
6999
|
+
const XY = modP(X * Y);
|
7000
|
+
const ZT = modP(Z * T);
|
7001
|
+
if (XY !== ZT)
|
7002
|
+
throw new Error('bad point: equation left != right (2)');
|
7003
|
+
return true;
|
7004
|
+
});
|
6894
7005
|
// Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
|
6895
7006
|
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
6896
7007
|
class Point {
|
@@ -6899,14 +7010,11 @@ function twistedEdwards(curveDef) {
|
|
6899
7010
|
this.ey = ey;
|
6900
7011
|
this.ez = ez;
|
6901
7012
|
this.et = et;
|
6902
|
-
|
6903
|
-
|
6904
|
-
|
6905
|
-
|
6906
|
-
|
6907
|
-
throw new Error('z required');
|
6908
|
-
if (!in0MaskRange(et))
|
6909
|
-
throw new Error('t required');
|
7013
|
+
aCoordinate('x', ex);
|
7014
|
+
aCoordinate('y', ey);
|
7015
|
+
aCoordinate('z', ez);
|
7016
|
+
aCoordinate('t', et);
|
7017
|
+
Object.freeze(this);
|
6910
7018
|
}
|
6911
7019
|
get x() {
|
6912
7020
|
return this.toAffine().x;
|
@@ -6918,8 +7026,8 @@ function twistedEdwards(curveDef) {
|
|
6918
7026
|
if (p instanceof Point)
|
6919
7027
|
throw new Error('extended point not allowed');
|
6920
7028
|
const { x, y } = p || {};
|
6921
|
-
|
6922
|
-
|
7029
|
+
aCoordinate('x', x);
|
7030
|
+
aCoordinate('y', y);
|
6923
7031
|
return new Point(x, y, _1n$3, modP(x * y));
|
6924
7032
|
}
|
6925
7033
|
static normalizeZ(points) {
|
@@ -6928,36 +7036,16 @@ function twistedEdwards(curveDef) {
|
|
6928
7036
|
}
|
6929
7037
|
// "Private method", don't use it directly
|
6930
7038
|
_setWindowSize(windowSize) {
|
6931
|
-
this
|
6932
|
-
pointPrecomputes.delete(this);
|
7039
|
+
wnaf.setWindowSize(this, windowSize);
|
6933
7040
|
}
|
6934
7041
|
// Not required for fromHex(), which always creates valid points.
|
6935
7042
|
// Could be useful for fromAffine().
|
6936
7043
|
assertValidity() {
|
6937
|
-
|
6938
|
-
if (this.is0())
|
6939
|
-
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
6940
|
-
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
6941
|
-
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
6942
|
-
const { ex: X, ey: Y, ez: Z, et: T } = this;
|
6943
|
-
const X2 = modP(X * X); // X²
|
6944
|
-
const Y2 = modP(Y * Y); // Y²
|
6945
|
-
const Z2 = modP(Z * Z); // Z²
|
6946
|
-
const Z4 = modP(Z2 * Z2); // Z⁴
|
6947
|
-
const aX2 = modP(X2 * a); // aX²
|
6948
|
-
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
6949
|
-
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
6950
|
-
if (left !== right)
|
6951
|
-
throw new Error('bad point: equation left != right (1)');
|
6952
|
-
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
6953
|
-
const XY = modP(X * Y);
|
6954
|
-
const ZT = modP(Z * T);
|
6955
|
-
if (XY !== ZT)
|
6956
|
-
throw new Error('bad point: equation left != right (2)');
|
7044
|
+
assertValidMemo(this);
|
6957
7045
|
}
|
6958
7046
|
// Compare one point to another.
|
6959
7047
|
equals(other) {
|
6960
|
-
|
7048
|
+
assertPoint(other);
|
6961
7049
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
6962
7050
|
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
6963
7051
|
const X1Z2 = modP(X1 * Z2);
|
@@ -6998,7 +7086,7 @@ function twistedEdwards(curveDef) {
|
|
6998
7086
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
6999
7087
|
// Cost: 9M + 1*a + 1*d + 7add.
|
7000
7088
|
add(other) {
|
7001
|
-
|
7089
|
+
assertPoint(other);
|
7002
7090
|
const { a, d } = CURVE;
|
7003
7091
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
7004
7092
|
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
@@ -7041,11 +7129,13 @@ function twistedEdwards(curveDef) {
|
|
7041
7129
|
return this.add(other.negate());
|
7042
7130
|
}
|
7043
7131
|
wNAF(n) {
|
7044
|
-
return wnaf.wNAFCached(this,
|
7132
|
+
return wnaf.wNAFCached(this, n, Point.normalizeZ);
|
7045
7133
|
}
|
7046
7134
|
// Constant-time multiplication.
|
7047
7135
|
multiply(scalar) {
|
7048
|
-
const
|
7136
|
+
const n = scalar;
|
7137
|
+
aInRange('scalar', n, _1n$3, CURVE_ORDER); // 1 <= scalar < L
|
7138
|
+
const { p, f } = this.wNAF(n);
|
7049
7139
|
return Point.normalizeZ([p, f])[0];
|
7050
7140
|
}
|
7051
7141
|
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
@@ -7053,7 +7143,8 @@ function twistedEdwards(curveDef) {
|
|
7053
7143
|
// an exposed private key e.g. sig verification.
|
7054
7144
|
// Does NOT allow scalars higher than CURVE.n.
|
7055
7145
|
multiplyUnsafe(scalar) {
|
7056
|
-
|
7146
|
+
const n = scalar;
|
7147
|
+
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7057
7148
|
if (n === _0n$1)
|
7058
7149
|
return I;
|
7059
7150
|
if (this.equals(I) || n === _1n$3)
|
@@ -7077,18 +7168,7 @@ function twistedEdwards(curveDef) {
|
|
7077
7168
|
// Converts Extended point to default (x, y) coordinates.
|
7078
7169
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
7079
7170
|
toAffine(iz) {
|
7080
|
-
|
7081
|
-
const is0 = this.is0();
|
7082
|
-
if (iz == null)
|
7083
|
-
iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
|
7084
|
-
const ax = modP(x * iz);
|
7085
|
-
const ay = modP(y * iz);
|
7086
|
-
const zz = modP(z * iz);
|
7087
|
-
if (is0)
|
7088
|
-
return { x: _0n$1, y: _1n$3 };
|
7089
|
-
if (zz !== _1n$3)
|
7090
|
-
throw new Error('invZ was invalid');
|
7091
|
-
return { x: ax, y: ay };
|
7171
|
+
return toAffineMemo(this, iz);
|
7092
7172
|
}
|
7093
7173
|
clearCofactor() {
|
7094
7174
|
const { h: cofactor } = CURVE;
|
@@ -7102,18 +7182,16 @@ function twistedEdwards(curveDef) {
|
|
7102
7182
|
const { d, a } = CURVE;
|
7103
7183
|
const len = Fp.BYTES;
|
7104
7184
|
hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
|
7185
|
+
abool('zip215', zip215);
|
7105
7186
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7106
7187
|
const lastByte = hex[len - 1]; // select last byte
|
7107
7188
|
normed[len - 1] = lastByte & ~0x80; // clear last bit
|
7108
7189
|
const y = bytesToNumberLE(normed);
|
7109
|
-
|
7110
|
-
|
7111
|
-
|
7112
|
-
|
7113
|
-
|
7114
|
-
else
|
7115
|
-
assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
|
7116
|
-
}
|
7190
|
+
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
7191
|
+
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7192
|
+
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
7193
|
+
const max = zip215 ? MASK : Fp.ORDER;
|
7194
|
+
aInRange('pointHex.y', y, _0n$1, max);
|
7117
7195
|
// Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
|
7118
7196
|
// ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
|
7119
7197
|
const y2 = modP(y * y); // denominator is always non-0 mod p.
|
@@ -7188,7 +7266,7 @@ function twistedEdwards(curveDef) {
|
|
7188
7266
|
const R = G.multiply(r).toRawBytes(); // R = rG
|
7189
7267
|
const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
|
7190
7268
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7191
|
-
|
7269
|
+
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7192
7270
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7193
7271
|
return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
|
7194
7272
|
}
|
@@ -7198,6 +7276,8 @@ function twistedEdwards(curveDef) {
|
|
7198
7276
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7199
7277
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7200
7278
|
msg = ensureBytes('message', msg);
|
7279
|
+
if (zip215 !== undefined)
|
7280
|
+
abool('zip215', zip215);
|
7201
7281
|
if (prehash)
|
7202
7282
|
msg = prehash(msg); // for ed25519ph, etc
|
7203
7283
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
@@ -7255,12 +7335,14 @@ function twistedEdwards(curveDef) {
|
|
7255
7335
|
*/
|
7256
7336
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7257
7337
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
7258
|
-
const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
7338
|
+
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
7259
7339
|
// prettier-ignore
|
7260
|
-
BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2)
|
7340
|
+
BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
|
7261
7341
|
// prettier-ignore
|
7262
|
-
const
|
7342
|
+
const _5n = BigInt(5), _8n = BigInt(8);
|
7263
7343
|
function ed25519_pow_2_252_3(x) {
|
7344
|
+
// prettier-ignore
|
7345
|
+
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
7264
7346
|
const P = ED25519_P;
|
7265
7347
|
const x2 = (x * x) % P;
|
7266
7348
|
const b2 = (x2 * x) % P; // x^3, 11
|
@@ -7309,8 +7391,8 @@ function uvRatio(u, v) {
|
|
7309
7391
|
x = mod(-x, P);
|
7310
7392
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7311
7393
|
}
|
7312
|
-
const Fp$1 = Field(ED25519_P, undefined, true);
|
7313
|
-
const ed25519Defaults = {
|
7394
|
+
const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7395
|
+
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7314
7396
|
// Param: a
|
7315
7397
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
7316
7398
|
// d is equal to -121665/121666 over finite field.
|
@@ -7322,7 +7404,7 @@ const ed25519Defaults = {
|
|
7322
7404
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7323
7405
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
7324
7406
|
// Cofactor
|
7325
|
-
h:
|
7407
|
+
h: _8n,
|
7326
7408
|
// Base point (x, y) aka generator point
|
7327
7409
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
7328
7410
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
@@ -7333,40 +7415,11 @@ const ed25519Defaults = {
|
|
7333
7415
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
7334
7416
|
// Constant-time, u/√v
|
7335
7417
|
uvRatio,
|
7336
|
-
};
|
7337
|
-
|
7338
|
-
|
7339
|
-
|
7340
|
-
|
7341
|
-
return concatBytes$1(utf8ToBytes$1('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
|
7342
|
-
}
|
7343
|
-
/* @__PURE__ */ twistedEdwards({
|
7344
|
-
...ed25519Defaults,
|
7345
|
-
domain: ed25519_domain,
|
7346
|
-
});
|
7347
|
-
/* @__PURE__ */ twistedEdwards({
|
7348
|
-
...ed25519Defaults,
|
7349
|
-
domain: ed25519_domain,
|
7350
|
-
prehash: sha512,
|
7351
|
-
});
|
7352
|
-
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
7353
|
-
// NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
|
7354
|
-
// SageMath returns different root first and everything falls apart
|
7355
|
-
const ELL2_C1 = (Fp$1.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
|
7356
|
-
Fp$1.pow(_2n$1, ELL2_C1); // 2. c2 = 2^c1
|
7357
|
-
Fp$1.sqrt(Fp$1.neg(Fp$1.ONE)); // 3. c3 = sqrt(-1)
|
7358
|
-
(Fp$1.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
|
7359
|
-
BigInt(486662);
|
7360
|
-
FpSqrtEven(Fp$1, Fp$1.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
|
7361
|
-
// √(ad - 1)
|
7362
|
-
BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
7363
|
-
// 1 / √(a-d)
|
7364
|
-
BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
7365
|
-
// 1-d²
|
7366
|
-
BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
7367
|
-
// (d-1)²
|
7368
|
-
BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
7369
|
-
BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
7418
|
+
}))();
|
7419
|
+
/**
|
7420
|
+
* ed25519 curve with EdDSA signatures.
|
7421
|
+
*/
|
7422
|
+
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7370
7423
|
|
7371
7424
|
const PUBLIC_KEY_BYTE_LENGTH = 32;
|
7372
7425
|
const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
@@ -7423,7 +7476,7 @@ function concatKeys(privateKeyRaw, publicKey) {
|
|
7423
7476
|
var webcrypto = {
|
7424
7477
|
get(win = globalThis) {
|
7425
7478
|
const nativeCrypto = win.crypto;
|
7426
|
-
if (nativeCrypto
|
7479
|
+
if (nativeCrypto?.subtle == null) {
|
7427
7480
|
throw Object.assign(new Error('Missing Web Crypto API. ' +
|
7428
7481
|
'The most likely cause of this error is that this page is being accessed ' +
|
7429
7482
|
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
@@ -7447,12 +7500,12 @@ var webcrypto = {
|
|
7447
7500
|
const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
|
7448
7501
|
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
|
7449
7502
|
function create(opts) {
|
7450
|
-
const algorithm =
|
7451
|
-
let keyLength =
|
7452
|
-
const nonceLength =
|
7453
|
-
const digest =
|
7454
|
-
const saltLength =
|
7455
|
-
const iterations =
|
7503
|
+
const algorithm = 'AES-GCM';
|
7504
|
+
let keyLength = 16;
|
7505
|
+
const nonceLength = 12;
|
7506
|
+
const digest = 'SHA-256';
|
7507
|
+
const saltLength = 16;
|
7508
|
+
const iterations = 32767;
|
7456
7509
|
const crypto = webcrypto.get();
|
7457
7510
|
keyLength *= 8; // Browser crypto uses bits instead of bytes
|
7458
7511
|
/**
|
@@ -8236,7 +8289,7 @@ function decodeMessage(buf, codec, opts) {
|
|
8236
8289
|
* A general purpose buffer pool
|
8237
8290
|
*/
|
8238
8291
|
function pool(size) {
|
8239
|
-
const SIZE =
|
8292
|
+
const SIZE = 8192;
|
8240
8293
|
const MAX = SIZE >>> 1;
|
8241
8294
|
let slab;
|
8242
8295
|
let offset = SIZE;
|
@@ -12824,6 +12877,12 @@ var RSA = /*#__PURE__*/Object.freeze({
|
|
12824
12877
|
|
12825
12878
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
12826
12879
|
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
12880
|
+
function validateSigVerOpts(opts) {
|
12881
|
+
if (opts.lowS !== undefined)
|
12882
|
+
abool('lowS', opts.lowS);
|
12883
|
+
if (opts.prehash !== undefined)
|
12884
|
+
abool('prehash', opts.prehash);
|
12885
|
+
}
|
12827
12886
|
function validatePointOpts(curve) {
|
12828
12887
|
const opts = validateBasic(curve);
|
12829
12888
|
validateObject(opts, {
|
@@ -12948,16 +13007,12 @@ function weierstrassPoints(opts) {
|
|
12948
13007
|
throw new Error('bad generator point: equation left != right');
|
12949
13008
|
// Valid group elements reside in range 1..n-1
|
12950
13009
|
function isWithinCurveOrder(num) {
|
12951
|
-
return
|
12952
|
-
}
|
12953
|
-
function assertGE(num) {
|
12954
|
-
if (!isWithinCurveOrder(num))
|
12955
|
-
throw new Error('Expected valid bigint: 0 < bigint < curve.n');
|
13010
|
+
return inRange(num, _1n$1, CURVE.n);
|
12956
13011
|
}
|
12957
13012
|
// Validates if priv key is valid and converts it to bigint.
|
12958
13013
|
// Supports options allowedPrivateKeyLengths and wrapPrivateKey.
|
12959
13014
|
function normPrivateKeyToScalar(key) {
|
12960
|
-
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
|
13015
|
+
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
|
12961
13016
|
if (lengths && typeof key !== 'bigint') {
|
12962
13017
|
if (isBytes$1(key))
|
12963
13018
|
key = bytesToHex(key);
|
@@ -12977,15 +13032,61 @@ function weierstrassPoints(opts) {
|
|
12977
13032
|
throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
|
12978
13033
|
}
|
12979
13034
|
if (wrapPrivateKey)
|
12980
|
-
num = mod(num,
|
12981
|
-
|
13035
|
+
num = mod(num, N); // disabled by default, enabled for BLS
|
13036
|
+
aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
|
12982
13037
|
return num;
|
12983
13038
|
}
|
12984
|
-
const pointPrecomputes = new Map();
|
12985
13039
|
function assertPrjPoint(other) {
|
12986
13040
|
if (!(other instanceof Point))
|
12987
13041
|
throw new Error('ProjectivePoint expected');
|
12988
13042
|
}
|
13043
|
+
// Memoized toAffine / validity check. They are heavy. Points are immutable.
|
13044
|
+
// Converts Projective point to affine (x, y) coordinates.
|
13045
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
13046
|
+
// (x, y, z) ∋ (x=x/z, y=y/z)
|
13047
|
+
const toAffineMemo = memoized((p, iz) => {
|
13048
|
+
const { px: x, py: y, pz: z } = p;
|
13049
|
+
// Fast-path for normalized points
|
13050
|
+
if (Fp.eql(z, Fp.ONE))
|
13051
|
+
return { x, y };
|
13052
|
+
const is0 = p.is0();
|
13053
|
+
// If invZ was 0, we return zero point. However we still want to execute
|
13054
|
+
// all operations, so we replace invZ with a random number, 1.
|
13055
|
+
if (iz == null)
|
13056
|
+
iz = is0 ? Fp.ONE : Fp.inv(z);
|
13057
|
+
const ax = Fp.mul(x, iz);
|
13058
|
+
const ay = Fp.mul(y, iz);
|
13059
|
+
const zz = Fp.mul(z, iz);
|
13060
|
+
if (is0)
|
13061
|
+
return { x: Fp.ZERO, y: Fp.ZERO };
|
13062
|
+
if (!Fp.eql(zz, Fp.ONE))
|
13063
|
+
throw new Error('invZ was invalid');
|
13064
|
+
return { x: ax, y: ay };
|
13065
|
+
});
|
13066
|
+
// NOTE: on exception this will crash 'cached' and no value will be set.
|
13067
|
+
// Otherwise true will be return
|
13068
|
+
const assertValidMemo = memoized((p) => {
|
13069
|
+
if (p.is0()) {
|
13070
|
+
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13071
|
+
// In BLS, ZERO can be serialized, so we allow it.
|
13072
|
+
// (0, 0, 0) is wrong representation of ZERO and is always invalid.
|
13073
|
+
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
13074
|
+
return;
|
13075
|
+
throw new Error('bad point: ZERO');
|
13076
|
+
}
|
13077
|
+
// Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
|
13078
|
+
const { x, y } = p.toAffine();
|
13079
|
+
// Check if x, y are valid field elements
|
13080
|
+
if (!Fp.isValid(x) || !Fp.isValid(y))
|
13081
|
+
throw new Error('bad point: x or y not FE');
|
13082
|
+
const left = Fp.sqr(y); // y²
|
13083
|
+
const right = weierstrassEquation(x); // x³ + ax + b
|
13084
|
+
if (!Fp.eql(left, right))
|
13085
|
+
throw new Error('bad point: equation left != right');
|
13086
|
+
if (!p.isTorsionFree())
|
13087
|
+
throw new Error('bad point: not in prime-order subgroup');
|
13088
|
+
return true;
|
13089
|
+
});
|
12989
13090
|
/**
|
12990
13091
|
* Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
|
12991
13092
|
* Default Point works in 2d / affine coordinates: (x, y)
|
@@ -13002,6 +13103,7 @@ function weierstrassPoints(opts) {
|
|
13002
13103
|
throw new Error('y required');
|
13003
13104
|
if (pz == null || !Fp.isValid(pz))
|
13004
13105
|
throw new Error('z required');
|
13106
|
+
Object.freeze(this);
|
13005
13107
|
}
|
13006
13108
|
// Does not validate if the point is on-curve.
|
13007
13109
|
// Use fromHex instead, or call assertValidity() later.
|
@@ -13048,30 +13150,11 @@ function weierstrassPoints(opts) {
|
|
13048
13150
|
}
|
13049
13151
|
// "Private method", don't use it directly
|
13050
13152
|
_setWindowSize(windowSize) {
|
13051
|
-
this
|
13052
|
-
pointPrecomputes.delete(this);
|
13153
|
+
wnaf.setWindowSize(this, windowSize);
|
13053
13154
|
}
|
13054
13155
|
// A point on curve is valid if it conforms to equation.
|
13055
13156
|
assertValidity() {
|
13056
|
-
|
13057
|
-
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13058
|
-
// In BLS, ZERO can be serialized, so we allow it.
|
13059
|
-
// (0, 0, 0) is wrong representation of ZERO and is always invalid.
|
13060
|
-
if (CURVE.allowInfinityPoint && !Fp.is0(this.py))
|
13061
|
-
return;
|
13062
|
-
throw new Error('bad point: ZERO');
|
13063
|
-
}
|
13064
|
-
// Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
|
13065
|
-
const { x, y } = this.toAffine();
|
13066
|
-
// Check if x, y are valid field elements
|
13067
|
-
if (!Fp.isValid(x) || !Fp.isValid(y))
|
13068
|
-
throw new Error('bad point: x or y not FE');
|
13069
|
-
const left = Fp.sqr(y); // y²
|
13070
|
-
const right = weierstrassEquation(x); // x³ + ax + b
|
13071
|
-
if (!Fp.eql(left, right))
|
13072
|
-
throw new Error('bad point: equation left != right');
|
13073
|
-
if (!this.isTorsionFree())
|
13074
|
-
throw new Error('bad point: not in prime-order subgroup');
|
13157
|
+
assertValidMemo(this);
|
13075
13158
|
}
|
13076
13159
|
hasEvenY() {
|
13077
13160
|
const { y } = this.toAffine();
|
@@ -13198,28 +13281,25 @@ function weierstrassPoints(opts) {
|
|
13198
13281
|
return this.equals(Point.ZERO);
|
13199
13282
|
}
|
13200
13283
|
wNAF(n) {
|
13201
|
-
return wnaf.wNAFCached(this,
|
13202
|
-
const toInv = Fp.invertBatch(comp.map((p) => p.pz));
|
13203
|
-
return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
13204
|
-
});
|
13284
|
+
return wnaf.wNAFCached(this, n, Point.normalizeZ);
|
13205
13285
|
}
|
13206
13286
|
/**
|
13207
13287
|
* Non-constant-time multiplication. Uses double-and-add algorithm.
|
13208
13288
|
* It's faster, but should only be used when you don't care about
|
13209
13289
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
13210
13290
|
*/
|
13211
|
-
multiplyUnsafe(
|
13291
|
+
multiplyUnsafe(sc) {
|
13292
|
+
aInRange('scalar', sc, _0n, CURVE.n);
|
13212
13293
|
const I = Point.ZERO;
|
13213
|
-
if (
|
13294
|
+
if (sc === _0n)
|
13214
13295
|
return I;
|
13215
|
-
|
13216
|
-
if (n === _1n$1)
|
13296
|
+
if (sc === _1n$1)
|
13217
13297
|
return this;
|
13218
13298
|
const { endo } = CURVE;
|
13219
13299
|
if (!endo)
|
13220
|
-
return wnaf.unsafeLadder(this,
|
13300
|
+
return wnaf.unsafeLadder(this, sc);
|
13221
13301
|
// Apply endomorphism
|
13222
|
-
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(
|
13302
|
+
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
13223
13303
|
let k1p = I;
|
13224
13304
|
let k2p = I;
|
13225
13305
|
let d = this;
|
@@ -13249,12 +13329,11 @@ function weierstrassPoints(opts) {
|
|
13249
13329
|
* @returns New point
|
13250
13330
|
*/
|
13251
13331
|
multiply(scalar) {
|
13252
|
-
|
13253
|
-
|
13332
|
+
const { endo, n: N } = CURVE;
|
13333
|
+
aInRange('scalar', scalar, _1n$1, N);
|
13254
13334
|
let point, fake; // Fake point is used to const-time mult
|
13255
|
-
const { endo } = CURVE;
|
13256
13335
|
if (endo) {
|
13257
|
-
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(
|
13336
|
+
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
|
13258
13337
|
let { p: k1p, f: f1p } = this.wNAF(k1);
|
13259
13338
|
let { p: k2p, f: f2p } = this.wNAF(k2);
|
13260
13339
|
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
@@ -13264,7 +13343,7 @@ function weierstrassPoints(opts) {
|
|
13264
13343
|
fake = f1p.add(f2p);
|
13265
13344
|
}
|
13266
13345
|
else {
|
13267
|
-
const { p, f } = this.wNAF(
|
13346
|
+
const { p, f } = this.wNAF(scalar);
|
13268
13347
|
point = p;
|
13269
13348
|
fake = f;
|
13270
13349
|
}
|
@@ -13288,20 +13367,7 @@ function weierstrassPoints(opts) {
|
|
13288
13367
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
13289
13368
|
// (x, y, z) ∋ (x=x/z, y=y/z)
|
13290
13369
|
toAffine(iz) {
|
13291
|
-
|
13292
|
-
const is0 = this.is0();
|
13293
|
-
// If invZ was 0, we return zero point. However we still want to execute
|
13294
|
-
// all operations, so we replace invZ with a random number, 1.
|
13295
|
-
if (iz == null)
|
13296
|
-
iz = is0 ? Fp.ONE : Fp.inv(z);
|
13297
|
-
const ax = Fp.mul(x, iz);
|
13298
|
-
const ay = Fp.mul(y, iz);
|
13299
|
-
const zz = Fp.mul(z, iz);
|
13300
|
-
if (is0)
|
13301
|
-
return { x: Fp.ZERO, y: Fp.ZERO };
|
13302
|
-
if (!Fp.eql(zz, Fp.ONE))
|
13303
|
-
throw new Error('invZ was invalid');
|
13304
|
-
return { x: ax, y: ay };
|
13370
|
+
return toAffineMemo(this, iz);
|
13305
13371
|
}
|
13306
13372
|
isTorsionFree() {
|
13307
13373
|
const { h: cofactor, isTorsionFree } = CURVE;
|
@@ -13320,10 +13386,12 @@ function weierstrassPoints(opts) {
|
|
13320
13386
|
return this.multiplyUnsafe(CURVE.h);
|
13321
13387
|
}
|
13322
13388
|
toRawBytes(isCompressed = true) {
|
13389
|
+
abool('isCompressed', isCompressed);
|
13323
13390
|
this.assertValidity();
|
13324
13391
|
return toBytes(Point, this, isCompressed);
|
13325
13392
|
}
|
13326
13393
|
toHex(isCompressed = true) {
|
13394
|
+
abool('isCompressed', isCompressed);
|
13327
13395
|
return bytesToHex(this.toRawBytes(isCompressed));
|
13328
13396
|
}
|
13329
13397
|
}
|
@@ -13353,14 +13421,18 @@ function validateOpts(curve) {
|
|
13353
13421
|
});
|
13354
13422
|
return Object.freeze({ lowS: true, ...opts });
|
13355
13423
|
}
|
13424
|
+
/**
|
13425
|
+
* Creates short weierstrass curve and ECDSA signature methods for it.
|
13426
|
+
* @example
|
13427
|
+
* import { Field } from '@noble/curves/abstract/modular';
|
13428
|
+
* // Before that, define BigInt-s: a, b, p, n, Gx, Gy
|
13429
|
+
* const curve = weierstrass({ a, b, Fp: Field(p), n, Gx, Gy, h: 1n })
|
13430
|
+
*/
|
13356
13431
|
function weierstrass(curveDef) {
|
13357
13432
|
const CURVE = validateOpts(curveDef);
|
13358
13433
|
const { Fp, n: CURVE_ORDER } = CURVE;
|
13359
13434
|
const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
|
13360
13435
|
const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
|
13361
|
-
function isValidFieldElement(num) {
|
13362
|
-
return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE
|
13363
|
-
}
|
13364
13436
|
function modN(a) {
|
13365
13437
|
return mod(a, CURVE_ORDER);
|
13366
13438
|
}
|
@@ -13373,6 +13445,7 @@ function weierstrass(curveDef) {
|
|
13373
13445
|
const a = point.toAffine();
|
13374
13446
|
const x = Fp.toBytes(a.x);
|
13375
13447
|
const cat = concatBytes;
|
13448
|
+
abool('isCompressed', isCompressed);
|
13376
13449
|
if (isCompressed) {
|
13377
13450
|
return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
|
13378
13451
|
}
|
@@ -13387,7 +13460,7 @@ function weierstrass(curveDef) {
|
|
13387
13460
|
// this.assertValidity() is done inside of fromHex
|
13388
13461
|
if (len === compressedLen && (head === 0x02 || head === 0x03)) {
|
13389
13462
|
const x = bytesToNumberBE(tail);
|
13390
|
-
if (!
|
13463
|
+
if (!inRange(x, _1n$1, Fp.ORDER))
|
13391
13464
|
throw new Error('Point is not on curve');
|
13392
13465
|
const y2 = weierstrassEquation(x); // y² = x³ + ax + b
|
13393
13466
|
let y;
|
@@ -13448,11 +13521,8 @@ function weierstrass(curveDef) {
|
|
13448
13521
|
return new Signature(r, s);
|
13449
13522
|
}
|
13450
13523
|
assertValidity() {
|
13451
|
-
//
|
13452
|
-
|
13453
|
-
throw new Error('r must be 0 < r < CURVE.n');
|
13454
|
-
if (!isWithinCurveOrder(this.s))
|
13455
|
-
throw new Error('s must be 0 < s < CURVE.n');
|
13524
|
+
aInRange('r', this.r, _1n$1, CURVE_ORDER); // r in [1..N]
|
13525
|
+
aInRange('s', this.s, _1n$1, CURVE_ORDER); // s in [1..N]
|
13456
13526
|
}
|
13457
13527
|
addRecoveryBit(recovery) {
|
13458
13528
|
return new Signature(this.r, this.s, recovery);
|
@@ -13595,10 +13665,7 @@ function weierstrass(curveDef) {
|
|
13595
13665
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13596
13666
|
*/
|
13597
13667
|
function int2octets(num) {
|
13598
|
-
|
13599
|
-
throw new Error('bigint expected');
|
13600
|
-
if (!(_0n <= num && num < ORDER_MASK))
|
13601
|
-
throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
|
13668
|
+
aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
|
13602
13669
|
// works with order, can have different size than numToField!
|
13603
13670
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13604
13671
|
}
|
@@ -13615,6 +13682,7 @@ function weierstrass(curveDef) {
|
|
13615
13682
|
if (lowS == null)
|
13616
13683
|
lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
|
13617
13684
|
msgHash = ensureBytes('msgHash', msgHash);
|
13685
|
+
validateSigVerOpts(opts);
|
13618
13686
|
if (prehash)
|
13619
13687
|
msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
|
13620
13688
|
// We can't later call bits2octets, since nested bits2int is broken for curves
|
@@ -13701,6 +13769,7 @@ function weierstrass(curveDef) {
|
|
13701
13769
|
publicKey = ensureBytes('publicKey', publicKey);
|
13702
13770
|
if ('strict' in opts)
|
13703
13771
|
throw new Error('options.strict was renamed to lowS');
|
13772
|
+
validateSigVerOpts(opts);
|
13704
13773
|
const { lowS, prehash } = opts;
|
13705
13774
|
let _sig = undefined;
|
13706
13775
|
let P;
|
@@ -13807,6 +13876,9 @@ function sqrtMod(y) {
|
|
13807
13876
|
return root;
|
13808
13877
|
}
|
13809
13878
|
const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
13879
|
+
/**
|
13880
|
+
* secp256k1 short weierstrass curve and ECDSA signatures over it.
|
13881
|
+
*/
|
13810
13882
|
const secp256k1 = createCurve({
|
13811
13883
|
a: BigInt(0), // equation params: a, b
|
13812
13884
|
b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
|
@@ -14212,6 +14284,41 @@ class Secp256k1PeerIdImpl extends PeerIdImpl {
|
|
14212
14284
|
this.publicKey = init.multihash.digest;
|
14213
14285
|
}
|
14214
14286
|
}
|
14287
|
+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14288
|
+
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
14289
|
+
class URLPeerIdImpl {
|
14290
|
+
type = 'url';
|
14291
|
+
multihash;
|
14292
|
+
privateKey;
|
14293
|
+
publicKey;
|
14294
|
+
url;
|
14295
|
+
constructor(url) {
|
14296
|
+
this.url = url.toString();
|
14297
|
+
this.multihash = identity.digest(fromString(this.url));
|
14298
|
+
}
|
14299
|
+
[inspect]() {
|
14300
|
+
return `PeerId(${this.url})`;
|
14301
|
+
}
|
14302
|
+
[peerIdSymbol] = true;
|
14303
|
+
toString() {
|
14304
|
+
return this.toCID().toString();
|
14305
|
+
}
|
14306
|
+
toCID() {
|
14307
|
+
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
|
14308
|
+
}
|
14309
|
+
toBytes() {
|
14310
|
+
return this.toCID().bytes;
|
14311
|
+
}
|
14312
|
+
equals(other) {
|
14313
|
+
if (other == null) {
|
14314
|
+
return false;
|
14315
|
+
}
|
14316
|
+
if (other instanceof Uint8Array) {
|
14317
|
+
other = toString$1(other);
|
14318
|
+
}
|
14319
|
+
return other.toString() === this.toString();
|
14320
|
+
}
|
14321
|
+
}
|
14215
14322
|
function peerIdFromString(str, decoder) {
|
14216
14323
|
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
14217
14324
|
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
@@ -14250,9 +14357,13 @@ function peerIdFromBytes(buf) {
|
|
14250
14357
|
throw new Error('Supplied PeerID CID is invalid');
|
14251
14358
|
}
|
14252
14359
|
function peerIdFromCID(cid) {
|
14253
|
-
if (cid == null || cid.
|
14360
|
+
if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
|
14254
14361
|
throw new Error('Supplied PeerID CID is invalid');
|
14255
14362
|
}
|
14363
|
+
if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
|
14364
|
+
const url = toString$1(cid.multihash.digest);
|
14365
|
+
return new URLPeerIdImpl(new URL(url));
|
14366
|
+
}
|
14256
14367
|
const multihash = cid.multihash;
|
14257
14368
|
if (multihash.code === sha256$1.code) {
|
14258
14369
|
return new RSAPeerIdImpl({ multihash: cid.multihash });
|
@@ -14289,6 +14400,9 @@ function getPublicKeyFromPeerId(peerId) {
|
|
14289
14400
|
if (peerId.type !== "secp256k1") {
|
14290
14401
|
throw new Error("Unsupported peer id type");
|
14291
14402
|
}
|
14403
|
+
if (!peerId.publicKey) {
|
14404
|
+
throw new Error("Public key not present on peer id");
|
14405
|
+
}
|
14292
14406
|
return unmarshalPublicKey(peerId.publicKey).marshal();
|
14293
14407
|
}
|
14294
14408
|
// Only used in tests
|
@@ -15137,9 +15251,6 @@ function isHexString(value, length) {
|
|
15137
15251
|
if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
|
15138
15252
|
return false;
|
15139
15253
|
}
|
15140
|
-
if (length && value.length !== 2 + 2 * length) {
|
15141
|
-
return false;
|
15142
|
-
}
|
15143
15254
|
return true;
|
15144
15255
|
}
|
15145
15256
|
const HexCharacters = "0123456789abcdef";
|