@noble/curves 0.9.0 → 1.0.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 (97) hide show
  1. package/README.md +197 -99
  2. package/abstract/bls.d.ts +43 -31
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +37 -28
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/edwards.d.ts +6 -2
  7. package/abstract/edwards.d.ts.map +1 -1
  8. package/abstract/edwards.js +37 -26
  9. package/abstract/edwards.js.map +1 -1
  10. package/abstract/hash-to-curve.d.ts +1 -1
  11. package/abstract/hash-to-curve.d.ts.map +1 -1
  12. package/abstract/hash-to-curve.js +3 -2
  13. package/abstract/hash-to-curve.js.map +1 -1
  14. package/abstract/modular.js +1 -1
  15. package/abstract/modular.js.map +1 -1
  16. package/abstract/utils.d.ts.map +1 -1
  17. package/abstract/utils.js +2 -2
  18. package/abstract/utils.js.map +1 -1
  19. package/abstract/weierstrass.d.ts +23 -0
  20. package/abstract/weierstrass.d.ts.map +1 -1
  21. package/abstract/weierstrass.js +44 -31
  22. package/abstract/weierstrass.js.map +1 -1
  23. package/bls12-381.d.ts.map +1 -1
  24. package/bls12-381.js +161 -162
  25. package/bls12-381.js.map +1 -1
  26. package/{bn.d.ts → bn254.d.ts} +1 -1
  27. package/bn254.d.ts.map +1 -0
  28. package/{bn.js → bn254.js} +1 -1
  29. package/bn254.js.map +1 -0
  30. package/ed25519.d.ts +9 -0
  31. package/ed25519.d.ts.map +1 -1
  32. package/ed25519.js +23 -9
  33. package/ed25519.js.map +1 -1
  34. package/ed448.d.ts +9 -0
  35. package/ed448.d.ts.map +1 -1
  36. package/ed448.js +19 -18
  37. package/ed448.js.map +1 -1
  38. package/esm/abstract/bls.js +37 -28
  39. package/esm/abstract/bls.js.map +1 -1
  40. package/esm/abstract/edwards.js +37 -26
  41. package/esm/abstract/edwards.js.map +1 -1
  42. package/esm/abstract/hash-to-curve.js +3 -2
  43. package/esm/abstract/hash-to-curve.js.map +1 -1
  44. package/esm/abstract/modular.js +1 -1
  45. package/esm/abstract/modular.js.map +1 -1
  46. package/esm/abstract/utils.js +2 -2
  47. package/esm/abstract/utils.js.map +1 -1
  48. package/esm/abstract/weierstrass.js +36 -23
  49. package/esm/abstract/weierstrass.js.map +1 -1
  50. package/esm/bls12-381.js +162 -163
  51. package/esm/bls12-381.js.map +1 -1
  52. package/esm/{bn.js → bn254.js} +1 -1
  53. package/esm/bn254.js.map +1 -0
  54. package/esm/ed25519.js +21 -8
  55. package/esm/ed25519.js.map +1 -1
  56. package/esm/ed448.js +17 -17
  57. package/esm/ed448.js.map +1 -1
  58. package/esm/p256.js +5 -6
  59. package/esm/p256.js.map +1 -1
  60. package/esm/p384.js +10 -12
  61. package/esm/p384.js.map +1 -1
  62. package/esm/p521.js +22 -18
  63. package/esm/p521.js.map +1 -1
  64. package/esm/secp256k1.js +1 -1
  65. package/esm/secp256k1.js.map +1 -1
  66. package/p256.d.ts +1 -1
  67. package/p256.d.ts.map +1 -1
  68. package/p256.js +6 -7
  69. package/p256.js.map +1 -1
  70. package/p384.d.ts +1 -1
  71. package/p384.d.ts.map +1 -1
  72. package/p384.js +11 -13
  73. package/p384.js.map +1 -1
  74. package/p521.d.ts +1 -1
  75. package/p521.d.ts.map +1 -1
  76. package/p521.js +23 -19
  77. package/p521.js.map +1 -1
  78. package/package.json +5 -8
  79. package/secp256k1.js +1 -1
  80. package/secp256k1.js.map +1 -1
  81. package/src/abstract/bls.ts +83 -61
  82. package/src/abstract/edwards.ts +49 -24
  83. package/src/abstract/hash-to-curve.ts +4 -3
  84. package/src/abstract/modular.ts +1 -1
  85. package/src/abstract/utils.ts +2 -2
  86. package/src/abstract/weierstrass.ts +36 -23
  87. package/src/bls12-381.ts +252 -171
  88. package/src/ed25519.ts +23 -9
  89. package/src/ed448.ts +18 -17
  90. package/src/p256.ts +15 -19
  91. package/src/p384.ts +17 -21
  92. package/src/p521.ts +34 -22
  93. package/src/secp256k1.ts +1 -1
  94. package/bn.d.ts.map +0 -1
  95. package/bn.js.map +0 -1
  96. package/esm/bn.js.map +0 -1
  97. /package/src/{bn.ts → bn254.ts} +0 -0
package/src/bls12-381.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  //
8
8
  // The library uses G1 for public keys and G2 for signatures. Support for G1 signatures is planned.
9
9
  // Compatible with Algorand, Chia, Dfinity, Ethereum, FIL, Zcash. Matches specs
10
- // [pairing-curves-10](https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-10),
10
+ // [pairing-curves-11](https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-11),
11
11
  // [bls-sigs-04](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04),
12
12
  // [hash-to-curve-12](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-12).
