@noble/curves 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +54 -22
  2. package/_shortw_utils.d.ts.map +1 -1
  3. package/abstract/bls.d.ts +7 -5
  4. package/abstract/bls.d.ts.map +1 -1
  5. package/abstract/bls.js +9 -9
  6. package/abstract/bls.js.map +1 -1
  7. package/abstract/curve.d.ts +29 -6
  8. package/abstract/curve.d.ts.map +1 -1
  9. package/abstract/curve.js +184 -41
  10. package/abstract/curve.js.map +1 -1
  11. package/abstract/edwards.d.ts +2 -0
  12. package/abstract/edwards.d.ts.map +1 -1
  13. package/abstract/edwards.js +20 -9
  14. package/abstract/edwards.js.map +1 -1
  15. package/abstract/hash-to-curve.d.ts.map +1 -1
  16. package/abstract/hash-to-curve.js +3 -4
  17. package/abstract/hash-to-curve.js.map +1 -1
  18. package/abstract/modular.d.ts.map +1 -1
  19. package/abstract/modular.js +32 -21
  20. package/abstract/modular.js.map +1 -1
  21. package/abstract/montgomery.d.ts.map +1 -1
  22. package/abstract/montgomery.js +5 -3
  23. package/abstract/montgomery.js.map +1 -1
  24. package/abstract/poseidon.d.ts.map +1 -1
  25. package/abstract/poseidon.js +22 -22
  26. package/abstract/poseidon.js.map +1 -1
  27. package/abstract/tower.d.ts +1 -0
  28. package/abstract/tower.d.ts.map +1 -1
  29. package/abstract/tower.js +6 -6
  30. package/abstract/tower.js.map +1 -1
  31. package/abstract/utils.d.ts.map +1 -1
  32. package/abstract/utils.js +21 -23
  33. package/abstract/utils.js.map +1 -1
  34. package/abstract/weierstrass.d.ts +1 -0
  35. package/abstract/weierstrass.d.ts.map +1 -1
  36. package/abstract/weierstrass.js +54 -36
  37. package/abstract/weierstrass.js.map +1 -1
  38. package/bls12-381.js +8 -8
  39. package/bn254.d.ts +2 -1
  40. package/bn254.d.ts.map +1 -1
  41. package/bn254.js +9 -7
  42. package/bn254.js.map +1 -1
  43. package/ed448.js +1 -1
  44. package/ed448.js.map +1 -1
  45. package/esm/_shortw_utils.d.ts.map +1 -1
  46. package/esm/abstract/bls.d.ts +7 -5
  47. package/esm/abstract/bls.d.ts.map +1 -1
  48. package/esm/abstract/bls.js +9 -9
  49. package/esm/abstract/bls.js.map +1 -1
  50. package/esm/abstract/curve.d.ts +29 -6
  51. package/esm/abstract/curve.d.ts.map +1 -1
  52. package/esm/abstract/curve.js +183 -41
  53. package/esm/abstract/curve.js.map +1 -1
  54. package/esm/abstract/edwards.d.ts +2 -0
  55. package/esm/abstract/edwards.d.ts.map +1 -1
  56. package/esm/abstract/edwards.js +20 -9
  57. package/esm/abstract/edwards.js.map +1 -1
  58. package/esm/abstract/hash-to-curve.d.ts.map +1 -1
  59. package/esm/abstract/hash-to-curve.js +3 -4
  60. package/esm/abstract/hash-to-curve.js.map +1 -1
  61. package/esm/abstract/modular.d.ts.map +1 -1
  62. package/esm/abstract/modular.js +32 -21
  63. package/esm/abstract/modular.js.map +1 -1
  64. package/esm/abstract/montgomery.d.ts.map +1 -1
  65. package/esm/abstract/montgomery.js +5 -3
  66. package/esm/abstract/montgomery.js.map +1 -1
  67. package/esm/abstract/poseidon.d.ts.map +1 -1
  68. package/esm/abstract/poseidon.js +22 -22
  69. package/esm/abstract/poseidon.js.map +1 -1
  70. package/esm/abstract/tower.d.ts +1 -0
  71. package/esm/abstract/tower.d.ts.map +1 -1
  72. package/esm/abstract/tower.js +6 -6
  73. package/esm/abstract/tower.js.map +1 -1
  74. package/esm/abstract/utils.d.ts.map +1 -1
  75. package/esm/abstract/utils.js +21 -23
  76. package/esm/abstract/utils.js.map +1 -1
  77. package/esm/abstract/weierstrass.d.ts +1 -0
  78. package/esm/abstract/weierstrass.d.ts.map +1 -1
  79. package/esm/abstract/weierstrass.js +54 -36
  80. package/esm/abstract/weierstrass.js.map +1 -1
  81. package/esm/bls12-381.js +8 -8
  82. package/esm/bn254.d.ts +2 -1
  83. package/esm/bn254.d.ts.map +1 -1
  84. package/esm/bn254.js +7 -6
  85. package/esm/bn254.js.map +1 -1
  86. package/esm/ed448.js +1 -1
  87. package/esm/ed448.js.map +1 -1
  88. package/esm/p256.d.ts.map +1 -1
  89. package/esm/p256.js +6 -6
  90. package/esm/p256.js.map +1 -1
  91. package/esm/p384.d.ts.map +1 -1
  92. package/esm/p384.js +6 -6
  93. package/esm/p384.js.map +1 -1
  94. package/esm/p521.d.ts.map +1 -1
  95. package/esm/p521.js +7 -7
  96. package/esm/p521.js.map +1 -1
  97. package/esm/secp256k1.d.ts.map +1 -1
  98. package/esm/secp256k1.js +8 -8
  99. package/esm/secp256k1.js.map +1 -1
  100. package/p256.d.ts.map +1 -1
  101. package/p256.js +6 -6
  102. package/p256.js.map +1 -1
  103. package/p384.d.ts.map +1 -1
  104. package/p384.js +6 -6
  105. package/p384.js.map +1 -1
  106. package/p521.d.ts.map +1 -1
  107. package/p521.js +7 -7
  108. package/p521.js.map +1 -1
  109. package/package.json +4 -3
  110. package/secp256k1.d.ts.map +1 -1
  111. package/secp256k1.js +8 -8
  112. package/secp256k1.js.map +1 -1
  113. package/src/abstract/bls.ts +25 -13
  114. package/src/abstract/curve.ts +188 -39
  115. package/src/abstract/edwards.ts +25 -10
  116. package/src/abstract/hash-to-curve.ts +2 -5
  117. package/src/abstract/modular.ts +29 -19
  118. package/src/abstract/montgomery.ts +5 -3
  119. package/src/abstract/poseidon.ts +20 -24
  120. package/src/abstract/tower.ts +7 -6
  121. package/src/abstract/utils.ts +18 -24
  122. package/src/abstract/weierstrass.ts +57 -35
  123. package/src/bls12-381.ts +9 -9
  124. package/src/bn254.ts +16 -7
  125. package/src/ed448.ts +1 -1
  126. package/src/p256.ts +6 -6
  127. package/src/p384.ts +6 -6
  128. package/src/p521.ts +7 -7
  129. package/src/secp256k1.ts +8 -8
