@noble/curves 1.8.0 → 1.8.2

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 (191) hide show
  1. package/README.md +282 -419
  2. package/_shortw_utils.d.ts +2 -2
  3. package/_shortw_utils.d.ts.map +1 -1
  4. package/_shortw_utils.js +2 -2
  5. package/_shortw_utils.js.map +1 -1
  6. package/abstract/bls.d.ts +5 -5
  7. package/abstract/bls.d.ts.map +1 -1
  8. package/abstract/bls.js +14 -15
  9. package/abstract/bls.js.map +1 -1
  10. package/abstract/curve.d.ts +10 -2
  11. package/abstract/curve.d.ts.map +1 -1
  12. package/abstract/curve.js +81 -78
  13. package/abstract/curve.js.map +1 -1
  14. package/abstract/edwards.d.ts +2 -2
  15. package/abstract/edwards.d.ts.map +1 -1
  16. package/abstract/edwards.js +55 -69
  17. package/abstract/edwards.js.map +1 -1
  18. package/abstract/hash-to-curve.d.ts +5 -4
  19. package/abstract/hash-to-curve.d.ts.map +1 -1
  20. package/abstract/hash-to-curve.js +20 -18
  21. package/abstract/hash-to-curve.js.map +1 -1
  22. package/abstract/modular.d.ts.map +1 -1
  23. package/abstract/modular.js +9 -9
  24. package/abstract/montgomery.js +12 -12
  25. package/abstract/poseidon.d.ts +1 -1
  26. package/abstract/poseidon.d.ts.map +1 -1
  27. package/abstract/poseidon.js +3 -3
  28. package/abstract/poseidon.js.map +1 -1
  29. package/abstract/tower.d.ts +2 -2
  30. package/abstract/tower.js +13 -13
  31. package/abstract/utils.d.ts +4 -2
  32. package/abstract/utils.d.ts.map +1 -1
  33. package/abstract/utils.js +25 -14
  34. package/abstract/utils.js.map +1 -1
  35. package/abstract/weierstrass.d.ts +19 -6
  36. package/abstract/weierstrass.d.ts.map +1 -1
  37. package/abstract/weierstrass.js +97 -80
  38. package/abstract/weierstrass.js.map +1 -1
  39. package/bls12-381.d.ts +1 -1
  40. package/bls12-381.d.ts.map +1 -1
  41. package/bls12-381.js +48 -49
  42. package/bls12-381.js.map +1 -1
  43. package/bn254.d.ts +2 -2
  44. package/bn254.d.ts.map +1 -1
  45. package/bn254.js +29 -30
  46. package/bn254.js.map +1 -1
  47. package/ed25519.d.ts +8 -6
  48. package/ed25519.d.ts.map +1 -1
  49. package/ed25519.js +65 -66
  50. package/ed25519.js.map +1 -1
  51. package/ed448.d.ts +6 -6
  52. package/ed448.d.ts.map +1 -1
  53. package/ed448.js +50 -52
  54. package/ed448.js.map +1 -1
  55. package/esm/_shortw_utils.d.ts +2 -2
  56. package/esm/_shortw_utils.d.ts.map +1 -1
  57. package/esm/_shortw_utils.js +1 -1
  58. package/esm/_shortw_utils.js.map +1 -1
  59. package/esm/abstract/bls.d.ts +5 -5
  60. package/esm/abstract/bls.d.ts.map +1 -1
  61. package/esm/abstract/bls.js +5 -6
  62. package/esm/abstract/bls.js.map +1 -1
  63. package/esm/abstract/curve.d.ts +10 -2
  64. package/esm/abstract/curve.d.ts.map +1 -1
  65. package/esm/abstract/curve.js +77 -74
  66. package/esm/abstract/curve.js.map +1 -1
  67. package/esm/abstract/edwards.d.ts +2 -2
  68. package/esm/abstract/edwards.d.ts.map +1 -1
  69. package/esm/abstract/edwards.js +36 -50
  70. package/esm/abstract/edwards.js.map +1 -1
  71. package/esm/abstract/hash-to-curve.d.ts +5 -4
  72. package/esm/abstract/hash-to-curve.d.ts.map +1 -1
  73. package/esm/abstract/hash-to-curve.js +4 -2
  74. package/esm/abstract/hash-to-curve.js.map +1 -1
  75. package/esm/abstract/modular.d.ts.map +1 -1
  76. package/esm/abstract/modular.js +1 -1
  77. package/esm/abstract/montgomery.js +2 -2
  78. package/esm/abstract/poseidon.d.ts +1 -1
  79. package/esm/abstract/poseidon.d.ts.map +1 -1
  80. package/esm/abstract/poseidon.js +1 -1
  81. package/esm/abstract/poseidon.js.map +1 -1
  82. package/esm/abstract/tower.d.ts +2 -2
  83. package/esm/abstract/tower.js +5 -5
  84. package/esm/abstract/utils.d.ts +4 -2
  85. package/esm/abstract/utils.d.ts.map +1 -1
  86. package/esm/abstract/utils.js +24 -13
  87. package/esm/abstract/utils.js.map +1 -1
  88. package/esm/abstract/weierstrass.d.ts +19 -6
  89. package/esm/abstract/weierstrass.d.ts.map +1 -1
  90. package/esm/abstract/weierstrass.js +77 -60
  91. package/esm/abstract/weierstrass.js.map +1 -1
  92. package/esm/bls12-381.d.ts +1 -1
  93. package/esm/bls12-381.d.ts.map +1 -1
  94. package/esm/bls12-381.js +16 -17
  95. package/esm/bls12-381.js.map +1 -1
  96. package/esm/bn254.d.ts +2 -2
  97. package/esm/bn254.d.ts.map +1 -1
  98. package/esm/bn254.js +7 -8
  99. package/esm/bn254.js.map +1 -1
  100. package/esm/ed25519.d.ts +8 -6
  101. package/esm/ed25519.d.ts.map +1 -1
  102. package/esm/ed25519.js +20 -21
  103. package/esm/ed25519.js.map +1 -1
  104. package/esm/ed448.d.ts +6 -6
  105. package/esm/ed448.d.ts.map +1 -1
  106. package/esm/ed448.js +13 -15
  107. package/esm/ed448.js.map +1 -1
  108. package/esm/index.js +13 -1
  109. package/esm/index.js.map +1 -1
  110. package/esm/jubjub.d.ts +1 -4
  111. package/esm/jubjub.d.ts.map +1 -1
  112. package/esm/jubjub.js +1 -60
  113. package/esm/jubjub.js.map +1 -1
  114. package/esm/misc.d.ts +15 -0
  115. package/esm/misc.d.ts.map +1 -0
  116. package/esm/misc.js +101 -0
  117. package/esm/misc.js.map +1 -0
  118. package/esm/p256.d.ts +8 -5
  119. package/esm/p256.d.ts.map +1 -1
  120. package/esm/p256.js +13 -12
  121. package/esm/p256.js.map +1 -1
  122. package/esm/p384.d.ts +8 -5
  123. package/esm/p384.d.ts.map +1 -1
  124. package/esm/p384.js +14 -15
  125. package/esm/p384.js.map +1 -1
  126. package/esm/p521.d.ts +6 -5
  127. package/esm/p521.d.ts.map +1 -1
  128. package/esm/p521.js +19 -28
  129. package/esm/p521.js.map +1 -1
  130. package/esm/pasta.d.ts +1 -7
  131. package/esm/pasta.d.ts.map +1 -1
  132. package/esm/pasta.js +1 -33
  133. package/esm/pasta.js.map +1 -1
  134. package/esm/secp256k1.d.ts +15 -10
  135. package/esm/secp256k1.d.ts.map +1 -1
  136. package/esm/secp256k1.js +18 -14
  137. package/esm/secp256k1.js.map +1 -1
  138. package/index.js +13 -1
  139. package/index.js.map +1 -1
  140. package/jubjub.d.ts +1 -4
  141. package/jubjub.d.ts.map +1 -1
  142. package/jubjub.js +5 -63
  143. package/jubjub.js.map +1 -1
  144. package/misc.d.ts +15 -0
  145. package/misc.d.ts.map +1 -0
  146. package/misc.js +106 -0
  147. package/misc.js.map +1 -0
  148. package/p256.d.ts +8 -5
  149. package/p256.d.ts.map +1 -1
  150. package/p256.js +19 -18
  151. package/p256.js.map +1 -1
  152. package/p384.d.ts +8 -5
  153. package/p384.d.ts.map +1 -1
  154. package/p384.js +19 -20
  155. package/p384.js.map +1 -1
  156. package/p521.d.ts +6 -5
  157. package/p521.d.ts.map +1 -1
  158. package/p521.js +23 -32
  159. package/p521.js.map +1 -1
  160. package/package.json +21 -16
  161. package/pasta.d.ts +1 -7
  162. package/pasta.d.ts.map +1 -1
  163. package/pasta.js +4 -34
  164. package/pasta.js.map +1 -1
  165. package/secp256k1.d.ts +15 -10
  166. package/secp256k1.d.ts.map +1 -1
  167. package/secp256k1.js +57 -53
  168. package/secp256k1.js.map +1 -1
  169. package/src/_shortw_utils.ts +2 -2
  170. package/src/abstract/bls.ts +14 -12
  171. package/src/abstract/curve.ts +88 -79
  172. package/src/abstract/edwards.ts +52 -59
  173. package/src/abstract/hash-to-curve.ts +7 -5
  174. package/src/abstract/modular.ts +1 -1
  175. package/src/abstract/montgomery.ts +2 -2
  176. package/src/abstract/poseidon.ts +1 -1
  177. package/src/abstract/tower.ts +6 -6
  178. package/src/abstract/utils.ts +26 -15
  179. package/src/abstract/weierstrass.ts +99 -77
  180. package/src/bls12-381.ts +30 -28
  181. package/src/bn254.ts +11 -13
  182. package/src/ed25519.ts +27 -26
  183. package/src/ed448.ts +21 -20
  184. package/src/index.ts +13 -1
  185. package/src/jubjub.ts +5 -63
  186. package/src/misc.ts +117 -0
  187. package/src/p256.ts +13 -12
  188. package/src/p384.ts +18 -15
  189. package/src/p521.ts +27 -32
  190. package/src/pasta.ts +1 -39
  191. package/src/secp256k1.ts +20 -16
