@waku/enr 0.0.25-15400a5.0 → 0.0.25-409642d.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundle/index.js 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;
@@ -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(RegExp.$1, 10) >= 31) ||
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$1 = BigInt(8);
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$1 === _5n$1) {
6474
- const c1 = (P - _5n$1) / _8n$1;
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, precomputesMap, n, transform) {
6803
- // @ts-ignore
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 = precomputesMap.get(P);
6867
+ let comp = pointPrecomputes.get(P);
6807
6868
  if (!comp) {
6808
6869
  comp = this.precomputeWindow(P, W);
6809
- if (W !== 1) {
6810
- precomputesMap.set(P, transform(comp));
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
- // 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
+ */
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
- const inBig = (n) => typeof n === 'bigint' && _0n$1 < n; // n in [1..]
6883
- const inRange = (n, max) => inBig(n) && inBig(max) && n < max; // n in [1..max-1]
6884
- const in0MaskRange = (n) => n === _0n$1 || inRange(n, MASK); // n in [0..MASK-1]
6885
- function assertInRange(n, max) {
6886
- // n in [1..max-1]
6887
- if (inRange(n, max))
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
- if (!in0MaskRange(ex))
6909
- throw new Error('x required');
6910
- if (!in0MaskRange(ey))
6911
- throw new Error('y required');
6912
- if (!in0MaskRange(ez))
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
- if (!in0MaskRange(x) || !in0MaskRange(y))
6928
- throw new Error('invalid affine point');
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._WINDOW_SIZE = windowSize;
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
- const { a, d } = CURVE;
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
- isPoint(other);
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
- isPoint(other);
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, pointPrecomputes, n, Point.normalizeZ);
7132
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
7051
7133
  }
7052
7134
  // Constant-time multiplication.
7053
7135
  multiply(scalar) {
7054
- 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);
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
- let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
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
- const { ex: x, ey: y, ez: z } = this;
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
- if (y === _0n$1) ;
7116
- else {
7117
- // RFC8032 prohibits >= p, but ZIP215 doesn't
7118
- if (zip215)
7119
- assertInRange(y, MASK); // zip215=true [1..P-1] (2^255-19-1 for ed25519)
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
- assertGE0(s); // 0 <= s < l
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), _5n = BigInt(5);
7340
+ BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
7267
7341
  // prettier-ignore
7268
- const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
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: BigInt(8),
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
- const ed25519 = /* @__PURE__ */ twistedEdwards(ed25519Defaults);
7344
- function ed25519_domain(data, ctx, phflag) {
7345
- if (ctx.length > 255)
7346
- throw new Error('Context is too big');
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 == null || nativeCrypto.subtle == null) {
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 = opts?.algorithm ?? 'AES-GCM';
7457
- let keyLength = opts?.keyLength ?? 16;
7458
- const nonceLength = opts?.nonceLength ?? 12;
7459
- const digest = opts?.digest ?? 'SHA-256';
7460
- const saltLength = opts?.saltLength ?? 16;
7461
- 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;
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 = size ?? 8192;
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 typeof num === 'bigint' && _0n < num && num < CURVE.n;
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, n); // disabled by default, enabled for BLS
12987
- 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]
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._WINDOW_SIZE = windowSize;
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
- if (this.is0()) {
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, pointPrecomputes, n, (comp) => {
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(n) {
13291
+ multiplyUnsafe(sc) {
13292
+ aInRange('scalar', sc, _0n, CURVE.n);
13218
13293
  const I = Point.ZERO;
13219
- if (n === _0n)
13294
+ if (sc === _0n)
13220
13295
  return I;
13221
- assertGE(n); // Will throw on 0
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, n);
13300
+ return wnaf.unsafeLadder(this, sc);
13227
13301
  // Apply endomorphism
13228
- let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
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
- assertGE(scalar);
13259
- let n = scalar;
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(n);
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(n);
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
- const { px: x, py: y, pz: z } = this;
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 (!isValidFieldElement(x))
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
- // can use assertGE here
13458
- if (!isWithinCurveOrder(this.r))
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
- if (typeof num !== 'bigint')
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.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)) {
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";