@@ -37,7 +37,7 @@ export type BasicWCurve<T> = BasicCurve<T> & {
37
37
 
38
38
  type Entropy = Hex | boolean;
39
39
  export type SignOpts = { lowS?: boolean; extraEntropy?: Entropy; prehash?: boolean };
40
- export type VerOpts = { lowS?: boolean; prehash?: boolean };
40
+ export type VerOpts = { lowS?: boolean; prehash?: boolean; format?: 'compact' | 'der' | undefined };
41
41
 
42
42
  function validateSigVerOpts(opts: SignOpts | VerOpts) {
43
43
  if (opts.lowS !== undefined) abool('lowS', opts.lowS);
@@ -123,14 +123,14 @@ function validatePointOpts<T>(curve: CurvePointsType<T>) {
123
123
  const { endo, Fp, a } = opts;
124
124
  if (endo) {
125
125
  if (!Fp.eql(a, Fp.ZERO)) {
126
- throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');
126
+ throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
127
127
  }
128
128
  if (
129
129
  typeof endo !== 'object' ||
130
130
  typeof endo.beta !== 'bigint' ||
131
131
  typeof endo.splitScalar !== 'function'
132
132
  ) {
133
- throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');
133
+ throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
134
134
  }
135
135
  }
136
136
  return Object.freeze({ ...opts } as const);
@@ -171,7 +171,8 @@ export const DER = {
171
171
  if ((len.length / 2) & 0b1000_0000) throw new E('tlv.encode: long form length too big');
172
172
  // length of length with long form flag
173
173
  const lenLen = dataLen > 127 ? ut.numberToHexUnpadded((len.length / 2) | 0b1000_0000) : '';
174
- return `${ut.numberToHexUnpadded(tag)}${lenLen}${len}${data}`;
174
+ const t = ut.numberToHexUnpadded(tag);
175
+ return t + lenLen + len + data;
175
176
  },
176
177
  // v - value, l - left bytes (unparsed)
177
178
  decode(tag: number, data: Uint8Array): { v: Uint8Array; l: Uint8Array } {
@@ -211,14 +212,14 @@ export const DER = {
211
212
  let hex = ut.numberToHexUnpadded(num);
212
213
  // Pad with zero byte if negative flag is present
213
214
  if (Number.parseInt(hex[0], 16) & 0b1000) hex = '00' + hex;
214
- if (hex.length & 1) throw new E('unexpected assertion');
215
+ if (hex.length & 1) throw new E('unexpected DER parsing assertion: unpadded hex');
215
216
  return hex;
216
217
  },
217
218
  decode(data: Uint8Array): bigint {
218
219
  const { Err: E } = DER;
219
- if (data[0] & 0b1000_0000) throw new E('Invalid signature integer: negative');
220
+ if (data[0] & 0b1000_0000) throw new E('invalid signature integer: negative');
220
221
  if (data[0] === 0x00 && !(data[1] & 0b1000_0000))
221
- throw new E('Invalid signature integer: unnecessary leading zero');
222
+ throw new E('invalid signature integer: unnecessary leading zero');
222
223
  return b2n(data);
223
224
  },
224
225
  },
@@ -228,15 +229,17 @@ export const DER = {
228
229
  const data = typeof hex === 'string' ? h2b(hex) : hex;
229
230
  ut.abytes(data);
230
231
  const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
231
- if (seqLeftBytes.length) throw new E('Invalid signature: left bytes after parsing');
232
+ if (seqLeftBytes.length) throw new E('invalid signature: left bytes after parsing');
232
233
  const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
233
234
  const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
234
- if (sLeftBytes.length) throw new E('Invalid signature: left bytes after parsing');
235
+ if (sLeftBytes.length) throw new E('invalid signature: left bytes after parsing');
235
236
  return { r: int.decode(rBytes), s: int.decode(sBytes) };
236
237
  },
237
238
  hexFromSig(sig: { r: bigint; s: bigint }): string {
238
239
  const { _tlv: tlv, _int: int } = DER;
239
- const seq = `${tlv.encode(0x02, int.encode(sig.r))}${tlv.encode(0x02, int.encode(sig.s))}`;
240
+ const rs = tlv.encode(0x02, int.encode(sig.r));
241
+ const ss = tlv.encode(0x02, int.encode(sig.s));
242
+ const seq = rs + ss;
240
243
  return tlv.encode(0x30, seq);
241
244
  },
242
245
  };
@@ -295,7 +298,8 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
295
298
  if (lengths && typeof key !== 'bigint') {
296
299
  if (ut.isBytes(key)) key = ut.bytesToHex(key);
297
300
  // Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
298
- if (typeof key !== 'string' || !lengths.includes(key.length)) throw new Error('Invalid key');
301
+ if (typeof key !== 'string' || !lengths.includes(key.length))
302
+ throw new Error('invalid private key');
299
303
  key = key.padStart(nByteLength * 2, '0');
300
304
  }
301
305
  let num: bigint;
@@ -305,7 +309,9 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
305
309
  ? key
306
310
  : ut.bytesToNumberBE(ensureBytes('private key', key, nByteLength));
307
311
  } catch (error) {
308
- throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
312
+ throw new Error(
313
+ 'invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key
314
+ );
309
315
  }
310
316
  if (wrapPrivateKey) num = mod.mod(num, N); // disabled by default, enabled for BLS
311
317
  ut.aInRange('private key', num, _1n, N); // num in range [1..N-1]
@@ -342,7 +348,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
342
348
  if (p.is0()) {
343
349
  // (0, 1, 0) aka ZERO is invalid in most contexts.
344
350
  // In BLS, ZERO can be serialized, so we allow it.
345
- // (0, 0, 0) is wrong representation of ZERO and is always invalid.
351
+ // (0, 0, 0) is invalid representation of ZERO.
346
352
  if (CURVE.allowInfinityPoint && !Fp.is0(p.py)) return;
347
353
  throw new Error('bad point: ZERO');
348
354
  }
@@ -423,7 +429,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
423
429
  }
