@noble/curves 1.4.1 → 1.5.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 (120) hide show
  1. package/README.md +135 -123
  2. package/_shortw_utils.d.ts.map +1 -1
  3. package/abstract/bls.d.ts +37 -34
  4. package/abstract/bls.d.ts.map +1 -1
  5. package/abstract/bls.js +167 -115
  6. package/abstract/bls.js.map +1 -1
  7. package/abstract/curve.d.ts +2 -1
  8. package/abstract/curve.d.ts.map +1 -1
  9. package/abstract/curve.js +22 -7
  10. package/abstract/curve.js.map +1 -1
  11. package/abstract/edwards.d.ts +11 -0
  12. package/abstract/edwards.d.ts.map +1 -1
  13. package/abstract/edwards.js +81 -85
  14. package/abstract/edwards.js.map +1 -1
  15. package/abstract/modular.d.ts +4 -0
  16. package/abstract/modular.d.ts.map +1 -1
  17. package/abstract/modular.js +13 -2
  18. package/abstract/modular.js.map +1 -1
  19. package/abstract/montgomery.d.ts.map +1 -1
  20. package/abstract/montgomery.js +4 -9
  21. package/abstract/montgomery.js.map +1 -1
  22. package/abstract/tower.d.ts +106 -0
  23. package/abstract/tower.d.ts.map +1 -0
  24. package/abstract/tower.js +497 -0
  25. package/abstract/tower.js.map +1 -0
  26. package/abstract/utils.d.ts +17 -0
  27. package/abstract/utils.d.ts.map +1 -1
  28. package/abstract/utils.js +50 -1
  29. package/abstract/utils.js.map +1 -1
  30. package/abstract/weierstrass.d.ts +7 -1
  31. package/abstract/weierstrass.d.ts.map +1 -1
  32. package/abstract/weierstrass.js +90 -84
  33. package/abstract/weierstrass.js.map +1 -1
  34. package/bls12-381.d.ts +1 -65
  35. package/bls12-381.d.ts.map +1 -1
  36. package/bls12-381.js +55 -582
  37. package/bls12-381.js.map +1 -1
  38. package/bn254.d.ts +10 -6
  39. package/bn254.d.ts.map +1 -1
  40. package/bn254.js +207 -10
  41. package/bn254.js.map +1 -1
  42. package/ed25519.d.ts +7 -4
  43. package/ed25519.d.ts.map +1 -1
  44. package/ed25519.js +3 -3
  45. package/ed25519.js.map +1 -1
  46. package/ed448.js +0 -3
  47. package/ed448.js.map +1 -1
  48. package/esm/_shortw_utils.d.ts.map +1 -1
  49. package/esm/abstract/bls.d.ts +37 -34
  50. package/esm/abstract/bls.d.ts.map +1 -1
  51. package/esm/abstract/bls.js +168 -116
  52. package/esm/abstract/bls.js.map +1 -1
  53. package/esm/abstract/curve.d.ts +2 -1
  54. package/esm/abstract/curve.d.ts.map +1 -1
  55. package/esm/abstract/curve.js +22 -7
  56. package/esm/abstract/curve.js.map +1 -1
  57. package/esm/abstract/edwards.d.ts +11 -0
  58. package/esm/abstract/edwards.d.ts.map +1 -1
  59. package/esm/abstract/edwards.js +82 -86
  60. package/esm/abstract/edwards.js.map +1 -1
  61. package/esm/abstract/modular.d.ts +4 -0
  62. package/esm/abstract/modular.d.ts.map +1 -1
  63. package/esm/abstract/modular.js +12 -2
  64. package/esm/abstract/modular.js.map +1 -1
  65. package/esm/abstract/montgomery.d.ts.map +1 -1
  66. package/esm/abstract/montgomery.js +5 -10
  67. package/esm/abstract/montgomery.js.map +1 -1
  68. package/esm/abstract/tower.d.ts +106 -0
  69. package/esm/abstract/tower.d.ts.map +1 -0
  70. package/esm/abstract/tower.js +493 -0
  71. package/esm/abstract/tower.js.map +1 -0
  72. package/esm/abstract/utils.d.ts +17 -0
  73. package/esm/abstract/utils.d.ts.map +1 -1
  74. package/esm/abstract/utils.js +44 -0
  75. package/esm/abstract/utils.js.map +1 -1
  76. package/esm/abstract/weierstrass.d.ts +7 -1
  77. package/esm/abstract/weierstrass.d.ts.map +1 -1
  78. package/esm/abstract/weierstrass.js +91 -85
  79. package/esm/abstract/weierstrass.js.map +1 -1
  80. package/esm/bls12-381.d.ts +1 -65
  81. package/esm/bls12-381.d.ts.map +1 -1
  82. package/esm/bls12-381.js +57 -584
  83. package/esm/bls12-381.js.map +1 -1
  84. package/esm/bn254.d.ts +10 -6
  85. package/esm/bn254.d.ts.map +1 -1
  86. package/esm/bn254.js +206 -9
  87. package/esm/bn254.js.map +1 -1
  88. package/esm/ed25519.d.ts +7 -4
  89. package/esm/ed25519.d.ts.map +1 -1
  90. package/esm/ed25519.js +3 -3
  91. package/esm/ed25519.js.map +1 -1
  92. package/esm/ed448.js +0 -3
  93. package/esm/ed448.js.map +1 -1
  94. package/esm/p256.d.ts.map +1 -1
  95. package/esm/p384.d.ts.map +1 -1
  96. package/esm/p521.d.ts.map +1 -1
  97. package/esm/secp256k1.d.ts +6 -0
  98. package/esm/secp256k1.d.ts.map +1 -1
  99. package/esm/secp256k1.js +17 -13
  100. package/esm/secp256k1.js.map +1 -1
  101. package/p256.d.ts.map +1 -1
  102. package/p384.d.ts.map +1 -1
  103. package/p521.d.ts.map +1 -1
  104. package/package.json +8 -8
  105. package/secp256k1.d.ts +6 -0
  106. package/secp256k1.d.ts.map +1 -1
  107. package/secp256k1.js +16 -12
  108. package/secp256k1.js.map +1 -1
  109. package/src/abstract/bls.ts +222 -168
  110. package/src/abstract/curve.ts +23 -7
  111. package/src/abstract/edwards.ts +81 -68
  112. package/src/abstract/modular.ts +13 -3
  113. package/src/abstract/montgomery.ts +11 -10
  114. package/src/abstract/tower.ts +604 -0
  115. package/src/abstract/utils.ts +49 -0
  116. package/src/abstract/weierstrass.ts +85 -68
  117. package/src/bls12-381.ts +53 -707
  118. package/src/bn254.ts +224 -9
  119. package/src/ed25519.ts +5 -2
  120. package/src/secp256k1.ts +24 -12
