@waku/enr 0.0.25-88a29c3.0 → 0.0.25-c33844e.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 +331 -226
- package/dist/.tsbuildinfo +1 -1
- package/dist/peer_id.js +3 -0
- package/dist/peer_id.js.map +1 -1
- package/package.json +1 -1
- package/src/peer_id.ts +4 -0
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;
|
@@ -4143,6 +4143,8 @@ var common = setup;
|
|
4143
4143
|
return false;
|
4144
4144
|
}
|
4145
4145
|
|
4146
|
+
let m;
|
4147
|
+
|
4146
4148
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
4147
4149
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
4148
4150
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
@@ -4150,7 +4152,7 @@ var common = setup;
|
|
4150
4152
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
4151
4153
|
// Is firefox >= v31?
|
4152
4154
|
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
4153
|
-
(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) ||
|
4154
4156
|
// Double check webkit in userAgent just in case we are in a worker
|
4155
4157
|
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
4156
4158
|
}
|
@@ -4987,6 +4989,7 @@ const table = [
|
|
4987
4989
|
[478, 0, 'wss'],
|
4988
4990
|
[479, 0, 'p2p-websocket-star'],
|
4989
4991
|
[480, 0, 'http'],
|
4992
|
+
[481, V, 'http-path'],
|
4990
4993
|
[777, V, 'memory']
|
4991
4994
|
];
|
4992
4995
|
// populate tables
|
@@ -5072,6 +5075,8 @@ function convertToString(proto, buf) {
|
|
5072
5075
|
return bytes2onion(buf);
|
5073
5076
|
case 466: // certhash
|
5074
5077
|
return bytes2mb(buf);
|
5078
|
+
case 481: // http-path
|
5079
|
+
return globalThis.encodeURIComponent(bytes2str(buf));
|
5075
5080
|
default:
|
5076
5081
|
return toString$1(buf, 'base16'); // no clue. convert to hex
|
5077
5082
|
}
|
@@ -5106,6 +5111,8 @@ function convertToBytes(proto, str) {
|
|
5106
5111
|
return onion32bytes(str);
|
5107
5112
|
case 466: // certhash
|
5108
5113
|
return mb2bytes(str);
|
5114
|
+
case 481: // http-path
|
5115
|
+
return str2bytes(globalThis.decodeURIComponent(str));
|
5109
5116
|
default:
|
5110
5117
|
return fromString(str, 'base16'); // no clue. convert from hex
|
5111
5118
|
}
|
@@ -6010,9 +6017,9 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
|
6010
6017
|
// This is OK: `abstract` directory does not use noble-hashes.
|
6011
6018
|
// User may opt-in into using different hashing library. This way, noble-hashes
|
6012
6019
|
// won't be included into their bundle.
|
6013
|
-
const _0n$4 = BigInt(0);
|
6014
|
-
const _1n$6 = BigInt(1);
|
6015
|
-
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);
|
6016
6023
|
function isBytes$1(a) {
|
6017
6024
|
return (a instanceof Uint8Array ||
|
6018
6025
|
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
@@ -6021,6 +6028,10 @@ function abytes(item) {
|
|
6021
6028
|
if (!isBytes$1(item))
|
6022
6029
|
throw new Error('Uint8Array expected');
|
6023
6030
|
}
|
6031
|
+
function abool(title, value) {
|
6032
|
+
if (typeof value !== 'boolean')
|
6033
|
+
throw new Error(`${title} must be valid boolean, got "${value}".`);
|
6034
|
+
}
|
6024
6035
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6025
6036
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
6026
6037
|
/**
|
@@ -6163,6 +6174,25 @@ function utf8ToBytes(str) {
|
|
6163
6174
|
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
6164
6175
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6165
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
|
+
}
|
6166
6196
|
// Bit operations
|
6167
6197
|
/**
|
6168
6198
|
* Calculates amount of bits in a bigint.
|
@@ -6293,9 +6323,32 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6293
6323
|
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
6294
6324
|
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
6295
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
|
+
}
|
6296
6347
|
|
6297
6348
|
var ut = /*#__PURE__*/Object.freeze({
|
6298
6349
|
__proto__: null,
|
6350
|
+
aInRange: aInRange,
|
6351
|
+
abool: abool,
|
6299
6352
|
abytes: abytes,
|
6300
6353
|
bitGet: bitGet,
|
6301
6354
|
bitLen: bitLen,
|
@@ -6310,7 +6363,10 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6310
6363
|
equalBytes: equalBytes,
|
6311
6364
|
hexToBytes: hexToBytes,
|
6312
6365
|
hexToNumber: hexToNumber,
|
6366
|
+
inRange: inRange,
|
6313
6367
|
isBytes: isBytes$1,
|
6368
|
+
memoized: memoized,
|
6369
|
+
notImplemented: notImplemented,
|
6314
6370
|
numberToBytesBE: numberToBytesBE,
|
6315
6371
|
numberToBytesLE: numberToBytesLE,
|
6316
6372
|
numberToHexUnpadded: numberToHexUnpadded,
|
@@ -6324,7 +6380,7 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6324
6380
|
// prettier-ignore
|
6325
6381
|
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
|
6326
6382
|
// prettier-ignore
|
6327
|
-
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$
|
6383
|
+
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
|
6328
6384
|
// prettier-ignore
|
6329
6385
|
BigInt(9); BigInt(16);
|
6330
6386
|
// Calculates a modulo b
|
@@ -6470,8 +6526,8 @@ function FpSqrt(P) {
|
|
6470
6526
|
};
|
6471
6527
|
}
|
6472
6528
|
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
6473
|
-
if (P % _8n$
|
6474
|
-
const c1 = (P - _5n$1) / _8n$
|
6529
|
+
if (P % _8n$2 === _5n$1) {
|
6530
|
+
const c1 = (P - _5n$1) / _8n$2;
|
6475
6531
|
return function sqrt5mod8(Fp, n) {
|
6476
6532
|
const n2 = Fp.mul(n, _2n$3);
|
6477
6533
|
const v = Fp.pow(n2, c1);
|
@@ -6569,6 +6625,9 @@ function nLength(n, nBitLength) {
|
|
6569
6625
|
* * a) denormalized operations like mulN instead of mul
|
6570
6626
|
* * b) same object shape: never add or remove keys
|
6571
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.
|
6572
6631
|
* @param ORDER prime positive bigint
|
6573
6632
|
* @param bitLen how many bits the field consumes
|
6574
6633
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6624,12 +6683,6 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6624
6683
|
});
|
6625
6684
|
return Object.freeze(f);
|
6626
6685
|
}
|
6627
|
-
function FpSqrtEven(Fp, elm) {
|
6628
|
-
if (!Fp.isOdd)
|
6629
|
-
throw new Error(`Field doesn't have isOdd`);
|
6630
|
-
const root = Fp.sqrt(elm);
|
6631
|
-
return Fp.isOdd(root) ? Fp.neg(root) : root;
|
6632
|
-
}
|
6633
6686
|
/**
|
6634
6687
|
* Returns total number of bytes consumed by the field element.
|
6635
6688
|
* For example, 32 bytes for usual 256-bit weierstrass curve.
|
@@ -6683,6 +6736,10 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6683
6736
|
// Abelian group utilities
|
6684
6737
|
const _0n$2 = BigInt(0);
|
6685
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)
|
6686
6743
|
// Elliptic curve multiplication of Point by scalar. Fragile.
|
6687
6744
|
// Scalars should always be less than curve order: this should be checked inside of a curve itself.
|
6688
6745
|
// Creates precomputation tables for fast multiplication:
|
@@ -6699,7 +6756,12 @@ function wNAF(c, bits) {
|
|
6699
6756
|
const neg = item.negate();
|
6700
6757
|
return condition ? neg : item;
|
6701
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
|
+
};
|
6702
6763
|
const opts = (W) => {
|
6764
|
+
validateW(W);
|
6703
6765
|
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6704
6766
|
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6705
6767
|
return { windows, windowSize };
|
@@ -6799,19 +6861,25 @@ function wNAF(c, bits) {
|
|
6799
6861
|
// which makes it less const-time: around 1 bigint multiply.
|
6800
6862
|
return { p, f };
|
6801
6863
|
},
|
6802
|
-
wNAFCached(P,
|
6803
|
-
|
6804
|
-
const W = P._WINDOW_SIZE || 1;
|
6864
|
+
wNAFCached(P, n, transform) {
|
6865
|
+
const W = pointWindowSizes.get(P) || 1;
|
6805
6866
|
// Calculate precomputes on a first run, reuse them after
|
6806
|
-
let comp =
|
6867
|
+
let comp = pointPrecomputes.get(P);
|
6807
6868
|
if (!comp) {
|
6808
6869
|
comp = this.precomputeWindow(P, W);
|
6809
|
-
if (W !== 1)
|
6810
|
-
|
6811
|
-
}
|
6870
|
+
if (W !== 1)
|
6871
|
+
pointPrecomputes.set(P, transform(comp));
|
6812
6872
|
}
|
6813
6873
|
return this.wNAF(W, comp, n);
|
6814
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
|
+
},
|
6815
6883
|
};
|
6816
6884
|
}
|
6817
6885
|
function validateBasic(curve) {
|
@@ -6837,7 +6905,7 @@ function validateBasic(curve) {
|
|
6837
6905
|
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
6838
6906
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
6839
6907
|
// prettier-ignore
|
6840
|
-
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);
|
6841
6909
|
// verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
|
6842
6910
|
const VERIFY_DEFAULT = { zip215: true };
|
6843
6911
|
function validateOpts$1(curve) {
|
@@ -6856,7 +6924,13 @@ function validateOpts$1(curve) {
|
|
6856
6924
|
// Set defaults
|
6857
6925
|
return Object.freeze({ ...opts });
|
6858
6926
|
}
|
6859
|
-
|
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
|
+
*/
|
6860
6934
|
function twistedEdwards(curveDef) {
|
6861
6935
|
const CURVE = validateOpts$1(curveDef);
|
6862
6936
|
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
@@ -6875,28 +6949,59 @@ function twistedEdwards(curveDef) {
|
|
6875
6949
|
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
|
6876
6950
|
const domain = CURVE.domain ||
|
6877
6951
|
((data, ctx, phflag) => {
|
6952
|
+
abool('phflag', phflag);
|
6878
6953
|
if (ctx.length || phflag)
|
6879
6954
|
throw new Error('Contexts/pre-hash are not supported');
|
6880
6955
|
return data;
|
6881
6956
|
}); // NOOP
|
6882
|
-
|
6883
|
-
|
6884
|
-
|
6885
|
-
|
6886
|
-
|
6887
|
-
|
6888
|
-
return n;
|
6889
|
-
throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
|
6890
|
-
}
|
6891
|
-
function assertGE0(n) {
|
6892
|
-
// n in [0..CURVE_ORDER-1]
|
6893
|
-
return n === _0n$1 ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
|
6894
|
-
}
|
6895
|
-
const pointPrecomputes = new Map();
|
6896
|
-
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) {
|
6897
6963
|
if (!(other instanceof Point))
|
6898
6964
|
throw new Error('ExtendedPoint expected');
|
6899
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
|
+
});
|
6900
7005
|
// Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
|
6901
7006
|
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
6902
7007
|
class Point {
|
@@ -6905,14 +7010,11 @@ function twistedEdwards(curveDef) {
|
|
6905
7010
|
this.ey = ey;
|
6906
7011
|
this.ez = ez;
|
6907
7012
|
this.et = et;
|
6908
|
-
|
6909
|
-
|
6910
|
-
|
6911
|
-
|
6912
|
-
|
6913
|
-
throw new Error('z required');
|
6914
|
-
if (!in0MaskRange(et))
|
6915
|
-
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);
|
6916
7018
|
}
|
6917
7019
|
get x() {
|
6918
7020
|
return this.toAffine().x;
|
@@ -6924,8 +7026,8 @@ function twistedEdwards(curveDef) {
|
|
6924
7026
|
if (p instanceof Point)
|
6925
7027
|
throw new Error('extended point not allowed');
|
6926
7028
|
const { x, y } = p || {};
|
6927
|
-
|
6928
|
-
|
7029
|
+
aCoordinate('x', x);
|
7030
|
+
aCoordinate('y', y);
|
6929
7031
|
return new Point(x, y, _1n$3, modP(x * y));
|
6930
7032
|
}
|
6931
7033
|
static normalizeZ(points) {
|
@@ -6934,36 +7036,16 @@ function twistedEdwards(curveDef) {
|
|
6934
7036
|
}
|
6935
7037
|
// "Private method", don't use it directly
|
6936
7038
|
_setWindowSize(windowSize) {
|
6937
|
-
this
|
6938
|
-
pointPrecomputes.delete(this);
|
7039
|
+
wnaf.setWindowSize(this, windowSize);
|
6939
7040
|
}
|
6940
7041
|
// Not required for fromHex(), which always creates valid points.
|
6941
7042
|
// Could be useful for fromAffine().
|
6942
7043
|
assertValidity() {
|
6943
|
-
|
6944
|
-
if (this.is0())
|
6945
|
-
throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
|
6946
|
-
// Equation in affine coordinates: ax² + y² = 1 + dx²y²
|
6947
|
-
// Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
|
6948
|
-
const { ex: X, ey: Y, ez: Z, et: T } = this;
|
6949
|
-
const X2 = modP(X * X); // X²
|
6950
|
-
const Y2 = modP(Y * Y); // Y²
|
6951
|
-
const Z2 = modP(Z * Z); // Z²
|
6952
|
-
const Z4 = modP(Z2 * Z2); // Z⁴
|
6953
|
-
const aX2 = modP(X2 * a); // aX²
|
6954
|
-
const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
|
6955
|
-
const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
|
6956
|
-
if (left !== right)
|
6957
|
-
throw new Error('bad point: equation left != right (1)');
|
6958
|
-
// In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
|
6959
|
-
const XY = modP(X * Y);
|
6960
|
-
const ZT = modP(Z * T);
|
6961
|
-
if (XY !== ZT)
|
6962
|
-
throw new Error('bad point: equation left != right (2)');
|
7044
|
+
assertValidMemo(this);
|
6963
7045
|
}
|
6964
7046
|
// Compare one point to another.
|
6965
7047
|
equals(other) {
|
6966
|
-
|
7048
|
+
assertPoint(other);
|
6967
7049
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
6968
7050
|
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
6969
7051
|
const X1Z2 = modP(X1 * Z2);
|
@@ -7004,7 +7086,7 @@ function twistedEdwards(curveDef) {
|
|
7004
7086
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
7005
7087
|
// Cost: 9M + 1*a + 1*d + 7add.
|
7006
7088
|
add(other) {
|
7007
|
-
|
7089
|
+
assertPoint(other);
|
7008
7090
|
const { a, d } = CURVE;
|
7009
7091
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
7010
7092
|
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
@@ -7047,11 +7129,13 @@ function twistedEdwards(curveDef) {
|
|
7047
7129
|
return this.add(other.negate());
|
7048
7130
|
}
|
7049
7131
|
wNAF(n) {
|
7050
|
-
return wnaf.wNAFCached(this,
|
7132
|
+
return wnaf.wNAFCached(this, n, Point.normalizeZ);
|
7051
7133
|
}
|
7052
7134
|
// Constant-time multiplication.
|
7053
7135
|
multiply(scalar) {
|
7054
|
-
const
|
7136
|
+
const n = scalar;
|
7137
|
+
aInRange('scalar', n, _1n$3, CURVE_ORDER); // 1 <= scalar < L
|
7138
|
+
const { p, f } = this.wNAF(n);
|
7055
7139
|
return Point.normalizeZ([p, f])[0];
|
7056
7140
|
}
|
7057
7141
|
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
@@ -7059,7 +7143,8 @@ function twistedEdwards(curveDef) {
|
|
7059
7143
|
// an exposed private key e.g. sig verification.
|
7060
7144
|
// Does NOT allow scalars higher than CURVE.n.
|
7061
7145
|
multiplyUnsafe(scalar) {
|
7062
|
-
|
7146
|
+
const n = scalar;
|
7147
|
+
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7063
7148
|
if (n === _0n$1)
|
7064
7149
|
return I;
|
7065
7150
|
if (this.equals(I) || n === _1n$3)
|
@@ -7083,18 +7168,7 @@ function twistedEdwards(curveDef) {
|
|
7083
7168
|
// Converts Extended point to default (x, y) coordinates.
|
7084
7169
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
7085
7170
|
toAffine(iz) {
|
7086
|
-
|
7087
|
-
const is0 = this.is0();
|
7088
|
-
if (iz == null)
|
7089
|
-
iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
|
7090
|
-
const ax = modP(x * iz);
|
7091
|
-
const ay = modP(y * iz);
|
7092
|
-
const zz = modP(z * iz);
|
7093
|
-
if (is0)
|
7094
|
-
return { x: _0n$1, y: _1n$3 };
|
7095
|
-
if (zz !== _1n$3)
|
7096
|
-
throw new Error('invZ was invalid');
|
7097
|
-
return { x: ax, y: ay };
|
7171
|
+
return toAffineMemo(this, iz);
|
7098
7172
|
}
|
7099
7173
|
clearCofactor() {
|
7100
7174
|
const { h: cofactor } = CURVE;
|
@@ -7108,18 +7182,16 @@ function twistedEdwards(curveDef) {
|
|
7108
7182
|
const { d, a } = CURVE;
|
7109
7183
|
const len = Fp.BYTES;
|
7110
7184
|
hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
|
7185
|
+
abool('zip215', zip215);
|
7111
7186
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7112
7187
|
const lastByte = hex[len - 1]; // select last byte
|
7113
7188
|
normed[len - 1] = lastByte & ~0x80; // clear last bit
|
7114
7189
|
const y = bytesToNumberLE(normed);
|
7115
|
-
|
7116
|
-
|
7117
|
-
|
7118
|
-
|
7119
|
-
|
7120
|
-
else
|
7121
|
-
assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
|
7122
|
-
}
|
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);
|
7123
7195
|
// Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
|
7124
7196
|
// ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
|
7125
7197
|
const y2 = modP(y * y); // denominator is always non-0 mod p.
|
@@ -7194,7 +7266,7 @@ function twistedEdwards(curveDef) {
|
|
7194
7266
|
const R = G.multiply(r).toRawBytes(); // R = rG
|
7195
7267
|
const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
|
7196
7268
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7197
|
-
|
7269
|
+
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7198
7270
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7199
7271
|
return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
|
7200
7272
|
}
|
@@ -7204,6 +7276,8 @@ function twistedEdwards(curveDef) {
|
|
7204
7276
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7205
7277
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7206
7278
|
msg = ensureBytes('message', msg);
|
7279
|
+
if (zip215 !== undefined)
|
7280
|
+
abool('zip215', zip215);
|
7207
7281
|
if (prehash)
|
7208
7282
|
msg = prehash(msg); // for ed25519ph, etc
|
7209
7283
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
@@ -7261,12 +7335,14 @@ function twistedEdwards(curveDef) {
|
|
7261
7335
|
*/
|
7262
7336
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7263
7337
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
7264
|
-
const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
7338
|
+
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
7265
7339
|
// prettier-ignore
|
7266
|
-
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);
|
7267
7341
|
// prettier-ignore
|
7268
|
-
const
|
7342
|
+
const _5n = BigInt(5), _8n = BigInt(8);
|
7269
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);
|
7270
7346
|
const P = ED25519_P;
|
7271
7347
|
const x2 = (x * x) % P;
|
7272
7348
|
const b2 = (x2 * x) % P; // x^3, 11
|
@@ -7315,8 +7391,8 @@ function uvRatio(u, v) {
|
|
7315
7391
|
x = mod(-x, P);
|
7316
7392
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7317
7393
|
}
|
7318
|
-
const Fp$1 = Field(ED25519_P, undefined, true);
|
7319
|
-
const ed25519Defaults = {
|
7394
|
+
const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7395
|
+
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7320
7396
|
// Param: a
|
7321
7397
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
7322
7398
|
// d is equal to -121665/121666 over finite field.
|
@@ -7328,7 +7404,7 @@ const ed25519Defaults = {
|
|
7328
7404
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7329
7405
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
7330
7406
|
// Cofactor
|
7331
|
-
h:
|
7407
|
+
h: _8n,
|
7332
7408
|
// Base point (x, y) aka generator point
|
7333
7409
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
7334
7410
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
@@ -7339,40 +7415,11 @@ const ed25519Defaults = {
|
|
7339
7415
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
7340
7416
|
// Constant-time, u/√v
|
7341
7417
|
uvRatio,
|
7342
|
-
};
|
7343
|
-
|
7344
|
-
|
7345
|
-
|
7346
|
-
|
7347
|
-
return concatBytes$1(utf8ToBytes$1('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
|
7348
|
-
}
|
7349
|
-
/* @__PURE__ */ twistedEdwards({
|
7350
|
-
...ed25519Defaults,
|
7351
|
-
domain: ed25519_domain,
|
7352
|
-
});
|
7353
|
-
/* @__PURE__ */ twistedEdwards({
|
7354
|
-
...ed25519Defaults,
|
7355
|
-
domain: ed25519_domain,
|
7356
|
-
prehash: sha512,
|
7357
|
-
});
|
7358
|
-
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
7359
|
-
// NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
|
7360
|
-
// SageMath returns different root first and everything falls apart
|
7361
|
-
const ELL2_C1 = (Fp$1.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
|
7362
|
-
Fp$1.pow(_2n$1, ELL2_C1); // 2. c2 = 2^c1
|
7363
|
-
Fp$1.sqrt(Fp$1.neg(Fp$1.ONE)); // 3. c3 = sqrt(-1)
|
7364
|
-
(Fp$1.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
|
7365
|
-
BigInt(486662);
|
7366
|
-
FpSqrtEven(Fp$1, Fp$1.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
|
7367
|
-
// √(ad - 1)
|
7368
|
-
BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
7369
|
-
// 1 / √(a-d)
|
7370
|
-
BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
7371
|
-
// 1-d²
|
7372
|
-
BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
7373
|
-
// (d-1)²
|
7374
|
-
BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
7375
|
-
BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
7418
|
+
}))();
|
7419
|
+
/**
|
7420
|
+
* ed25519 curve with EdDSA signatures.
|
7421
|
+
*/
|
7422
|
+
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7376
7423
|
|
7377
7424
|
const PUBLIC_KEY_BYTE_LENGTH = 32;
|
7378
7425
|
const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
@@ -7429,7 +7476,7 @@ function concatKeys(privateKeyRaw, publicKey) {
|
|
7429
7476
|
var webcrypto = {
|
7430
7477
|
get(win = globalThis) {
|
7431
7478
|
const nativeCrypto = win.crypto;
|
7432
|
-
if (nativeCrypto
|
7479
|
+
if (nativeCrypto?.subtle == null) {
|
7433
7480
|
throw Object.assign(new Error('Missing Web Crypto API. ' +
|
7434
7481
|
'The most likely cause of this error is that this page is being accessed ' +
|
7435
7482
|
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
@@ -7453,12 +7500,12 @@ var webcrypto = {
|
|
7453
7500
|
const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
|
7454
7501
|
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
|
7455
7502
|
function create(opts) {
|
7456
|
-
const algorithm =
|
7457
|
-
let keyLength =
|
7458
|
-
const nonceLength =
|
7459
|
-
const digest =
|
7460
|
-
const saltLength =
|
7461
|
-
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;
|
7462
7509
|
const crypto = webcrypto.get();
|
7463
7510
|
keyLength *= 8; // Browser crypto uses bits instead of bytes
|
7464
7511
|
/**
|
@@ -8242,7 +8289,7 @@ function decodeMessage(buf, codec, opts) {
|
|
8242
8289
|
* A general purpose buffer pool
|
8243
8290
|
*/
|
8244
8291
|
function pool(size) {
|
8245
|
-
const SIZE =
|
8292
|
+
const SIZE = 8192;
|
8246
8293
|
const MAX = SIZE >>> 1;
|
8247
8294
|
let slab;
|
8248
8295
|
let offset = SIZE;
|
@@ -12830,6 +12877,12 @@ var RSA = /*#__PURE__*/Object.freeze({
|
|
12830
12877
|
|
12831
12878
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
12832
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
|
+
}
|
12833
12886
|
function validatePointOpts(curve) {
|
12834
12887
|
const opts = validateBasic(curve);
|
12835
12888
|
validateObject(opts, {
|
@@ -12954,16 +13007,12 @@ function weierstrassPoints(opts) {
|
|
12954
13007
|
throw new Error('bad generator point: equation left != right');
|
12955
13008
|
// Valid group elements reside in range 1..n-1
|
12956
13009
|
function isWithinCurveOrder(num) {
|
12957
|
-
return
|
12958
|
-
}
|
12959
|
-
function assertGE(num) {
|
12960
|
-
if (!isWithinCurveOrder(num))
|
12961
|
-
throw new Error('Expected valid bigint: 0 < bigint < curve.n');
|
13010
|
+
return inRange(num, _1n$1, CURVE.n);
|
12962
13011
|
}
|
12963
13012
|
// Validates if priv key is valid and converts it to bigint.
|
12964
13013
|
// Supports options allowedPrivateKeyLengths and wrapPrivateKey.
|
12965
13014
|
function normPrivateKeyToScalar(key) {
|
12966
|
-
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
|
13015
|
+
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
|
12967
13016
|
if (lengths && typeof key !== 'bigint') {
|
12968
13017
|
if (isBytes$1(key))
|
12969
13018
|
key = bytesToHex(key);
|
@@ -12983,15 +13032,61 @@ function weierstrassPoints(opts) {
|
|
12983
13032
|
throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
|
12984
13033
|
}
|
12985
13034
|
if (wrapPrivateKey)
|
12986
|
-
num = mod(num,
|
12987
|
-
|
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]
|
12988
13037
|
return num;
|
12989
13038
|
}
|
12990
|
-
const pointPrecomputes = new Map();
|
12991
13039
|
function assertPrjPoint(other) {
|
12992
13040
|
if (!(other instanceof Point))
|
12993
13041
|
throw new Error('ProjectivePoint expected');
|
12994
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
|
+
});
|
12995
13090
|
/**
|
12996
13091
|
* Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
|
12997
13092
|
* Default Point works in 2d / affine coordinates: (x, y)
|
@@ -13008,6 +13103,7 @@ function weierstrassPoints(opts) {
|
|
13008
13103
|
throw new Error('y required');
|
13009
13104
|
if (pz == null || !Fp.isValid(pz))
|
13010
13105
|
throw new Error('z required');
|
13106
|
+
Object.freeze(this);
|
13011
13107
|
}
|
13012
13108
|
// Does not validate if the point is on-curve.
|
13013
13109
|
// Use fromHex instead, or call assertValidity() later.
|
@@ -13054,30 +13150,11 @@ function weierstrassPoints(opts) {
|
|
13054
13150
|
}
|
13055
13151
|
// "Private method", don't use it directly
|
13056
13152
|
_setWindowSize(windowSize) {
|
13057
|
-
this
|
13058
|
-
pointPrecomputes.delete(this);
|
13153
|
+
wnaf.setWindowSize(this, windowSize);
|
13059
13154
|
}
|
13060
13155
|
// A point on curve is valid if it conforms to equation.
|
13061
13156
|
assertValidity() {
|
13062
|
-
|
13063
|
-
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13064
|
-
// In BLS, ZERO can be serialized, so we allow it.
|
13065
|
-
// (0, 0, 0) is wrong representation of ZERO and is always invalid.
|
13066
|
-
if (CURVE.allowInfinityPoint && !Fp.is0(this.py))
|
13067
|
-
return;
|
13068
|
-
throw new Error('bad point: ZERO');
|
13069
|
-
}
|
13070
|
-
// Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
|
13071
|
-
const { x, y } = this.toAffine();
|
13072
|
-
// Check if x, y are valid field elements
|
13073
|
-
if (!Fp.isValid(x) || !Fp.isValid(y))
|
13074
|
-
throw new Error('bad point: x or y not FE');
|
13075
|
-
const left = Fp.sqr(y); // y²
|
13076
|
-
const right = weierstrassEquation(x); // x³ + ax + b
|
13077
|
-
if (!Fp.eql(left, right))
|
13078
|
-
throw new Error('bad point: equation left != right');
|
13079
|
-
if (!this.isTorsionFree())
|
13080
|
-
throw new Error('bad point: not in prime-order subgroup');
|
13157
|
+
assertValidMemo(this);
|
13081
13158
|
}
|
13082
13159
|
hasEvenY() {
|
13083
13160
|
const { y } = this.toAffine();
|
@@ -13204,28 +13281,25 @@ function weierstrassPoints(opts) {
|
|
13204
13281
|
return this.equals(Point.ZERO);
|
13205
13282
|
}
|
13206
13283
|
wNAF(n) {
|
13207
|
-
return wnaf.wNAFCached(this,
|
13208
|
-
const toInv = Fp.invertBatch(comp.map((p) => p.pz));
|
13209
|
-
return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
13210
|
-
});
|
13284
|
+
return wnaf.wNAFCached(this, n, Point.normalizeZ);
|
13211
13285
|
}
|
13212
13286
|
/**
|
13213
13287
|
* Non-constant-time multiplication. Uses double-and-add algorithm.
|
13214
13288
|
* It's faster, but should only be used when you don't care about
|
13215
13289
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
13216
13290
|
*/
|
13217
|
-
multiplyUnsafe(
|
13291
|
+
multiplyUnsafe(sc) {
|
13292
|
+
aInRange('scalar', sc, _0n, CURVE.n);
|
13218
13293
|
const I = Point.ZERO;
|
13219
|
-
if (
|
13294
|
+
if (sc === _0n)
|
13220
13295
|
return I;
|
13221
|
-
|
13222
|
-
if (n === _1n$1)
|
13296
|
+
if (sc === _1n$1)
|
13223
13297
|
return this;
|
13224
13298
|
const { endo } = CURVE;
|
13225
13299
|
if (!endo)
|
13226
|
-
return wnaf.unsafeLadder(this,
|
13300
|
+
return wnaf.unsafeLadder(this, sc);
|
13227
13301
|
// Apply endomorphism
|
13228
|
-
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(
|
13302
|
+
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
13229
13303
|
let k1p = I;
|
13230
13304
|
let k2p = I;
|
13231
13305
|
let d = this;
|
@@ -13255,12 +13329,11 @@ function weierstrassPoints(opts) {
|
|
13255
13329
|
* @returns New point
|
13256
13330
|
*/
|
13257
13331
|
multiply(scalar) {
|
13258
|
-
|
13259
|
-
|
13332
|
+
const { endo, n: N } = CURVE;
|
13333
|
+
aInRange('scalar', scalar, _1n$1, N);
|
13260
13334
|
let point, fake; // Fake point is used to const-time mult
|
13261
|
-
const { endo } = CURVE;
|
13262
13335
|
if (endo) {
|
13263
|
-
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(
|
13336
|
+
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
|
13264
13337
|
let { p: k1p, f: f1p } = this.wNAF(k1);
|
13265
13338
|
let { p: k2p, f: f2p } = this.wNAF(k2);
|
13266
13339
|
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
@@ -13270,7 +13343,7 @@ function weierstrassPoints(opts) {
|
|
13270
13343
|
fake = f1p.add(f2p);
|
13271
13344
|
}
|
13272
13345
|
else {
|
13273
|
-
const { p, f } = this.wNAF(
|
13346
|
+
const { p, f } = this.wNAF(scalar);
|
13274
13347
|
point = p;
|
13275
13348
|
fake = f;
|
13276
13349
|
}
|
@@ -13294,20 +13367,7 @@ function weierstrassPoints(opts) {
|
|
13294
13367
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
13295
13368
|
// (x, y, z) ∋ (x=x/z, y=y/z)
|
13296
13369
|
toAffine(iz) {
|
13297
|
-
|
13298
|
-
const is0 = this.is0();
|
13299
|
-
// If invZ was 0, we return zero point. However we still want to execute
|
13300
|
-
// all operations, so we replace invZ with a random number, 1.
|
13301
|
-
if (iz == null)
|
13302
|
-
iz = is0 ? Fp.ONE : Fp.inv(z);
|
13303
|
-
const ax = Fp.mul(x, iz);
|
13304
|
-
const ay = Fp.mul(y, iz);
|
13305
|
-
const zz = Fp.mul(z, iz);
|
13306
|
-
if (is0)
|
13307
|
-
return { x: Fp.ZERO, y: Fp.ZERO };
|
13308
|
-
if (!Fp.eql(zz, Fp.ONE))
|
13309
|
-
throw new Error('invZ was invalid');
|
13310
|
-
return { x: ax, y: ay };
|
13370
|
+
return toAffineMemo(this, iz);
|
13311
13371
|
}
|
13312
13372
|
isTorsionFree() {
|
13313
13373
|
const { h: cofactor, isTorsionFree } = CURVE;
|
@@ -13326,10 +13386,12 @@ function weierstrassPoints(opts) {
|
|
13326
13386
|
return this.multiplyUnsafe(CURVE.h);
|
13327
13387
|
}
|
13328
13388
|
toRawBytes(isCompressed = true) {
|
13389
|
+
abool('isCompressed', isCompressed);
|
13329
13390
|
this.assertValidity();
|
13330
13391
|
return toBytes(Point, this, isCompressed);
|
13331
13392
|
}
|
13332
13393
|
toHex(isCompressed = true) {
|
13394
|
+
abool('isCompressed', isCompressed);
|
13333
13395
|
return bytesToHex(this.toRawBytes(isCompressed));
|
13334
13396
|
}
|
13335
13397
|
}
|
@@ -13359,14 +13421,18 @@ function validateOpts(curve) {
|
|
13359
13421
|
});
|
13360
13422
|
return Object.freeze({ lowS: true, ...opts });
|
13361
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
|
+
*/
|
13362
13431
|
function weierstrass(curveDef) {
|
13363
13432
|
const CURVE = validateOpts(curveDef);
|
13364
13433
|
const { Fp, n: CURVE_ORDER } = CURVE;
|
13365
13434
|
const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
|
13366
13435
|
const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
|
13367
|
-
function isValidFieldElement(num) {
|
13368
|
-
return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE
|
13369
|
-
}
|
13370
13436
|
function modN(a) {
|
13371
13437
|
return mod(a, CURVE_ORDER);
|
13372
13438
|
}
|
@@ -13379,6 +13445,7 @@ function weierstrass(curveDef) {
|
|
13379
13445
|
const a = point.toAffine();
|
13380
13446
|
const x = Fp.toBytes(a.x);
|
13381
13447
|
const cat = concatBytes;
|
13448
|
+
abool('isCompressed', isCompressed);
|
13382
13449
|
if (isCompressed) {
|
13383
13450
|
return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
|
13384
13451
|
}
|
@@ -13393,7 +13460,7 @@ function weierstrass(curveDef) {
|
|
13393
13460
|
// this.assertValidity() is done inside of fromHex
|
13394
13461
|
if (len === compressedLen && (head === 0x02 || head === 0x03)) {
|
13395
13462
|
const x = bytesToNumberBE(tail);
|
13396
|
-
if (!
|
13463
|
+
if (!inRange(x, _1n$1, Fp.ORDER))
|
13397
13464
|
throw new Error('Point is not on curve');
|
13398
13465
|
const y2 = weierstrassEquation(x); // y² = x³ + ax + b
|
13399
13466
|
let y;
|
@@ -13454,11 +13521,8 @@ function weierstrass(curveDef) {
|
|
13454
13521
|
return new Signature(r, s);
|
13455
13522
|
}
|
13456
13523
|
assertValidity() {
|
13457
|
-
//
|
13458
|
-
|
13459
|
-
throw new Error('r must be 0 < r < CURVE.n');
|
13460
|
-
if (!isWithinCurveOrder(this.s))
|
13461
|
-
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]
|
13462
13526
|
}
|
13463
13527
|
addRecoveryBit(recovery) {
|
13464
13528
|
return new Signature(this.r, this.s, recovery);
|
@@ -13601,10 +13665,7 @@ function weierstrass(curveDef) {
|
|
13601
13665
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13602
13666
|
*/
|
13603
13667
|
function int2octets(num) {
|
13604
|
-
|
13605
|
-
throw new Error('bigint expected');
|
13606
|
-
if (!(_0n <= num && num < ORDER_MASK))
|
13607
|
-
throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
|
13668
|
+
aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
|
13608
13669
|
// works with order, can have different size than numToField!
|
13609
13670
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13610
13671
|
}
|
@@ -13621,6 +13682,7 @@ function weierstrass(curveDef) {
|
|
13621
13682
|
if (lowS == null)
|
13622
13683
|
lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
|
13623
13684
|
msgHash = ensureBytes('msgHash', msgHash);
|
13685
|
+
validateSigVerOpts(opts);
|
13624
13686
|
if (prehash)
|
13625
13687
|
msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
|
13626
13688
|
// We can't later call bits2octets, since nested bits2int is broken for curves
|
@@ -13707,6 +13769,7 @@ function weierstrass(curveDef) {
|
|
13707
13769
|
publicKey = ensureBytes('publicKey', publicKey);
|
13708
13770
|
if ('strict' in opts)
|
13709
13771
|
throw new Error('options.strict was renamed to lowS');
|
13772
|
+
validateSigVerOpts(opts);
|
13710
13773
|
const { lowS, prehash } = opts;
|
13711
13774
|
let _sig = undefined;
|
13712
13775
|
let P;
|
@@ -13813,6 +13876,9 @@ function sqrtMod(y) {
|
|
13813
13876
|
return root;
|
13814
13877
|
}
|
13815
13878
|
const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
13879
|
+
/**
|
13880
|
+
* secp256k1 short weierstrass curve and ECDSA signatures over it.
|
13881
|
+
*/
|
13816
13882
|
const secp256k1 = createCurve({
|
13817
13883
|
a: BigInt(0), // equation params: a, b
|
13818
13884
|
b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
|
@@ -14218,6 +14284,41 @@ class Secp256k1PeerIdImpl extends PeerIdImpl {
|
|
14218
14284
|
this.publicKey = init.multihash.digest;
|
14219
14285
|
}
|
14220
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
|
+
}
|
14221
14322
|
function peerIdFromString(str, decoder) {
|
14222
14323
|
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
14223
14324
|
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
@@ -14256,9 +14357,13 @@ function peerIdFromBytes(buf) {
|
|
14256
14357
|
throw new Error('Supplied PeerID CID is invalid');
|
14257
14358
|
}
|
14258
14359
|
function peerIdFromCID(cid) {
|
14259
|
-
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)) {
|
14260
14361
|
throw new Error('Supplied PeerID CID is invalid');
|
14261
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
|
+
}
|
14262
14367
|
const multihash = cid.multihash;
|
14263
14368
|
if (multihash.code === sha256$1.code) {
|
14264
14369
|
return new RSAPeerIdImpl({ multihash: cid.multihash });
|
@@ -14295,6 +14400,9 @@ function getPublicKeyFromPeerId(peerId) {
|
|
14295
14400
|
if (peerId.type !== "secp256k1") {
|
14296
14401
|
throw new Error("Unsupported peer id type");
|
14297
14402
|
}
|
14403
|
+
if (!peerId.publicKey) {
|
14404
|
+
throw new Error("Public key not present on peer id");
|
14405
|
+
}
|
14298
14406
|
return unmarshalPublicKey(peerId.publicKey).marshal();
|
14299
14407
|
}
|
14300
14408
|
// Only used in tests
|
@@ -15143,9 +15251,6 @@ function isHexString(value, length) {
|
|
15143
15251
|
if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
|
15144
15252
|
return false;
|
15145
15253
|
}
|
15146
|
-
if (length && value.length !== 2 + 2 * length) {
|
15147
|
-
return false;
|
15148
|
-
}
|
15149
15254
|
return true;
|
15150
15255
|
}
|
15151
15256
|
const HexCharacters = "0123456789abcdef";
|