@waku/enr 0.0.25-ce62600.0 → 0.0.25

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
@@ -3493,7 +3498,7 @@ var ProtocolError;
3493
3498
  * The remote peer did not behave as expected. Mitigation for `NO_PEER_AVAILABLE`
3494
3499
  * or `DECODE_FAILED` can be used.
3495
3500
  */
3496
- ProtocolError["REMOTE_PEER_FAULT"] = "Remote peer fault";
3501
+ ProtocolError["NO_RESPONSE"] = "No response received";
3497
3502
  /**
3498
3503
  * The remote peer rejected the message. Information provided by the remote peer
3499
3504
  * is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
@@ -3505,14 +3510,28 @@ var ProtocolError;
3505
3510
  * Mitigation can be: retrying after a given time period
3506
3511
  */
3507
3512
  ProtocolError["REQUEST_TIMEOUT"] = "Request timeout";
3513
+ /**
3514
+ * Missing credentials info message.
3515
+ * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L186
3516
+ */
3517
+ ProtocolError["RLN_IDENTITY_MISSING"] = "Identity credentials are not set";
3518
+ /**
3519
+ * Membership index missing info message.
3520
+ * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L188
3521
+ */
3522
+ ProtocolError["RLN_MEMBERSHIP_INDEX"] = "Membership index is not set";
3523
+ /**
3524
+ * Message limit is missing.
3525
+ * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
3526
+ */
3527
+ ProtocolError["RLN_LIMIT_MISSING"] = "User message limit is not set";
3528
+ /**
3529
+ * General proof generation error message.
3530
+ * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
3531
+ */
3532
+ ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
3508
3533
  })(ProtocolError || (ProtocolError = {}));
3509
3534
 
3510
- var PageDirection;
3511
- (function (PageDirection) {
3512
- PageDirection["BACKWARD"] = "backward";
3513
- PageDirection["FORWARD"] = "forward";
3514
- })(PageDirection || (PageDirection = {}));
3515
-
3516
3535
  var Tags;
3517
3536
  (function (Tags) {
3518
3537
  Tags["BOOTSTRAP"] = "bootstrap";
@@ -3531,6 +3550,13 @@ var EConnectionStateEvents;
3531
3550
  EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
3532
3551
  })(EConnectionStateEvents || (EConnectionStateEvents = {}));
3533
3552
 
3553
+ var HealthStatus;
3554
+ (function (HealthStatus) {
3555
+ HealthStatus["Unhealthy"] = "Unhealthy";
3556
+ HealthStatus["MinimallyHealthy"] = "MinimallyHealthy";
3557
+ HealthStatus["SufficientlyHealthy"] = "SufficientlyHealthy";
3558
+ })(HealthStatus || (HealthStatus = {}));
3559
+
3534
3560
  const decodeRelayShard = (bytes) => {
3535
3561
  // explicitly converting to Uint8Array to avoid Buffer
3536
3562
  // https://github.com/libp2p/js-libp2p/issues/2146
@@ -4137,6 +4163,8 @@ var common = setup;
4137
4163
  return false;
4138
4164
  }
4139
4165
 
4166
+ let m;
4167
+
4140
4168
  // Is webkit? http://stackoverflow.com/a/16459606/376773
4141
4169
  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
4142
4170
  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
