@noble/curves 1.7.0 → 1.8.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 +24 -8
- package/_shortw_utils.d.ts +8 -54
- package/_shortw_utils.d.ts.map +1 -1
- package/_shortw_utils.js +6 -2
- package/_shortw_utils.js.map +1 -1
- package/abstract/bls.d.ts +8 -6
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +17 -1
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +26 -31
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +19 -12
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +12 -23
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +5 -1
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +28 -8
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +15 -10
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +30 -5
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +36 -16
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +6 -1
- package/abstract/montgomery.js.map +1 -1
- package/abstract/poseidon.d.ts +9 -0
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +9 -1
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +12 -1
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +14 -11
- package/abstract/tower.js.map +1 -1
- package/abstract/utils.d.ts +10 -5
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +5 -1
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +46 -80
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +34 -7
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +11 -0
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +72 -59
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +4 -3
- package/bn254.d.ts.map +1 -1
- package/bn254.js +24 -20
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +24 -4
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +30 -6
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +23 -8
- package/ed448.d.ts.map +1 -1
- package/ed448.js +30 -8
- package/ed448.js.map +1 -1
- package/esm/_shortw_utils.d.ts +8 -54
- package/esm/_shortw_utils.d.ts.map +1 -1
- package/esm/_shortw_utils.js +6 -2
- package/esm/_shortw_utils.js.map +1 -1
- package/esm/abstract/bls.d.ts +8 -6
- package/esm/abstract/bls.d.ts.map +1 -1
- package/esm/abstract/bls.js +17 -1
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.d.ts +26 -31
- package/esm/abstract/curve.d.ts.map +1 -1
- package/esm/abstract/curve.js +19 -12
- package/esm/abstract/curve.js.map +1 -1
- package/esm/abstract/edwards.d.ts +12 -23
- package/esm/abstract/edwards.d.ts.map +1 -1
- package/esm/abstract/edwards.js +5 -1
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/hash-to-curve.d.ts +28 -8
- package/esm/abstract/hash-to-curve.d.ts.map +1 -1
- package/esm/abstract/hash-to-curve.js +15 -10
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.d.ts +30 -5
- package/esm/abstract/modular.d.ts.map +1 -1
- package/esm/abstract/modular.js +36 -16
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/montgomery.d.ts.map +1 -1
- package/esm/abstract/montgomery.js +6 -1
- package/esm/abstract/montgomery.js.map +1 -1
- package/esm/abstract/poseidon.d.ts +9 -0
- package/esm/abstract/poseidon.d.ts.map +1 -1
- package/esm/abstract/poseidon.js +9 -1
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/tower.d.ts +12 -1
- package/esm/abstract/tower.d.ts.map +1 -1
- package/esm/abstract/tower.js +14 -11
- package/esm/abstract/tower.js.map +1 -1
- package/esm/abstract/utils.d.ts +10 -5
- package/esm/abstract/utils.d.ts.map +1 -1
- package/esm/abstract/utils.js +4 -0
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.d.ts +46 -80
- package/esm/abstract/weierstrass.d.ts.map +1 -1
- package/esm/abstract/weierstrass.js +32 -6
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.d.ts +11 -0
- package/esm/bls12-381.d.ts.map +1 -1
- package/esm/bls12-381.js +72 -59
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn254.d.ts +4 -3
- package/esm/bn254.d.ts.map +1 -1
- package/esm/bn254.js +24 -20
- package/esm/bn254.js.map +1 -1
- package/esm/ed25519.d.ts +24 -4
- package/esm/ed25519.d.ts.map +1 -1
- package/esm/ed25519.js +31 -7
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.d.ts +23 -8
- package/esm/ed448.d.ts.map +1 -1
- package/esm/ed448.js +31 -9
- package/esm/ed448.js.map +1 -1
- package/esm/index.js +4 -0
- package/esm/index.js.map +1 -1
- package/esm/jubjub.d.ts +4 -8
- package/esm/jubjub.d.ts.map +1 -1
- package/esm/jubjub.js +6 -5
- package/esm/jubjub.js.map +1 -1
- package/esm/p256.d.ts +10 -104
- package/esm/p256.d.ts.map +1 -1
- package/esm/p256.js +9 -2
- package/esm/p256.js.map +1 -1
- package/esm/p384.d.ts +10 -104
- package/esm/p384.d.ts.map +1 -1
- package/esm/p384.js +9 -2
- package/esm/p384.js.map +1 -1
- package/esm/p521.d.ts +11 -104
- package/esm/p521.d.ts.map +1 -1
- package/esm/p521.js +11 -3
- package/esm/p521.js.map +1 -1
- package/esm/pasta.d.ts +5 -2
- package/esm/pasta.d.ts.map +1 -1
- package/esm/pasta.js +6 -2
- package/esm/pasta.js.map +1 -1
- package/esm/secp256k1.d.ts +29 -57
- package/esm/secp256k1.d.ts.map +1 -1
- package/esm/secp256k1.js +33 -7
- package/esm/secp256k1.js.map +1 -1
- package/index.js +4 -0
- package/index.js.map +1 -1
- package/jubjub.d.ts +4 -8
- package/jubjub.d.ts.map +1 -1
- package/jubjub.js +6 -5
- package/jubjub.js.map +1 -1
- package/p256.d.ts +10 -104
- package/p256.d.ts.map +1 -1
- package/p256.js +9 -2
- package/p256.js.map +1 -1
- package/p384.d.ts +10 -104
- package/p384.d.ts.map +1 -1
- package/p384.js +9 -2
- package/p384.js.map +1 -1
- package/p521.d.ts +11 -104
- package/p521.d.ts.map +1 -1
- package/p521.js +11 -3
- package/p521.js.map +1 -1
- package/package.json +10 -8
- package/pasta.d.ts +5 -2
- package/pasta.d.ts.map +1 -1
- package/pasta.js +6 -2
- package/pasta.js.map +1 -1
- package/secp256k1.d.ts +29 -57
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +33 -7
- package/secp256k1.js.map +1 -1
- package/src/_shortw_utils.ts +18 -8
- package/src/abstract/bls.ts +17 -17
- package/src/abstract/curve.ts +50 -17
- package/src/abstract/edwards.ts +11 -5
- package/src/abstract/hash-to-curve.ts +41 -16
- package/src/abstract/modular.ts +55 -27
- package/src/abstract/montgomery.ts +7 -1
- package/src/abstract/poseidon.ts +28 -6
- package/src/abstract/tower.ts +59 -14
- package/src/abstract/utils.ts +26 -19
- package/src/abstract/weierstrass.ts +68 -35
- package/src/bls12-381.ts +72 -60
- package/src/bn254.ts +32 -24
- package/src/ed25519.ts +50 -20
- package/src/ed448.ts +48 -21
- package/src/index.ts +4 -0
- package/src/jubjub.ts +10 -10
- package/src/p256.ts +15 -9
- package/src/p384.ts +15 -9
- package/src/p521.ts +17 -10
- package/src/pasta.ts +15 -7
- package/src/secp256k1.ts +55 -13
package/src/abstract/tower.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
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
|
+
*/
|
|
1
12
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
13
|
import * as mod from './modular.js';
|
|
3
14
|
import { bitLen, bitMask, concatBytes, notImplemented } from './utils.js';
|
|
4
15
|
import type { ProjConstructor, ProjPointType } from './weierstrass.js';
|
|
5
16
|
|
|
6
|
-
/*
|
|
7
|
-
Towered extension fields
|
|
8
|
-
|
|
9
|
-
Rather than implementing a massive 12th-degree extension directly, it is more efficient
|
|
10
|
-
to build it up from smaller extensions: a tower of extensions.
|
|
11
|
-
|
|
12
|
-
For BLS12-381, the Fp12 field is implemented as a quadratic (degree two) extension,
|
|
13
|
-
on top of a cubic (degree three) extension, on top of a quadratic extension of Fp.
|
|
14
|
-
|
|
15
|
-
For more info: "Pairings for beginners" by Costello, section 7.3.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
17
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
19
18
|
// prettier-ignore
|
|
20
19
|
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
|
@@ -75,7 +74,20 @@ function calcFrobeniusCoefficients<T>(
|
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
// This works same at least for bls12-381, bn254 and bls12-377
|
|
78
|
-
export function psiFrobenius(
|
|
77
|
+
export function psiFrobenius(
|
|
78
|
+
Fp: mod.IField<Fp>,
|
|
79
|
+
Fp2: Fp2Bls,
|
|
80
|
+
base: Fp2
|
|
81
|
+
): {
|
|
82
|
+
psi: (x: Fp2, y: Fp2) => [Fp2, Fp2];
|
|
83
|
+
psi2: (x: Fp2, y: Fp2) => [Fp2, Fp2];
|
|
84
|
+
G2psi: (c: ProjConstructor<Fp2>, P: ProjPointType<Fp2>) => ProjPointType<Fp2>;
|
|
85
|
+
G2psi2: (c: ProjConstructor<Fp2>, P: ProjPointType<Fp2>) => ProjPointType<Fp2>;
|
|
86
|
+
PSI_X: Fp2;
|
|
87
|
+
PSI_Y: Fp2;
|
|
88
|
+
PSI2_X: Fp2;
|
|
89
|
+
PSI2_Y: Fp2;
|
|
90
|
+
} {
|
|
79
91
|
// Ψ endomorphism
|
|
80
92
|
const PSI_X = Fp2.pow(base, (Fp.ORDER - _1n) / _3n); // u^((p-1)/3)
|
|
81
93
|
const PSI_Y = Fp2.pow(base, (Fp.ORDER - _1n) / _2n); // u^((p-1)/2)
|
|
@@ -120,7 +132,37 @@ export type Tower12Opts = {
|
|
|
120
132
|
Fp12finalExponentiate: (num: Fp12) => Fp12;
|
|
121
133
|
};
|
|
122
134
|
|
|
123
|
-
export function tower12(opts: Tower12Opts) {
|
|
135
|
+
export function tower12(opts: Tower12Opts): {
|
|
136
|
+
Fp: Readonly<mod.IField<bigint> & Required<Pick<mod.IField<bigint>, 'isOdd'>>>;
|
|
137
|
+
Fp2: mod.IField<Fp2> & {
|
|
138
|
+
NONRESIDUE: Fp2;
|
|
139
|
+
fromBigTuple: (tuple: BigintTuple | bigint[]) => Fp2;
|
|
140
|
+
reim: (num: Fp2) => { re: bigint; im: bigint };
|
|
141
|
+
mulByNonresidue: (num: Fp2) => Fp2;
|
|
142
|
+
mulByB: (num: Fp2) => Fp2;
|
|
143
|
+
frobeniusMap(num: Fp2, power: number): Fp2;
|
|
144
|
+
};
|
|
145
|
+
Fp6: mod.IField<Fp6> & {
|
|
146
|
+
fromBigSix: (tuple: BigintSix) => Fp6;
|
|
147
|
+
mulByNonresidue: (num: Fp6) => Fp6;
|
|
148
|
+
frobeniusMap(num: Fp6, power: number): Fp6;
|
|
149
|
+
mul1(num: Fp6, b1: Fp2): Fp6;
|
|
150
|
+
mul01(num: Fp6, b0: Fp2, b1: Fp2): Fp6;
|
|
151
|
+
mulByFp2(lhs: Fp6, rhs: Fp2): Fp6;
|
|
152
|
+
};
|
|
153
|
+
Fp4Square: (a: Fp2, b: Fp2) => { first: Fp2; second: Fp2 };
|
|
154
|
+
Fp12: mod.IField<Fp12> & {
|
|
155
|
+
fromBigTwelve: (t: BigintTwelve) => Fp12;
|
|
156
|
+
frobeniusMap(num: Fp12, power: number): Fp12;
|
|
157
|
+
mul014(num: Fp12, o0: Fp2, o1: Fp2, o4: Fp2): Fp12;
|
|
158
|
+
mul034(num: Fp12, o0: Fp2, o3: Fp2, o4: Fp2): Fp12;
|
|
159
|
+
mulByFp2(lhs: Fp12, rhs: Fp2): Fp12;
|
|
160
|
+
conjugate(num: Fp12): Fp12;
|
|
161
|
+
finalExponentiate(num: Fp12): Fp12;
|
|
162
|
+
_cyclotomicSquare(num: Fp12): Fp12;
|
|
163
|
+
_cyclotomicExp(num: Fp12, n: bigint): Fp12;
|
|
164
|
+
};
|
|
165
|
+
} {
|
|
124
166
|
const { ORDER } = opts;
|
|
125
167
|
// Fp
|
|
126
168
|
const Fp = mod.Field(ORDER);
|
|
@@ -173,6 +215,7 @@ export function tower12(opts: Tower12Opts) {
|
|
|
173
215
|
const Fp2Nonresidue = Fp2fromBigTuple(opts.FP2_NONRESIDUE);
|
|
174
216
|
const Fp2: mod.IField<Fp2> & Fp2Utils = {
|
|
175
217
|
ORDER: FP2_ORDER,
|
|
218
|
+
isLE: Fp.isLE,
|
|
176
219
|
NONRESIDUE: Fp2Nonresidue,
|
|
177
220
|
BITS: bitLen(FP2_ORDER),
|
|
178
221
|
BYTES: Math.ceil(bitLen(FP2_ORDER) / 8),
|
|
@@ -339,6 +382,7 @@ export function tower12(opts: Tower12Opts) {
|
|
|
339
382
|
|
|
340
383
|
const Fp6: mod.IField<Fp6> & Fp6Utils = {
|
|
341
384
|
ORDER: Fp2.ORDER, // TODO: unused, but need to verify
|
|
385
|
+
isLE: Fp2.isLE,
|
|
342
386
|
BITS: 3 * Fp2.BITS,
|
|
343
387
|
BYTES: 3 * Fp2.BYTES,
|
|
344
388
|
MASK: bitMask(3 * Fp2.BITS),
|
|
@@ -495,6 +539,7 @@ export function tower12(opts: Tower12Opts) {
|
|
|
495
539
|
|
|
496
540
|
const Fp12: mod.IField<Fp12> & Fp12Utils = {
|
|
497
541
|
ORDER: Fp2.ORDER, // TODO: unused, but need to verify
|
|
542
|
+
isLE: Fp6.isLE,
|
|
498
543
|
BITS: 2 * Fp2.BITS,
|
|
499
544
|
BYTES: 2 * Fp2.BYTES,
|
|
500
545
|
MASK: bitMask(2 * Fp2.BITS),
|
package/src/abstract/utils.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hex, bytes and number utilities.
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
1
5
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
6
|
+
|
|
2
7
|
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
|
3
8
|
// This is OK: `abstract` directory does not use noble-hashes.
|
|
4
9
|
// User may opt-in into using different hashing library. This way, noble-hashes
|
|
@@ -155,7 +160,7 @@ export function concatBytes(...arrays: Uint8Array[]): Uint8Array {
|
|
|
155
160
|
}
|
|
156
161
|
|
|
157
162
|
// Compares 2 u8a-s in kinda constant time
|
|
158
|
-
export function equalBytes(a: Uint8Array, b: Uint8Array) {
|
|
163
|
+
export function equalBytes(a: Uint8Array, b: Uint8Array): boolean {
|
|
159
164
|
if (a.length !== b.length) return false;
|
|
160
165
|
let diff = 0;
|
|
161
166
|
for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
|
|
@@ -177,7 +182,7 @@ export function utf8ToBytes(str: string): Uint8Array {
|
|
|
177
182
|
// Is positive bigint
|
|
178
183
|
const isPosBig = (n: bigint) => typeof n === 'bigint' && _0n <= n;
|
|
179
184
|
|
|
180
|
-
export function inRange(n: bigint, min: bigint, max: bigint) {
|
|
185
|
+
export function inRange(n: bigint, min: bigint, max: bigint): boolean {
|
|
181
186
|
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
182
187
|
}
|
|
183
188
|
|
|
@@ -186,7 +191,7 @@ export function inRange(n: bigint, min: bigint, max: bigint) {
|
|
|
186
191
|
* @example
|
|
187
192
|
* aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)
|
|
188
193
|
*/
|
|
189
|
-
export function aInRange(title: string, n: bigint, min: bigint, max: bigint) {
|
|
194
|
+
export function aInRange(title: string, n: bigint, min: bigint, max: bigint): void {
|
|
190
195
|
// Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?
|
|
191
196
|
// consider P=256n, min=0n, max=P
|
|
192
197
|
// - a for min=0 would require -1: `inRange('x', x, -1n, P)`
|
|
@@ -202,7 +207,7 @@ export function aInRange(title: string, n: bigint, min: bigint, max: bigint) {
|
|
|
202
207
|
* Calculates amount of bits in a bigint.
|
|
203
208
|
* Same as `n.toString(2).length`
|
|
204
209
|
*/
|
|
205
|
-
export function bitLen(n: bigint) {
|
|
210
|
+
export function bitLen(n: bigint): number {
|
|
206
211
|
let len;
|
|
207
212
|
for (len = 0; n > _0n; n >>= _1n, len += 1);
|
|
208
213
|
return len;
|
|
@@ -213,14 +218,14 @@ export function bitLen(n: bigint) {
|
|
|
213
218
|
* NOTE: first bit position is 0 (same as arrays)
|
|
214
219
|
* Same as `!!+Array.from(n.toString(2)).reverse()[pos]`
|
|
215
220
|
*/
|
|
216
|
-
export function bitGet(n: bigint, pos: number) {
|
|
221
|
+
export function bitGet(n: bigint, pos: number): bigint {
|
|
217
222
|
return (n >> BigInt(pos)) & _1n;
|
|
218
223
|
}
|
|
219
224
|
|
|
220
225
|
/**
|
|
221
226
|
* Sets single bit at position.
|
|
222
227
|
*/
|
|
223
|
-
export function bitSet(n: bigint, pos: number, value: boolean) {
|
|
228
|
+
export function bitSet(n: bigint, pos: number, value: boolean): bigint {
|
|
224
229
|
return n | ((value ? _1n : _0n) << BigInt(pos));
|
|
225
230
|
}
|
|
226
231
|
|
|
@@ -228,7 +233,7 @@ export function bitSet(n: bigint, pos: number, value: boolean) {
|
|
|
228
233
|
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
|
229
234
|
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
|
230
235
|
*/
|
|
231
|
-
export const bitMask = (n: number) => (_2n << BigInt(n - 1)) - _1n;
|
|
236
|
+
export const bitMask = (n: number): bigint => (_2n << BigInt(n - 1)) - _1n;
|
|
232
237
|
|
|
233
238
|
// DRBG
|
|
234
239
|
|
|
@@ -295,15 +300,15 @@ export function createHmacDrbg<T>(
|
|
|
295
300
|
// Validating curves and fields
|
|
296
301
|
|
|
297
302
|
const validatorFns = {
|
|
298
|
-
bigint: (val: any) => typeof val === 'bigint',
|
|
299
|
-
function: (val: any) => typeof val === 'function',
|
|
300
|
-
boolean: (val: any) => typeof val === 'boolean',
|
|
301
|
-
string: (val: any) => typeof val === 'string',
|
|
302
|
-
stringOrUint8Array: (val: any) => typeof val === 'string' || isBytes(val),
|
|
303
|
-
isSafeInteger: (val: any) => Number.isSafeInteger(val),
|
|
304
|
-
array: (val: any) => Array.isArray(val),
|
|
305
|
-
field: (val: any, object: any) => (object as any).Fp.isValid(val),
|
|
306
|
-
hash: (val: any) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
|
303
|
+
bigint: (val: any): boolean => typeof val === 'bigint',
|
|
304
|
+
function: (val: any): boolean => typeof val === 'function',
|
|
305
|
+
boolean: (val: any): boolean => typeof val === 'boolean',
|
|
306
|
+
string: (val: any): boolean => typeof val === 'string',
|
|
307
|
+
stringOrUint8Array: (val: any): boolean => typeof val === 'string' || isBytes(val),
|
|
308
|
+
isSafeInteger: (val: any): boolean => Number.isSafeInteger(val),
|
|
309
|
+
array: (val: any): boolean => Array.isArray(val),
|
|
310
|
+
field: (val: any, object: any): any => (object as any).Fp.isValid(val),
|
|
311
|
+
hash: (val: any): boolean => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
|
307
312
|
} as const;
|
|
308
313
|
type Validator = keyof typeof validatorFns;
|
|
309
314
|
type ValMap<T extends Record<string, any>> = { [K in keyof T]?: Validator };
|
|
@@ -313,7 +318,7 @@ export function validateObject<T extends Record<string, any>>(
|
|
|
313
318
|
object: T,
|
|
314
319
|
validators: ValMap<T>,
|
|
315
320
|
optValidators: ValMap<T> = {}
|
|
316
|
-
) {
|
|
321
|
+
): T {
|
|
317
322
|
const checkField = (fieldName: keyof T, type: Validator, isOptional: boolean) => {
|
|
318
323
|
const checkVal = validatorFns[type];
|
|
319
324
|
if (typeof checkVal !== 'function') throw new Error('invalid validator function');
|
|
@@ -342,7 +347,7 @@ export function validateObject<T extends Record<string, any>>(
|
|
|
342
347
|
/**
|
|
343
348
|
* throws not implemented error
|
|
344
349
|
*/
|
|
345
|
-
export const notImplemented = () => {
|
|
350
|
+
export const notImplemented = (): never => {
|
|
346
351
|
throw new Error('not implemented');
|
|
347
352
|
};
|
|
348
353
|
|
|
@@ -350,7 +355,9 @@ export const notImplemented = () => {
|
|
|
350
355
|
* Memoizes (caches) computation result.
|
|
351
356
|
* Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
|
|
352
357
|
*/
|
|
353
|
-
export function memoized<T extends object, R, O extends any[]>(
|
|
358
|
+
export function memoized<T extends object, R, O extends any[]>(
|
|
359
|
+
fn: (arg: T, ...args: O) => R
|
|
360
|
+
): (arg: T, ...args: O) => R {
|
|
354
361
|
const map = new WeakMap<T, R>();
|
|
355
362
|
return (arg: T, ...args: O): R => {
|
|
356
363
|
const val = map.get(arg);
|
|
@@ -1,5 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
|
|
3
|
+
*
|
|
4
|
+
* ### Design rationale for types
|
|
5
|
+
*
|
|
6
|
+
* * Interaction between classes from different curves should fail:
|
|
7
|
+
* `k256.Point.BASE.add(p256.Point.BASE)`
|
|
8
|
+
* * For this purpose we want to use `instanceof` operator, which is fast and works during runtime
|
|
9
|
+
* * Different calls of `curve()` would return different classes -
|
|
10
|
+
* `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,
|
|
11
|
+
* it won't affect others
|
|
12
|
+
*
|
|
13
|
+
* TypeScript can't infer types for classes created inside a function. Classes is one instance
|
|
14
|
+
* of nominative types in TypeScript and interfaces only check for shape, so it's hard to create
|
|
15
|
+
* unique type for every function call.
|
|
16
|
+
*
|
|
17
|
+
* We can use generic types via some param, like curve opts, but that would:
|
|
18
|
+
* 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)
|
|
19
|
+
* which is hard to debug.
|
|
20
|
+
* 2. Params can be generic and we can't enforce them to be constant value:
|
|
21
|
+
* if somebody creates curve from non-constant params,
|
|
22
|
+
* it would be allowed to interact with other curves with non-constant params
|
|
23
|
+
*
|
|
24
|
+
* @todo https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
1
27
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
|
-
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
|
3
28
|
import {
|
|
4
29
|
AffinePoint,
|
|
5
30
|
BasicCurve,
|
|
@@ -44,28 +69,6 @@ function validateSigVerOpts(opts: SignOpts | VerOpts) {
|
|
|
44
69
|
if (opts.prehash !== undefined) abool('prehash', opts.prehash);
|
|
45
70
|
}
|
|
46
71
|
|
|
47
|
-
/**
|
|
48
|
-
* ### Design rationale for types
|
|
49
|
-
*
|
|
50
|
-
* * Interaction between classes from different curves should fail:
|
|
51
|
-
* `k256.Point.BASE.add(p256.Point.BASE)`
|
|
52
|
-
* * For this purpose we want to use `instanceof` operator, which is fast and works during runtime
|
|
53
|
-
* * Different calls of `curve()` would return different classes -
|
|
54
|
-
* `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,
|
|
55
|
-
* it won't affect others
|
|
56
|
-
*
|
|
57
|
-
* TypeScript can't infer types for classes created inside a function. Classes is one instance of nominative types in TypeScript and interfaces only check for shape, so it's hard to create unique type for every function call.
|
|
58
|
-
*
|
|
59
|
-
* We can use generic types via some param, like curve opts, but that would:
|
|
60
|
-
* 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)
|
|
61
|
-
* which is hard to debug.
|
|
62
|
-
* 2. Params can be generic and we can't enforce them to be constant value:
|
|
63
|
-
* if somebody creates curve from non-constant params,
|
|
64
|
-
* it would be allowed to interact with other curves with non-constant params
|
|
65
|
-
*
|
|
66
|
-
* TODO: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
72
|
// Instance for 3d XYZ points
|
|
70
73
|
export interface ProjPointType<T> extends Group<ProjPointType<T>> {
|
|
71
74
|
readonly px: T;
|
|
@@ -102,7 +105,11 @@ export type CurvePointsType<T> = BasicWCurve<T> & {
|
|
|
102
105
|
toBytes?: (c: ProjConstructor<T>, point: ProjPointType<T>, isCompressed: boolean) => Uint8Array;
|
|
103
106
|
};
|
|
104
107
|
|
|
105
|
-
|
|
108
|
+
export type CurvePointsTypeWithLength<T> = Readonly<
|
|
109
|
+
CurvePointsType<T> & { nByteLength: number; nBitLength: number }
|
|
110
|
+
>;
|
|
111
|
+
|
|
112
|
+
function validatePointOpts<T>(curve: CurvePointsType<T>): CurvePointsTypeWithLength<T> {
|
|
106
113
|
const opts = validateBasic(curve);
|
|
107
114
|
ut.validateObject(
|
|
108
115
|
opts,
|
|
@@ -146,6 +153,31 @@ export type CurvePointsRes<T> = {
|
|
|
146
153
|
|
|
147
154
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
|
148
155
|
|
|
156
|
+
export class DERErr extends Error {
|
|
157
|
+
constructor(m = '') {
|
|
158
|
+
super(m);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
export type IDER = {
|
|
162
|
+
// asn.1 DER encoding utils
|
|
163
|
+
Err: typeof DERErr;
|
|
164
|
+
// Basic building block is TLV (Tag-Length-Value)
|
|
165
|
+
_tlv: {
|
|
166
|
+
encode: (tag: number, data: string) => string;
|
|
167
|
+
// v - value, l - left bytes (unparsed)
|
|
168
|
+
decode(tag: number, data: Uint8Array): { v: Uint8Array; l: Uint8Array };
|
|
169
|
+
};
|
|
170
|
+
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
|
171
|
+
// since we always use positive integers here. It must always be empty:
|
|
172
|
+
// - add zero byte if exists
|
|
173
|
+
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
|
174
|
+
_int: {
|
|
175
|
+
encode(num: bigint): string;
|
|
176
|
+
decode(data: Uint8Array): bigint;
|
|
177
|
+
};
|
|
178
|
+
toSig(hex: string | Uint8Array): { r: bigint; s: bigint };
|
|
179
|
+
hexFromSig(sig: { r: bigint; s: bigint }): string;
|
|
180
|
+
};
|
|
149
181
|
/**
|
|
150
182
|
* ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
|
|
151
183
|
*
|
|
@@ -153,16 +185,12 @@ const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
|
|
153
185
|
*
|
|
154
186
|
* Docs: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/, https://luca.ntop.org/Teaching/Appunti/asn1.html
|
|
155
187
|
*/
|
|
156
|
-
export const DER = {
|
|
188
|
+
export const DER: IDER = {
|
|
157
189
|
// asn.1 DER encoding utils
|
|
158
|
-
Err:
|
|
159
|
-
constructor(m = '') {
|
|
160
|
-
super(m);
|
|
161
|
-
}
|
|
162
|
-
},
|
|
190
|
+
Err: DERErr,
|
|
163
191
|
// Basic building block is TLV (Tag-Length-Value)
|
|
164
192
|
_tlv: {
|
|
165
|
-
encode: (tag: number, data: string) => {
|
|
193
|
+
encode: (tag: number, data: string): string => {
|
|
166
194
|
const { Err: E } = DER;
|
|
167
195
|
if (tag < 0 || tag > 256) throw new E('tlv.encode: wrong tag');
|
|
168
196
|
if (data.length & 1) throw new E('tlv.encode: unpadded data');
|
|
@@ -206,7 +234,7 @@ export const DER = {
|
|
|
206
234
|
// - add zero byte if exists
|
|
207
235
|
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
|
208
236
|
_int: {
|
|
209
|
-
encode(num: bigint) {
|
|
237
|
+
encode(num: bigint): string {
|
|
210
238
|
const { Err: E } = DER;
|
|
211
239
|
if (num < _0n) throw new E('integer: negative integers are not allowed');
|
|
212
240
|
let hex = ut.numberToHexUnpadded(num);
|
|
@@ -737,7 +765,9 @@ export type CurveType = BasicWCurve<bigint> & {
|
|
|
737
765
|
bits2int_modN?: (bytes: Uint8Array) => bigint;
|
|
738
766
|
};
|
|
739
767
|
|
|
740
|
-
function validateOpts(
|
|
768
|
+
function validateOpts(
|
|
769
|
+
curve: CurveType
|
|
770
|
+
): Readonly<CurveType & { nByteLength: number; nBitLength: number }> {
|
|
741
771
|
const opts = validateBasic(curve);
|
|
742
772
|
ut.validateObject(
|
|
743
773
|
opts,
|
|
@@ -1214,7 +1244,10 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|
|
1214
1244
|
* @param Z
|
|
1215
1245
|
* @returns
|
|
1216
1246
|
*/
|
|
1217
|
-
export function SWUFpSqrtRatio<T>(
|
|
1247
|
+
export function SWUFpSqrtRatio<T>(
|
|
1248
|
+
Fp: mod.IField<T>,
|
|
1249
|
+
Z: T
|
|
1250
|
+
): (u: T, v: T) => { isValid: boolean; value: T } {
|
|
1218
1251
|
// Generic implementation
|
|
1219
1252
|
const q = Fp.ORDER;
|
|
1220
1253
|
let l = _0n;
|
|
@@ -1293,7 +1326,7 @@ export function mapToCurveSimpleSWU<T>(
|
|
|
1293
1326
|
B: T;
|
|
1294
1327
|
Z: T;
|
|
1295
1328
|
}
|
|
1296
|
-
) {
|
|
1329
|
+
): (u: T) => { x: T; y: T } {
|
|
1297
1330
|
mod.validateField(Fp);
|
|
1298
1331
|
if (!Fp.isValid(opts.A) || !Fp.isValid(opts.B) || !Fp.isValid(opts.Z))
|
|
1299
1332
|
throw new Error('mapToCurveSimpleSWU: invalid opts');
|
package/src/bls12-381.ts
CHANGED
|
@@ -19,61 +19,72 @@ import { AffinePoint, mapToCurveSimpleSWU, ProjPointType } from './abstract/weie
|
|
|
19
19
|
import { tower12, psiFrobenius } from './abstract/tower.js';
|
|
20
20
|
import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
bls12-381 is pairing-friendly Barreto-Lynn-Scott elliptic curve construction allowing to:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
### Summary
|
|
29
|
-
1. BLS Relies on Bilinear Pairing (expensive)
|
|
30
|
-
2. Private Keys: 32 bytes
|
|
31
|
-
3. Public Keys: 48 bytes: 381 bit affine x coordinate, encoded into 48 big-endian bytes.
|
|
32
|
-
4. Signatures: 96 bytes: two 381 bit integers (affine x coordinate), encoded into two 48 big-endian byte arrays.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- `
|
|
41
|
-
- `
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
[cfrg-
|
|
52
|
-
[
|
|
53
|
-
|
|
22
|
+
/**
|
|
23
|
+
* bls12-381 is pairing-friendly Barreto-Lynn-Scott elliptic curve construction allowing to:
|
|
24
|
+
* * Construct zk-SNARKs at the ~120-bit security
|
|
25
|
+
* * Efficiently verify N aggregate signatures with 1 pairing and N ec additions:
|
|
26
|
+
* the Boneh-Lynn-Shacham signature scheme is orders of magnitude more efficient than Schnorr
|
|
27
|
+
*
|
|
28
|
+
* ### Summary
|
|
29
|
+
* 1. BLS Relies on Bilinear Pairing (expensive)
|
|
30
|
+
* 2. Private Keys: 32 bytes
|
|
31
|
+
* 3. Public Keys: 48 bytes: 381 bit affine x coordinate, encoded into 48 big-endian bytes.
|
|
32
|
+
* 4. Signatures: 96 bytes: two 381 bit integers (affine x coordinate), encoded into two 48 big-endian byte arrays.
|
|
33
|
+
* - The signature is a point on the G2 subgroup, which is defined over a finite field
|
|
34
|
+
* with elements twice as big as the G1 curve (G2 is over Fp2 rather than Fp. Fp2 is analogous to the
|
|
35
|
+
* complex numbers).
|
|
36
|
+
* - We also support reversed 96-byte pubkeys & 48-byte short signatures.
|
|
37
|
+
* 5. The 12 stands for the Embedding degree.
|
|
38
|
+
*
|
|
39
|
+
* ### Formulas
|
|
40
|
+
* - `P = pk x G` - public keys
|
|
41
|
+
* - `S = pk x H(m)` - signing
|
|
42
|
+
* - `e(P, H(m)) == e(G, S)` - verification using pairings
|
|
43
|
+
* - `e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))` - signature aggregation
|
|
44
|
+
*
|
|
45
|
+
* ### Compatibility and notes
|
|
46
|
+
* 1. It is compatible with Algorand, Chia, Dfinity, Ethereum, Filecoin, ZEC.
|
|
47
|
+
* Filecoin uses little endian byte arrays for private keys - make sure to reverse byte order.
|
|
48
|
+
* 2. Some projects use G2 for public keys and G1 for signatures. It's called "short signature".
|
|
49
|
+
* 3. Curve security level is about 120 bits as per [Barbulescu-Duquesne 2017](https://hal.science/hal-01534101/file/main.pdf)
|
|
50
|
+
* 4. Compatible with specs:
|
|
51
|
+
* [cfrg-pairing-friendly-curves-11](https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-11),
|
|
52
|
+
* [cfrg-bls-signature-05](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-05),
|
|
53
|
+
* [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380).
|
|
54
|
+
*
|
|
55
|
+
* ### Params
|
|
56
|
+
* To verify curve parameters, see
|
|
57
|
+
* [pairing-friendly-curves spec](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11).
|
|
58
|
+
* Basic math is done over finite fields over p.
|
|
59
|
+
* More complicated math is done over polynominal extension fields.
|
|
60
|
+
* To simplify calculations in Fp12, we construct extension tower:
|
|
61
|
+
* - Fp₁₂ = Fp₆² => Fp₂³
|
|
62
|
+
* - Fp(u) / (u² - β) where β = -1
|
|
63
|
+
* - Fp₂(v) / (v³ - ξ) where ξ = u + 1
|
|
64
|
+
* - Fp₆(w) / (w² - γ) where γ = v
|
|
65
|
+
* Here goes constants && point encoding format
|
|
66
|
+
*
|
|
67
|
+
* Embedding degree (k): 12
|
|
68
|
+
* Seed (X): -15132376222941642752
|
|
69
|
+
* Fr: (x⁴-x²+1)
|
|
70
|
+
* Fp: ((x-1)² ⋅ r(x)/3+x)
|
|
71
|
+
* (E/Fp): Y²=X³+4
|
|
72
|
+
* (Eₜ/Fp²): Y² = X³+4(u+1) (M-type twist)
|
|
73
|
+
* Ate loop size: X
|
|
74
|
+
*
|
|
75
|
+
* ### Towers
|
|
76
|
+
* - Fp²[u] = Fp/u²+1
|
|
77
|
+
* - Fp⁶[v] = Fp²/v³-1-u
|
|
78
|
+
* - Fp¹²[w] = Fp⁶/w²-v
|
|
79
|
+
*
|
|
80
|
+
* @todo construct bls & bn fp/fr from seed.
|
|
81
|
+
* @module
|
|
82
|
+
*/
|
|
54
83
|
|
|
55
84
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
56
85
|
// prettier-ignore
|
|
57
86
|
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
|
|
58
87
|
|
|
59
|
-
/*
|
|
60
|
-
Embedding degree (k): 12
|
|
61
|
-
Seed (X): -15132376222941642752
|
|
62
|
-
Fr: (x⁴-x²+1)
|
|
63
|
-
Fp: ((x-1)² ⋅ r(x)/3+x)
|
|
64
|
-
(E/Fp): Y²=X³+4
|
|
65
|
-
(Eₜ/Fp²): Y² = X³+4(u+1) (M-type twist)
|
|
66
|
-
Ate loop size: X
|
|
67
|
-
|
|
68
|
-
Towers:
|
|
69
|
-
- Fp²[u] = Fp/u²+1
|
|
70
|
-
- Fp⁶[v] = Fp²/v³-1-u
|
|
71
|
-
- Fp¹²[w] = Fp⁶/w²-v
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
TODO: BLS & BN Fp/Fr can be constructed from seed.
|
|
75
|
-
*/
|
|
76
|
-
|
|
77
88
|
// The BLS parameter x (seed) for BLS12-381. NOTE: it is negative!
|
|
78
89
|
const BLS_X = BigInt('0xd201000000010000');
|
|
79
90
|
const BLS_X_LEN = bitLen(BLS_X);
|
|
@@ -418,16 +429,17 @@ function signatureG2ToRawBytes(point: ProjPointType<Fp2>) {
|
|
|
418
429
|
);
|
|
419
430
|
}
|
|
420
431
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
432
|
+
/**
|
|
433
|
+
* bls12-381 pairing-friendly curve.
|
|
434
|
+
* @example
|
|
435
|
+
* import { bls12_381 as bls } from '@noble/curves/bls12-381';
|
|
436
|
+
* // G1 keys, G2 signatures
|
|
437
|
+
* const privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';
|
|
438
|
+
* const message = '64726e3da8';
|
|
439
|
+
* const publicKey = bls.getPublicKey(privateKey);
|
|
440
|
+
* const signature = bls.sign(message, privateKey);
|
|
441
|
+
* const isValid = bls.verify(signature, message, publicKey);
|
|
442
|
+
*/
|
|
431
443
|
export const bls12_381: CurveFn = bls({
|
|
432
444
|
// Fields
|
|
433
445
|
fields: {
|
package/src/bn254.ts
CHANGED
|
@@ -1,24 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { getHash } from './_shortw_utils.js';
|
|
4
|
-
import { weierstrass } from './abstract/weierstrass.js';
|
|
5
|
-
import { randomBytes } from '@noble/hashes/utils';
|
|
6
|
-
import { bls, CurveFn, PostPrecomputeFn, PostPrecomputePointAddFn } from './abstract/bls.js';
|
|
7
|
-
import { Field } from './abstract/modular.js';
|
|
8
|
-
import { bitGet, bitLen, notImplemented } from './abstract/utils.js';
|
|
9
|
-
import { tower12, psiFrobenius } from './abstract/tower.js';
|
|
10
|
-
// Types
|
|
11
|
-
import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
|
|
12
|
-
// prettier-ignore
|
|
13
|
-
const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
|
14
|
-
// prettier-ignore
|
|
15
|
-
const _6n = BigInt(6);
|
|
1
|
+
/**
|
|
2
|
+
* bn254, previously known as alt_bn_128, when it had 128-bit security.
|
|
16
3
|
|
|
17
|
-
/*
|
|
18
|
-
bn254, previously known as alt_bn_128, when it had 128-bit security.
|
|
19
4
|
Barbulescu-Duquesne 2017 shown it's weaker: just about 100 bits,
|
|
20
5
|
so the naming has been adjusted to its prime bit count:
|
|
21
|
-
https://hal.science/hal-01534101/file/main.pdf
|
|
6
|
+
https://hal.science/hal-01534101/file/main.pdf.
|
|
7
|
+
Compatible with EIP-196 and EIP-197.
|
|
22
8
|
|
|
23
9
|
There are huge compatibility issues in the ecosystem:
|
|
24
10
|
|
|
@@ -42,9 +28,8 @@ because it at least has specs:
|
|
|
42
28
|
- https://github.com/ethereum/py_pairing
|
|
43
29
|
- https://github.com/ethereum/execution-specs/blob/master/src/ethereum/crypto/alt_bn128.py
|
|
44
30
|
- Points are encoded differently in different implementations
|
|
45
|
-
*/
|
|
46
31
|
|
|
47
|
-
|
|
32
|
+
### Params
|
|
48
33
|
Seed (X): 4965661367192848881
|
|
49
34
|
Fr: (36x⁴+36x³+18x²+6x+1)
|
|
50
35
|
Fp: (36x⁴+36x³+24x²+6x+1)
|
|
@@ -52,11 +37,34 @@ Fp: (36x⁴+36x³+24x²+6x+1)
|
|
|
52
37
|
(Et / Fp²): Y² = X³+3/(u+9) (D-type twist)
|
|
53
38
|
Ate loop size: 6x+2
|
|
54
39
|
|
|
55
|
-
Towers
|
|
40
|
+
### Towers
|
|
56
41
|
- Fp²[u] = Fp/u²+1
|
|
57
42
|
- Fp⁶[v] = Fp²/v³-9-u
|
|
58
43
|
- Fp¹²[w] = Fp⁶/w²-v
|
|
59
|
-
|
|
44
|
+
|
|
45
|
+
* @module
|
|
46
|
+
*/
|
|
47
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
48
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
49
|
+
import { getHash } from './_shortw_utils.js';
|
|
50
|
+
import { CurveFn, weierstrass } from './abstract/weierstrass.js';
|
|
51
|
+
import { randomBytes } from '@noble/hashes/utils';
|
|
52
|
+
import {
|
|
53
|
+
bls,
|
|
54
|
+
CurveFn as BLSCurveFn,
|
|
55
|
+
PostPrecomputeFn,
|
|
56
|
+
PostPrecomputePointAddFn,
|
|
57
|
+
} from './abstract/bls.js';
|
|
58
|
+
import { Field } from './abstract/modular.js';
|
|
59
|
+
import { bitGet, bitLen, notImplemented } from './abstract/utils.js';
|
|
60
|
+
import { tower12, psiFrobenius } from './abstract/tower.js';
|
|
61
|
+
// Types
|
|
62
|
+
import type { Fp, Fp2, Fp6, Fp12 } from './abstract/tower.js';
|
|
63
|
+
// prettier-ignore
|
|
64
|
+
const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
|
65
|
+
// prettier-ignore
|
|
66
|
+
const _6n = BigInt(6);
|
|
67
|
+
|
|
60
68
|
const BN_X = BigInt('4965661367192848881');
|
|
61
69
|
const BN_X_LEN = bitLen(BN_X);
|
|
62
70
|
const SIX_X_SQUARED = _6n * BN_X ** _2n;
|
|
@@ -166,7 +174,7 @@ export const _postPrecompute: PostPrecomputeFn = (
|
|
|
166
174
|
* bn254 (a.k.a. alt_bn128) pairing-friendly curve.
|
|
167
175
|
* Contains G1 / G2 operations and pairings.
|
|
168
176
|
*/
|
|
169
|
-
export const bn254:
|
|
177
|
+
export const bn254: BLSCurveFn = bls({
|
|
170
178
|
// Fields
|
|
171
179
|
fields: { Fp, Fp2, Fp6, Fp12, Fr },
|
|
172
180
|
G1: {
|
|
@@ -234,7 +242,7 @@ export const bn254: CurveFn = bls({
|
|
|
234
242
|
* This is very rare and probably not used anywhere.
|
|
235
243
|
* Instead, you should use G1 / G2, defined above.
|
|
236
244
|
*/
|
|
237
|
-
export const bn254_weierstrass = weierstrass({
|
|
245
|
+
export const bn254_weierstrass: CurveFn = weierstrass({
|
|
238
246
|
a: BigInt(0),
|
|
239
247
|
b: BigInt(3),
|
|
240
248
|
Fp,
|