@noble/curves 1.9.7 → 2.0.0-beta.2

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