13
13
  //
@@ -27,24 +27,6 @@
27
27
  // - `e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))` - signature aggregation
28
28
  // Filecoin uses little endian byte arrays for private keys -
29
29
  // so ensure to reverse byte order if you'll use it with FIL.
30
- //
31
- // ### Resources
32
- // - [BLS12-381 for the rest of us](https://hackmd.io/@benjaminion/bls12-381)
33
- // - [Key concepts of pairings](https://medium.com/@alonmuroch_65570/bls-signatures-part-2-key-concepts-of-pairings-27a8a9533d0c)
34
- // - Pairing over bls12-381:
35
- // [part 1](https://research.nccgroup.com/2020/07/06/pairing-over-bls12-381-part-1-fields/),
36
- // [part 2](https://research.nccgroup.com/2020/07/13/pairing-over-bls12-381-part-2-curves/),
37
- // [part 3](https://research.nccgroup.com/2020/08/13/pairing-over-bls12-381-part-3-pairing/)
38
- // - [Estimating the bit security of pairing-friendly curves](https://research.nccgroup.com/2022/02/03/estimating-the-bit-security-of-pairing-friendly-curves/)
39
- //
40
- // ### Differences from @noble/bls12-381 1.4
41
- // - PointG1 -> G1.Point
42
- // - PointG2 -> G2.Point
43
- // - PointG2.fromSignature -> Signature.decode
44
- // - PointG2.toSignature -> Signature.encode
45
- // - Fixed Fp2 ORDER
46
- // - Points now have only two coordinates
47
-
48
30
  import { sha256 } from '@noble/hashes/sha256';
49
31
  import { randomBytes } from '@noble/hashes/utils';
50
32
  import { bls, CurveFn } from './abstract/bls.js';
@@ -59,6 +41,7 @@ import {
59
41
  bitGet,
60
42
  Hex,
61
43
  bitMask,
44
+ bytesToHex,
62
45
  } from './abstract/utils.js';
63
46
  // Types
