@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 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$2 = BigInt(8);
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$2 * C);
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$2 : invert$1(z);
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(RegExp.$1, 10) >= 31) ||
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$1 = BigInt(8);
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$1 === _5n$1) {
6468
- const c1 = (P - _5n$1) / _8n$1;
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, precomputesMap, n, transform) {
6797
- // @ts-ignore
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 = precomputesMap.get(P);
6867
+ let comp = pointPrecomputes.get(P);
6801
6868
  if (!comp) {
6802
6869
  comp = this.precomputeWindow(P, W);
6803
- if (W !== 1) {
6804
- precomputesMap.set(P, transform(comp));
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
- // It is not generic twisted curve for now, but ed25519/ed448 generic implementation
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
- const inBig = (n) => typeof n === 'bigint' && _0n$1 < n; // n in [1..]
6877
- const inRange = (n, max) => inBig(n) && inBig(max) && n < max; // n in [1..max-1]
6878
- const in0MaskRange = (n) => n === _0n$1 || inRange(n, MASK); // n in [0..MASK-1]
6879
- function assertInRange(n, max) {
6880
- // n in [1..max-1]
6881
- if (inRange(n, max))
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
- if (!in0MaskRange(ex))
6903
- throw new Error('x required');
6904
- if (!in0MaskRange(ey))
6905
- throw new Error('y required');
6906
- if (!in0MaskRange(ez))
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
- if (!in0MaskRange(x) || !in0MaskRange(y))
6922
- throw new Error('invalid affine point');
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._WINDOW_SIZE = windowSize;
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
- const { a, d } = CURVE;
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
- isPoint(other);
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
- isPoint(other);
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, pointPrecomputes, n, Point.normalizeZ);
7132
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
7045
7133
  }
7046
7134
  // Constant-time multiplication.
7047
7135
  multiply(scalar) {
7048
- const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
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
- let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
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
- const { ex: x, ey: y, ez: z } = this;
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
- if (y === _0n$1) ;
7110
- else {
7111
- // RFC8032 prohibits >= p, but ZIP215 doesn't
7112
- if (zip215)
7113
- assertInRange(y, MASK); // zip215=true [1..P-1] (2^255-19-1 for ed25519)
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
- assertGE0(s); // 0 <= s < l
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), _5n = BigInt(5);
7340
+ BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
7261
7341
  // prettier-ignore
7262
- const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
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: BigInt(8),
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
- const ed25519 = /* @__PURE__ */ twistedEdwards(ed25519Defaults);
7338
- function ed25519_domain(data, ctx, phflag) {
7339
- if (ctx.length > 255)
7340
- throw new Error('Context is too big');
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 == null || nativeCrypto.subtle == null) {
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 = opts?.algorithm ?? 'AES-GCM';
7451
- let keyLength = opts?.keyLength ?? 16;
7452
- const nonceLength = opts?.nonceLength ?? 12;
7453
- const digest = opts?.digest ?? 'SHA-256';
7454
- const saltLength = opts?.saltLength ?? 16;
7455
- const iterations = opts?.iterations ?? 32767;
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 = size ?? 8192;
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 typeof num === 'bigint' && _0n < num && num < CURVE.n;
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, n); // disabled by default, enabled for BLS
12981
- assertGE(num); // num in range [1..N-1]
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._WINDOW_SIZE = windowSize;
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
- if (this.is0()) {
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, pointPrecomputes, n, (comp) => {
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(n) {
13291
+ multiplyUnsafe(sc) {
13292
+ aInRange('scalar', sc, _0n, CURVE.n);
13212
13293
  const I = Point.ZERO;
13213
- if (n === _0n)
13294
+ if (sc === _0n)
13214
13295
  return I;
13215
- assertGE(n); // Will throw on 0
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, n);
13300
+ return wnaf.unsafeLadder(this, sc);
13221
13301
  // Apply endomorphism
13222
- let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
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
- assertGE(scalar);
13253
- let n = scalar;
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(n);
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(n);
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
- const { px: x, py: y, pz: z } = this;
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 (!isValidFieldElement(x))
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
- // can use assertGE here
13452
- if (!isWithinCurveOrder(this.r))
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
- if (typeof num !== 'bigint')
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.multihash == null || cid.version == null || (cid.version === 1 && cid.code !== LIBP2P_KEY_CODE)) {
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";