@@ -1,6 +1,19 @@
1
1
  /**
2
2
  * Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
3
3
  *
4
+ * ### Parameters
5
+ *
6
+ * To initialize a weierstrass curve, one needs to pass following params:
7
+ *
8
+ * * a: formula param
9
+ * * b: formula param
10
+ * * Fp: finite Field over which we'll do calculations. Can be complex (Fp2, Fp12)
11
+ * * n: Curve prime subgroup order, total count of valid points in the field
12
+ * * Gx: Base point (x, y) aka generator point x coordinate
13
+ * * Gy: ...y coordinate
14
+ * * h: cofactor, usually 1. h*n = curve group order (n is only subgroup order)
15
+ * * lowS: whether to enable (default) or disable "low-s" non-malleable signatures
16
+ *
4
17
  * ### Design rationale for types
5
18
  *
6
19
  * * Interaction between classes from different curves should fail:
@@ -25,18 +38,23 @@
25
38
  * @module
26
39
  */
27
40
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
41
+ // prettier-ignore
28
42
  import {
29
- AffinePoint,
30
- BasicCurve,
31
- Group,
32
- GroupConstructor,
33
- validateBasic,
34
- wNAF,
35
- pippenger,
36
- } from './curve.js';
37
- import * as mod from './modular.js';
38
- import * as ut from './utils.js';
39
- import { CHash, Hex, PrivKey, ensureBytes, memoized, abool } from './utils.js';
43
+ type AffinePoint, type BasicCurve, type Group, type GroupConstructor,
44
+ pippenger, validateBasic, wNAF,
45
+ } from './curve.ts';
46
+ // prettier-ignore
47
+ import {
48
+ Field, type IField, getMinHashLength, invert, mapHashToField, mod, validateField,
49
+ } from './modular.ts';
50
+ // prettier-ignore
51
+ import {
52
+ type CHash, type Hex, type PrivKey,
53
+ aInRange, abool,
54
+ bitMask,
55
+ bytesToHex, bytesToNumberBE, concatBytes, createHmacDrbg, ensureBytes, hexToBytes,
56
+ inRange, isBytes, memoized, numberToBytesBE, numberToHexUnpadded, validateObject
57
+ } from './utils.ts';
40
58
 