424
430
 
425
431
  // Multiscalar Multiplication
426
- static msm(points: Point[], scalars: bigint[]) {
432
+ static msm(points: Point[], scalars: bigint[]): Point {
427
433
  return pippenger(Point, Fn, points, scalars);
428
434
  }
429
435
 
@@ -576,14 +582,17 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
576
582
  * an exposed private key e.g. sig verification, which works over *public* keys.
577
583
  */
578
584
  multiplyUnsafe(sc: bigint): Point {
579
- ut.aInRange('scalar', sc, _0n, CURVE.n);
585
+ const { endo, n: N } = CURVE;
586
+ ut.aInRange('scalar', sc, _0n, N);
580
587
  const I = Point.ZERO;
581
588
  if (sc === _0n) return I;
582
- if (sc === _1n) return this;
583
- const { endo } = CURVE;
584
- if (!endo) return wnaf.unsafeLadder(this, sc);
589
+ if (this.is0() || sc === _1n) return this;
590
+
591
+ // Case a: no endomorphism. Case b: has precomputes.
592
+ if (!endo || wnaf.hasPrecomputes(this))
593
+ return wnaf.wNAFCachedUnsafe(this, sc, Point.normalizeZ);
585
594
 
586
- // Apply endomorphism
595
+ // Case c: endomorphism
587
596
  let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
588
597
  let k1p = I;
589
598
  let k2p = I;
@@ -826,8 +835,10 @@ export function weierstrass(curveDef: CurveType): CurveFn {
826
835
  const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));
827
836
  return { x, y };
828
837
  } else {
838
+ const cl = compressedLen;
839
+ const ul = uncompressedLen;
829
840
  throw new Error(
830
- `Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`
841
+ 'invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len
831
842
  );
832
843
  }