64
47
  import {
@@ -69,16 +52,23 @@ import {
69
52
  } from './abstract/weierstrass.js';
70
53
  import { isogenyMap } from './abstract/hash-to-curve.js';
71
54
 
55
+ // Be friendly to bad ECMAScript parsers by not using bigint literals
56
+ // prettier-ignore
57
+ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
58
+ // prettier-ignore
59
+ const _8n = BigInt(8), _16n = BigInt(16);
60
+
72
61
  // CURVE FIELDS
73
62
  // Finite field over p.
74
- const Fp =
75
- mod.Field(
76
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn
77
- );
63
+ const Fp = mod.Field(
64
+ BigInt(
65
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'
66
+ )
67
+ );
78
68
  type Fp = bigint;
79
69
  // Finite field over r.
80
70
  // This particular field is not used anywhere in bls12-381, but it is still useful.
81
- const Fr = mod.Field(0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n);
71
+ const Fr = mod.Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'));
82
72
 
83
73
  // Fp₂ over complex plane
84
74
  type BigintTuple = [bigint, bigint];
@@ -121,8 +111,9 @@ type Fp2Utils = {
121
111
  // h2q
122
112
  // NOTE: ORDER was wrong!
123
113
  const FP2_ORDER =
124
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn **
125
- 2n;
114
+ BigInt(
115
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'
116
+ ) ** _2n;
126
117
 
127
118
  const Fp2: mod.IField<Fp2> & Fp2Utils = {
128
119
  ORDER: FP2_ORDER,
@@ -175,7 +166,7 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
175
166
  // https://github.com/zkcrypto/bls12_381/blob/080eaa74ec0e394377caa1ba302c8c121df08b07/src/fp2.rs#L250
176
167
  // https://github.com/supranational/blst/blob/aae0c7d70b799ac269ff5edf29d8191dbd357876/src/exp2.c#L1
177
168
  // Inspired by https://github.com/dalek-cryptography/curve25519-dalek/blob/17698df9d4c834204f83a3574143abacb4fc81a5/src/field.rs#L99
178
- const candidateSqrt = Fp2.pow(num, (Fp2.ORDER + 8n) / 16n);
169
+ const candidateSqrt = Fp2.pow(num, (Fp2.ORDER + _8n) / _16n);
179
170
  const check = Fp2.div(Fp2.sqr(candidateSqrt), num); // candidateSqrt.square().div(this);
180
171
  const R = FP2_ROOTS_OF_UNITY;
181
172
  const divisor = [R[0], R[2], R[4], R[6]].find((r) => Fp2.eql(r, check));
@@ -193,10 +184,10 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
193
184
  // Same as sgn0_fp2 in draft-irtf-cfrg-hash-to-curve-16
194
185
  isOdd: (x: Fp2) => {
195
186
  const { re: x0, im: x1 } = Fp2.reim(x);
196
- const sign_0 = x0 % 2n;
197
- const zero_0 = x0 === 0n;
198
- const sign_1 = x1 % 2n;
199
- return BigInt(sign_0 || (zero_0 && sign_1)) == 1n;
187
+ const sign_0 = x0 % _2n;
188
+ const zero_0 = x0 === _0n;
189
+ const sign_1 = x1 % _2n;
190
+ return BigInt(sign_0 || (zero_0 && sign_1)) == _1n;
200
191
  },
201
192
  // Bytes util
202
193
  fromBytes(b: Uint8Array): Fp2 {
@@ -216,8 +207,8 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
216
207
  // multiply by u + 1
217
208
  mulByNonresidue: ({ c0, c1 }) => ({ c0: Fp.sub(c0, c1), c1: Fp.add(c0, c1) }),
218
209
  multiplyByB: ({ c0, c1 }) => {
219
- let t0 = Fp.mul(c0, 4n); // 4 * c0
220
- let t1 = Fp.mul(c1, 4n); // 4 * c1
210
+ let t0 = Fp.mul(c0, _4n); // 4 * c0
211
+ let t1 = Fp.mul(c1, _4n); // 4 * c1
221
212
  // (T0-T1) + (T0+T1)*i
222
213
  return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
223
214
  },
@@ -234,33 +225,36 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
234
225
  // Finite extension field over irreducible polynominal.
235
226
  // Fp(u) / (u² - β) where β = -1
236
227
  const FP2_FROBENIUS_COEFFICIENTS = [
237
- 0x1n,
238
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
228
+ BigInt('0x1'),
229
+ BigInt(
230
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
231
+ ),
239
232
  ].map((item) => Fp.create(item));
240
233
 
241
234
  // For Fp2 roots of unity.
242
- const rv1 =
243
- 0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n;
235
+ const rv1 = BigInt(
236
+ '0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
237
+ );
244
238
  // const ev1 =
245
- // 0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90n;
239
+ // BigInt('0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90');
246
240
  // const ev2 =
247
- // 0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5n;
241
+ // BigInt('0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5');
248
242
  // const ev3 =
249
- // 0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17n;
243
+ // BigInt('0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17');
250
244
  // const ev4 =
251
- // 0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1n;
245
+ // BigInt('0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1');
252
246
 
253
247
  // Eighth roots of unity, used for computing square roots in Fp2.
254
248
  // To verify or re-calculate:
255
249
  // Array(8).fill(new Fp2([1n, 1n])).map((fp2, k) => fp2.pow(Fp2.ORDER * BigInt(k) / 8n))
256
250
  const FP2_ROOTS_OF_UNITY = [
257
- [1n, 0n],
251
+ [_1n, _0n],
258
252
  [rv1, -rv1],
259
- [0n, 1n],
253
+ [_0n, _1n],
260
254
  [rv1, rv1],
261
- [-1n, 0n],
255
+ [-_1n, _0n],
262
256
  [-rv1, rv1],
263
- [0n, -1n],
257
+ [_0n, -_1n],
264
258
  [-rv1, -rv1],
265
259
  ].map((pair) => Fp2.fromBigTuple(pair));
266
260
  // eta values, used for computing sqrt(g(X1(t)))
@@ -314,8 +308,8 @@ const Fp6Multiply = ({ c0, c1, c2 }: Fp6, rhs: Fp6 | bigint) => {
314
308
  };
315
309
  const Fp6Square = ({ c0, c1, c2 }: Fp6) => {
316
310
  let t0 = Fp2.sqr(c0); // c0²
317
- let t1 = Fp2.mul(Fp2.mul(c0, c1), 2n); // 2 * c0 * c1
318
- let t3 = Fp2.mul(Fp2.mul(c1, c2), 2n); // 2 * c1 * c2
311
+ let t1 = Fp2.mul(Fp2.mul(c0, c1), _2n); // 2 * c0 * c1
312
+ let t3 = Fp2.mul(Fp2.mul(c1, c2), _2n); // 2 * c1 * c2
319
313
  let t4 = Fp2.sqr(c2); // c2²
320
314
  return {
321
315
  c0: Fp2.add(Fp2.mulByNonresidue(t3), t0), // T3 * (u + 1) + T0
@@ -440,46 +434,64 @@ const Fp6: mod.IField<Fp6> & Fp6Utils = {
440
434
  };
441
435
 
442
436
  const FP6_FROBENIUS_COEFFICIENTS_1 = [
443
- [0x1n, 0x0n],
437
+ [BigInt('0x1'), BigInt('0x0')],
444
438
  [
445
- 0x0n,
446
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
439
+ BigInt('0x0'),
440
+ BigInt(
441
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
442
+ ),
447
443
  ],
448
444
  [
449
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
450
- 0x0n,
445
+ BigInt(
446
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
447
+ ),
448
+ BigInt('0x0'),
451
449
  ],
452
- [0x0n, 0x1n],
450
+ [BigInt('0x0'), BigInt('0x1')],
453
451
  [
454
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
455
- 0x0n,
452
+ BigInt(
453
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
454
+ ),
455
+ BigInt('0x0'),
456
456
  ],
457
457
  [
458
- 0x0n,
459
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
458
+ BigInt('0x0'),
459
+ BigInt(
460
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
461
+ ),
460
462
  ],
461
463
  ].map((pair) => Fp2.fromBigTuple(pair));
462
464
  const FP6_FROBENIUS_COEFFICIENTS_2 = [
463
- [0x1n, 0x0n],
465
+ [BigInt('0x1'), BigInt('0x0')],
464
466
  [
465
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaadn,
466
- 0x0n,
467
+ BigInt(
468
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'
469
+ ),
470
+ BigInt('0x0'),
467
471
  ],
468
472
  [
469
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
470
- 0x0n,
473
+ BigInt(
474
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
475
+ ),
476
+ BigInt('0x0'),
471
477
  ],
472
478
  [
473
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
474
- 0x0n,
479
+ BigInt(
480
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
481
+ ),
482
+ BigInt('0x0'),
475
483
  ],
476
484
  [
477
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
478
- 0x0n,
485
+ BigInt(
486
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
487
+ ),
488
+ BigInt('0x0'),
479
489
  ],
480
490
  [
481
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffffn,
482
- 0x0n,
491
+ BigInt(
492
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'
493
+ ),
494
+ BigInt('0x0'),
483
495
  ],
484
496
  ].map((pair) => Fp2.fromBigTuple(pair));
485
497
 
@@ -488,7 +500,7 @@ const FP6_FROBENIUS_COEFFICIENTS_2 = [
488
500
  // Fp₆(w) / (w² - γ) where γ = v
489
501
  type Fp12 = { c0: Fp6; c1: Fp6 };
490
502
  // The BLS parameter x for BLS12-381
491
- const BLS_X = 0xd201000000010000n;
503
+ const BLS_X = BigInt('0xd201000000010000');
492
504
  const BLS_X_LEN = bitLen(BLS_X);
493
505
 
494
506
  // prettier-ignore
@@ -646,14 +658,14 @@ const Fp12: mod.IField<Fp12> & Fp12Utils = {
646
658
  let t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
647
659
  return {
648
660
  c0: Fp6.create({
649
- c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), 2n), t3), // 2 * (T3 - c0c0) + T3
650
- c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), 2n), t5), // 2 * (T5 - c0c1) + T5
651
- c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), 2n), t7),
661
+ c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3), // 2 * (T3 - c0c0) + T3
662
+ c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), _2n), t5), // 2 * (T5 - c0c1) + T5
663
+ c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), _2n), t7),
652
664
  }), // 2 * (T7 - c0c2) + T7