41
59
  export type { AffinePoint };
42
60
  type HmacFnSync = (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
@@ -60,7 +78,7 @@ export type BasicWCurve<T> = BasicCurve<T> & {
60
78
  clearCofactor?: (c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>;
61
79
  };
62
80
 
63
- type Entropy = Hex | boolean;
81
+ export type Entropy = Hex | boolean;
64
82
  export type SignOpts = { lowS?: boolean; extraEntropy?: Entropy; prehash?: boolean };
65
83
  export type VerOpts = { lowS?: boolean; prehash?: boolean; format?: 'compact' | 'der' | undefined };
66
84
 
@@ -111,7 +129,7 @@ export type CurvePointsTypeWithLength<T> = Readonly<
111
129
 
112
130
  function validatePointOpts<T>(curve: CurvePointsType<T>): CurvePointsTypeWithLength<T> {
113
131
  const opts = validateBasic(curve);
114
- ut.validateObject(
132
+ validateObject(
115
133
  opts,
116
134
  {
117
135
  a: 'field',
@@ -151,8 +169,6 @@ export type CurvePointsRes<T> = {
151
169
  isWithinCurveOrder: (num: bigint) => boolean;
152
170
  };
153
171
 
154
- const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
155
-
156
172
  export class DERErr extends Error {
157
173
  constructor(m = '') {
158
174
  super(m);
@@ -195,11 +211,11 @@ export const DER: IDER = {
195
211
  if (tag < 0 || tag > 256) throw new E('tlv.encode: wrong tag');
196
212
  if (data.length & 1) throw new E('tlv.encode: unpadded data');
197
213
  const dataLen = data.length / 2;
198
- const len = ut.numberToHexUnpadded(dataLen);
214
+ const len = numberToHexUnpadded(dataLen);
199
215
  if ((len.length / 2) & 0b1000_0000) throw new E('tlv.encode: long form length too big');
200
216
  // length of length with long form flag
201
- const lenLen = dataLen > 127 ? ut.numberToHexUnpadded((len.length / 2) | 0b1000_0000) : '';
202
- const t = ut.numberToHexUnpadded(tag);
217
+ const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 0b1000_0000) : '';
218
+ const t = numberToHexUnpadded(tag);
203
219
  return t + lenLen + len + data;
204
220
  },
205
221
  // v - value, l - left bytes (unparsed)
@@ -237,7 +253,7 @@ export const DER: IDER = {
237
253
  encode(num: bigint): string {
238
254
  const { Err: E } = DER;
239
255
  if (num < _0n) throw new E('integer: negative integers are not allowed');
240
- let hex = ut.numberToHexUnpadded(num);
256
+ let hex = numberToHexUnpadded(num);
241
257
  // Pad with zero byte if negative flag is present
242
258
  if (Number.parseInt(hex[0], 16) & 0b1000) hex = '00' + hex;
243
259
  if (hex.length & 1) throw new E('unexpected DER parsing assertion: unpadded hex');
@@ -248,14 +264,13 @@ export const DER: IDER = {
248
264
  if (data[0] & 0b1000_0000) throw new E('invalid signature integer: negative');
249
265
  if (data[0] === 0x00 && !(data[1] & 0b1000_0000))
250
266
  throw new E('invalid signature integer: unnecessary leading zero');
251
- return b2n(data);
267
+ return bytesToNumberBE(data);
252
268
  },
253
269
  },
254
270
  toSig(hex: string | Uint8Array): { r: bigint; s: bigint } {
255
271
  // parse DER signature
256
272
  const { Err: E, _int: int, _tlv: tlv } = DER;
257
- const data = typeof hex === 'string' ? h2b(hex) : hex;
258
- ut.abytes(data);
273
+ const data = ensureBytes('signature', hex);
259
274
  const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
260
275
  if (seqLeftBytes.length) throw new E('invalid signature: left bytes after parsing');
261
276
  const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
@@ -279,13 +294,13 @@ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n =
279
294
  export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T> {
280
295
  const CURVE = validatePointOpts(opts);
281
296
  const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
282
- const Fn = mod.Field(CURVE.n, CURVE.nBitLength);
297
+ const Fn = Field(CURVE.n, CURVE.nBitLength);
283
298
 
284
299
  const toBytes =
285
300
  CURVE.toBytes ||
286
301
  ((_c: ProjConstructor<T>, point: ProjPointType<T>, _isCompressed: boolean) => {
287
302
  const a = point.toAffine();
288
- return ut.concatBytes(Uint8Array.from([0x04]), Fp.toBytes(a.x), Fp.toBytes(a.y));
303
+ return concatBytes(Uint8Array.from([0x04]), Fp.toBytes(a.x), Fp.toBytes(a.y));
289
304
  });
290
305
  const fromBytes =
291
306
  CURVE.fromBytes ||
@@ -299,7 +314,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
299
314
  });
300
315
 
301
316
  /**
302
- * y² = x³ + ax + b: Short weierstrass curve formula
317
+ * y² = x³ + ax + b: Short weierstrass curve formula. Takes x, returns y².
303
318
  * @returns y²
304
319
  */
305
320
  function weierstrassEquation(x: T): T {
@@ -317,14 +332,14 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
317
332
 
318
333
  // Valid group elements reside in range 1..n-1
319
334
  function isWithinCurveOrder(num: bigint): boolean {
320
- return ut.inRange(num, _1n, CURVE.n);
335
+ return inRange(num, _1n, CURVE.n);
321
336
  }
322
337
  // Validates if priv key is valid and converts it to bigint.
323
338
  // Supports options allowedPrivateKeyLengths and wrapPrivateKey.
324
339
  function normPrivateKeyToScalar(key: PrivKey): bigint {
325
340
  const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
326
341
  if (lengths && typeof key !== 'bigint') {
327
- if (ut.isBytes(key)) key = ut.bytesToHex(key);
342
+ if (isBytes(key)) key = bytesToHex(key);
328
343
  // Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
329
344
  if (typeof key !== 'string' || !lengths.includes(key.length))
330
345
  throw new Error('invalid private key');
@@ -335,18 +350,18 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
335
350
  num =
336
351
  typeof key === 'bigint'
337
352
  ? key
338
- : ut.bytesToNumberBE(ensureBytes('private key', key, nByteLength));
353
+ : bytesToNumberBE(ensureBytes('private key', key, nByteLength));
339
354
  } catch (error) {
340
355
  throw new Error(
341
356
  'invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key
342
357
  );
343
358
  }
344
- if (wrapPrivateKey) num = mod.mod(num, N); // disabled by default, enabled for BLS
345
- ut.aInRange('private key', num, _1n, N); // num in range [1..N-1]
359
+ if (wrapPrivateKey) num = mod(num, N); // disabled by default, enabled for BLS
360
+ aInRange('private key', num, _1n, N); // num in range [1..N-1]
346
361
  return num;
347
362
  }
348
363
 
349
- function assertPrjPoint(other: unknown) {
364
+ function aprjpoint(other: unknown) {
350
365
  if (!(other instanceof Point)) throw new Error('ProjectivePoint expected');
351
366
  }
352
367
 
@@ -399,15 +414,17 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
399
414
  class Point implements ProjPointType<T> {
400
415
  static readonly BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
401
416
  static readonly ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
417
+ readonly px: T;
418
+ readonly py: T;
419
+ readonly pz: T;
402
420
 
403
- constructor(
404
- readonly px: T,
405
- readonly py: T,
406
- readonly pz: T
407
- ) {
421
+ constructor(px: T, py: T, pz: T) {
408
422
  if (px == null || !Fp.isValid(px)) throw new Error('x required');
409
423
  if (py == null || !Fp.isValid(py)) throw new Error('y required');
410
424
  if (pz == null || !Fp.isValid(pz)) throw new Error('z required');
425
+ this.px = px;
426
+ this.py = py;
427
+ this.pz = pz;
411
428
  Object.freeze(this);
412
429
  }
413
430
 
@@ -481,7 +498,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
481
498
  * Compare one point to another.
482
499
  */
483
500
  equals(other: Point): boolean {
484
- assertPrjPoint(other);
501
+ aprjpoint(other);
485
502
  const { px: X1, py: Y1, pz: Z1 } = this;
486
503
  const { px: X2, py: Y2, pz: Z2 } = other;
487
504
  const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
@@ -544,7 +561,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
544
561
  // https://eprint.iacr.org/2015/1060, algorithm 1
545
562
  // Cost: 12M + 0S + 3*a + 3*b3 + 23add.
546
563
  add(other: Point): Point {
547
- assertPrjPoint(other);
564
+ aprjpoint(other);
548
565
  const { px: X1, py: Y1, pz: Z1 } = this;
549
566
  const { px: X2, py: Y2, pz: Z2 } = other;
550
567
  let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
@@ -611,7 +628,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
611
628
  */
612
629
  multiplyUnsafe(sc: bigint): Point {
613
630
  const { endo, n: N } = CURVE;
614
- ut.aInRange('scalar', sc, _0n, N);
631
+ aInRange('scalar', sc, _0n, N);
615
632
  const I = Point.ZERO;
616
633
  if (sc === _0n) return I;
617
634
  if (this.is0() || sc === _1n) return this;
@@ -649,7 +666,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
649
666
  */
650
667
  multiply(scalar: bigint): Point {
651
668
  const { endo, n: N } = CURVE;
652
- ut.aInRange('scalar', scalar, _1n, N);
669
+ aInRange('scalar', scalar, _1n, N);
653
670
  let point: Point, fake: Point; // Fake point is used to const-time mult
654
671
  if (endo) {
655
672
  const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
@@ -712,7 +729,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T
712
729
 
713
730
  toHex(isCompressed = true): string {
714
731
  abool('isCompressed', isCompressed);
715
- return ut.bytesToHex(this.toRawBytes(isCompressed));
732
+ return bytesToHex(this.toRawBytes(isCompressed));
716
733
  }
717
734
  }
718
735
  const _bits = CURVE.nBitLength;
@@ -769,7 +786,7 @@ function validateOpts(
769
786
  curve: CurveType
770
787
  ): Readonly<CurveType & { nByteLength: number; nBitLength: number }> {
771
788
  const opts = validateBasic(curve);
772
- ut.validateObject(
789
+ validateObject(
773
790
  opts,
774
791
  {
775
792
  hash: 'hash',
@@ -815,10 +832,10 @@ export function weierstrass(curveDef: CurveType): CurveFn {
815
832
  const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
816
833
 
817
834
  function modN(a: bigint) {
818
- return mod.mod(a, CURVE_ORDER);
835
+ return mod(a, CURVE_ORDER);
819
836
  }
820
837
  function invN(a: bigint) {
821
- return mod.invert(a, CURVE_ORDER);
838
+ return invert(a, CURVE_ORDER);
822
839
  }
823
840
 
824
841
  const {
@@ -831,7 +848,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
831
848
  toBytes(_c, point, isCompressed: boolean): Uint8Array {
832
849
  const a = point.toAffine();
833
850
  const x = Fp.toBytes(a.x);
834
- const cat = ut.concatBytes;
851
+ const cat = concatBytes;
835
852
  abool('isCompressed', isCompressed);
836
853
  if (isCompressed) {
837
854
  return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
@@ -845,8 +862,8 @@ export function weierstrass(curveDef: CurveType): CurveFn {
845
862
  const tail = bytes.subarray(1);
846
863
  // this.assertValidity() is done inside of fromHex
847
864
  if (len === compressedLen && (head === 0x02 || head === 0x03)) {
848
- const x = ut.bytesToNumberBE(tail);
849
- if (!ut.inRange(x, _1n, Fp.ORDER)) throw new Error('Point is not on curve');
865
+ const x = bytesToNumberBE(tail);
866
+ if (!inRange(x, _1n, Fp.ORDER)) throw new Error('Point is not on curve');
850
867
  const y2 = weierstrassEquation(x); // y² = x³ + ax + b
851
868
  let y: bigint;
852
869
  try {
@@ -873,8 +890,8 @@ export function weierstrass(curveDef: CurveType): CurveFn {
873
890
  }
874
891
  },
875
892
  });
876
- const numToNByteStr = (num: bigint): string =>
877
- ut.bytesToHex(ut.numberToBytesBE(num, CURVE.nByteLength));
893
+ const numToNByteHex = (num: bigint): string =>
894
+ bytesToHex(numberToBytesBE(num, CURVE.nByteLength));
878
895
 
879
896
  function isBiggerThanHalfOrder(number: bigint) {
880
897
  const HALF = CURVE_ORDER >> _1n;
@@ -885,18 +902,22 @@ export function weierstrass(curveDef: CurveType): CurveFn {
885
902
  return isBiggerThanHalfOrder(s) ? modN(-s) : s;
886
903
  }
887
904
  // slice bytes num
888
- const slcNum = (b: Uint8Array, from: number, to: number) => ut.bytesToNumberBE(b.slice(from, to));
905
+ const slcNum = (b: Uint8Array, from: number, to: number) => bytesToNumberBE(b.slice(from, to));
889
906
 
890
907
  /**
891
908
  * ECDSA signature with its (r, s) properties. Supports DER & compact representations.
892
909
  */
893
910
  class Signature implements SignatureType {
894
- constructor(
895
- readonly r: bigint,
896
- readonly s: bigint,
897
- readonly recovery?: number
898
- ) {
899
- this.assertValidity();
911
+ readonly r: bigint;
912
+ readonly s: bigint;
913
+ readonly recovery?: number;
914
+ constructor(r: bigint, s: bigint, recovery?: number) {
915
+ aInRange('r', r, _1n, CURVE_ORDER); // r in [1..N]
916
+ aInRange('s', s, _1n, CURVE_ORDER); // s in [1..N]
917
+ this.r = r;
918
+ this.s = s;
919
+ if (recovery != null) this.recovery = recovery;
920
+ Object.freeze(this);
900
921
  }
901
922
 
902
923
  // pair (bytes of r, bytes of s)
@@ -913,10 +934,11 @@ export function weierstrass(curveDef: CurveType): CurveFn {
913
934
  return new Signature(r, s);
914
935
  }
915
936
 
916
- assertValidity(): void {
917
- ut.aInRange('r', this.r, _1n, CURVE_ORDER); // r in [1..N]
918
- ut.aInRange('s', this.s, _1n, CURVE_ORDER); // s in [1..N]
919
- }
937
+ /**
938
+ * @todo remove
939
+ * @deprecated
940
+ */
941
+ assertValidity(): void {}
920
942
 
921
943
  addRecoveryBit(recovery: number): RecoveredSignature {
922
944
  return new Signature(this.r, this.s, recovery) as RecoveredSignature;
@@ -929,7 +951,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
929
951
  const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;
930
952
  if (radj >= Fp.ORDER) throw new Error('recovery id 2 or 3 invalid');
931
953
  const prefix = (rec & 1) === 0 ? '02' : '03';
932
- const R = Point.fromHex(prefix + numToNByteStr(radj));
954
+ const R = Point.fromHex(prefix + numToNByteHex(radj));
933
955
  const ir = invN(radj); // r^-1
934
956
  const u1 = modN(-h * ir); // -hr^-1
935
957
  const u2 = modN(s * ir); // sr^-1
@@ -950,7 +972,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
950
972
 
951
973
  // DER-encoded
952
974
  toDERRawBytes() {
953
- return ut.hexToBytes(this.toDERHex());
975
+ return hexToBytes(this.toDERHex());
954
976
  }
955
977
  toDERHex() {
956
978
  return DER.hexFromSig({ r: this.r, s: this.s });
@@ -958,10 +980,10 @@ export function weierstrass(curveDef: CurveType): CurveFn {
958
980
 
959
981
  // padded bytes of r, then padded bytes of s
960
982
  toCompactRawBytes() {
961
- return ut.hexToBytes(this.toCompactHex());
983
+ return hexToBytes(this.toCompactHex());
962
984
  }
963
985
  toCompactHex() {
964
- return numToNByteStr(this.r) + numToNByteStr(this.s);
986
+ return numToNByteHex(this.r) + numToNByteHex(this.s);
965
987
  }
966
988
  }
967
989
  type RecoveredSignature = Signature & { recovery: number };
@@ -982,8 +1004,8 @@ export function weierstrass(curveDef: CurveType): CurveFn {
982
1004
  * (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.
983
1005
  */
984
1006
  randomPrivateKey: (): Uint8Array => {
985
- const length = mod.getMinHashLength(CURVE.n);
986
- return mod.mapHashToField(CURVE.randomBytes(length), CURVE.n);
1007
+ const length = getMinHashLength(CURVE.n);
1008
+ return mapHashToField(CURVE.randomBytes(length), CURVE.n);
987
1009
  },
988
1010
 
989
1011
  /**
@@ -1015,7 +1037,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1015
1037
  * Quick and dirty check for item being public key. Does not validate hex, or being on-curve.
1016
1038
  */
1017
1039
  function isProbPub(item: PrivKey | PubKey): boolean {
1018
- const arr = ut.isBytes(item);
1040
+ const arr = isBytes(item);
1019
1041
  const str = typeof item === 'string';
1020
1042
  const len = (arr || str) && (item as Hex).length;
1021
1043
  if (arr) return len === compressedLen || len === uncompressedLen;
@@ -1052,7 +1074,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1052
1074
  if (bytes.length > 8192) throw new Error('input is too large');
1053
1075
  // For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
1054
1076
  // for some cases, since bytes.length * 8 is not actual bitLength.
1055
- const num = ut.bytesToNumberBE(bytes); // check for == u8 done here
1077
+ const num = bytesToNumberBE(bytes); // check for == u8 done here
1056
1078
  const delta = bytes.length * 8 - CURVE.nBitLength; // truncate to nBitLength leftmost bits
1057
1079
  return delta > 0 ? num >> BigInt(delta) : num;
1058
1080
  };
@@ -1062,14 +1084,14 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1062
1084
  return modN(bits2int(bytes)); // can't use bytesToNumberBE here
1063
1085
  };
1064
1086
  // NOTE: pads output with zero as per spec
1065
- const ORDER_MASK = ut.bitMask(CURVE.nBitLength);
1087
+ const ORDER_MASK = bitMask(CURVE.nBitLength);
1066
1088
  /**
1067
1089
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
1068
1090
  */
1069
1091
  function int2octets(num: bigint): Uint8Array {
1070
- ut.aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
1092
+ aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
1071
1093
  // works with order, can have different size than numToField!
1072
- return ut.numberToBytesBE(num, CURVE.nByteLength);
1094
+ return numberToBytesBE(num, CURVE.nByteLength);
1073
1095
  }
1074
1096
 
1075
1097
  // Steps A, D of RFC6979 3.2
@@ -1099,7 +1121,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1099
1121
  const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is
1100
1122
  seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes
1101
1123
  }
1102
- const seed = ut.concatBytes(...seedArgs); // Step D of RFC6979 3.2
1124
+ const seed = concatBytes(...seedArgs); // Step D of RFC6979 3.2
1103
1125
  const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!
1104
1126
  // Converts signature params into point w r/s, checks result for validity.
1105
1127
  function k2sig(kBytes: Uint8Array): RecoveredSignature | undefined {
@@ -1144,7 +1166,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1144
1166
  function sign(msgHash: Hex, privKey: PrivKey, opts = defaultSigOpts): RecoveredSignature {
1145
1167
  const { seed, k2sig } = prepSig(msgHash, privKey, opts); // Steps A, D of RFC6979 3.2.
1146
1168
  const C = CURVE;
1147
- const drbg = ut.createHmacDrbg<RecoveredSignature>(C.hash.outputLen, C.nByteLength, C.hmac);
1169
+ const drbg = createHmacDrbg<RecoveredSignature>(C.hash.outputLen, C.nByteLength, C.hmac);
1148
1170
  return drbg(seed, k2sig); // Steps B, C, D, E, F, G
1149
1171
  }
1150
1172
 
@@ -1181,7 +1203,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1181
1203
  if ('strict' in opts) throw new Error('options.strict was renamed to lowS');
1182
1204
  if (format !== undefined && format !== 'compact' && format !== 'der')
1183
1205
  throw new Error('format must be compact or der');
1184
- const isHex = typeof sg === 'string' || ut.isBytes(sg);
1206
+ const isHex = typeof sg === 'string' || isBytes(sg);
1185
1207
  const isObj =
1186
1208
  !isHex &&
1187
1209
  !format &&
@@ -1245,7 +1267,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1245
1267
  * @returns
1246
1268
  */
1247
1269
  export function SWUFpSqrtRatio<T>(
1248
- Fp: mod.IField<T>,
1270
+ Fp: IField<T>,
1249
1271
  Z: T
1250
1272
  ): (u: T, v: T) => { isValid: boolean; value: T } {
1251
1273
  // Generic implementation
@@ -1320,14 +1342,14 @@ export function SWUFpSqrtRatio<T>(
1320
1342
  * https://www.rfc-editor.org/rfc/rfc9380#section-6.6.2
1321
1343
  */
1322
1344
  export function mapToCurveSimpleSWU<T>(
1323
- Fp: mod.IField<T>,
1345
+ Fp: IField<T>,
1324
1346
  opts: {
1325
1347
  A: T;
1326
1348
  B: T;
1327
1349
  Z: T;
1328
1350
  }
1329
1351
  ): (u: T) => { x: T; y: T } {
1330
- mod.validateField(Fp);
1352
+ validateField(Fp);
1331
1353
  if (!Fp.isValid(opts.A) || !Fp.isValid(opts.B) || !Fp.isValid(opts.Z))
1332
1354
  throw new Error('mapToCurveSimpleSWU: invalid opts');
1333
1355
  const sqrtRatio = SWUFpSqrtRatio(Fp, opts.Z);
package/src/bls12-381.ts CHANGED
@@ -1,24 +1,3 @@
1
- /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
- import { sha256 } from '@noble/hashes/sha256';
3
- import { randomBytes } from '@noble/hashes/utils';
4
- import { bls, CurveFn } from './abstract/bls.js';
5
- import * as mod from './abstract/modular.js';
6
- import {
7
- bitGet,
8
- bitLen,
9
- bytesToHex,
10
- bytesToNumberBE,
11
- concatBytes as concatB,
12
- ensureBytes,
13
- Hex,
14
- numberToBytesBE,
15
- } from './abstract/utils.js';
16
- // Types
17
- import { isogenyMap } from './abstract/hash-to-curve.js';
18
- import { AffinePoint, mapToCurveSimpleSWU, ProjPointType } from './abstract/weierstrass.js';
19
- import { tower12, psiFrobenius } from './abstract/tower.js';
20
- import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
21
-
22
1
  /**
23
2
  * bls12-381 is pairing-friendly Barreto-Lynn-Scott elliptic curve construction allowing to:
24
3
  * * Construct zk-SNARKs at the ~120-bit security
@@ -50,7 +29,7 @@ import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
50
29
  * 4. Compatible with specs:
51
30
  * [cfrg-pairing-friendly-curves-11](https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-11),
52
31
  * [cfrg-bls-signature-05](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-05),
53
- * [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380).
32
+ * RFC 9380.
54
33
  *
55
34
  * ### Params
56
35
  * To verify curve parameters, see
@@ -58,11 +37,6 @@ import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
58
37
  * Basic math is done over finite fields over p.
59
38
  * More complicated math is done over polynominal extension fields.
60
39
  * To simplify calculations in Fp12, we construct extension tower:
61
- * - Fp₁₂ = Fp₆² => Fp₂³
62
- * - Fp(u) / (u² - β) where β = -1
63
- * - Fp₂(v) / (v³ - ξ) where ξ = u + 1
64
- * - Fp₆(w) / (w² - γ) where γ = v
65
- * Here goes constants && point encoding format
66
40
  *
67
41
  * Embedding degree (k): 12
68
42
  * Seed (X): -15132376222941642752
@@ -73,6 +47,10 @@ import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
73
47
  * Ate loop size: X
74
48
  *
75
49
  * ### Towers
50
+ * - Fp₁₂ = Fp₆² => Fp₂³
51
+ * - Fp(u) / (u² - β) where β = -1
52
+ * - Fp₂(v) / (v³ - ξ) where ξ = u + 1
53
+ * - Fp₆(w) / (w² - γ) where γ = v
76
54
  * - Fp²[u] = Fp/u²+1
77
55
  * - Fp⁶[v] = Fp²/v³-1-u
78
56
  * - Fp¹²[w] = Fp⁶/w²-v
@@ -80,6 +58,30 @@ import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
80
58
  * @todo construct bls & bn fp/fr from seed.
81
59
  * @module
82
60
  */
61
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
62
+ import { sha256 } from '@noble/hashes/sha2';
63
+ import { randomBytes } from '@noble/hashes/utils';
64
+ import { bls, type CurveFn } from './abstract/bls.ts';
65
+ import { Field } from './abstract/modular.ts';
66
+ import {
67
+ bitGet,
68
+ bitLen,
69
+ bytesToHex,
70
+ bytesToNumberBE,
71
+ concatBytes as concatB,
72
+ ensureBytes,
73
+ type Hex,
74
+ numberToBytesBE,
75
+ } from './abstract/utils.ts';
76
+ // Types
77
+ import { isogenyMap } from './abstract/hash-to-curve.ts';
78
+ import type { Fp, Fp12, Fp2, Fp6 } from './abstract/tower.ts';
79
+ import { psiFrobenius, tower12 } from './abstract/tower.ts';
80
+ import {
81
+ type AffinePoint,
82
+ mapToCurveSimpleSWU,
83
+ type ProjPointType,
84
+ } from './abstract/weierstrass.ts';
83
85
 
84
86
  // Be friendly to bad ECMAScript parsers by not using bigint literals
85
87
  // prettier-ignore
@@ -162,7 +164,7 @@ const { Fp, Fp2, Fp6, Fp4Square, Fp12 } = tower12({
162
164
 
163
165
  // Finite field over r.
164
166
  // This particular field is not used anywhere in bls12-381, but it is still useful.
165
- const Fr = mod.Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'));
167
+ const Fr = Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'));
166
168
 
167
169
  // END OF CURVE FIELDS
168
170
 
package/src/bn254.ts CHANGED
@@ -45,24 +45,22 @@ Ate loop size: 6x+2
45
45
  * @module
46
46
  */
47
47
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
48
- import { sha256 } from '@noble/hashes/sha256';
49
- import { getHash } from './_shortw_utils.js';
50
- import { CurveFn, weierstrass } from './abstract/weierstrass.js';
48
+ import { sha256 } from '@noble/hashes/sha2';
51
49
  import { randomBytes } from '@noble/hashes/utils';
50
+ import { getHash } from './_shortw_utils.ts';
52
51
  import {
53
52
  bls,
54
- CurveFn as BLSCurveFn,
55
- PostPrecomputeFn,
56
- PostPrecomputePointAddFn,
57
- } from './abstract/bls.js';
58
- import { Field } from './abstract/modular.js';
59
- import { bitGet, bitLen, notImplemented } from './abstract/utils.js';
60
- import { tower12, psiFrobenius } from './abstract/tower.js';
61
- // Types
62
- import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
53
+ type CurveFn as BLSCurveFn,
54
+ type PostPrecomputeFn,
55
+ type PostPrecomputePointAddFn,
56
+ } from './abstract/bls.ts';
57
+ import { Field } from './abstract/modular.ts';
58
+ import type { Fp, Fp12, Fp2, Fp6 } from './abstract/tower.ts';
59
+ import { psiFrobenius, tower12 } from './abstract/tower.ts';
60
+ import { bitGet, bitLen, notImplemented } from './abstract/utils.ts';
61
+ import { type CurveFn, weierstrass } from './abstract/weierstrass.ts';
63
62
  // prettier-ignore
64
63
  const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
65
- // prettier-ignore
66
64
  const _6n = BigInt(6);
67
65
 
68
66
  const BN_X = BigInt('4965661367192848881');