@noble/curves 1.9.4 → 1.9.6

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 (124) hide show
  1. package/abstract/bls.d.ts +2 -2
  2. package/abstract/bls.d.ts.map +1 -1
  3. package/abstract/curve.d.ts +47 -46
  4. package/abstract/curve.d.ts.map +1 -1
  5. package/abstract/curve.js +9 -6
  6. package/abstract/curve.js.map +1 -1
  7. package/abstract/edwards.d.ts +41 -33
  8. package/abstract/edwards.d.ts.map +1 -1
  9. package/abstract/edwards.js +166 -170
  10. package/abstract/edwards.js.map +1 -1
  11. package/abstract/modular.d.ts +1 -1
  12. package/abstract/modular.d.ts.map +1 -1
  13. package/abstract/modular.js +4 -4
  14. package/abstract/modular.js.map +1 -1
  15. package/abstract/montgomery.d.ts +2 -6
  16. package/abstract/montgomery.d.ts.map +1 -1
  17. package/abstract/montgomery.js +13 -10
  18. package/abstract/montgomery.js.map +1 -1
  19. package/abstract/tower.d.ts +9 -7
  20. package/abstract/tower.d.ts.map +1 -1
  21. package/abstract/tower.js +569 -357
  22. package/abstract/tower.js.map +1 -1
  23. package/abstract/weierstrass.d.ts +162 -92
  24. package/abstract/weierstrass.d.ts.map +1 -1
  25. package/abstract/weierstrass.js +394 -336
  26. package/abstract/weierstrass.js.map +1 -1
  27. package/bls12-381.d.ts.map +1 -1
  28. package/bls12-381.js +9 -42
  29. package/bls12-381.js.map +1 -1
  30. package/bn254.d.ts.map +1 -1
  31. package/bn254.js +2 -34
  32. package/bn254.js.map +1 -1
  33. package/ed25519.d.ts +15 -15
  34. package/ed25519.d.ts.map +1 -1
  35. package/ed25519.js +51 -48
  36. package/ed25519.js.map +1 -1
  37. package/ed448.d.ts +16 -17
  38. package/ed448.d.ts.map +1 -1
  39. package/ed448.js +67 -48
  40. package/ed448.js.map +1 -1
  41. package/esm/abstract/bls.d.ts +2 -2
  42. package/esm/abstract/bls.d.ts.map +1 -1
  43. package/esm/abstract/curve.d.ts +47 -46
  44. package/esm/abstract/curve.d.ts.map +1 -1
  45. package/esm/abstract/curve.js +9 -6
  46. package/esm/abstract/curve.js.map +1 -1
  47. package/esm/abstract/edwards.d.ts +41 -33
  48. package/esm/abstract/edwards.d.ts.map +1 -1
  49. package/esm/abstract/edwards.js +167 -171
  50. package/esm/abstract/edwards.js.map +1 -1
  51. package/esm/abstract/modular.d.ts +1 -1
  52. package/esm/abstract/modular.d.ts.map +1 -1
  53. package/esm/abstract/modular.js +4 -4
  54. package/esm/abstract/modular.js.map +1 -1
  55. package/esm/abstract/montgomery.d.ts +2 -6
  56. package/esm/abstract/montgomery.d.ts.map +1 -1
  57. package/esm/abstract/montgomery.js +14 -11
  58. package/esm/abstract/montgomery.js.map +1 -1
  59. package/esm/abstract/tower.d.ts +9 -7
  60. package/esm/abstract/tower.d.ts.map +1 -1
  61. package/esm/abstract/tower.js +570 -358
  62. package/esm/abstract/tower.js.map +1 -1
  63. package/esm/abstract/weierstrass.d.ts +162 -92
  64. package/esm/abstract/weierstrass.d.ts.map +1 -1
  65. package/esm/abstract/weierstrass.js +395 -338
  66. package/esm/abstract/weierstrass.js.map +1 -1
  67. package/esm/bls12-381.d.ts.map +1 -1
  68. package/esm/bls12-381.js +10 -43
  69. package/esm/bls12-381.js.map +1 -1
  70. package/esm/bn254.d.ts.map +1 -1
  71. package/esm/bn254.js +3 -35
  72. package/esm/bn254.js.map +1 -1
  73. package/esm/ed25519.d.ts +15 -15
  74. package/esm/ed25519.d.ts.map +1 -1
  75. package/esm/ed25519.js +51 -48
  76. package/esm/ed25519.js.map +1 -1
  77. package/esm/ed448.d.ts +16 -17
  78. package/esm/ed448.d.ts.map +1 -1
  79. package/esm/ed448.js +68 -49
  80. package/esm/ed448.js.map +1 -1
  81. package/esm/misc.js +2 -2
  82. package/esm/misc.js.map +1 -1
  83. package/esm/nist.d.ts +6 -0
  84. package/esm/nist.d.ts.map +1 -1
  85. package/esm/nist.js +6 -0
  86. package/esm/nist.js.map +1 -1
  87. package/esm/secp256k1.d.ts +2 -6
  88. package/esm/secp256k1.d.ts.map +1 -1
  89. package/esm/secp256k1.js +34 -35
  90. package/esm/secp256k1.js.map +1 -1
  91. package/esm/utils.d.ts +14 -0
  92. package/esm/utils.d.ts.map +1 -1
  93. package/esm/utils.js +43 -0
  94. package/esm/utils.js.map +1 -1
  95. package/misc.js +2 -2
  96. package/misc.js.map +1 -1
  97. package/nist.d.ts +6 -0
  98. package/nist.d.ts.map +1 -1
  99. package/nist.js +7 -1
  100. package/nist.js.map +1 -1
  101. package/package.json +2 -2
  102. package/secp256k1.d.ts +2 -6
  103. package/secp256k1.d.ts.map +1 -1
  104. package/secp256k1.js +33 -34
  105. package/secp256k1.js.map +1 -1
  106. package/src/abstract/bls.ts +2 -2
  107. package/src/abstract/curve.ts +131 -68
  108. package/src/abstract/edwards.ts +210 -219
  109. package/src/abstract/modular.ts +4 -4
  110. package/src/abstract/montgomery.ts +16 -16
  111. package/src/abstract/tower.ts +630 -382
  112. package/src/abstract/weierstrass.ts +587 -484
  113. package/src/bls12-381.ts +10 -42
  114. package/src/bn254.ts +3 -34
  115. package/src/ed25519.ts +62 -58
  116. package/src/ed448.ts +74 -77
  117. package/src/misc.ts +2 -2
  118. package/src/nist.ts +7 -0
  119. package/src/secp256k1.ts +35 -36
  120. package/src/utils.ts +48 -0
  121. package/utils.d.ts +14 -0
  122. package/utils.d.ts.map +1 -1
  123. package/utils.js +47 -0
  124. package/utils.js.map +1 -1
package/abstract/tower.js CHANGED
@@ -66,23 +66,79 @@ function psiFrobenius(Fp, Fp2, base) {
66
66
  const G2psi2 = mapAffine(psi2);
67
67
  return { psi, psi2, G2psi, G2psi2, PSI_X, PSI_Y, PSI2_X, PSI2_Y };
68
68
  }