653
665
  c1: Fp6.create({
654
- c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), 2n), t9), // 2 * (T9 + c1c0) + T9
655
- c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), 2n), t4), // 2 * (T4 + c1c1) + T4
656
- c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), 2n), t6),
666
+ c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), _2n), t9), // 2 * (T9 + c1c0) + T9
667
+ c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), _2n), t4), // 2 * (T4 + c1c1) + T4
668
+ c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), _2n), t6),
657
669
  }),
658
670
  }; // 2 * (T6 + c1c2) + T6
659
671
  },
@@ -688,50 +700,84 @@ const Fp12: mod.IField<Fp12> & Fp12Utils = {
688
700
  },
689
701
  };
690
702
  const FP12_FROBENIUS_COEFFICIENTS = [
691
- [0x1n, 0x0n],
703
+ [BigInt('0x1'), BigInt('0x0')],
692
704
  [
693
- 0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8n,
694
- 0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3n,
705
+ BigInt(
706
+ '0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'
707
+ ),
708
+ BigInt(
709
+ '0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'
710
+ ),
695
711
  ],
696
712
  [
697
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffffn,
698
- 0x0n,
713
+ BigInt(
714
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'
715
+ ),
716
+ BigInt('0x0'),
699
717
  ],
700
718
  [
701
- 0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2n,
702
- 0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
719
+ BigInt(
720
+ '0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'
721
+ ),
722
+ BigInt(
723
+ '0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
724
+ ),
703
725
  ],
704
726
  [
705
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
706
- 0x0n,
727
+ BigInt(
728
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
729
+ ),
730
+ BigInt('0x0'),
707
731
  ],
708
732
  [
709
- 0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995n,
710
- 0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116n,
733
+ BigInt(
734
+ '0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'
735
+ ),
736
+ BigInt(
737
+ '0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'
738
+ ),
711
739
  ],
712
740
  [
713
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
714
- 0x0n,
741
+ BigInt(
742
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
743
+ ),
744
+ BigInt('0x0'),
715
745
  ],
716
746
  [
717
- 0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3n,
718
- 0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8n,
747
+ BigInt(
748
+ '0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'
749
+ ),
750
+ BigInt(
751
+ '0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'
752
+ ),
719
753
  ],
720
754
  [
721
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
722
- 0x0n,
755
+ BigInt(
756
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
757
+ ),
758
+ BigInt('0x0'),
723
759
  ],
724
760
  [
725
- 0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
726
- 0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2n,
761
+ BigInt(
762
+ '0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
763
+ ),
764
+ BigInt(
765
+ '0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'
766
+ ),
727
767
  ],
728
768
  [
729
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaadn,
730
- 0x0n,
769
+ BigInt(
770
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'
771
+ ),
772
+ BigInt('0x0'),
731
773
  ],
732
774
  [
733
- 0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116n,
734
- 0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995n,
775
+ BigInt(
776
+ '0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'
777
+ ),
778
+ BigInt(
779
+ '0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'
780
+ ),
735
781
  ],
736
782
  ].map((n) => Fp2.fromBigTuple(n));
737
783
  // END OF CURVE FIELDS
