@frequency-chain/ethereum-utils 1.17.2 → 1.17.3

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.
@@ -3539,7 +3539,7 @@ const REGEX_HEX_NOPREFIX = /^[\da-fA-F]+$/;
3539
3539
  function isHex(value, bitLength = -1, ignoreLength) {
3540
3540
  return (typeof value === 'string' && (value === '0x' ||
3541
3541
  REGEX_HEX_PREFIXED.test(value))) && (bitLength === -1
3542
- ? ((value.length % 2 === 0))
3542
+ ? (ignoreLength || (value.length % 2 === 0))
3543
3543
  : (value.length === (2 + Math.ceil(bitLength / 4))));
3544
3544
  }/**
3545
3545
  * @name isObject
@@ -7545,6 +7545,11 @@ var knownSubstrate = [
7545
7545
  composable: [
7546
7546
  '0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d'
7547
7547
  ],
7548
+ creditcoin3: [
7549
+ '0x4436a7d64e363df85e065a894721002a86643283f9707338bf195d360ba2ee71', // cc3 mainnet
7550
+ '0xfc4ec97a1c1f119c4353aecb4a17c7c0cf7b40d5d660143d8bad9117e9866572', // cc3 testnet/drynet
7551
+ '0xfc9df99a665f964aed6649f275055e54df5e3420489538ed31d7788f53d11ef6' // cc3 devnet
7552
+ ],
7548
7553
  darwinia: [
7549
7554
  '0xe71578b37a7c799b0ab4ee87ffa6f059a6b98f71f06fb8c84a8d88013a548ad6'
7550
7555
  ],
@@ -7713,6 +7718,7 @@ var knownSubstrate = [
7713
7718
  bittensor: 0x00000162,
7714
7719
  centrifuge: 0x000002eb,
7715
7720
  composable: 0x00000162,
7721
+ creditcoin3: 0x00000162,
7716
7722
  darwinia: 0x00000162,
7717
7723
  'dock-mainnet': 0x00000252,
7718
7724
  edgeware: 0x0000020b,
@@ -8024,10 +8030,28 @@ hmac$1.create = (hash, key) => new HMAC$1(hash, key);/**
8024
8030
  */
8025
8031
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
8026
8032
  const _0n$9 = /* @__PURE__ */ BigInt(0);