package/bls12-381.js CHANGED
@@ -10,6 +10,7 @@ const utils_js_1 = require("./abstract/utils.js");
10
10
  // Types
11
11
  const hash_to_curve_js_1 = require("./abstract/hash-to-curve.js");
12
12
  const weierstrass_js_1 = require("./abstract/weierstrass.js");
13
+ const tower_js_1 = require("./abstract/tower.js");
13
14
  /*
14
15
  bls12-381 is pairing-friendly Barreto-Lynn-Scott elliptic curve construction allowing to:
15
16
  - Construct zk-SNARKs at the 120-bit security
@@ -45,511 +46,51 @@ bls12-381 is pairing-friendly Barreto-Lynn-Scott elliptic curve construction all
45
46
  // Be friendly to bad ECMAScript parsers by not using bigint literals
46
47
  // prettier-ignore
47
48
  const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
48
- // prettier-ignore
49
- const _8n = BigInt(8), _16n = BigInt(16);
49
+ /*
50
+ Embedding degree (k): 12
51
+ Seed (X): -15132376222941642752
52
+ Fr: (x⁴-x²+1)
53
+ Fp: ((x-1)² ⋅ r(x)/3+x)
54
+ (E/Fp): Y²=X³+4
55
+ (Eₜ/Fp²): Y² = X³+4(u+1) (M-type twist)
56
+ Ate loop size: X
57
+
58
+ Towers:
59
+ - Fp²[u] = Fp/u²+1
60
+ - Fp⁶[v] = Fp²/v³-1-u
61
+ - Fp¹²[w] = Fp⁶/w²-v
62
+
63
+
64
+ TODO: BLS & BN Fp/Fr can be constructed from seed.
65
+ */
66
+ // The BLS parameter x (seed) for BLS12-381. NOTE: it is negative!
67
+ const BLS_X = BigInt('0xd201000000010000');
68
+ const BLS_X_LEN = (0, utils_js_1.bitLen)(BLS_X);
50
69
  // CURVE FIELDS