@@ -887,19 +933,23 @@ const isogenyMapG1 = isogenyMap(
887
933
 
888
934
  // SWU Map - Fp2 to G2': y² = x³ + 240i * x + 1012 + 1012i
889
935
  const G2_SWU = mapToCurveSimpleSWU(Fp2, {
890
- A: Fp2.create({ c0: Fp.create(0n), c1: Fp.create(240n) }), // A' = 240 * I
891
- B: Fp2.create({ c0: Fp.create(1012n), c1: Fp.create(1012n) }), // B' = 1012 * (1 + I)
892
- Z: Fp2.create({ c0: Fp.create(-2n), c1: Fp.create(-1n) }), // Z: -(2 + I)
936
+ A: Fp2.create({ c0: Fp.create(_0n), c1: Fp.create(BigInt(240)) }), // A' = 240 * I
937
+ B: Fp2.create({ c0: Fp.create(BigInt(1012)), c1: Fp.create(BigInt(1012)) }), // B' = 1012 * (1 + I)
938
+ Z: Fp2.create({ c0: Fp.create(BigInt(-2)), c1: Fp.create(BigInt(-1)) }), // Z: -(2 + I)
893
939
  });
894
940
  // Optimized SWU Map - Fp to G1
895
941
  const G1_SWU = mapToCurveSimpleSWU(Fp, {
896
942
  A: Fp.create(
897
- 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1dn
943
+ BigInt(
944
+ '0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d'
945
+ )
898
946
  ),
899
947
  B: Fp.create(
900
- 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0n
948
+ BigInt(
949
+ '0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0'
950
+ )
901
951
  ),
902
- Z: Fp.create(11n),
952
+ Z: Fp.create(BigInt(11)),
903
953
  });
904
954
 
905
955
  // Endomorphisms (for fast cofactor clearing)
@@ -922,8 +972,9 @@ function G2psi(c: ProjConstructor<Fp2>, P: ProjPointType<Fp2>) {
922
972
  }
923
973
  // Ψ²(P) endomorphism
924
974
  // 1 / F2(2)^((p-1)/3) in GF(p²)
925
- const PSI2_C1 =
926
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn;
975
+ const PSI2_C1 = BigInt(
976
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
977
+ );
927
978
 
928
979
  function psi2(x: Fp2, y: Fp2): [Fp2, Fp2] {
929
980
  return [Fp2.mul(x, PSI2_C1), Fp2.neg(y)];
@@ -974,7 +1025,23 @@ const C_BIT_POS = Fp.BITS; // C_bit, compression bit for serialization flag
974
1025
  const I_BIT_POS = Fp.BITS + 1; // I_bit, point-at-infinity bit for serialization flag
975
1026
  const S_BIT_POS = Fp.BITS + 2; // S_bit, sign bit for serialization flag
976
1027
  // Compressed point of infinity
977
- const COMPRESSED_ZERO = Fp.toBytes(bitSet(bitSet(0n, I_BIT_POS, true), S_BIT_POS, true)); // set compressed & point-at-infinity bits
1028
+ const COMPRESSED_ZERO = Fp.toBytes(bitSet(bitSet(_0n, I_BIT_POS, true), S_BIT_POS, true)); // set compressed & point-at-infinity bits
1029
+
1030
+ function signatureG2ToRawBytes(point: ProjPointType<Fp2>) {
1031
+ // NOTE: by some reasons it was missed in bls12-381, looks like bug
1032
+ point.assertValidity();
1033
+ const len = Fp.BYTES;
1034
+ if (point.equals(bls12_381.G2.ProjectivePoint.ZERO))
1035
+ return concatB(COMPRESSED_ZERO, numberToBytesBE(_0n, len));
1036
+ const { x, y } = point.toAffine();
1037
+ const { re: x0, im: x1 } = Fp2.reim(x);
1038
+ const { re: y0, im: y1 } = Fp2.reim(y);
1039
+ const tmp = y1 > _0n ? y1 * _2n : y0 * _2n;
1040
+ const aflag1 = Boolean((tmp / Fp.ORDER) & _1n);
1041
+ const z1 = bitSet(bitSet(x1, 381, aflag1), S_BIT_POS, true);
1042
+ const z2 = x0;
1043
+ return concatB(numberToBytesBE(z1, len), numberToBytesBE(z2, len));
1044
+ }
978
1045
 
979
1046
  // To verify curve parameters, see pairing-friendly-curves spec:
980
1047
  // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09
@@ -988,26 +1055,30 @@ const COMPRESSED_ZERO = Fp.toBytes(bitSet(bitSet(0n, I_BIT_POS, true), S_BIT_POS
988
1055
  // Here goes constants && point encoding format
989
1056
  export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
990
1057
  // Fields
991
- Fr,
992
- Fp,
993
- Fp2,
994
- Fp6,
995
- Fp12,
996
- // order; z⁴ − z² + 1
997
- r: Fr.ORDER, // Same as N in other curves
1058
+ fields: {
1059
+ Fp,
1060
+ Fp2,
1061
+ Fp6,
1062
+ Fp12,
1063
+ Fr,
1064
+ },
998
1065
  // G1 is the order-q subgroup of E1(Fp) : y² = x³ + 4, #E1(Fp) = h1q, where
999
1066
  // characteristic; z + (z⁴ - z² + 1)(z - 1)²/3
1000
1067
  G1: {
1001
1068
  Fp,
1002
1069
  // cofactor; (z - 1)²/3
1003
- h: 0x396c8c005555e1568c00aaab0000aaabn,
1070
+ h: BigInt('0x396c8c005555e1568c00aaab0000aaab'),
1004
1071
  // generator's coordinates
1005
1072
  // x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
1006
1073
  // y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
1007
- Gx: 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bbn,
1008
- Gy: 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1n,
1074
+ Gx: BigInt(
1075
+ '0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb'
1076
+ ),
1077
+ Gy: BigInt(
1078
+ '0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1'
1079
+ ),
1009
1080
  a: Fp.ZERO,
1010
- b: 4n,
1081
+ b: _4n,
1011
1082
  htfDefaults: { ...htfDefaults, m: 1 },
1012
1083
  wrapPrivateKey: true,
1013
1084
  allowInfinityPoint: true,
@@ -1017,18 +1088,19 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1017
1088
  // https://eprint.iacr.org/2021/1130.pdf
1018
1089
  isTorsionFree: (c, point): boolean => {
1019
1090
  // φ endomorphism
1020
- const cubicRootOfUnityModP =
1021
- 0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen;
1091
+ const cubicRootOfUnityModP = BigInt(
1092
+ '0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
1093
+ );
1022
1094
  const phi = new c(Fp.mul(point.px, cubicRootOfUnityModP), point.py, point.pz);
1023
1095
 
1024
1096
  // todo: unroll
1025
- const xP = point.multiplyUnsafe(bls12_381.CURVE.x).negate(); // [x]P
1026
- const u2P = xP.multiplyUnsafe(bls12_381.CURVE.x); // [u2]P
1097
+ const xP = point.multiplyUnsafe(bls12_381.params.x).negate(); // [x]P
1098
+ const u2P = xP.multiplyUnsafe(bls12_381.params.x); // [u2]P
1027
1099
  return u2P.equals(phi);
1028
1100
 
1029
1101
  // https://eprint.iacr.org/2019/814.pdf
1030
1102
  // (z² − 1)/3
1031
- // const c1 = 0x396c8c005555e1560000000055555555n;
1103
+ // const c1 = BigInt('0x396c8c005555e1560000000055555555');
1032
1104
  // const P = this;
1033
1105
  // const S = P.sigma();
1034
1106
  // const Q = S.double();
@@ -1042,31 +1114,33 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1042
1114
  // https://eprint.iacr.org/2019/403
1043
1115
  clearCofactor: (c, point) => {
1044
1116
  // return this.multiplyUnsafe(CURVE.h);
1045
- return point.multiplyUnsafe(bls12_381.CURVE.x).add(point); // x*P + P
1117
+ return point.multiplyUnsafe(bls12_381.params.x).add(point); // x*P + P
1046
1118
  },
1047
1119
  mapToCurve: (scalars: bigint[]) => {
1048
1120
  const { x, y } = G1_SWU(Fp.create(scalars[0]));
1049
1121
  return isogenyMapG1(x, y);
1050
1122
  },
1051
1123
  fromBytes: (bytes: Uint8Array): AffinePoint<Fp> => {
1124
+ bytes = bytes.slice();
1052
1125
  if (bytes.length === 48) {
1126
+ // TODO: Fp.bytes
1053
1127
  const P = Fp.ORDER;
1054
1128
  const compressedValue = bytesToNumberBE(bytes);
1055
1129
  const bflag = bitGet(compressedValue, I_BIT_POS);
1056
1130
  // Zero
1057
- if (bflag === 1n) return { x: 0n, y: 0n };
1131
+ if (bflag === _1n) return { x: _0n, y: _0n };
1058
1132
  const x = Fp.create(compressedValue & Fp.MASK);
1059
- const right = Fp.add(Fp.pow(x, 3n), Fp.create(bls12_381.CURVE.G1.b)); // y² = x³ + b
1133
+ const right = Fp.add(Fp.pow(x, _3n), Fp.create(bls12_381.params.G1b)); // y² = x³ + b
1060
1134
  let y = Fp.sqrt(right);
1061
1135
  if (!y) throw new Error('Invalid compressed G1 point');
1062
1136
  const aflag = bitGet(compressedValue, C_BIT_POS);
1063
- if ((y * 2n) / P !== aflag) y = Fp.neg(y);
1137
+ if ((y * _2n) / P !== aflag) y = Fp.neg(y);
1064
1138
  return { x: Fp.create(x), y: Fp.create(y) };
1065
1139
  } else if (bytes.length === 96) {
1066
1140
  // Check if the infinity flag is set
1067
1141
  if ((bytes[0] & (1 << 6)) !== 0) return bls12_381.G1.ProjectivePoint.ZERO.toAffine();
1068
- const x = bytesToNumberBE(bytes.slice(0, Fp.BYTES));
1069
- const y = bytesToNumberBE(bytes.slice(Fp.BYTES));
1142
+ const x = bytesToNumberBE(bytes.subarray(0, Fp.BYTES));
1143
+ const y = bytesToNumberBE(bytes.subarray(Fp.BYTES));
1070
1144
  return { x: Fp.create(x), y: Fp.create(y) };
1071
1145
  } else {
1072
1146
  throw new Error('Invalid point G1, expected 48/96 bytes');
@@ -1079,7 +1153,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1079
1153
  if (isZero) return COMPRESSED_ZERO.slice();
1080
1154
  const P = Fp.ORDER;
1081
1155
  let num;
1082
- num = bitSet(x, C_BIT_POS, Boolean((y * 2n) / P)); // set aflag
1156
+ num = bitSet(x, C_BIT_POS, Boolean((y * _2n) / P)); // set aflag
1083
1157
  num = bitSet(num, S_BIT_POS, true);
1084
1158
  return numberToBytesBE(num, Fp.BYTES);
1085
1159
  } else {
@@ -1100,21 +1174,33 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1100
1174
  G2: {
1101
1175
  Fp: Fp2,
1102
1176
  // cofactor
1103
- h: 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5n,
1177
+ h: BigInt(
1178
+ '0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5'
1179
+ ),
1104
1180
  Gx: Fp2.fromBigTuple([
1105
- 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8n,
1106
- 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7en,
1181
+ BigInt(
1182
+ '0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8'
1183
+ ),
1184
+ BigInt(
1185
+ '0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e'
1186
+ ),
1107
1187
  ]),
1108
1188
  // y =
1109
1189
  // 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582,
1110
1190
  // 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
1111
1191
  Gy: Fp2.fromBigTuple([
1112
- 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801n,
1113
- 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79ben,
1192
+ BigInt(
1193
+ '0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801'
1194
+ ),
1195
+ BigInt(
1196
+ '0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be'
1197
+ ),
1114
1198
  ]),
1115
1199
  a: Fp2.ZERO,
1116
- b: Fp2.fromBigTuple([4n, 4n]),
1117
- hEff: 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551n,
1200
+ b: Fp2.fromBigTuple([4n, _4n]),
1201
+ hEff: BigInt(
1202
+ '0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551'
1203
+ ),
1118
1204
  htfDefaults: { ...htfDefaults },
1119
1205
  wrapPrivateKey: true,
1120
1206
  allowInfinityPoint: true,
@@ -1127,7 +1213,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1127
1213
  // It returns false for shitty points.
1128
1214
  // https://eprint.iacr.org/2021/1130.pdf
1129
1215
  isTorsionFree: (c, P): boolean => {
1130
- return P.multiplyUnsafe(bls12_381.CURVE.x).negate().equals(G2psi(c, P)); // ψ(P) == [u](P)
1216
+ return P.multiplyUnsafe(bls12_381.params.x).negate().equals(G2psi(c, P)); // ψ(P) == [u](P)
1131
1217
  // Older version: https://eprint.iacr.org/2019/814.pdf
1132
1218
  // Ψ²(P) => Ψ³(P) => [z]Ψ³(P) where z = -x => [z]Ψ³(P) - Ψ²(P) + P == O
1133
1219
  // return P.psi2().psi().mulNegX().subtract(psi2).add(P).isZero();
@@ -1137,7 +1223,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1137
1223
  // https://eprint.iacr.org/2017/419.pdf
1138
1224
  // prettier-ignore
1139
1225
  clearCofactor: (c, P) => {
1140
- const { x } = bls12_381.CURVE;
1226
+ const x = bls12_381.params.x;
1141
1227
  let t1 = P.multiplyUnsafe(x).negate(); // [-x]P
1142
1228
  let t2 = G2psi(c, P); // Ψ(P)
1143
1229
  let t3 = P.double(); // 2P
@@ -1151,6 +1237,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1151
1237
  return Q; // [x²-x-1]P + [x-1]Ψ(P) + Ψ²(2P)
1152
1238
  },
1153
1239
  fromBytes: (bytes: Uint8Array): AffinePoint<Fp2> => {
1240
+ bytes = bytes.slice();
1154
1241
  const m_byte = bytes[0] & 0xe0;
1155
1242
  if (m_byte === 0x20 || m_byte === 0x60 || m_byte === 0xe0) {
1156
1243
  throw new Error('Invalid encoding flag: ' + m_byte);
@@ -1161,7 +1248,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1161
1248
  const L = Fp.BYTES;
1162
1249
  const slc = (b: Uint8Array, from: number, to?: number) => bytesToNumberBE(b.slice(from, to));
1163
1250
  if (bytes.length === 96 && bitC) {
1164
- const { b } = bls12_381.CURVE.G2;
1251
+ const b = bls12_381.params.G2b;
1165
1252
  const P = Fp.ORDER;
1166
1253
 
1167
1254
  bytes[0] = bytes[0] & 0x1f; // clear flags
@@ -1175,9 +1262,9 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1175
1262
  const x_1 = slc(bytes, 0, L);
1176
1263
  const x_0 = slc(bytes, L, 2 * L);
1177
1264
  const x = Fp2.create({ c0: Fp.create(x_0), c1: Fp.create(x_1) });
1178
- const right = Fp2.add(Fp2.pow(x, 3n), b); // y² = x³ + 4 * (u+1) = x³ + b
1265
+ const right = Fp2.add(Fp2.pow(x, _3n), b); // y² = x³ + 4 * (u+1) = x³ + b
1179
1266
  let y = Fp2.sqrt(right);
1180
- const Y_bit = y.c1 === 0n ? (y.c0 * 2n) / P : (y.c1 * 2n) / P ? 1n : 0n;
1267
+ const Y_bit = y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P ? _1n : _0n;
1181
1268
  y = bitS > 0 && Y_bit > 0 ? y : Fp2.neg(y);
1182
1269
  return { x, y };
1183
1270
  } else if (bytes.length === 192 && !bitC) {
@@ -1195,31 +1282,31 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1195
1282
  }
1196
1283
  },
1197
1284
  toBytes: (c, point, isCompressed) => {
1285
+ const { BYTES: len, ORDER: P } = Fp;
1198
1286
  const isZero = point.equals(c.ZERO);
1199
1287
  const { x, y } = point.toAffine();
1200
1288
  if (isCompressed) {
1201
- const P = Fp.ORDER;
1202
- if (isZero) return concatB(COMPRESSED_ZERO, numberToBytesBE(0n, Fp.BYTES));
1203
- const flag = Boolean(y.c1 === 0n ? (y.c0 * 2n) / P : (y.c1 * 2n) / P);
1289
+ if (isZero) return concatB(COMPRESSED_ZERO, numberToBytesBE(_0n, len));
1290
+ const flag = Boolean(y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P);
1204
1291
  // set compressed & sign bits (looks like different offsets than for G1/Fp?)
1205
1292
  let x_1 = bitSet(x.c1, C_BIT_POS, flag);
1206
1293
  x_1 = bitSet(x_1, S_BIT_POS, true);
1207
- return concatB(numberToBytesBE(x_1, Fp.BYTES), numberToBytesBE(x.c0, Fp.BYTES));
1294
+ return concatB(numberToBytesBE(x_1, len), numberToBytesBE(x.c0, len));
1208
1295
  } else {
1209
- if (isZero) return concatB(new Uint8Array([0x40]), new Uint8Array(4 * Fp.BYTES - 1)); // bytes[0] |= 1 << 6;
1296
+ if (isZero) return concatB(new Uint8Array([0x40]), new Uint8Array(4 * len - 1)); // bytes[0] |= 1 << 6;
1210
1297
  const { re: x0, im: x1 } = Fp2.reim(x);
1211
1298
  const { re: y0, im: y1 } = Fp2.reim(y);
1212
1299
  return concatB(
1213
- numberToBytesBE(x1, Fp.BYTES),
1214
- numberToBytesBE(x0, Fp.BYTES),
1215
- numberToBytesBE(y1, Fp.BYTES),
1216
- numberToBytesBE(y0, Fp.BYTES)
1300
+ numberToBytesBE(x1, len),
1301
+ numberToBytesBE(x0, len),
1302
+ numberToBytesBE(y1, len),
1303
+ numberToBytesBE(y0, len)
1217
1304
  );
1218
1305
  }
1219
1306
  },
1220
1307
  Signature: {
1221
1308
  // TODO: Optimize, it's very slow because of sqrt.
1222
- decode(hex: Hex): ProjPointType<Fp2> {
1309
+ fromHex(hex: Hex): ProjPointType<Fp2> {
1223
1310
  hex = ensureBytes('signatureHex', hex);
1224
1311
  const P = Fp.ORDER;
1225
1312
  const half = hex.length / 2;
@@ -1229,12 +1316,12 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1229
1316
  const z2 = bytesToNumberBE(hex.slice(half));
1230
1317
  // Indicates the infinity point
1231
1318
  const bflag1 = bitGet(z1, I_BIT_POS);
1232
- if (bflag1 === 1n) return bls12_381.G2.ProjectivePoint.ZERO;
1319
+ if (bflag1 === _1n) return bls12_381.G2.ProjectivePoint.ZERO;
1233
1320
 
1234
1321
  const x1 = Fp.create(z1 & Fp.MASK);
1235
1322
  const x2 = Fp.create(z2);
1236
1323
  const x = Fp2.create({ c0: x2, c1: x1 });
1237
- const y2 = Fp2.add(Fp2.pow(x, 3n), bls12_381.CURVE.G2.b); // y² = x³ + 4
1324
+ const y2 = Fp2.add(Fp2.pow(x, _3n), bls12_381.params.G2b); // y² = x³ + 4
1238
1325
  // The slow part
1239
1326
  let y = Fp2.sqrt(y2);
1240
1327
  if (!y) throw new Error('Failed to find a square root');
@@ -1243,31 +1330,25 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1243
1330
  // If y1 happens to be zero, then use the bit of y0
1244
1331
  const { re: y0, im: y1 } = Fp2.reim(y);
1245
1332
  const aflag1 = bitGet(z1, 381);
1246
- const isGreater = y1 > 0n && (y1 * 2n) / P !== aflag1;
1247
- const isZero = y1 === 0n && (y0 * 2n) / P !== aflag1;
1333
+ const isGreater = y1 > _0n && (y1 * _2n) / P !== aflag1;
1334
+ const isZero = y1 === _0n && (y0 * _2n) / P !== aflag1;
1248
1335
  if (isGreater || isZero) y = Fp2.neg(y);
1249
1336
  const point = bls12_381.G2.ProjectivePoint.fromAffine({ x, y });
1250
1337
  point.assertValidity();
1251
1338
  return point;
1252
1339
  },
1253
- encode(point: ProjPointType<Fp2>) {
1254
- // NOTE: by some reasons it was missed in bls12-381, looks like bug
1255
- point.assertValidity();
1256
- if (point.equals(bls12_381.G2.ProjectivePoint.ZERO))
1257
- return concatB(COMPRESSED_ZERO, numberToBytesBE(0n, Fp.BYTES));
1258
- const a = point.toAffine();
1259
- const { re: x0, im: x1 } = Fp2.reim(a.x);
1260
- const { re: y0, im: y1 } = Fp2.reim(a.y);
1261
- const tmp = y1 > 0n ? y1 * 2n : y0 * 2n;
1262
- const aflag1 = Boolean((tmp / Fp.ORDER) & 1n);
1263
- const z1 = bitSet(bitSet(x1, 381, aflag1), S_BIT_POS, true);
1264
- const z2 = x0;
1265
- return concatB(numberToBytesBE(z1, Fp.BYTES), numberToBytesBE(z2, Fp.BYTES));
1340
+ toRawBytes(point: ProjPointType<Fp2>) {
1341
+ return signatureG2ToRawBytes(point);
1342
+ },
1343
+ toHex(point: ProjPointType<Fp2>) {
1344
+ return bytesToHex(signatureG2ToRawBytes(point));
1266
1345
  },
1267
1346
  },
1268
1347
  },
1269
- // The BLS parameter x for BLS12-381
1270
- x: BLS_X,
1348
+ params: {
1349
+ x: BLS_X, // The BLS parameter x for BLS12-381
1350
+ r: Fr.ORDER, // order; z⁴ − z² + 1; CURVE.n from other curves
1351
+ },
1271
1352
  htfDefaults,
1272
1353
  hash: sha256,
1273
1354
  randomBytes,