@noble/curves 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -99
- package/abstract/bls.d.ts +43 -31
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +37 -28
- package/abstract/bls.js.map +1 -1
- package/abstract/edwards.d.ts +6 -2
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +37 -26
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +1 -1
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +3 -2
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.js +1 -1
- package/abstract/modular.js.map +1 -1
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +2 -2
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +23 -0
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +44 -31
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +161 -162
- package/bls12-381.js.map +1 -1
- package/{bn.d.ts → bn254.d.ts} +1 -1
- package/bn254.d.ts.map +1 -0
- package/{bn.js → bn254.js} +1 -1
- package/bn254.js.map +1 -0
- package/ed25519.d.ts +9 -0
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +23 -9
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +9 -0
- package/ed448.d.ts.map +1 -1
- package/ed448.js +19 -18
- package/ed448.js.map +1 -1
- package/esm/abstract/bls.js +37 -28
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/edwards.js +37 -26
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/hash-to-curve.js +3 -2
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.js +1 -1
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/utils.js +2 -2
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.js +36 -23
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.js +162 -163
- package/esm/bls12-381.js.map +1 -1
- package/esm/{bn.js → bn254.js} +1 -1
- package/esm/bn254.js.map +1 -0
- package/esm/ed25519.js +21 -8
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.js +17 -17
- package/esm/ed448.js.map +1 -1
- package/esm/p256.js +5 -6
- package/esm/p256.js.map +1 -1
- package/esm/p384.js +10 -12
- package/esm/p384.js.map +1 -1
- package/esm/p521.js +22 -18
- package/esm/p521.js.map +1 -1
- package/esm/secp256k1.js +1 -1
- package/esm/secp256k1.js.map +1 -1
- package/p256.d.ts +1 -1
- package/p256.d.ts.map +1 -1
- package/p256.js +6 -7
- package/p256.js.map +1 -1
- package/p384.d.ts +1 -1
- package/p384.d.ts.map +1 -1
- package/p384.js +11 -13
- package/p384.js.map +1 -1
- package/p521.d.ts +1 -1
- package/p521.d.ts.map +1 -1
- package/p521.js +23 -19
- package/p521.js.map +1 -1
- package/package.json +5 -8
- package/secp256k1.js +1 -1
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +83 -61
- package/src/abstract/edwards.ts +49 -24
- package/src/abstract/hash-to-curve.ts +4 -3
- package/src/abstract/modular.ts +1 -1
- package/src/abstract/utils.ts +2 -2
- package/src/abstract/weierstrass.ts +36 -23
- package/src/bls12-381.ts +252 -171
- package/src/ed25519.ts +23 -9
- package/src/ed448.ts +18 -17
- package/src/p256.ts +15 -19
- package/src/p384.ts +17 -21
- package/src/p521.ts +34 -22
- package/src/secp256k1.ts +1 -1
- package/bn.d.ts.map +0 -1
- package/bn.js.map +0 -1
- package/esm/bn.js.map +0 -1
- /package/src/{bn.ts → bn254.ts} +0 -0
package/bls12-381.js
CHANGED
|
@@ -9,7 +9,7 @@ exports.bls12_381 = void 0;
|
|
|
9
9
|
//
|
|
10
10
|
// The library uses G1 for public keys and G2 for signatures. Support for G1 signatures is planned.
|
|
11
11
|
// Compatible with Algorand, Chia, Dfinity, Ethereum, FIL, Zcash. Matches specs
|
|
12
|
-
// [pairing-curves-
|
|
12
|
+
// [pairing-curves-11](https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-11),
|
|
13
13
|
// [bls-sigs-04](https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04),
|
|
14
14
|
// [hash-to-curve-12](https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-12).
|
|
15
15
|
//
|
|
@@ -29,23 +29,6 @@ exports.bls12_381 = void 0;
|
|
|
29
29
|
// - `e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))` - signature aggregation
|
|
30
30
|
// Filecoin uses little endian byte arrays for private keys -
|
|
31
31
|
// so ensure to reverse byte order if you'll use it with FIL.
|
|
32
|
-
//
|
|
33
|
-
// ### Resources
|
|
34
|
-
// - [BLS12-381 for the rest of us](https://hackmd.io/@benjaminion/bls12-381)
|
|
35
|
-
// - [Key concepts of pairings](https://medium.com/@alonmuroch_65570/bls-signatures-part-2-key-concepts-of-pairings-27a8a9533d0c)
|
|
36
|
-
// - Pairing over bls12-381:
|
|
37
|
-
// [part 1](https://research.nccgroup.com/2020/07/06/pairing-over-bls12-381-part-1-fields/),
|
|
38
|
-
// [part 2](https://research.nccgroup.com/2020/07/13/pairing-over-bls12-381-part-2-curves/),
|
|
39
|
-
// [part 3](https://research.nccgroup.com/2020/08/13/pairing-over-bls12-381-part-3-pairing/)
|
|
40
|
-
// - [Estimating the bit security of pairing-friendly curves](https://research.nccgroup.com/2022/02/03/estimating-the-bit-security-of-pairing-friendly-curves/)
|
|
41
|
-
//
|
|
42
|
-
// ### Differences from @noble/bls12-381 1.4
|
|
43
|
-
// - PointG1 -> G1.Point
|
|
44
|
-
// - PointG2 -> G2.Point
|
|
45
|
-
// - PointG2.fromSignature -> Signature.decode
|
|
46
|
-
// - PointG2.toSignature -> Signature.encode
|
|
47
|
-
// - Fixed Fp2 ORDER
|
|
48
|
-
// - Points now have only two coordinates
|
|
49
32
|
const sha256_1 = require("@noble/hashes/sha256");
|
|
50
33
|
const utils_1 = require("@noble/hashes/utils");
|
|
51
34
|
const bls_js_1 = require("./abstract/bls.js");
|
|
@@ -54,12 +37,17 @@ const utils_js_1 = require("./abstract/utils.js");
|
|
|
54
37
|
// Types
|
|
55
38
|
const weierstrass_js_1 = require("./abstract/weierstrass.js");
|
|
56
39
|
const hash_to_curve_js_1 = require("./abstract/hash-to-curve.js");
|
|
40
|
+
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
41
|
+
// prettier-ignore
|
|
42
|
+
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
|
|
43
|
+
// prettier-ignore
|
|
44
|
+
const _8n = BigInt(8), _16n = BigInt(16);
|
|
57
45
|
// CURVE FIELDS
|
|
58
46
|
// Finite field over p.
|
|
59
|
-
const Fp = mod.Field(
|
|
47
|
+
const Fp = mod.Field(BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'));
|
|
60
48
|
// Finite field over r.
|
|
61
49
|
// This particular field is not used anywhere in bls12-381, but it is still useful.
|
|
62
|
-
const Fr = mod.Field(
|
|
50
|
+
const Fr = mod.Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'));
|
|
63
51
|
const Fp2Add = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
|
|
64
52
|
c0: Fp.add(c0, r0),
|
|
65
53
|
c1: Fp.add(c1, r1),
|
|
@@ -91,8 +79,7 @@ const Fp2Square = ({ c0, c1 }) => {
|
|
|
91
79
|
// G² - 1
|
|
92
80
|
// h2q
|
|
93
81
|
// NOTE: ORDER was wrong!
|
|
94
|
-
const FP2_ORDER =
|
|
95
|
-
2n;
|
|
82
|
+
const FP2_ORDER = BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab') ** _2n;
|
|
96
83
|
const Fp2 = {
|
|
97
84
|
ORDER: FP2_ORDER,
|
|
98
85
|
BITS: (0, utils_js_1.bitLen)(FP2_ORDER),
|
|
@@ -145,7 +132,7 @@ const Fp2 = {
|
|
|
145
132
|
// https://github.com/zkcrypto/bls12_381/blob/080eaa74ec0e394377caa1ba302c8c121df08b07/src/fp2.rs#L250
|
|
146
133
|
// https://github.com/supranational/blst/blob/aae0c7d70b799ac269ff5edf29d8191dbd357876/src/exp2.c#L1
|
|
147
134
|
// Inspired by https://github.com/dalek-cryptography/curve25519-dalek/blob/17698df9d4c834204f83a3574143abacb4fc81a5/src/field.rs#L99
|
|
148
|
-
const candidateSqrt = Fp2.pow(num, (Fp2.ORDER +
|
|
135
|
+
const candidateSqrt = Fp2.pow(num, (Fp2.ORDER + _8n) / _16n);
|
|
149
136
|
const check = Fp2.div(Fp2.sqr(candidateSqrt), num); // candidateSqrt.square().div(this);
|
|
150
137
|
const R = FP2_ROOTS_OF_UNITY;
|
|
151
138
|
const divisor = [R[0], R[2], R[4], R[6]].find((r) => Fp2.eql(r, check));
|
|
@@ -166,10 +153,10 @@ const Fp2 = {
|
|
|
166
153
|
// Same as sgn0_fp2 in draft-irtf-cfrg-hash-to-curve-16
|
|
167
154
|
isOdd: (x) => {
|
|
168
155
|
const { re: x0, im: x1 } = Fp2.reim(x);
|
|
169
|
-
const sign_0 = x0 %
|
|
170
|
-
const zero_0 = x0 ===
|
|
171
|
-
const sign_1 = x1 %
|
|
172
|
-
return BigInt(sign_0 || (zero_0 && sign_1)) ==
|
|
156
|
+
const sign_0 = x0 % _2n;
|
|
157
|
+
const zero_0 = x0 === _0n;
|
|
158
|
+
const sign_1 = x1 % _2n;
|
|
159
|
+
return BigInt(sign_0 || (zero_0 && sign_1)) == _1n;
|
|
173
160
|
},
|
|
174
161
|
// Bytes util
|
|
175
162
|
fromBytes(b) {
|
|
@@ -190,8 +177,8 @@ const Fp2 = {
|
|
|
190
177
|
// multiply by u + 1
|
|
191
178
|
mulByNonresidue: ({ c0, c1 }) => ({ c0: Fp.sub(c0, c1), c1: Fp.add(c0, c1) }),
|
|
192
179
|
multiplyByB: ({ c0, c1 }) => {
|
|
193
|
-
let t0 = Fp.mul(c0,
|
|
194
|
-
let t1 = Fp.mul(c1,
|
|
180
|
+
let t0 = Fp.mul(c0, _4n); // 4 * c0
|
|
181
|
+
let t1 = Fp.mul(c1, _4n); // 4 * c1
|
|
195
182
|
// (T0-T1) + (T0+T1)*i
|
|
196
183
|
return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
|
|
197
184
|
},
|
|
@@ -209,30 +196,30 @@ const Fp2 = {
|
|
|
209
196
|
// Finite extension field over irreducible polynominal.
|
|
210
197
|
// Fp(u) / (u² - β) where β = -1
|
|
211
198
|
const FP2_FROBENIUS_COEFFICIENTS = [
|
|
212
|
-
|
|
213
|
-
|
|
199
|
+
BigInt('0x1'),
|
|
200
|
+
BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'),
|
|
214
201
|
].map((item) => Fp.create(item));
|
|
215
202
|
// For Fp2 roots of unity.
|
|
216
|
-
const rv1 =
|
|
203
|
+
const rv1 = BigInt('0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09');
|
|
217
204
|
// const ev1 =
|
|
218
|
-
//
|
|
205
|
+
// BigInt('0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90');
|
|
219
206
|
// const ev2 =
|
|
220
|
-
//
|
|
207
|
+
// BigInt('0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5');
|
|
221
208
|
// const ev3 =
|
|
222
|
-
//
|
|
209
|
+
// BigInt('0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17');
|
|
223
210
|
// const ev4 =
|
|
224
|
-
//
|
|
211
|
+
// BigInt('0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1');
|
|
225
212
|
// Eighth roots of unity, used for computing square roots in Fp2.
|
|
226
213
|
// To verify or re-calculate:
|
|
227
214
|
// Array(8).fill(new Fp2([1n, 1n])).map((fp2, k) => fp2.pow(Fp2.ORDER * BigInt(k) / 8n))
|
|
228
215
|
const FP2_ROOTS_OF_UNITY = [
|
|
229
|
-
[
|
|
216
|
+
[_1n, _0n],
|
|
230
217
|
[rv1, -rv1],
|
|
231
|
-
[
|
|
218
|
+
[_0n, _1n],
|
|
232
219
|
[rv1, rv1],
|
|
233
|
-
[-
|
|
220
|
+
[-_1n, _0n],
|
|
234
221
|
[-rv1, rv1],
|
|
235
|
-
[
|
|
222
|
+
[_0n, -_1n],
|
|
236
223
|
[-rv1, -rv1],
|
|
237
224
|
].map((pair) => Fp2.fromBigTuple(pair));
|
|
238
225
|
const Fp6Add = ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => ({
|
|
@@ -268,8 +255,8 @@ const Fp6Multiply = ({ c0, c1, c2 }, rhs) => {
|
|
|
268
255
|
};
|
|
269
256
|
const Fp6Square = ({ c0, c1, c2 }) => {
|
|
270
257
|
let t0 = Fp2.sqr(c0); // c0²
|
|
271
|
-
let t1 = Fp2.mul(Fp2.mul(c0, c1),
|
|
272
|
-
let t3 = Fp2.mul(Fp2.mul(c1, c2),
|
|
258
|
+
let t1 = Fp2.mul(Fp2.mul(c0, c1), _2n); // 2 * c0 * c1
|
|
259
|
+
let t3 = Fp2.mul(Fp2.mul(c1, c2), _2n); // 2 * c1 * c2
|
|
273
260
|
let t4 = Fp2.sqr(c2); // c2²
|
|
274
261
|
return {
|
|
275
262
|
c0: Fp2.add(Fp2.mulByNonresidue(t3), t0),
|
|
@@ -379,50 +366,50 @@ const Fp6 = {
|
|
|
379
366
|
}),
|
|
380
367
|
};
|
|
381
368
|
const FP6_FROBENIUS_COEFFICIENTS_1 = [
|
|
382
|
-
[
|
|
369
|
+
[BigInt('0x1'), BigInt('0x0')],
|
|
383
370
|
[
|
|
384
|
-
|
|
385
|
-
|
|
371
|
+
BigInt('0x0'),
|
|
372
|
+
BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'),
|
|
386
373
|
],
|
|
387
374
|
[
|
|
388
|
-
|
|
389
|
-
|
|
375
|
+
BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'),
|
|
376
|
+
BigInt('0x0'),
|
|
390
377
|
],
|
|
391
|
-
[
|
|
378
|
+
[BigInt('0x0'), BigInt('0x1')],
|
|
392
379
|
[
|
|
393
|
-
|
|
394
|
-
|
|
380
|
+
BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'),
|
|
381
|
+
BigInt('0x0'),
|
|
395
382
|
],
|
|
396
383
|
[
|
|
397
|
-
|
|
398
|
-
|
|
384
|
+
BigInt('0x0'),
|
|
385
|
+
BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'),
|
|
399
386
|
],
|
|
400
387
|
].map((pair) => Fp2.fromBigTuple(pair));
|
|
401
388
|
const FP6_FROBENIUS_COEFFICIENTS_2 = [
|
|
402
|
-
[
|
|
389
|
+
[BigInt('0x1'), BigInt('0x0')],
|
|
403
390
|
[
|
|
404
|
-
|
|
405
|
-
|
|
391
|
+
BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'),
|
|
392
|
+
BigInt('0x0'),
|
|
406
393
|
],
|
|
407
394
|
[
|
|
408
|
-
|
|
409
|
-
|
|
395
|
+
BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'),
|
|
396
|
+
BigInt('0x0'),
|
|
410
397
|
],
|
|
411
398
|
[
|
|
412
|
-
|
|
413
|
-
|
|
399
|
+
BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'),
|
|
400
|
+
BigInt('0x0'),
|
|
414
401
|
],
|
|
415
402
|
[
|
|
416
|
-
|
|
417
|
-
|
|
403
|
+
BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'),
|
|
404
|
+
BigInt('0x0'),
|
|
418
405
|
],
|
|
419
406
|
[
|
|
420
|
-
|
|
421
|
-
|
|
407
|
+
BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'),
|
|
408
|
+
BigInt('0x0'),
|
|
422
409
|
],
|
|
423
410
|
].map((pair) => Fp2.fromBigTuple(pair));
|
|
424
411
|
// The BLS parameter x for BLS12-381
|
|
425
|
-
const BLS_X =
|
|
412
|
+
const BLS_X = BigInt('0xd201000000010000');
|
|
426
413
|
const BLS_X_LEN = (0, utils_js_1.bitLen)(BLS_X);
|
|
427
414
|
const Fp12Add = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
|
|
428
415
|
c0: Fp6.add(c0, r0),
|
|
@@ -559,14 +546,14 @@ const Fp12 = {
|
|
|
559
546
|
let t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
|
|
560
547
|
return {
|
|
561
548
|
c0: Fp6.create({
|
|
562
|
-
c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0),
|
|
563
|
-
c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1),
|
|
564
|
-
c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2),
|
|
549
|
+
c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3),
|
|
550
|
+
c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), _2n), t5),
|
|
551
|
+
c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), _2n), t7),
|
|
565
552
|
}),
|
|
566
553
|
c1: Fp6.create({
|
|
567
|
-
c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0),
|
|
568
|
-
c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1),
|
|
569
|
-
c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2),
|
|
554
|
+
c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), _2n), t9),
|
|
555
|
+
c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), _2n), t4),
|
|
556
|
+
c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), _2n), t6),
|
|
570
557
|
}),
|
|
571
558
|
}; // 2 * (T6 + c1c2) + T6
|
|
572
559
|
},
|
|
@@ -602,50 +589,50 @@ const Fp12 = {
|
|
|
602
589
|
},
|
|
603
590
|
};
|
|
604
591
|
const FP12_FROBENIUS_COEFFICIENTS = [
|
|
605
|
-
[
|
|
592
|
+
[BigInt('0x1'), BigInt('0x0')],
|
|
606
593
|
[
|
|
607
|
-
|
|
608
|
-
|
|
594
|
+
BigInt('0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'),
|
|
595
|
+
BigInt('0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'),
|
|
609
596
|
],
|
|
610
597
|
[
|
|
611
|
-
|
|
612
|
-
|
|
598
|
+
BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'),
|
|
599
|
+
BigInt('0x0'),
|
|
613
600
|
],
|
|
614
601
|
[
|
|
615
|
-
|
|
616
|
-
|
|
602
|
+
BigInt('0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'),
|
|
603
|
+
BigInt('0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'),
|
|
617
604
|
],
|
|
618
605
|
[
|
|
619
|
-
|
|
620
|
-
|
|
606
|
+
BigInt('0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'),
|
|
607
|
+
BigInt('0x0'),
|
|
621
608
|
],
|
|
622
609
|
[
|
|
623
|
-
|
|
624
|
-
|
|
610
|
+
BigInt('0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'),
|
|
611
|
+
BigInt('0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'),
|
|
625
612
|
],
|
|
626
613
|
[
|
|
627
|
-
|
|
628
|
-
|
|
614
|
+
BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'),
|
|
615
|
+
BigInt('0x0'),
|
|
629
616
|
],
|
|
630
617
|
[
|
|
631
|
-
|
|
632
|
-
|
|
618
|
+
BigInt('0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'),
|
|
619
|
+
BigInt('0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'),
|
|
633
620
|
],
|
|
634
621
|
[
|
|
635
|
-
|
|
636
|
-
|
|
622
|
+
BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'),
|
|
623
|
+
BigInt('0x0'),
|
|
637
624
|
],
|
|
638
625
|
[
|
|
639
|
-
|
|
640
|
-
|
|
626
|
+
BigInt('0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'),
|
|
627
|
+
BigInt('0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'),
|
|
641
628
|
],
|
|
642
629
|
[
|
|
643
|
-
|
|
644
|
-
|
|
630
|
+
BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'),
|
|
631
|
+
BigInt('0x0'),
|
|
645
632
|
],
|
|
646
633
|
[
|
|
647
|
-
|
|
648
|
-
|
|
634
|
+
BigInt('0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'),
|
|
635
|
+
BigInt('0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'),
|
|
649
636
|
],
|
|
650
637
|
].map((n) => Fp2.fromBigTuple(n));
|
|
651
638
|
// END OF CURVE FIELDS
|
|
@@ -792,15 +779,15 @@ const isogenyMapG1 = (0, hash_to_curve_js_1.isogenyMap)(Fp, [
|
|
|
792
779
|
].map((i) => i.map((j) => BigInt(j))));
|
|
793
780
|
// SWU Map - Fp2 to G2': y² = x³ + 240i * x + 1012 + 1012i
|
|
794
781
|
const G2_SWU = (0, weierstrass_js_1.mapToCurveSimpleSWU)(Fp2, {
|
|
795
|
-
A: Fp2.create({ c0: Fp.create(
|
|
796
|
-
B: Fp2.create({ c0: Fp.create(
|
|
797
|
-
Z: Fp2.create({ c0: Fp.create(-
|
|
782
|
+
A: Fp2.create({ c0: Fp.create(_0n), c1: Fp.create(BigInt(240)) }),
|
|
783
|
+
B: Fp2.create({ c0: Fp.create(BigInt(1012)), c1: Fp.create(BigInt(1012)) }),
|
|
784
|
+
Z: Fp2.create({ c0: Fp.create(BigInt(-2)), c1: Fp.create(BigInt(-1)) }), // Z: -(2 + I)
|
|
798
785
|
});
|
|
799
786
|
// Optimized SWU Map - Fp to G1
|
|
800
787
|
const G1_SWU = (0, weierstrass_js_1.mapToCurveSimpleSWU)(Fp, {
|
|
801
|
-
A: Fp.create(
|
|
802
|
-
B: Fp.create(
|
|
803
|
-
Z: Fp.create(
|
|
788
|
+
A: Fp.create(BigInt('0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d')),
|
|
789
|
+
B: Fp.create(BigInt('0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0')),
|
|
790
|
+
Z: Fp.create(BigInt(11)),
|
|
804
791
|
});
|
|
805
792
|
// Endomorphisms (for fast cofactor clearing)
|
|
806
793
|
// Ψ(P) endomorphism
|
|
@@ -822,7 +809,7 @@ function G2psi(c, P) {
|
|
|
822
809
|
}
|
|
823
810
|
// Ψ²(P) endomorphism
|
|
824
811
|
// 1 / F2(2)^((p-1)/3) in GF(p²)
|
|
825
|
-
const PSI2_C1 =
|
|
812
|
+
const PSI2_C1 = BigInt('0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac');
|
|
826
813
|
function psi2(x, y) {
|
|
827
814
|
return [Fp2.mul(x, PSI2_C1), Fp2.neg(y)];
|
|
828
815
|
}
|
|
@@ -870,7 +857,22 @@ const C_BIT_POS = Fp.BITS; // C_bit, compression bit for serialization flag
|
|
|
870
857
|
const I_BIT_POS = Fp.BITS + 1; // I_bit, point-at-infinity bit for serialization flag
|
|
871
858
|
const S_BIT_POS = Fp.BITS + 2; // S_bit, sign bit for serialization flag
|
|
872
859
|
// Compressed point of infinity
|
|
873
|
-
const COMPRESSED_ZERO = Fp.toBytes((0, utils_js_1.bitSet)((0, utils_js_1.bitSet)(
|
|
860
|
+
const COMPRESSED_ZERO = Fp.toBytes((0, utils_js_1.bitSet)((0, utils_js_1.bitSet)(_0n, I_BIT_POS, true), S_BIT_POS, true)); // set compressed & point-at-infinity bits
|
|
861
|
+
function signatureG2ToRawBytes(point) {
|
|
862
|
+
// NOTE: by some reasons it was missed in bls12-381, looks like bug
|
|
863
|
+
point.assertValidity();
|
|
864
|
+
const len = Fp.BYTES;
|
|
865
|
+
if (point.equals(exports.bls12_381.G2.ProjectivePoint.ZERO))
|
|
866
|
+
return (0, utils_js_1.concatBytes)(COMPRESSED_ZERO, (0, utils_js_1.numberToBytesBE)(_0n, len));
|
|
867
|
+
const { x, y } = point.toAffine();
|
|
868
|
+
const { re: x0, im: x1 } = Fp2.reim(x);
|
|
869
|
+
const { re: y0, im: y1 } = Fp2.reim(y);
|
|
870
|
+
const tmp = y1 > _0n ? y1 * _2n : y0 * _2n;
|
|
871
|
+
const aflag1 = Boolean((tmp / Fp.ORDER) & _1n);
|
|
872
|
+
const z1 = (0, utils_js_1.bitSet)((0, utils_js_1.bitSet)(x1, 381, aflag1), S_BIT_POS, true);
|
|
873
|
+
const z2 = x0;
|
|
874
|
+
return (0, utils_js_1.concatBytes)((0, utils_js_1.numberToBytesBE)(z1, len), (0, utils_js_1.numberToBytesBE)(z2, len));
|
|
875
|
+
}
|
|
874
876
|
// To verify curve parameters, see pairing-friendly-curves spec:
|
|
875
877
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09
|
|
876
878
|
// Basic math is done over finite fields over p.
|
|
@@ -883,26 +885,26 @@ const COMPRESSED_ZERO = Fp.toBytes((0, utils_js_1.bitSet)((0, utils_js_1.bitSet)
|
|
|
883
885
|
// Here goes constants && point encoding format
|
|
884
886
|
exports.bls12_381 = (0, bls_js_1.bls)({
|
|
885
887
|
// Fields
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
888
|
+
fields: {
|
|
889
|
+
Fp,
|
|
890
|
+
Fp2,
|
|
891
|
+
Fp6,
|
|
892
|
+
Fp12,
|
|
893
|
+
Fr,
|
|
894
|
+
},
|
|
893
895
|
// G1 is the order-q subgroup of E1(Fp) : y² = x³ + 4, #E1(Fp) = h1q, where
|
|
894
896
|
// characteristic; z + (z⁴ - z² + 1)(z - 1)²/3
|
|
895
897
|
G1: {
|
|
896
898
|
Fp,
|
|
897
899
|
// cofactor; (z - 1)²/3
|
|
898
|
-
h:
|
|
900
|
+
h: BigInt('0x396c8c005555e1568c00aaab0000aaab'),
|
|
899
901
|
// generator's coordinates
|
|
900
902
|
// x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
|
|
901
903
|
// y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
|
902
|
-
Gx:
|
|
903
|
-
Gy:
|
|
904
|
+
Gx: BigInt('0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb'),
|
|
905
|
+
Gy: BigInt('0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1'),
|
|
904
906
|
a: Fp.ZERO,
|
|
905
|
-
b:
|
|
907
|
+
b: _4n,
|
|
906
908
|
htfDefaults: { ...htfDefaults, m: 1 },
|
|
907
909
|
wrapPrivateKey: true,
|
|
908
910
|
allowInfinityPoint: true,
|
|
@@ -912,15 +914,15 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
912
914
|
// https://eprint.iacr.org/2021/1130.pdf
|
|
913
915
|
isTorsionFree: (c, point) => {
|
|
914
916
|
// φ endomorphism
|
|
915
|
-
const cubicRootOfUnityModP =
|
|
917
|
+
const cubicRootOfUnityModP = BigInt('0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe');
|
|
916
918
|
const phi = new c(Fp.mul(point.px, cubicRootOfUnityModP), point.py, point.pz);
|
|
917
919
|
// todo: unroll
|
|
918
|
-
const xP = point.multiplyUnsafe(exports.bls12_381.
|
|
919
|
-
const u2P = xP.multiplyUnsafe(exports.bls12_381.
|
|
920
|
+
const xP = point.multiplyUnsafe(exports.bls12_381.params.x).negate(); // [x]P
|
|
921
|
+
const u2P = xP.multiplyUnsafe(exports.bls12_381.params.x); // [u2]P
|
|
920
922
|
return u2P.equals(phi);
|
|
921
923
|
// https://eprint.iacr.org/2019/814.pdf
|
|
922
924
|
// (z² − 1)/3
|
|
923
|
-
// const c1 =
|
|
925
|
+
// const c1 = BigInt('0x396c8c005555e1560000000055555555');
|
|
924
926
|
// const P = this;
|
|
925
927
|
// const S = P.sigma();
|
|
926
928
|
// const Q = S.double();
|
|
@@ -934,27 +936,29 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
934
936
|
// https://eprint.iacr.org/2019/403
|
|
935
937
|
clearCofactor: (c, point) => {
|
|
936
938
|
// return this.multiplyUnsafe(CURVE.h);
|
|
937
|
-
return point.multiplyUnsafe(exports.bls12_381.
|
|
939
|
+
return point.multiplyUnsafe(exports.bls12_381.params.x).add(point); // x*P + P
|
|
938
940
|
},
|
|
939
941
|
mapToCurve: (scalars) => {
|
|
940
942
|
const { x, y } = G1_SWU(Fp.create(scalars[0]));
|
|
941
943
|
return isogenyMapG1(x, y);
|
|
942
944
|
},
|
|
943
945
|
fromBytes: (bytes) => {
|
|
946
|
+
bytes = bytes.slice();
|
|
944
947
|
if (bytes.length === 48) {
|
|
948
|
+
// TODO: Fp.bytes
|
|
945
949
|
const P = Fp.ORDER;
|
|
946
950
|
const compressedValue = (0, utils_js_1.bytesToNumberBE)(bytes);
|
|
947
951
|
const bflag = (0, utils_js_1.bitGet)(compressedValue, I_BIT_POS);
|
|
948
952
|
// Zero
|
|
949
|
-
if (bflag ===
|
|
950
|
-
return { x:
|
|
953
|
+
if (bflag === _1n)
|
|
954
|
+
return { x: _0n, y: _0n };
|
|
951
955
|
const x = Fp.create(compressedValue & Fp.MASK);
|
|
952
|
-
const right = Fp.add(Fp.pow(x,
|
|
956
|
+
const right = Fp.add(Fp.pow(x, _3n), Fp.create(exports.bls12_381.params.G1b)); // y² = x³ + b
|
|
953
957
|
let y = Fp.sqrt(right);
|
|
954
958
|
if (!y)
|
|
955
959
|
throw new Error('Invalid compressed G1 point');
|
|
956
960
|
const aflag = (0, utils_js_1.bitGet)(compressedValue, C_BIT_POS);
|
|
957
|
-
if ((y *
|
|
961
|
+
if ((y * _2n) / P !== aflag)
|
|
958
962
|
y = Fp.neg(y);
|
|
959
963
|
return { x: Fp.create(x), y: Fp.create(y) };
|
|
960
964
|
}
|
|
@@ -962,8 +966,8 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
962
966
|
// Check if the infinity flag is set
|
|
963
967
|
if ((bytes[0] & (1 << 6)) !== 0)
|
|
964
968
|
return exports.bls12_381.G1.ProjectivePoint.ZERO.toAffine();
|
|
965
|
-
const x = (0, utils_js_1.bytesToNumberBE)(bytes.
|
|
966
|
-
const y = (0, utils_js_1.bytesToNumberBE)(bytes.
|
|
969
|
+
const x = (0, utils_js_1.bytesToNumberBE)(bytes.subarray(0, Fp.BYTES));
|
|
970
|
+
const y = (0, utils_js_1.bytesToNumberBE)(bytes.subarray(Fp.BYTES));
|
|
967
971
|
return { x: Fp.create(x), y: Fp.create(y) };
|
|
968
972
|
}
|
|
969
973
|
else {
|
|
@@ -978,7 +982,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
978
982
|
return COMPRESSED_ZERO.slice();
|
|
979
983
|
const P = Fp.ORDER;
|
|
980
984
|
let num;
|
|
981
|
-
num = (0, utils_js_1.bitSet)(x, C_BIT_POS, Boolean((y *
|
|
985
|
+
num = (0, utils_js_1.bitSet)(x, C_BIT_POS, Boolean((y * _2n) / P)); // set aflag
|
|
982
986
|
num = (0, utils_js_1.bitSet)(num, S_BIT_POS, true);
|
|
983
987
|
return (0, utils_js_1.numberToBytesBE)(num, Fp.BYTES);
|
|
984
988
|
}
|
|
@@ -1001,21 +1005,21 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1001
1005
|
G2: {
|
|
1002
1006
|
Fp: Fp2,
|
|
1003
1007
|
// cofactor
|
|
1004
|
-
h:
|
|
1008
|
+
h: BigInt('0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5'),
|
|
1005
1009
|
Gx: Fp2.fromBigTuple([
|
|
1006
|
-
|
|
1007
|
-
|
|
1010
|
+
BigInt('0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8'),
|
|
1011
|
+
BigInt('0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e'),
|
|
1008
1012
|
]),
|
|
1009
1013
|
// y =
|
|
1010
1014
|
// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582,
|
|
1011
1015
|
// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
|
|
1012
1016
|
Gy: Fp2.fromBigTuple([
|
|
1013
|
-
|
|
1014
|
-
|
|
1017
|
+
BigInt('0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801'),
|
|
1018
|
+
BigInt('0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be'),
|
|
1015
1019
|
]),
|
|
1016
1020
|
a: Fp2.ZERO,
|
|
1017
|
-
b: Fp2.fromBigTuple([4n,
|
|
1018
|
-
hEff:
|
|
1021
|
+
b: Fp2.fromBigTuple([4n, _4n]),
|
|
1022
|
+
hEff: BigInt('0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551'),
|
|
1019
1023
|
htfDefaults: { ...htfDefaults },
|
|
1020
1024
|
wrapPrivateKey: true,
|
|
1021
1025
|
allowInfinityPoint: true,
|
|
@@ -1028,7 +1032,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1028
1032
|
// It returns false for shitty points.
|
|
1029
1033
|
// https://eprint.iacr.org/2021/1130.pdf
|
|
1030
1034
|
isTorsionFree: (c, P) => {
|
|
1031
|
-
return P.multiplyUnsafe(exports.bls12_381.
|
|
1035
|
+
return P.multiplyUnsafe(exports.bls12_381.params.x).negate().equals(G2psi(c, P)); // ψ(P) == [u](P)
|
|
1032
1036
|
// Older version: https://eprint.iacr.org/2019/814.pdf
|
|
1033
1037
|
// Ψ²(P) => Ψ³(P) => [z]Ψ³(P) where z = -x => [z]Ψ³(P) - Ψ²(P) + P == O
|
|
1034
1038
|
// return P.psi2().psi().mulNegX().subtract(psi2).add(P).isZero();
|
|
@@ -1038,7 +1042,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1038
1042
|
// https://eprint.iacr.org/2017/419.pdf
|
|
1039
1043
|
// prettier-ignore
|
|
1040
1044
|
clearCofactor: (c, P) => {
|
|
1041
|
-
const
|
|
1045
|
+
const x = exports.bls12_381.params.x;
|
|
1042
1046
|
let t1 = P.multiplyUnsafe(x).negate(); // [-x]P
|
|
1043
1047
|
let t2 = G2psi(c, P); // Ψ(P)
|
|
1044
1048
|
let t3 = P.double(); // 2P
|
|
@@ -1052,6 +1056,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1052
1056
|
return Q; // [x²-x-1]P + [x-1]Ψ(P) + Ψ²(2P)
|
|
1053
1057
|
},
|
|
1054
1058
|
fromBytes: (bytes) => {
|
|
1059
|
+
bytes = bytes.slice();
|
|
1055
1060
|
const m_byte = bytes[0] & 0xe0;
|
|
1056
1061
|
if (m_byte === 0x20 || m_byte === 0x60 || m_byte === 0xe0) {
|
|
1057
1062
|
throw new Error('Invalid encoding flag: ' + m_byte);
|
|
@@ -1062,7 +1067,7 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1062
1067
|
const L = Fp.BYTES;
|
|
1063
1068
|
const slc = (b, from, to) => (0, utils_js_1.bytesToNumberBE)(b.slice(from, to));
|
|
1064
1069
|
if (bytes.length === 96 && bitC) {
|
|
1065
|
-
const
|
|
1070
|
+
const b = exports.bls12_381.params.G2b;
|
|
1066
1071
|
const P = Fp.ORDER;
|
|
1067
1072
|
bytes[0] = bytes[0] & 0x1f; // clear flags
|
|
1068
1073
|
if (bitI) {
|
|
@@ -1075,9 +1080,9 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1075
1080
|
const x_1 = slc(bytes, 0, L);
|
|
1076
1081
|
const x_0 = slc(bytes, L, 2 * L);
|
|
1077
1082
|
const x = Fp2.create({ c0: Fp.create(x_0), c1: Fp.create(x_1) });
|
|
1078
|
-
const right = Fp2.add(Fp2.pow(x,
|
|
1083
|
+
const right = Fp2.add(Fp2.pow(x, _3n), b); // y² = x³ + 4 * (u+1) = x³ + b
|
|
1079
1084
|
let y = Fp2.sqrt(right);
|
|
1080
|
-
const Y_bit = y.c1 ===
|
|
1085
|
+
const Y_bit = y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P ? _1n : _0n;
|
|
1081
1086
|
y = bitS > 0 && Y_bit > 0 ? y : Fp2.neg(y);
|
|
1082
1087
|
return { x, y };
|
|
1083
1088
|
}
|
|
@@ -1097,29 +1102,29 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1097
1102
|
}
|
|
1098
1103
|
},
|
|
1099
1104
|
toBytes: (c, point, isCompressed) => {
|
|
1105
|
+
const { BYTES: len, ORDER: P } = Fp;
|
|
1100
1106
|
const isZero = point.equals(c.ZERO);
|
|
1101
1107
|
const { x, y } = point.toAffine();
|
|
1102
1108
|
if (isCompressed) {
|
|
1103
|
-
const P = Fp.ORDER;
|
|
1104
1109
|
if (isZero)
|
|
1105
|
-
return (0, utils_js_1.concatBytes)(COMPRESSED_ZERO, (0, utils_js_1.numberToBytesBE)(
|
|
1106
|
-
const flag = Boolean(y.c1 ===
|
|
1110
|
+
return (0, utils_js_1.concatBytes)(COMPRESSED_ZERO, (0, utils_js_1.numberToBytesBE)(_0n, len));
|
|
1111
|
+
const flag = Boolean(y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P);
|
|
1107
1112
|
// set compressed & sign bits (looks like different offsets than for G1/Fp?)
|
|
1108
1113
|
let x_1 = (0, utils_js_1.bitSet)(x.c1, C_BIT_POS, flag);
|
|
1109
1114
|
x_1 = (0, utils_js_1.bitSet)(x_1, S_BIT_POS, true);
|
|
1110
|
-
return (0, utils_js_1.concatBytes)((0, utils_js_1.numberToBytesBE)(x_1,
|
|
1115
|
+
return (0, utils_js_1.concatBytes)((0, utils_js_1.numberToBytesBE)(x_1, len), (0, utils_js_1.numberToBytesBE)(x.c0, len));
|
|
1111
1116
|
}
|
|
1112
1117
|
else {
|
|
1113
1118
|
if (isZero)
|
|
1114
|
-
return (0, utils_js_1.concatBytes)(new Uint8Array([0x40]), new Uint8Array(4 *
|
|
1119
|
+
return (0, utils_js_1.concatBytes)(new Uint8Array([0x40]), new Uint8Array(4 * len - 1)); // bytes[0] |= 1 << 6;
|
|
1115
1120
|
const { re: x0, im: x1 } = Fp2.reim(x);
|
|
1116
1121
|
const { re: y0, im: y1 } = Fp2.reim(y);
|
|
1117
|
-
return (0, utils_js_1.concatBytes)((0, utils_js_1.numberToBytesBE)(x1,
|
|
1122
|
+
return (0, utils_js_1.concatBytes)((0, utils_js_1.numberToBytesBE)(x1, len), (0, utils_js_1.numberToBytesBE)(x0, len), (0, utils_js_1.numberToBytesBE)(y1, len), (0, utils_js_1.numberToBytesBE)(y0, len));
|
|
1118
1123
|
}
|
|
1119
1124
|
},
|
|
1120
1125
|
Signature: {
|
|
1121
1126
|
// TODO: Optimize, it's very slow because of sqrt.
|
|
1122
|
-
|
|
1127
|
+
fromHex(hex) {
|
|
1123
1128
|
hex = (0, utils_js_1.ensureBytes)('signatureHex', hex);
|
|
1124
1129
|
const P = Fp.ORDER;
|
|
1125
1130
|
const half = hex.length / 2;
|
|
@@ -1129,12 +1134,12 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1129
1134
|
const z2 = (0, utils_js_1.bytesToNumberBE)(hex.slice(half));
|
|
1130
1135
|
// Indicates the infinity point
|
|
1131
1136
|
const bflag1 = (0, utils_js_1.bitGet)(z1, I_BIT_POS);
|
|
1132
|
-
if (bflag1 ===
|
|
1137
|
+
if (bflag1 === _1n)
|
|
1133
1138
|
return exports.bls12_381.G2.ProjectivePoint.ZERO;
|
|
1134
1139
|
const x1 = Fp.create(z1 & Fp.MASK);
|
|
1135
1140
|
const x2 = Fp.create(z2);
|
|
1136
1141
|
const x = Fp2.create({ c0: x2, c1: x1 });
|
|
1137
|
-
const y2 = Fp2.add(Fp2.pow(x,
|
|
1142
|
+
const y2 = Fp2.add(Fp2.pow(x, _3n), exports.bls12_381.params.G2b); // y² = x³ + 4
|
|
1138
1143
|
// The slow part
|
|
1139
1144
|
let y = Fp2.sqrt(y2);
|
|
1140
1145
|
if (!y)
|
|
@@ -1143,32 +1148,26 @@ exports.bls12_381 = (0, bls_js_1.bls)({
|
|
|
1143
1148
|
// If y1 happens to be zero, then use the bit of y0
|
|
1144
1149
|
const { re: y0, im: y1 } = Fp2.reim(y);
|
|
1145
1150
|
const aflag1 = (0, utils_js_1.bitGet)(z1, 381);
|
|
1146
|
-
const isGreater = y1 >
|
|
1147
|
-
const isZero = y1 ===
|
|
1151
|
+
const isGreater = y1 > _0n && (y1 * _2n) / P !== aflag1;
|
|
1152
|
+
const isZero = y1 === _0n && (y0 * _2n) / P !== aflag1;
|
|
1148
1153
|
if (isGreater || isZero)
|
|
1149
1154
|
y = Fp2.neg(y);
|
|
1150
1155
|
const point = exports.bls12_381.G2.ProjectivePoint.fromAffine({ x, y });
|
|
1151
1156
|
point.assertValidity();
|
|
1152
1157
|
return point;
|
|
1153
1158
|
},
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
const a = point.toAffine();
|
|
1160
|
-
const { re: x0, im: x1 } = Fp2.reim(a.x);
|
|
1161
|
-
const { re: y0, im: y1 } = Fp2.reim(a.y);
|
|
1162
|
-
const tmp = y1 > 0n ? y1 * 2n : y0 * 2n;
|
|
1163
|
-
const aflag1 = Boolean((tmp / Fp.ORDER) & 1n);
|
|
1164
|
-
const z1 = (0, utils_js_1.bitSet)((0, utils_js_1.bitSet)(x1, 381, aflag1), S_BIT_POS, true);
|
|
1165
|
-
const z2 = x0;
|
|
1166
|
-
return (0, utils_js_1.concatBytes)((0, utils_js_1.numberToBytesBE)(z1, Fp.BYTES), (0, utils_js_1.numberToBytesBE)(z2, Fp.BYTES));
|
|
1159
|
+
toRawBytes(point) {
|
|
1160
|
+
return signatureG2ToRawBytes(point);
|
|
1161
|
+
},
|
|
1162
|
+
toHex(point) {
|
|
1163
|
+
return (0, utils_js_1.bytesToHex)(signatureG2ToRawBytes(point));
|
|
1167
1164
|
},
|
|
1168
1165
|
},
|
|
1169
1166
|
},
|
|
1170
|
-
|
|
1171
|
-
|
|
1167
|
+
params: {
|
|
1168
|
+
x: BLS_X,
|
|
1169
|
+
r: Fr.ORDER, // order; z⁴ − z² + 1; CURVE.n from other curves
|
|
1170
|
+
},
|
|
1172
1171
|
htfDefaults,
|
|
1173
1172
|
hash: sha256_1.sha256,
|
|
1174
1173
|
randomBytes: utils_1.randomBytes,
|