69
- function tower12(opts) {
70
- const { ORDER } = opts;
71
- // Fp
72
- const Fp = mod.Field(ORDER);
73
- const FpNONRESIDUE = Fp.create(opts.NONRESIDUE || BigInt(-1));
74
- const Fpdiv2 = Fp.div(Fp.ONE, _2n); // 1/2
75
- // Fp2
76
- const FP2_FROBENIUS_COEFFICIENTS = calcFrobeniusCoefficients(Fp, FpNONRESIDUE, Fp.ORDER, 2)[0];
77
- const Fp2Add = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
78
- c0: Fp.add(c0, r0),
79
- c1: Fp.add(c1, r1),
80
- });
81
- const Fp2Subtract = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
82
- c0: Fp.sub(c0, r0),
83
- c1: Fp.sub(c1, r1),
84
- });
85
- const Fp2Multiply = ({ c0, c1 }, rhs) => {
69
+ const Fp2fromBigTuple = (Fp, tuple) => {
70
+ if (tuple.length !== 2)
71
+ throw new Error('invalid tuple');
72
+ const fps = tuple.map((n) => Fp.create(n));
73
+ return { c0: fps[0], c1: fps[1] };
74
+ };
75
+ class _Field2 {
76
+ constructor(Fp, opts = {}) {
77
+ this.MASK = _1n;
78
+ const ORDER = Fp.ORDER;
79
+ const FP2_ORDER = ORDER * ORDER;
80
+ this.Fp = Fp;
81
+ this.ORDER = FP2_ORDER;
82
+ this.BITS = (0, utils_ts_1.bitLen)(FP2_ORDER);
83
+ this.BYTES = Math.ceil((0, utils_ts_1.bitLen)(FP2_ORDER) / 8);
84
+ this.isLE = Fp.isLE;
85
+ this.ZERO = { c0: Fp.ZERO, c1: Fp.ZERO };
86
+ this.ONE = { c0: Fp.ONE, c1: Fp.ZERO };
87
+ this.Fp_NONRESIDUE = Fp.create(opts.NONRESIDUE || BigInt(-1));
88
+ this.Fp_div2 = Fp.div(Fp.ONE, _2n); // 1/2
89
+ this.NONRESIDUE = Fp2fromBigTuple(Fp, opts.FP2_NONRESIDUE);
90
+ // const Fp2Nonresidue = Fp2fromBigTuple(opts.FP2_NONRESIDUE);
91
+ this.FROBENIUS_COEFFICIENTS = calcFrobeniusCoefficients(Fp, this.Fp_NONRESIDUE, Fp.ORDER, 2)[0];
92
+ this.mulByB = opts.Fp2mulByB;
93
+ Object.seal(this);
94
+ }
95
+ fromBigTuple(tuple) {
96
+ return Fp2fromBigTuple(this.Fp, tuple);
97
+ }
98
+ create(num) {
99
+ return num;
100
+ }
101
+ isValid({ c0, c1 }) {
102
+ function isValidC(num, ORDER) {
103
+ return typeof num === 'bigint' && _0n <= num && num < ORDER;
104
+ }
105
+ return isValidC(c0, this.ORDER) && isValidC(c1, this.ORDER);
106
+ }
107
+ is0({ c0, c1 }) {
108
+ return this.Fp.is0(c0) && this.Fp.is0(c1);
109
+ }
110
+ isValidNot0(num) {
111
+ return !this.is0(num) && this.isValid(num);
112
+ }
113
+ eql({ c0, c1 }, { c0: r0, c1: r1 }) {
114
+ return this.Fp.eql(c0, r0) && this.Fp.eql(c1, r1);
115
+ }
116
+ neg({ c0, c1 }) {
117
+ return { c0: this.Fp.neg(c0), c1: this.Fp.neg(c1) };
118
+ }
119
+ pow(num, power) {
120
+ return mod.FpPow(this, num, power);
121
+ }
122
+ invertBatch(nums) {
123
+ return mod.FpInvertBatch(this, nums);
124
+ }
125
+ // Normalized
126
+ add(f1, f2) {
127
+ const { c0, c1 } = f1;
128
+ const { c0: r0, c1: r1 } = f2;
129
+ return {
130
+ c0: this.Fp.add(c0, r0),
131
+ c1: this.Fp.add(c1, r1),
132
+ };
133
+ }
134
+ sub({ c0, c1 }, { c0: r0, c1: r1 }) {
135
+ return {
136
+ c0: this.Fp.sub(c0, r0),
137
+ c1: this.Fp.sub(c1, r1),
138
+ };
139
+ }
140
+ mul({ c0, c1 }, rhs) {
141
+ const { Fp } = this;
86
142
  if (typeof rhs === 'bigint')
87
143
  return { c0: Fp.mul(c0, rhs), c1: Fp.mul(c1, rhs) };
88
144
  // (a+bi)(c+di) = (ac−bd) + (ad+bc)i
@@ -93,142 +149,163 @@ function tower12(opts) {
93
149
  const o0 = Fp.sub(t1, t2);
94
150
  const o1 = Fp.sub(Fp.mul(Fp.add(c0, c1), Fp.add(r0, r1)), Fp.add(t1, t2));
95
151
  return { c0: o0, c1: o1 };
96
- };
97
- const Fp2Square = ({ c0, c1 }) => {
152
+ }
153
+ sqr({ c0, c1 }) {
154
+ const { Fp } = this;
98
155
  const a = Fp.add(c0, c1);
99
156
  const b = Fp.sub(c0, c1);
100
157
  const c = Fp.add(c0, c0);
101
158
  return { c0: Fp.mul(a, b), c1: Fp.mul(c, c1) };
102
- };
103
- const Fp2fromBigTuple = (tuple) => {
104
- if (tuple.length !== 2)
105
- throw new Error('invalid tuple');
106
- const fps = tuple.map((n) => Fp.create(n));
107
- return { c0: fps[0], c1: fps[1] };
108
- };
109
- function isValidC(num, ORDER) {
110
- return typeof num === 'bigint' && _0n <= num && num < ORDER;
111
- }
112
- const FP2_ORDER = ORDER * ORDER;
113
- const Fp2Nonresidue = Fp2fromBigTuple(opts.FP2_NONRESIDUE);
114
- const Fp2 = {
115
- ORDER: FP2_ORDER,
116
- isLE: Fp.isLE,
117
- NONRESIDUE: Fp2Nonresidue,
118
- BITS: (0, utils_ts_1.bitLen)(FP2_ORDER),
119
- BYTES: Math.ceil((0, utils_ts_1.bitLen)(FP2_ORDER) / 8),
120
- MASK: (0, utils_ts_1.bitMask)((0, utils_ts_1.bitLen)(FP2_ORDER)),
121
- ZERO: { c0: Fp.ZERO, c1: Fp.ZERO },
122
- ONE: { c0: Fp.ONE, c1: Fp.ZERO },
123
- create: (num) => num,
124
- isValid: ({ c0, c1 }) => isValidC(c0, FP2_ORDER) && isValidC(c1, FP2_ORDER),
125
- is0: ({ c0, c1 }) => Fp.is0(c0) && Fp.is0(c1),
126
- isValidNot0: (num) => !Fp2.is0(num) && Fp2.isValid(num),
127
- eql: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp.eql(c0, r0) && Fp.eql(c1, r1),
128
- neg: ({ c0, c1 }) => ({ c0: Fp.neg(c0), c1: Fp.neg(c1) }),
129
- pow: (num, power) => mod.FpPow(Fp2, num, power),
130
- invertBatch: (nums) => mod.FpInvertBatch(Fp2, nums),
131
- // Normalized
132
- add: Fp2Add,
133
- sub: Fp2Subtract,
134
- mul: Fp2Multiply,
135
- sqr: Fp2Square,
136
- // NonNormalized stuff
137
- addN: Fp2Add,
138
- subN: Fp2Subtract,
139
- mulN: Fp2Multiply,
140
- sqrN: Fp2Square,
141
- // Why inversion for bigint inside Fp instead of Fp2? it is even used in that context?
142
- div: (lhs, rhs) => Fp2.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp2.inv(rhs)),
143
- inv: ({ c0: a, c1: b }) => {
144
- // We wish to find the multiplicative inverse of a nonzero
145
- // element a + bu in Fp2. We leverage an identity
146
- //
147
- // (a + bu)(a - bu) = a² + b²
148
- //
149
- // which holds because u² = -1. This can be rewritten as
150
- //
151
- // (a + bu)(a - bu)/(a² + b²) = 1
152
- //
153
- // because a² + b² = 0 has no nonzero solutions for (a, b).
154
- // This gives that (a - bu)/(a² + b²) is the inverse
155
- // of (a + bu). Importantly, this can be computing using
156
- // only a single inversion in Fp.
157
- const factor = Fp.inv(Fp.create(a * a + b * b));
158
- return { c0: Fp.mul(factor, Fp.create(a)), c1: Fp.mul(factor, Fp.create(-b)) };
159
- },
160
- sqrt: (num) => {
161
- if (opts.Fp2sqrt)
162
- return opts.Fp2sqrt(num);
163
- // This is generic for all quadratic extensions (Fp2)
164
- const { c0, c1 } = num;
165
- if (Fp.is0(c1)) {
166
- // if c0 is quadratic residue
167
- if (mod.FpLegendre(Fp, c0) === 1)
168
- return Fp2.create({ c0: Fp.sqrt(c0), c1: Fp.ZERO });
169
- else
170
- return Fp2.create({ c0: Fp.ZERO, c1: Fp.sqrt(Fp.div(c0, FpNONRESIDUE)) });
171
- }
172
- const a = Fp.sqrt(Fp.sub(Fp.sqr(c0), Fp.mul(Fp.sqr(c1), FpNONRESIDUE)));
173
- let d = Fp.mul(Fp.add(a, c0), Fpdiv2);
174
- const legendre = mod.FpLegendre(Fp, d);
175
- // -1, Quadratic non residue
176
- if (legendre === -1)
177
- d = Fp.sub(d, a);
178
- const a0 = Fp.sqrt(d);
179
- const candidateSqrt = Fp2.create({ c0: a0, c1: Fp.div(Fp.mul(c1, Fpdiv2), a0) });
180
- if (!Fp2.eql(Fp2.sqr(candidateSqrt), num))
181
- throw new Error('Cannot find square root');
182
- // Normalize root: at this point candidateSqrt ** 2 = num, but also -candidateSqrt ** 2 = num
183
- const x1 = candidateSqrt;
184
- const x2 = Fp2.neg(x1);
185
- const { re: re1, im: im1 } = Fp2.reim(x1);
186
- const { re: re2, im: im2 } = Fp2.reim(x2);
187
- if (im1 > im2 || (im1 === im2 && re1 > re2))
188
- return x1;
189
- return x2;
190
- },
191
- // Same as sgn0_m_eq_2 in RFC 9380
192
- isOdd: (x) => {
193
- const { re: x0, im: x1 } = Fp2.reim(x);
194
- const sign_0 = x0 % _2n;
195
- const zero_0 = x0 === _0n;
196
- const sign_1 = x1 % _2n;
197
- return BigInt(sign_0 || (zero_0 && sign_1)) == _1n;
198
- },
199
- // Bytes util
200
- fromBytes(b) {
201
- if (b.length !== Fp2.BYTES)
202
- throw new Error('fromBytes invalid length=' + b.length);
203
- return { c0: Fp.fromBytes(b.subarray(0, Fp.BYTES)), c1: Fp.fromBytes(b.subarray(Fp.BYTES)) };
204
- },
205
- toBytes: ({ c0, c1 }) => (0, utils_ts_1.concatBytes)(Fp.toBytes(c0), Fp.toBytes(c1)),
206
- cmov: ({ c0, c1 }, { c0: r0, c1: r1 }, c) => ({
207
- c0: Fp.cmov(c0, r0, c),
208
- c1: Fp.cmov(c1, r1, c),
209
- }),
210
- reim: ({ c0, c1 }) => ({ re: c0, im: c1 }),
211
- // multiply by u + 1
212
- mulByNonresidue: ({ c0, c1 }) => Fp2.mul({ c0, c1 }, Fp2Nonresidue),
213
- mulByB: opts.Fp2mulByB,
214
- fromBigTuple: Fp2fromBigTuple,
215
- frobeniusMap: ({ c0, c1 }, power) => ({
159
+ }
160
+ // NonNormalized stuff
161
+ addN(a, b) {
162
+ return this.add(a, b);
163
+ }
164
+ subN(a, b) {
165
+ return this.sub(a, b);
166
+ }
167
+ mulN(a, b) {
168
+ return this.mul(a, b);
169
+ }
170
+ sqrN(a) {
171
+ return this.sqr(a);
172
+ }
173
+ // Why inversion for bigint inside Fp instead of Fp2? it is even used in that context?
174
+ div(lhs, rhs) {
175
+ const { Fp } = this;
176
+ // @ts-ignore
177
+ return this.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : this.inv(rhs));
178
+ }
179
+ inv({ c0: a, c1: b }) {
180
+ // We wish to find the multiplicative inverse of a nonzero
181
+ // element a + bu in Fp2. We leverage an identity
182
+ //
183
+ // (a + bu)(a - bu) = a² + b²
184
+ //
185
+ // which holds because = -1. This can be rewritten as
186
+ //
187
+ // (a + bu)(a - bu)/( + b²) = 1
188
+ //
189
+ // because a² + b² = 0 has no nonzero solutions for (a, b).
190
+ // This gives that (a - bu)/(a² + b²) is the inverse
191
+ // of (a + bu). Importantly, this can be computing using
192
+ // only a single inversion in Fp.
193
+ const { Fp } = this;
194
+ const factor = Fp.inv(Fp.create(a * a + b * b));
195
+ return { c0: Fp.mul(factor, Fp.create(a)), c1: Fp.mul(factor, Fp.create(-b)) };
196
+ }
197
+ sqrt(num) {
198
+ // This is generic for all quadratic extensions (Fp2)
199
+ const { Fp } = this;
200
+ const Fp2 = this;
201
+ const { c0, c1 } = num;
202
+ if (Fp.is0(c1)) {
203
+ // if c0 is quadratic residue
204
+ if (mod.FpLegendre(Fp, c0) === 1)
205
+ return Fp2.create({ c0: Fp.sqrt(c0), c1: Fp.ZERO });
206
+ else
207
+ return Fp2.create({ c0: Fp.ZERO, c1: Fp.sqrt(Fp.div(c0, this.Fp_NONRESIDUE)) });
208
+ }
209
+ const a = Fp.sqrt(Fp.sub(Fp.sqr(c0), Fp.mul(Fp.sqr(c1), this.Fp_NONRESIDUE)));
210
+ let d = Fp.mul(Fp.add(a, c0), this.Fp_div2);
211
+ const legendre = mod.FpLegendre(Fp, d);
212
+ // -1, Quadratic non residue
213
+ if (legendre === -1)
214
+ d = Fp.sub(d, a);
215
+ const a0 = Fp.sqrt(d);
216
+ const candidateSqrt = Fp2.create({ c0: a0, c1: Fp.div(Fp.mul(c1, this.Fp_div2), a0) });
217
+ if (!Fp2.eql(Fp2.sqr(candidateSqrt), num))
218
+ throw new Error('Cannot find square root');
219
+ // Normalize root: at this point candidateSqrt ** 2 = num, but also -candidateSqrt ** 2 = num
220
+ const x1 = candidateSqrt;
221
+ const x2 = Fp2.neg(x1);
222
+ const { re: re1, im: im1 } = Fp2.reim(x1);
223
+ const { re: re2, im: im2 } = Fp2.reim(x2);
224
+ if (im1 > im2 || (im1 === im2 && re1 > re2))
225
+ return x1;
226
+ return x2;
227
+ }
228
+ // Same as sgn0_m_eq_2 in RFC 9380
229
+ isOdd(x) {
230
+ const { re: x0, im: x1 } = this.reim(x);
231
+ const sign_0 = x0 % _2n;
232
+ const zero_0 = x0 === _0n;
233
+ const sign_1 = x1 % _2n;
234
+ return BigInt(sign_0 || (zero_0 && sign_1)) == _1n;
235
+ }
236
+ // Bytes util
237
+ fromBytes(b) {
238
+ const { Fp } = this;
239
+ if (b.length !== this.BYTES)
240
+ throw new Error('fromBytes invalid length=' + b.length);
241
+ return { c0: Fp.fromBytes(b.subarray(0, Fp.BYTES)), c1: Fp.fromBytes(b.subarray(Fp.BYTES)) };
242
+ }
243
+ toBytes({ c0, c1 }) {
244
+ return (0, utils_ts_1.concatBytes)(this.Fp.toBytes(c0), this.Fp.toBytes(c1));
245
+ }
246
+ cmov({ c0, c1 }, { c0: r0, c1: r1 }, c) {
247
+ return {
248
+ c0: this.Fp.cmov(c0, r0, c),
249
+ c1: this.Fp.cmov(c1, r1, c),
250
+ };
251
+ }
252
+ reim({ c0, c1 }) {
253
+ return { re: c0, im: c1 };
254
+ }
255
+ Fp4Square(a, b) {
256
+ const Fp2 = this;
257
+ const a2 = Fp2.sqr(a);
258
+ const b2 = Fp2.sqr(b);
259
+ return {
260
+ first: Fp2.add(Fp2.mulByNonresidue(b2), a2), // b² * Nonresidue + a²
261
+ second: Fp2.sub(Fp2.sub(Fp2.sqr(Fp2.add(a, b)), a2), b2), // (a + b)² - a² - b²
262
+ };
263
+ }
264
+ // multiply by u + 1
265
+ mulByNonresidue({ c0, c1 }) {
266
+ return this.mul({ c0, c1 }, this.NONRESIDUE);
267
+ }
268
+ frobeniusMap({ c0, c1 }, power) {
269
+ return {
216
270
  c0,
217
- c1: Fp.mul(c1, FP2_FROBENIUS_COEFFICIENTS[power % 2]),
218
- }),
219
- };
220
- // Fp6
221
- const Fp6Add = ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => ({
222
- c0: Fp2.add(c0, r0),
223
- c1: Fp2.add(c1, r1),
224
- c2: Fp2.add(c2, r2),
225
- });
226
- const Fp6Subtract = ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => ({
227
- c0: Fp2.sub(c0, r0),
228
- c1: Fp2.sub(c1, r1),
229
- c2: Fp2.sub(c2, r2),
230
- });
231
- const Fp6Multiply = ({ c0, c1, c2 }, rhs) => {
271
+ c1: this.Fp.mul(c1, this.FROBENIUS_COEFFICIENTS[power % 2]),
272
+ };
273
+ }
274
+ }
275
+ class _Field6 {
276
+ constructor(Fp2) {
277
+ this.MASK = _1n;
278
+ this.Fp2 = Fp2;
279
+ this.ORDER = Fp2.ORDER; // TODO: unused, but need to verify
280
+ this.BITS = 3 * Fp2.BITS;
281
+ this.BYTES = 3 * Fp2.BYTES;
282
+ this.isLE = Fp2.isLE;
283
+ this.ZERO = { c0: Fp2.ZERO, c1: Fp2.ZERO, c2: Fp2.ZERO };
284
+ this.ONE = { c0: Fp2.ONE, c1: Fp2.ZERO, c2: Fp2.ZERO };
285
+ const { Fp } = Fp2;
286
+ const frob = calcFrobeniusCoefficients(Fp2, Fp2.NONRESIDUE, Fp.ORDER, 6, 2, 3);
287
+ this.FROBENIUS_COEFFICIENTS_1 = frob[0];
288
+ this.FROBENIUS_COEFFICIENTS_2 = frob[1];
289
+ Object.seal(this);
290
+ }
291
+ add({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) {
292
+ const { Fp2 } = this;
293
+ return {
294
+ c0: Fp2.add(c0, r0),
295
+ c1: Fp2.add(c1, r1),
296
+ c2: Fp2.add(c2, r2),
297
+ };
298
+ }
299
+ sub({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) {
300
+ const { Fp2 } = this;
301
+ return {
302
+ c0: Fp2.sub(c0, r0),
303
+ c1: Fp2.sub(c1, r1),
304
+ c2: Fp2.sub(c2, r2),
305
+ };
306
+ }
307
+ mul({ c0, c1, c2 }, rhs) {
308
+ const { Fp2 } = this;
232
309
  if (typeof rhs === 'bigint') {
233
310
  return {
234
311
  c0: Fp2.mul(c0, rhs),
@@ -248,8 +325,9 @@ function tower12(opts) {
248
325
  // T1 + (c0 + c2) * (r0 + r2) - T0 + T2
249
326
  c2: Fp2.sub(Fp2.add(t1, Fp2.mul(Fp2.add(c0, c2), Fp2.add(r0, r2))), Fp2.add(t0, t2)),
250
327
  };
251
- };
252
- const Fp6Square = ({ c0, c1, c2 }) => {
328
+ }
329
+ sqr({ c0, c1, c2 }) {
330
+ const { Fp2 } = this;
253
331
  let t0 = Fp2.sqr(c0); // c0²
254
332
  let t1 = Fp2.mul(Fp2.mul(c0, c1), _2n); // 2 * c0 * c1
255
333
  let t3 = Fp2.mul(Fp2.mul(c1, c2), _2n); // 2 * c1 * c2
@@ -260,112 +338,218 @@ function tower12(opts) {
260
338
  // T1 + (c0 - c1 + c2)² + T3 - T0 - T4
261
339
  c2: Fp2.sub(Fp2.sub(Fp2.add(Fp2.add(t1, Fp2.sqr(Fp2.add(Fp2.sub(c0, c1), c2))), t3), t0), t4),
262
340
  };
263
- };
264
- const [FP6_FROBENIUS_COEFFICIENTS_1, FP6_FROBENIUS_COEFFICIENTS_2] = calcFrobeniusCoefficients(Fp2, Fp2Nonresidue, Fp.ORDER, 6, 2, 3);
265
- const Fp6 = {
266
- ORDER: Fp2.ORDER, // TODO: unused, but need to verify
267
- isLE: Fp2.isLE,
268
- BITS: 3 * Fp2.BITS,
269
- BYTES: 3 * Fp2.BYTES,
270
- MASK: (0, utils_ts_1.bitMask)(3 * Fp2.BITS),
271
- ZERO: { c0: Fp2.ZERO, c1: Fp2.ZERO, c2: Fp2.ZERO },
272
- ONE: { c0: Fp2.ONE, c1: Fp2.ZERO, c2: Fp2.ZERO },
273
- create: (num) => num,
274
- isValid: ({ c0, c1, c2 }) => Fp2.isValid(c0) && Fp2.isValid(c1) && Fp2.isValid(c2),
275
- is0: ({ c0, c1, c2 }) => Fp2.is0(c0) && Fp2.is0(c1) && Fp2.is0(c2),
276
- isValidNot0: (num) => !Fp6.is0(num) && Fp6.isValid(num),
277
- neg: ({ c0, c1, c2 }) => ({ c0: Fp2.neg(c0), c1: Fp2.neg(c1), c2: Fp2.neg(c2) }),
278
- eql: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => Fp2.eql(c0, r0) && Fp2.eql(c1, r1) && Fp2.eql(c2, r2),
279
- sqrt: utils_ts_1.notImplemented,
280
- // Do we need division by bigint at all? Should be done via order:
281
- div: (lhs, rhs) => Fp6.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp6.inv(rhs)),
282
- pow: (num, power) => mod.FpPow(Fp6, num, power),
283
- invertBatch: (nums) => mod.FpInvertBatch(Fp6, nums),
284
- // Normalized
285
- add: Fp6Add,
286
- sub: Fp6Subtract,
287
- mul: Fp6Multiply,
288
- sqr: Fp6Square,
289
- // NonNormalized stuff
290
- addN: Fp6Add,
291
- subN: Fp6Subtract,
292
- mulN: Fp6Multiply,
293
- sqrN: Fp6Square,
294
- inv: ({ c0, c1, c2 }) => {
295
- let t0 = Fp2.sub(Fp2.sqr(c0), Fp2.mulByNonresidue(Fp2.mul(c2, c1))); // c0² - c2 * c1 * (u + 1)
296
- let t1 = Fp2.sub(Fp2.mulByNonresidue(Fp2.sqr(c2)), Fp2.mul(c0, c1)); // c2² * (u + 1) - c0 * c1
297
- let t2 = Fp2.sub(Fp2.sqr(c1), Fp2.mul(c0, c2)); // c1² - c0 * c2
298
- // 1/(((c2 * T1 + c1 * T2) * v) + c0 * T0)
299
- let t4 = Fp2.inv(Fp2.add(Fp2.mulByNonresidue(Fp2.add(Fp2.mul(c2, t1), Fp2.mul(c1, t2))), Fp2.mul(c0, t0)));
300
- return { c0: Fp2.mul(t4, t0), c1: Fp2.mul(t4, t1), c2: Fp2.mul(t4, t2) };
301
- },
302
- // Bytes utils
303
- fromBytes: (b) => {
304
- if (b.length !== Fp6.BYTES)
305
- throw new Error('fromBytes invalid length=' + b.length);
306
- return {
307
- c0: Fp2.fromBytes(b.subarray(0, Fp2.BYTES)),
308
- c1: Fp2.fromBytes(b.subarray(Fp2.BYTES, 2 * Fp2.BYTES)),
309
- c2: Fp2.fromBytes(b.subarray(2 * Fp2.BYTES)),
310
- };
311
- },
312
- toBytes: ({ c0, c1, c2 }) => (0, utils_ts_1.concatBytes)(Fp2.toBytes(c0), Fp2.toBytes(c1), Fp2.toBytes(c2)),
313
- cmov: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }, c) => ({
341
+ }
342
+ addN(a, b) {
343
+ return this.add(a, b);
344
+ }
345
+ subN(a, b) {
346
+ return this.sub(a, b);
347
+ }
348
+ mulN(a, b) {
349
+ return this.mul(a, b);
350
+ }
351
+ sqrN(a) {
352
+ return this.sqr(a);
353
+ }
354
+ create(num) {
355
+ return num;
356
+ }
357
+ isValid({ c0, c1, c2 }) {
358
+ const { Fp2 } = this;
359
+ return Fp2.isValid(c0) && Fp2.isValid(c1) && Fp2.isValid(c2);
360
+ }
361
+ is0({ c0, c1, c2 }) {
362
+ const { Fp2 } = this;
363
+ return Fp2.is0(c0) && Fp2.is0(c1) && Fp2.is0(c2);
364
+ }
365
+ isValidNot0(num) {
366
+ return !this.is0(num) && this.isValid(num);
367
+ }
368
+ neg({ c0, c1, c2 }) {
369
+ const { Fp2 } = this;
370
+ return { c0: Fp2.neg(c0), c1: Fp2.neg(c1), c2: Fp2.neg(c2) };
371
+ }
372
+ eql({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) {
373
+ const { Fp2 } = this;
374
+ return Fp2.eql(c0, r0) && Fp2.eql(c1, r1) && Fp2.eql(c2, r2);
375
+ }
376
+ sqrt(_) {
377
+ return (0, utils_ts_1.notImplemented)();
378
+ }
379
+ // Do we need division by bigint at all? Should be done via order:
380
+ div(lhs, rhs) {
381
+ const { Fp2 } = this;
382
+ const { Fp } = Fp2;
383
+ return this.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : this.inv(rhs));
384
+ }
385
+ pow(num, power) {
386
+ return mod.FpPow(this, num, power);
387
+ }
388
+ invertBatch(nums) {
389
+ return mod.FpInvertBatch(this, nums);
390
+ }
391
+ inv({ c0, c1, c2 }) {
392
+ const { Fp2 } = this;
393
+ let t0 = Fp2.sub(Fp2.sqr(c0), Fp2.mulByNonresidue(Fp2.mul(c2, c1))); // c0² - c2 * c1 * (u + 1)
394
+ let t1 = Fp2.sub(Fp2.mulByNonresidue(Fp2.sqr(c2)), Fp2.mul(c0, c1)); // c2² * (u + 1) - c0 * c1
395
+ let t2 = Fp2.sub(Fp2.sqr(c1), Fp2.mul(c0, c2)); // c1² - c0 * c2
396
+ // 1/(((c2 * T1 + c1 * T2) * v) + c0 * T0)
397
+ let t4 = Fp2.inv(Fp2.add(Fp2.mulByNonresidue(Fp2.add(Fp2.mul(c2, t1), Fp2.mul(c1, t2))), Fp2.mul(c0, t0)));
398
+ return { c0: Fp2.mul(t4, t0), c1: Fp2.mul(t4, t1), c2: Fp2.mul(t4, t2) };
399
+ }
400
+ // Bytes utils
401
+ fromBytes(b) {
402
+ const { Fp2 } = this;
403
+ if (b.length !== this.BYTES)
404
+ throw new Error('fromBytes invalid length=' + b.length);
405
+ const B2 = Fp2.BYTES;
406
+ return {
407
+ c0: Fp2.fromBytes(b.subarray(0, B2)),
408
+ c1: Fp2.fromBytes(b.subarray(B2, B2 * 2)),
409
+ c2: Fp2.fromBytes(b.subarray(2 * B2)),
410
+ };
411
+ }
412
+ toBytes({ c0, c1, c2 }) {
413
+ const { Fp2 } = this;
414
+ return (0, utils_ts_1.concatBytes)(Fp2.toBytes(c0), Fp2.toBytes(c1), Fp2.toBytes(c2));
415
+ }
416
+ cmov({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }, c) {
417
+ const { Fp2 } = this;
418
+ return {
314
419
  c0: Fp2.cmov(c0, r0, c),
315
420
  c1: Fp2.cmov(c1, r1, c),
316
421
  c2: Fp2.cmov(c2, r2, c),
317
- }),
318
- fromBigSix: (t) => {
319
- if (!Array.isArray(t) || t.length !== 6)
320
- throw new Error('invalid Fp6 usage');
321
- return {
322
- c0: Fp2.fromBigTuple(t.slice(0, 2)),
323
- c1: Fp2.fromBigTuple(t.slice(2, 4)),
324
- c2: Fp2.fromBigTuple(t.slice(4, 6)),
325
- };
326
- },
327
- frobeniusMap: ({ c0, c1, c2 }, power) => ({
422
+ };
423
+ }
424
+ fromBigSix(t) {
425
+ const { Fp2 } = this;
426
+ if (!Array.isArray(t) || t.length !== 6)
427
+ throw new Error('invalid Fp6 usage');
428
+ return {
429
+ c0: Fp2.fromBigTuple(t.slice(0, 2)),
430
+ c1: Fp2.fromBigTuple(t.slice(2, 4)),
431
+ c2: Fp2.fromBigTuple(t.slice(4, 6)),
432
+ };
433
+ }
434
+ frobeniusMap({ c0, c1, c2 }, power) {
435
+ const { Fp2 } = this;
436
+ return {
328
437
  c0: Fp2.frobeniusMap(c0, power),
329
- c1: Fp2.mul(Fp2.frobeniusMap(c1, power), FP6_FROBENIUS_COEFFICIENTS_1[power % 6]),
330
- c2: Fp2.mul(Fp2.frobeniusMap(c2, power), FP6_FROBENIUS_COEFFICIENTS_2[power % 6]),
331
- }),
332
- mulByFp2: ({ c0, c1, c2 }, rhs) => ({
438
+ c1: Fp2.mul(Fp2.frobeniusMap(c1, power), this.FROBENIUS_COEFFICIENTS_1[power % 6]),
439
+ c2: Fp2.mul(Fp2.frobeniusMap(c2, power), this.FROBENIUS_COEFFICIENTS_2[power % 6]),
440
+ };
441
+ }
442
+ mulByFp2({ c0, c1, c2 }, rhs) {
443
+ const { Fp2 } = this;
444
+ return {
333
445
  c0: Fp2.mul(c0, rhs),
334
446
  c1: Fp2.mul(c1, rhs),
335
447
  c2: Fp2.mul(c2, rhs),
336
- }),
337
- mulByNonresidue: ({ c0, c1, c2 }) => ({ c0: Fp2.mulByNonresidue(c2), c1: c0, c2: c1 }),
338
- // Sparse multiplication
339
- mul1: ({ c0, c1, c2 }, b1) => ({
448
+ };
449
+ }
450
+ mulByNonresidue({ c0, c1, c2 }) {
451
+ const { Fp2 } = this;
452
+ return { c0: Fp2.mulByNonresidue(c2), c1: c0, c2: c1 };
453
+ }
454
+ // Sparse multiplication
455
+ mul1({ c0, c1, c2 }, b1) {
456
+ const { Fp2 } = this;
457
+ return {
340
458
  c0: Fp2.mulByNonresidue(Fp2.mul(c2, b1)),
341
459
  c1: Fp2.mul(c0, b1),
342
460
  c2: Fp2.mul(c1, b1),
343
- }),
344
- // Sparse multiplication
345
- mul01({ c0, c1, c2 }, b0, b1) {
346
- let t0 = Fp2.mul(c0, b0); // c0 * b0
347
- let t1 = Fp2.mul(c1, b1); // c1 * b1
348
- return {
349
- // ((c1 + c2) * b1 - T1) * (u + 1) + T0
350
- c0: Fp2.add(Fp2.mulByNonresidue(Fp2.sub(Fp2.mul(Fp2.add(c1, c2), b1), t1)), t0),
351
- // (b0 + b1) * (c0 + c1) - T0 - T1
352
- c1: Fp2.sub(Fp2.sub(Fp2.mul(Fp2.add(b0, b1), Fp2.add(c0, c1)), t0), t1),
353
- // (c0 + c2) * b0 - T0 + T1
354
- c2: Fp2.add(Fp2.sub(Fp2.mul(Fp2.add(c0, c2), b0), t0), t1),
355
- };
356
- },
357
- };
358
- // Fp12
359
- const FP12_FROBENIUS_COEFFICIENTS = calcFrobeniusCoefficients(Fp2, Fp2Nonresidue, Fp.ORDER, 12, 1, 6)[0];
360
- const Fp12Add = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
361
- c0: Fp6.add(c0, r0),
362
- c1: Fp6.add(c1, r1),
363
- });
364
- const Fp12Subtract = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
365
- c0: Fp6.sub(c0, r0),
366
- c1: Fp6.sub(c1, r1),
367
- });
368
- const Fp12Multiply = ({ c0, c1 }, rhs) => {
461
+ };
462
+ }
463
+ // Sparse multiplication
464
+ mul01({ c0, c1, c2 }, b0, b1) {
465
+ const { Fp2 } = this;
466
+ let t0 = Fp2.mul(c0, b0); // c0 * b0
467
+ let t1 = Fp2.mul(c1, b1); // c1 * b1
468
+ return {
469
+ // ((c1 + c2) * b1 - T1) * (u + 1) + T0
470
+ c0: Fp2.add(Fp2.mulByNonresidue(Fp2.sub(Fp2.mul(Fp2.add(c1, c2), b1), t1)), t0),
471
+ // (b0 + b1) * (c0 + c1) - T0 - T1
472
+ c1: Fp2.sub(Fp2.sub(Fp2.mul(Fp2.add(b0, b1), Fp2.add(c0, c1)), t0), t1),
473
+ // (c0 + c2) * b0 - T0 + T1
474
+ c2: Fp2.add(Fp2.sub(Fp2.mul(Fp2.add(c0, c2), b0), t0), t1),
475
+ };
476
+ }
477
+ }
478
+ class _Field12 {
479
+ constructor(Fp6, opts) {
480
+ this.MASK = _1n;
481
+ const { Fp2 } = Fp6;
482
+ const { Fp } = Fp2;
483
+ this.Fp6 = Fp6;
484
+ this.ORDER = Fp2.ORDER; // TODO: verify if it's unuesd
485
+ this.BITS = 2 * Fp6.BITS;
486
+ this.BYTES = 2 * Fp6.BYTES;
487
+ this.isLE = Fp6.isLE;
488
+ this.ZERO = { c0: Fp6.ZERO, c1: Fp6.ZERO };
489
+ this.ONE = { c0: Fp6.ONE, c1: Fp6.ZERO };
490
+ this.FROBENIUS_COEFFICIENTS = calcFrobeniusCoefficients(Fp2, Fp2.NONRESIDUE, Fp.ORDER, 12, 1, 6)[0];
491
+ this.X_LEN = opts.X_LEN;
492
+ this.finalExponentiate = opts.Fp12finalExponentiate;
493
+ }
494
+ create(num) {
495
+ return num;
496
+ }
497
+ isValid({ c0, c1 }) {
498
+ const { Fp6 } = this;
499
+ return Fp6.isValid(c0) && Fp6.isValid(c1);
500
+ }
501
+ is0({ c0, c1 }) {
502
+ const { Fp6 } = this;
503
+ return Fp6.is0(c0) && Fp6.is0(c1);
504
+ }
505
+ isValidNot0(num) {
506
+ return !this.is0(num) && this.isValid(num);
507
+ }
508
+ neg({ c0, c1 }) {
509
+ const { Fp6 } = this;
510
+ return { c0: Fp6.neg(c0), c1: Fp6.neg(c1) };
511
+ }
512
+ eql({ c0, c1 }, { c0: r0, c1: r1 }) {
513
+ const { Fp6 } = this;
514
+ return Fp6.eql(c0, r0) && Fp6.eql(c1, r1);
515
+ }
516
+ sqrt(_) {
517
+ (0, utils_ts_1.notImplemented)();
518
+ }
519
+ inv({ c0, c1 }) {
520
+ const { Fp6 } = this;
521
+ let t = Fp6.inv(Fp6.sub(Fp6.sqr(c0), Fp6.mulByNonresidue(Fp6.sqr(c1)))); // 1 / (c0² - c1² * v)
522
+ return { c0: Fp6.mul(c0, t), c1: Fp6.neg(Fp6.mul(c1, t)) }; // ((C0 * T) * T) + (-C1 * T) * w
523
+ }
524
+ div(lhs, rhs) {
525
+ const { Fp6 } = this;
526
+ const { Fp2 } = Fp6;
527
+ const { Fp } = Fp2;
528
+ return this.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : this.inv(rhs));
529
+ }
530
+ pow(num, power) {
531
+ return mod.FpPow(this, num, power);
532
+ }
533
+ invertBatch(nums) {
534
+ return mod.FpInvertBatch(this, nums);
535
+ }
536
+ // Normalized
537
+ add({ c0, c1 }, { c0: r0, c1: r1 }) {
538
+ const { Fp6 } = this;
539
+ return {
540
+ c0: Fp6.add(c0, r0),
541
+ c1: Fp6.add(c1, r1),
542
+ };
543
+ }
544
+ sub({ c0, c1 }, { c0: r0, c1: r1 }) {
545
+ const { Fp6 } = this;
546
+ return {
547
+ c0: Fp6.sub(c0, r0),
548
+ c1: Fp6.sub(c1, r1),
549
+ };
550
+ }
551
+ mul({ c0, c1 }, rhs) {
552
+ const { Fp6 } = this;
369
553
  if (typeof rhs === 'bigint')
370
554
  return { c0: Fp6.mul(c0, rhs), c1: Fp6.mul(c1, rhs) };
371
555
  let { c0: r0, c1: r1 } = rhs;
@@ -376,131 +560,159 @@ function tower12(opts) {
376
560
  // (c0 + c1) * (r0 + r1) - (T1 + T2)
377
561
  c1: Fp6.sub(Fp6.mul(Fp6.add(c0, c1), Fp6.add(r0, r1)), Fp6.add(t1, t2)),
378
562
  };
379
- };
380
- const Fp12Square = ({ c0, c1 }) => {
563
+ }
564
+ sqr({ c0, c1 }) {
565
+ const { Fp6 } = this;
381
566
  let ab = Fp6.mul(c0, c1); // c0 * c1
382
567
  return {
383
568
  // (c1 * v + c0) * (c0 + c1) - AB - AB * v
384
569
  c0: Fp6.sub(Fp6.sub(Fp6.mul(Fp6.add(Fp6.mulByNonresidue(c1), c0), Fp6.add(c0, c1)), ab), Fp6.mulByNonresidue(ab)),
385
570
  c1: Fp6.add(ab, ab),
386
571
  }; // AB + AB
387
- };
388
- function Fp4Square(a, b) {
389
- const a2 = Fp2.sqr(a);
390
- const b2 = Fp2.sqr(b);
572
+ }
573
+ // NonNormalized stuff
574
+ addN(a, b) {
575
+ return this.add(a, b);
576
+ }
577
+ subN(a, b) {
578
+ return this.sub(a, b);
579
+ }
580
+ mulN(a, b) {
581
+ return this.mul(a, b);
582
+ }
583
+ sqrN(a) {
584
+ return this.sqr(a);
585
+ }
586
+ // Bytes utils
587
+ fromBytes(b) {
588
+ const { Fp6 } = this;
589
+ if (b.length !== this.BYTES)
590
+ throw new Error('fromBytes invalid length=' + b.length);
391
591
  return {
392
- first: Fp2.add(Fp2.mulByNonresidue(b2), a2), // b² * Nonresidue + a²
393
- second: Fp2.sub(Fp2.sub(Fp2.sqr(Fp2.add(a, b)), a2), b2), // (a + b)² - a² - b²
592
+ c0: Fp6.fromBytes(b.subarray(0, Fp6.BYTES)),
593
+ c1: Fp6.fromBytes(b.subarray(Fp6.BYTES)),
394
594
  };
395
595
  }
