@noble/curves 1.9.5 → 1.9.7

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 (96) hide show
  1. package/abstract/bls.d.ts +2 -2
  2. package/abstract/bls.d.ts.map +1 -1
  3. package/abstract/curve.d.ts +3 -3
  4. package/abstract/curve.d.ts.map +1 -1
  5. package/abstract/edwards.d.ts +10 -4
  6. package/abstract/edwards.d.ts.map +1 -1
  7. package/abstract/edwards.js +62 -67
  8. package/abstract/edwards.js.map +1 -1
  9. package/abstract/montgomery.js +2 -2
  10. package/abstract/montgomery.js.map +1 -1
  11. package/abstract/tower.d.ts +9 -7
  12. package/abstract/tower.d.ts.map +1 -1
  13. package/abstract/tower.js +569 -357
  14. package/abstract/tower.js.map +1 -1
  15. package/abstract/utils.d.ts +74 -1
  16. package/abstract/utils.d.ts.map +1 -1
  17. package/abstract/utils.js +67 -17
  18. package/abstract/utils.js.map +1 -1
  19. package/abstract/weierstrass.d.ts +8 -4
  20. package/abstract/weierstrass.d.ts.map +1 -1
  21. package/abstract/weierstrass.js +81 -96
  22. package/abstract/weierstrass.js.map +1 -1
  23. package/bls12-381.d.ts.map +1 -1
  24. package/bls12-381.js +6 -39
  25. package/bls12-381.js.map +1 -1
  26. package/bn254.d.ts.map +1 -1
  27. package/bn254.js +2 -34
  28. package/bn254.js.map +1 -1
  29. package/ed25519.d.ts +1 -1
  30. package/ed25519.d.ts.map +1 -1
  31. package/ed25519.js +16 -16
  32. package/ed25519.js.map +1 -1
  33. package/ed448.d.ts +3 -4
  34. package/ed448.d.ts.map +1 -1
  35. package/ed448.js +30 -19
  36. package/ed448.js.map +1 -1
  37. package/esm/abstract/bls.d.ts +2 -2
  38. package/esm/abstract/bls.d.ts.map +1 -1
  39. package/esm/abstract/curve.d.ts +3 -3
  40. package/esm/abstract/curve.d.ts.map +1 -1
  41. package/esm/abstract/edwards.d.ts +10 -4
  42. package/esm/abstract/edwards.d.ts.map +1 -1
  43. package/esm/abstract/edwards.js +63 -68
  44. package/esm/abstract/edwards.js.map +1 -1
  45. package/esm/abstract/montgomery.js +2 -2
  46. package/esm/abstract/montgomery.js.map +1 -1
  47. package/esm/abstract/tower.d.ts +9 -7
  48. package/esm/abstract/tower.d.ts.map +1 -1
  49. package/esm/abstract/tower.js +570 -358
  50. package/esm/abstract/tower.js.map +1 -1
  51. package/esm/abstract/utils.d.ts +74 -1
  52. package/esm/abstract/utils.d.ts.map +1 -1
  53. package/esm/abstract/utils.js +66 -3
  54. package/esm/abstract/utils.js.map +1 -1
  55. package/esm/abstract/weierstrass.d.ts +8 -4
  56. package/esm/abstract/weierstrass.d.ts.map +1 -1
  57. package/esm/abstract/weierstrass.js +83 -98
  58. package/esm/abstract/weierstrass.js.map +1 -1
  59. package/esm/bls12-381.d.ts.map +1 -1
  60. package/esm/bls12-381.js +7 -40
  61. package/esm/bls12-381.js.map +1 -1
  62. package/esm/bn254.d.ts.map +1 -1
  63. package/esm/bn254.js +3 -35
  64. package/esm/bn254.js.map +1 -1
  65. package/esm/ed25519.d.ts +1 -1
  66. package/esm/ed25519.d.ts.map +1 -1
  67. package/esm/ed25519.js +17 -17
  68. package/esm/ed25519.js.map +1 -1
  69. package/esm/ed448.d.ts +3 -4
  70. package/esm/ed448.d.ts.map +1 -1
  71. package/esm/ed448.js +32 -21
  72. package/esm/ed448.js.map +1 -1
  73. package/esm/secp256k1.d.ts.map +1 -1
  74. package/esm/secp256k1.js +30 -28
  75. package/esm/secp256k1.js.map +1 -1
  76. package/esm/utils.js +1 -1
  77. package/esm/utils.js.map +1 -1
  78. package/package.json +2 -2
  79. package/secp256k1.d.ts.map +1 -1
  80. package/secp256k1.js +29 -27
  81. package/secp256k1.js.map +1 -1
  82. package/src/abstract/bls.ts +2 -2
  83. package/src/abstract/curve.ts +3 -3
  84. package/src/abstract/edwards.ts +71 -76
  85. package/src/abstract/montgomery.ts +2 -2
  86. package/src/abstract/tower.ts +630 -382
  87. package/src/abstract/utils.ts +76 -3
  88. package/src/abstract/weierstrass.ts +88 -97
  89. package/src/bls12-381.ts +6 -39
  90. package/src/bn254.ts +3 -34
  91. package/src/ed25519.ts +17 -18
  92. package/src/ed448.ts +35 -40
  93. package/src/secp256k1.ts +28 -27
  94. package/src/utils.ts +1 -1
  95. package/utils.js +1 -1
  96. package/utils.js.map +1 -1