51
- // Finite field over p.
52
- const Fp_raw = BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab');
53
- const Fp = mod.Field(Fp_raw);
54
- // Finite field over r.
55
- // This particular field is not used anywhere in bls12-381, but it is still useful.
56
- const Fr = mod.Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'));
57
- const Fp2Add = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
58
- c0: Fp.add(c0, r0),
59
- c1: Fp.add(c1, r1),
60
- });
61
- const Fp2Subtract = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
62
- c0: Fp.sub(c0, r0),
63
- c1: Fp.sub(c1, r1),
64
- });
65
- const Fp2Multiply = ({ c0, c1 }, rhs) => {
66
- if (typeof rhs === 'bigint')
67
- return { c0: Fp.mul(c0, rhs), c1: Fp.mul(c1, rhs) };
68
- // (a+bi)(c+di) = (ac−bd) + (ad+bc)i
69
- const { c0: r0, c1: r1 } = rhs;
70
- let t1 = Fp.mul(c0, r0); // c0 * o0
71
- let t2 = Fp.mul(c1, r1); // c1 * o1
72
- // (T1 - T2) + ((c0 + c1) * (r0 + r1) - (T1 + T2))*i
73
- const o0 = Fp.sub(t1, t2);
74
- const o1 = Fp.sub(Fp.mul(Fp.add(c0, c1), Fp.add(r0, r1)), Fp.add(t1, t2));
75
- return { c0: o0, c1: o1 };
76
- };
77
- const Fp2Square = ({ c0, c1 }) => {
78
- const a = Fp.add(c0, c1);
79
- const b = Fp.sub(c0, c1);
80
- const c = Fp.add(c0, c0);
81
- return { c0: Fp.mul(a, b), c1: Fp.mul(c, c1) };
82
- };
83
- // G2 is the order-q subgroup of E2(Fp²) : y² = x³+4(1+√−1),
84
- // where Fp2 is Fp[√−1]/(x2+1). #E2(Fp2 ) = h2q, where
85
- // G² - 1
86
- // h2q
87
- // NOTE: ORDER was wrong!
88
- const FP2_ORDER = Fp_raw * Fp_raw;
89
- const Fp2 = {
90
- ORDER: FP2_ORDER,
91
- BITS: (0, utils_js_1.bitLen)(FP2_ORDER),
92
- BYTES: Math.ceil((0, utils_js_1.bitLen)(FP2_ORDER) / 8),
93
- MASK: (0, utils_js_1.bitMask)((0, utils_js_1.bitLen)(FP2_ORDER)),
94
- ZERO: { c0: Fp.ZERO, c1: Fp.ZERO },
95
- ONE: { c0: Fp.ONE, c1: Fp.ZERO },
96
- create: (num) => num,
97
- isValid: ({ c0, c1 }) => typeof c0 === 'bigint' && typeof c1 === 'bigint',
98
- is0: ({ c0, c1 }) => Fp.is0(c0) && Fp.is0(c1),
99
- eql: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp.eql(c0, r0) && Fp.eql(c1, r1),
100
- neg: ({ c0, c1 }) => ({ c0: Fp.neg(c0), c1: Fp.neg(c1) }),
101
- pow: (num, power) => mod.FpPow(Fp2, num, power),
102
- invertBatch: (nums) => mod.FpInvertBatch(Fp2, nums),
103
- // Normalized
104
- add: Fp2Add,
105
- sub: Fp2Subtract,
106
- mul: Fp2Multiply,
107
- sqr: Fp2Square,
108
- // NonNormalized stuff
109
- addN: Fp2Add,
110
- subN: Fp2Subtract,
111
- mulN: Fp2Multiply,
112
- sqrN: Fp2Square,
113
- // Why inversion for bigint inside Fp instead of Fp2? it is even used in that context?
114
- div: (lhs, rhs) => Fp2.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp2.inv(rhs)),
115
- inv: ({ c0: a, c1: b }) => {
116
- // We wish to find the multiplicative inverse of a nonzero
117
- // element a + bu in Fp2. We leverage an identity
118
- //
119
- // (a + bu)(a - bu) = a² + b²
120
- //
121
- // which holds because u² = -1. This can be rewritten as
122
- //
123
- // (a + bu)(a - bu)/(a² + b²) = 1
124
- //
125
- // because a² + b² = 0 has no nonzero solutions for (a, b).
126
- // This gives that (a - bu)/(a² + b²) is the inverse
127
- // of (a + bu). Importantly, this can be computing using
128
- // only a single inversion in Fp.
129
- const factor = Fp.inv(Fp.create(a * a + b * b));
130
- return { c0: Fp.mul(factor, Fp.create(a)), c1: Fp.mul(factor, Fp.create(-b)) };
131
- },
132
- sqrt: (num) => {
133
- if (Fp2.eql(num, Fp2.ZERO))
134
- return Fp2.ZERO; // Algo doesn't handles this case
135
- // TODO: Optimize this line. It's extremely slow.
136
- // Speeding this up would boost aggregateSignatures.
137
- // https://eprint.iacr.org/2012/685.pdf applicable?
138
- // https://github.com/zkcrypto/bls12_381/blob/080eaa74ec0e394377caa1ba302c8c121df08b07/src/fp2.rs#L250
139
- // https://github.com/supranational/blst/blob/aae0c7d70b799ac269ff5edf29d8191dbd357876/src/exp2.c#L1
140
- // Inspired by https://github.com/dalek-cryptography/curve25519-dalek/blob/17698df9d4c834204f83a3574143abacb4fc81a5/src/field.rs#L99
141
- const candidateSqrt = Fp2.pow(num, (Fp2.ORDER + _8n) / _16n);
142
- const check = Fp2.div(Fp2.sqr(candidateSqrt), num); // candidateSqrt.square().div(this);
143
- const R = FP2_ROOTS_OF_UNITY;
144
- const divisor = [R[0], R[2], R[4], R[6]].find((r) => Fp2.eql(r, check));
145
- if (!divisor)
146
- throw new Error('No root');
147
- const index = R.indexOf(divisor);
148
- const root = R[index / 2];
149
- if (!root)
150
- throw new Error('Invalid root');
151
- const x1 = Fp2.div(candidateSqrt, root);
152
- const x2 = Fp2.neg(x1);
153
- const { re: re1, im: im1 } = Fp2.reim(x1);
154
- const { re: re2, im: im2 } = Fp2.reim(x2);
155
- if (im1 > im2 || (im1 === im2 && re1 > re2))
156
- return x1;
157
- return x2;
158
- },
159
- // Same as sgn0_m_eq_2 in RFC 9380
160
- isOdd: (x) => {
161
- const { re: x0, im: x1 } = Fp2.reim(x);
162
- const sign_0 = x0 % _2n;
163
- const zero_0 = x0 === _0n;
164
- const sign_1 = x1 % _2n;
165
- return BigInt(sign_0 || (zero_0 && sign_1)) == _1n;
166
- },
167
- // Bytes util
168
- fromBytes(b) {
169
- if (b.length !== Fp2.BYTES)
170
- throw new Error(`fromBytes wrong length=${b.length}`);
171
- return { c0: Fp.fromBytes(b.subarray(0, Fp.BYTES)), c1: Fp.fromBytes(b.subarray(Fp.BYTES)) };
172
- },
173
- toBytes: ({ c0, c1 }) => (0, utils_js_1.concatBytes)(Fp.toBytes(c0), Fp.toBytes(c1)),
174
- cmov: ({ c0, c1 }, { c0: r0, c1: r1 }, c) => ({
175
- c0: Fp.cmov(c0, r0, c),
176
- c1: Fp.cmov(c1, r1, c),
177
- }),
178
- // Specific utils
179
- // toString() {
180
- // return `Fp2(${this.c0} + ${this.c1}×i)`;
181
- // }
182
- reim: ({ c0, c1 }) => ({ re: c0, im: c1 }),
183
- // multiply by u + 1
184
- mulByNonresidue: ({ c0, c1 }) => ({ c0: Fp.sub(c0, c1), c1: Fp.add(c0, c1) }),
185
- multiplyByB: ({ c0, c1 }) => {
186
- let t0 = Fp.mul(c0, _4n); // 4 * c0
187
- let t1 = Fp.mul(c1, _4n); // 4 * c1
70
+ const { Fp, Fp2, Fp6, Fp4Square, Fp12 } = (0, tower_js_1.tower12)({
71
+ // Order of Fp
72
+ ORDER: BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'),
73
+ // Finite extension field over irreducible polynominal.
74
+ // Fp(u) / (u² - β) where β = -1
75
+ FP2_NONRESIDUE: [_1n, _1n],
76
+ Fp2mulByB: ({ c0, c1 }) => {
77
+ const t0 = Fp.mul(c0, _4n); // 4 * c0
78
+ const t1 = Fp.mul(c1, _4n); // 4 * c1
188
79
  // (T0-T1) + (T0+T1)*i
189
80
  return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
190
81
  },
191
- fromBigTuple: (tuple) => {
192
- if (tuple.length !== 2)
193
- throw new Error('Invalid tuple');
194
- const fps = tuple.map((n) => Fp.create(n));
195
- return { c0: fps[0], c1: fps[1] };
196
- },
197
- frobeniusMap: ({ c0, c1 }, power) => ({
198
- c0,
199
- c1: Fp.mul(c1, FP2_FROBENIUS_COEFFICIENTS[power % 2]),
200
- }),
201
- };
202
- // Finite extension field over irreducible polynominal.
203
- // Fp(u) / (u² - β) where β = -1
204
- const FP2_FROBENIUS_COEFFICIENTS = [
205
- BigInt('0x1'),
206
- BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'),
207
- ].map((item) => Fp.create(item));
208
- // For Fp2 roots of unity.
209
- const rv1 = BigInt('0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09');
210
- // const ev1 =
211
- // BigInt('0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90');
212
- // const ev2 =
213
- // BigInt('0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5');
214
- // const ev3 =
215
- // BigInt('0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17');
216
- // const ev4 =
217
- // BigInt('0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1');
218
- // Eighth roots of unity, used for computing square roots in Fp2.
219
- // To verify or re-calculate:
220
- // Array(8).fill(new Fp2([1n, 1n])).map((fp2, k) => fp2.pow(Fp2.ORDER * BigInt(k) / 8n))
221
- const FP2_ROOTS_OF_UNITY = [
222
- [_1n, _0n],
223
- [rv1, -rv1],
224
- [_0n, _1n],
225
- [rv1, rv1],
226
- [-_1n, _0n],
227
- [-rv1, rv1],
228
- [_0n, -_1n],
229
- [-rv1, -rv1],
230
- ].map((pair) => Fp2.fromBigTuple(pair));
231
- const Fp6Add = ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => ({
232
- c0: Fp2.add(c0, r0),
233
- c1: Fp2.add(c1, r1),
234
- c2: Fp2.add(c2, r2),
235
- });
236
- const Fp6Subtract = ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => ({
237
- c0: Fp2.sub(c0, r0),
238
- c1: Fp2.sub(c1, r1),
239
- c2: Fp2.sub(c2, r2),
240
- });
241
- const Fp6Multiply = ({ c0, c1, c2 }, rhs) => {
242
- if (typeof rhs === 'bigint') {
243
- return {
244
- c0: Fp2.mul(c0, rhs),
245
- c1: Fp2.mul(c1, rhs),
246
- c2: Fp2.mul(c2, rhs),
247
- };
248
- }
249
- const { c0: r0, c1: r1, c2: r2 } = rhs;
250
- const t0 = Fp2.mul(c0, r0); // c0 * o0
251
- const t1 = Fp2.mul(c1, r1); // c1 * o1
252
- const t2 = Fp2.mul(c2, r2); // c2 * o2
253
- return {
254
- // t0 + (c1 + c2) * (r1 * r2) - (T1 + T2) * (u + 1)
255
- c0: Fp2.add(t0, Fp2.mulByNonresidue(Fp2.sub(Fp2.mul(Fp2.add(c1, c2), Fp2.add(r1, r2)), Fp2.add(t1, t2)))),
256
- // (c0 + c1) * (r0 + r1) - (T0 + T1) + T2 * (u + 1)
257
- c1: Fp2.add(Fp2.sub(Fp2.mul(Fp2.add(c0, c1), Fp2.add(r0, r1)), Fp2.add(t0, t1)), Fp2.mulByNonresidue(t2)),
258
- // T1 + (c0 + c2) * (r0 + r2) - T0 + T2
259
- c2: Fp2.sub(Fp2.add(t1, Fp2.mul(Fp2.add(c0, c2), Fp2.add(r0, r2))), Fp2.add(t0, t2)),
260
- };
261
- };
262
- const Fp6Square = ({ c0, c1, c2 }) => {
263
- let t0 = Fp2.sqr(c0); // c0²
264
- let t1 = Fp2.mul(Fp2.mul(c0, c1), _2n); // 2 * c0 * c1
265
- let t3 = Fp2.mul(Fp2.mul(c1, c2), _2n); // 2 * c1 * c2
266
- let t4 = Fp2.sqr(c2); // c2²
267
- return {
268
- c0: Fp2.add(Fp2.mulByNonresidue(t3), t0), // T3 * (u + 1) + T0
269
- c1: Fp2.add(Fp2.mulByNonresidue(t4), t1), // T4 * (u + 1) + T1
270
- // T1 + (c0 - c1 + c2)² + T3 - T0 - T4
271
- c2: Fp2.sub(Fp2.sub(Fp2.add(Fp2.add(t1, Fp2.sqr(Fp2.add(Fp2.sub(c0, c1), c2))), t3), t0), t4),
272
- };
273
- };
274
- const Fp6 = {
275
- ORDER: Fp2.ORDER, // TODO: unused, but need to verify
276
- BITS: 3 * Fp2.BITS,
277
- BYTES: 3 * Fp2.BYTES,
278
- MASK: (0, utils_js_1.bitMask)(3 * Fp2.BITS),
279
- ZERO: { c0: Fp2.ZERO, c1: Fp2.ZERO, c2: Fp2.ZERO },
280
- ONE: { c0: Fp2.ONE, c1: Fp2.ZERO, c2: Fp2.ZERO },
281
- create: (num) => num,
282
- isValid: ({ c0, c1, c2 }) => Fp2.isValid(c0) && Fp2.isValid(c1) && Fp2.isValid(c2),
283
- is0: ({ c0, c1, c2 }) => Fp2.is0(c0) && Fp2.is0(c1) && Fp2.is0(c2),
284
- neg: ({ c0, c1, c2 }) => ({ c0: Fp2.neg(c0), c1: Fp2.neg(c1), c2: Fp2.neg(c2) }),
285
- eql: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => Fp2.eql(c0, r0) && Fp2.eql(c1, r1) && Fp2.eql(c2, r2),
286
- sqrt: () => {
287
- throw new Error('Not implemented');
288
- },
289
- // Do we need division by bigint at all? Should be done via order:
290
- div: (lhs, rhs) => Fp6.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp6.inv(rhs)),
291
- pow: (num, power) => mod.FpPow(Fp6, num, power),
292
- invertBatch: (nums) => mod.FpInvertBatch(Fp6, nums),
293
- // Normalized
294
- add: Fp6Add,
295
- sub: Fp6Subtract,
296
- mul: Fp6Multiply,
297
- sqr: Fp6Square,
298
- // NonNormalized stuff
299
- addN: Fp6Add,
300
- subN: Fp6Subtract,
301
- mulN: Fp6Multiply,
302
- sqrN: Fp6Square,
303
- inv: ({ c0, c1, c2 }) => {
304
- let t0 = Fp2.sub(Fp2.sqr(c0), Fp2.mulByNonresidue(Fp2.mul(c2, c1))); // c0² - c2 * c1 * (u + 1)
305
- let t1 = Fp2.sub(Fp2.mulByNonresidue(Fp2.sqr(c2)), Fp2.mul(c0, c1)); // c2² * (u + 1) - c0 * c1
306
- let t2 = Fp2.sub(Fp2.sqr(c1), Fp2.mul(c0, c2)); // c1² - c0 * c2
307
- // 1/(((c2 * T1 + c1 * T2) * v) + c0 * T0)
308
- let t4 = Fp2.inv(Fp2.add(Fp2.mulByNonresidue(Fp2.add(Fp2.mul(c2, t1), Fp2.mul(c1, t2))), Fp2.mul(c0, t0)));
309
- return { c0: Fp2.mul(t4, t0), c1: Fp2.mul(t4, t1), c2: Fp2.mul(t4, t2) };
310
- },
311
- // Bytes utils
312
- fromBytes: (b) => {
313
- if (b.length !== Fp6.BYTES)
314
- throw new Error(`fromBytes wrong length=${b.length}`);
315
- return {
316
- c0: Fp2.fromBytes(b.subarray(0, Fp2.BYTES)),
317
- c1: Fp2.fromBytes(b.subarray(Fp2.BYTES, 2 * Fp2.BYTES)),
318
- c2: Fp2.fromBytes(b.subarray(2 * Fp2.BYTES)),
319
- };
320
- },
321
- toBytes: ({ c0, c1, c2 }) => (0, utils_js_1.concatBytes)(Fp2.toBytes(c0), Fp2.toBytes(c1), Fp2.toBytes(c2)),
322
- cmov: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }, c) => ({
323
- c0: Fp2.cmov(c0, r0, c),
324
- c1: Fp2.cmov(c1, r1, c),
325
- c2: Fp2.cmov(c2, r2, c),
326
- }),
327
- // Utils
328
- // fromTriple(triple: [Fp2, Fp2, Fp2]) {
329
- // return new Fp6(...triple);
330
- // }
331
- // toString() {
332
- // return `Fp6(${this.c0} + ${this.c1} * v, ${this.c2} * v^2)`;
333
- // }
334
- fromBigSix: (t) => {
335
- if (!Array.isArray(t) || t.length !== 6)
336
- throw new Error('Invalid Fp6 usage');
337
- return {
338
- c0: Fp2.fromBigTuple(t.slice(0, 2)),
339
- c1: Fp2.fromBigTuple(t.slice(2, 4)),
340
- c2: Fp2.fromBigTuple(t.slice(4, 6)),
341
- };
342
- },
343
- frobeniusMap: ({ c0, c1, c2 }, power) => ({
344
- c0: Fp2.frobeniusMap(c0, power),
345
- c1: Fp2.mul(Fp2.frobeniusMap(c1, power), FP6_FROBENIUS_COEFFICIENTS_1[power % 6]),
346
- c2: Fp2.mul(Fp2.frobeniusMap(c2, power), FP6_FROBENIUS_COEFFICIENTS_2[power % 6]),
347
- }),
348
- mulByNonresidue: ({ c0, c1, c2 }) => ({ c0: Fp2.mulByNonresidue(c2), c1: c0, c2: c1 }),
349
- // Sparse multiplication
350
- multiplyBy1: ({ c0, c1, c2 }, b1) => ({
351
- c0: Fp2.mulByNonresidue(Fp2.mul(c2, b1)),
352
- c1: Fp2.mul(c0, b1),
353
- c2: Fp2.mul(c1, b1),
354
- }),
355
- // Sparse multiplication
356
- multiplyBy01({ c0, c1, c2 }, b0, b1) {
357
- let t0 = Fp2.mul(c0, b0); // c0 * b0
358
- let t1 = Fp2.mul(c1, b1); // c1 * b1
359
- return {
360
- // ((c1 + c2) * b1 - T1) * (u + 1) + T0
361
- c0: Fp2.add(Fp2.mulByNonresidue(Fp2.sub(Fp2.mul(Fp2.add(c1, c2), b1), t1)), t0),
362
- // (b0 + b1) * (c0 + c1) - T0 - T1
363
- c1: Fp2.sub(Fp2.sub(Fp2.mul(Fp2.add(b0, b1), Fp2.add(c0, c1)), t0), t1),
364
- // (c0 + c2) * b0 - T0 + T1
365
- c2: Fp2.add(Fp2.sub(Fp2.mul(Fp2.add(c0, c2), b0), t0), t1),
366
- };
367
- },
368
- multiplyByFp2: ({ c0, c1, c2 }, rhs) => ({
369
- c0: Fp2.mul(c0, rhs),
370
- c1: Fp2.mul(c1, rhs),
371
- c2: Fp2.mul(c2, rhs),
372
- }),
373
- };
374
- const FP6_FROBENIUS_COEFFICIENTS_1 = [
375
- [BigInt('0x1'), BigInt('0x0')],
376
- [
377
- BigInt('0x0'),
378
- BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'),
379
- ],
380
- [
381
- BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'),
382
- BigInt('0x0'),
383
- ],
384
- [BigInt('0x0'), BigInt('0x1')],
385
- [
386
- BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'),
387
- BigInt('0x0'),
388
- ],
389
- [
390
- BigInt('0x0'),
391
- BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'),
392
- ],
393
- ].map((pair) => Fp2.fromBigTuple(pair));
394
- const FP6_FROBENIUS_COEFFICIENTS_2 = [
395
- [BigInt('0x1'), BigInt('0x0')],
396
- [
397
- BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'),
398
- BigInt('0x0'),
399
- ],
400
- [
401
- BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'),
402
- BigInt('0x0'),
403
- ],
404
- [
405
- BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'),
406
- BigInt('0x0'),
407
- ],
408
- [
409
- BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'),
410
- BigInt('0x0'),
411
- ],
412
- [
413
- BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'),
414
- BigInt('0x0'),
415
- ],
416
- ].map((pair) => Fp2.fromBigTuple(pair));
417
- // The BLS parameter x for BLS12-381
418
- const BLS_X = BigInt('0xd201000000010000');
419
- const BLS_X_LEN = (0, utils_js_1.bitLen)(BLS_X);
420
- const Fp12Add = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
421
- c0: Fp6.add(c0, r0),
422
- c1: Fp6.add(c1, r1),
423
- });
424
- const Fp12Subtract = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
425
- c0: Fp6.sub(c0, r0),
426
- c1: Fp6.sub(c1, r1),
427
- });
428
- const Fp12Multiply = ({ c0, c1 }, rhs) => {
429
- if (typeof rhs === 'bigint')
430
- return { c0: Fp6.mul(c0, rhs), c1: Fp6.mul(c1, rhs) };
431
- let { c0: r0, c1: r1 } = rhs;
432
- let t1 = Fp6.mul(c0, r0); // c0 * r0
433
- let t2 = Fp6.mul(c1, r1); // c1 * r1
434
- return {
435
- c0: Fp6.add(t1, Fp6.mulByNonresidue(t2)), // T1 + T2 * v
436
- // (c0 + c1) * (r0 + r1) - (T1 + T2)
437
- c1: Fp6.sub(Fp6.mul(Fp6.add(c0, c1), Fp6.add(r0, r1)), Fp6.add(t1, t2)),
438
- };
439
- };
440
- const Fp12Square = ({ c0, c1 }) => {
441
- let ab = Fp6.mul(c0, c1); // c0 * c1
442
- return {
443
- // (c1 * v + c0) * (c0 + c1) - AB - AB * v
444
- c0: Fp6.sub(Fp6.sub(Fp6.mul(Fp6.add(Fp6.mulByNonresidue(c1), c0), Fp6.add(c0, c1)), ab), Fp6.mulByNonresidue(ab)),
445
- c1: Fp6.add(ab, ab),
446
- }; // AB + AB
447
- };
448
- function Fp4Square(a, b) {
449
- const a2 = Fp2.sqr(a);
450
- const b2 = Fp2.sqr(b);
451
- return {
452
- first: Fp2.add(Fp2.mulByNonresidue(b2), a2), // b² * Nonresidue + a²
453
- second: Fp2.sub(Fp2.sub(Fp2.sqr(Fp2.add(a, b)), a2), b2), // (a + b)² - a² - b²
454
- };
455
- }
456
- const Fp12 = {
457
- ORDER: Fp2.ORDER, // TODO: unused, but need to verify
458
- BITS: 2 * Fp2.BITS,
459
- BYTES: 2 * Fp2.BYTES,
460
- MASK: (0, utils_js_1.bitMask)(2 * Fp2.BITS),
461
- ZERO: { c0: Fp6.ZERO, c1: Fp6.ZERO },
462
- ONE: { c0: Fp6.ONE, c1: Fp6.ZERO },
463
- create: (num) => num,
464
- isValid: ({ c0, c1 }) => Fp6.isValid(c0) && Fp6.isValid(c1),
465
- is0: ({ c0, c1 }) => Fp6.is0(c0) && Fp6.is0(c1),
466
- neg: ({ c0, c1 }) => ({ c0: Fp6.neg(c0), c1: Fp6.neg(c1) }),
467
- eql: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp6.eql(c0, r0) && Fp6.eql(c1, r1),
468
- sqrt: () => {
469
- throw new Error('Not implemented');
470
- },
471
- inv: ({ c0, c1 }) => {
472
- let t = Fp6.inv(Fp6.sub(Fp6.sqr(c0), Fp6.mulByNonresidue(Fp6.sqr(c1)))); // 1 / (c0² - c1² * v)
473
- return { c0: Fp6.mul(c0, t), c1: Fp6.neg(Fp6.mul(c1, t)) }; // ((C0 * T) * T) + (-C1 * T) * w
474
- },
475
- div: (lhs, rhs) => Fp12.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp12.inv(rhs)),
476
- pow: (num, power) => mod.FpPow(Fp12, num, power),
477
- invertBatch: (nums) => mod.FpInvertBatch(Fp12, nums),
478
- // Normalized
479
- add: Fp12Add,
480
- sub: Fp12Subtract,
481
- mul: Fp12Multiply,
482
- sqr: Fp12Square,
483
- // NonNormalized stuff
484
- addN: Fp12Add,
485
- subN: Fp12Subtract,
486
- mulN: Fp12Multiply,
487
- sqrN: Fp12Square,
488
- // Bytes utils
489
- fromBytes: (b) => {
490
- if (b.length !== Fp12.BYTES)
491
- throw new Error(`fromBytes wrong length=${b.length}`);
492
- return {
493
- c0: Fp6.fromBytes(b.subarray(0, Fp6.BYTES)),
494
- c1: Fp6.fromBytes(b.subarray(Fp6.BYTES)),
495
- };
496
- },
497
- toBytes: ({ c0, c1 }) => (0, utils_js_1.concatBytes)(Fp6.toBytes(c0), Fp6.toBytes(c1)),
498
- cmov: ({ c0, c1 }, { c0: r0, c1: r1 }, c) => ({
499
- c0: Fp6.cmov(c0, r0, c),
500
- c1: Fp6.cmov(c1, r1, c),
501
- }),
502
- // Utils
503
- // toString() {
504
- // return `Fp12(${this.c0} + ${this.c1} * w)`;
505
- // },
506
- // fromTuple(c: [Fp6, Fp6]) {
507
- // return new Fp12(...c);
508
- // }
509
- fromBigTwelve: (t) => ({
510
- c0: Fp6.fromBigSix(t.slice(0, 6)),
511
- c1: Fp6.fromBigSix(t.slice(6, 12)),
512
- }),
513
- // Raises to q**i -th power
514
- frobeniusMap(lhs, power) {
515
- const r0 = Fp6.frobeniusMap(lhs.c0, power);
516
- const { c0, c1, c2 } = Fp6.frobeniusMap(lhs.c1, power);
517
- const coeff = FP12_FROBENIUS_COEFFICIENTS[power % 12];
518
- return {
519
- c0: r0,
520
- c1: Fp6.create({
521
- c0: Fp2.mul(c0, coeff),
522
- c1: Fp2.mul(c1, coeff),
523
- c2: Fp2.mul(c2, coeff),
524
- }),
525
- };
526
- },
527
- // Sparse multiplication
528
- multiplyBy014: ({ c0, c1 }, o0, o1, o4) => {
529
- let t0 = Fp6.multiplyBy01(c0, o0, o1);
530
- let t1 = Fp6.multiplyBy1(c1, o4);
531
- return {
532
- c0: Fp6.add(Fp6.mulByNonresidue(t1), t0), // T1 * v + T0
533
- // (c1 + c0) * [o0, o1+o4] - T0 - T1
534
- c1: Fp6.sub(Fp6.sub(Fp6.multiplyBy01(Fp6.add(c1, c0), o0, Fp2.add(o1, o4)), t0), t1),
535
- };
536
- },
537
- multiplyByFp2: ({ c0, c1 }, rhs) => ({
538
- c0: Fp6.multiplyByFp2(c0, rhs),
539
- c1: Fp6.multiplyByFp2(c1, rhs),
540
- }),
541
- conjugate: ({ c0, c1 }) => ({ c0, c1: Fp6.neg(c1) }),
82
+ // Fp12
542
83
  // A cyclotomic group is a subgroup of Fp^n defined by