396
- const Fp12 = {
397
- ORDER: Fp2.ORDER, // TODO: unused, but need to verify
398
- isLE: Fp6.isLE,
399
- BITS: 2 * Fp6.BITS,
400
- BYTES: 2 * Fp6.BYTES,
401
- MASK: (0, utils_ts_1.bitMask)(2 * Fp6.BITS),
402
- ZERO: { c0: Fp6.ZERO, c1: Fp6.ZERO },
403
- ONE: { c0: Fp6.ONE, c1: Fp6.ZERO },
404
- create: (num) => num,
405
- isValid: ({ c0, c1 }) => Fp6.isValid(c0) && Fp6.isValid(c1),
406
- is0: ({ c0, c1 }) => Fp6.is0(c0) && Fp6.is0(c1),
407
- isValidNot0: (num) => !Fp12.is0(num) && Fp12.isValid(num),
408
- neg: ({ c0, c1 }) => ({ c0: Fp6.neg(c0), c1: Fp6.neg(c1) }),
409
- eql: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp6.eql(c0, r0) && Fp6.eql(c1, r1),
410
- sqrt: utils_ts_1.notImplemented,
411
- inv: ({ c0, c1 }) => {
412
- let t = Fp6.inv(Fp6.sub(Fp6.sqr(c0), Fp6.mulByNonresidue(Fp6.sqr(c1)))); // 1 / (c0² - c1² * v)
413
- return { c0: Fp6.mul(c0, t), c1: Fp6.neg(Fp6.mul(c1, t)) }; // ((C0 * T) * T) + (-C1 * T) * w
414
- },
415
- div: (lhs, rhs) => Fp12.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp12.inv(rhs)),
416
- pow: (num, power) => mod.FpPow(Fp12, num, power),
417
- invertBatch: (nums) => mod.FpInvertBatch(Fp12, nums),
418
- // Normalized
419
- add: Fp12Add,
420
- sub: Fp12Subtract,
421
- mul: Fp12Multiply,
422
- sqr: Fp12Square,
423
- // NonNormalized stuff
424
- addN: Fp12Add,
425
- subN: Fp12Subtract,
426
- mulN: Fp12Multiply,
427
- sqrN: Fp12Square,
428
- // Bytes utils
429
- fromBytes: (b) => {
430
- if (b.length !== Fp12.BYTES)
431
- throw new Error('fromBytes invalid length=' + b.length);
432
- return {
433
- c0: Fp6.fromBytes(b.subarray(0, Fp6.BYTES)),
434
- c1: Fp6.fromBytes(b.subarray(Fp6.BYTES)),
435
- };
436
- },
437
- toBytes: ({ c0, c1 }) => (0, utils_ts_1.concatBytes)(Fp6.toBytes(c0), Fp6.toBytes(c1)),
438
- cmov: ({ c0, c1 }, { c0: r0, c1: r1 }, c) => ({
596
+ toBytes({ c0, c1 }) {
597
+ const { Fp6 } = this;
598
+ return (0, utils_ts_1.concatBytes)(Fp6.toBytes(c0), Fp6.toBytes(c1));
599
+ }
600
+ cmov({ c0, c1 }, { c0: r0, c1: r1 }, c) {
601
+ const { Fp6 } = this;
602
+ return {
439
603
  c0: Fp6.cmov(c0, r0, c),
440
604
  c1: Fp6.cmov(c1, r1, c),
441
- }),
442
- // Utils
443
- // toString() {
444
- // return '' + 'Fp12(' + this.c0 + this.c1 + '* w');
445
- // },
446
- // fromTuple(c: [Fp6, Fp6]) {
447
- // return new Fp12(...c);
448
- // }
449
- fromBigTwelve: (t) => ({
605
+ };
606
+ }
607
+ // Utils
608
+ // toString() {
609
+ // return '' + 'Fp12(' + this.c0 + this.c1 + '* w');
610
+ // },
611
+ // fromTuple(c: [Fp6, Fp6]) {
612
+ // return new Fp12(...c);
613
+ // }
614
+ fromBigTwelve(t) {
615
+ const { Fp6 } = this;
616
+ return {
450
617
  c0: Fp6.fromBigSix(t.slice(0, 6)),
451
618
  c1: Fp6.fromBigSix(t.slice(6, 12)),
452
- }),
453
- // Raises to q**i -th power
454
- frobeniusMap(lhs, power) {
455
- const { c0, c1, c2 } = Fp6.frobeniusMap(lhs.c1, power);
456
- const coeff = FP12_FROBENIUS_COEFFICIENTS[power % 12];
457
- return {
458
- c0: Fp6.frobeniusMap(lhs.c0, power),
459
- c1: Fp6.create({
460
- c0: Fp2.mul(c0, coeff),
461
- c1: Fp2.mul(c1, coeff),
462
- c2: Fp2.mul(c2, coeff),
463
- }),
464
- };
465
- },
466
- mulByFp2: ({ c0, c1 }, rhs) => ({
619
+ };
620
+ }
621
+ // Raises to q**i -th power
622
+ frobeniusMap(lhs, power) {
623
+ const { Fp6 } = this;
624
+ const { Fp2 } = Fp6;
625
+ const { c0, c1, c2 } = Fp6.frobeniusMap(lhs.c1, power);
626
+ const coeff = this.FROBENIUS_COEFFICIENTS[power % 12];
627
+ return {
628
+ c0: Fp6.frobeniusMap(lhs.c0, power),
629
+ c1: Fp6.create({
630
+ c0: Fp2.mul(c0, coeff),
631
+ c1: Fp2.mul(c1, coeff),
632
+ c2: Fp2.mul(c2, coeff),
633
+ }),
634
+ };
635
+ }
636
+ mulByFp2({ c0, c1 }, rhs) {
637
+ const { Fp6 } = this;
638
+ return {
467
639
  c0: Fp6.mulByFp2(c0, rhs),
468
640
  c1: Fp6.mulByFp2(c1, rhs),
469
- }),
470
- conjugate: ({ c0, c1 }) => ({ c0, c1: Fp6.neg(c1) }),
471
- // Sparse multiplication
472
- mul014: ({ c0, c1 }, o0, o1, o4) => {
473
- let t0 = Fp6.mul01(c0, o0, o1);
474
- let t1 = Fp6.mul1(c1, o4);
475
- return {
476
- c0: Fp6.add(Fp6.mulByNonresidue(t1), t0), // T1 * v + T0
477
- // (c1 + c0) * [o0, o1+o4] - T0 - T1
478
- c1: Fp6.sub(Fp6.sub(Fp6.mul01(Fp6.add(c1, c0), o0, Fp2.add(o1, o4)), t0), t1),
479
- };
480
- },
481
- mul034: ({ c0, c1 }, o0, o3, o4) => {
482
- const a = Fp6.create({
483
- c0: Fp2.mul(c0.c0, o0),
484
- c1: Fp2.mul(c0.c1, o0),
485
- c2: Fp2.mul(c0.c2, o0),
486
- });
487
- const b = Fp6.mul01(c1, o3, o4);
488
- const e = Fp6.mul01(Fp6.add(c0, c1), Fp2.add(o0, o3), o4);
489
- return {
490
- c0: Fp6.add(Fp6.mulByNonresidue(b), a),
491
- c1: Fp6.sub(e, Fp6.add(a, b)),
492
- };
493
- },
494
- // A cyclotomic group is a subgroup of Fp^n defined by
495
- // GΦₙ(p) = Fpⁿ : α^Φₙ(p) = 1}
496
- // The result of any pairing is in a cyclotomic subgroup
497
- // https://eprint.iacr.org/2009/565.pdf
498
- _cyclotomicSquare: opts.Fp12cyclotomicSquare,
499
- _cyclotomicExp: opts.Fp12cyclotomicExp,
500
- // https://eprint.iacr.org/2010/354.pdf
501
- // https://eprint.iacr.org/2009/565.pdf
502
- finalExponentiate: opts.Fp12finalExponentiate,
503
- };
504
- return { Fp, Fp2, Fp6, Fp12, Fp4Square };
641
+ };
642
+ }
643
+ conjugate({ c0, c1 }) {
644
+ return { c0, c1: this.Fp6.neg(c1) };
645
+ }
646
+ // Sparse multiplication
647
+ mul014({ c0, c1 }, o0, o1, o4) {
648
+ const { Fp6 } = this;
649
+ const { Fp2 } = Fp6;
650
+ let t0 = Fp6.mul01(c0, o0, o1);
651
+ let t1 = Fp6.mul1(c1, o4);
652
+ return {
653
+ c0: Fp6.add(Fp6.mulByNonresidue(t1), t0), // T1 * v + T0
654
+ // (c1 + c0) * [o0, o1+o4] - T0 - T1
655
+ c1: Fp6.sub(Fp6.sub(Fp6.mul01(Fp6.add(c1, c0), o0, Fp2.add(o1, o4)), t0), t1),
656
+ };
657
+ }
658
+ mul034({ c0, c1 }, o0, o3, o4) {
659
+ const { Fp6 } = this;
660
+ const { Fp2 } = Fp6;
661
+ const a = Fp6.create({
662
+ c0: Fp2.mul(c0.c0, o0),
663
+ c1: Fp2.mul(c0.c1, o0),
664
+ c2: Fp2.mul(c0.c2, o0),
665
+ });
666
+ const b = Fp6.mul01(c1, o3, o4);
667
+ const e = Fp6.mul01(Fp6.add(c0, c1), Fp2.add(o0, o3), o4);
668
+ return {
669
+ c0: Fp6.add(Fp6.mulByNonresidue(b), a),
670
+ c1: Fp6.sub(e, Fp6.add(a, b)),
671
+ };
672
+ }
673
+ // A cyclotomic group is a subgroup of Fp^n defined by
674
+ // GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) = 1}
675
+ // The result of any pairing is in a cyclotomic subgroup
676
+ // https://eprint.iacr.org/2009/565.pdf
677
+ // https://eprint.iacr.org/2010/354.pdf
678
+ _cyclotomicSquare({ c0, c1 }) {
679
+ const { Fp6 } = this;
680
+ const { Fp2 } = Fp6;
681
+ const { c0: c0c0, c1: c0c1, c2: c0c2 } = c0;
682
+ const { c0: c1c0, c1: c1c1, c2: c1c2 } = c1;
683
+ const { first: t3, second: t4 } = Fp2.Fp4Square(c0c0, c1c1);
684
+ const { first: t5, second: t6 } = Fp2.Fp4Square(c1c0, c0c2);
685
+ const { first: t7, second: t8 } = Fp2.Fp4Square(c0c1, c1c2);
686
+ const t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
687
+ return {
688
+ c0: Fp6.create({
689
+ c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3), // 2 * (T3 - c0c0) + T3
690
+ c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), _2n), t5), // 2 * (T5 - c0c1) + T5
691
+ c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), _2n), t7),
692
+ }), // 2 * (T7 - c0c2) + T7
693
+ c1: Fp6.create({
694
+ c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), _2n), t9), // 2 * (T9 + c1c0) + T9
695
+ c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), _2n), t4), // 2 * (T4 + c1c1) + T4
696
+ c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), _2n), t6),
697
+ }),
698
+ }; // 2 * (T6 + c1c2) + T6
699
+ }
700
+ // https://eprint.iacr.org/2009/565.pdf
701
+ _cyclotomicExp(num, n) {
702
+ let z = this.ONE;
703
+ for (let i = this.X_LEN - 1; i >= 0; i--) {
704
+ z = this._cyclotomicSquare(z);
705
+ if ((0, utils_ts_1.bitGet)(n, i))
706
+ z = this.mul(z, num);
707
+ }
708
+ return z;
709
+ }
710
+ }
711
+ function tower12(opts) {
712
+ const Fp = mod.Field(opts.ORDER);
713
+ const Fp2 = new _Field2(Fp, opts);
714
+ const Fp6 = new _Field6(Fp2);
715
+ const Fp12 = new _Field12(Fp6, opts);
716
+ return { Fp, Fp2, Fp6, Fp12 };
505
717
  }
506
718
  //# sourceMappingURL=tower.js.map