@@ -4144,7 +4172,7 @@ var common = setup;
4144
4172
  (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
4145
4173
  // Is firefox >= v31?
4146
4174
  // 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) ||
4175
+ (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
4148
4176
  // Double check webkit in userAgent just in case we are in a worker
4149
4177
  (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
4150
4178
  }
@@ -4981,6 +5009,7 @@ const table = [
4981
5009
  [478, 0, 'wss'],
4982
5010
  [479, 0, 'p2p-websocket-star'],
4983
5011
  [480, 0, 'http'],
5012
+ [481, V, 'http-path'],
4984
5013
  [777, V, 'memory']
4985
5014
  ];
4986
5015
  // populate tables
@@ -5066,6 +5095,8 @@ function convertToString(proto, buf) {
5066
5095
  return bytes2onion(buf);
5067
5096
  case 466: // certhash
5068
5097
  return bytes2mb(buf);
5098
+ case 481: // http-path
5099
+ return globalThis.encodeURIComponent(bytes2str(buf));
5069
5100
  default:
5070
5101
  return toString$1(buf, 'base16'); // no clue. convert to hex
5071
5102
  }
@@ -5100,6 +5131,8 @@ function convertToBytes(proto, str) {
5100
5131
  return onion32bytes(str);
5101
5132
  case 466: // certhash
5102
5133
  return mb2bytes(str);
5134
+ case 481: // http-path
5135
+ return str2bytes(globalThis.decodeURIComponent(str));
5103
5136
  default:
5104
5137
  return fromString(str, 'base16'); // no clue. convert from hex
5105
5138
  }
@@ -6004,9 +6037,9 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
6004
6037
  // This is OK: `abstract` directory does not use noble-hashes.
6005
6038
  // User may opt-in into using different hashing library. This way, noble-hashes
6006
6039
  // 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);
6040
+ const _0n$4 = /* @__PURE__ */ BigInt(0);
6041
+ const _1n$6 = /* @__PURE__ */ BigInt(1);
6042
+ const _2n$4 = /* @__PURE__ */ BigInt(2);
6010
6043
  function isBytes$1(a) {
6011
6044
  return (a instanceof Uint8Array ||
6012
6045
  (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
@@ -6015,6 +6048,10 @@ function abytes(item) {
6015
6048
  if (!isBytes$1(item))
6016
6049
  throw new Error('Uint8Array expected');
6017
6050
  }
6051
+ function abool(title, value) {
6052
+ if (typeof value !== 'boolean')
6053
+ throw new Error(`${title} must be valid boolean, got "${value}".`);
6054
+ }
6018
6055
  // Array where index 0xf0 (240) is mapped to string 'f0'
6019
6056
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
6020
6057
  /**
@@ -6157,6 +6194,25 @@ function utf8ToBytes(str) {
6157
6194
  throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
6158
6195
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
6159
6196
  }
6197
+ // Is positive bigint
6198
+ const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
6199
+ function inRange(n, min, max) {
6200
+ return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
6201
+ }
6202
+ /**
6203
+ * Asserts min <= n < max. NOTE: It's < max and not <= max.
6204
+ * @example
6205
+ * aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)
6206
+ */
6207
+ function aInRange(title, n, min, max) {
6208
+ // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?
6209
+ // consider P=256n, min=0n, max=P
6210
+ // - a for min=0 would require -1: `inRange('x', x, -1n, P)`
6211
+ // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
6212
+ // - our way is the cleanest: `inRange('x', x, 0n, P)
6213
+ if (!inRange(n, min, max))
6214
+ throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
6215
+ }
6160
6216
  // Bit operations
6161
6217
  /**
6162
6218
  * Calculates amount of bits in a bigint.
@@ -6287,9 +6343,32 @@ function validateObject(object, validators, optValidators = {}) {
6287
6343
  // const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
6288
6344
  // const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
6289
6345
  // const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
6346
+ /**
6347
+ * throws not implemented error
6348
+ */
6349
+ const notImplemented = () => {
6350
+ throw new Error('not implemented');
6351
+ };
6352
+ /**
6353
+ * Memoizes (caches) computation result.
6354
+ * Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
6355
+ */
6356
+ function memoized(fn) {
6357
+ const map = new WeakMap();
6358
+ return (arg, ...args) => {
6359
+ const val = map.get(arg);
6360
+ if (val !== undefined)
6361
+ return val;
6362
+ const computed = fn(arg, ...args);
6363
+ map.set(arg, computed);
6364
+ return computed;
6365
+ };
6366
+ }
6290
6367
 
6291
6368
  var ut = /*#__PURE__*/Object.freeze({
6292
6369
  __proto__: null,
6370
+ aInRange: aInRange,
6371
+ abool: abool,
6293
6372
  abytes: abytes,
6294
6373
  bitGet: bitGet,
6295
6374
  bitLen: bitLen,
@@ -6304,7 +6383,10 @@ var ut = /*#__PURE__*/Object.freeze({
6304
6383
  equalBytes: equalBytes,
6305
6384
  hexToBytes: hexToBytes,
6306
6385
  hexToNumber: hexToNumber,
6386
+ inRange: inRange,
6307
6387
  isBytes: isBytes$1,
6388
+ memoized: memoized,
6389
+ notImplemented: notImplemented,
6308
6390
  numberToBytesBE: numberToBytesBE,
6309
6391
  numberToBytesLE: numberToBytesLE,
6310
6392
  numberToHexUnpadded: numberToHexUnpadded,
@@ -6318,7 +6400,7 @@ var ut = /*#__PURE__*/Object.freeze({
6318
6400
  // prettier-ignore
6319
6401
  const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
6320
6402
  // prettier-ignore
6321
- const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$1 = BigInt(8);
6403
+ const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
6322
6404
  // prettier-ignore
6323
6405
  BigInt(9); BigInt(16);
6324
6406
  // Calculates a modulo b
@@ -6464,8 +6546,8 @@ function FpSqrt(P) {
6464
6546
  };
6465
6547
  }
6466
6548
  // 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;
6549
+ if (P % _8n$2 === _5n$1) {
6550
+ const c1 = (P - _5n$1) / _8n$2;
6469
6551
  return function sqrt5mod8(Fp, n) {
6470
6552
  const n2 = Fp.mul(n, _2n$3);
6471
6553
  const v = Fp.pow(n2, c1);
@@ -6563,6 +6645,9 @@ function nLength(n, nBitLength) {
6563
6645
  * * a) denormalized operations like mulN instead of mul
6564
6646
  * * b) same object shape: never add or remove keys
6565
6647
  * * c) Object.freeze
6648
+ * NOTE: operations don't check 'isValid' for all elements for performance reasons,
6649
+ * it is caller responsibility to check this.
6650
+ * This is low-level code, please make sure you know what you doing.
6566
6651
  * @param ORDER prime positive bigint
6567
6652
  * @param bitLen how many bits the field consumes
6568
6653
  * @param isLE (def: false) if encoding / decoding should be in little-endian
@@ -6618,12 +6703,6 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
6618
6703
  });
6619
6704
  return Object.freeze(f);
6620
6705
  }
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
6706
  /**
6628
6707
  * Returns total number of bytes consumed by the field element.
6629
6708
  * For example, 32 bytes for usual 256-bit weierstrass curve.
@@ -6677,6 +6756,10 @@ function mapHashToField(key, fieldOrder, isLE = false) {
6677
6756
  // Abelian group utilities
6678
6757
  const _0n$2 = BigInt(0);
6679
6758
  const _1n$4 = BigInt(1);
6759
+ // Since points in different groups cannot be equal (different object constructor),
6760
+ // we can have single place to store precomputes
6761
+ const pointPrecomputes = new WeakMap();
6762
+ const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
6680
6763
  // Elliptic curve multiplication of Point by scalar. Fragile.
6681
6764
  // Scalars should always be less than curve order: this should be checked inside of a curve itself.
6682
6765
  // Creates precomputation tables for fast multiplication:
@@ -6693,7 +6776,12 @@ function wNAF(c, bits) {
6693
6776
  const neg = item.negate();
6694
6777
  return condition ? neg : item;
6695
6778
  };
6779
+ const validateW = (W) => {
6780
+ if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
6781
+ throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
6782
+ };
6696
6783
  const opts = (W) => {
6784
+ validateW(W);
6697
6785
  const windows = Math.ceil(bits / W) + 1; // +1, because
6698
6786
  const windowSize = 2 ** (W - 1); // -1 because we skip zero
6699
6787
  return { windows, windowSize };
@@ -6793,19 +6881,25 @@ function wNAF(c, bits) {
6793
6881
  // which makes it less const-time: around 1 bigint multiply.
6794
6882
  return { p, f };
6795
6883
  },
6796
- wNAFCached(P, precomputesMap, n, transform) {
6797
- // @ts-ignore
6798
- const W = P._WINDOW_SIZE || 1;
6884
+ wNAFCached(P, n, transform) {
6885
+ const W = pointWindowSizes.get(P) || 1;
6799
6886
  // Calculate precomputes on a first run, reuse them after
6800
- let comp = precomputesMap.get(P);
6887
+ let comp = pointPrecomputes.get(P);
6801
6888
  if (!comp) {
6802
6889
  comp = this.precomputeWindow(P, W);
6803
- if (W !== 1) {
6804
- precomputesMap.set(P, transform(comp));
6805
- }
6890
+ if (W !== 1)
6891
+ pointPrecomputes.set(P, transform(comp));
6806
6892
  }
6807
6893
  return this.wNAF(W, comp, n);
6808
6894
  },
6895
+ // We calculate precomputes for elliptic curve point multiplication
6896
+ // using windowed method. This specifies window size and
6897
+ // stores precomputed values. Usually only base point would be precomputed.
6898
+ setWindowSize(P, W) {
6899
+ validateW(W);
6900
+ pointWindowSizes.set(P, W);
6901
+ pointPrecomputes.delete(P);
6902
+ },
6809
6903
  };
6810
6904
  }
6811
6905
  function validateBasic(curve) {
@@ -6831,7 +6925,7 @@ function validateBasic(curve) {
6831
6925
  // Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
6832
6926
  // Be friendly to bad ECMAScript parsers by not using bigint literals
6833
6927
  // prettier-ignore
6834
- const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n = BigInt(8);
6928
+ const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
6835
6929
  // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
6836
6930
  const VERIFY_DEFAULT = { zip215: true };
6837
6931
  function validateOpts$1(curve) {
@@ -6850,7 +6944,13 @@ function validateOpts$1(curve) {
6850
6944
  // Set defaults
6851
6945
  return Object.freeze({ ...opts });
6852
6946
  }
6853
- // It is not generic twisted curve for now, but ed25519/ed448 generic implementation
6947
+ /**
6948
+ * Creates Twisted Edwards curve with EdDSA signatures.
6949
+ * @example
6950
+ * import { Field } from '@noble/curves/abstract/modular';
6951
+ * // Before that, define BigInt-s: a, d, p, n, Gx, Gy, h
6952
+ * const curve = twistedEdwards({ a, d, Fp: Field(p), n, Gx, Gy, h })
6953
+ */
6854
6954
  function twistedEdwards(curveDef) {
6855
6955
  const CURVE = validateOpts$1(curveDef);
6856
6956
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
@@ -6869,28 +6969,59 @@ function twistedEdwards(curveDef) {
6869
6969
  const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
6870
6970
  const domain = CURVE.domain ||
6871
6971
  ((data, ctx, phflag) => {
6972
+ abool('phflag', phflag);
6872
6973
  if (ctx.length || phflag)
6873
6974
  throw new Error('Contexts/pre-hash are not supported');
6874
6975
  return data;
6875
6976
  }); // 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) {
6977
+ // 0 <= n < MASK
6978
+ // Coordinates larger than Fp.ORDER are allowed for zip215
6979
+ function aCoordinate(title, n) {
6980
+ aInRange('coordinate ' + title, n, _0n$1, MASK);
6981
+ }
6982
+ function assertPoint(other) {
6891
6983
  if (!(other instanceof Point))
6892
6984
  throw new Error('ExtendedPoint expected');
6893
6985
  }
6986
+ // Converts Extended point to default (x, y) coordinates.
6987
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
6988
+ const toAffineMemo = memoized((p, iz) => {
6989
+ const { ex: x, ey: y, ez: z } = p;
6990
+ const is0 = p.is0();
6991
+ if (iz == null)
6992
+ iz = is0 ? _8n$1 : Fp.inv(z); // 8 was chosen arbitrarily
6993
+ const ax = modP(x * iz);
6994
+ const ay = modP(y * iz);
6995
+ const zz = modP(z * iz);
6996
+ if (is0)
6997
+ return { x: _0n$1, y: _1n$3 };
6998
+ if (zz !== _1n$3)
6999
+ throw new Error('invZ was invalid');
7000
+ return { x: ax, y: ay };
7001
+ });
7002
+ const assertValidMemo = memoized((p) => {
7003
+ const { a, d } = CURVE;
7004
+ if (p.is0())
7005
+ throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
7006
+ // Equation in affine coordinates: ax² + y² = 1 + dx²y²
7007
+ // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
7008
+ const { ex: X, ey: Y, ez: Z, et: T } = p;
7009
+ const X2 = modP(X * X); // X²
7010
+ const Y2 = modP(Y * Y); // Y²
7011
+ const Z2 = modP(Z * Z); // Z²
7012
+ const Z4 = modP(Z2 * Z2); // Z⁴
7013
+ const aX2 = modP(X2 * a); // aX²
7014
+ const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
7015
+ const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
7016
+ if (left !== right)
7017
+ throw new Error('bad point: equation left != right (1)');
7018
+ // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
7019
+ const XY = modP(X * Y);
7020
+ const ZT = modP(Z * T);
7021
+ if (XY !== ZT)
7022
+ throw new Error('bad point: equation left != right (2)');
7023
+ return true;
7024
+ });
6894
7025
  // Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
6895
7026
  // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
6896
7027
  class Point {
@@ -6899,14 +7030,11 @@ function twistedEdwards(curveDef) {
6899
7030
  this.ey = ey;
6900
7031
  this.ez = ez;
6901
7032
  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');
7033
+ aCoordinate('x', ex);
7034
+ aCoordinate('y', ey);
7035
+ aCoordinate('z', ez);
7036
+ aCoordinate('t', et);
7037
+ Object.freeze(this);
6910
7038
  }
6911
7039
  get x() {
6912
7040
  return this.toAffine().x;
@@ -6918,8 +7046,8 @@ function twistedEdwards(curveDef) {
6918
7046
  if (p instanceof Point)
6919
7047
  throw new Error('extended point not allowed');
6920
7048
  const { x, y } = p || {};
6921
- if (!in0MaskRange(x) || !in0MaskRange(y))
6922
- throw new Error('invalid affine point');
7049
+ aCoordinate('x', x);
7050
+ aCoordinate('y', y);
6923
7051
  return new Point(x, y, _1n$3, modP(x * y));
6924
7052
  }
6925
7053
  static normalizeZ(points) {
@@ -6928,36 +7056,16 @@ function twistedEdwards(curveDef) {
6928
7056
  }
6929
7057
  // "Private method", don't use it directly
6930
7058
  _setWindowSize(windowSize) {
6931
- this._WINDOW_SIZE = windowSize;
6932
- pointPrecomputes.delete(this);
7059
+ wnaf.setWindowSize(this, windowSize);
6933
7060
  }
6934
7061
  // Not required for fromHex(), which always creates valid points.
6935
7062
  // Could be useful for fromAffine().
6936
7063
  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)');
7064
+ assertValidMemo(this);
6957
7065
  }
6958
7066
  // Compare one point to another.
6959
7067
  equals(other) {
6960
- isPoint(other);
7068
+ assertPoint(other);
6961
7069
  const { ex: X1, ey: Y1, ez: Z1 } = this;
6962
7070
  const { ex: X2, ey: Y2, ez: Z2 } = other;
6963
7071
  const X1Z2 = modP(X1 * Z2);
@@ -6998,7 +7106,7 @@ function twistedEdwards(curveDef) {
6998
7106
  // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
6999
7107
  // Cost: 9M + 1*a + 1*d + 7add.
7000
7108
  add(other) {
7001
- isPoint(other);
7109
+ assertPoint(other);
7002
7110
  const { a, d } = CURVE;
7003
7111
  const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
7004
7112
  const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
@@ -7041,11 +7149,13 @@ function twistedEdwards(curveDef) {
7041
7149
  return this.add(other.negate());
7042
7150
  }
7043
7151
  wNAF(n) {
7044
- return wnaf.wNAFCached(this, pointPrecomputes, n, Point.normalizeZ);
7152
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
7045
7153
  }
7046
7154
  // Constant-time multiplication.
7047
7155
  multiply(scalar) {
7048
- const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
7156
+ const n = scalar;
7157
+ aInRange('scalar', n, _1n$3, CURVE_ORDER); // 1 <= scalar < L
7158
+ const { p, f } = this.wNAF(n);
7049
7159
  return Point.normalizeZ([p, f])[0];
7050
7160
  }
7051
7161
  // Non-constant-time multiplication. Uses double-and-add algorithm.
@@ -7053,7 +7163,8 @@ function twistedEdwards(curveDef) {
7053
7163
  // an exposed private key e.g. sig verification.
7054
7164
  // Does NOT allow scalars higher than CURVE.n.
7055
7165
  multiplyUnsafe(scalar) {
7056
- let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
7166
+ const n = scalar;
7167
+ aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
7057
7168
  if (n === _0n$1)
7058
7169
  return I;
7059
7170
  if (this.equals(I) || n === _1n$3)
@@ -7077,18 +7188,7 @@ function twistedEdwards(curveDef) {
7077
7188
  // Converts Extended point to default (x, y) coordinates.
7078
7189
  // Can accept precomputed Z^-1 - for example, from invertBatch.
7079
7190
  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 };
7191
+ return toAffineMemo(this, iz);
7092
7192
  }
7093
7193
  clearCofactor() {
7094
7194
  const { h: cofactor } = CURVE;
@@ -7102,18 +7202,16 @@ function twistedEdwards(curveDef) {
7102
7202
  const { d, a } = CURVE;
7103
7203
  const len = Fp.BYTES;
7104
7204
  hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
7205
+ abool('zip215', zip215);
7105
7206
  const normed = hex.slice(); // copy again, we'll manipulate it
7106
7207
  const lastByte = hex[len - 1]; // select last byte
7107
7208
  normed[len - 1] = lastByte & ~0x80; // clear last bit
7108
7209
  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
- }
7210
+ // RFC8032 prohibits >= p, but ZIP215 doesn't
7211
+ // zip215=true: 0 <= y < MASK (2^256 for ed25519)
7212
+ // zip215=false: 0 <= y < P (2^255-19 for ed25519)
7213
+ const max = zip215 ? MASK : Fp.ORDER;
7214
+ aInRange('pointHex.y', y, _0n$1, max);
7117
7215
  // Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
7118
7216
  // ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
7119
7217
  const y2 = modP(y * y); // denominator is always non-0 mod p.
@@ -7188,7 +7286,7 @@ function twistedEdwards(curveDef) {
7188
7286
  const R = G.multiply(r).toRawBytes(); // R = rG
7189
7287
  const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
7190
7288
  const s = modN(r + k * scalar); // S = (r + k * s) mod L
7191
- assertGE0(s); // 0 <= s < l
7289
+ aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
7192
7290
  const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
7193
7291
  return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
7194
7292
  }
@@ -7198,6 +7296,8 @@ function twistedEdwards(curveDef) {
7198
7296
  const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
7199
7297
  sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
7200
7298
  msg = ensureBytes('message', msg);
7299
+ if (zip215 !== undefined)
7300
+ abool('zip215', zip215);
7201
7301
  if (prehash)
7202
7302
  msg = prehash(msg); // for ed25519ph, etc
7203
7303
  const s = bytesToNumberLE(sig.slice(len, 2 * len));
@@ -7255,12 +7355,14 @@ function twistedEdwards(curveDef) {
7255
7355
  */
7256
7356
  const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
7257
7357
  // √(-1) aka √(a) aka 2^((p-1)/4)
7258
- const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
7358
+ const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
7259
7359
  // prettier-ignore
7260
- BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2), _5n = BigInt(5);
7360
+ BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
7261
7361
  // prettier-ignore
7262
- const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
7362
+ const _5n = BigInt(5), _8n = BigInt(8);
7263
7363
  function ed25519_pow_2_252_3(x) {
7364
+ // prettier-ignore
7365
+ const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
7264
7366
  const P = ED25519_P;
7265
7367
  const x2 = (x * x) % P;
7266
7368
  const b2 = (x2 * x) % P; // x^3, 11
@@ -7309,8 +7411,8 @@ function uvRatio(u, v) {
7309
7411
  x = mod(-x, P);
7310
7412
  return { isValid: useRoot1 || useRoot2, value: x };
7311
7413
  }
7312
- const Fp$1 = Field(ED25519_P, undefined, true);
7313
- const ed25519Defaults = {
7414
+ const Fp$1 = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
7415
+ const ed25519Defaults = /* @__PURE__ */ (() => ({
7314
7416
  // Param: a
7315
7417
  a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
7316
7418
  // d is equal to -121665/121666 over finite field.
@@ -7322,7 +7424,7 @@ const ed25519Defaults = {
7322
7424
  // 2n**252n + 27742317777372353535851937790883648493n;
7323
7425
  n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
7324
7426
  // Cofactor
7325
- h: BigInt(8),
7427
+ h: _8n,
7326
7428
  // Base point (x, y) aka generator point
7327
7429
  Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
7328
7430
  Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
@@ -7333,40 +7435,11 @@ const ed25519Defaults = {
7333
7435
  // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
7334
7436
  // Constant-time, u/√v
7335
7437
  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');
7438
+ }))();
7439
+ /**
7440
+ * ed25519 curve with EdDSA signatures.
7441
+ */
7442
+ const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
7370
7443
 
7371
7444
  const PUBLIC_KEY_BYTE_LENGTH = 32;
7372
7445
  const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
@@ -7423,7 +7496,7 @@ function concatKeys(privateKeyRaw, publicKey) {
7423
7496
  var webcrypto = {
7424
7497
  get(win = globalThis) {
7425
7498
  const nativeCrypto = win.crypto;
7426
- if (nativeCrypto == null || nativeCrypto.subtle == null) {
7499
+ if (nativeCrypto?.subtle == null) {
7427
7500
  throw Object.assign(new Error('Missing Web Crypto API. ' +
7428
7501
  'The most likely cause of this error is that this page is being accessed ' +
7429
7502
  'from an insecure context (i.e. not HTTPS). For more information and ' +
@@ -7447,12 +7520,12 @@ var webcrypto = {
7447
7520
  const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
7448
7521
  // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
7449
7522
  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;
7523
+ const algorithm = 'AES-GCM';
7524
+ let keyLength = 16;
7525
+ const nonceLength = 12;
7526
+ const digest = 'SHA-256';
7527
+ const saltLength = 16;
7528
+ const iterations = 32767;
7456
7529
  const crypto = webcrypto.get();
7457
7530
  keyLength *= 8; // Browser crypto uses bits instead of bytes
7458
7531
  /**
@@ -8236,7 +8309,7 @@ function decodeMessage(buf, codec, opts) {
8236
8309
  * A general purpose buffer pool
8237
8310
  */
8238
8311
  function pool(size) {
8239
- const SIZE = size ?? 8192;
8312
+ const SIZE = 8192;
8240
8313
  const MAX = SIZE >>> 1;
8241
8314
  let slab;
8242
8315
  let offset = SIZE;
@@ -12824,6 +12897,12 @@ var RSA = /*#__PURE__*/Object.freeze({
12824
12897
 
12825
12898
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
12826
12899
  // Short Weierstrass curve. The formula is: y² = x³ + ax + b
12900
+ function validateSigVerOpts(opts) {
12901
+ if (opts.lowS !== undefined)
12902
+ abool('lowS', opts.lowS);
12903
+ if (opts.prehash !== undefined)
12904
+ abool('prehash', opts.prehash);
12905
+ }
12827
12906
  function validatePointOpts(curve) {
12828
12907
  const opts = validateBasic(curve);
12829
12908
  validateObject(opts, {
@@ -12948,16 +13027,12 @@ function weierstrassPoints(opts) {
12948
13027
  throw new Error('bad generator point: equation left != right');
12949
13028
  // Valid group elements reside in range 1..n-1
12950
13029
  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');
13030
+ return inRange(num, _1n$1, CURVE.n);
12956
13031
  }
12957
13032
  // Validates if priv key is valid and converts it to bigint.
12958
13033
  // Supports options allowedPrivateKeyLengths and wrapPrivateKey.
12959
13034
  function normPrivateKeyToScalar(key) {
12960
- const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
13035
+ const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
12961
13036
  if (lengths && typeof key !== 'bigint') {
12962
13037
  if (isBytes$1(key))
12963
13038
  key = bytesToHex(key);
@@ -12977,15 +13052,61 @@ function weierstrassPoints(opts) {
12977
13052
  throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
12978
13053
  }
12979
13054
  if (wrapPrivateKey)
12980
- num = mod(num, n); // disabled by default, enabled for BLS
12981
- assertGE(num); // num in range [1..N-1]
13055
+ num = mod(num, N); // disabled by default, enabled for BLS
13056
+ aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
12982
13057
  return num;
12983
13058
  }
12984
- const pointPrecomputes = new Map();
12985
13059
  function assertPrjPoint(other) {
12986
13060
  if (!(other instanceof Point))
12987
13061
  throw new Error('ProjectivePoint expected');
12988
13062
  }
13063
+ // Memoized toAffine / validity check. They are heavy. Points are immutable.
13064
+ // Converts Projective point to affine (x, y) coordinates.
13065
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
13066
+ // (x, y, z) ∋ (x=x/z, y=y/z)
13067
+ const toAffineMemo = memoized((p, iz) => {
13068
+ const { px: x, py: y, pz: z } = p;
13069
+ // Fast-path for normalized points
13070
+ if (Fp.eql(z, Fp.ONE))
13071
+ return { x, y };
13072
+ const is0 = p.is0();
13073
+ // If invZ was 0, we return zero point. However we still want to execute
13074
+ // all operations, so we replace invZ with a random number, 1.
13075
+ if (iz == null)
13076
+ iz = is0 ? Fp.ONE : Fp.inv(z);
13077
+ const ax = Fp.mul(x, iz);
13078
+ const ay = Fp.mul(y, iz);
13079
+ const zz = Fp.mul(z, iz);
13080
+ if (is0)
13081
+ return { x: Fp.ZERO, y: Fp.ZERO };
13082
+ if (!Fp.eql(zz, Fp.ONE))
13083
+ throw new Error('invZ was invalid');
13084
+ return { x: ax, y: ay };
13085
+ });
13086
+ // NOTE: on exception this will crash 'cached' and no value will be set.
13087
+ // Otherwise true will be return
13088
+ const assertValidMemo = memoized((p) => {
13089
+ if (p.is0()) {
13090
+ // (0, 1, 0) aka ZERO is invalid in most contexts.
13091
+ // In BLS, ZERO can be serialized, so we allow it.
13092
+ // (0, 0, 0) is wrong representation of ZERO and is always invalid.
13093
+ if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
13094
+ return;
13095
+ throw new Error('bad point: ZERO');
13096
+ }
13097
+ // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
13098
+ const { x, y } = p.toAffine();
13099
+ // Check if x, y are valid field elements
13100
+ if (!Fp.isValid(x) || !Fp.isValid(y))
13101
+ throw new Error('bad point: x or y not FE');
13102
+ const left = Fp.sqr(y); // y²
13103
+ const right = weierstrassEquation(x); // x³ + ax + b
13104
+ if (!Fp.eql(left, right))
13105
+ throw new Error('bad point: equation left != right');
13106
+ if (!p.isTorsionFree())
13107
+ throw new Error('bad point: not in prime-order subgroup');
13108
+ return true;
13109
+ });
12989
13110
  /**
12990
13111
  * Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
12991
13112
  * Default Point works in 2d / affine coordinates: (x, y)
@@ -13002,6 +13123,7 @@ function weierstrassPoints(opts) {
13002
13123
  throw new Error('y required');
13003
13124
  if (pz == null || !Fp.isValid(pz))
13004
13125
  throw new Error('z required');
13126
+ Object.freeze(this);
13005
13127
  }
13006
13128
  // Does not validate if the point is on-curve.
13007
13129
  // Use fromHex instead, or call assertValidity() later.
@@ -13048,30 +13170,11 @@ function weierstrassPoints(opts) {
13048
13170
  }
13049
13171
  // "Private method", don't use it directly
13050
13172
  _setWindowSize(windowSize) {
13051
- this._WINDOW_SIZE = windowSize;
13052
- pointPrecomputes.delete(this);
13173
+ wnaf.setWindowSize(this, windowSize);
13053
13174
  }
13054
13175
  // A point on curve is valid if it conforms to equation.
13055
13176
  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');
13177
+ assertValidMemo(this);
13075
13178
  }
13076
13179
  hasEvenY() {
13077
13180
  const { y } = this.toAffine();
@@ -13198,28 +13301,25 @@ function weierstrassPoints(opts) {
13198
13301
  return this.equals(Point.ZERO);
13199
13302
  }
13200
13303
  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
- });
13304
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
13205
13305
  }
13206
13306
  /**
13207
13307
  * Non-constant-time multiplication. Uses double-and-add algorithm.
13208
13308
  * It's faster, but should only be used when you don't care about
13209
13309
  * an exposed private key e.g. sig verification, which works over *public* keys.
13210
13310
  */
13211
- multiplyUnsafe(n) {
13311
+ multiplyUnsafe(sc) {
13312
+ aInRange('scalar', sc, _0n, CURVE.n);
13212
13313
  const I = Point.ZERO;
13213
- if (n === _0n)
13314
+ if (sc === _0n)
13214
13315
  return I;
13215
- assertGE(n); // Will throw on 0
13216
- if (n === _1n$1)
13316
+ if (sc === _1n$1)
13217
13317
  return this;
13218
13318
  const { endo } = CURVE;
13219
13319
  if (!endo)
13220
- return wnaf.unsafeLadder(this, n);
13320
+ return wnaf.unsafeLadder(this, sc);
13221
13321
  // Apply endomorphism
13222
- let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
13322
+ let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
13223
13323
  let k1p = I;
13224
13324
  let k2p = I;
13225
13325
  let d = this;
@@ -13249,12 +13349,11 @@ function weierstrassPoints(opts) {
13249
13349
  * @returns New point
13250
13350
  */
13251
13351
  multiply(scalar) {
13252
- assertGE(scalar);
13253
- let n = scalar;
13352
+ const { endo, n: N } = CURVE;
13353
+ aInRange('scalar', scalar, _1n$1, N);
13254
13354
  let point, fake; // Fake point is used to const-time mult
13255
- const { endo } = CURVE;
13256
13355
  if (endo) {
13257
- const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
13356
+ const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
13258
13357
  let { p: k1p, f: f1p } = this.wNAF(k1);
13259
13358
  let { p: k2p, f: f2p } = this.wNAF(k2);
13260
13359
  k1p = wnaf.constTimeNegate(k1neg, k1p);
@@ -13264,7 +13363,7 @@ function weierstrassPoints(opts) {
13264
13363
  fake = f1p.add(f2p);
13265
13364
  }
13266
13365
  else {
13267
- const { p, f } = this.wNAF(n);
13366
+ const { p, f } = this.wNAF(scalar);
13268
13367
  point = p;
13269
13368
  fake = f;
13270
13369
  }
@@ -13288,20 +13387,7 @@ function weierstrassPoints(opts) {
13288
13387
  // Can accept precomputed Z^-1 - for example, from invertBatch.
13289
13388
  // (x, y, z) ∋ (x=x/z, y=y/z)
13290
13389
  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 };
13390
+ return toAffineMemo(this, iz);
13305
13391
  }
13306
13392
  isTorsionFree() {
13307
13393
  const { h: cofactor, isTorsionFree } = CURVE;
@@ -13320,10 +13406,12 @@ function weierstrassPoints(opts) {
13320
13406
  return this.multiplyUnsafe(CURVE.h);
13321
13407
  }
13322
13408
  toRawBytes(isCompressed = true) {
13409
+ abool('isCompressed', isCompressed);
13323
13410
  this.assertValidity();
13324
13411
  return toBytes(Point, this, isCompressed);
13325
13412
  }
13326
13413
  toHex(isCompressed = true) {
13414
+ abool('isCompressed', isCompressed);
13327
13415
  return bytesToHex(this.toRawBytes(isCompressed));
13328
13416
  }
13329
13417
  }
@@ -13353,14 +13441,18 @@ function validateOpts(curve) {
13353
13441
  });
13354
13442
  return Object.freeze({ lowS: true, ...opts });
13355
13443
  }
13444
+ /**
13445
+ * Creates short weierstrass curve and ECDSA signature methods for it.
13446
+ * @example
13447
+ * import { Field } from '@noble/curves/abstract/modular';
13448
+ * // Before that, define BigInt-s: a, b, p, n, Gx, Gy
13449
+ * const curve = weierstrass({ a, b, Fp: Field(p), n, Gx, Gy, h: 1n })
13450
+ */
13356
13451
  function weierstrass(curveDef) {
13357
13452
  const CURVE = validateOpts(curveDef);
13358
13453
  const { Fp, n: CURVE_ORDER } = CURVE;
13359
13454
  const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
13360
13455
  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
13456
  function modN(a) {
13365
13457
  return mod(a, CURVE_ORDER);
13366
13458
  }
@@ -13373,6 +13465,7 @@ function weierstrass(curveDef) {
13373
13465
  const a = point.toAffine();
13374
13466
  const x = Fp.toBytes(a.x);
13375
13467
  const cat = concatBytes;
13468
+ abool('isCompressed', isCompressed);
13376
13469
  if (isCompressed) {
13377
13470
  return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
13378
13471
  }
@@ -13387,7 +13480,7 @@ function weierstrass(curveDef) {
13387
13480
  // this.assertValidity() is done inside of fromHex
13388
13481
  if (len === compressedLen && (head === 0x02 || head === 0x03)) {
13389
13482
  const x = bytesToNumberBE(tail);
13390
- if (!isValidFieldElement(x))
13483
+ if (!inRange(x, _1n$1, Fp.ORDER))
13391
13484
  throw new Error('Point is not on curve');
13392
13485
  const y2 = weierstrassEquation(x); // y² = x³ + ax + b
13393
13486
  let y;
@@ -13448,11 +13541,8 @@ function weierstrass(curveDef) {
13448
13541
  return new Signature(r, s);
13449
13542
  }
13450
13543
  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');
13544
+ aInRange('r', this.r, _1n$1, CURVE_ORDER); // r in [1..N]
13545
+ aInRange('s', this.s, _1n$1, CURVE_ORDER); // s in [1..N]
13456
13546
  }
13457
13547
  addRecoveryBit(recovery) {
13458
13548
  return new Signature(this.r, this.s, recovery);
@@ -13595,10 +13685,7 @@ function weierstrass(curveDef) {
13595
13685
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
13596
13686
  */
13597
13687
  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}`);
13688
+ aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
13602
13689
  // works with order, can have different size than numToField!
13603
13690
  return numberToBytesBE(num, CURVE.nByteLength);
13604
13691
  }
@@ -13615,6 +13702,7 @@ function weierstrass(curveDef) {
13615
13702
  if (lowS == null)
13616
13703
  lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
13617
13704
  msgHash = ensureBytes('msgHash', msgHash);
13705
+ validateSigVerOpts(opts);
13618
13706
  if (prehash)
13619
13707
  msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
13620
13708
  // We can't later call bits2octets, since nested bits2int is broken for curves
@@ -13701,6 +13789,7 @@ function weierstrass(curveDef) {
13701
13789
  publicKey = ensureBytes('publicKey', publicKey);
13702
13790
  if ('strict' in opts)
13703
13791
  throw new Error('options.strict was renamed to lowS');
13792
+ validateSigVerOpts(opts);
13704
13793
  const { lowS, prehash } = opts;
13705
13794
  let _sig = undefined;
13706
13795
  let P;
@@ -13807,6 +13896,9 @@ function sqrtMod(y) {
13807
13896
  return root;
13808
13897
  }
13809
13898
  const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
13899
+ /**
13900
+ * secp256k1 short weierstrass curve and ECDSA signatures over it.
13901
+ */
13810
13902
  const secp256k1 = createCurve({
13811
13903
  a: BigInt(0), // equation params: a, b
13812
13904
  b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
@@ -14212,6 +14304,41 @@ class Secp256k1PeerIdImpl extends PeerIdImpl {
14212
14304
  this.publicKey = init.multihash.digest;
14213
14305
  }
14214
14306
  }
14307
+ // these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
14308
+ const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
14309
+ class URLPeerIdImpl {
14310
+ type = 'url';
14311
+ multihash;
14312
+ privateKey;
14313
+ publicKey;
14314
+ url;
14315
+ constructor(url) {
14316
+ this.url = url.toString();
14317
+ this.multihash = identity.digest(fromString(this.url));
14318
+ }
14319
+ [inspect]() {
14320
+ return `PeerId(${this.url})`;
14321
+ }
14322
+ [peerIdSymbol] = true;
14323
+ toString() {
14324
+ return this.toCID().toString();
14325
+ }
14326
+ toCID() {
14327
+ return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
14328
+ }
14329
+ toBytes() {
14330
+ return this.toCID().bytes;
14331
+ }
14332
+ equals(other) {
14333
+ if (other == null) {
14334
+ return false;
14335
+ }
14336
+ if (other instanceof Uint8Array) {
14337
+ other = toString$1(other);
14338
+ }
14339
+ return other.toString() === this.toString();
14340
+ }
14341
+ }
14215
14342
  function peerIdFromString(str, decoder) {
14216
14343
  if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
14217
14344
  // identity hash ed25519/secp256k1 key or sha2-256 hash of
@@ -14250,9 +14377,13 @@ function peerIdFromBytes(buf) {
14250
14377
  throw new Error('Supplied PeerID CID is invalid');
14251
14378
  }
14252
14379
  function peerIdFromCID(cid) {
14253
- if (cid == null || cid.multihash == null || cid.version == null || (cid.version === 1 && cid.code !== LIBP2P_KEY_CODE)) {
14380
+ if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
14254
14381
  throw new Error('Supplied PeerID CID is invalid');
14255
14382
  }
14383
+ if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
14384
+ const url = toString$1(cid.multihash.digest);
14385
+ return new URLPeerIdImpl(new URL(url));
14386
+ }
14256
14387
  const multihash = cid.multihash;
14257
14388
  if (multihash.code === sha256$1.code) {
14258
14389
  return new RSAPeerIdImpl({ multihash: cid.multihash });
@@ -14289,6 +14420,9 @@ function getPublicKeyFromPeerId(peerId) {
14289
14420
  if (peerId.type !== "secp256k1") {
14290
14421
  throw new Error("Unsupported peer id type");
14291
14422
  }
14423
+ if (!peerId.publicKey) {
14424
+ throw new Error("Public key not present on peer id");
14425
+ }
14292
14426
  return unmarshalPublicKey(peerId.publicKey).marshal();
14293
14427
  }
14294
14428
  // Only used in tests
@@ -15137,9 +15271,6 @@ function isHexString(value, length) {
15137
15271
  if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
15138
15272
  return false;
15139
15273
  }
15140
- if (length && value.length !== 2 + 2 * length) {
15141
- return false;
15142
- }
15143
15274
  return true;
15144
15275
  }
15145
15276
  const HexCharacters = "0123456789abcdef";