@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.
- package/README.md +520 -505
- package/abstract/bls.d.ts +58 -120
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +108 -152
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +18 -54
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +30 -49
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +18 -77
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +68 -144
- package/abstract/edwards.js.map +1 -1
- package/abstract/fft.js +14 -27
- package/abstract/fft.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +35 -47
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +42 -46
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +5 -17
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +170 -169
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +7 -12
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +22 -29
- package/abstract/montgomery.js.map +1 -1
- package/abstract/oprf.d.ts +282 -0
- package/abstract/oprf.d.ts.map +1 -0
- package/abstract/oprf.js +297 -0
- package/abstract/oprf.js.map +1 -0
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +26 -31
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +43 -19
- package/abstract/tower.js.map +1 -1
- package/abstract/weierstrass.d.ts +77 -168
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +184 -389
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +5 -11
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +161 -181
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +59 -11
- package/bn254.d.ts.map +1 -1
- package/bn254.js +69 -97
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +33 -48
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +147 -161
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +27 -36
- package/ed448.d.ts.map +1 -1
- package/ed448.js +143 -164
- package/ed448.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +20 -4
- package/index.js.map +1 -1
- package/misc.d.ts +10 -14
- package/misc.d.ts.map +1 -1
- package/misc.js +53 -62
- package/misc.js.map +1 -1
- package/nist.d.ts +31 -16
- package/nist.d.ts.map +1 -1
- package/nist.js +75 -64
- package/nist.js.map +1 -1
- package/package.json +20 -234
- package/secp256k1.d.ts +17 -30
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +59 -73
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +207 -354
- package/src/abstract/curve.ts +25 -84
- package/src/abstract/edwards.ts +68 -193
- package/src/abstract/hash-to-curve.ts +71 -85
- package/src/abstract/modular.ts +150 -134
- package/src/abstract/montgomery.ts +28 -35
- package/src/abstract/oprf.ts +600 -0
- package/src/abstract/poseidon.ts +6 -8
- package/src/abstract/tower.ts +0 -3
- package/src/abstract/weierstrass.ts +203 -525
- package/src/bls12-381.ts +133 -139
- package/src/bn254.ts +69 -93
- package/src/ed25519.ts +106 -133
- package/src/ed448.ts +111 -138
- package/src/index.ts +19 -3
- package/src/misc.ts +68 -51
- package/src/nist.ts +77 -70
- package/src/secp256k1.ts +46 -81
- package/src/utils.ts +67 -137
- package/src/webcrypto.ts +403 -0
- package/utils.d.ts +31 -38
- package/utils.d.ts.map +1 -1
- package/utils.js +66 -185
- package/utils.js.map +1 -1
- package/webcrypto.d.ts +99 -0
- package/webcrypto.d.ts.map +1 -0
- package/webcrypto.js +256 -0
- package/webcrypto.js.map +1 -0
- package/_shortw_utils.d.ts +0 -19
- package/_shortw_utils.d.ts.map +0 -1
- package/_shortw_utils.js +0 -20
- package/_shortw_utils.js.map +0 -1
- package/abstract/utils.d.ts +0 -78
- package/abstract/utils.d.ts.map +0 -1
- package/abstract/utils.js +0 -73
- package/abstract/utils.js.map +0 -1
- package/esm/_shortw_utils.d.ts +0 -19
- package/esm/_shortw_utils.d.ts.map +0 -1
- package/esm/_shortw_utils.js +0 -16
- package/esm/_shortw_utils.js.map +0 -1
- package/esm/abstract/bls.d.ts +0 -190
- package/esm/abstract/bls.d.ts.map +0 -1
- package/esm/abstract/bls.js +0 -408
- package/esm/abstract/bls.js.map +0 -1
- package/esm/abstract/curve.d.ts +0 -231
- package/esm/abstract/curve.d.ts.map +0 -1
- package/esm/abstract/curve.js +0 -465
- package/esm/abstract/curve.js.map +0 -1
- package/esm/abstract/edwards.d.ts +0 -243
- package/esm/abstract/edwards.d.ts.map +0 -1
- package/esm/abstract/edwards.js +0 -627
- package/esm/abstract/edwards.js.map +0 -1
- package/esm/abstract/fft.d.ts +0 -122
- package/esm/abstract/fft.d.ts.map +0 -1
- package/esm/abstract/fft.js +0 -425
- package/esm/abstract/fft.js.map +0 -1
- package/esm/abstract/hash-to-curve.d.ts +0 -102
- package/esm/abstract/hash-to-curve.d.ts.map +0 -1
- package/esm/abstract/hash-to-curve.js +0 -203
- package/esm/abstract/hash-to-curve.js.map +0 -1
- package/esm/abstract/modular.d.ts +0 -171
- package/esm/abstract/modular.d.ts.map +0 -1
- package/esm/abstract/modular.js +0 -530
- package/esm/abstract/modular.js.map +0 -1
- package/esm/abstract/montgomery.d.ts +0 -30
- package/esm/abstract/montgomery.d.ts.map +0 -1
- package/esm/abstract/montgomery.js +0 -157
- package/esm/abstract/montgomery.js.map +0 -1
- package/esm/abstract/poseidon.d.ts +0 -68
- package/esm/abstract/poseidon.d.ts.map +0 -1
- package/esm/abstract/poseidon.js +0 -296
- package/esm/abstract/poseidon.js.map +0 -1
- package/esm/abstract/tower.d.ts +0 -95
- package/esm/abstract/tower.d.ts.map +0 -1
- package/esm/abstract/tower.js +0 -714
- package/esm/abstract/tower.js.map +0 -1
- package/esm/abstract/utils.d.ts +0 -78
- package/esm/abstract/utils.d.ts.map +0 -1
- package/esm/abstract/utils.js +0 -70
- package/esm/abstract/utils.js.map +0 -1
- package/esm/abstract/weierstrass.d.ts +0 -416
- package/esm/abstract/weierstrass.d.ts.map +0 -1
- package/esm/abstract/weierstrass.js +0 -1413
- package/esm/abstract/weierstrass.js.map +0 -1
- package/esm/bls12-381.d.ts +0 -16
- package/esm/bls12-381.d.ts.map +0 -1
- package/esm/bls12-381.js +0 -705
- package/esm/bls12-381.js.map +0 -1
- package/esm/bn254.d.ts +0 -18
- package/esm/bn254.d.ts.map +0 -1
- package/esm/bn254.js +0 -214
- package/esm/bn254.js.map +0 -1
- package/esm/ed25519.d.ts +0 -106
- package/esm/ed25519.d.ts.map +0 -1
- package/esm/ed25519.js +0 -467
- package/esm/ed25519.js.map +0 -1
- package/esm/ed448.d.ts +0 -100
- package/esm/ed448.d.ts.map +0 -1
- package/esm/ed448.js +0 -459
- package/esm/ed448.js.map +0 -1
- package/esm/index.d.ts +0 -2
- package/esm/index.d.ts.map +0 -1
- package/esm/index.js +0 -17
- package/esm/index.js.map +0 -1
- package/esm/jubjub.d.ts +0 -12
- package/esm/jubjub.d.ts.map +0 -1
- package/esm/jubjub.js +0 -12
- package/esm/jubjub.js.map +0 -1
- package/esm/misc.d.ts +0 -19
- package/esm/misc.d.ts.map +0 -1
- package/esm/misc.js +0 -109
- package/esm/misc.js.map +0 -1
- package/esm/nist.d.ts +0 -21
- package/esm/nist.d.ts.map +0 -1
- package/esm/nist.js +0 -132
- package/esm/nist.js.map +0 -1
- package/esm/p256.d.ts +0 -16
- package/esm/p256.d.ts.map +0 -1
- package/esm/p256.js +0 -16
- package/esm/p256.js.map +0 -1
- package/esm/p384.d.ts +0 -16
- package/esm/p384.d.ts.map +0 -1
- package/esm/p384.js +0 -16
- package/esm/p384.js.map +0 -1
- package/esm/p521.d.ts +0 -16
- package/esm/p521.d.ts.map +0 -1
- package/esm/p521.js +0 -16
- package/esm/p521.js.map +0 -1
- package/esm/package.json +0 -4
- package/esm/pasta.d.ts +0 -10
- package/esm/pasta.d.ts.map +0 -1
- package/esm/pasta.js +0 -10
- package/esm/pasta.js.map +0 -1
- package/esm/secp256k1.d.ts +0 -89
- package/esm/secp256k1.d.ts.map +0 -1
- package/esm/secp256k1.js +0 -294
- package/esm/secp256k1.js.map +0 -1
- package/esm/utils.d.ts +0 -110
- package/esm/utils.d.ts.map +0 -1
- package/esm/utils.js +0 -322
- package/esm/utils.js.map +0 -1
- package/jubjub.d.ts +0 -12
- package/jubjub.d.ts.map +0 -1
- package/jubjub.js +0 -15
- package/jubjub.js.map +0 -1
- package/p256.d.ts +0 -16
- package/p256.d.ts.map +0 -1
- package/p256.js +0 -13
- package/p256.js.map +0 -1
- package/p384.d.ts +0 -16
- package/p384.d.ts.map +0 -1
- package/p384.js +0 -13
- package/p384.js.map +0 -1
- package/p521.d.ts +0 -16
- package/p521.d.ts.map +0 -1
- package/p521.js +0 -13
- package/p521.js.map +0 -1
- package/pasta.d.ts +0 -10
- package/pasta.d.ts.map +0 -1
- package/pasta.js +0 -13
- package/pasta.js.map +0 -1
- package/src/_shortw_utils.ts +0 -21
- package/src/abstract/utils.ts +0 -80
- package/src/jubjub.ts +0 -12
- package/src/p256.ts +0 -15
- package/src/p384.ts +0 -15
- package/src/p521.ts +0 -15
- package/src/package.json +0 -3
- package/src/pasta.ts +0 -9
package/esm/bls12-381.js
DELETED
|
@@ -1,705 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* bls12-381 is pairing-friendly Barreto-Lynn-Scott elliptic curve construction allowing to:
|
|
3
|
-
|
|
4
|
-
* Construct zk-SNARKs at the ~120-bit security, as per [Barbulescu-Duquesne 2017](https://hal.science/hal-01534101/file/main.pdf)
|
|
5
|
-
* Efficiently verify N aggregate signatures with 1 pairing and N ec additions:
|
|
6
|
-
the Boneh-Lynn-Shacham signature scheme is orders of magnitude more efficient than Schnorr
|
|
7
|
-
|
|
8
|
-
BLS can mean 2 different things:
|
|
9
|
-
|
|
10
|
-
* Barreto-Lynn-Scott: BLS12, a Pairing Friendly Elliptic Curve
|
|
11
|
-
* Boneh-Lynn-Shacham: A Signature Scheme.
|
|
12
|
-
|
|
13
|
-
### Summary
|
|
14
|
-
|
|
15
|
-
1. BLS Relies on expensive bilinear pairing
|
|
16
|
-
2. Secret Keys: 32 bytes
|
|
17
|
-
3. Public Keys: 48 OR 96 bytes - big-endian x coordinate of point on G1 OR G2 curve
|
|
18
|
-
4. Signatures: 96 OR 48 bytes - big-endian x coordinate of point on G2 OR G1 curve
|
|
19
|
-
5. The 12 stands for the Embedding degree.
|
|
20
|
-
|
|
21
|
-
Modes of operation:
|
|
22
|
-
|
|
23
|
-
* Long signatures: 48-byte keys + 96-byte sigs (G1 keys + G2 sigs).
|
|
24
|
-
* Short signatures: 96-byte keys + 48-byte sigs (G2 keys + G1 sigs).
|
|
25
|
-
|
|
26
|
-
### Formulas
|
|
27
|
-
|
|
28
|
-
- `P = pk x G` - public keys
|
|
29
|
-
- `S = pk x H(m)` - signing, uses hash-to-curve on m
|
|
30
|
-
- `e(P, H(m)) == e(G, S)` - verification using pairings
|
|
31
|
-
- `e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))` - signature aggregation
|
|
32
|
-
|
|
33
|
-
### Curves
|
|
34
|
-
|
|
35
|
-
G1 is ordinary elliptic curve. G2 is extension field curve, think "over complex numbers".
|
|
36
|
-
|
|
37
|
-
- G1: y² = x³ + 4
|
|
38
|
-
- G2: y² = x³ + 4(u + 1) where u = √−1; r-order subgroup of E'(Fp²), M-type twist
|
|
39
|
-
|
|
40
|
-
### Towers
|
|
41
|
-
|
|
42
|
-
Pairing G1 + G2 produces element in Fp₁₂, 12-degree polynomial.
|
|
43
|
-
Fp₁₂ is usually implemented using tower of lower-degree polynomials for speed.
|
|
44
|
-
|
|
45
|
-
- Fp₁₂ = Fp₆² => Fp₂³
|
|
46
|
-
- Fp(u) / (u² - β) where β = -1
|
|
47
|
-
- Fp₂(v) / (v³ - ξ) where ξ = u + 1
|
|
48
|
-
- Fp₆(w) / (w² - γ) where γ = v
|
|
49
|
-
- Fp²[u] = Fp/u²+1
|
|
50
|
-
- Fp⁶[v] = Fp²/v³-1-u
|
|
51
|
-
- Fp¹²[w] = Fp⁶/w²-v
|
|
52
|
-
|
|
53
|
-
### Params
|
|
54
|
-
|
|
55
|
-
* Embedding degree (k): 12
|
|
56
|
-
* Seed is sometimes named x or t
|
|
57
|
-
* t = -15132376222941642752
|
|
58
|
-
* p = (t-1)² * (t⁴-t²+1)/3 + t
|
|
59
|
-
* r = t⁴-t²+1
|
|
60
|
-
* Ate loop size: X
|
|
61
|
-
|
|
62
|
-
To verify curve parameters, see
|
|
63
|
-
[pairing-friendly-curves spec](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11).
|
|
64
|
-
Basic math is done over finite fields over p.
|
|
65
|
-
More complicated math is done over polynominal extension fields.
|
|
66
|
-
|
|
67
|
-
### Compatibility and notes
|
|
68
|
-
1. It is compatible with Algorand, Chia, Dfinity, Ethereum, Filecoin, ZEC.
|
|
69
|
-
Filecoin uses little endian byte arrays for secret keys - make sure to reverse byte order.
|
|
70
|
-
2. Make sure to correctly select mode: "long signature" or "short signature".
|
|
71
|
-
3. Compatible with specs:
|
|
72
|
-
RFC 9380,
|
|
73
|
-
[cfrg-pairing-friendly-curves-11](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11),
|
|
74
|
-
[cfrg-bls-signature-05](https://datatracker.ietf.org/doc/draft-irtf-cfrg-bls-signature/).
|
|
75
|
-
|
|
76
|
-
*
|
|
77
|
-
* @module
|
|
78
|
-
*/
|
|
79
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
80
|
-
import { sha256 } from '@noble/hashes/sha2.js';
|
|
81
|
-
import { bls } from "./abstract/bls.js";
|
|
82
|
-
import { Field } from "./abstract/modular.js";
|
|
83
|
-
import { abytes, bitLen, bitMask, bytesToHex, bytesToNumberBE, concatBytes, ensureBytes, numberToBytesBE, } from "./utils.js";
|
|
84
|
-
// Types
|
|
85
|
-
import { isogenyMap } from "./abstract/hash-to-curve.js";
|
|
86
|
-
import { psiFrobenius, tower12 } from "./abstract/tower.js";
|
|
87
|
-
import { mapToCurveSimpleSWU, } from "./abstract/weierstrass.js";
|
|
88
|
-
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
89
|
-
// prettier-ignore
|
|
90
|
-
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
|
|
91
|
-
// To verify math:
|
|
92
|
-
// https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-11
|
|
93
|
-
// The BLS parameter x (seed) for BLS12-381. NOTE: it is negative!
|
|
94
|
-
// x = -2^63 - 2^62 - 2^60 - 2^57 - 2^48 - 2^16
|
|
95
|
-
const BLS_X = BigInt('0xd201000000010000');
|
|
96
|
-
// t = x (called differently in different places)
|
|
97
|
-
// const t = -BLS_X;
|
|
98
|
-
const BLS_X_LEN = bitLen(BLS_X);
|
|
99
|
-
// a=0, b=4
|
|
100
|
-
// P is characteristic of field Fp, in which curve calculations are done.
|
|
101
|
-
// p = (t-1)² * (t⁴-t²+1)/3 + t
|
|
102
|
-
// bls12_381_Fp = (t-1n)**2n * (t**4n - t**2n + 1n) / 3n + t
|
|
103
|
-
// r*h is curve order, amount of points on curve,
|
|
104
|
-
// where r is order of prime subgroup and h is cofactor.
|
|
105
|
-
// r = t⁴-t²+1
|
|
106
|
-
// r = (t**4n - t**2n + 1n)
|
|
107
|
-
// cofactor h of G1: (t - 1)²/3
|
|
108
|
-
// cofactorG1 = (t-1n)**2n/3n
|
|
109
|
-
// x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
|
|
110
|
-
// y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
|
|
111
|
-
const bls12_381_CURVE_G1 = {
|
|
112
|
-
p: BigInt('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'),
|
|
113
|
-
n: BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'),
|
|
114
|
-
h: BigInt('0x396c8c005555e1568c00aaab0000aaab'),
|
|
115
|
-
a: _0n,
|
|
116
|
-
b: _4n,
|
|
117
|
-
Gx: BigInt('0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb'),
|
|
118
|
-
Gy: BigInt('0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1'),
|
|
119
|
-
};
|
|
120
|
-
// CURVE FIELDS
|
|
121
|
-
export const bls12_381_Fr = Field(bls12_381_CURVE_G1.n, {
|
|
122
|
-
modFromBytes: true,
|
|
123
|
-
isLE: true,
|
|
124
|
-
});
|
|
125
|
-
const { Fp, Fp2, Fp6, Fp12 } = tower12({
|
|
126
|
-
ORDER: bls12_381_CURVE_G1.p,
|
|
127
|
-
X_LEN: BLS_X_LEN,
|
|
128
|
-
// Finite extension field over irreducible polynominal.
|
|
129
|
-
// Fp(u) / (u² - β) where β = -1
|
|
130
|
-
FP2_NONRESIDUE: [_1n, _1n],
|
|
131
|
-
Fp2mulByB: ({ c0, c1 }) => {
|
|
132
|
-
const t0 = Fp.mul(c0, _4n); // 4 * c0
|
|
133
|
-
const t1 = Fp.mul(c1, _4n); // 4 * c1
|
|
134
|
-
// (T0-T1) + (T0+T1)*i
|
|
135
|
-
return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
|
|
136
|
-
},
|
|
137
|
-
Fp12finalExponentiate: (num) => {
|
|
138
|
-
const x = BLS_X;
|
|
139
|
-
// this^(q⁶) / this
|
|
140
|
-
const t0 = Fp12.div(Fp12.frobeniusMap(num, 6), num);
|
|
141
|
-
// t0^(q²) * t0
|
|
142
|
-
const t1 = Fp12.mul(Fp12.frobeniusMap(t0, 2), t0);
|
|
143
|
-
const t2 = Fp12.conjugate(Fp12._cyclotomicExp(t1, x));
|
|
144
|
-
const t3 = Fp12.mul(Fp12.conjugate(Fp12._cyclotomicSquare(t1)), t2);
|
|
145
|
-
const t4 = Fp12.conjugate(Fp12._cyclotomicExp(t3, x));
|
|
146
|
-
const t5 = Fp12.conjugate(Fp12._cyclotomicExp(t4, x));
|
|
147
|
-
const t6 = Fp12.mul(Fp12.conjugate(Fp12._cyclotomicExp(t5, x)), Fp12._cyclotomicSquare(t2));
|
|
148
|
-
const t7 = Fp12.conjugate(Fp12._cyclotomicExp(t6, x));
|
|
149
|
-
const t2_t5_pow_q2 = Fp12.frobeniusMap(Fp12.mul(t2, t5), 2);
|
|
150
|
-
const t4_t1_pow_q3 = Fp12.frobeniusMap(Fp12.mul(t4, t1), 3);
|
|
151
|
-
const t6_t1c_pow_q1 = Fp12.frobeniusMap(Fp12.mul(t6, Fp12.conjugate(t1)), 1);
|
|
152
|
-
const t7_t3c_t1 = Fp12.mul(Fp12.mul(t7, Fp12.conjugate(t3)), t1);
|
|
153
|
-
// (t2 * t5)^(q²) * (t4 * t1)^(q³) * (t6 * t1.conj)^(q^1) * t7 * t3.conj * t1
|
|
154
|
-
return Fp12.mul(Fp12.mul(Fp12.mul(t2_t5_pow_q2, t4_t1_pow_q3), t6_t1c_pow_q1), t7_t3c_t1);
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
// GLV endomorphism Ψ(P), for fast cofactor clearing
|
|
158
|
-
const { G2psi, G2psi2 } = psiFrobenius(Fp, Fp2, Fp2.div(Fp2.ONE, Fp2.NONRESIDUE)); // 1/(u+1)
|
|
159
|
-
/**
|
|
160
|
-
* Default hash_to_field / hash-to-curve for BLS.
|
|
161
|
-
* m: 1 for G1, 2 for G2
|
|
162
|
-
* k: target security level in bits
|
|
163
|
-
* hash: any function, e.g. BBS+ uses BLAKE2: see [github](https://github.com/hyperledger/aries-framework-go/issues/2247).
|
|
164
|
-
* Parameter values come from [section 8.8.2 of RFC 9380](https://www.rfc-editor.org/rfc/rfc9380#section-8.8.2).
|
|
165
|
-
*/
|
|
166
|
-
const htfDefaults = Object.freeze({
|
|
167
|
-
DST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_',
|
|
168
|
-
encodeDST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_',
|
|
169
|
-
p: Fp.ORDER,
|
|
170
|
-
m: 2,
|
|
171
|
-
k: 128,
|
|
172
|
-
expand: 'xmd',
|
|
173
|
-
hash: sha256,
|
|
174
|
-
});
|
|
175
|
-
// a=0, b=4
|
|
176
|
-
// cofactor h of G2
|
|
177
|
-
// (t^8 - 4t^7 + 5t^6 - 4t^4 + 6t^3 - 4t^2 - 4t + 13)/9
|
|
178
|
-
// cofactorG2 = (t**8n - 4n*t**7n + 5n*t**6n - 4n*t**4n + 6n*t**3n - 4n*t**2n - 4n*t+13n)/9n
|
|
179
|
-
// x = 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758*u + 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
|
|
180
|
-
// y = 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582*u + 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
|
|
181
|
-
const bls12_381_CURVE_G2 = {
|
|
182
|
-
p: Fp2.ORDER,
|
|
183
|
-
n: bls12_381_CURVE_G1.n,
|
|
184
|
-
h: BigInt('0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5'),
|
|
185
|
-
a: Fp2.ZERO,
|
|
186
|
-
b: Fp2.fromBigTuple([_4n, _4n]),
|
|
187
|
-
Gx: Fp2.fromBigTuple([
|
|
188
|
-
BigInt('0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8'),
|
|
189
|
-
BigInt('0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e'),
|
|
190
|
-
]),
|
|
191
|
-
Gy: Fp2.fromBigTuple([
|
|
192
|
-
BigInt('0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801'),
|
|
193
|
-
BigInt('0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be'),
|
|
194
|
-
]),
|
|
195
|
-
};
|
|
196
|
-
// Encoding utils
|
|
197
|
-
// Compressed point of infinity
|
|
198
|
-
// Set compressed & point-at-infinity bits
|
|
199
|
-
const COMPZERO = setMask(Fp.toBytes(_0n), { infinity: true, compressed: true });
|
|
200
|
-
function parseMask(bytes) {
|
|
201
|
-
// Copy, so we can remove mask data. It will be removed also later, when Fp.create will call modulo.
|
|
202
|
-
bytes = bytes.slice();
|
|
203
|
-
const mask = bytes[0] & 224;
|
|
204
|
-
const compressed = !!((mask >> 7) & 1); // compression bit (0b1000_0000)
|
|
205
|
-
const infinity = !!((mask >> 6) & 1); // point at infinity bit (0b0100_0000)
|
|
206
|
-
const sort = !!((mask >> 5) & 1); // sort bit (0b0010_0000)
|
|
207
|
-
bytes[0] &= 31; // clear mask (zero first 3 bits)
|
|
208
|
-
return { compressed, infinity, sort, value: bytes };
|
|
209
|
-
}
|
|
210
|
-
function setMask(bytes, mask) {
|
|
211
|
-
if (bytes[0] & 224)
|
|
212
|
-
throw new Error('setMask: non-empty mask');
|
|
213
|
-
if (mask.compressed)
|
|
214
|
-
bytes[0] |= 128;
|
|
215
|
-
if (mask.infinity)
|
|
216
|
-
bytes[0] |= 64;
|
|
217
|
-
if (mask.sort)
|
|
218
|
-
bytes[0] |= 32;
|
|
219
|
-
return bytes;
|
|
220
|
-
}
|
|
221
|
-
function pointG1ToBytes(_c, point, isComp) {
|
|
222
|
-
const { BYTES: L, ORDER: P } = Fp;
|
|
223
|
-
const is0 = point.is0();
|
|
224
|
-
const { x, y } = point.toAffine();
|
|
225
|
-
if (isComp) {
|
|
226
|
-
if (is0)
|
|
227
|
-
return COMPZERO.slice();
|
|
228
|
-
const sort = Boolean((y * _2n) / P);
|
|
229
|
-
return setMask(numberToBytesBE(x, L), { compressed: true, sort });
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
if (is0) {
|
|
233
|
-
return concatBytes(Uint8Array.of(0x40), new Uint8Array(2 * L - 1));
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
return concatBytes(numberToBytesBE(x, L), numberToBytesBE(y, L));
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
function signatureG1ToBytes(point) {
|
|
241
|
-
point.assertValidity();
|
|
242
|
-
const { BYTES: L, ORDER: P } = Fp;
|
|
243
|
-
const { x, y } = point.toAffine();
|
|
244
|
-
if (point.is0())
|
|
245
|
-
return COMPZERO.slice();
|
|
246
|
-
const sort = Boolean((y * _2n) / P);
|
|
247
|
-
return setMask(numberToBytesBE(x, L), { compressed: true, sort });
|
|
248
|
-
}
|
|
249
|
-
function pointG1FromBytes(bytes) {
|
|
250
|
-
const { compressed, infinity, sort, value } = parseMask(bytes);
|
|
251
|
-
const { BYTES: L, ORDER: P } = Fp;
|
|
252
|
-
if (value.length === 48 && compressed) {
|
|
253
|
-
const compressedValue = bytesToNumberBE(value);
|
|
254
|
-
// Zero
|
|
255
|
-
const x = Fp.create(compressedValue & bitMask(Fp.BITS));
|
|
256
|
-
if (infinity) {
|
|
257
|
-
if (x !== _0n)
|
|
258
|
-
throw new Error('invalid G1 point: non-empty, at infinity, with compression');
|
|
259
|
-
return { x: _0n, y: _0n };
|
|
260
|
-
}
|
|
261
|
-
const right = Fp.add(Fp.pow(x, _3n), Fp.create(bls12_381_CURVE_G1.b)); // y² = x³ + b
|
|
262
|
-
let y = Fp.sqrt(right);
|
|
263
|
-
if (!y)
|
|
264
|
-
throw new Error('invalid G1 point: compressed point');
|
|
265
|
-
if ((y * _2n) / P !== BigInt(sort))
|
|
266
|
-
y = Fp.neg(y);
|
|
267
|
-
return { x: Fp.create(x), y: Fp.create(y) };
|
|
268
|
-
}
|
|
269
|
-
else if (value.length === 96 && !compressed) {
|
|
270
|
-
// Check if the infinity flag is set
|
|
271
|
-
const x = bytesToNumberBE(value.subarray(0, L));
|
|
272
|
-
const y = bytesToNumberBE(value.subarray(L));
|
|
273
|
-
if (infinity) {
|
|
274
|
-
if (x !== _0n || y !== _0n)
|
|
275
|
-
throw new Error('G1: non-empty point at infinity');
|
|
276
|
-
return bls12_381.G1.Point.ZERO.toAffine();
|
|
277
|
-
}
|
|
278
|
-
return { x: Fp.create(x), y: Fp.create(y) };
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
throw new Error('invalid G1 point: expected 48/96 bytes');
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
function signatureG1FromBytes(hex) {
|
|
285
|
-
const { infinity, sort, value } = parseMask(ensureBytes('signatureHex', hex, 48));
|
|
286
|
-
const P = Fp.ORDER;
|
|
287
|
-
const Point = bls12_381.G1.Point;
|
|
288
|
-
const compressedValue = bytesToNumberBE(value);
|
|
289
|
-
// Zero
|
|
290
|
-
if (infinity)
|
|
291
|
-
return Point.ZERO;
|
|
292
|
-
const x = Fp.create(compressedValue & bitMask(Fp.BITS));
|
|
293
|
-
const right = Fp.add(Fp.pow(x, _3n), Fp.create(bls12_381_CURVE_G1.b)); // y² = x³ + b
|
|
294
|
-
let y = Fp.sqrt(right);
|
|
295
|
-
if (!y)
|
|
296
|
-
throw new Error('invalid G1 point: compressed');
|
|
297
|
-
const aflag = BigInt(sort);
|
|
298
|
-
if ((y * _2n) / P !== aflag)
|
|
299
|
-
y = Fp.neg(y);
|
|
300
|
-
const point = Point.fromAffine({ x, y });
|
|
301
|
-
point.assertValidity();
|
|
302
|
-
return point;
|
|
303
|
-
}
|
|
304
|
-
function pointG2ToBytes(_c, point, isComp) {
|
|
305
|
-
const { BYTES: L, ORDER: P } = Fp;
|
|
306
|
-
const is0 = point.is0();
|
|
307
|
-
const { x, y } = point.toAffine();
|
|
308
|
-
if (isComp) {
|
|
309
|
-
if (is0)
|
|
310
|
-
return concatBytes(COMPZERO, numberToBytesBE(_0n, L));
|
|
311
|
-
const flag = Boolean(y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P);
|
|
312
|
-
return concatBytes(setMask(numberToBytesBE(x.c1, L), { compressed: true, sort: flag }), numberToBytesBE(x.c0, L));
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
if (is0)
|
|
316
|
-
return concatBytes(Uint8Array.of(0x40), new Uint8Array(4 * L - 1));
|
|
317
|
-
const { re: x0, im: x1 } = Fp2.reim(x);
|
|
318
|
-
const { re: y0, im: y1 } = Fp2.reim(y);
|
|
319
|
-
return concatBytes(numberToBytesBE(x1, L), numberToBytesBE(x0, L), numberToBytesBE(y1, L), numberToBytesBE(y0, L));
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
function signatureG2ToBytes(point) {
|
|
323
|
-
point.assertValidity();
|
|
324
|
-
const { BYTES: L } = Fp;
|
|
325
|
-
if (point.is0())
|
|
326
|
-
return concatBytes(COMPZERO, numberToBytesBE(_0n, L));
|
|
327
|
-
const { x, y } = point.toAffine();
|
|
328
|
-
const { re: x0, im: x1 } = Fp2.reim(x);
|
|
329
|
-
const { re: y0, im: y1 } = Fp2.reim(y);
|
|
330
|
-
const tmp = y1 > _0n ? y1 * _2n : y0 * _2n;
|
|
331
|
-
const sort = Boolean((tmp / Fp.ORDER) & _1n);
|
|
332
|
-
const z2 = x0;
|
|
333
|
-
return concatBytes(setMask(numberToBytesBE(x1, L), { sort, compressed: true }), numberToBytesBE(z2, L));
|
|
334
|
-
}
|
|
335
|
-
function pointG2FromBytes(bytes) {
|
|
336
|
-
const { BYTES: L, ORDER: P } = Fp;
|
|
337
|
-
const { compressed, infinity, sort, value } = parseMask(bytes);
|
|
338
|
-
if ((!compressed && !infinity && sort) || // 00100000
|
|
339
|
-
(!compressed && infinity && sort) || // 01100000
|
|
340
|
-
(sort && infinity && compressed) // 11100000
|
|
341
|
-
) {
|
|
342
|
-
throw new Error('invalid encoding flag: ' + (bytes[0] & 224));
|
|
343
|
-
}
|
|
344
|
-
const slc = (b, from, to) => bytesToNumberBE(b.slice(from, to));
|
|
345
|
-
if (value.length === 96 && compressed) {
|
|
346
|
-
if (infinity) {
|
|
347
|
-
// check that all bytes are 0
|
|
348
|
-
if (value.reduce((p, c) => (p !== 0 ? c + 1 : c), 0) > 0) {
|
|
349
|
-
throw new Error('invalid G2 point: compressed');
|
|
350
|
-
}
|
|
351
|
-
return { x: Fp2.ZERO, y: Fp2.ZERO };
|
|
352
|
-
}
|
|
353
|
-
const x_1 = slc(value, 0, L);
|
|
354
|
-
const x_0 = slc(value, L, 2 * L);
|
|
355
|
-
const x = Fp2.create({ c0: Fp.create(x_0), c1: Fp.create(x_1) });
|
|
356
|
-
const right = Fp2.add(Fp2.pow(x, _3n), bls12_381_CURVE_G2.b); // y² = x³ + 4 * (u+1) = x³ + b
|
|
357
|
-
let y = Fp2.sqrt(right);
|
|
358
|
-
const Y_bit = y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P ? _1n : _0n;
|
|
359
|
-
y = sort && Y_bit > 0 ? y : Fp2.neg(y);
|
|
360
|
-
return { x, y };
|
|
361
|
-
}
|
|
362
|
-
else if (value.length === 192 && !compressed) {
|
|
363
|
-
if (infinity) {
|
|
364
|
-
if (value.reduce((p, c) => (p !== 0 ? c + 1 : c), 0) > 0) {
|
|
365
|
-
throw new Error('invalid G2 point: uncompressed');
|
|
366
|
-
}
|
|
367
|
-
return { x: Fp2.ZERO, y: Fp2.ZERO };
|
|
368
|
-
}
|
|
369
|
-
const x1 = slc(value, 0 * L, 1 * L);
|
|
370
|
-
const x0 = slc(value, 1 * L, 2 * L);
|
|
371
|
-
const y1 = slc(value, 2 * L, 3 * L);
|
|
372
|
-
const y0 = slc(value, 3 * L, 4 * L);
|
|
373
|
-
return { x: Fp2.fromBigTuple([x0, x1]), y: Fp2.fromBigTuple([y0, y1]) };
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
throw new Error('invalid G2 point: expected 96/192 bytes');
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
function signatureG2FromBytes(hex) {
|
|
380
|
-
const { ORDER: P } = Fp;
|
|
381
|
-
// TODO: Optimize, it's very slow because of sqrt.
|
|
382
|
-
const { infinity, sort, value } = parseMask(ensureBytes('signatureHex', hex));
|
|
383
|
-
const Point = bls12_381.G2.Point;
|
|
384
|
-
const half = value.length / 2;
|
|
385
|
-
if (half !== 48 && half !== 96)
|
|
386
|
-
throw new Error('invalid compressed signature length, expected 96/192 bytes');
|
|
387
|
-
const z1 = bytesToNumberBE(value.slice(0, half));
|
|
388
|
-
const z2 = bytesToNumberBE(value.slice(half));
|
|
389
|
-
// Indicates the infinity point
|
|
390
|
-
if (infinity)
|
|
391
|
-
return Point.ZERO;
|
|
392
|
-
const x1 = Fp.create(z1 & bitMask(Fp.BITS));
|
|
393
|
-
const x2 = Fp.create(z2);
|
|
394
|
-
const x = Fp2.create({ c0: x2, c1: x1 });
|
|
395
|
-
const y2 = Fp2.add(Fp2.pow(x, _3n), bls12_381_CURVE_G2.b); // y² = x³ + 4
|
|
396
|
-
// The slow part
|
|
397
|
-
let y = Fp2.sqrt(y2);
|
|
398
|
-
if (!y)
|
|
399
|
-
throw new Error('Failed to find a square root');
|
|
400
|
-
// Choose the y whose leftmost bit of the imaginary part is equal to the a_flag1
|
|
401
|
-
// If y1 happens to be zero, then use the bit of y0
|
|
402
|
-
const { re: y0, im: y1 } = Fp2.reim(y);
|
|
403
|
-
const aflag1 = BigInt(sort);
|
|
404
|
-
const isGreater = y1 > _0n && (y1 * _2n) / P !== aflag1;
|
|
405
|
-
const is0 = y1 === _0n && (y0 * _2n) / P !== aflag1;
|
|
406
|
-
if (isGreater || is0)
|
|
407
|
-
y = Fp2.neg(y);
|
|
408
|
-
const point = Point.fromAffine({ x, y });
|
|
409
|
-
point.assertValidity();
|
|
410
|
-
return point;
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* bls12-381 pairing-friendly curve.
|
|
414
|
-
* @example
|
|
415
|
-
* import { bls12_381 as bls } from '@noble/curves/bls12-381';
|
|
416
|
-
* // G1 keys, G2 signatures
|
|
417
|
-
* const privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';
|
|
418
|
-
* const message = '64726e3da8';
|
|
419
|
-
* const publicKey = bls.getPublicKey(privateKey);
|
|
420
|
-
* const signature = bls.sign(message, privateKey);
|
|
421
|
-
* const isValid = bls.verify(signature, message, publicKey);
|
|
422
|
-
*/
|
|
423
|
-
export const bls12_381 = bls({
|
|
424
|
-
// Fields
|
|
425
|
-
fields: {
|
|
426
|
-
Fp,
|
|
427
|
-
Fp2,
|
|
428
|
-
Fp6,
|
|
429
|
-
Fp12,
|
|
430
|
-
Fr: bls12_381_Fr,
|
|
431
|
-
},
|
|
432
|
-
// G1: y² = x³ + 4
|
|
433
|
-
G1: {
|
|
434
|
-
...bls12_381_CURVE_G1,
|
|
435
|
-
Fp,
|
|
436
|
-
htfDefaults: { ...htfDefaults, m: 1, DST: 'BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_' },
|
|
437
|
-
wrapPrivateKey: true,
|
|
438
|
-
allowInfinityPoint: true,
|
|
439
|
-
// Checks is the point resides in prime-order subgroup.
|
|
440
|
-
// point.isTorsionFree() should return true for valid points
|
|
441
|
-
// It returns false for shitty points.
|
|
442
|
-
// https://eprint.iacr.org/2021/1130.pdf
|
|
443
|
-
isTorsionFree: (c, point) => {
|
|
444
|
-
// GLV endomorphism ψ(P)
|
|
445
|
-
const beta = BigInt('0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe');
|
|
446
|
-
const phi = new c(Fp.mul(point.X, beta), point.Y, point.Z);
|
|
447
|
-
// TODO: unroll
|
|
448
|
-
const xP = point.multiplyUnsafe(BLS_X).negate(); // [x]P
|
|
449
|
-
const u2P = xP.multiplyUnsafe(BLS_X); // [u2]P
|
|
450
|
-
return u2P.equals(phi);
|
|
451
|
-
},
|
|
452
|
-
// Clear cofactor of G1
|
|
453
|
-
// https://eprint.iacr.org/2019/403
|
|
454
|
-
clearCofactor: (_c, point) => {
|
|
455
|
-
// return this.multiplyUnsafe(CURVE.h);
|
|
456
|
-
return point.multiplyUnsafe(BLS_X).add(point); // x*P + P
|
|
457
|
-
},
|
|
458
|
-
mapToCurve: mapToG1,
|
|
459
|
-
fromBytes: pointG1FromBytes,
|
|
460
|
-
toBytes: pointG1ToBytes,
|
|
461
|
-
ShortSignature: {
|
|
462
|
-
fromBytes(bytes) {
|
|
463
|
-
abytes(bytes);
|
|
464
|
-
return signatureG1FromBytes(bytes);
|
|
465
|
-
},
|
|
466
|
-
fromHex(hex) {
|
|
467
|
-
return signatureG1FromBytes(hex);
|
|
468
|
-
},
|
|
469
|
-
toBytes(point) {
|
|
470
|
-
return signatureG1ToBytes(point);
|
|
471
|
-
},
|
|
472
|
-
toRawBytes(point) {
|
|
473
|
-
return signatureG1ToBytes(point);
|
|
474
|
-
},
|
|
475
|
-
toHex(point) {
|
|
476
|
-
return bytesToHex(signatureG1ToBytes(point));
|
|
477
|
-
},
|
|
478
|
-
},
|
|
479
|
-
},
|
|
480
|
-
G2: {
|
|
481
|
-
...bls12_381_CURVE_G2,
|
|
482
|
-
Fp: Fp2,
|
|
483
|
-
// https://datatracker.ietf.org/doc/html/rfc9380#name-clearing-the-cofactor
|
|
484
|
-
// https://datatracker.ietf.org/doc/html/rfc9380#name-cofactor-clearing-for-bls12
|
|
485
|
-
hEff: BigInt('0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551'),
|
|
486
|
-
htfDefaults: { ...htfDefaults },
|
|
487
|
-
wrapPrivateKey: true,
|
|
488
|
-
allowInfinityPoint: true,
|
|
489
|
-
mapToCurve: mapToG2,
|
|
490
|
-
// Checks is the point resides in prime-order subgroup.
|
|
491
|
-
// point.isTorsionFree() should return true for valid points
|
|
492
|
-
// It returns false for shitty points.
|
|
493
|
-
// https://eprint.iacr.org/2021/1130.pdf
|
|
494
|
-
// Older version: https://eprint.iacr.org/2019/814.pdf
|
|
495
|
-
isTorsionFree: (c, P) => {
|
|
496
|
-
return P.multiplyUnsafe(BLS_X).negate().equals(G2psi(c, P)); // ψ(P) == [u](P)
|
|
497
|
-
},
|
|
498
|
-
// Maps the point into the prime-order subgroup G2.
|
|
499
|
-
// clear_cofactor_bls12381_g2 from RFC 9380.
|
|
500
|
-
// https://eprint.iacr.org/2017/419.pdf
|
|
501
|
-
// prettier-ignore
|
|
502
|
-
clearCofactor: (c, P) => {
|
|
503
|
-
const x = BLS_X;
|
|
504
|
-
let t1 = P.multiplyUnsafe(x).negate(); // [-x]P
|
|
505
|
-
let t2 = G2psi(c, P); // Ψ(P)
|
|
506
|
-
let t3 = P.double(); // 2P
|
|
507
|
-
t3 = G2psi2(c, t3); // Ψ²(2P)
|
|
508
|
-
t3 = t3.subtract(t2); // Ψ²(2P) - Ψ(P)
|
|
509
|
-
t2 = t1.add(t2); // [-x]P + Ψ(P)
|
|
510
|
-
t2 = t2.multiplyUnsafe(x).negate(); // [x²]P - [x]Ψ(P)
|
|
511
|
-
t3 = t3.add(t2); // Ψ²(2P) - Ψ(P) + [x²]P - [x]Ψ(P)
|
|
512
|
-
t3 = t3.subtract(t1); // Ψ²(2P) - Ψ(P) + [x²]P - [x]Ψ(P) + [x]P
|
|
513
|
-
const Q = t3.subtract(P); // Ψ²(2P) - Ψ(P) + [x²]P - [x]Ψ(P) + [x]P - 1P
|
|
514
|
-
return Q; // [x²-x-1]P + [x-1]Ψ(P) + Ψ²(2P)
|
|
515
|
-
},
|
|
516
|
-
fromBytes: pointG2FromBytes,
|
|
517
|
-
toBytes: pointG2ToBytes,
|
|
518
|
-
Signature: {
|
|
519
|
-
fromBytes(bytes) {
|
|
520
|
-
abytes(bytes);
|
|
521
|
-
return signatureG2FromBytes(bytes);
|
|
522
|
-
},
|
|
523
|
-
fromHex(hex) {
|
|
524
|
-
return signatureG2FromBytes(hex);
|
|
525
|
-
},
|
|
526
|
-
toBytes(point) {
|
|
527
|
-
return signatureG2ToBytes(point);
|
|
528
|
-
},
|
|
529
|
-
toRawBytes(point) {
|
|
530
|
-
return signatureG2ToBytes(point);
|
|
531
|
-
},
|
|
532
|
-
toHex(point) {
|
|
533
|
-
return bytesToHex(signatureG2ToBytes(point));
|
|
534
|
-
},
|
|
535
|
-
},
|
|
536
|
-
},
|
|
537
|
-
params: {
|
|
538
|
-
ateLoopSize: BLS_X, // The BLS parameter x for BLS12-381
|
|
539
|
-
r: bls12_381_CURVE_G1.n, // order; z⁴ − z² + 1; CURVE.n from other curves
|
|
540
|
-
xNegative: true,
|
|
541
|
-
twistType: 'multiplicative',
|
|
542
|
-
},
|
|
543
|
-
htfDefaults,
|
|
544
|
-
hash: sha256,
|
|
545
|
-
});
|
|
546
|
-
// 3-isogeny map from E' to E https://www.rfc-editor.org/rfc/rfc9380#appendix-E.3
|
|
547
|
-
const isogenyMapG2 = isogenyMap(Fp2, [
|
|
548
|
-
// xNum
|
|
549
|
-
[
|
|
550
|
-
[
|
|
551
|
-
'0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6',
|
|
552
|
-
'0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6',
|
|
553
|
-
],
|
|
554
|
-
[
|
|
555
|
-
'0x0',
|
|
556
|
-
'0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a',
|
|
557
|
-
],
|
|
558
|
-
[
|
|
559
|
-
'0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e',
|
|
560
|
-
'0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d',
|
|
561
|
-
],
|
|
562
|
-
[
|
|
563
|
-
'0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1',
|
|
564
|
-
'0x0',
|
|
565
|
-
],
|
|
566
|
-
],
|
|
567
|
-
// xDen
|
|
568
|
-
[
|
|
569
|
-
[
|
|
570
|
-
'0x0',
|
|
571
|
-
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63',
|
|
572
|
-
],
|
|
573
|
-
[
|
|
574
|
-
'0xc',
|
|
575
|
-
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f',
|
|
576
|
-
],
|
|
577
|
-
['0x1', '0x0'], // LAST 1
|
|
578
|
-
],
|
|
579
|
-
// yNum
|
|
580
|
-
[
|
|
581
|
-
[
|
|
582
|
-
'0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706',
|
|
583
|
-
'0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706',
|
|
584
|
-
],
|
|
585
|
-
[
|
|
586
|
-
'0x0',
|
|
587
|
-
'0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be',
|
|
588
|
-
],
|
|
589
|
-
[
|
|
590
|
-
'0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c',
|
|
591
|
-
'0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f',
|
|
592
|
-
],
|
|
593
|
-
[
|
|
594
|
-
'0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10',
|
|
595
|
-
'0x0',
|
|
596
|
-
],
|
|
597
|
-
],
|
|
598
|
-
// yDen
|
|
599
|
-
[
|
|
600
|
-
[
|
|
601
|
-
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb',
|
|
602
|
-
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb',
|
|
603
|
-
],
|
|
604
|
-
[
|
|
605
|
-
'0x0',
|
|
606
|
-
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3',
|
|
607
|
-
],
|
|
608
|
-
[
|
|
609
|
-
'0x12',
|
|
610
|
-
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99',
|
|
611
|
-
],
|
|
612
|
-
['0x1', '0x0'], // LAST 1
|
|
613
|
-
],
|
|
614
|
-
].map((i) => i.map((pair) => Fp2.fromBigTuple(pair.map(BigInt)))));
|
|
615
|
-
// 11-isogeny map from E' to E
|
|
616
|
-
const isogenyMapG1 = isogenyMap(Fp, [
|
|
617
|
-
// xNum
|
|
618
|
-
[
|
|
619
|
-
'0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7',
|
|
620
|
-
'0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb',
|
|
621
|
-
'0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0',
|
|
622
|
-
'0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861',
|
|
623
|
-
'0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9',
|
|
624
|
-
'0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983',
|
|
625
|
-
'0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84',
|
|
626
|
-
'0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e',
|
|
627
|
-
'0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317',
|
|
628
|
-
'0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e',
|
|
629
|
-
'0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b',
|
|
630
|
-
'0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229',
|
|
631
|
-
],
|
|
632
|
-
// xDen
|
|
633
|
-
[
|
|
634
|
-
'0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c',
|
|
635
|
-
'0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff',
|
|
636
|
-
'0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19',
|
|
637
|
-
'0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8',
|
|
638
|
-
'0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e',
|
|
639
|
-
'0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5',
|
|
640
|
-
'0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a',
|
|
641
|
-
'0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e',
|
|
642
|
-
'0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641',
|
|
643
|
-
'0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a',
|
|
644
|
-
'0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', // LAST 1
|
|
645
|
-
],
|
|
646
|
-
// yNum
|
|
647
|
-
[
|
|
648
|
-
'0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33',
|
|
649
|
-
'0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696',
|
|
650
|
-
'0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6',
|
|
651
|
-
'0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb',
|
|
652
|
-
'0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb',
|
|
653
|
-
'0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0',
|
|
654
|
-
'0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2',
|
|
655
|
-
'0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29',
|
|
656
|
-
'0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587',
|
|
657
|
-
'0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30',
|
|
658
|
-
'0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132',
|
|
659
|
-
'0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e',
|
|
660
|
-
'0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8',
|
|
661
|
-
'0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133',
|
|
662
|
-
'0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b',
|
|
663
|
-
'0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604',
|
|
664
|
-
],
|
|
665
|
-
// yDen
|
|
666
|
-
[
|
|
667
|
-
'0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1',
|
|
668
|
-
'0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d',
|
|
669
|
-
'0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2',
|
|
670
|
-
'0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416',
|
|
671
|
-
'0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d',
|
|
672
|
-
'0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac',
|
|
673
|
-
'0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c',
|
|
674
|
-
'0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9',
|
|
675
|
-
'0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a',
|
|
676
|
-
'0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55',
|
|
677
|
-
'0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8',
|
|
678
|
-
'0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092',
|
|
679
|
-
'0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc',
|
|
680
|
-
'0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7',
|
|
681
|
-
'0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f',
|
|
682
|
-
'0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', // LAST 1
|
|
683
|
-
],
|
|
684
|
-
].map((i) => i.map((j) => BigInt(j))));
|
|
685
|
-
// Optimized SWU Map - Fp to G1
|
|
686
|
-
const G1_SWU = mapToCurveSimpleSWU(Fp, {
|
|
687
|
-
A: Fp.create(BigInt('0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d')),
|
|
688
|
-
B: Fp.create(BigInt('0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0')),
|
|
689
|
-
Z: Fp.create(BigInt(11)),
|
|
690
|
-
});
|
|
691
|
-
// SWU Map - Fp2 to G2': y² = x³ + 240i * x + 1012 + 1012i
|
|
692
|
-
const G2_SWU = mapToCurveSimpleSWU(Fp2, {
|
|
693
|
-
A: Fp2.create({ c0: Fp.create(_0n), c1: Fp.create(BigInt(240)) }), // A' = 240 * I
|
|
694
|
-
B: Fp2.create({ c0: Fp.create(BigInt(1012)), c1: Fp.create(BigInt(1012)) }), // B' = 1012 * (1 + I)
|
|
695
|
-
Z: Fp2.create({ c0: Fp.create(BigInt(-2)), c1: Fp.create(BigInt(-1)) }), // Z: -(2 + I)
|
|
696
|
-
});
|
|
697
|
-
function mapToG1(scalars) {
|
|
698
|
-
const { x, y } = G1_SWU(Fp.create(scalars[0]));
|
|
699
|
-
return isogenyMapG1(x, y);
|
|
700
|
-
}
|
|
701
|
-
function mapToG2(scalars) {
|
|
702
|
-
const { x, y } = G2_SWU(Fp2.fromBigTuple(scalars));
|
|
703
|
-
return isogenyMapG2(x, y);
|
|
704
|
-
}
|
|
705
|
-
//# sourceMappingURL=bls12-381.js.map
|