@@ -1,7 +1,80 @@
1
1
  /**
2
+ * Deprecated module: moved from curves/abstract/utils.js to curves/utils.js
2
3
  * @module
3
4
  */
4
- export * from '../utils.ts';
5
+ import * as u from '../utils.ts';
5
6
 
6
- // TODO
7
- // @deprecated use `@noble/curves/utils.js`
7
+ /** @deprecated moved to `@noble/curves/utils.js` */
8
+ export type Hex = u.Hex;
9
+ /** @deprecated moved to `@noble/curves/utils.js` */
10
+ export type PrivKey = u.PrivKey;
11
+ /** @deprecated moved to `@noble/curves/utils.js` */
12
+ export type CHash = u.CHash;
13
+ /** @deprecated moved to `@noble/curves/utils.js` */
14
+ export type FHash = u.FHash;
15
+
16
+ /** @deprecated moved to `@noble/curves/utils.js` */
17
+ export const abytes: typeof u.abytes = u.abytes;
18
+ /** @deprecated moved to `@noble/curves/utils.js` */
19
+ export const anumber: typeof u.anumber = u.anumber;
20
+ /** @deprecated moved to `@noble/curves/utils.js` */
21
+ export const bytesToHex: typeof u.bytesToHex = u.bytesToHex;
22
+ /** @deprecated moved to `@noble/curves/utils.js` */
23
+ export const bytesToUtf8: typeof u.bytesToUtf8 = u.bytesToUtf8;
24
+ /** @deprecated moved to `@noble/curves/utils.js` */
25
+ export const concatBytes: typeof u.concatBytes = u.concatBytes;
26
+ /** @deprecated moved to `@noble/curves/utils.js` */
27
+ export const hexToBytes: typeof u.hexToBytes = u.hexToBytes;
28
+ /** @deprecated moved to `@noble/curves/utils.js` */
29
+ export const isBytes: typeof u.isBytes = u.isBytes;
30
+ /** @deprecated moved to `@noble/curves/utils.js` */
31
+ export const randomBytes: typeof u.randomBytes = u.randomBytes;
32
+ /** @deprecated moved to `@noble/curves/utils.js` */
33
+ export const utf8ToBytes: typeof u.utf8ToBytes = u.utf8ToBytes;
34
+
35
+ /** @deprecated moved to `@noble/curves/utils.js` */
36
+ export const abool: typeof u.abool = u.abool;
37
+ /** @deprecated moved to `@noble/curves/utils.js` */
38
+ export const numberToHexUnpadded: typeof u.numberToHexUnpadded = u.numberToHexUnpadded;
39
+ /** @deprecated moved to `@noble/curves/utils.js` */
40
+ export const hexToNumber: typeof u.hexToNumber = u.hexToNumber;
41
+ /** @deprecated moved to `@noble/curves/utils.js` */
42
+ export const bytesToNumberBE: typeof u.bytesToNumberBE = u.bytesToNumberBE;
43
+ /** @deprecated moved to `@noble/curves/utils.js` */
44
+ export const bytesToNumberLE: typeof u.bytesToNumberLE = u.bytesToNumberLE;
45
+ /** @deprecated moved to `@noble/curves/utils.js` */
46
+ export const numberToBytesBE: typeof u.numberToBytesBE = u.numberToBytesBE;
47
+ /** @deprecated moved to `@noble/curves/utils.js` */
48
+ export const numberToBytesLE: typeof u.numberToBytesLE = u.numberToBytesLE;
49
+ /** @deprecated moved to `@noble/curves/utils.js` */
50
+ export const numberToVarBytesBE: typeof u.numberToVarBytesBE = u.numberToVarBytesBE;
51
+ /** @deprecated moved to `@noble/curves/utils.js` */
52
+ export const ensureBytes: typeof u.ensureBytes = u.ensureBytes;
53
+ /** @deprecated moved to `@noble/curves/utils.js` */
54
+ export const equalBytes: typeof u.equalBytes = u.equalBytes;
55
+ /** @deprecated moved to `@noble/curves/utils.js` */
56
+ export const copyBytes: typeof u.copyBytes = u.copyBytes;
57
+ /** @deprecated moved to `@noble/curves/utils.js` */
58
+ export const asciiToBytes: typeof u.asciiToBytes = u.asciiToBytes;
59
+ /** @deprecated moved to `@noble/curves/utils.js` */
60
+ export const inRange: typeof u.inRange = u.inRange;
61
+ /** @deprecated moved to `@noble/curves/utils.js` */
62
+ export const aInRange: typeof u.aInRange = u.aInRange;
63
+ /** @deprecated moved to `@noble/curves/utils.js` */
64
+ export const bitLen: typeof u.bitLen = u.bitLen;
65
+ /** @deprecated moved to `@noble/curves/utils.js` */
66
+ export const bitGet: typeof u.bitGet = u.bitGet;
67
+ /** @deprecated moved to `@noble/curves/utils.js` */
68
+ export const bitSet: typeof u.bitSet = u.bitSet;
69
+ /** @deprecated moved to `@noble/curves/utils.js` */
70
+ export const bitMask: typeof u.bitMask = u.bitMask;
71
+ /** @deprecated moved to `@noble/curves/utils.js` */
72
+ export const createHmacDrbg: typeof u.createHmacDrbg = u.createHmacDrbg;
73
+ /** @deprecated moved to `@noble/curves/utils.js` */
74
+ export const notImplemented: typeof u.notImplemented = u.notImplemented;
75
+ /** @deprecated moved to `@noble/curves/utils.js` */
76
+ export const memoized: typeof u.memoized = u.memoized;
77
+ /** @deprecated moved to `@noble/curves/utils.js` */
78
+ export const validateObject: typeof u.validateObject = u.validateObject;
79
+ /** @deprecated moved to `@noble/curves/utils.js` */
80
+ export const isHash: typeof u.isHash = u.isHash;
@@ -44,7 +44,7 @@ import {
44
44
  isBytes,
45
45
  memoized,
46
46
  numberToHexUnpadded,
47
- randomBytes as wcRandomBytes,
47
+ randomBytes as randomBytesWeb,
48
48
  type CHash,
49
49
  type Hex,
50
50
  type PrivKey,
@@ -531,7 +531,7 @@ export function weierstrassN<T>(
531
531
  }
532
532
  function pointFromBytes(bytes: Uint8Array) {
533
533
  abytes(bytes, undefined, 'Point');
534
- const { public: comp, publicUncompressed: uncomp } = lengths; // e.g. for 32-byte: 33, 65
534
+ const { publicKey: comp, publicKeyUncompressed: uncomp } = lengths; // e.g. for 32-byte: 33, 65
535
535
  const length = bytes.length;
536
536
  const head = bytes[0];
537
537
  const tail = bytes.subarray(1);
@@ -988,6 +988,7 @@ export function weierstrassN<T>(
988
988
  }
989
989
  const bits = Fn.BITS;
990
990
  const wnaf = new wNAF(Point, extraOpts.endo ? Math.ceil(bits / 2) : bits);
991
+ Point.BASE.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
991
992
  return Point;
992
993
  }
993
994
 
@@ -1171,9 +1172,9 @@ export function mapToCurveSimpleSWU<T>(
1171
1172
 
1172
1173
  function getWLengths<T>(Fp: IField<T>, Fn: IField<bigint>) {
1173
1174
  return {
1174
- secret: Fn.BYTES,
1175
- public: 1 + Fp.BYTES,
1176
- publicUncompressed: 1 + 2 * Fp.BYTES,
1175
+ secretKey: Fn.BYTES,
1176
+ publicKey: 1 + Fp.BYTES,
1177
+ publicKeyUncompressed: 1 + 2 * Fp.BYTES,
1177
1178
  publicKeyHasPrefix: true,
1178
1179
  signature: 2 * Fn.BYTES,
1179
1180
  };
@@ -1188,7 +1189,7 @@ export function ecdh(
1188
1189
  ecdhOpts: { randomBytes?: (bytesLength?: number) => Uint8Array } = {}
1189
1190
  ): ECDH {
1190
1191
  const { Fn } = Point;
1191
- const randomBytes_ = ecdhOpts.randomBytes || wcRandomBytes;
1192
+ const randomBytes_ = ecdhOpts.randomBytes || randomBytesWeb;
1192
1193
  const lengths = Object.assign(getWLengths(Point.Fp, Fn), { seed: getMinHashLength(Fn.ORDER) });
1193
1194
 
1194
1195
  function isValidSecretKey(secretKey: PrivKey) {
@@ -1200,11 +1201,11 @@ export function ecdh(
1200
1201
  }
1201
1202
 
1202
1203
  function isValidPublicKey(publicKey: Uint8Array, isCompressed?: boolean): boolean {
1203
- const { public: comp, publicUncompressed } = lengths;
1204
+ const { publicKey: comp, publicKeyUncompressed } = lengths;
1204
1205
  try {
1205
1206
  const l = publicKey.length;
1206
1207
  if (isCompressed === true && l !== comp) return false;
1207
- if (isCompressed === false && l !== publicUncompressed) return false;
1208
+ if (isCompressed === false && l !== publicKeyUncompressed) return false;
1208
1209
  return !!Point.fromBytes(publicKey);
1209
1210
  } catch (error) {
1210
1211
  return false;
@@ -1239,9 +1240,10 @@ export function ecdh(
1239
1240
  function isProbPub(item: PrivKey | PubKey): boolean | undefined {
1240
1241
  if (typeof item === 'bigint') return false;
1241
1242
  if (item instanceof Point) return true;
1242
- if (Fn.allowedLengths || lengths.secret === lengths.public) return undefined;
1243
+ const { secretKey, publicKey, publicKeyUncompressed } = lengths;
1244
+ if (Fn.allowedLengths || secretKey === publicKey) return undefined;
1243
1245
  const l = ensureBytes('key', item).length;
1244
- return l === lengths.public || l === lengths.publicUncompressed;
1246
+ return l === publicKey || l === publicKeyUncompressed;
1245
1247
  }
1246
1248
 
1247
1249
  /**
@@ -1290,6 +1292,7 @@ export function ecdh(
1290
1292
  * const p256_Point = weierstrass(...);
1291
1293
  * const p256_sha256 = ecdsa(p256_Point, sha256);
1292
1294
  * const p256_sha224 = ecdsa(p256_Point, sha224);
1295
+ * const p256_sha224_r = ecdsa(p256_Point, sha224, { randomBytes: (length) => { ... } });
1293
1296
  * ```
1294
1297
  */
1295
1298
  export function ecdsa(
@@ -1310,8 +1313,8 @@ export function ecdsa(
1310
1313
  }
1311
1314
  );
1312
1315
 
1313
- const randomBytes_ = ecdsaOpts.randomBytes || wcRandomBytes;
1314
- const hmac_: HmacFnSync =
1316
+ const randomBytes = ecdsaOpts.randomBytes || randomBytesWeb;
1317
+ const hmac: HmacFnSync =
1315
1318
  ecdsaOpts.hmac ||
1316
1319
  (((key, ...msgs) => nobleHmac(hash, key, concatBytes(...msgs))) satisfies HmacFnSync);
1317
1320
 
@@ -1330,14 +1333,17 @@ export function ecdsa(
1330
1333
  const HALF = CURVE_ORDER >> _1n;
1331
1334
  return number > HALF;
1332
1335
  }
1333
- function normalizeS(s: bigint) {
1334
- return isBiggerThanHalfOrder(s) ? Fn.neg(s) : s;
1335
- }
1336
1336
  function validateRS(title: string, num: bigint): bigint {
1337
1337
  if (!Fn.isValidNot0(num))
1338
1338
  throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`);
1339
1339
  return num;
1340
1340
  }
1341
+ function validateSigLength(bytes: Uint8Array, format: ECDSASigFormat) {
1342
+ validateSigFormat(format);
1343
+ const size = lengths.signature!;
1344
+ const sizer = format === 'compact' ? size : format === 'recovered' ? size + 1 : undefined;
1345
+ return abytes(bytes, sizer, `${format} signature`);
1346
+ }
1341
1347
 
1342
1348
  /**
1343
1349
  * ECDSA signature with its (r, s) properties. Supports compact, recovered & DER representations.
@@ -1354,21 +1360,18 @@ export function ecdsa(
1354
1360
  }
1355
1361
 
1356
1362
  static fromBytes(bytes: Uint8Array, format: ECDSASigFormat = defaultSigOpts_format): Signature {
1357
- validateSigFormat(format);
1358
- const size = lengths.signature!;
1363
+ validateSigLength(bytes, format);
1359
1364
  let recid: number | undefined;
1360
1365
  if (format === 'der') {
1361
1366
  const { r, s } = DER.toSig(abytes(bytes));
1362
1367
  return new Signature(r, s);
1363
1368
  }
1364
1369
  if (format === 'recovered') {
1365
- abytes(bytes, size + 1);
1366
1370
  recid = bytes[0];
1367
1371
  format = 'compact';
1368
1372
  bytes = bytes.subarray(1);
1369
1373
  }
1370
- abytes(bytes, size);
1371
- const L = size / 2;
1374
+ const L = Fn.BYTES;
1372
1375
  const r = bytes.subarray(0, L);
1373
1376
  const s = bytes.subarray(L, L * 2);
1374
1377
  return new Signature(Fn.fromBytes(r), Fn.fromBytes(s), recid);
@@ -1382,7 +1385,7 @@ export function ecdsa(
1382
1385
  return new Signature(this.r, this.s, recovery) as RecoveredSignature;
1383
1386
  }
1384
1387
 
1385
- recoverPublicKey(msgHash: Hex): typeof Point.BASE {
1388
+ recoverPublicKey(messageHash: Hex): WeierstrassPoint<bigint> {
1386
1389
  const FIELD_ORDER = Fp.ORDER;
1387
1390
  const { r, s, recovery: rec } = this;
1388
1391
  if (rec == null || ![0, 1, 2, 3].includes(rec)) throw new Error('recovery id invalid');
@@ -1403,7 +1406,7 @@ export function ecdsa(
1403
1406
  const x = Fp.toBytes(radj);
1404
1407
  const R = Point.fromBytes(concatBytes(pprefix((rec & 1) === 0), x));
1405
1408
  const ir = Fn.inv(radj); // r^-1
1406
- const h = bits2int_modN(ensureBytes('msgHash', msgHash)); // Truncate hash
1409
+ const h = bits2int_modN(ensureBytes('msgHash', messageHash)); // Truncate hash
1407
1410
  const u1 = Fn.create(-h * ir); // -hr^-1
1408
1411
  const u2 = Fn.create(s * ir); // sr^-1
1409
1412
  // (sr^-1)R-(hr^-1)G = -(hr^-1)G + (sr^-1). unsafe is fine: there is no private data.
@@ -1466,7 +1469,7 @@ export function ecdsa(
1466
1469
  // int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
1467
1470
  const bits2int =
1468
1471
  ecdsaOpts.bits2int ||
1469
- function (bytes: Uint8Array): bigint {
1472
+ function bits2int_def(bytes: Uint8Array): bigint {
1470
1473
  // Our custom check "just in case", for protection against DoS
1471
1474
  if (bytes.length > 8192) throw new Error('input is too large');
1472
1475
  // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
@@ -1477,20 +1480,23 @@ export function ecdsa(
1477
1480
  };
1478
1481
  const bits2int_modN =
1479
1482
  ecdsaOpts.bits2int_modN ||
1480
- function (bytes: Uint8Array): bigint {
1483
+ function bits2int_modN_def(bytes: Uint8Array): bigint {
1481
1484
  return Fn.create(bits2int(bytes)); // can't use bytesToNumberBE here
1482
1485
  };
1483
- // NOTE: pads output with zero as per spec
1486
+ // Pads output with zero as per spec
1484
1487
  const ORDER_MASK = bitMask(fnBits);
1485
- /**
1486
- * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
1487
- */
1488
+ /** Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`. */
1488
1489
  function int2octets(num: bigint): Uint8Array {
1489
1490
  // IMPORTANT: the check ensures working for case `Fn.BYTES != Fn.BITS * 8`
1490
1491
  aInRange('num < 2^' + fnBits, num, _0n, ORDER_MASK);
1491
1492
  return Fn.toBytes(num);
1492
1493
  }
1493
1494
 
1495
+ function validateMsgAndHash(message: Uint8Array, prehash: boolean) {
1496
+ abytes(message, undefined, 'message');
1497
+ return prehash ? abytes(hash(message), undefined, 'prehashed message') : message;
1498
+ }
1499
+
1494
1500
  /**
1495
1501
  * Steps A, D of RFC6979 3.2.
1496
1502
  * Creates RFC6979 seed; converts msg/privKey to numbers.
@@ -1503,10 +1509,7 @@ export function ecdsa(
1503
1509
  if (['recovered', 'canonical'].some((k) => k in opts))
1504
1510
  throw new Error('sign() legacy options not supported');
1505
1511
  const { lowS, prehash, extraEntropy } = validateSigOpts(opts, defaultSigOpts);
1506
- // RFC6979 3.2: we skip step A, because we already provide hash
1507
- message = abytes(message, undefined, 'message');
1508
- if (prehash) message = abytes(hash(message), undefined, 'prehashed message');
1509
-
1512
+ message = validateMsgAndHash(message, prehash); // RFC6979 3.2 A: h1 = H(m)
1510
1513
  // We can't later call bits2octets, since nested bits2int is broken for curves
1511
1514
  // with fnBits % 8 !== 0. Because of that, we unwrap it here as int2octets call.
1512
1515
  // const bits2octets = (bits) => int2octets(bits2int_modN(bits))
@@ -1517,7 +1520,7 @@ export function ecdsa(
1517
1520
  if (extraEntropy != null && extraEntropy !== false) {
1518
1521
  // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
1519
1522
  // gen random bytes OR pass as-is
1520
- const e = extraEntropy === true ? randomBytes_(lengths.secret) : extraEntropy;
1523
+ const e = extraEntropy === true ? randomBytes(lengths.secretKey) : extraEntropy;
1521
1524
  seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes
1522
1525
  }
1523
1526
  const seed = concatBytes(...seedArgs); // Step D of RFC6979 3.2
@@ -1544,7 +1547,7 @@ export function ecdsa(
1544
1547
  let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3, when q.x > n)
1545
1548
  let normS = s;
1546
1549
  if (lowS && isBiggerThanHalfOrder(s)) {
1547
- normS = normalizeS(s); // if lowS was passed, ensure s is always
1550
+ normS = Fn.neg(s); // if lowS was passed, ensure s is always
1548
1551
  recovery ^= 1; // // in the bottom half of N
1549
1552
  }
1550
1553
  return new Signature(r, normS, recovery) as RecoveredSignature; // use normS, not s
@@ -1566,13 +1569,42 @@ export function ecdsa(
1566
1569
  function sign(message: Hex, secretKey: PrivKey, opts: ECDSASignOpts = {}): RecoveredSignature {
1567
1570
  message = ensureBytes('message', message);
1568
1571
  const { seed, k2sig } = prepSig(message, secretKey, opts); // Steps A, D of RFC6979 3.2.
1569
- const drbg = createHmacDrbg<RecoveredSignature>(hash.outputLen, Fn.BYTES, hmac_);
1572
+ const drbg = createHmacDrbg<RecoveredSignature>(hash.outputLen, Fn.BYTES, hmac);
1570
1573
  const sig = drbg(seed, k2sig); // Steps B, C, D, E, F, G
1571
1574
  return sig;
1572
1575
  }
1573
1576
 
1574
- // Enable precomputes. Slows down first publicKey computation by 20ms.
1575
- Point.BASE.precompute(8);
1577
+ function tryParsingSig(sg: Hex | SignatureLike) {
1578
+ // Try to deduce format
1579
+ let sig: Signature | undefined = undefined;
1580
+ const isHex = typeof sg === 'string' || isBytes(sg);
1581
+ const isObj =
1582
+ !isHex &&
1583
+ sg !== null &&
1584
+ typeof sg === 'object' &&
1585
+ typeof sg.r === 'bigint' &&
1586
+ typeof sg.s === 'bigint';
1587
+ if (!isHex && !isObj)
1588
+ throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
1589
+ if (isObj) {
1590
+ sig = new Signature(sg.r, sg.s);
1591
+ } else if (isHex) {
1592
+ try {
1593
+ sig = Signature.fromBytes(ensureBytes('sig', sg), 'der');
1594
+ } catch (derError) {
1595
+ if (!(derError instanceof DER.Err)) throw derError;
1596
+ }
1597
+ if (!sig) {
1598
+ try {
1599
+ sig = Signature.fromBytes(ensureBytes('sig', sg), 'compact');
1600
+ } catch (error) {
1601
+ return false;
1602
+ }
1603
+ }
1604
+ }
1605
+ if (!sig) return false;
1606
+ return sig;
1607
+ }
1576
1608
 
1577
1609
  /**
1578
1610
  * Verifies a signature against message and public key.
@@ -1593,61 +1625,19 @@ export function ecdsa(
1593
1625
  publicKey: Hex,
1594
1626
  opts: ECDSAVerifyOpts = {}
1595
1627
  ): boolean {
1596
- const sg = signature;
1597
- message = ensureBytes('msgHash', message);
1598
- publicKey = ensureBytes('publicKey', publicKey);
1599
1628
  const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts);
1600
- let _sig: Signature | undefined = undefined;
1601
- let P: WeierstrassPoint<bigint>;
1602
-
1629
+ publicKey = ensureBytes('publicKey', publicKey);
1630
+ message = validateMsgAndHash(ensureBytes('message', message), prehash);
1603
1631
  if ('strict' in opts) throw new Error('options.strict was renamed to lowS');
1604
- if (format === undefined) {
1605
- // Try to deduce format
1606
- const isHex = typeof sg === 'string' || isBytes(sg);
1607
- const isObj =
1608
- !isHex &&
1609
- sg !== null &&
1610
- typeof sg === 'object' &&
1611
- typeof sg.r === 'bigint' &&
1612
- typeof sg.s === 'bigint';
1613
- if (!isHex && !isObj)
1614
- throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
1615
- if (isObj) {
1616
- _sig = new Signature(sg.r, sg.s);
1617
- } else if (isHex) {
1618
- // TODO: remove this malleable check
1619
- // Signature can be represented in 2 ways: compact (2*Fn.BYTES) & DER (variable-length).
1620
- // Since DER can also be 2*Fn.BYTES bytes, we check for it first.
1621
- try {
1622
- _sig = Signature.fromDER(sg);
1623
- } catch (derError) {
1624
- if (!(derError instanceof DER.Err)) throw derError;
1625
- }
1626
- if (!_sig) {
1627
- try {
1628
- _sig = Signature.fromCompact(sg);
1629
- } catch (error) {
1630
- return false;
1631
- }
1632
- }
1633
- }
1634
- } else {
1635
- if (format === 'compact' || format === 'der') {
1636
- if (typeof sg !== 'string' && !isBytes(sg))
1637
- throw new Error('"der" / "compact" format expects Uint8Array signature');
1638
- _sig = Signature.fromBytes(ensureBytes('sig', sg), format);
1639
- } else {
1640
- throw new Error('format must be "compact", "der" or "js"');
1641
- }
1642
- }
1643
-
1644
- if (!_sig) return false;
1632
+ const sig =
1633
+ format === undefined
1634
+ ? tryParsingSig(signature)
1635
+ : Signature.fromBytes(ensureBytes('sig', signature as Hex), format);
1636
+ if (sig === false) return false;
1645
1637
  try {
1646
- P = Point.fromHex(publicKey);
1647
- if (lowS && _sig.hasHighS()) return false;
1648
- // todo: optional.hash => hash
1649
- if (prehash) message = hash(message);
1650
- const { r, s } = _sig;
1638
+ const P = Point.fromBytes(publicKey);
1639
+ if (lowS && sig.hasHighS()) return false;
1640
+ const { r, s } = sig;
1651
1641
  const h = bits2int_modN(message); // mod n, not mod p
1652
1642
  const is = Fn.inv(s); // s^-1 mod n
1653
1643
  const u1 = Fn.create(h * is); // u1 = hs^-1 mod n
@@ -1666,10 +1656,8 @@ export function ecdsa(
1666
1656
  message: Uint8Array,
1667
1657
  opts: ECDSARecoverOpts = {}
1668
1658
  ): Uint8Array {
1669
- const prehash = opts.prehash !== undefined ? opts.prehash : defaultSigOpts.prehash;
1670
- abool(prehash, 'prehash');
1671
- message = abytes(message, undefined, 'message');
1672
- if (prehash) message = abytes(hash(message), undefined, 'prehashed message');
1659
+ const { prehash } = validateSigOpts(opts, defaultSigOpts);
1660
+ message = validateMsgAndHash(message, prehash);
1673
1661
  return Signature.fromBytes(signature, 'recovered').recoverPublicKey(message).toBytes();
1674
1662
  }
1675
1663
 
@@ -1689,13 +1677,14 @@ export function ecdsa(
1689
1677
  }
1690
1678
 
1691
1679
  // TODO: remove everything below
1692
- /** @deprecated */
1680
+ /** @deprecated use ECDSASignature */
1693
1681
  export type SignatureType = ECDSASignature;
1694
- /** @deprecated */
1682
+ /** @deprecated use ECDSASigRecovered */
1695
1683
  export type RecoveredSignatureType = ECDSASigRecovered;
1696
- /** @deprecated */
1684
+ /** @deprecated switch to Uint8Array signatures in format 'compact' */
1697
1685
  export type SignatureLike = { r: bigint; s: bigint };
1698
- /** @deprecated use `Uint8Array | boolean` */
1686
+ export type ECDSAExtraEntropy = Hex | boolean;
1687
+ /** @deprecated use `ECDSAExtraEntropy` */
1699
1688
  export type Entropy = Hex | boolean;
1700
1689
  export type BasicWCurve<T> = BasicCurve<T> & {
1701
1690
  // Params: a, b
@@ -1721,6 +1710,8 @@ export type VerOpts = ECDSAVerifyOpts;
1721
1710
  export type ProjPointType<T> = WeierstrassPoint<T>;
1722
1711
  /** @deprecated use WeierstrassPointCons */
1723
1712
  export type ProjConstructor<T> = WeierstrassPointCons<T>;
1713
+ /** @deprecated use ECDSASignatureCons */
1714
+ export type SignatureConstructor = ECDSASignatureCons;
1724
1715
 
1725
1716
  // TODO: remove
1726
1717
  export type CurvePointsType<T> = BasicWCurve<T> & {
package/src/bls12-381.ts CHANGED
@@ -82,7 +82,6 @@ import { bls, type CurveFn } from './abstract/bls.ts';
82
82
  import { Field, type IField } from './abstract/modular.ts';
83
83
  import {
84
84
  abytes,
85
- bitGet,
86
85
  bitLen,
87
86
  bitMask,
88
87
  bytesToHex,
@@ -147,10 +146,13 @@ const bls12_381_CURVE_G1: WeierstrassOpts<bigint> = {
147
146
  };
148
147
 
149
148
  // CURVE FIELDS
150
- export const bls12_381_Fr: IField<bigint> = Field(bls12_381_CURVE_G1.n, { modFromBytes: true });
151
- const { Fp, Fp2, Fp6, Fp4Square, Fp12 } = tower12({
152
- // Order of Fp
149
+ export const bls12_381_Fr: IField<bigint> = Field(bls12_381_CURVE_G1.n, {
150
+ modFromBytes: true,
151
+ isLE: true,
152
+ });
153
+ const { Fp, Fp2, Fp6, Fp12 } = tower12({
153
154
  ORDER: bls12_381_CURVE_G1.p,
155
+ X_LEN: BLS_X_LEN,
154
156
  // Finite extension field over irreducible polynominal.
155
157
  // Fp(u) / (u² - β) where β = -1
156
158
  FP2_NONRESIDUE: [_1n, _1n],
@@ -160,41 +162,6 @@ const { Fp, Fp2, Fp6, Fp4Square, Fp12 } = tower12({
160
162
  // (T0-T1) + (T0+T1)*i
161
163
  return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
162
164
  },
163
- // Fp12
164
- // A cyclotomic group is a subgroup of Fp^n defined by
165
- // GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) = 1}
166
- // The result of any pairing is in a cyclotomic subgroup
167
- // https://eprint.iacr.org/2009/565.pdf
168
- Fp12cyclotomicSquare: ({ c0, c1 }): Fp12 => {
169
- const { c0: c0c0, c1: c0c1, c2: c0c2 } = c0;
170
- const { c0: c1c0, c1: c1c1, c2: c1c2 } = c1;
171
- const { first: t3, second: t4 } = Fp4Square(c0c0, c1c1);
172
- const { first: t5, second: t6 } = Fp4Square(c1c0, c0c2);
173
- const { first: t7, second: t8 } = Fp4Square(c0c1, c1c2);
174
- const t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
175
- return {
176
- c0: Fp6.create({
177
- c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3), // 2 * (T3 - c0c0) + T3
178
- c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), _2n), t5), // 2 * (T5 - c0c1) + T5
179
- c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), _2n), t7),
180
- }), // 2 * (T7 - c0c2) + T7
181
- c1: Fp6.create({
182
- c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), _2n), t9), // 2 * (T9 + c1c0) + T9
183
- c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), _2n), t4), // 2 * (T4 + c1c1) + T4
184
- c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), _2n), t6),
185
- }),
186
- }; // 2 * (T6 + c1c2) + T6
187
- },
188
- Fp12cyclotomicExp(num, n) {
189
- let z = Fp12.ONE;
190
- for (let i = BLS_X_LEN - 1; i >= 0; i--) {
191
- z = Fp12._cyclotomicSquare(z);
192
- if (bitGet(n, i)) z = Fp12.mul(z, num);
193
- }
194
- return z;
195
- },
196
- // https://eprint.iacr.org/2010/354.pdf
197
- // https://eprint.iacr.org/2009/565.pdf
198
165
  Fp12finalExponentiate: (num) => {
199
166
  const x = BLS_X;
200
167
  // this^(q⁶) / this
package/src/bn254.ts CHANGED
@@ -65,7 +65,7 @@ import { Field, type IField } from './abstract/modular.ts';
65
65
  import type { Fp, Fp12, Fp2, Fp6 } from './abstract/tower.ts';
66
66
  import { psiFrobenius, tower12 } from './abstract/tower.ts';
67
67
  import { type CurveFn, weierstrass, type WeierstrassOpts } from './abstract/weierstrass.ts';
68
- import { bitGet, bitLen, notImplemented } from './utils.ts';
68
+ import { bitLen, notImplemented } from './utils.ts';
69
69
  // prettier-ignore
70
70
  const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
71
71
  const _6n = BigInt(6);
@@ -94,42 +94,11 @@ const Fp2B = {
94
94
  c1: BigInt('266929791119991161246907387137283842545076965332900288569378510910307636690'),
95
95
  };
96
96
 
97
- const { Fp, Fp2, Fp6, Fp4Square, Fp12 } = tower12({
97
+ const { Fp, Fp2, Fp6, Fp12 } = tower12({
98
98
  ORDER: bn254_G1_CURVE.p,
99
+ X_LEN: BN_X_LEN,
99
100
  FP2_NONRESIDUE: [BigInt(9), _1n],
100
101
  Fp2mulByB: (num) => Fp2.mul(num, Fp2B),
101
- // The result of any pairing is in a cyclotomic subgroup
102
- // https://eprint.iacr.org/2009/565.pdf
103
- Fp12cyclotomicSquare: ({ c0, c1 }): Fp12 => {
104
- const { c0: c0c0, c1: c0c1, c2: c0c2 } = c0;
105
- const { c0: c1c0, c1: c1c1, c2: c1c2 } = c1;
106
- const { first: t3, second: t4 } = Fp4Square(c0c0, c1c1);
107
- const { first: t5, second: t6 } = Fp4Square(c1c0, c0c2);
108
- const { first: t7, second: t8 } = Fp4Square(c0c1, c1c2);
109
- let t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
110
- return {
111
- c0: Fp6.create({
112
- c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3), // 2 * (T3 - c0c0) + T3
113
- c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), _2n), t5), // 2 * (T5 - c0c1) + T5
114
- c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), _2n), t7),
115
- }), // 2 * (T7 - c0c2) + T7
116
- c1: Fp6.create({
117
- c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), _2n), t9), // 2 * (T9 + c1c0) + T9
118
- c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), _2n), t4), // 2 * (T4 + c1c1) + T4
119
- c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), _2n), t6),
120
- }),
121
- }; // 2 * (T6 + c1c2) + T6
122
- },
123
- Fp12cyclotomicExp(num, n) {
124
- let z = Fp12.ONE;
125
- for (let i = BN_X_LEN - 1; i >= 0; i--) {
126
- z = Fp12._cyclotomicSquare(z);
127
- if (bitGet(n, i)) z = Fp12.mul(z, num);
128
- }
129
- return z;
130
- },
131
- // https://eprint.iacr.org/2010/354.pdf
132
- // https://eprint.iacr.org/2009/565.pdf
133
102
  Fp12finalExponentiate: (num) => {
134
103
  const powMinusX = (num: Fp12) => Fp12.conjugate(Fp12._cyclotomicExp(num, BN_X));
135
104
  const r0 = Fp12.mul(Fp12.conjugate(num), Fp12.inv(num));