833
844
  },
@@ -1007,6 +1018,8 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1007
1018
  const bits2int =
1008
1019
  CURVE.bits2int ||
1009
1020
  function (bytes: Uint8Array): bigint {
1021
+ // Our custom check "just in case"
1022
+ if (bytes.length > 8192) throw new Error('input is too large');
1010
1023
  // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
1011
1024
  // for some cases, since bytes.length * 8 is not actual bitLength.
1012
1025
  const num = ut.bytesToNumberBE(bytes); // check for == u8 done here
@@ -1024,7 +1037,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1024
1037
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
1025
1038
  */
1026
1039
  function int2octets(num: bigint): Uint8Array {
1027
- ut.aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
1040
+ ut.aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
1028
1041
  // works with order, can have different size than numToField!
1029
1042
  return ut.numberToBytesBE(num, CURVE.nByteLength);
1030
1043
  }
@@ -1032,8 +1045,8 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1032
1045
  // Steps A, D of RFC6979 3.2
1033
1046
  // Creates RFC6979 seed; converts msg/privKey to numbers.
1034
1047
  // Used only in sign, not in verify.
1035
- // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order, this will be wrong at least for P521.
1036
- // Also it can be bigger for P224 + SHA256
1048
+ // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
1049
+ // this will be invalid at least for P521. Also it can be bigger for P224 + SHA256
1037
1050
  function prepSig(msgHash: Hex, privateKey: PrivKey, opts = defaultSigOpts) {
1038
1051
  if (['recovered', 'canonical'].some((k) => k in opts))
1039
1052
  throw new Error('sign() legacy options not supported');
@@ -1131,34 +1144,43 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1131
1144
  const sg = signature;
1132
1145
  msgHash = ensureBytes('msgHash', msgHash);
1133
1146
  publicKey = ensureBytes('publicKey', publicKey);
1134
- if ('strict' in opts) throw new Error('options.strict was renamed to lowS');
1147
+ const { lowS, prehash, format } = opts;
1148
+
1149
+ // Verify opts, deduce signature format
1135
1150
  validateSigVerOpts(opts);
1136
- const { lowS, prehash } = opts;
1151
+ if ('strict' in opts) throw new Error('options.strict was renamed to lowS');
1152
+ if (format !== undefined && format !== 'compact' && format !== 'der')
1153
+ throw new Error('format must be compact or der');
1154
+ const isHex = typeof sg === 'string' || ut.isBytes(sg);
1155
+ const isObj =
1156
+ !isHex &&
1157
+ !format &&
1158
+ typeof sg === 'object' &&
1159
+ sg !== null &&
1160
+ typeof sg.r === 'bigint' &&
1161
+ typeof sg.s === 'bigint';
1162
+ if (!isHex && !isObj)
1163
+ throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
1137
1164
 
1138
1165
  let _sig: Signature | undefined = undefined;
1139
1166
  let P: ProjPointType<bigint>;
1140
1167
  try {
1141
- if (typeof sg === 'string' || ut.isBytes(sg)) {
1168
+ if (isObj) _sig = new Signature(sg.r, sg.s);
1169
+ if (isHex) {
1142
1170
  // Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
1143
1171
  // Since DER can also be 2*nByteLength bytes, we check for it first.
1144
1172
  try {
1145
- _sig = Signature.fromDER(sg);
1173
+ if (format !== 'compact') _sig = Signature.fromDER(sg);
1146
1174
  } catch (derError) {
1147
1175
  if (!(derError instanceof DER.Err)) throw derError;
1148
- _sig = Signature.fromCompact(sg);
1149
1176
  }
1150
- } else if (typeof sg === 'object' && typeof sg.r === 'bigint' && typeof sg.s === 'bigint') {
1151
- const { r, s } = sg;
1152
- _sig = new Signature(r, s);
1153
- } else {
1154
- throw new Error('PARSE');
1177
+ if (!_sig && format !== 'der') _sig = Signature.fromCompact(sg);
1155
1178
  }
1156
1179
  P = Point.fromHex(publicKey);
1157
1180
  } catch (error) {
1158
- if ((error as Error).message === 'PARSE')
1159
- throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
1160
1181
  return false;
1161
1182
  }
1183
+ if (!_sig) return false;
1162
1184
  if (lowS && _sig.hasHighS()) return false;
1163
1185
  if (prehash) msgHash = CURVE.hash(msgHash);
1164
1186
  const { r, s } = _sig;
package/src/bls12-381.ts CHANGED
@@ -56,7 +56,7 @@ bls12-381 is pairing-friendly Barreto-Lynn-Scott elliptic curve construction all
56
56
  // prettier-ignore
57
57
  const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
58
58
 
59
- /*
59
+ /*
60
60
  Embedding degree (k): 12
61
61
  Seed (X): -15132376222941642752
62
62
  Fr: (x⁴-x²+1)
@@ -509,7 +509,7 @@ export const bls12_381: CurveFn = bls({
509
509
  }
510
510
  const right = Fp.add(Fp.pow(x, _3n), Fp.create(bls12_381.params.G1b)); // y² = x³ + b
511
511
  let y = Fp.sqrt(right);
512
- if (!y) throw new Error('Invalid compressed G1 point');
512
+ if (!y) throw new Error('invalid compressed G1 point');
513
513
  if ((y * _2n) / P !== BigInt(sort)) y = Fp.neg(y);
514
514
  return { x: Fp.create(x), y: Fp.create(y) };
515
515
  } else if (value.length === 96 && !compressed) {
@@ -522,7 +522,7 @@ export const bls12_381: CurveFn = bls({
522
522
  }
523
523
  return { x: Fp.create(x), y: Fp.create(y) };
524
524
  } else {
525
- throw new Error('Invalid point G1, expected 48/96 bytes');
525
+ throw new Error('invalid point G1, expected 48/96 bytes');
526
526
  }
527
527
  },
528
528
  toBytes: (c, point, isCompressed) => {
@@ -553,7 +553,7 @@ export const bls12_381: CurveFn = bls({
553
553
  const x = Fp.create(compressedValue & Fp.MASK);
554
554
  const right = Fp.add(Fp.pow(x, _3n), Fp.create(bls12_381.params.G1b)); // y² = x³ + b
555
555
  let y = Fp.sqrt(right);
556
- if (!y) throw new Error('Invalid compressed G1 point');
556
+ if (!y) throw new Error('invalid compressed G1 point');
557
557
  const aflag = BigInt(sort);
558
558
  if ((y * _2n) / P !== aflag) y = Fp.neg(y);
559
559
  const point = bls12_381.G1.ProjectivePoint.fromAffine({ x, y });
@@ -644,7 +644,7 @@ export const bls12_381: CurveFn = bls({
644
644
  (!compressed && infinity && sort) || // 01100000
645
645
  (sort && infinity && compressed) // 11100000
646
646
  ) {
647
- throw new Error('Invalid encoding flag: ' + (bytes[0] & 0b1110_0000));
647
+ throw new Error('invalid encoding flag: ' + (bytes[0] & 0b1110_0000));
648
648
  }
649
649
  const L = Fp.BYTES;
650
650
  const slc = (b: Uint8Array, from: number, to?: number) => bytesToNumberBE(b.slice(from, to));
@@ -654,7 +654,7 @@ export const bls12_381: CurveFn = bls({
654
654
  if (infinity) {
655
655
  // check that all bytes are 0
656
656
  if (value.reduce((p, c) => (p !== 0 ? c + 1 : c), 0) > 0) {
657
- throw new Error('Invalid compressed G2 point');
657
+ throw new Error('invalid compressed G2 point');
658
658
  }
659
659
  return { x: Fp2.ZERO, y: Fp2.ZERO };
660
660
  }
@@ -669,7 +669,7 @@ export const bls12_381: CurveFn = bls({
669
669
  } else if (value.length === 192 && !compressed) {
670
670
  if (infinity) {
671
671
  if (value.reduce((p, c) => (p !== 0 ? c + 1 : c), 0) > 0) {
672
- throw new Error('Invalid uncompressed G2 point');
672
+ throw new Error('invalid uncompressed G2 point');
673
673
  }
674
674
  return { x: Fp2.ZERO, y: Fp2.ZERO };
675
675
  }
@@ -679,7 +679,7 @@ export const bls12_381: CurveFn = bls({
679
679
  const y0 = slc(value, 3 * L, 4 * L);
680
680
  return { x: Fp2.fromBigTuple([x0, x1]), y: Fp2.fromBigTuple([y0, y1]) };
681
681
  } else {
682
- throw new Error('Invalid point G2, expected 96/192 bytes');
682
+ throw new Error('invalid point G2, expected 96/192 bytes');
683
683
  }
684
684
  },
685
685
  toBytes: (c, point, isCompressed) => {
@@ -712,7 +712,7 @@ export const bls12_381: CurveFn = bls({
712
712
  const P = Fp.ORDER;
713
713
  const half = value.length / 2;
714
714
  if (half !== 48 && half !== 96)
715
- throw new Error('Invalid compressed signature length, must be 96 or 192');
715
+ throw new Error('invalid compressed signature length, must be 96 or 192');
716
716
  const z1 = bytesToNumberBE(value.slice(0, half));
717
717
  const z2 = bytesToNumberBE(value.slice(half));
718
718
  // Indicates the infinity point
package/src/bn254.ts CHANGED
@@ -3,7 +3,7 @@ import { sha256 } from '@noble/hashes/sha256';
3
3
  import { getHash } from './_shortw_utils.js';
4
4
  import { weierstrass } from './abstract/weierstrass.js';
5
5
  import { randomBytes } from '@noble/hashes/utils';
6
- import { bls, CurveFn } from './abstract/bls.js';
6
+ import { bls, CurveFn, PostPrecomputeFn, PostPrecomputePointAddFn } from './abstract/bls.js';
7
7
  import { Field } from './abstract/modular.js';
8
8
  import { bitGet, bitLen, notImplemented } from './abstract/utils.js';
9
9
  import { tower12, psiFrobenius } from './abstract/tower.js';
@@ -148,6 +148,20 @@ const htfDefaults = Object.freeze({
148
148
  hash: sha256,
149
149
  } as const);
150
150
 
151
+ export const _postPrecompute: PostPrecomputeFn = (
152
+ Rx: Fp2,
153
+ Ry: Fp2,
154
+ Rz: Fp2,
155
+ Qx: Fp2,
156
+ Qy: Fp2,
157
+ pointAdd: PostPrecomputePointAddFn
158
+ ) => {
159
+ const q = psi(Qx, Qy);
160
+ ({ Rx, Ry, Rz } = pointAdd(Rx, Ry, Rz, q[0], q[1]));
161
+ const q2 = psi(q[0], q[1]);
162
+ pointAdd(Rx, Ry, Rz, q2[0], Fp2.neg(q2[1]));
163
+ };
164
+
151
165
  /**
152
166
  * bn254 (a.k.a. alt_bn128) pairing-friendly curve.
153
167
  * Contains G1 / G2 operations and pairings.
@@ -212,12 +226,7 @@ export const bn254: CurveFn = bls({
212
226
  hash: sha256,
213
227
  randomBytes,
214
228
 
215
- postPrecompute: (Rx, Ry, Rz, Qx, Qy, pointAdd) => {
216
- const q = psi(Qx, Qy);
217
- ({ Rx, Ry, Rz } = pointAdd(Rx, Ry, Rz, q[0], q[1]));
218
- const q2 = psi(q[0], q[1]);
219
- pointAdd(Rx, Ry, Rz, q2[0], Fp2.neg(q2[1]));
220
- },
229
+ postPrecompute: _postPrecompute,
221
230
  });
222
231
 
223
232
  /**
package/src/ed448.ts CHANGED
@@ -120,7 +120,7 @@ const ED448_DEF = {
120
120
  adjustScalarBytes,
121
121
  // dom4
122
122
  domain: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => {
123
- if (ctx.length > 255) throw new Error(`Context is too big: ${ctx.length}`);
123
+ if (ctx.length > 255) throw new Error('context must be smaller than 255, got: ' + ctx.length);
124
124
  return concatBytes(
125
125
  utf8ToBytes('SigEd448'),
126
126
  new Uint8Array([phflag ? 1 : 0, ctx.length]),
package/src/p256.ts CHANGED
@@ -8,15 +8,15 @@ import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
8
8
  // NIST secp256r1 aka p256
9
9
  // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256
10
10
 
11
- const Fp = Field(BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff'));
12
- const CURVE_A = Fp.create(BigInt('-3'));
11
+ const Fp256 = Field(BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff'));
12
+ const CURVE_A = Fp256.create(BigInt('-3'));
13
13
  const CURVE_B = BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b');
14
14
 
15
15
  // prettier-ignore
16
16
  export const p256 = createCurve({
17
17
  a: CURVE_A, // Equation params: a, b
18
18
  b: CURVE_B,
19
- Fp, // Field: 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n-1n
19
+ Fp: Fp256, // Field: 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n-1n
20
20
  // Curve order, total count of valid points in the field
21
21
  n: BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551'),
22
22
  // Base (generator) point (x, y)
@@ -28,17 +28,17 @@ export const p256 = createCurve({
28
28
  export const secp256r1 = p256;
29
29
 
30
30
  const mapSWU = /* @__PURE__ */ (() =>
31
- mapToCurveSimpleSWU(Fp, {
31
+ mapToCurveSimpleSWU(Fp256, {
32
32
  A: CURVE_A,
33
33
  B: CURVE_B,
34
- Z: Fp.create(BigInt('-10')),
34
+ Z: Fp256.create(BigInt('-10')),
35
35
  }))();
36
36
 
37
37
  const htf = /* @__PURE__ */ (() =>
38
38
  createHasher(secp256r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
39
39
  DST: 'P256_XMD:SHA-256_SSWU_RO_',
40
40
  encodeDST: 'P256_XMD:SHA-256_SSWU_NU_',
41
- p: Fp.ORDER,
41
+ p: Fp256.ORDER,
42
42
  m: 1,
43
43
  k: 128,
44
44
  expand: 'xmd',
package/src/p384.ts CHANGED
@@ -11,8 +11,8 @@ import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
11
11
  // Field over which we'll do calculations.
12
12
  // prettier-ignore
13
13
  const P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff');
14
- const Fp = Field(P);
15
- const CURVE_A = Fp.create(BigInt('-3'));
14
+ const Fp384 = Field(P);
15
+ const CURVE_A = Fp384.create(BigInt('-3'));
16
16
  // prettier-ignore
17
17
  const CURVE_B = BigInt('0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef');
18
18
 
@@ -20,7 +20,7 @@ const CURVE_B = BigInt('0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe814112031408
20
20
  export const p384 = createCurve({
21
21
  a: CURVE_A, // Equation params: a, b
22
22
  b: CURVE_B,
23
- Fp, // Field: 2n**384n - 2n**128n - 2n**96n + 2n**32n - 1n
23
+ Fp: Fp384, // Field: 2n**384n - 2n**128n - 2n**96n + 2n**32n - 1n
24
24
  // Curve order, total count of valid points in the field.
25
25
  n: BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973'),
26
26
  // Base (generator) point (x, y)
@@ -32,17 +32,17 @@ export const p384 = createCurve({
32
32
  export const secp384r1 = p384;
33
33
 
34
34
  const mapSWU = /* @__PURE__ */ (() =>
35
- mapToCurveSimpleSWU(Fp, {
35
+ mapToCurveSimpleSWU(Fp384, {
36
36
  A: CURVE_A,
37
37
  B: CURVE_B,
38
- Z: Fp.create(BigInt('-12')),
38
+ Z: Fp384.create(BigInt('-12')),
39
39
  }))();
40
40
 
41
41
  const htf = /* @__PURE__ */ (() =>
42
42
  createHasher(secp384r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
43
43
  DST: 'P384_XMD:SHA-384_SSWU_RO_',
44
44
  encodeDST: 'P384_XMD:SHA-384_SSWU_NU_',
45
- p: Fp.ORDER,
45
+ p: Fp384.ORDER,
46
46
  m: 1,
47
47
  k: 192,
48
48
  expand: 'xmd',
package/src/p521.ts CHANGED
@@ -12,14 +12,14 @@ import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
12
12
  // Field over which we'll do calculations.
13
13
  // prettier-ignore
14
14
  const P = BigInt('0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
15
- const Fp = Field(P);
15
+ const Fp521 = Field(P);
16
16
 
17
17
  const CURVE = {
18
- a: Fp.create(BigInt('-3')),
18
+ a: Fp521.create(BigInt('-3')),
19
19
  b: BigInt(
20
20
  '0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00'
21
21
  ),
22
- Fp,
22
+ Fp: Fp521,
23
23
  n: BigInt(
24
24
  '0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409'
25
25
  ),
@@ -36,7 +36,7 @@ const CURVE = {
36
36
  export const p521 = createCurve({
37
37
  a: CURVE.a, // Equation params: a, b
38
38
  b: CURVE.b,
39
- Fp, // Field: 2n**521n - 1n
39
+ Fp: Fp521, // Field: 2n**521n - 1n
40
40
  // Curve order, total count of valid points in the field
41
41
  n: CURVE.n,
42
42
  Gx: CURVE.Gx, // Base point (x, y) aka generator point
@@ -48,17 +48,17 @@ export const p521 = createCurve({
48
48
  export const secp521r1 = p521;
49
49
 
50
50
  const mapSWU = /* @__PURE__ */ (() =>
51
- mapToCurveSimpleSWU(Fp, {
51
+ mapToCurveSimpleSWU(Fp521, {
52
52
  A: CURVE.a,
53
53
  B: CURVE.b,
54
- Z: Fp.create(BigInt('-4')),
54
+ Z: Fp521.create(BigInt('-4')),
55
55
  }))();
56
56
 
57
57
  const htf = /* @__PURE__ */ (() =>
58
58
  createHasher(secp521r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
59
59
  DST: 'P521_XMD:SHA-512_SSWU_RO_',
60
60
  encodeDST: 'P521_XMD:SHA-512_SSWU_NU_',
61
- p: Fp.ORDER,
61
+ p: Fp521.ORDER,
62
62
  m: 1,
63
63
  k: 256,
64
64
  expand: 'xmd',
package/src/secp256k1.ts CHANGED
@@ -45,11 +45,11 @@ function sqrtMod(y: bigint): bigint {
45
45
  const t1 = (pow2(b223, _23n, P) * b22) % P;
46
46
  const t2 = (pow2(t1, _6n, P) * b2) % P;
47
47
  const root = pow2(t2, _2n, P);
48
- if (!Fp.eql(Fp.sqr(root), y)) throw new Error('Cannot find square root');
48
+ if (!Fpk1.eql(Fpk1.sqr(root), y)) throw new Error('Cannot find square root');
49
49
  return root;
50
50
  }
51
51
 
52
- const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
52
+ const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
53
53
 
54
54
  /**
55
55
  * secp256k1 short weierstrass curve and ECDSA signatures over it.
@@ -58,7 +58,7 @@ export const secp256k1 = createCurve(
58
58
  {
59
59
  a: BigInt(0), // equation params: a, b
60
60
  b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975
61
- Fp, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
61
+ Fp: Fpk1, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
62
62
  n: secp256k1N, // Curve order, total count of valid points in the field
63
63
  // Base point (x, y) aka generator point
64
64
  Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
@@ -228,7 +228,7 @@ export const schnorr = /* @__PURE__ */ (() => ({
228
228
 
229
229
  const isoMap = /* @__PURE__ */ (() =>
230
230
  isogenyMap(
231
- Fp,
231
+ Fpk1,
232
232
  [
233
233
  // xNum
234
234
  [
@@ -260,22 +260,22 @@ const isoMap = /* @__PURE__ */ (() =>
260
260
  ].map((i) => i.map((j) => BigInt(j))) as [bigint[], bigint[], bigint[], bigint[]]
261
261
  ))();
262
262
  const mapSWU = /* @__PURE__ */ (() =>
263
- mapToCurveSimpleSWU(Fp, {
263
+ mapToCurveSimpleSWU(Fpk1, {
264
264
  A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'),
265
265
  B: BigInt('1771'),
266
- Z: Fp.create(BigInt('-11')),
266
+ Z: Fpk1.create(BigInt('-11')),
267
267
  }))();
268
268
  const htf = /* @__PURE__ */ (() =>
269
269
  createHasher(
270
270
  secp256k1.ProjectivePoint,
271
271
  (scalars: bigint[]) => {
272
- const { x, y } = mapSWU(Fp.create(scalars[0]));
272
+ const { x, y } = mapSWU(Fpk1.create(scalars[0]));
273
273
  return isoMap(x, y);
274
274
  },
275
275
  {
276
276
  DST: 'secp256k1_XMD:SHA-256_SSWU_RO_',
277
277
  encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_',
278
- p: Fp.ORDER,
278
+ p: Fpk1.ORDER,
279
279
  m: 1,
280
280
  k: 128,
281
281
  expand: 'xmd',