543
84
  // GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) = 1}
544
85
  // The result of any pairing is in a cyclotomic subgroup
545
86
  // https://eprint.iacr.org/2009/565.pdf
546
- _cyclotomicSquare: ({ c0, c1 }) => {
87
+ Fp12cyclotomicSquare: ({ c0, c1 }) => {
547
88
  const { c0: c0c0, c1: c0c1, c2: c0c2 } = c0;
548
89
  const { c0: c1c0, c1: c1c1, c2: c1c2 } = c1;
549
90
  const { first: t3, second: t4 } = Fp4Square(c0c0, c1c1);
550
91
  const { first: t5, second: t6 } = Fp4Square(c1c0, c0c2);
551
92
  const { first: t7, second: t8 } = Fp4Square(c0c1, c1c2);
552
- let t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
93
+ const t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
553
94
  return {
554
95
  c0: Fp6.create({
555
96
  c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3), // 2 * (T3 - c0c0) + T3
@@ -563,7 +104,7 @@ const Fp12 = {
563
104
  }),
564
105
  }; // 2 * (T6 + c1c2) + T6
565
106
  },
566
- _cyclotomicExp(num, n) {
107
+ Fp12cyclotomicExp(num, n) {
567
108
  let z = Fp12.ONE;
568
109
  for (let i = BLS_X_LEN - 1; i >= 0; i--) {
569
110
  z = Fp12._cyclotomicSquare(z);
@@ -574,7 +115,7 @@ const Fp12 = {
574
115
  },
575
116
  // https://eprint.iacr.org/2010/354.pdf
576
117
  // https://eprint.iacr.org/2009/565.pdf
577
- finalExponentiate: (num) => {
118
+ Fp12finalExponentiate: (num) => {
578
119
  const x = BLS_X;
579
120
  // this^(q⁶) / this
580
121
  const t0 = Fp12.div(Fp12.frobeniusMap(num, 6), num);
@@ -593,54 +134,10 @@ const Fp12 = {
593
134
  // (t2 * t5)^(q²) * (t4 * t1)^(q³) * (t6 * t1.conj)^(q^1) * t7 * t3.conj * t1
594
135
  return Fp12.mul(Fp12.mul(Fp12.mul(t2_t5_pow_q2, t4_t1_pow_q3), t6_t1c_pow_q1), t7_t3c_t1);
595
136
  },
596
- };
597
- const FP12_FROBENIUS_COEFFICIENTS = [
598
- [BigInt('0x1'), BigInt('0x0')],
599
- [
600
- BigInt('0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'),
601
- BigInt('0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'),
602
- ],
603
- [
604
- BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'),
605
- BigInt('0x0'),
606
- ],
607
- [
608
- BigInt('0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'),
609
- BigInt('0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'),
610
- ],
611
- [
612
- BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'),
613
- BigInt('0x0'),
614
- ],
615
- [
616
- BigInt('0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'),
617
- BigInt('0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'),
618
- ],
619
- [
620
- BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'),
621
- BigInt('0x0'),
622
- ],
623
- [
624
- BigInt('0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'),
625
- BigInt('0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'),
626
- ],
627
- [
628
- BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'),
629
- BigInt('0x0'),
630
- ],
631
- [
632
- BigInt('0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'),
633
- BigInt('0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'),
634
- ],
635
- [
636
- BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'),
637
- BigInt('0x0'),
638
- ],
639
- [
640
- BigInt('0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'),
641
- BigInt('0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'),
642
- ],
643
- ].map((n) => Fp2.fromBigTuple(n));
137
+ });
138
+ // Finite field over r.
139
+ // This particular field is not used anywhere in bls12-381, but it is still useful.
140
+ const Fr = mod.Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'));
644
141
  // END OF CURVE FIELDS
645
142
  // HashToCurve
646
143
  // 3-isogeny map from E' to E https://www.rfc-editor.org/rfc/rfc9380#appendix-E.3
@@ -796,33 +293,7 @@ const G1_SWU = (0, weierstrass_js_1.mapToCurveSimpleSWU)(Fp, {
796
293
  });
797
294
  // Endomorphisms (for fast cofactor clearing)
798
295
  // Ψ(P) endomorphism
799
- const ut_root = Fp6.create({ c0: Fp2.ZERO, c1: Fp2.ONE, c2: Fp2.ZERO });
800
- const wsq = Fp12.create({ c0: ut_root, c1: Fp6.ZERO });
801
- const wcu = Fp12.create({ c0: Fp6.ZERO, c1: ut_root });
802
- const [wsq_inv, wcu_inv] = Fp12.invertBatch([wsq, wcu]);
803
- function psi(x, y) {
804
- // Untwist Fp2->Fp12 && frobenius(1) && twist back
805
- const x2 = Fp12.mul(Fp12.frobeniusMap(Fp12.multiplyByFp2(wsq_inv, x), 1), wsq).c0.c0;
806
- const y2 = Fp12.mul(Fp12.frobeniusMap(Fp12.multiplyByFp2(wcu_inv, y), 1), wcu).c0.c0;
807
- return [x2, y2];
808
- }
809
- // Ψ endomorphism
810
- function G2psi(c, P) {
811
- const affine = P.toAffine();
812
- const p = psi(affine.x, affine.y);
813
- return new c(p[0], p[1], Fp2.ONE);
814
- }
815
- // Ψ²(P) endomorphism
816
- // 1 / F2(2)^((p-1)/3) in GF(p²)
817
- const PSI2_C1 = BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac');
818
- function psi2(x, y) {
819
- return [Fp2.mul(x, PSI2_C1), Fp2.neg(y)];
820
- }
821
- function G2psi2(c, P) {
822
- const affine = P.toAffine();
823
- const p = psi2(affine.x, affine.y);
824
- return new c(p[0], p[1], Fp2.ONE);
825
- }
296
+ const { G2psi, G2psi2 } = (0, tower_js_1.psiFrobenius)(Fp, Fp2, Fp2.div(Fp2.ONE, Fp2.NONRESIDUE)); // 1/(u+1)
826
297
  // Default hash_to_field options are for hash to G2.
827
298
  //
828
299
  // Parameter definitions are in section 5.3 of the spec unless otherwise noted.
@@ -863,22 +334,22 @@ const COMPRESSED_ZERO = setMask(Fp.toBytes(_0n), { infinity: true, compressed: t
863
334
  function parseMask(bytes) {
864
335
  // Copy, so we can remove mask data. It will be removed also later, when Fp.create will call modulo.
865
336
  bytes = bytes.slice();
866
- const mask = bytes[0] & 0b1110_0000;
337
+ const mask = bytes[0] & 224;
867
338
  const compressed = !!((mask >> 7) & 1); // compression bit (0b1000_0000)
868
339
  const infinity = !!((mask >> 6) & 1); // point at infinity bit (0b0100_0000)
869
340
  const sort = !!((mask >> 5) & 1); // sort bit (0b0010_0000)
870
- bytes[0] &= 0b0001_1111; // clear mask (zero first 3 bits)
341
+ bytes[0] &= 31; // clear mask (zero first 3 bits)
871
342
  return { compressed, infinity, sort, value: bytes };
872
343
  }
873
344
  function setMask(bytes, mask) {
874
- if (bytes[0] & 0b1110_0000)
345
+ if (bytes[0] & 224)
875
346
  throw new Error('setMask: non-empty mask');
876
347
  if (mask.compressed)
877
- bytes[0] |= 0b1000_0000;
348
+ bytes[0] |= 128;
878
349
  if (mask.infinity)
879
- bytes[0] |= 0b0100_0000;
350
+ bytes[0] |= 64;
880
351
  if (mask.sort)
881
- bytes[0] |= 0b0010_0000;
352
+ bytes[0] |= 32;
882
353
  return bytes;
883
354
  }
884
355
  function signatureG1ToRawBytes(point) {
@@ -949,8 +420,8 @@ exports.bls12_381 = (0, bls_js_1.bls)({
949
420
  const cubicRootOfUnityModP = BigInt('0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe');
950
421
  const phi = new c(Fp.mul(point.px, cubicRootOfUnityModP), point.py, point.pz);
951
422
  // todo: unroll
952
- const xP = point.multiplyUnsafe(exports.bls12_381.params.x).negate(); // [x]P
953
- const u2P = xP.multiplyUnsafe(exports.bls12_381.params.x); // [u2]P
423
+ const xP = point.multiplyUnsafe(BLS_X).negate(); // [x]P
424
+ const u2P = xP.multiplyUnsafe(BLS_X); // [u2]P
954
425
  return u2P.equals(phi);
955
426
  // https://eprint.iacr.org/2019/814.pdf
956
427
  // (z² − 1)/3
@@ -968,7 +439,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
968
439
  // https://eprint.iacr.org/2019/403
969
440
  clearCofactor: (_c, point) => {
970
441
  // return this.multiplyUnsafe(CURVE.h);
971
- return point.multiplyUnsafe(exports.bls12_381.params.x).add(point); // x*P + P
442
+ return point.multiplyUnsafe(BLS_X).add(point); // x*P + P
972
443
  },
973
444
  mapToCurve: (scalars) => {
974
445
  const { x, y } = G1_SWU(Fp.create(scalars[0]));
@@ -1093,7 +564,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
1093
564
  // It returns false for shitty points.
1094
565
  // https://eprint.iacr.org/2021/1130.pdf
1095
566
  isTorsionFree: (c, P) => {
1096
- return P.multiplyUnsafe(exports.bls12_381.params.x).negate().equals(G2psi(c, P)); // ψ(P) == [u](P)
567
+ return P.multiplyUnsafe(BLS_X).negate().equals(G2psi(c, P)); // ψ(P) == [u](P)
1097
568
  // Older version: https://eprint.iacr.org/2019/814.pdf
1098
569
  // Ψ²(P) => Ψ³(P) => [z]Ψ³(P) where z = -x => [z]Ψ³(P) - Ψ²(P) + P == O
1099
570
  // return P.psi2().psi().mulNegX().subtract(psi2).add(P).isZero();
@@ -1103,7 +574,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
1103
574
  // https://eprint.iacr.org/2017/419.pdf
1104
575
  // prettier-ignore
1105
576
  clearCofactor: (c, P) => {
1106
- const x = exports.bls12_381.params.x;
577
+ const x = BLS_X;
1107
578
  let t1 = P.multiplyUnsafe(x).negate(); // [-x]P
1108
579
  let t2 = G2psi(c, P); // Ψ(P)
1109
580
  let t3 = P.double(); // 2P
@@ -1122,7 +593,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
1122
593
  (!compressed && infinity && sort) || // 01100000
1123
594
  (sort && infinity && compressed) // 11100000
1124
595
  ) {
1125
- throw new Error('Invalid encoding flag: ' + (bytes[0] & 0b1110_0000));
596
+ throw new Error('Invalid encoding flag: ' + (bytes[0] & 224));
1126
597
  }
1127
598
  const L = Fp.BYTES;
1128
599
  const slc = (b, from, to) => (0, utils_js_1.bytesToNumberBE)(b.slice(from, to));
@@ -1222,8 +693,10 @@ exports.bls12_381 = (0, bls_js_1.bls)({
1222
693
  },
1223
694
  },
1224
695
  params: {
1225
- x: BLS_X, // The BLS parameter x for BLS12-381
696
+ ateLoopSize: BLS_X, // The BLS parameter x for BLS12-381
1226
697
  r: Fr.ORDER, // order; z⁴ − z² + 1; CURVE.n from other curves
698
+ xNegative: true,
699
+ twistType: 'multiplicative',
1227
700
  },
1228
701
  htfDefaults,
1229
702
  hash: sha256_1.sha256,