8027
- const _1n$b = /* @__PURE__ */ BigInt(1);
8028
- function abool(title, value) {
8029
- if (typeof value !== 'boolean')
8030
- throw new Error(title + ' boolean expected, got ' + value);
8033
+ const _1n$a = /* @__PURE__ */ BigInt(1);
8034
+ // tmp name until v2
8035
+ function _abool2(value, title = '') {
8036
+ if (typeof value !== 'boolean') {
8037
+ const prefix = title && `"${title}"`;
8038
+ throw new Error(prefix + 'expected boolean, got type=' + typeof value);
8039
+ }
8040
+ return value;
8041
+ }
8042
+ // tmp name until v2
8043
+ /** Asserts something is Uint8Array. */
8044
+ function _abytes2(value, length, title = '') {
8045
+ const bytes = isBytes(value);
8046
+ const len = value?.length;
8047
+ const needsLen = length !== undefined;
8048
+ if (!bytes || (needsLen && len !== length)) {
8049
+ const prefix = title && `"${title}"`;
8050
+ const ofLen = needsLen ? ` of length ${length}` : '';
8051
+ const got = bytes ? `length=${len}` : `type=${typeof value}`;
8052
+ throw new Error(prefix + 'expected Uint8Array' + ofLen + ', got ' + got);
8053
+ }
8054
+ return value;
8031
8055
  }
8032
8056
  // Used in weierstrass, der
8033
8057
  function numberToHexUnpadded$1(num) {
@@ -8057,7 +8081,7 @@ function numberToBytesLE$1(n, len) {
8057
8081
  * Takes hex string or Uint8Array, converts to Uint8Array.
8058
8082
  * Validates output length.
8059
8083
  * Will throw error for other types.
8060
- * @param title descriptive title for an error e.g. 'private key'
8084
+ * @param title descriptive title for an error e.g. 'secret key'
8061
8085
  * @param hex hex string or Uint8Array
8062
8086
  * @param expectedLength optional, will compare to result array's length
8063
8087
  * @returns
@@ -8080,9 +8104,7 @@ function ensureBytes$1(title, hex, expectedLength) {
8080
8104
  else {
8081
8105
  throw new Error(title + ' must be hex string or Uint8Array');
8082
8106
  }
8083
- const len = res.length;
8084
- if (typeof expectedLength === 'number' && len !== expectedLength)
8085
- throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
8107
+ res.length;
8086
8108
  return res;
8087
8109
  }
8088
8110
  /**
@@ -8121,7 +8143,7 @@ function aInRange(title, n, min, max) {
8121
8143
  */
8122
8144
  function bitLen$1(n) {
8123
8145
  let len;
8124
- for (len = 0; n > _0n$9; n >>= _1n$b, len += 1)
8146
+ for (len = 0; n > _0n$9; n >>= _1n$a, len += 1)
8125
8147
  ;
8126
8148
  return len;
8127
8149
  }
@@ -8129,7 +8151,7 @@ function bitLen$1(n) {
8129
8151
  * Calculate mask for N bits. Not using ** operator with bigints because of old engines.
8130
8152
  * Same as BigInt(`0b${Array(i).fill('1').join('')}`)
8131
8153
  */
8132
- const bitMask$1 = (n) => (_1n$b << BigInt(n)) - _1n$b;
8154
+ const bitMask$1 = (n) => (_1n$a << BigInt(n)) - _1n$a;
8133
8155
  /**
8134
8156
  * Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
8135
8157
  * @returns function that will call DRBG until 2nd arg returns something meaningful
@@ -8226,10 +8248,11 @@ function memoized(fn) {
8226
8248
  */
8227
8249
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
8228
8250
  // prettier-ignore
8229
- const _0n$8 = BigInt(0), _1n$a = BigInt(1), _2n$7 = /* @__PURE__ */ BigInt(2), _3n$3 = /* @__PURE__ */ BigInt(3);
8251
+ const _0n$8 = BigInt(0), _1n$9 = BigInt(1), _2n$7 = /* @__PURE__ */ BigInt(2), _3n$3 = /* @__PURE__ */ BigInt(3);
8230
8252
  // prettier-ignore
8231
- const _4n$2 = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5);
8232
- const _8n$1 = /* @__PURE__ */ BigInt(8);
8253
+ const _4n$2 = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _7n$2 = /* @__PURE__ */ BigInt(7);
8254
+ // prettier-ignore
8255
+ const _8n$1 = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9), _16n = /* @__PURE__ */ BigInt(16);
8233
8256
  // Calculates a modulo b
8234
8257
  function mod$1(a, b) {
8235
8258
  const result = a % b;
@@ -8257,7 +8280,7 @@ function invert$1(number, modulo) {
8257
8280
  let a = mod$1(number, modulo);
8258
8281
  let b = modulo;
8259
8282
  // prettier-ignore
8260
- let x = _0n$8, u = _1n$a;
8283
+ let x = _0n$8, u = _1n$9;
8261
8284
  while (a !== _0n$8) {
8262
8285
  // JIT applies optimization if those two lines follow each other
8263
8286
  const q = b / a;
@@ -8267,20 +8290,22 @@ function invert$1(number, modulo) {
8267
8290
  b = a, a = r, x = u, u = m;
8268
8291
  }
8269
8292
  const gcd = b;
8270
- if (gcd !== _1n$a)
8293
+ if (gcd !== _1n$9)
8271
8294
  throw new Error('invert: does not exist');
8272
8295
  return mod$1(x, modulo);
8273
8296
  }
8297
+ function assertIsSquare(Fp, root, n) {
8298
+ if (!Fp.eql(Fp.sqr(root), n))
8299
+ throw new Error('Cannot find square root');
8300
+ }
8274
8301
  // Not all roots are possible! Example which will throw:
8275
8302
  // const NUM =
8276
8303
  // n = 72057594037927816n;
8277
8304
  // Fp = Field(BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'));
8278
8305
  function sqrt3mod4(Fp, n) {
8279
- const p1div4 = (Fp.ORDER + _1n$a) / _4n$2;
8306
+ const p1div4 = (Fp.ORDER + _1n$9) / _4n$2;
8280
8307
  const root = Fp.pow(n, p1div4);
8281
- // Throw if root^2 != n
8282
- if (!Fp.eql(Fp.sqr(root), n))
8283
- throw new Error('Cannot find square root');
8308
+ assertIsSquare(Fp, root, n);
8284
8309
  return root;
8285
8310
  }
8286
8311
  function sqrt5mod8(Fp, n) {
@@ -8290,32 +8315,33 @@ function sqrt5mod8(Fp, n) {
8290
8315
  const nv = Fp.mul(n, v);
8291
8316
  const i = Fp.mul(Fp.mul(nv, _2n$7), v);
8292
8317
  const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
8293
- if (!Fp.eql(Fp.sqr(root), n))
8294
- throw new Error('Cannot find square root');
8318
+ assertIsSquare(Fp, root, n);
8295
8319
  return root;
8296
8320
  }
8297
- // TODO: Commented-out for now. Provide test vectors.
8298
- // Tonelli is too slow for extension fields Fp2.
8299
- // That means we can't use sqrt (c1, c2...) even for initialization constants.
8300
- // if (P % _16n === _9n) return sqrt9mod16;
8301
- // // prettier-ignore
8302
- // function sqrt9mod16<T>(Fp: IField<T>, n: T, p7div16?: bigint) {
8303
- // if (p7div16 === undefined) p7div16 = (Fp.ORDER + BigInt(7)) / _16n;
8304
- // const c1 = Fp.sqrt(Fp.neg(Fp.ONE)); // 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F
8305
- // const c2 = Fp.sqrt(c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F
8306
- // const c3 = Fp.sqrt(Fp.neg(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F
8307
- // const c4 = p7div16; // 4. c4 = (q + 7) / 16 # Integer arithmetic
8308
- // let tv1 = Fp.pow(n, c4); // 1. tv1 = x^c4
8309
- // let tv2 = Fp.mul(c1, tv1); // 2. tv2 = c1 * tv1
8310
- // const tv3 = Fp.mul(c2, tv1); // 3. tv3 = c2 * tv1
8311
- // let tv4 = Fp.mul(c3, tv1); // 4. tv4 = c3 * tv1
8312
- // const e1 = Fp.eql(Fp.sqr(tv2), n); // 5. e1 = (tv2^2) == x
8313
- // const e2 = Fp.eql(Fp.sqr(tv3), n); // 6. e2 = (tv3^2) == x
8314
- // tv1 = Fp.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x
8315
- // tv2 = Fp.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x
8316
- // const e3 = Fp.eql(Fp.sqr(tv2), n); // 9. e3 = (tv2^2) == x
8317
- // return Fp.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select the sqrt from tv1 and tv2
8318
- // }
8321
+ // Based on RFC9380, Kong algorithm
8322
+ // prettier-ignore
8323
+ function sqrt9mod16(P) {
8324
+ const Fp_ = Field$1(P);
8325
+ const tn = tonelliShanks$1(P);
8326
+ const c1 = tn(Fp_, Fp_.neg(Fp_.ONE)); // 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F
8327
+ const c2 = tn(Fp_, c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F
8328
+ const c3 = tn(Fp_, Fp_.neg(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F
8329
+ const c4 = (P + _7n$2) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic
8330
+ return (Fp, n) => {
8331
+ let tv1 = Fp.pow(n, c4); // 1. tv1 = x^c4
8332
+ let tv2 = Fp.mul(tv1, c1); // 2. tv2 = c1 * tv1
8333
+ const tv3 = Fp.mul(tv1, c2); // 3. tv3 = c2 * tv1
8334
+ const tv4 = Fp.mul(tv1, c3); // 4. tv4 = c3 * tv1
8335
+ const e1 = Fp.eql(Fp.sqr(tv2), n); // 5. e1 = (tv2^2) == x
8336
+ const e2 = Fp.eql(Fp.sqr(tv3), n); // 6. e2 = (tv3^2) == x
8337
+ tv1 = Fp.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x
8338
+ tv2 = Fp.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x
8339
+ const e3 = Fp.eql(Fp.sqr(tv2), n); // 9. e3 = (tv2^2) == x
8340
+ const root = Fp.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select sqrt from tv1 & tv2
8341
+ assertIsSquare(Fp, root, n);
8342
+ return root;
8343
+ };
8344
+ }
8319
8345
  /**
8320
8346
  * Tonelli-Shanks square root search algorithm.
8321
8347
  * 1. https://eprint.iacr.org/2012/685.pdf (page 12)
@@ -8326,10 +8352,10 @@ function sqrt5mod8(Fp, n) {
8326
8352
  function tonelliShanks$1(P) {
8327
8353
  // Initialization (precomputation).
8328
8354
  // Caching initialization could boost perf by 7%.
8329
- if (P < BigInt(3))
8355
+ if (P < _3n$3)
8330
8356
  throw new Error('sqrt is not defined for small field');
8331
8357
  // Factor P - 1 = Q * 2^S, where Q is odd
8332
- let Q = P - _1n$a;
8358
+ let Q = P - _1n$9;
8333
8359
  let S = 0;
8334
8360
  while (Q % _2n$7 === _0n$8) {
8335
8361
  Q /= _2n$7;
@@ -8350,7 +8376,7 @@ function tonelliShanks$1(P) {
8350
8376
  // Slow-path
8351
8377
  // TODO: test on Fp2 and others
8352
8378
  let cc = _Fp.pow(Z, Q); // c = z^Q
8353
- const Q1div2 = (Q + _1n$a) / _2n$7;
8379
+ const Q1div2 = (Q + _1n$9) / _2n$7;
8354
8380
  return function tonelliSlow(Fp, n) {
8355
8381
  if (Fp.is0(n))
8356
8382
  return n;
@@ -8377,7 +8403,7 @@ function tonelliShanks$1(P) {
8377
8403
  throw new Error('Cannot find square root');
8378
8404
  }
8379
8405
  // Calculate the exponent for b: 2^(M - i - 1)
8380
- const exponent = _1n$a << BigInt(M - i - 1); // bigint is important
8406
+ const exponent = _1n$9 << BigInt(M - i - 1); // bigint is important
8381
8407
  const b = Fp.pow(c, exponent); // b = 2^(M - i - 1)
8382
8408
  // Update variables
8383
8409
  M = i;
@@ -8393,7 +8419,8 @@ function tonelliShanks$1(P) {
8393
8419
  *
8394
8420
  * 1. P ≡ 3 (mod 4)
8395
8421
  * 2. P ≡ 5 (mod 8)
8396
- * 3. Tonelli-Shanks algorithm
8422
+ * 3. P ≡ 9 (mod 16)
8423
+ * 4. Tonelli-Shanks algorithm
8397
8424
  *
8398
8425
  * Different algorithms can give different roots, it is up to user to decide which one they want.
8399
8426
  * For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
@@ -8405,7 +8432,9 @@ function FpSqrt$1(P) {
8405
8432
  // P ≡ 5 (mod 8) => Atkin algorithm, page 10 of https://eprint.iacr.org/2012/685.pdf
8406
8433
  if (P % _8n$1 === _5n$1)
8407
8434
  return sqrt5mod8;
8408
- // P ≡ 9 (mod 16) not implemented, see above
8435
+ // P ≡ 9 (mod 16) => Kong algorithm, page 11 of https://eprint.iacr.org/2012/685.pdf (algorithm 4)
8436
+ if (P % _16n === _9n)
8437
+ return sqrt9mod16(P);
8409
8438
  // Tonelli-Shanks algorithm
8410
8439
  return tonelliShanks$1(P);
8411
8440
  }
@@ -8442,15 +8471,15 @@ function FpPow$1(Fp, num, power) {
8442
8471
  throw new Error('invalid exponent, negatives unsupported');
8443
8472
  if (power === _0n$8)
8444
8473
  return Fp.ONE;
8445
- if (power === _1n$a)
8474
+ if (power === _1n$9)
8446
8475
  return num;
8447
8476
  let p = Fp.ONE;
8448
8477
  let d = num;
8449
8478
  while (power > _0n$8) {
8450
- if (power & _1n$a)
8479
+ if (power & _1n$9)
8451
8480
  p = Fp.mul(p, d);
8452
8481
  d = Fp.sqr(d);
8453
- power >>= _1n$a;
8482
+ power >>= _1n$9;
8454
8483
  }
8455
8484
  return p;
8456
8485
  }
@@ -8491,7 +8520,7 @@ function FpInvertBatch$1(Fp, nums, passZero = false) {
8491
8520
  function FpLegendre(Fp, n) {
8492
8521
  // We can use 3rd argument as optional cache of this value
8493
8522
  // but seems unneeded for now. The operation is very fast.
8494
- const p1mod2 = (Fp.ORDER - _1n$a) / _2n$7;
8523
+ const p1mod2 = (Fp.ORDER - _1n$9) / _2n$7;
8495
8524
  const powered = Fp.pow(n, p1mod2);
8496
8525
  const yes = Fp.eql(powered, Fp.ONE);
8497
8526
  const zero = Fp.eql(powered, Fp.ZERO);
@@ -8528,11 +8557,14 @@ function nLength$1(n, nBitLength) {
8528
8557
  * @param isLE (default: false) if encoding / decoding should be in little-endian
8529
8558
  * @param redef optional faster redefinitions of sqrt and other methods
8530
8559
  */
8531
- function Field$1(ORDER, bitLenOrOpts, isLE = false, opts = {}) {
8560
+ function Field$1(ORDER, bitLenOrOpts, // TODO: use opts only in v2?
8561
+ isLE = false, opts = {}) {
8532
8562
  if (ORDER <= _0n$8)
8533
8563
  throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
8534
8564
  let _nbitLength = undefined;
8535
8565
  let _sqrt = undefined;
8566
+ let modFromBytes = false;
8567
+ let allowedLengths = undefined;
8536
8568
  if (typeof bitLenOrOpts === 'object' && bitLenOrOpts != null) {
8537
8569
  if (opts.sqrt || isLE)
8538
8570
  throw new Error('cannot specify opts in two arguments');
@@ -8543,6 +8575,9 @@ function Field$1(ORDER, bitLenOrOpts, isLE = false, opts = {}) {
8543
8575
  _sqrt = _opts.sqrt;
8544
8576
  if (typeof _opts.isLE === 'boolean')
8545
8577
  isLE = _opts.isLE;
8578
+ if (typeof _opts.modFromBytes === 'boolean')
8579
+ modFromBytes = _opts.modFromBytes;
8580
+ allowedLengths = _opts.allowedLengths;
8546
8581
  }
8547
8582
  else {
8548
8583
  if (typeof bitLenOrOpts === 'number')
@@ -8561,7 +8596,8 @@ function Field$1(ORDER, bitLenOrOpts, isLE = false, opts = {}) {
8561
8596
  BYTES,
8562
8597
  MASK: bitMask$1(BITS),
8563
8598
  ZERO: _0n$8,
8564
- ONE: _1n$a,
8599
+ ONE: _1n$9,
8600
+ allowedLengths: allowedLengths,
8565
8601
  create: (num) => mod$1(num, ORDER),
8566
8602
  isValid: (num) => {
8567
8603
  if (typeof num !== 'bigint')
@@ -8571,7 +8607,7 @@ function Field$1(ORDER, bitLenOrOpts, isLE = false, opts = {}) {
8571
8607
  is0: (num) => num === _0n$8,
8572
8608
  // is valid and invertible
8573
8609
  isValidNot0: (num) => !f.is0(num) && f.isValid(num),
8574
- isOdd: (num) => (num & _1n$a) === _1n$a,
8610
+ isOdd: (num) => (num & _1n$9) === _1n$9,
8575
8611
  neg: (num) => mod$1(-num, ORDER),
8576
8612
  eql: (lhs, rhs) => lhs === rhs,
8577
8613
  sqr: (num) => mod$1(num * num, ORDER),
@@ -8593,10 +8629,27 @@ function Field$1(ORDER, bitLenOrOpts, isLE = false, opts = {}) {
8593
8629
  return sqrtP(f, n);
8594
8630
  }),
8595
8631
  toBytes: (num) => (isLE ? numberToBytesLE$1(num, BYTES) : numberToBytesBE$1(num, BYTES)),
8596
- fromBytes: (bytes) => {
8632
+ fromBytes: (bytes, skipValidation = true) => {
8633
+ if (allowedLengths) {
8634
+ if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) {
8635
+ throw new Error('Field.fromBytes: expected ' + allowedLengths + ' bytes, got ' + bytes.length);
8636
+ }
8637
+ const padded = new Uint8Array(BYTES);
8638
+ // isLE add 0 to right, !isLE to the left.
8639
+ padded.set(bytes, isLE ? 0 : padded.length - bytes.length);
8640
+ bytes = padded;
8641
+ }
8597
8642
  if (bytes.length !== BYTES)
8598
8643
  throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
8599
- return isLE ? bytesToNumberLE$1(bytes) : bytesToNumberBE$1(bytes);
8644
+ let scalar = isLE ? bytesToNumberLE$1(bytes) : bytesToNumberBE$1(bytes);
8645
+ if (modFromBytes)
8646
+ scalar = mod$1(scalar, ORDER);
8647
+ if (!skipValidation)
8648
+ if (!f.isValid(scalar))
8649
+ throw new Error('invalid field element: outside of range 0..ORDER');
8650
+ // NOTE: we don't validate scalar here, please use isValid. This done such way because some
8651
+ // protocol may allow non-reduced scalar that reduced later or changed some other way.
8652
+ return scalar;
8600
8653
  },
8601
8654
  // TODO: we don't need it here, move out to separate fn
8602
8655
  invertBatch: (lst) => FpInvertBatch$1(f, lst),
@@ -8651,16 +8704,16 @@ function mapHashToField$1(key, fieldOrder, isLE = false) {
8651
8704
  throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
8652
8705
  const num = isLE ? bytesToNumberLE$1(key) : bytesToNumberBE$1(key);
8653
8706
  // `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
8654
- const reduced = mod$1(num, fieldOrder - _1n$a) + _1n$a;
8707
+ const reduced = mod$1(num, fieldOrder - _1n$9) + _1n$9;
8655
8708
  return isLE ? numberToBytesLE$1(reduced, fieldLen) : numberToBytesBE$1(reduced, fieldLen);
8656
8709
  }/**
8657
8710
  * Methods for elliptic curve multiplication by scalars.
8658
- * Contains wNAF, pippenger
8711
+ * Contains wNAF, pippenger.
8659
8712
  * @module
8660
8713
  */
8661
8714
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
8662
8715
  const _0n$7 = BigInt(0);
8663
- const _1n$9 = BigInt(1);
8716
+ const _1n$8 = BigInt(1);
8664
8717
  function negateCt(condition, item) {
8665
8718
  const neg = item.negate();
8666
8719
  return condition ? neg : item;
@@ -8671,12 +8724,9 @@ function negateCt(condition, item) {
8671
8724
  * so this improves performance massively.
8672
8725
  * Optimization: converts a list of projective points to a list of identical points with Z=1.
8673
8726
  */
8674
- function normalizeZ(c, property, points) {
8675
- const getz = (p) => p.pz ;
8676
- const toInv = FpInvertBatch$1(c.Fp, points.map(getz));
8677
- // @ts-ignore
8678
- const affined = points.map((p, i) => p.toAffine(toInv[i]));
8679
- return affined.map(c.fromAffine);
8727
+ function normalizeZ(c, points) {
8728
+ const invertedZs = FpInvertBatch$1(c.Fp, points.map((p) => p.Z));
8729
+ return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
8680
8730
  }
8681
8731
  function validateW(W, bits) {
8682
8732
  if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
@@ -8703,7 +8753,7 @@ function calcOffsets(n, window, wOpts) {
8703
8753
  if (wbits > windowSize) {
8704
8754
  // we skip zero, which means instead of `>= size-1`, we do `> size`
8705
8755
  wbits -= maxNumber; // -32, can be maxNumber - wbits, but then we need to set isNeg here.
8706
- nextN += _1n$9; // +256 (carry)
8756
+ nextN += _1n$8; // +256 (carry)
8707
8757
  }
8708
8758
  const offsetStart = window * windowSize;
8709
8759
  const offset = offsetStart + Math.abs(wbits) - 1; // -1 because we skip zero
@@ -8735,6 +8785,8 @@ function validateMSMScalars(scalars, field) {
8735
8785
  const pointPrecomputes = new WeakMap();
8736
8786
  const pointWindowSizes = new WeakMap();
8737
8787
  function getW(P) {
8788
+ // To disable precomputes:
8789
+ // return 1;
8738
8790
  return pointWindowSizes.get(P) || 1;
8739
8791
  }
8740
8792
  function assert0(n) {
@@ -8743,6 +8795,10 @@ function assert0(n) {
8743
8795
  }
8744
8796
  /**
8745
8797
  * Elliptic curve multiplication of Point by scalar. Fragile.
8798
+ * Table generation takes **30MB of ram and 10ms on high-end CPU**,
8799
+ * but may take much longer on slow devices. Actual generation will happen on
8800
+ * first call of `multiply()`. By default, `BASE` point is precomputed.
8801
+ *
8746
8802
  * Scalars should always be less than curve order: this should be checked inside of a curve itself.
8747
8803
  * Creates precomputation tables for fast multiplication:
8748
8804
  * - private scalar is split by fixed size windows of W bits
@@ -8755,172 +8811,170 @@ function assert0(n) {
8755
8811
  * @todo Research returning 2d JS array of windows, instead of a single window.
8756
8812
  * This would allow windows to be in different memory locations
8757
8813
  */
8758
- function wNAF$1(c, bits) {
8759
- return {
8760
- constTimeNegate: negateCt,
8761
- hasPrecomputes(elm) {
8762
- return getW(elm) !== 1;
8763
- },
8764
- // non-const time multiplication ladder
8765
- unsafeLadder(elm, n, p = c.ZERO) {
8766
- let d = elm;
8767
- while (n > _0n$7) {
8768
- if (n & _1n$9)
8769
- p = p.add(d);
8770
- d = d.double();
8771
- n >>= _1n$9;
8772
- }
8773
- return p;
8774
- },
8775
- /**
8776
- * Creates a wNAF precomputation window. Used for caching.
8777
- * Default window size is set by `utils.precompute()` and is equal to 8.
8778
- * Number of precomputed points depends on the curve size:
8779
- * 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
8780
- * - 𝑊 is the window size
8781
- * - 𝑛 is the bitlength of the curve order.
8782
- * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
8783
- * @param elm Point instance
8784
- * @param W window size
8785
- * @returns precomputed point tables flattened to a single array
8786
- */
8787
- precomputeWindow(elm, W) {
8788
- const { windows, windowSize } = calcWOpts(W, bits);
8789
- const points = [];
8790
- let p = elm;
8791
- let base = p;
8792
- for (let window = 0; window < windows; window++) {
8793
- base = p;
8814
+ let wNAF$1=class wNAF {
8815
+ // Parametrized with a given Point class (not individual point)
8816
+ constructor(Point, bits) {
8817
+ this.BASE = Point.BASE;
8818
+ this.ZERO = Point.ZERO;
8819
+ this.Fn = Point.Fn;
8820
+ this.bits = bits;
8821
+ }
8822
+ // non-const time multiplication ladder
8823
+ _unsafeLadder(elm, n, p = this.ZERO) {
8824
+ let d = elm;
8825
+ while (n > _0n$7) {
8826
+ if (n & _1n$8)
8827
+ p = p.add(d);
8828
+ d = d.double();
8829
+ n >>= _1n$8;
8830
+ }
8831
+ return p;
8832
+ }
8833
+ /**
8834
+ * Creates a wNAF precomputation window. Used for caching.
8835
+ * Default window size is set by `utils.precompute()` and is equal to 8.
8836
+ * Number of precomputed points depends on the curve size:
8837
+ * 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
8838
+ * - 𝑊 is the window size
8839
+ * - 𝑛 is the bitlength of the curve order.
8840
+ * For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
8841
+ * @param point Point instance
8842
+ * @param W window size
8843
+ * @returns precomputed point tables flattened to a single array
8844
+ */
8845
+ precomputeWindow(point, W) {
8846
+ const { windows, windowSize } = calcWOpts(W, this.bits);
8847
+ const points = [];
8848
+ let p = point;
8849
+ let base = p;
8850
+ for (let window = 0; window < windows; window++) {
8851
+ base = p;
8852
+ points.push(base);
8853
+ // i=1, bc we skip 0
8854
+ for (let i = 1; i < windowSize; i++) {
8855
+ base = base.add(p);
8794
8856
  points.push(base);
8795
- // i=1, bc we skip 0
8796
- for (let i = 1; i < windowSize; i++) {
8797
- base = base.add(p);
8798
- points.push(base);
8799
- }
8800
- p = base.double();
8801
8857
  }
8802
- return points;
8803
- },
8804
- /**
8805
- * Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
8806
- * @param W window size
8807
- * @param precomputes precomputed tables
8808
- * @param n scalar (we don't check here, but should be less than curve order)
8809
- * @returns real and fake (for const-time) points
8810
- */
8811
- wNAF(W, precomputes, n) {
8812
- // Smaller version:
8813
- // https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
8814
- // TODO: check the scalar is less than group order?
8815
- // wNAF behavior is undefined otherwise. But have to carefully remove
8816
- // other checks before wNAF. ORDER == bits here.
8817
- // Accumulators
8818
- let p = c.ZERO;
8819
- let f = c.BASE;
8820
- // This code was first written with assumption that 'f' and 'p' will never be infinity point:
8821
- // since each addition is multiplied by 2 ** W, it cannot cancel each other. However,
8822
- // there is negate now: it is possible that negated element from low value
8823
- // would be the same as high element, which will create carry into next window.
8824
- // It's not obvious how this can fail, but still worth investigating later.
8825
- const wo = calcWOpts(W, bits);
8826
- for (let window = 0; window < wo.windows; window++) {
8827
- // (n === _0n) is handled and not early-exited. isEven and offsetF are used for noise
8828
- const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
8829
- n = nextN;
8830
- if (isZero) {
8831
- // bits are 0: add garbage to fake point
8832
- // Important part for const-time getPublicKey: add random "noise" point to f.
8833
- f = f.add(negateCt(isNegF, precomputes[offsetF]));
8834
- }
8835
- else {
8836
- // bits are 1: add to result point
8837
- p = p.add(negateCt(isNeg, precomputes[offset]));
8838
- }
8858
+ p = base.double();
8859
+ }
8860
+ return points;
8861
+ }
8862
+ /**
8863
+ * Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
8864
+ * More compact implementation:
8865
+ * https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
8866
+ * @returns real and fake (for const-time) points
8867
+ */
8868
+ wNAF(W, precomputes, n) {
8869
+ // Scalar should be smaller than field order
8870
+ if (!this.Fn.isValid(n))
8871
+ throw new Error('invalid scalar');
8872
+ // Accumulators
8873
+ let p = this.ZERO;
8874
+ let f = this.BASE;
8875
+ // This code was first written with assumption that 'f' and 'p' will never be infinity point:
8876
+ // since each addition is multiplied by 2 ** W, it cannot cancel each other. However,
8877
+ // there is negate now: it is possible that negated element from low value
8878
+ // would be the same as high element, which will create carry into next window.
8879
+ // It's not obvious how this can fail, but still worth investigating later.
8880
+ const wo = calcWOpts(W, this.bits);
8881
+ for (let window = 0; window < wo.windows; window++) {
8882
+ // (n === _0n) is handled and not early-exited. isEven and offsetF are used for noise
8883
+ const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
8884
+ n = nextN;
8885
+ if (isZero) {
8886
+ // bits are 0: add garbage to fake point
8887
+ // Important part for const-time getPublicKey: add random "noise" point to f.
8888
+ f = f.add(negateCt(isNegF, precomputes[offsetF]));
8839
8889
  }
8840
- assert0(n);
8841
- // Return both real and fake points: JIT won't eliminate f.
8842
- // At this point there is a way to F be infinity-point even if p is not,
8843
- // which makes it less const-time: around 1 bigint multiply.
8844
- return { p, f };
8845
- },
8846
- /**
8847
- * Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
8848
- * @param W window size
8849
- * @param precomputes precomputed tables
8850
- * @param n scalar (we don't check here, but should be less than curve order)
8851
- * @param acc accumulator point to add result of multiplication
8852
- * @returns point
8853
- */
8854
- wNAFUnsafe(W, precomputes, n, acc = c.ZERO) {
8855
- const wo = calcWOpts(W, bits);
8856
- for (let window = 0; window < wo.windows; window++) {
8857
- if (n === _0n$7)
8858
- break; // Early-exit, skip 0 value
8859
- const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
8860
- n = nextN;
8861
- if (isZero) {
8862
- // Window bits are 0: skip processing.
8863
- // Move to next window.
8864
- continue;
8865
- }
8866
- else {
8867
- const item = precomputes[offset];
8868
- acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM
8869
- }
8890
+ else {
8891
+ // bits are 1: add to result point
8892
+ p = p.add(negateCt(isNeg, precomputes[offset]));
8870
8893
  }
8871
- assert0(n);
8872
- return acc;
8873
- },
8874
- getPrecomputes(W, P, transform) {
8875
- // Calculate precomputes on a first run, reuse them after
8876
- let comp = pointPrecomputes.get(P);
8877
- if (!comp) {
8878
- comp = this.precomputeWindow(P, W);
8879
- if (W !== 1) {
8880
- // Doing transform outside of if brings 15% perf hit
8881
- if (typeof transform === 'function')
8882
- comp = transform(comp);
8883
- pointPrecomputes.set(P, comp);
8884
- }
8894
+ }
8895
+ assert0(n);
8896
+ // Return both real and fake points: JIT won't eliminate f.
8897
+ // At this point there is a way to F be infinity-point even if p is not,
8898
+ // which makes it less const-time: around 1 bigint multiply.
8899
+ return { p, f };
8900
+ }
8901
+ /**
8902
+ * Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
8903
+ * @param acc accumulator point to add result of multiplication
8904
+ * @returns point
8905
+ */
8906
+ wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
8907
+ const wo = calcWOpts(W, this.bits);
8908
+ for (let window = 0; window < wo.windows; window++) {
8909
+ if (n === _0n$7)
8910
+ break; // Early-exit, skip 0 value
8911
+ const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
8912
+ n = nextN;
8913
+ if (isZero) {
8914
+ // Window bits are 0: skip processing.
8915
+ // Move to next window.
8916
+ continue;
8885
8917
  }
8886
- return comp;
8887
- },
8888
- wNAFCached(P, n, transform) {
8889
- const W = getW(P);
8890
- return this.wNAF(W, this.getPrecomputes(W, P, transform), n);
8891
- },
8892
- wNAFCachedUnsafe(P, n, transform, prev) {
8893
- const W = getW(P);
8894
- if (W === 1)
8895
- return this.unsafeLadder(P, n, prev); // For W=1 ladder is ~x2 faster
8896
- return this.wNAFUnsafe(W, this.getPrecomputes(W, P, transform), n, prev);
8897
- },
8898
- // We calculate precomputes for elliptic curve point multiplication
8899
- // using windowed method. This specifies window size and
8900
- // stores precomputed values. Usually only base point would be precomputed.
8901
- setWindowSize(P, W) {
8902
- validateW(W, bits);
8903
- pointWindowSizes.set(P, W);
8904
- pointPrecomputes.delete(P);
8905
- },
8906
- };
8907
- }
8918
+ else {
8919
+ const item = precomputes[offset];
8920
+ acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM
8921
+ }
8922
+ }
8923
+ assert0(n);
8924
+ return acc;
8925
+ }
8926
+ getPrecomputes(W, point, transform) {
8927
+ // Calculate precomputes on a first run, reuse them after
8928
+ let comp = pointPrecomputes.get(point);
8929
+ if (!comp) {
8930
+ comp = this.precomputeWindow(point, W);
8931
+ if (W !== 1) {
8932
+ // Doing transform outside of if brings 15% perf hit
8933
+ if (typeof transform === 'function')
8934
+ comp = transform(comp);
8935
+ pointPrecomputes.set(point, comp);
8936
+ }
8937
+ }
8938
+ return comp;
8939
+ }
8940
+ cached(point, scalar, transform) {
8941
+ const W = getW(point);
8942
+ return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);
8943
+ }
8944
+ unsafe(point, scalar, transform, prev) {
8945
+ const W = getW(point);
8946
+ if (W === 1)
8947
+ return this._unsafeLadder(point, scalar, prev); // For W=1 ladder is ~x2 faster
8948
+ return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);
8949
+ }
8950
+ // We calculate precomputes for elliptic curve point multiplication
8951
+ // using windowed method. This specifies window size and
8952
+ // stores precomputed values. Usually only base point would be precomputed.
8953
+ createCache(P, W) {
8954
+ validateW(W, this.bits);
8955
+ pointWindowSizes.set(P, W);
8956
+ pointPrecomputes.delete(P);
8957
+ }
8958
+ hasCache(elm) {
8959
+ return getW(elm) !== 1;
8960
+ }
8961
+ };
8908
8962
  /**
8909
8963
  * Endomorphism-specific multiplication for Koblitz curves.
8910
8964
  * Cost: 128 dbl, 0-256 adds.
8911
8965
  */
8912
- function mulEndoUnsafe(c, point, k1, k2) {
8966
+ function mulEndoUnsafe(Point, point, k1, k2) {
8913
8967
  let acc = point;
8914
- let p1 = c.ZERO;
8915
- let p2 = c.ZERO;
8968
+ let p1 = Point.ZERO;
8969
+ let p2 = Point.ZERO;
8916
8970
  while (k1 > _0n$7 || k2 > _0n$7) {
8917
- if (k1 & _1n$9)
8971
+ if (k1 & _1n$8)
8918
8972
  p1 = p1.add(acc);
8919
- if (k2 & _1n$9)
8973
+ if (k2 & _1n$8)
8920
8974
  p2 = p2.add(acc);
8921
8975
  acc = acc.double();
8922
- k1 >>= _1n$9;
8923
- k2 >>= _1n$9;
8976
+ k1 >>= _1n$8;
8977
+ k2 >>= _1n$8;
8924
8978
  }
8925
8979
  return { p1, p2 };
8926
8980
  }
@@ -8932,7 +8986,7 @@ function mulEndoUnsafe(c, point, k1, k2) {
8932
8986
  * @param c Curve Point constructor
8933
8987
  * @param fieldN field over CURVE.N - important that it's not over CURVE.P
8934
8988
  * @param points array of L curve points
8935
- * @param scalars array of L scalars (aka private keys / bigints)
8989
+ * @param scalars array of L scalars (aka secret keys / bigints)
8936
8990
  */
8937
8991
  function pippenger(c, fieldN, points, scalars) {
8938
8992
  // If we split scalars by some window (let's say 8 bits), every chunk will only
@@ -8981,7 +9035,7 @@ function pippenger(c, fieldN, points, scalars) {
8981
9035
  }
8982
9036
  return sum;
8983
9037
  }
8984
- function createField(order, field) {
9038
+ function createField(order, field, isLE) {
8985
9039
  if (field) {
8986
9040
  if (field.ORDER !== order)
8987
9041
  throw new Error('Field.ORDER must match order: Fp == p, Fn == n');
@@ -8989,11 +9043,13 @@ function createField(order, field) {
8989
9043
  return field;
8990
9044
  }
8991
9045
  else {
8992
- return Field$1(order);
9046
+ return Field$1(order, { isLE });
8993
9047
  }
8994
9048
  }
8995
9049
  /** Validates CURVE opts and creates fields */
8996
- function _createCurveFields(type, CURVE, curveOpts = {}) {
9050
+ function _createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
9051
+ if (FpFnLE === undefined)
9052
+ FpFnLE = type === 'edwards';
8997
9053
  if (!CURVE || typeof CURVE !== 'object')
8998
9054
  throw new Error(`expected valid ${type} CURVE object`);
8999
9055
  for (const p of ['p', 'n', 'h']) {
@@ -9001,8 +9057,8 @@ function _createCurveFields(type, CURVE, curveOpts = {}) {
9001
9057
  if (!(typeof val === 'bigint' && val > _0n$7))
9002
9058
  throw new Error(`CURVE.${p} must be positive bigint`);
9003
9059
  }
9004
- const Fp = createField(CURVE.p, curveOpts.Fp);
9005
- const Fn = createField(CURVE.n, curveOpts.Fn);
9060
+ const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE);
9061
+ const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE);
9006
9062
  const _b = 'b' ;
9007
9063
  const params = ['Gx', 'Gy', 'a', _b];
9008
9064
  for (const p of params) {
@@ -9010,7 +9066,8 @@ function _createCurveFields(type, CURVE, curveOpts = {}) {
9010
9066
  if (!Fp.isValid(CURVE[p]))
9011
9067
  throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
9012
9068
  }
9013
- return { Fp, Fn };
9069
+ CURVE = Object.freeze(Object.assign({}, CURVE));
9070
+ return { CURVE, Fp, Fn };
9014
9071
  }/**
9015
9072
  * Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
9016
9073
  *
@@ -9038,11 +9095,52 @@ function _createCurveFields(type, CURVE, curveOpts = {}) {
9038
9095
  * @module
9039
9096
  */
9040
9097
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
9041
- function validateSigVerOpts(opts) {
9042
- if (opts.lowS !== undefined)
9043
- abool('lowS', opts.lowS);
9044
- if (opts.prehash !== undefined)
9045
- abool('prehash', opts.prehash);
9098
+ // We construct basis in such way that den is always positive and equals n, but num sign depends on basis (not on secret value)
9099
+ const divNearest$1 = (num, den) => (num + (num >= 0 ? den : -den) / _2n$6) / den;
9100
+ /**
9101
+ * Splits scalar for GLV endomorphism.
9102
+ */
9103
+ function _splitEndoScalar(k, basis, n) {
9104
+ // Split scalar into two such that part is ~half bits: `abs(part) < sqrt(N)`
9105
+ // Since part can be negative, we need to do this on point.
9106
+ // TODO: verifyScalar function which consumes lambda
9107
+ const [[a1, b1], [a2, b2]] = basis;
9108
+ const c1 = divNearest$1(b2 * k, n);
9109
+ const c2 = divNearest$1(-b1 * k, n);
9110
+ // |k1|/|k2| is < sqrt(N), but can be negative.
9111
+ // If we do `k1 mod N`, we'll get big scalar (`> sqrt(N)`): so, we do cheaper negation instead.
9112
+ let k1 = k - c1 * a1 - c2 * a2;
9113
+ let k2 = -c1 * b1 - c2 * b2;
9114
+ const k1neg = k1 < _0n$6;
9115
+ const k2neg = k2 < _0n$6;
9116
+ if (k1neg)
9117
+ k1 = -k1;
9118
+ if (k2neg)
9119
+ k2 = -k2;
9120
+ // Double check that resulting scalar less than half bits of N: otherwise wNAF will fail.
9121
+ // This should only happen on wrong basises. Also, math inside is too complex and I don't trust it.
9122
+ const MAX_NUM = bitMask$1(Math.ceil(bitLen$1(n) / 2)) + _1n$7; // Half bits of N
9123
+ if (k1 < _0n$6 || k1 >= MAX_NUM || k2 < _0n$6 || k2 >= MAX_NUM) {
9124
+ throw new Error('splitScalar (endomorphism): failed, k=' + k);
9125
+ }
9126
+ return { k1neg, k1, k2neg, k2 };
9127
+ }
9128
+ function validateSigFormat(format) {
9129
+ if (!['compact', 'recovered', 'der'].includes(format))
9130
+ throw new Error('Signature format must be "compact", "recovered", or "der"');
9131
+ return format;
9132
+ }
9133
+ function validateSigOpts(opts, def) {
9134
+ const optsn = {};
9135
+ for (let optName of Object.keys(def)) {
9136
+ // @ts-ignore
9137
+ optsn[optName] = opts[optName] === undefined ? def[optName] : opts[optName];
9138
+ }
9139
+ _abool2(optsn.lowS, 'lowS');
9140
+ _abool2(optsn.prehash, 'prehash');
9141
+ if (optsn.format !== undefined)
9142
+ validateSigFormat(optsn.format);
9143
+ return optsn;
9046
9144
  }
9047
9145
  class DERErr extends Error {
9048
9146
  constructor(m = '') {
@@ -9162,56 +9260,49 @@ const DER$1 = {
9162
9260
  };
9163
9261
  // Be friendly to bad ECMAScript parsers by not using bigint literals
9164
9262
  // prettier-ignore
9165
- const _0n$6 = BigInt(0), _1n$8 = BigInt(1), _2n$6 = BigInt(2), _3n$2 = BigInt(3), _4n$1 = BigInt(4);
9166
- // TODO: remove
9167
- function _legacyHelperEquat(Fp, a, b) {
9168
- /**
9169
- * y² = x³ + ax + b: Short weierstrass curve formula. Takes x, returns y².
9170
- * @returns y²
9171
- */
9172
- function weierstrassEquation(x) {
9173
- const x2 = Fp.sqr(x); // x * x
9174
- const x3 = Fp.mul(x2, x); // x² * x
9175
- return Fp.add(Fp.add(x3, Fp.mul(x, a)), b); // x³ + a * x + b
9176
- }
9177
- return weierstrassEquation;
9178
- }
9179
- function _legacyHelperNormPriv(Fn, allowedPrivateKeyLengths, wrapPrivateKey) {
9263
+ const _0n$6 = BigInt(0), _1n$7 = BigInt(1), _2n$6 = BigInt(2), _3n$2 = BigInt(3), _4n$1 = BigInt(4);
9264
+ function _normFnElement(Fn, key) {
9180
9265
  const { BYTES: expected } = Fn;
9181
- // Validates if priv key is valid and converts it to bigint.
9182
- function normPrivateKeyToScalar(key) {
9183
- let num;
9184
- if (typeof key === 'bigint') {
9185
- num = key;
9266
+ let num;
9267
+ if (typeof key === 'bigint') {
9268
+ num = key;
9269
+ }
9270
+ else {
9271
+ let bytes = ensureBytes$1('private key', key);
9272
+ try {
9273
+ num = Fn.fromBytes(bytes);
9186
9274
  }
9187
- else {
9188
- let bytes = ensureBytes$1('private key', key);
9189
- if (allowedPrivateKeyLengths) {
9190
- if (!allowedPrivateKeyLengths.includes(bytes.length * 2))
9191
- throw new Error('invalid private key');
9192
- const padded = new Uint8Array(expected);
9193
- padded.set(bytes, padded.length - bytes.length);
9194
- bytes = padded;
9195
- }
9196
- try {
9197
- num = Fn.fromBytes(bytes);
9198
- }
9199
- catch (error) {
9200
- throw new Error(`invalid private key: expected ui8a of size ${expected}, got ${typeof key}`);
9201
- }
9275
+ catch (error) {
9276
+ throw new Error(`invalid private key: expected ui8a of size ${expected}, got ${typeof key}`);
9202
9277
  }
9203
- if (wrapPrivateKey)
9204
- num = Fn.create(num); // disabled by default, enabled for BLS
9205
- if (!Fn.isValidNot0(num))
9206
- throw new Error('invalid private key: out of range [1..N-1]');
9207
- return num;
9208
9278
  }
9209
- return normPrivateKeyToScalar;
9279
+ if (!Fn.isValidNot0(num))
9280
+ throw new Error('invalid private key: out of range [1..N-1]');
9281
+ return num;
9210
9282
  }
9211
- function weierstrassN(CURVE, curveOpts = {}) {
9212
- const { Fp, Fn } = _createCurveFields('weierstrass', CURVE, curveOpts);
9283
+ /**
9284
+ * Creates weierstrass Point constructor, based on specified curve options.
9285
+ *
9286
+ * @example
9287
+ ```js
9288
+ const opts = {
9289
+ p: BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff'),
9290
+ n: BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551'),
9291
+ h: BigInt(1),
9292
+ a: BigInt('0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc'),
9293
+ b: BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b'),
9294
+ Gx: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),
9295
+ Gy: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5'),
9296
+ };
9297
+ const p256_Point = weierstrass(opts);
9298
+ ```
9299
+ */
9300
+ function weierstrassN(params, extraOpts = {}) {
9301
+ const validated = _createCurveFields('weierstrass', params, extraOpts);
9302
+ const { Fp, Fn } = validated;
9303
+ let CURVE = validated.CURVE;
9213
9304
  const { h: cofactor, n: CURVE_ORDER } = CURVE;
9214
- _validateObject(curveOpts, {}, {
9305
+ _validateObject(extraOpts, {}, {
9215
9306
  allowInfinityPoint: 'boolean',
9216
9307
  clearCofactor: 'function',
9217
9308
  isTorsionFree: 'function',
@@ -9220,15 +9311,14 @@ function weierstrassN(CURVE, curveOpts = {}) {
9220
9311
  endo: 'object',
9221
9312
  wrapPrivateKey: 'boolean',
9222
9313
  });
9223
- const { endo } = curveOpts;
9314
+ const { endo } = extraOpts;
9224
9315
  if (endo) {
9225
9316
  // validateObject(endo, { beta: 'bigint', splitScalar: 'function' });
9226
- if (!Fp.is0(CURVE.a) ||
9227
- typeof endo.beta !== 'bigint' ||
9228
- typeof endo.splitScalar !== 'function') {
9229
- throw new Error('invalid endo: expected "beta": bigint and "splitScalar": function');
9317
+ if (!Fp.is0(CURVE.a) || typeof endo.beta !== 'bigint' || !Array.isArray(endo.basises)) {
9318
+ throw new Error('invalid endo: expected "beta": bigint and "basises": array');
9230
9319
  }
9231
9320
  }
9321
+ const lengths = getWLengths(Fp, Fn);
9232
9322
  function assertCompressionIsSupported() {
9233
9323
  if (!Fp.isOdd)
9234
9324
  throw new Error('compression is not supported: Field does not have .isOdd()');
@@ -9237,7 +9327,7 @@ function weierstrassN(CURVE, curveOpts = {}) {
9237
9327
  function pointToBytes(_c, point, isCompressed) {
9238
9328
  const { x, y } = point.toAffine();
9239
9329
  const bx = Fp.toBytes(x);
9240
- abool('isCompressed', isCompressed);
9330
+ _abool2(isCompressed, 'isCompressed');
9241
9331
  if (isCompressed) {
9242
9332
  assertCompressionIsSupported();
9243
9333
  const hasEvenY = !Fp.isOdd(y);
@@ -9248,15 +9338,13 @@ function weierstrassN(CURVE, curveOpts = {}) {
9248
9338
  }
9249
9339
  }
9250
9340
  function pointFromBytes(bytes) {
9251
- abytes(bytes);
9252
- const L = Fp.BYTES;
9253
- const LC = L + 1; // length compressed, e.g. 33 for 32-byte field
9254
- const LU = 2 * L + 1; // length uncompressed, e.g. 65 for 32-byte field
9341
+ _abytes2(bytes, undefined, 'Point');
9342
+ const { public: comp, publicUncompressed: uncomp } = lengths; // e.g. for 32-byte: 33, 65
9255
9343
  const length = bytes.length;
9256
9344
  const head = bytes[0];
9257
9345
  const tail = bytes.subarray(1);
9258
9346
  // No actual validation is done here: use .assertValidity()
9259
- if (length === LC && (head === 0x02 || head === 0x03)) {
9347
+ if (length === comp && (head === 0x02 || head === 0x03)) {
9260
9348
  const x = Fp.fromBytes(tail);
9261
9349
  if (!Fp.isValid(x))
9262
9350
  throw new Error('bad point: is not on curve, wrong x');
@@ -9276,21 +9364,26 @@ function weierstrassN(CURVE, curveOpts = {}) {
9276
9364
  y = Fp.neg(y);
9277
9365
  return { x, y };
9278
9366
  }
9279
- else if (length === LU && head === 0x04) {
9367
+ else if (length === uncomp && head === 0x04) {
9280
9368
  // TODO: more checks
9281
- const x = Fp.fromBytes(tail.subarray(L * 0, L * 1));
9282
- const y = Fp.fromBytes(tail.subarray(L * 1, L * 2));
9369
+ const L = Fp.BYTES;
9370
+ const x = Fp.fromBytes(tail.subarray(0, L));
9371
+ const y = Fp.fromBytes(tail.subarray(L, L * 2));
9283
9372
  if (!isValidXY(x, y))
9284
9373
  throw new Error('bad point: is not on curve');
9285
9374
  return { x, y };
9286
9375
  }
9287
9376
  else {
9288
- throw new Error(`bad point: got length ${length}, expected compressed=${LC} or uncompressed=${LU}`);
9377
+ throw new Error(`bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`);
9289
9378
  }
9290
9379
  }
9291
- const toBytes = curveOpts.toBytes || pointToBytes;
9292
- const fromBytes = curveOpts.fromBytes || pointFromBytes;
9293
- const weierstrassEquation = _legacyHelperEquat(Fp, CURVE.a, CURVE.b);
9380
+ const encodePoint = extraOpts.toBytes || pointToBytes;
9381
+ const decodePoint = extraOpts.fromBytes || pointFromBytes;
9382
+ function weierstrassEquation(x) {
9383
+ const x2 = Fp.sqr(x); // x * x
9384
+ const x3 = Fp.mul(x2, x); // x² * x
9385
+ return Fp.add(Fp.add(x3, Fp.mul(x, CURVE.a)), CURVE.b); // x³ + a * x + b
9386
+ }
9294
9387
  // TODO: move top-level
9295
9388
  /** Checks whether equation holds for given x, y: y² == x³ + ax + b */
9296
9389
  function isValidXY(x, y) {
@@ -9318,28 +9411,33 @@ function weierstrassN(CURVE, curveOpts = {}) {
9318
9411
  if (!(other instanceof Point))
9319
9412
  throw new Error('ProjectivePoint expected');
9320
9413
  }
9414
+ function splitEndoScalarN(k) {
9415
+ if (!endo || !endo.basises)
9416
+ throw new Error('no endo');
9417
+ return _splitEndoScalar(k, endo.basises, Fn.ORDER);
9418
+ }
9321
9419
  // Memoized toAffine / validity check. They are heavy. Points are immutable.
9322
9420
  // Converts Projective point to affine (x, y) coordinates.
9323
9421
  // Can accept precomputed Z^-1 - for example, from invertBatch.
9324
9422
  // (X, Y, Z) ∋ (x=X/Z, y=Y/Z)
9325
9423
  const toAffineMemo = memoized((p, iz) => {
9326
- const { px: x, py: y, pz: z } = p;
9424
+ const { X, Y, Z } = p;
9327
9425
  // Fast-path for normalized points
9328
- if (Fp.eql(z, Fp.ONE))
9329
- return { x, y };
9426
+ if (Fp.eql(Z, Fp.ONE))
9427
+ return { x: X, y: Y };
9330
9428
  const is0 = p.is0();
9331
9429
  // If invZ was 0, we return zero point. However we still want to execute
9332
9430
  // all operations, so we replace invZ with a random number, 1.
9333
9431
  if (iz == null)
9334
- iz = is0 ? Fp.ONE : Fp.inv(z);
9335
- const ax = Fp.mul(x, iz);
9336
- const ay = Fp.mul(y, iz);
9337
- const zz = Fp.mul(z, iz);
9432
+ iz = is0 ? Fp.ONE : Fp.inv(Z);
9433
+ const x = Fp.mul(X, iz);
9434
+ const y = Fp.mul(Y, iz);
9435
+ const zz = Fp.mul(Z, iz);
9338
9436
  if (is0)
9339
9437
  return { x: Fp.ZERO, y: Fp.ZERO };
9340
9438
  if (!Fp.eql(zz, Fp.ONE))
9341
9439
  throw new Error('invZ was invalid');
9342
- return { x: ax, y: ay };
9440
+ return { x, y };
9343
9441
  });
9344
9442
  // NOTE: on exception this will crash 'cached' and no value will be set.
9345
9443
  // Otherwise true will be return
@@ -9348,7 +9446,7 @@ function weierstrassN(CURVE, curveOpts = {}) {
9348
9446
  // (0, 1, 0) aka ZERO is invalid in most contexts.
9349
9447
  // In BLS, ZERO can be serialized, so we allow it.
9350
9448
  // (0, 0, 0) is invalid representation of ZERO.
9351
- if (curveOpts.allowInfinityPoint && !Fp.is0(p.py))
9449
+ if (extraOpts.allowInfinityPoint && !Fp.is0(p.Y))
9352
9450
  return;
9353
9451
  throw new Error('bad point: ZERO');
9354
9452
  }
@@ -9363,7 +9461,7 @@ function weierstrassN(CURVE, curveOpts = {}) {
9363
9461
  return true;
9364
9462
  });
9365
9463
  function finishEndo(endoBeta, k1p, k2p, k1neg, k2neg) {
9366
- k2p = new Point(Fp.mul(k2p.px, endoBeta), k2p.py, k2p.pz);
9464
+ k2p = new Point(Fp.mul(k2p.X, endoBeta), k2p.Y, k2p.Z);
9367
9465
  k1p = negateCt(k1neg, k1p);
9368
9466
  k2p = negateCt(k2neg, k2p);
9369
9467
  return k1p.add(k2p);
@@ -9375,12 +9473,15 @@ function weierstrassN(CURVE, curveOpts = {}) {
9375
9473
  */
9376
9474
  class Point {
9377
9475
  /** Does NOT validate if the point is valid. Use `.assertValidity()`. */
9378
- constructor(px, py, pz) {
9379
- this.px = acoord('x', px);
9380
- this.py = acoord('y', py, true);
9381
- this.pz = acoord('z', pz);
9476
+ constructor(X, Y, Z) {
9477
+ this.X = acoord('x', X);
9478
+ this.Y = acoord('y', Y, true);
9479
+ this.Z = acoord('z', Z);
9382
9480
  Object.freeze(this);
9383
9481
  }
9482
+ static CURVE() {
9483
+ return CURVE;
9484
+ }
9384
9485
  /** Does NOT validate if the point is valid. Use `.assertValidity()`. */
9385
9486
  static fromAffine(p) {
9386
9487
  const { x, y } = p || {};
@@ -9393,33 +9494,19 @@ function weierstrassN(CURVE, curveOpts = {}) {
9393
9494
  return Point.ZERO;
9394
9495
  return new Point(x, y, Fp.ONE);
9395
9496
  }
9396
- get x() {
9397
- return this.toAffine().x;
9398
- }
9399
- get y() {
9400
- return this.toAffine().y;
9401
- }
9402
- static normalizeZ(points) {
9403
- return normalizeZ(Point, 'pz', points);
9404
- }
9405
9497
  static fromBytes(bytes) {
9406
- abytes(bytes);
9407
- return Point.fromHex(bytes);
9408
- }
9409
- /** Converts hash string or Uint8Array to Point. */
9410
- static fromHex(hex) {
9411
- const P = Point.fromAffine(fromBytes(ensureBytes$1('pointHex', hex)));
9498
+ const P = Point.fromAffine(decodePoint(_abytes2(bytes, undefined, 'point')));
9412
9499
  P.assertValidity();
9413
9500
  return P;
9414
9501
  }
9415
- /** Multiplies generator point by privateKey. */
9416
- static fromPrivateKey(privateKey) {
9417
- const normPrivateKeyToScalar = _legacyHelperNormPriv(Fn, curveOpts.allowedPrivateKeyLengths, curveOpts.wrapPrivateKey);
9418
- return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
9502
+ static fromHex(hex) {
9503
+ return Point.fromBytes(ensureBytes$1('pointHex', hex));
9419
9504
  }
9420
- /** Multiscalar Multiplication */
9421
- static msm(points, scalars) {
9422
- return pippenger(Point, Fn, points, scalars);
9505
+ get x() {
9506
+ return this.toAffine().x;
9507
+ }
9508
+ get y() {
9509
+ return this.toAffine().y;
9423
9510
  }
9424
9511
  /**
9425
9512
  *
@@ -9428,15 +9515,11 @@ function weierstrassN(CURVE, curveOpts = {}) {
9428
9515
  * @returns
9429
9516
  */
9430
9517
  precompute(windowSize = 8, isLazy = true) {
9431
- wnaf.setWindowSize(this, windowSize);
9518
+ wnaf.createCache(this, windowSize);
9432
9519
  if (!isLazy)
9433
9520
  this.multiply(_3n$2); // random number
9434
9521
  return this;
9435
9522
  }
9436
- /** "Private method", don't use it directly */
9437
- _setWindowSize(windowSize) {
9438
- this.precompute(windowSize);
9439
- }
9440
9523
  // TODO: return `this`
9441
9524
  /** A point on curve is valid if it conforms to equation. */
9442
9525
  assertValidity() {
@@ -9451,15 +9534,15 @@ function weierstrassN(CURVE, curveOpts = {}) {
9451
9534
  /** Compare one point to another. */
9452
9535
  equals(other) {
9453
9536
  aprjpoint(other);
9454
- const { px: X1, py: Y1, pz: Z1 } = this;
9455
- const { px: X2, py: Y2, pz: Z2 } = other;
9537
+ const { X: X1, Y: Y1, Z: Z1 } = this;
9538
+ const { X: X2, Y: Y2, Z: Z2 } = other;
9456
9539
  const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
9457
9540
  const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));
9458
9541
  return U1 && U2;
9459
9542
  }
9460
9543
  /** Flips point to one corresponding to (x, -y) in Affine coordinates. */
9461
9544
  negate() {
9462
- return new Point(this.px, Fp.neg(this.py), this.pz);
9545
+ return new Point(this.X, Fp.neg(this.Y), this.Z);
9463
9546
  }
9464
9547
  // Renes-Costello-Batina exception-free doubling formula.
9465
9548
  // There is 30% faster Jacobian formula, but it is not complete.
@@ -9468,7 +9551,7 @@ function weierstrassN(CURVE, curveOpts = {}) {
9468
9551
  double() {
9469
9552
  const { a, b } = CURVE;
9470
9553
  const b3 = Fp.mul(b, _3n$2);
9471
- const { px: X1, py: Y1, pz: Z1 } = this;
9554
+ const { X: X1, Y: Y1, Z: Z1 } = this;
9472
9555
  let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
9473
9556
  let t0 = Fp.mul(X1, X1); // step 1
9474
9557
  let t1 = Fp.mul(Y1, Y1);
@@ -9509,8 +9592,8 @@ function weierstrassN(CURVE, curveOpts = {}) {
9509
9592
  // Cost: 12M + 0S + 3*a + 3*b3 + 23add.
9510
9593
  add(other) {
9511
9594
  aprjpoint(other);
9512
- const { px: X1, py: Y1, pz: Z1 } = this;
9513
- const { px: X2, py: Y2, pz: Z2 } = other;
9595
+ const { X: X1, Y: Y1, Z: Z1 } = this;
9596
+ const { X: X2, Y: Y2, Z: Z2 } = other;
9514
9597
  let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
9515
9598
  const a = CURVE.a;
9516
9599
  const b3 = Fp.mul(CURVE.b, _3n$2);
@@ -9572,14 +9655,14 @@ function weierstrassN(CURVE, curveOpts = {}) {
9572
9655
  * @returns New point
9573
9656
  */
9574
9657
  multiply(scalar) {
9575
- const { endo } = curveOpts;
9658
+ const { endo } = extraOpts;
9576
9659
  if (!Fn.isValidNot0(scalar))
9577
9660
  throw new Error('invalid scalar: out of range'); // 0 is invalid
9578
9661
  let point, fake; // Fake point is used to const-time mult
9579
- const mul = (n) => wnaf.wNAFCached(this, n, Point.normalizeZ);
9662
+ const mul = (n) => wnaf.cached(this, n, (p) => normalizeZ(Point, p));
9580
9663
  /** See docs for {@link EndomorphismOpts} */
9581
9664
  if (endo) {
9582
- const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
9665
+ const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(scalar);
9583
9666
  const { p: k1p, f: k1f } = mul(k1);
9584
9667
  const { p: k2p, f: k2f } = mul(k2);
9585
9668
  fake = k1f.add(k2f);
@@ -9591,32 +9674,31 @@ function weierstrassN(CURVE, curveOpts = {}) {
9591
9674
  fake = f;
9592
9675
  }
9593
9676
  // Normalize `z` for both points, but return only real one
9594
- return Point.normalizeZ([point, fake])[0];
9677
+ return normalizeZ(Point, [point, fake])[0];
9595
9678
  }
9596
9679
  /**
9597
9680
  * Non-constant-time multiplication. Uses double-and-add algorithm.
9598
9681
  * It's faster, but should only be used when you don't care about
9599
- * an exposed private key e.g. sig verification, which works over *public* keys.
9682
+ * an exposed secret key e.g. sig verification, which works over *public* keys.
9600
9683
  */
9601
9684
  multiplyUnsafe(sc) {
9602
- const { endo } = curveOpts;
9685
+ const { endo } = extraOpts;
9603
9686
  const p = this;
9604
9687
  if (!Fn.isValid(sc))
9605
9688
  throw new Error('invalid scalar: out of range'); // 0 is valid
9606
9689
  if (sc === _0n$6 || p.is0())
9607
9690
  return Point.ZERO;
9608
- if (sc === _1n$8)
9691
+ if (sc === _1n$7)
9609
9692
  return p; // fast-path
9610
- if (wnaf.hasPrecomputes(this))
9693
+ if (wnaf.hasCache(this))
9611
9694
  return this.multiply(sc);
9612
9695
  if (endo) {
9613
- const { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
9614
- // `wNAFCachedUnsafe` is 30% slower
9615
- const { p1, p2 } = mulEndoUnsafe(Point, p, k1, k2);
9696
+ const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(sc);
9697
+ const { p1, p2 } = mulEndoUnsafe(Point, p, k1, k2); // 30% faster vs wnaf.unsafe
9616
9698
  return finishEndo(endo.beta, p1, p2, k1neg, k2neg);
9617
9699
  }
9618
9700
  else {
9619
- return wnaf.wNAFCachedUnsafe(p, sc);
9701
+ return wnaf.unsafe(p, sc);
9620
9702
  }
9621
9703
  }
9622
9704
  multiplyAndAddUnsafe(Q, a, b) {
@@ -9635,29 +9717,29 @@ function weierstrassN(CURVE, curveOpts = {}) {
9635
9717
  * Always torsion-free for cofactor=1 curves.
9636
9718
  */
9637
9719
  isTorsionFree() {
9638
- const { isTorsionFree } = curveOpts;
9639
- if (cofactor === _1n$8)
9720
+ const { isTorsionFree } = extraOpts;
9721
+ if (cofactor === _1n$7)
9640
9722
  return true;
9641
9723
  if (isTorsionFree)
9642
9724
  return isTorsionFree(Point, this);
9643
- return wnaf.wNAFCachedUnsafe(this, CURVE_ORDER).is0();
9725
+ return wnaf.unsafe(this, CURVE_ORDER).is0();
9644
9726
  }
9645
9727
  clearCofactor() {
9646
- const { clearCofactor } = curveOpts;
9647
- if (cofactor === _1n$8)
9728
+ const { clearCofactor } = extraOpts;
9729
+ if (cofactor === _1n$7)
9648
9730
  return this; // Fast-path
9649
9731
  if (clearCofactor)
9650
9732
  return clearCofactor(Point, this);
9651
9733
  return this.multiplyUnsafe(cofactor);
9652
9734
  }
9735
+ isSmallOrder() {
9736
+ // can we use this.clearCofactor()?
9737
+ return this.multiplyUnsafe(cofactor).is0();
9738
+ }
9653
9739
  toBytes(isCompressed = true) {
9654
- abool('isCompressed', isCompressed);
9740
+ _abool2(isCompressed, 'isCompressed');
9655
9741
  this.assertValidity();
9656
- return toBytes(Point, this, isCompressed);
9657
- }
9658
- /** @deprecated use `toBytes` */
9659
- toRawBytes(isCompressed = true) {
9660
- return this.toBytes(isCompressed);
9742
+ return encodePoint(Point, this, isCompressed);
9661
9743
  }
9662
9744
  toHex(isCompressed = true) {
9663
9745
  return bytesToHex$1(this.toBytes(isCompressed));
@@ -9665,24 +9747,168 @@ function weierstrassN(CURVE, curveOpts = {}) {
9665
9747
  toString() {
9666
9748
  return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;
9667
9749
  }
9750
+ // TODO: remove
9751
+ get px() {
9752
+ return this.X;
9753
+ }
9754
+ get py() {
9755
+ return this.X;
9756
+ }
9757
+ get pz() {
9758
+ return this.Z;
9759
+ }
9760
+ toRawBytes(isCompressed = true) {
9761
+ return this.toBytes(isCompressed);
9762
+ }
9763
+ _setWindowSize(windowSize) {
9764
+ this.precompute(windowSize);
9765
+ }
9766
+ static normalizeZ(points) {
9767
+ return normalizeZ(Point, points);
9768
+ }
9769
+ static msm(points, scalars) {
9770
+ return pippenger(Point, Fn, points, scalars);
9771
+ }
9772
+ static fromPrivateKey(privateKey) {
9773
+ return Point.BASE.multiply(_normFnElement(Fn, privateKey));
9774
+ }
9668
9775
  }
9669
9776
  // base / generator point
9670
9777
  Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
9671
9778
  // zero / infinity / identity point
9672
9779
  Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO); // 0, 1, 0
9673
- // fields
9780
+ // math field
9674
9781
  Point.Fp = Fp;
9782
+ // scalar field
9675
9783
  Point.Fn = Fn;
9676
9784
  const bits = Fn.BITS;
9677
- const wnaf = wNAF$1(Point, curveOpts.endo ? Math.ceil(bits / 2) : bits);
9785
+ const wnaf = new wNAF$1(Point, extraOpts.endo ? Math.ceil(bits / 2) : bits);
9678
9786
  return Point;
9679
9787
  }
9680
9788
  // Points start with byte 0x02 when y is even; otherwise 0x03
9681
9789
  function pprefix(hasEvenY) {
9682
9790
  return Uint8Array.of(hasEvenY ? 0x02 : 0x03);
9683
9791
  }
9684
- function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
9685
- _validateObject(ecdsaOpts, { hash: 'function' }, {
9792
+ function getWLengths(Fp, Fn) {
9793
+ return {
9794
+ secret: Fn.BYTES,
9795
+ public: 1 + Fp.BYTES,
9796
+ publicUncompressed: 1 + 2 * Fp.BYTES,
9797
+ publicKeyHasPrefix: true,
9798
+ signature: 2 * Fn.BYTES,
9799
+ };
9800
+ }
9801
+ /**
9802
+ * Sometimes users only need getPublicKey, getSharedSecret, and secret key handling.
9803
+ * This helper ensures no signature functionality is present. Less code, smaller bundle size.
9804
+ */
9805
+ function ecdh(Point, ecdhOpts = {}) {
9806
+ const { Fn } = Point;
9807
+ const randomBytes_ = ecdhOpts.randomBytes || randomBytes$3;
9808
+ const lengths = Object.assign(getWLengths(Point.Fp, Fn), { seed: getMinHashLength$1(Fn.ORDER) });
9809
+ function isValidSecretKey(secretKey) {
9810
+ try {
9811
+ return !!_normFnElement(Fn, secretKey);
9812
+ }
9813
+ catch (error) {
9814
+ return false;
9815
+ }
9816
+ }
9817
+ function isValidPublicKey(publicKey, isCompressed) {
9818
+ const { public: comp, publicUncompressed } = lengths;
9819
+ try {
9820
+ const l = publicKey.length;
9821
+ if (isCompressed === true && l !== comp)
9822
+ return false;
9823
+ if (isCompressed === false && l !== publicUncompressed)
9824
+ return false;
9825
+ return !!Point.fromBytes(publicKey);
9826
+ }
9827
+ catch (error) {
9828
+ return false;
9829
+ }
9830
+ }
9831
+ /**
9832
+ * Produces cryptographically secure secret key from random of size
9833
+ * (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.
9834
+ */
9835
+ function randomSecretKey(seed = randomBytes_(lengths.seed)) {
9836
+ return mapHashToField$1(_abytes2(seed, lengths.seed, 'seed'), Fn.ORDER);
9837
+ }
9838
+ /**
9839
+ * Computes public key for a secret key. Checks for validity of the secret key.
9840
+ * @param isCompressed whether to return compact (default), or full key
9841
+ * @returns Public key, full when isCompressed=false; short when isCompressed=true
9842
+ */
9843
+ function getPublicKey(secretKey, isCompressed = true) {
9844
+ return Point.BASE.multiply(_normFnElement(Fn, secretKey)).toBytes(isCompressed);
9845
+ }
9846
+ function keygen(seed) {
9847
+ const secretKey = randomSecretKey(seed);
9848
+ return { secretKey, publicKey: getPublicKey(secretKey) };
9849
+ }
9850
+ /**
9851
+ * Quick and dirty check for item being public key. Does not validate hex, or being on-curve.
9852
+ */
9853
+ function isProbPub(item) {
9854
+ if (typeof item === 'bigint')
9855
+ return false;
9856
+ if (item instanceof Point)
9857
+ return true;
9858
+ if (Fn.allowedLengths || lengths.secret === lengths.public)
9859
+ return undefined;
9860
+ const l = ensureBytes$1('key', item).length;
9861
+ return l === lengths.public || l === lengths.publicUncompressed;
9862
+ }
9863
+ /**
9864
+ * ECDH (Elliptic Curve Diffie Hellman).
9865
+ * Computes shared public key from secret key A and public key B.
9866
+ * Checks: 1) secret key validity 2) shared key is on-curve.
9867
+ * Does NOT hash the result.
9868
+ * @param isCompressed whether to return compact (default), or full key
9869
+ * @returns shared public key
9870
+ */
9871
+ function getSharedSecret(secretKeyA, publicKeyB, isCompressed = true) {
9872
+ if (isProbPub(secretKeyA) === true)
9873
+ throw new Error('first arg must be private key');
9874
+ if (isProbPub(publicKeyB) === false)
9875
+ throw new Error('second arg must be public key');
9876
+ const s = _normFnElement(Fn, secretKeyA);
9877
+ const b = Point.fromHex(publicKeyB); // checks for being on-curve
9878
+ return b.multiply(s).toBytes(isCompressed);
9879
+ }
9880
+ const utils = {
9881
+ isValidSecretKey,
9882
+ isValidPublicKey,
9883
+ randomSecretKey,
9884
+ // TODO: remove
9885
+ isValidPrivateKey: isValidSecretKey,
9886
+ randomPrivateKey: randomSecretKey,
9887
+ normPrivateKeyToScalar: (key) => _normFnElement(Fn, key),
9888
+ precompute(windowSize = 8, point = Point.BASE) {
9889
+ return point.precompute(windowSize, false);
9890
+ },
9891
+ };
9892
+ return Object.freeze({ getPublicKey, getSharedSecret, keygen, Point, utils, lengths });
9893
+ }
9894
+ /**
9895
+ * Creates ECDSA signing interface for given elliptic curve `Point` and `hash` function.
9896
+ * We need `hash` for 2 features:
9897
+ * 1. Message prehash-ing. NOT used if `sign` / `verify` are called with `prehash: false`
9898
+ * 2. k generation in `sign`, using HMAC-drbg(hash)
9899
+ *
9900
+ * ECDSAOpts are only rarely needed.
9901
+ *
9902
+ * @example
9903
+ * ```js
9904
+ * const p256_Point = weierstrass(...);
9905
+ * const p256_sha256 = ecdsa(p256_Point, sha256);
9906
+ * const p256_sha224 = ecdsa(p256_Point, sha224);
9907
+ * ```
9908
+ */
9909
+ function ecdsa(Point, hash, ecdsaOpts = {}) {
9910
+ ahash(hash);
9911
+ _validateObject(ecdsaOpts, {}, {
9686
9912
  hmac: 'function',
9687
9913
  lowS: 'boolean',
9688
9914
  randomBytes: 'function',
@@ -9691,54 +9917,66 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
9691
9917
  });
9692
9918
  const randomBytes_ = ecdsaOpts.randomBytes || randomBytes$3;
9693
9919
  const hmac_ = ecdsaOpts.hmac ||
9694
- ((key, ...msgs) => hmac$1(ecdsaOpts.hash, key, concatBytes$2(...msgs)));
9920
+ ((key, ...msgs) => hmac$1(hash, key, concatBytes$2(...msgs)));
9695
9921
  const { Fp, Fn } = Point;
9696
9922
  const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;
9923
+ const { keygen, getPublicKey, getSharedSecret, utils, lengths } = ecdh(Point, ecdsaOpts);
9924
+ const defaultSigOpts = {
9925
+ prehash: false,
9926
+ lowS: typeof ecdsaOpts.lowS === 'boolean' ? ecdsaOpts.lowS : false,
9927
+ format: undefined, //'compact' as ECDSASigFormat,
9928
+ extraEntropy: false,
9929
+ };
9930
+ const defaultSigOpts_format = 'compact';
9697
9931
  function isBiggerThanHalfOrder(number) {
9698
- const HALF = CURVE_ORDER >> _1n$8;
9932
+ const HALF = CURVE_ORDER >> _1n$7;
9699
9933
  return number > HALF;
9700
9934
  }
9701
9935
  function normalizeS(s) {
9702
9936
  return isBiggerThanHalfOrder(s) ? Fn.neg(s) : s;
9703
9937
  }
9704
- function aValidRS(title, num) {
9938
+ function validateRS(title, num) {
9705
9939
  if (!Fn.isValidNot0(num))
9706
- throw new Error(`invalid signature ${title}: out of range 1..CURVE.n`);
9940
+ throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`);
9941
+ return num;
9707
9942
  }
9708
9943
  /**
9709
- * ECDSA signature with its (r, s) properties. Supports DER & compact representations.
9944
+ * ECDSA signature with its (r, s) properties. Supports compact, recovered & DER representations.
9710
9945
  */
9711
9946
  class Signature {
9712
9947
  constructor(r, s, recovery) {
9713
- aValidRS('r', r); // r in [1..N-1]
9714
- aValidRS('s', s); // s in [1..N-1]
9715
- this.r = r;
9716
- this.s = s;
9948
+ this.r = validateRS('r', r); // r in [1..N-1];
9949
+ this.s = validateRS('s', s); // s in [1..N-1];
9717
9950
  if (recovery != null)
9718
9951
  this.recovery = recovery;
9719
9952
  Object.freeze(this);
9720
9953
  }
9721
- // pair (bytes of r, bytes of s)
9722
- static fromCompact(hex) {
9723
- const L = Fn.BYTES;
9724
- const b = ensureBytes$1('compactSignature', hex, L * 2);
9725
- return new Signature(Fn.fromBytes(b.subarray(0, L)), Fn.fromBytes(b.subarray(L, L * 2)));
9954
+ static fromBytes(bytes, format = defaultSigOpts_format) {
9955
+ validateSigFormat(format);
9956
+ const size = lengths.signature;
9957
+ let recid;
9958
+ if (format === 'der') {
9959
+ const { r, s } = DER$1.toSig(_abytes2(bytes));
9960
+ return new Signature(r, s);
9961
+ }
9962
+ if (format === 'recovered') {
9963
+ _abytes2(bytes, size + 1);
9964
+ recid = bytes[0];
9965
+ format = 'compact';
9966
+ bytes = bytes.subarray(1);
9967
+ }
9968
+ _abytes2(bytes, size);
9969
+ const L = size / 2;
9970
+ const r = bytes.subarray(0, L);
9971
+ const s = bytes.subarray(L, L * 2);
9972
+ return new Signature(Fn.fromBytes(r), Fn.fromBytes(s), recid);
9726
9973
  }
9727
- // DER encoded ECDSA signature
9728
- // https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script
9729
- static fromDER(hex) {
9730
- const { r, s } = DER$1.toSig(ensureBytes$1('DER', hex));
9731
- return new Signature(r, s);
9974
+ static fromHex(hex, format) {
9975
+ return this.fromBytes(hexToBytes$1(hex), format);
9732
9976
  }
9733
- /**
9734
- * @todo remove
9735
- * @deprecated
9736
- */
9737
- assertValidity() { }
9738
9977
  addRecoveryBit(recovery) {
9739
9978
  return new Signature(this.r, this.s, recovery);
9740
9979
  }
9741
- // ProjPointType<bigint>
9742
9980
  recoverPublicKey(msgHash) {
9743
9981
  const FIELD_ORDER = Fp.ORDER;
9744
9982
  const { r, s, recovery: rec } = this;
@@ -9759,7 +9997,7 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
9759
9997
  if (!Fp.isValid(radj))
9760
9998
  throw new Error('recovery id 2 or 3 invalid');
9761
9999
  const x = Fp.toBytes(radj);
9762
- const R = Point.fromHex(concatBytes$2(pprefix((rec & 1) === 0), x));
10000
+ const R = Point.fromBytes(concatBytes$2(pprefix((rec & 1) === 0), x));
9763
10001
  const ir = Fn.inv(radj); // r^-1
9764
10002
  const h = bits2int_modN(ensureBytes$1('msgHash', msgHash)); // Truncate hash
9765
10003
  const u1 = Fn.create(-h * ir); // -hr^-1
@@ -9775,24 +10013,39 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
9775
10013
  hasHighS() {
9776
10014
  return isBiggerThanHalfOrder(this.s);
9777
10015
  }
9778
- normalizeS() {
9779
- return this.hasHighS() ? new Signature(this.r, Fn.neg(this.s), this.recovery) : this;
9780
- }
9781
- toBytes(format) {
9782
- if (format === 'compact')
9783
- return concatBytes$2(Fn.toBytes(this.r), Fn.toBytes(this.s));
10016
+ toBytes(format = defaultSigOpts_format) {
10017
+ validateSigFormat(format);
9784
10018
  if (format === 'der')
9785
10019
  return hexToBytes$1(DER$1.hexFromSig(this));
9786
- throw new Error('invalid format');
10020
+ const r = Fn.toBytes(this.r);
10021
+ const s = Fn.toBytes(this.s);
10022
+ if (format === 'recovered') {
10023
+ if (this.recovery == null)
10024
+ throw new Error('recovery bit must be present');
10025
+ return concatBytes$2(Uint8Array.of(this.recovery), r, s);
10026
+ }
10027
+ return concatBytes$2(r, s);
10028
+ }
10029
+ toHex(format) {
10030
+ return bytesToHex$1(this.toBytes(format));
10031
+ }
10032
+ // TODO: remove
10033
+ assertValidity() { }
10034
+ static fromCompact(hex) {
10035
+ return Signature.fromBytes(ensureBytes$1('sig', hex), 'compact');
10036
+ }
10037
+ static fromDER(hex) {
10038
+ return Signature.fromBytes(ensureBytes$1('sig', hex), 'der');
10039
+ }
10040
+ normalizeS() {
10041
+ return this.hasHighS() ? new Signature(this.r, Fn.neg(this.s), this.recovery) : this;
9787
10042
  }
9788
- // DER-encoded
9789
10043
  toDERRawBytes() {
9790
10044
  return this.toBytes('der');
9791
10045
  }
9792
10046
  toDERHex() {
9793
10047
  return bytesToHex$1(this.toBytes('der'));
9794
10048
  }
9795
- // padded bytes of r, then padded bytes of s
9796
10049
  toCompactRawBytes() {
9797
10050
  return this.toBytes('compact');
9798
10051
  }
@@ -9800,77 +10053,6 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
9800
10053
  return bytesToHex$1(this.toBytes('compact'));
9801
10054
  }
9802
10055
  }
9803
- const normPrivateKeyToScalar = _legacyHelperNormPriv(Fn, curveOpts.allowedPrivateKeyLengths, curveOpts.wrapPrivateKey);
9804
- const utils = {
9805
- isValidPrivateKey(privateKey) {
9806
- try {
9807
- normPrivateKeyToScalar(privateKey);
9808
- return true;
9809
- }
9810
- catch (error) {
9811
- return false;
9812
- }
9813
- },
9814
- normPrivateKeyToScalar: normPrivateKeyToScalar,
9815
- /**
9816
- * Produces cryptographically secure private key from random of size
9817
- * (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.
9818
- */
9819
- randomPrivateKey: () => {
9820
- const n = CURVE_ORDER;
9821
- return mapHashToField$1(randomBytes_(getMinHashLength$1(n)), n);
9822
- },
9823
- precompute(windowSize = 8, point = Point.BASE) {
9824
- return point.precompute(windowSize, false);
9825
- },
9826
- };
9827
- /**
9828
- * Computes public key for a private key. Checks for validity of the private key.
9829
- * @param privateKey private key
9830
- * @param isCompressed whether to return compact (default), or full key
9831
- * @returns Public key, full when isCompressed=false; short when isCompressed=true
9832
- */
9833
- function getPublicKey(privateKey, isCompressed = true) {
9834
- return Point.fromPrivateKey(privateKey).toBytes(isCompressed);
9835
- }
9836
- /**
9837
- * Quick and dirty check for item being public key. Does not validate hex, or being on-curve.
9838
- */
9839
- function isProbPub(item) {
9840
- if (typeof item === 'bigint')
9841
- return false;
9842
- if (item instanceof Point)
9843
- return true;
9844
- const arr = ensureBytes$1('key', item);
9845
- const length = arr.length;
9846
- const L = Fp.BYTES;
9847
- const LC = L + 1; // e.g. 33 for 32
9848
- const LU = 2 * L + 1; // e.g. 65 for 32
9849
- if (curveOpts.allowedPrivateKeyLengths || Fn.BYTES === LC) {
9850
- return undefined;
9851
- }
9852
- else {
9853
- return length === LC || length === LU;
9854
- }
9855
- }
9856
- /**
9857
- * ECDH (Elliptic Curve Diffie Hellman).
9858
- * Computes shared public key from private key and public key.
9859
- * Checks: 1) private key validity 2) shared key is on-curve.
9860
- * Does NOT hash the result.
9861
- * @param privateA private key
9862
- * @param publicB different public key
9863
- * @param isCompressed whether to return compact (default), or full key
9864
- * @returns shared public key
9865
- */
9866
- function getSharedSecret(privateA, publicB, isCompressed = true) {
9867
- if (isProbPub(privateA) === true)
9868
- throw new Error('first arg must be private key');
9869
- if (isProbPub(publicB) === false)
9870
- throw new Error('second arg must be public key');
9871
- const b = Point.fromHex(publicB); // check for being on-curve
9872
- return b.multiply(normPrivateKeyToScalar(privateA)).toBytes(isCompressed);
9873
- }
9874
10056
  // RFC6979: ensure ECDSA msg is X bytes and < N. RFC suggests optional truncating via bits2octets.
9875
10057
  // FIPS 186-4 4.6 suggests the leftmost min(nBitLen, outLen) bits, which matches bits2int.
9876
10058
  // bits2int can produce res>N, we can do mod(res, N) since the bitLen is the same.
@@ -9900,55 +10082,60 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
9900
10082
  aInRange('num < 2^' + fnBits, num, _0n$6, ORDER_MASK);
9901
10083
  return Fn.toBytes(num);
9902
10084
  }
9903
- // Steps A, D of RFC6979 3.2
9904
- // Creates RFC6979 seed; converts msg/privKey to numbers.
9905
- // Used only in sign, not in verify.
9906
- // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
9907
- // this will be invalid at least for P521. Also it can be bigger for P224 + SHA256
9908
- function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
10085
+ /**
10086
+ * Steps A, D of RFC6979 3.2.
10087
+ * Creates RFC6979 seed; converts msg/privKey to numbers.
10088
+ * Used only in sign, not in verify.
10089
+ *
10090
+ * Warning: we cannot assume here that message has same amount of bytes as curve order,
10091
+ * this will be invalid at least for P521. Also it can be bigger for P224 + SHA256.
10092
+ */
10093
+ function prepSig(message, privateKey, opts) {
9909
10094
  if (['recovered', 'canonical'].some((k) => k in opts))
9910
10095
  throw new Error('sign() legacy options not supported');
9911
- const { hash } = ecdsaOpts;
9912
- let { lowS, prehash, extraEntropy: ent } = opts; // generates low-s sigs by default
9913
- if (lowS == null)
9914
- lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
9915
- msgHash = ensureBytes$1('msgHash', msgHash);
9916
- validateSigVerOpts(opts);
10096
+ const { lowS, prehash, extraEntropy } = validateSigOpts(opts, defaultSigOpts);
10097
+ // RFC6979 3.2: we skip step A, because we already provide hash
10098
+ message = _abytes2(message, undefined, 'message');
9917
10099
  if (prehash)
9918
- msgHash = ensureBytes$1('prehashed msgHash', hash(msgHash));
10100
+ message = _abytes2(hash(message), undefined, 'prehashed message');
9919
10101
  // We can't later call bits2octets, since nested bits2int is broken for curves
9920
10102
  // with fnBits % 8 !== 0. Because of that, we unwrap it here as int2octets call.
9921
10103
  // const bits2octets = (bits) => int2octets(bits2int_modN(bits))
9922
- const h1int = bits2int_modN(msgHash);
9923
- const d = normPrivateKeyToScalar(privateKey); // validate private key, convert to bigint
10104
+ const h1int = bits2int_modN(message);
10105
+ const d = _normFnElement(Fn, privateKey); // validate secret key, convert to bigint
9924
10106
  const seedArgs = [int2octets(d), int2octets(h1int)];
9925
10107
  // extraEntropy. RFC6979 3.6: additional k' (optional).
9926
- if (ent != null && ent !== false) {
10108
+ if (extraEntropy != null && extraEntropy !== false) {
9927
10109
  // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
9928
- const e = ent === true ? randomBytes_(Fp.BYTES) : ent; // generate random bytes OR pass as-is
10110
+ // gen random bytes OR pass as-is
10111
+ const e = extraEntropy === true ? randomBytes_(lengths.secret) : extraEntropy;
9929
10112
  seedArgs.push(ensureBytes$1('extraEntropy', e)); // check for being bytes
9930
10113
  }
9931
10114
  const seed = concatBytes$2(...seedArgs); // Step D of RFC6979 3.2
9932
10115
  const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!
9933
10116
  // Converts signature params into point w r/s, checks result for validity.
10117
+ // To transform k => Signature:
10118
+ // q = k⋅G
10119
+ // r = q.x mod n
10120
+ // s = k^-1(m + rd) mod n
9934
10121
  // Can use scalar blinding b^-1(bm + bdr) where b ∈ [1,q−1] according to
9935
10122
  // https://tches.iacr.org/index.php/TCHES/article/view/7337/6509. We've decided against it:
9936
10123
  // a) dependency on CSPRNG b) 15% slowdown c) doesn't really help since bigints are not CT
9937
10124
  function k2sig(kBytes) {
9938
10125
  // RFC 6979 Section 3.2, step 3: k = bits2int(T)
9939
10126
  // Important: all mod() calls here must be done over N
9940
- const k = bits2int(kBytes); // Cannot use fields methods, since it is group element
10127
+ const k = bits2int(kBytes); // mod n, not mod p
9941
10128
  if (!Fn.isValidNot0(k))
9942
10129
  return; // Valid scalars (including k) must be in 1..N-1
9943
10130
  const ik = Fn.inv(k); // k^-1 mod n
9944
- const q = Point.BASE.multiply(k).toAffine(); // q = Gk
10131
+ const q = Point.BASE.multiply(k).toAffine(); // q = k⋅G
9945
10132
  const r = Fn.create(q.x); // r = q.x mod n
9946
10133
  if (r === _0n$6)
9947
10134
  return;
9948
10135
  const s = Fn.create(ik * Fn.create(m + r * d)); // Not using blinding here, see comment above
9949
10136
  if (s === _0n$6)
9950
10137
  return;
9951
- let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n$8); // recovery bit (2 or 3, when q.x > n)
10138
+ let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n$7); // recovery bit (2 or 3, when q.x > n)
9952
10139
  let normS = s;
9953
10140
  if (lowS && isBiggerThanHalfOrder(s)) {
9954
10141
  normS = normalizeS(s); // if lowS was passed, ensure s is always
@@ -9958,131 +10145,136 @@ function ecdsa(Point, ecdsaOpts, curveOpts = {}) {
9958
10145
  }
9959
10146
  return { seed, k2sig };
9960
10147
  }
9961
- const defaultSigOpts = { lowS: ecdsaOpts.lowS, prehash: false };
9962
- const defaultVerOpts = { lowS: ecdsaOpts.lowS, prehash: false };
9963
10148
  /**
9964
- * Signs message hash with a private key.
10149
+ * Signs message hash with a secret key.
10150
+ *
9965
10151
  * ```
9966
- * sign(m, d, k) where
10152
+ * sign(m, d) where
10153
+ * k = rfc6979_hmac_drbg(m, d)
9967
10154
  * (x, y) = G × k
9968
10155
  * r = x mod n
9969
- * s = (m + dr)/k mod n
10156
+ * s = (m + dr) / k mod n
9970
10157
  * ```
9971
- * @param msgHash NOT message. msg needs to be hashed to `msgHash`, or use `prehash`.
9972
- * @param privKey private key
9973
- * @param opts lowS for non-malleable sigs. extraEntropy for mixing randomness into k. prehash will hash first arg.
9974
- * @returns signature with recovery param
9975
10158
  */
9976
- function sign(msgHash, privKey, opts = defaultSigOpts) {
9977
- const { seed, k2sig } = prepSig(msgHash, privKey, opts); // Steps A, D of RFC6979 3.2.
9978
- const drbg = createHmacDrbg$1(ecdsaOpts.hash.outputLen, Fn.BYTES, hmac_);
9979
- return drbg(seed, k2sig); // Steps B, C, D, E, F, G
10159
+ function sign(message, secretKey, opts = {}) {
10160
+ message = ensureBytes$1('message', message);
10161
+ const { seed, k2sig } = prepSig(message, secretKey, opts); // Steps A, D of RFC6979 3.2.
10162
+ const drbg = createHmacDrbg$1(hash.outputLen, Fn.BYTES, hmac_);
10163
+ const sig = drbg(seed, k2sig); // Steps B, C, D, E, F, G
10164
+ return sig;
9980
10165
  }
9981
10166
  // Enable precomputes. Slows down first publicKey computation by 20ms.
9982
10167
  Point.BASE.precompute(8);
9983
10168
  /**
9984
- * Verifies a signature against message hash and public key.
9985
- * Rejects lowS signatures by default: to override,
9986
- * specify option `{lowS: false}`. Implements section 4.1.4 from https://www.secg.org/sec1-v2.pdf:
10169
+ * Verifies a signature against message and public key.
10170
+ * Rejects lowS signatures by default: see {@link ECDSAVerifyOpts}.
10171
+ * Implements section 4.1.4 from https://www.secg.org/sec1-v2.pdf:
9987
10172
  *
9988
10173
  * ```
9989
10174
  * verify(r, s, h, P) where
9990
- * U1 = hs^-1 mod n
9991
- * U2 = rs^-1 mod n
9992
- * R = U1⋅G - U2⋅P
10175
+ * u1 = hs^-1 mod n
10176
+ * u2 = rs^-1 mod n
10177
+ * R = u1⋅G + u2⋅P
9993
10178
  * mod(R.x, n) == r
9994
10179
  * ```
9995
10180
  */
9996
- function verify(signature, msgHash, publicKey, opts = defaultVerOpts) {
10181
+ function verify(signature, message, publicKey, opts = {}) {
9997
10182
  const sg = signature;
9998
- msgHash = ensureBytes$1('msgHash', msgHash);
10183
+ message = ensureBytes$1('msgHash', message);
9999
10184
  publicKey = ensureBytes$1('publicKey', publicKey);
10000
- // Verify opts
10001
- validateSigVerOpts(opts);
10002
- const { lowS, prehash, format } = opts;
10003
- // TODO: remove
10004
- if ('strict' in opts)
10005
- throw new Error('options.strict was renamed to lowS');
10006
- if (format !== undefined && !['compact', 'der', 'js'].includes(format))
10007
- throw new Error('format must be "compact", "der" or "js"');
10008
- const isHex = typeof sg === 'string' || isBytes(sg);
10009
- const isObj = !isHex &&
10010
- !format &&
10011
- typeof sg === 'object' &&
10012
- sg !== null &&
10013
- typeof sg.r === 'bigint' &&
10014
- typeof sg.s === 'bigint';
10015
- if (!isHex && !isObj)
10016
- throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
10185
+ const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts);
10017
10186
  let _sig = undefined;
10018
10187
  let P;
10019
- // deduce signature format
10020
- try {
10021
- // if (format === 'js') {
10022
- // if (sg != null && !isBytes(sg)) _sig = new Signature(sg.r, sg.s);
10023
- // } else if (format === 'compact') {
10024
- // _sig = Signature.fromCompact(sg);
10025
- // } else if (format === 'der') {
10026
- // _sig = Signature.fromDER(sg);
10027
- // } else {
10028
- // throw new Error('invalid format');
10029
- // }
10188
+ if ('strict' in opts)
10189
+ throw new Error('options.strict was renamed to lowS');
10190
+ if (format === undefined) {
10191
+ // Try to deduce format
10192
+ const isHex = typeof sg === 'string' || isBytes(sg);
10193
+ const isObj = !isHex &&
10194
+ sg !== null &&
10195
+ typeof sg === 'object' &&
10196
+ typeof sg.r === 'bigint' &&
10197
+ typeof sg.s === 'bigint';
10198
+ if (!isHex && !isObj)
10199
+ throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
10030
10200
  if (isObj) {
10031
- if (format === undefined || format === 'js') {
10032
- _sig = new Signature(sg.r, sg.s);
10033
- }
10034
- else {
10035
- throw new Error('invalid format');
10036
- }
10201
+ _sig = new Signature(sg.r, sg.s);
10037
10202
  }
10038
- if (isHex) {
10203
+ else if (isHex) {
10039
10204
  // TODO: remove this malleable check
10040
10205
  // Signature can be represented in 2 ways: compact (2*Fn.BYTES) & DER (variable-length).
10041
10206
  // Since DER can also be 2*Fn.BYTES bytes, we check for it first.
10042
10207
  try {
10043
- if (format !== 'compact')
10044
- _sig = Signature.fromDER(sg);
10208
+ _sig = Signature.fromDER(sg);
10045
10209
  }
10046
10210
  catch (derError) {
10047
10211
  if (!(derError instanceof DER$1.Err))
10048
10212
  throw derError;
10049
10213
  }
10050
- if (!_sig && format !== 'der')
10051
- _sig = Signature.fromCompact(sg);
10214
+ if (!_sig) {
10215
+ try {
10216
+ _sig = Signature.fromCompact(sg);
10217
+ }
10218
+ catch (error) {
10219
+ return false;
10220
+ }
10221
+ }
10052
10222
  }
10053
- P = Point.fromHex(publicKey);
10054
10223
  }
10055
- catch (error) {
10056
- return false;
10224
+ else {
10225
+ if (format === 'compact' || format === 'der') {
10226
+ if (typeof sg !== 'string' && !isBytes(sg))
10227
+ throw new Error('"der" / "compact" format expects Uint8Array signature');
10228
+ _sig = Signature.fromBytes(ensureBytes$1('sig', sg), format);
10229
+ }
10230
+ else {
10231
+ throw new Error('format must be "compact", "der" or "js"');
10232
+ }
10057
10233
  }
10058
10234
  if (!_sig)
10059
10235
  return false;
10060
- if (lowS && _sig.hasHighS())
10236
+ try {
10237
+ P = Point.fromHex(publicKey);
10238
+ if (lowS && _sig.hasHighS())
10239
+ return false;
10240
+ // todo: optional.hash => hash
10241
+ if (prehash)
10242
+ message = hash(message);
10243
+ const { r, s } = _sig;
10244
+ const h = bits2int_modN(message); // mod n, not mod p
10245
+ const is = Fn.inv(s); // s^-1 mod n
10246
+ const u1 = Fn.create(h * is); // u1 = hs^-1 mod n
10247
+ const u2 = Fn.create(r * is); // u2 = rs^-1 mod n
10248
+ const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2)); // u1⋅G + u2⋅P
10249
+ if (R.is0())
10250
+ return false;
10251
+ const v = Fn.create(R.x); // v = r.x mod n
10252
+ return v === r;
10253
+ }
10254
+ catch (e) {
10061
10255
  return false;
10062
- // todo: optional.hash => hash
10256
+ }
10257
+ }
10258
+ function recoverPublicKey(signature, message, opts = {}) {
10259
+ const prehash = opts.prehash !== undefined ? opts.prehash : defaultSigOpts.prehash;
10260
+ _abool2(prehash, 'prehash');
10261
+ message = _abytes2(message, undefined, 'message');
10063
10262
  if (prehash)
10064
- msgHash = ecdsaOpts.hash(msgHash);
10065
- const { r, s } = _sig;
10066
- const h = bits2int_modN(msgHash); // Cannot use fields methods, since it is group element
10067
- const is = Fn.inv(s); // s^-1
10068
- const u1 = Fn.create(h * is); // u1 = hs^-1 mod n
10069
- const u2 = Fn.create(r * is); // u2 = rs^-1 mod n
10070
- const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2));
10071
- if (R.is0())
10072
- return false;
10073
- const v = Fn.create(R.x); // v = r.x mod n
10074
- return v === r;
10263
+ message = _abytes2(hash(message), undefined, 'prehashed message');
10264
+ return Signature.fromBytes(signature, 'recovered').recoverPublicKey(message).toBytes();
10075
10265
  }
10076
- // TODO: clarify API for cloning .clone({hash: sha512}) ? .createWith({hash: sha512})?
10077
- // const clone = (hash: CHash): ECDSA => ecdsa(Point, { ...ecdsaOpts, ...getHash(hash) }, curveOpts);
10078
10266
  return Object.freeze({
10267
+ keygen,
10079
10268
  getPublicKey,
10080
10269
  getSharedSecret,
10081
- sign,
10082
- verify,
10083
10270
  utils,
10271
+ lengths,
10084
10272
  Point,
10273
+ sign,
10274
+ verify,
10275
+ recoverPublicKey,
10085
10276
  Signature,
10277
+ hash,
10086
10278
  });
10087
10279
  }
10088
10280
  function _weierstrass_legacy_opts_to_new(c) {
@@ -10096,14 +10288,19 @@ function _weierstrass_legacy_opts_to_new(c) {
10096
10288
  Gy: c.Gy,
10097
10289
  };
10098
10290
  const Fp = c.Fp;
10099
- const Fn = Field$1(CURVE.n, c.nBitLength);
10291
+ let allowedLengths = c.allowedPrivateKeyLengths
10292
+ ? Array.from(new Set(c.allowedPrivateKeyLengths.map((l) => Math.ceil(l / 2))))
10293
+ : undefined;
10294
+ const Fn = Field$1(CURVE.n, {
10295
+ BITS: c.nBitLength,
10296
+ allowedLengths: allowedLengths,
10297
+ modFromBytes: c.wrapPrivateKey,
10298
+ });
10100
10299
  const curveOpts = {
10101
10300
  Fp,
10102
10301
  Fn,
10103
- allowedPrivateKeyLengths: c.allowedPrivateKeyLengths,
10104
10302
  allowInfinityPoint: c.allowInfinityPoint,
10105
10303
  endo: c.endo,
10106
- wrapPrivateKey: c.wrapPrivateKey,
10107
10304
  isTorsionFree: c.isTorsionFree,
10108
10305
  clearCofactor: c.clearCofactor,
10109
10306
  fromBytes: c.fromBytes,
@@ -10114,32 +10311,33 @@ function _weierstrass_legacy_opts_to_new(c) {
10114
10311
  function _ecdsa_legacy_opts_to_new(c) {
10115
10312
  const { CURVE, curveOpts } = _weierstrass_legacy_opts_to_new(c);
10116
10313
  const ecdsaOpts = {
10117
- hash: c.hash,
10118
10314
  hmac: c.hmac,
10119
10315
  randomBytes: c.randomBytes,
10120
10316
  lowS: c.lowS,
10121
10317
  bits2int: c.bits2int,
10122
10318
  bits2int_modN: c.bits2int_modN,
10123
10319
  };
10124
- return { CURVE, curveOpts, ecdsaOpts };
10320
+ return { CURVE, curveOpts, hash: c.hash, ecdsaOpts };
10125
10321
  }
10126
- function _ecdsa_new_output_to_legacy(c, ecdsa) {
10127
- return Object.assign({}, ecdsa, {
10128
- ProjectivePoint: ecdsa.Point,
10129
- CURVE: c,
10322
+ function _ecdsa_new_output_to_legacy(c, _ecdsa) {
10323
+ const Point = _ecdsa.Point;
10324
+ return Object.assign({}, _ecdsa, {
10325
+ ProjectivePoint: Point,
10326
+ CURVE: Object.assign({}, c, nLength$1(Point.Fn.ORDER, Point.Fn.BITS)),
10130
10327
  });
10131
10328
  }
10132
10329
  // _ecdsa_legacy
10133
10330
  function weierstrass$1(c) {
10134
- const { CURVE, curveOpts, ecdsaOpts } = _ecdsa_legacy_opts_to_new(c);
10331
+ const { CURVE, curveOpts, hash, ecdsaOpts } = _ecdsa_legacy_opts_to_new(c);
10135
10332
  const Point = weierstrassN(CURVE, curveOpts);
10136
- const signs = ecdsa(Point, ecdsaOpts, curveOpts);
10333
+ const signs = ecdsa(Point, hash, ecdsaOpts);
10137
10334
  return _ecdsa_new_output_to_legacy(c, signs);
10138
10335
  }/**
10139
10336
  * Utilities for short weierstrass curves, combined with noble-hashes.
10140
10337
  * @module
10141
10338
  */
10142
10339
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
10340
+ /** @deprecated use new `weierstrass()` and `ecdsa()` methods */
10143
10341
  function createCurve$1(curveDef, defHash) {
10144
10342
  const create = (hash) => weierstrass$1({ ...curveDef, hash: hash });
10145
10343
  return { ...create(defHash), create };
@@ -10163,10 +10361,14 @@ const secp256k1_CURVE = {
10163
10361
  Gx: BigInt('0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
10164
10362
  Gy: BigInt('0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'),
10165
10363
  };
10166
- BigInt(0);
10167
- const _1n$7 = BigInt(1);
10168
- const _2n$5 = BigInt(2);
10169
- const divNearest$1 = (a, b) => (a + b / _2n$5) / b;
10364
+ const secp256k1_ENDO = {
10365
+ beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
10366
+ basises: [
10367
+ [BigInt('0x3086d221a7d46bcde86c90e49284eb15'), -BigInt('0xe4437ed6010e88286f547fa90abfe4c3')],
10368
+ [BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8'), BigInt('0x3086d221a7d46bcde86c90e49284eb15')],
10369
+ ],
10370
+ };
10371
+ const _2n$5 = /* @__PURE__ */ BigInt(2);
10170
10372
  /**
10171
10373
  * √n = n^((p+1)/4) for fields p = 3 mod 4. We unwrap the loop and multiply bit-by-bit.
10172
10374
  * (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]
@@ -10195,7 +10397,7 @@ function sqrtMod$1(y) {
10195
10397
  throw new Error('Cannot find square root');
10196
10398
  return root;
10197
10399
  }
10198
- const Fpk1 = Field$1(secp256k1_CURVE.p, undefined, undefined, { sqrt: sqrtMod$1 });
10400
+ const Fpk1 = Field$1(secp256k1_CURVE.p, { sqrt: sqrtMod$1 });
10199
10401
  /**
10200
10402
  * secp256k1 curve, ECDSA and ECDH methods.
10201
10403
  *
@@ -10204,44 +10406,13 @@ const Fpk1 = Field$1(secp256k1_CURVE.p, undefined, undefined, { sqrt: sqrtMod$1
10204
10406
  * @example
10205
10407
  * ```js
10206
10408
  * import { secp256k1 } from '@noble/curves/secp256k1';
10207
- * const priv = secp256k1.utils.randomPrivateKey();
10208
- * const pub = secp256k1.getPublicKey(priv);
10209
- * const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
10210
- * const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
10211
- * const isValid = secp256k1.verify(sig, msg, pub) === true;
10409
+ * const { secretKey, publicKey } = secp256k1.keygen();
10410
+ * const msg = new TextEncoder().encode('hello');
10411
+ * const sig = secp256k1.sign(msg, secretKey);
10412
+ * const isValid = secp256k1.verify(sig, msg, publicKey) === true;
10212
10413
  * ```
10213
10414
  */
10214
- const secp256k1$1 = createCurve$1({
10215
- ...secp256k1_CURVE,
10216
- Fp: Fpk1,
10217
- lowS: true, // Allow only low-S signatures by default in sign() and verify()
10218
- endo: {
10219
- // Endomorphism, see above
10220
- beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
10221
- splitScalar: (k) => {
10222
- const n = secp256k1_CURVE.n;
10223
- const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15');
10224
- const b1 = -_1n$7 * BigInt('0xe4437ed6010e88286f547fa90abfe4c3');
10225
- const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8');
10226
- const b2 = a1;
10227
- const POW_2_128 = BigInt('0x100000000000000000000000000000000'); // (2n**128n).toString(16)
10228
- const c1 = divNearest$1(b2 * k, n);
10229
- const c2 = divNearest$1(-b1 * k, n);
10230
- let k1 = mod$1(k - c1 * a1 - c2 * a2, n);
10231
- let k2 = mod$1(-c1 * b1 - c2 * b2, n);
10232
- const k1neg = k1 > POW_2_128;
10233
- const k2neg = k2 > POW_2_128;
10234
- if (k1neg)
10235
- k1 = n - k1;
10236
- if (k2neg)
10237
- k2 = n - k2;
10238
- if (k1 > POW_2_128 || k2 > POW_2_128) {
10239
- throw new Error('splitScalar: Endomorphism failed, k=' + k);
10240
- }
10241
- return { k1neg, k1, k2neg, k2 };
10242
- },
10243
- },
10244
- }, sha256$2);function encodeAddress(key, ss58Format = defaults.prefix) {
10415
+ const secp256k1$1 = createCurve$1({ ...secp256k1_CURVE, Fp: Fpk1, lowS: true, endo: secp256k1_ENDO }, sha256$2);function encodeAddress(key, ss58Format = defaults.prefix) {
10245
10416
  // decode it, this means we can re-encode an address
10246
10417
  const u8a = decodeAddress(key);
10247
10418
  if ((ss58Format < 0) || (ss58Format > 16383) || [46, 47].includes(ss58Format)) {
@@ -19823,13 +19994,27 @@ function createPasskeyPublicKey(publicKey) {
19823
19994
  publicKey: parsedNewPublicKey,
19824
19995
  };
19825
19996
  }
19997
+ /**
19998
+ * Build AddAction payload for Itemized storage.
19999
+ *
20000
+ * @param data The data to be persisted on the Frequency chain
20001
+ */
19826
20002
  function createItemizedAddAction(data) {
19827
20003
  const parsedData = typeof data === 'object' ? u8aToHex(data) : data;
19828
20004
  assert(isHexString(parsedData), 'itemized data should be valid hex');
20005
+ // since Metamask does not support union types, we have to include all fields and have to set the `index` value to zero
20006
+ // even though it is not used for Add action
19829
20007
  return { actionType: 'Add', data, index: 0 };
19830
20008
  }
20009
+ /**
20010
+ * Build DeleteAction payload for Itemized storage.
20011
+ *
20012
+ * @param index The index of the item that we want to remove from the Frequency chain
20013
+ */
19831
20014
  function createItemizedDeleteAction(index) {
19832
20015
  assert(isValidUint16(index), 'itemized index should be a valid uint16');
20016
+ // since Metamask does not support union types, we have to include all fields and have to set the `data` value to 0x
20017
+ // even though it is not used for Delete action
19833
20018
  return { actionType: 'Delete', data: '0x', index };
19834
20019
  }
19835
20020
  /**