@noble/curves 2.0.1 → 2.2.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 +214 -122
- package/abstract/bls.d.ts +299 -16
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +82 -22
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +274 -27
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +177 -23
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +166 -30
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +221 -86
- package/abstract/edwards.js.map +1 -1
- package/abstract/fft.d.ts +322 -10
- package/abstract/fft.d.ts.map +1 -1
- package/abstract/fft.js +154 -12
- package/abstract/fft.js.map +1 -1
- package/abstract/frost.d.ts +293 -0
- package/abstract/frost.d.ts.map +1 -0
- package/abstract/frost.js +704 -0
- package/abstract/frost.js.map +1 -0
- package/abstract/hash-to-curve.d.ts +173 -24
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +170 -31
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +429 -37
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +414 -119
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +83 -12
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +32 -7
- package/abstract/montgomery.js.map +1 -1
- package/abstract/oprf.d.ts +164 -91
- package/abstract/oprf.d.ts.map +1 -1
- package/abstract/oprf.js +88 -29
- package/abstract/oprf.js.map +1 -1
- package/abstract/poseidon.d.ts +138 -7
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +178 -15
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +122 -3
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +323 -139
- package/abstract/tower.js.map +1 -1
- package/abstract/weierstrass.d.ts +339 -76
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +395 -205
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +16 -2
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +199 -209
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +11 -2
- package/bn254.d.ts.map +1 -1
- package/bn254.js +93 -38
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +125 -14
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +202 -40
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +108 -14
- package/ed448.d.ts.map +1 -1
- package/ed448.js +194 -42
- package/ed448.js.map +1 -1
- package/index.js +7 -1
- package/index.js.map +1 -1
- package/misc.d.ts +106 -7
- package/misc.d.ts.map +1 -1
- package/misc.js +141 -32
- package/misc.js.map +1 -1
- package/nist.d.ts +112 -11
- package/nist.d.ts.map +1 -1
- package/nist.js +139 -17
- package/nist.js.map +1 -1
- package/package.json +11 -6
- package/secp256k1.d.ts +92 -15
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +211 -28
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +350 -67
- package/src/abstract/curve.ts +327 -44
- package/src/abstract/edwards.ts +367 -143
- package/src/abstract/fft.ts +369 -36
- package/src/abstract/frost.ts +1092 -0
- package/src/abstract/hash-to-curve.ts +255 -56
- package/src/abstract/modular.ts +591 -144
- package/src/abstract/montgomery.ts +114 -30
- package/src/abstract/oprf.ts +383 -194
- package/src/abstract/poseidon.ts +235 -35
- package/src/abstract/tower.ts +428 -159
- package/src/abstract/weierstrass.ts +710 -312
- package/src/bls12-381.ts +239 -236
- package/src/bn254.ts +107 -46
- package/src/ed25519.ts +227 -55
- package/src/ed448.ts +227 -57
- package/src/index.ts +7 -1
- package/src/misc.ts +154 -35
- package/src/nist.ts +143 -20
- package/src/secp256k1.ts +284 -41
- package/src/utils.ts +583 -81
- package/src/webcrypto.ts +302 -73
- package/utils.d.ts +457 -24
- package/utils.d.ts.map +1 -1
- package/utils.js +410 -53
- package/utils.js.map +1 -1
- package/webcrypto.d.ts +167 -25
- package/webcrypto.d.ts.map +1 -1
- package/webcrypto.js +165 -58
- package/webcrypto.js.map +1 -1
package/src/abstract/bls.ts
CHANGED
|
@@ -15,13 +15,12 @@
|
|
|
15
15
|
* @module
|
|
16
16
|
**/
|
|
17
17
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
18
|
-
import { abytes,
|
|
19
|
-
import {
|
|
18
|
+
import { abytes, notImplemented, randomBytes, type TArg, type TRet } from '../utils.ts';
|
|
19
|
+
import { type CurveLengths } from './curve.ts';
|
|
20
20
|
import {
|
|
21
21
|
createHasher,
|
|
22
22
|
type H2CDSTOpts,
|
|
23
23
|
type H2CHasher,
|
|
24
|
-
type H2CHashOpts,
|
|
25
24
|
type H2COpts,
|
|
26
25
|
type MapToCurve,
|
|
27
26
|
} from './hash-to-curve.ts';
|
|
@@ -34,30 +33,99 @@ type Fp = bigint; // Can be different field?
|
|
|
34
33
|
// prettier-ignore
|
|
35
34
|
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
|
36
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Twist convention used by the pairing formulas for a concrete curve family.
|
|
38
|
+
* BLS12-381 uses a multiplicative twist, while BN254 uses a divisive one.
|
|
39
|
+
*/
|
|
37
40
|
export type BlsTwistType = 'multiplicative' | 'divisive';
|
|
38
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Codec exposed as `curve.shortSignatures.Signature`.
|
|
44
|
+
* Use it to parse or serialize G1 signatures in short-signature mode.
|
|
45
|
+
* In this mode, public keys live in G2.
|
|
46
|
+
*/
|
|
39
47
|
export type BlsShortSignatureCoder<Fp> = {
|
|
40
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Parse a compressed signature from raw bytes.
|
|
50
|
+
* @param bytes - Compressed signature bytes.
|
|
51
|
+
* @returns Parsed signature point.
|
|
52
|
+
*/
|
|
53
|
+
fromBytes(bytes: TArg<Uint8Array>): WeierstrassPoint<Fp>;
|
|
54
|
+
/**
|
|
55
|
+
* Parse a compressed signature from a hex string.
|
|
56
|
+
* @param hex - Compressed signature hex string.
|
|
57
|
+
* @returns Parsed signature point.
|
|
58
|
+
*/
|
|
41
59
|
fromHex(hex: string): WeierstrassPoint<Fp>;
|
|
42
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Encode a signature point into compressed bytes.
|
|
62
|
+
* @param point - Signature point.
|
|
63
|
+
* @returns Compressed signature bytes.
|
|
64
|
+
*/
|
|
65
|
+
toBytes(point: WeierstrassPoint<Fp>): TRet<Uint8Array>;
|
|
66
|
+
/**
|
|
67
|
+
* Encode a signature point into a hex string.
|
|
68
|
+
* @param point - Signature point.
|
|
69
|
+
* @returns Compressed signature hex.
|
|
70
|
+
*/
|
|
43
71
|
toHex(point: WeierstrassPoint<Fp>): string;
|
|
44
72
|
};
|
|
45
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Codec exposed as `curve.longSignatures.Signature`.
|
|
76
|
+
* Use it to parse or serialize G2 signatures in long-signature mode.
|
|
77
|
+
* In this mode, public keys live in G1.
|
|
78
|
+
*/
|
|
46
79
|
export type BlsLongSignatureCoder<Fp> = {
|
|
47
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Parse a compressed signature from raw bytes.
|
|
82
|
+
* @param bytes - Compressed signature bytes.
|
|
83
|
+
* @returns Parsed signature point.
|
|
84
|
+
*/
|
|
85
|
+
fromBytes(bytes: TArg<Uint8Array>): WeierstrassPoint<Fp>;
|
|
86
|
+
/**
|
|
87
|
+
* Parse a compressed signature from a hex string.
|
|
88
|
+
* @param hex - Compressed signature hex string.
|
|
89
|
+
* @returns Parsed signature point.
|
|
90
|
+
*/
|
|
48
91
|
fromHex(hex: string): WeierstrassPoint<Fp>;
|
|
49
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Encode a signature point into compressed bytes.
|
|
94
|
+
* @param point - Signature point.
|
|
95
|
+
* @returns Compressed signature bytes.
|
|
96
|
+
*/
|
|
97
|
+
toBytes(point: WeierstrassPoint<Fp>): TRet<Uint8Array>;
|
|
98
|
+
/**
|
|
99
|
+
* Encode a signature point into a hex string.
|
|
100
|
+
* @param point - Signature point.
|
|
101
|
+
* @returns Compressed signature hex.
|
|
102
|
+
*/
|
|
50
103
|
toHex(point: WeierstrassPoint<Fp>): string;
|
|
51
104
|
};
|
|
52
105
|
|
|
106
|
+
/** Tower fields needed by pairing code, hash-to-curve, and subgroup arithmetic. */
|
|
53
107
|
export type BlsFields = {
|
|
108
|
+
/** Base field of G1 coordinates. */
|
|
54
109
|
Fp: IField<Fp>;
|
|
110
|
+
/** Scalar field used for secret scalars and subgroup order arithmetic. */
|
|
55
111
|
Fr: IField<bigint>;
|
|
112
|
+
/** Quadratic extension field used by G2. */
|
|
56
113
|
Fp2: Fp2Bls;
|
|
114
|
+
/** Sextic extension field used inside pairing arithmetic. */
|
|
57
115
|
Fp6: Fp6Bls;
|
|
116
|
+
/** Degree-12 extension field that contains the GT target group. */
|
|
58
117
|
Fp12: Fp12Bls;
|
|
59
118
|
};
|
|
60
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Callback used by pairing post-processing hooks to add one more G2 point to the Miller-loop state.
|
|
122
|
+
* @param Rx - Current projective X coordinate.
|
|
123
|
+
* @param Ry - Current projective Y coordinate.
|
|
124
|
+
* @param Rz - Current projective Z coordinate.
|
|
125
|
+
* @param Qx - G2 affine x coordinate.
|
|
126
|
+
* @param Qy - G2 affine y coordinate.
|
|
127
|
+
* @returns Updated projective accumulator coordinates.
|
|
128
|
+
*/
|
|
61
129
|
export type BlsPostPrecomputePointAddFn = (
|
|
62
130
|
Rx: Fp2,
|
|
63
131
|
Ry: Fp2,
|
|
@@ -65,6 +133,15 @@ export type BlsPostPrecomputePointAddFn = (
|
|
|
65
133
|
Qx: Fp2,
|
|
66
134
|
Qy: Fp2
|
|
67
135
|
) => { Rx: Fp2; Ry: Fp2; Rz: Fp2 };
|
|
136
|
+
/**
|
|
137
|
+
* Hook for curve-specific pairing cleanup after the Miller loop precomputes are built.
|
|
138
|
+
* @param Rx - Current projective X coordinate.
|
|
139
|
+
* @param Ry - Current projective Y coordinate.
|
|
140
|
+
* @param Rz - Current projective Z coordinate.
|
|
141
|
+
* @param Qx - G2 affine x coordinate.
|
|
142
|
+
* @param Qy - G2 affine y coordinate.
|
|
143
|
+
* @param pointAdd - Callback used to fold one more point into the accumulator.
|
|
144
|
+
*/
|
|
68
145
|
export type BlsPostPrecomputeFn = (
|
|
69
146
|
Rx: Fp2,
|
|
70
147
|
Ry: Fp2,
|
|
@@ -73,34 +150,97 @@ export type BlsPostPrecomputeFn = (
|
|
|
73
150
|
Qy: Fp2,
|
|
74
151
|
pointAdd: BlsPostPrecomputePointAddFn
|
|
75
152
|
) => void;
|
|
153
|
+
/** Low-level pairing helpers shared by BLS curve bundles. */
|
|
76
154
|
export type BlsPairing = {
|
|
155
|
+
/** Byte lengths for keys and signatures exposed by this pairing family. */
|
|
77
156
|
lengths: CurveLengths;
|
|
157
|
+
/** Scalar field used by the pairing and signing helpers. */
|
|
78
158
|
Fr: IField<bigint>;
|
|
159
|
+
/** Target field used for the GT result of pairings. */
|
|
79
160
|
Fp12: Fp12Bls;
|
|
161
|
+
/**
|
|
162
|
+
* Build Miller-loop precomputes for one G2 point.
|
|
163
|
+
* @param p - G2 point to precompute.
|
|
164
|
+
* @returns Pairing precompute table.
|
|
165
|
+
*/
|
|
80
166
|
calcPairingPrecomputes: (p: WeierstrassPoint<Fp2>) => Precompute;
|
|
167
|
+
/**
|
|
168
|
+
* Evaluate a batch of Miller loops from precomputed line coefficients.
|
|
169
|
+
* @param pairs - Precomputed Miller-loop inputs.
|
|
170
|
+
* @returns Accumulated GT value before or after final exponentiation.
|
|
171
|
+
*/
|
|
81
172
|
millerLoopBatch: (pairs: [Precompute, Fp, Fp][]) => Fp12;
|
|
173
|
+
/**
|
|
174
|
+
* Pair one G1 point with one G2 point.
|
|
175
|
+
* @param P - G1 point.
|
|
176
|
+
* @param Q - G2 point.
|
|
177
|
+
* @param withFinalExponent - Whether to apply the final exponentiation step.
|
|
178
|
+
* @returns GT pairing result.
|
|
179
|
+
* @throws If either point is the point at infinity. {@link Error}
|
|
180
|
+
*/
|
|
82
181
|
pairing: (P: WeierstrassPoint<Fp>, Q: WeierstrassPoint<Fp2>, withFinalExponent?: boolean) => Fp12;
|
|
182
|
+
/**
|
|
183
|
+
* Pair many G1/G2 pairs in one batch.
|
|
184
|
+
* @param pairs - Point pairs to accumulate.
|
|
185
|
+
* @param withFinalExponent - Whether to apply the final exponentiation step.
|
|
186
|
+
* @returns GT pairing result. Empty input returns the multiplicative identity in GT.
|
|
187
|
+
*/
|
|
83
188
|
pairingBatch: (
|
|
84
189
|
pairs: { g1: WeierstrassPoint<Fp>; g2: WeierstrassPoint<Fp2> }[],
|
|
85
190
|
withFinalExponent?: boolean
|
|
86
191
|
) => Fp12;
|
|
87
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Generate a random secret key for this pairing family.
|
|
194
|
+
* @param seed - Optional seed material.
|
|
195
|
+
* @returns Secret key bytes.
|
|
196
|
+
*/
|
|
197
|
+
randomSecretKey: (seed?: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
88
198
|
};
|
|
89
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Parameters that define the Miller-loop shape and twist handling
|
|
202
|
+
* for a concrete pairing family.
|
|
203
|
+
*/
|
|
90
204
|
export type BlsPairingParams = {
|
|
91
205
|
// MSB is always ignored and used as marker for length, otherwise leading zeros will be lost.
|
|
92
206
|
// Can be different from `X` (seed) param.
|
|
207
|
+
/** Signed loop parameter used by the Miller loop. */
|
|
93
208
|
ateLoopSize: bigint;
|
|
209
|
+
/** Whether the signed Miller-loop parameter is negative. */
|
|
94
210
|
xNegative: boolean;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
211
|
+
/**
|
|
212
|
+
* Twist convention used by the pairing formulas.
|
|
213
|
+
* BLS12-381 is multiplicative; BN254 is divisive.
|
|
214
|
+
*/
|
|
215
|
+
twistType: BlsTwistType;
|
|
216
|
+
/**
|
|
217
|
+
* Optional RNG override used by helper constructors.
|
|
218
|
+
* Receives the requested byte length and returns random bytes.
|
|
219
|
+
*/
|
|
220
|
+
randomBytes?: (len?: number) => TRet<Uint8Array>;
|
|
221
|
+
/**
|
|
222
|
+
* Optional hook for curve-specific untwisting after precomputation.
|
|
223
|
+
* Used by BN254 after the Miller loop.
|
|
224
|
+
*/
|
|
225
|
+
postPrecompute?: BlsPostPrecomputeFn;
|
|
98
226
|
};
|
|
227
|
+
/** Hash-to-curve settings shared by the G1 and G2 hashers inside a BLS curve bundle. */
|
|
99
228
|
export type BlsHasherParams = {
|
|
229
|
+
/**
|
|
230
|
+
* Optional map-to-curve override for G1.
|
|
231
|
+
* Receives the hash-to-field tuple and returns one affine G1 point.
|
|
232
|
+
*/
|
|
100
233
|
mapToG1?: MapToCurve<Fp>;
|
|
234
|
+
/**
|
|
235
|
+
* Optional map-to-curve override for G2.
|
|
236
|
+
* Receives the hash-to-field tuple and returns one affine G2 point.
|
|
237
|
+
*/
|
|
101
238
|
mapToG2?: MapToCurve<Fp2>;
|
|
239
|
+
/** Shared baseline hash-to-curve options. */
|
|
102
240
|
hasherOpts: H2COpts;
|
|
241
|
+
/** G1-specific hash-to-curve options merged on top of `hasherOpts`. */
|
|
103
242
|
hasherOptsG1: H2COpts;
|
|
243
|
+
/** G2-specific hash-to-curve options merged on top of `hasherOpts`. */
|
|
104
244
|
hasherOptsG2: H2COpts;
|
|
105
245
|
};
|
|
106
246
|
type PrecomputeSingle = [Fp2, Fp2, Fp2][];
|
|
@@ -112,12 +252,35 @@ type Precompute = PrecomputeSingle[];
|
|
|
112
252
|
* - G2 is a subgroup of ((x₁, x₂+i), (y₁, y₂+i)) E(Fq²) over y² = x³ + 4(1 + i) where i is √-1
|
|
113
253
|
*/
|
|
114
254
|
export interface BlsCurvePair {
|
|
255
|
+
/** Byte lengths for keys and signatures exposed by this curve family. */
|
|
115
256
|
lengths: CurveLengths;
|
|
257
|
+
/**
|
|
258
|
+
* Shared Miller-loop batch evaluator.
|
|
259
|
+
* @param pairs - Precomputed Miller-loop inputs.
|
|
260
|
+
* @returns Accumulated GT value.
|
|
261
|
+
*/
|
|
116
262
|
millerLoopBatch: BlsPairing['millerLoopBatch'];
|
|
263
|
+
/**
|
|
264
|
+
* Pair one G1 point with one G2 point.
|
|
265
|
+
* @param P - G1 point.
|
|
266
|
+
* @param Q - G2 point.
|
|
267
|
+
* @param withFinalExponent - Whether to apply the final exponentiation step.
|
|
268
|
+
* @returns GT pairing result.
|
|
269
|
+
* @throws If either point is the point at infinity. {@link Error}
|
|
270
|
+
*/
|
|
117
271
|
pairing: BlsPairing['pairing'];
|
|
272
|
+
/**
|
|
273
|
+
* Pair many G1/G2 pairs in one batch.
|
|
274
|
+
* @param pairs - Point pairs to accumulate.
|
|
275
|
+
* @param withFinalExponent - Whether to apply the final exponentiation step.
|
|
276
|
+
* @returns GT pairing result. Empty input returns the multiplicative identity in GT.
|
|
277
|
+
*/
|
|
118
278
|
pairingBatch: BlsPairing['pairingBatch'];
|
|
279
|
+
/** G1 point constructor for the base field subgroup. */
|
|
119
280
|
G1: { Point: WeierstrassPointCons<Fp> };
|
|
281
|
+
/** G2 point constructor for the twist subgroup. */
|
|
120
282
|
G2: { Point: WeierstrassPointCons<Fp2> };
|
|
283
|
+
/** Tower fields exposed by the pairing implementation. */
|
|
121
284
|
fields: {
|
|
122
285
|
Fp: IField<Fp>;
|
|
123
286
|
Fp2: Fp2Bls;
|
|
@@ -125,51 +288,112 @@ export interface BlsCurvePair {
|
|
|
125
288
|
Fp12: Fp12Bls;
|
|
126
289
|
Fr: IField<bigint>;
|
|
127
290
|
};
|
|
291
|
+
/** Utility helpers shared by hashers and signers. */
|
|
128
292
|
utils: {
|
|
129
|
-
randomSecretKey: (seed?: Uint8Array) => Uint8Array
|
|
293
|
+
randomSecretKey: (seed?: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
130
294
|
calcPairingPrecomputes: BlsPairing['calcPairingPrecomputes'];
|
|
131
295
|
};
|
|
296
|
+
/** Public pairing parameters exposed for introspection. */
|
|
132
297
|
params: {
|
|
133
298
|
ateLoopSize: bigint;
|
|
134
299
|
twistType: BlsTwistType;
|
|
135
300
|
};
|
|
136
301
|
}
|
|
137
302
|
|
|
303
|
+
/** BLS curve bundle extended with hash-to-curve helpers for G1 and G2. */
|
|
138
304
|
export interface BlsCurvePairWithHashers extends BlsCurvePair {
|
|
305
|
+
/** G1 hasher bundle with RFC 9380 helpers. */
|
|
139
306
|
G1: H2CHasher<WeierstrassPointCons<Fp>>;
|
|
307
|
+
/** G2 hasher bundle with RFC 9380 helpers. */
|
|
140
308
|
G2: H2CHasher<WeierstrassPointCons<Fp2>>;
|
|
141
309
|
}
|
|
142
310
|
|
|
311
|
+
/** BLS curve bundle extended with both hashers and signature helpers. */
|
|
143
312
|
export interface BlsCurvePairWithSignatures extends BlsCurvePairWithHashers {
|
|
313
|
+
/** Long-signature mode: G1 public keys and G2 signatures. */
|
|
144
314
|
longSignatures: BlsSigs<bigint, Fp2>;
|
|
315
|
+
/** Short-signature mode: G2 public keys and G1 signatures. */
|
|
145
316
|
shortSignatures: BlsSigs<Fp2, bigint>;
|
|
146
317
|
}
|
|
147
318
|
|
|
148
|
-
type BLSInput = Uint8Array
|
|
319
|
+
type BLSInput = TArg<Uint8Array>;
|
|
320
|
+
/** BLS signer helpers for one signature mode. */
|
|
149
321
|
export interface BlsSigs<P, S> {
|
|
322
|
+
/** Byte lengths for secret keys, public keys, and signatures. */
|
|
150
323
|
lengths: CurveLengths;
|
|
151
|
-
|
|
152
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Generate a secret/public key pair for this signature mode.
|
|
326
|
+
* @param seed - Optional seed material.
|
|
327
|
+
* @returns Secret and public key pair.
|
|
328
|
+
*/
|
|
329
|
+
keygen(seed?: TArg<Uint8Array>): {
|
|
330
|
+
secretKey: TRet<Uint8Array>;
|
|
153
331
|
publicKey: WeierstrassPoint<P>;
|
|
154
332
|
};
|
|
155
|
-
|
|
156
|
-
|
|
333
|
+
/**
|
|
334
|
+
* Derive the public key from a secret key.
|
|
335
|
+
* @param secretKey - Secret key bytes.
|
|
336
|
+
* @returns Public-key point.
|
|
337
|
+
*/
|
|
338
|
+
getPublicKey(secretKey: TArg<Uint8Array>): WeierstrassPoint<P>;
|
|
339
|
+
/**
|
|
340
|
+
* Sign a message already hashed onto the signature subgroup.
|
|
341
|
+
* @param hashedMessage - Message mapped to the signature subgroup.
|
|
342
|
+
* @param secretKey - Secret key bytes.
|
|
343
|
+
* @returns Signature point.
|
|
344
|
+
*/
|
|
345
|
+
sign(hashedMessage: WeierstrassPoint<S>, secretKey: TArg<Uint8Array>): WeierstrassPoint<S>;
|
|
346
|
+
/**
|
|
347
|
+
* Verify one signature against one public key and hashed message.
|
|
348
|
+
* @param signature - Signature point or encoded signature.
|
|
349
|
+
* @param message - Hashed message point.
|
|
350
|
+
* @param publicKey - Public-key point or encoded key.
|
|
351
|
+
* @returns Whether the signature is valid.
|
|
352
|
+
*/
|
|
157
353
|
verify(
|
|
158
354
|
signature: WeierstrassPoint<S> | BLSInput,
|
|
159
355
|
message: WeierstrassPoint<S>,
|
|
160
356
|
publicKey: WeierstrassPoint<P> | BLSInput
|
|
161
357
|
): boolean;
|
|
358
|
+
/**
|
|
359
|
+
* Verify one aggregated signature against many `(message, publicKey)` pairs.
|
|
360
|
+
* @param signature - Aggregated signature.
|
|
361
|
+
* @param items - Message/public-key pairs.
|
|
362
|
+
* @returns Whether the aggregated signature is valid. Same-message aggregate verification still
|
|
363
|
+
* requires proof of possession or another rogue-key defense from the caller.
|
|
364
|
+
*/
|
|
162
365
|
verifyBatch: (
|
|
163
366
|
signature: WeierstrassPoint<S> | BLSInput,
|
|
164
367
|
items: { message: WeierstrassPoint<S>; publicKey: WeierstrassPoint<P> | BLSInput }[]
|
|
165
368
|
) => boolean;
|
|
369
|
+
/**
|
|
370
|
+
* Add many public keys into one aggregate point.
|
|
371
|
+
* @param publicKeys - Public keys to aggregate.
|
|
372
|
+
* @returns Aggregated public-key point. This is raw point addition and does not add proof of
|
|
373
|
+
* possession or rogue-key protection on its own.
|
|
374
|
+
*/
|
|
166
375
|
aggregatePublicKeys(publicKeys: (WeierstrassPoint<P> | BLSInput)[]): WeierstrassPoint<P>;
|
|
376
|
+
/**
|
|
377
|
+
* Add many signatures into one aggregate point.
|
|
378
|
+
* @param signatures - Signatures to aggregate.
|
|
379
|
+
* @returns Aggregated signature point. This is raw point addition and does not change the proof
|
|
380
|
+
* of possession requirements of the aggregate-verification scheme.
|
|
381
|
+
*/
|
|
167
382
|
aggregateSignatures(signatures: (WeierstrassPoint<S> | BLSInput)[]): WeierstrassPoint<S>;
|
|
168
|
-
|
|
383
|
+
/**
|
|
384
|
+
* Hash an arbitrary message onto the signature subgroup.
|
|
385
|
+
* @param message - Message bytes.
|
|
386
|
+
* @param DST - Optional domain separation tag.
|
|
387
|
+
* @returns Curve point on the signature subgroup.
|
|
388
|
+
*/
|
|
389
|
+
hash(message: TArg<Uint8Array>, DST?: TArg<string | Uint8Array>): WeierstrassPoint<S>;
|
|
390
|
+
/** Signature codec for this mode. */
|
|
169
391
|
Signature: BlsLongSignatureCoder<S>;
|
|
170
392
|
}
|
|
171
393
|
|
|
172
|
-
//
|
|
394
|
+
// Signed non-adjacent decomposition of the spec-defined Miller-loop parameter.
|
|
395
|
+
// BN254 benefits most because `6x+2` has multiple adjacent `11` runs, but BLS12-381's
|
|
396
|
+
// stored `|x|` still starts with `11`, so the Miller loop must also handle one `-1` digit there.
|
|
173
397
|
function NAfDecomposition(a: bigint) {
|
|
174
398
|
const res = [];
|
|
175
399
|
// a>1 because of marker bit
|
|
@@ -182,17 +406,19 @@ function NAfDecomposition(a: bigint) {
|
|
|
182
406
|
}
|
|
183
407
|
return res;
|
|
184
408
|
}
|
|
185
|
-
|
|
186
409
|
function aNonEmpty(arr: any[]) {
|
|
410
|
+
// Aggregate helpers use this to reject empty variable-length inputs consistently.
|
|
411
|
+
// Without the guard, each caller would fall through into a different empty-input / identity
|
|
412
|
+
// case and hide missing inputs behind outputs that still look structurally valid.
|
|
187
413
|
if (!Array.isArray(arr) || arr.length === 0) throw new Error('expected non-empty array');
|
|
188
414
|
}
|
|
189
415
|
|
|
190
416
|
// This should be enough for bn254, no need to export full stuff?
|
|
191
417
|
function createBlsPairing(
|
|
192
|
-
fields: BlsFields
|
|
418
|
+
fields: TArg<BlsFields>,
|
|
193
419
|
G1: WeierstrassPointCons<Fp>,
|
|
194
420
|
G2: WeierstrassPointCons<Fp2>,
|
|
195
|
-
params: BlsPairingParams
|
|
421
|
+
params: TArg<BlsPairingParams>
|
|
196
422
|
): BlsPairing {
|
|
197
423
|
const { Fr, Fp2, Fp12 } = fields;
|
|
198
424
|
const { twistType, ateLoopSize, xNegative, postPrecompute } = params;
|
|
@@ -224,7 +450,8 @@ function createBlsPairing(
|
|
|
224
450
|
ell.push([c0, c1, c2]);
|
|
225
451
|
|
|
226
452
|
Rx = Fp2.mul(Fp2.mul(Fp2.mul(Fp2.sub(t0, t3), Rx), Ry), Fp2div2); // ((T0 - T3) * Rx * Ry) / 2
|
|
227
|
-
|
|
453
|
+
// ((T0 + T3) / 2)² - 3 * T2²
|
|
454
|
+
Ry = Fp2.sub(Fp2.sqr(Fp2.mul(Fp2.add(t0, t3), Fp2div2)), Fp2.mul(Fp2.sqr(t2), _3n));
|
|
228
455
|
Rz = Fp2.mul(t0, t4); // T0 * T4
|
|
229
456
|
return { Rx, Ry, Rz };
|
|
230
457
|
}
|
|
@@ -241,7 +468,8 @@ function createBlsPairing(
|
|
|
241
468
|
const t2 = Fp2.sqr(t1); // T1²
|
|
242
469
|
const t3 = Fp2.mul(t2, t1); // T2 * T1
|
|
243
470
|
const t4 = Fp2.mul(t2, Rx); // T2 * Rx
|
|
244
|
-
|
|
471
|
+
// T3 - 2 * T4 + T0² * Rz
|
|
472
|
+
const t5 = Fp2.add(Fp2.sub(t3, Fp2.mul(t4, _2n)), Fp2.mul(Fp2.sqr(t0), Rz));
|
|
245
473
|
Rx = Fp2.mul(t1, t5); // T1 * T5
|
|
246
474
|
Ry = Fp2.sub(Fp2.mul(Fp2.sub(t4, t5), t0), Fp2.mul(t3, Ry)); // (T4 - T5) * T0 - T3 * Ry
|
|
247
475
|
Rz = Fp2.mul(Rz, t3); // Rz * T3
|
|
@@ -254,7 +482,7 @@ function createBlsPairing(
|
|
|
254
482
|
// add + double in windowed precomputes here, otherwise it would be single op (since X is static)
|
|
255
483
|
const ATE_NAF = NAfDecomposition(ateLoopSize);
|
|
256
484
|
|
|
257
|
-
const calcPairingPrecomputes =
|
|
485
|
+
const calcPairingPrecomputes = (point: G2) => {
|
|
258
486
|
const p = point;
|
|
259
487
|
const { x, y } = p.toAffine();
|
|
260
488
|
// prettier-ignore
|
|
@@ -273,7 +501,7 @@ function createBlsPairing(
|
|
|
273
501
|
postPrecompute(Rx, Ry, Rz, Qx, Qy, pointAdd.bind(null, last));
|
|
274
502
|
}
|
|
275
503
|
return ell;
|
|
276
|
-
}
|
|
504
|
+
};
|
|
277
505
|
|
|
278
506
|
// Main pairing logic is here. Computes product of miller loops + final exponentiate
|
|
279
507
|
// Applies calculated precomputes
|
|
@@ -298,16 +526,11 @@ function createBlsPairing(
|
|
|
298
526
|
// This up to x2 faster than just `map(({g1, g2})=>pairing({g1,g2}))`
|
|
299
527
|
function pairingBatch(pairs: PairingInput[], withFinalExponent: boolean = true) {
|
|
300
528
|
const res: MillerInput = [];
|
|
301
|
-
// Cache precomputed toAffine for all points
|
|
302
|
-
normalizeZ(
|
|
303
|
-
G1,
|
|
304
|
-
pairs.map(({ g1 }) => g1)
|
|
305
|
-
);
|
|
306
|
-
normalizeZ(
|
|
307
|
-
G2,
|
|
308
|
-
pairs.map(({ g2 }) => g2)
|
|
309
|
-
);
|
|
310
529
|
for (const { g1, g2 } of pairs) {
|
|
530
|
+
// Mathematically, a zero pairing term contributes GT.ONE. We still reject it here because
|
|
531
|
+
// this API mainly backs BLS verification, where ZERO inputs usually mean broken hash /
|
|
532
|
+
// wiring. Silently skipping them would turn those failures into a neutral pairing product.
|
|
533
|
+
// Callers that want the algebraic neutral-element behavior can filter ZERO terms first.
|
|
311
534
|
if (g1.is0() || g2.is0()) throw new Error('pairing is not available for ZERO point');
|
|
312
535
|
// This uses toAffine inside
|
|
313
536
|
g1.assertValidity();
|
|
@@ -324,11 +547,15 @@ function createBlsPairing(
|
|
|
324
547
|
const lengths = {
|
|
325
548
|
seed: getMinHashLength(Fr.ORDER),
|
|
326
549
|
};
|
|
327
|
-
const rand = params.randomBytes
|
|
328
|
-
|
|
550
|
+
const rand = params.randomBytes === undefined ? randomBytes : params.randomBytes;
|
|
551
|
+
// Seeded calls deterministically reduce exactly `lengths.seed` bytes into `1..Fr.ORDER-1`;
|
|
552
|
+
// omitting `seed` just fills that input buffer from the configured RNG first.
|
|
553
|
+
const randomSecretKey = (seed?: TArg<Uint8Array>): TRet<Uint8Array> => {
|
|
554
|
+
seed = seed === undefined ? rand(lengths.seed) : seed;
|
|
329
555
|
abytes(seed, lengths.seed, 'seed');
|
|
330
|
-
return mapHashToField(seed, Fr.ORDER)
|
|
556
|
+
return mapHashToField(seed, Fr.ORDER) as TRet<Uint8Array>;
|
|
331
557
|
};
|
|
558
|
+
Object.freeze(lengths);
|
|
332
559
|
return {
|
|
333
560
|
lengths,
|
|
334
561
|
Fr,
|
|
@@ -346,7 +573,7 @@ function createBlsSig<P, S>(
|
|
|
346
573
|
PubPoint: WeierstrassPointCons<P>,
|
|
347
574
|
SigPoint: WeierstrassPointCons<S>,
|
|
348
575
|
isSigG1: boolean,
|
|
349
|
-
hashToSigCurve: (msg: Uint8Array
|
|
576
|
+
hashToSigCurve: (msg: TArg<Uint8Array>, options?: TArg<H2CDSTOpts>) => WeierstrassPoint<S>,
|
|
350
577
|
SignatureCoder?: BlsLongSignatureCoder<S>
|
|
351
578
|
): BlsSigs<P, S> {
|
|
352
579
|
const { Fr, Fp12, pairingBatch, randomSecretKey, lengths } = blsPairing;
|
|
@@ -366,6 +593,9 @@ function createBlsSig<P, S>(
|
|
|
366
593
|
function normSig(point: SigPoint | BLSInput): SigPoint {
|
|
367
594
|
return point instanceof SigPoint ? (point as SigPoint) : SigPoint.fromBytes(point);
|
|
368
595
|
}
|
|
596
|
+
// Sign/verify here take points already hashed onto the signature subgroup.
|
|
597
|
+
// Raw bytes and points from the other subgroup must fail this constructor-brand
|
|
598
|
+
// check before later validity checks run.
|
|
369
599
|
function amsg(m: unknown): SigPoint {
|
|
370
600
|
if (!(m instanceof SigPoint))
|
|
371
601
|
throw new Error(`expected valid message hashed to ${!isSigG1 ? 'G2' : 'G1'} curve`);
|
|
@@ -380,14 +610,14 @@ function createBlsSig<P, S>(
|
|
|
380
610
|
? (a: PubPoint, b: SigPoint) => ({ g1: a, g2: b }) as PairingInput
|
|
381
611
|
: (a: PubPoint, b: SigPoint) => ({ g1: b, g2: a }) as PairingInput;
|
|
382
612
|
return Object.freeze({
|
|
383
|
-
lengths: { ...lengths, secretKey: Fr.BYTES },
|
|
384
|
-
keygen(seed?: Uint8Array) {
|
|
613
|
+
lengths: Object.freeze({ ...lengths, secretKey: Fr.BYTES }),
|
|
614
|
+
keygen(seed?: TArg<Uint8Array>) {
|
|
385
615
|
const secretKey = randomSecretKey(seed);
|
|
386
616
|
const publicKey = this.getPublicKey(secretKey);
|
|
387
617
|
return { secretKey, publicKey };
|
|
388
618
|
},
|
|
389
619
|
// P = pk x G
|
|
390
|
-
getPublicKey(secretKey: Uint8Array): PubPoint {
|
|
620
|
+
getPublicKey(secretKey: TArg<Uint8Array>): PubPoint {
|
|
391
621
|
let sec;
|
|
392
622
|
try {
|
|
393
623
|
sec = PubPoint.Fn.fromBytes(secretKey);
|
|
@@ -398,7 +628,7 @@ function createBlsSig<P, S>(
|
|
|
398
628
|
return PubPoint.BASE.multiply(sec);
|
|
399
629
|
},
|
|
400
630
|
// S = pk x H(m)
|
|
401
|
-
sign(message: SigPoint, secretKey: Uint8Array
|
|
631
|
+
sign(message: SigPoint, secretKey: TArg<Uint8Array>, unusedArg?: any): SigPoint {
|
|
402
632
|
if (unusedArg != null) throw new Error('sign() expects 2 arguments');
|
|
403
633
|
const sec = PubPoint.Fn.fromBytes(secretKey);
|
|
404
634
|
amsg(message).assertValidity();
|
|
@@ -487,12 +717,12 @@ function createBlsSig<P, S>(
|
|
|
487
717
|
return agg;
|
|
488
718
|
},
|
|
489
719
|
|
|
490
|
-
hash(messageBytes: Uint8Array
|
|
720
|
+
hash(messageBytes: TArg<Uint8Array>, DST?: TArg<string | Uint8Array>): SigPoint {
|
|
491
721
|
abytes(messageBytes);
|
|
492
722
|
const opts = DST ? { DST } : undefined;
|
|
493
723
|
return hashToSigCurve(messageBytes, opts);
|
|
494
724
|
},
|
|
495
|
-
Signature: SignatureCoder,
|
|
725
|
+
Signature: Object.freeze({ ...SignatureCoder }),
|
|
496
726
|
}) /*satisfies Signer */;
|
|
497
727
|
}
|
|
498
728
|
|
|
@@ -502,11 +732,30 @@ type BlsSignatureCoders = Partial<{
|
|
|
502
732
|
}>;
|
|
503
733
|
|
|
504
734
|
// NOTE: separate function instead of function override, so we don't depend on hasher in bn254.
|
|
735
|
+
/**
|
|
736
|
+
* @param fields - Tower field implementations.
|
|
737
|
+
* @param G1_Point - G1 point constructor.
|
|
738
|
+
* @param G2_Point - G2 point constructor.
|
|
739
|
+
* @param params - Pairing parameters. See {@link BlsPairingParams}.
|
|
740
|
+
* @returns Pairing-only BLS helpers. The returned pairing surface rejects infinity inputs, while
|
|
741
|
+
* empty `pairingBatch(...)` calls return the multiplicative identity in GT. This keeps the
|
|
742
|
+
* low-level pairing API fail-closed for BLS-style callers, where identity points usually signal
|
|
743
|
+
* broken hash / wiring instead of an intentionally neutral pairing term. This also eagerly
|
|
744
|
+
* precomputes the G1 base-point table as a performance side effect.
|
|
745
|
+
* @throws If the pairing parameters or underlying curve helpers are inconsistent. {@link Error}
|
|
746
|
+
* @example
|
|
747
|
+
* ```ts
|
|
748
|
+
* import { blsBasic } from '@noble/curves/abstract/bls.js';
|
|
749
|
+
* import { bn254 } from '@noble/curves/bn254.js';
|
|
750
|
+
* // Pair a G1 point with a G2 point without the higher-level signer helpers.
|
|
751
|
+
* const gt = bn254.pairing(bn254.G1.Point.BASE, bn254.G2.Point.BASE);
|
|
752
|
+
* ```
|
|
753
|
+
*/
|
|
505
754
|
export function blsBasic(
|
|
506
|
-
fields: BlsFields
|
|
755
|
+
fields: TArg<BlsFields>,
|
|
507
756
|
G1_Point: WeierstrassPointCons<Fp>,
|
|
508
757
|
G2_Point: WeierstrassPointCons<Fp2>,
|
|
509
|
-
params: BlsPairingParams
|
|
758
|
+
params: TArg<BlsPairingParams>
|
|
510
759
|
): BlsCurvePair {
|
|
511
760
|
// Fields are specific for curve, so for now we'll need to pass them with opts
|
|
512
761
|
const { Fp, Fr, Fp2, Fp6, Fp12 } = fields;
|
|
@@ -527,53 +776,87 @@ export function blsBasic(
|
|
|
527
776
|
} = pairingRes;
|
|
528
777
|
|
|
529
778
|
G1.Point.BASE.precompute(4);
|
|
779
|
+
Object.freeze(G1);
|
|
780
|
+
Object.freeze(G2);
|
|
530
781
|
return Object.freeze({
|
|
531
|
-
lengths,
|
|
782
|
+
lengths: Object.freeze(lengths),
|
|
532
783
|
millerLoopBatch,
|
|
533
784
|
pairing,
|
|
534
785
|
pairingBatch,
|
|
535
786
|
G1,
|
|
536
787
|
G2,
|
|
537
|
-
fields: { Fr, Fp, Fp2, Fp6, Fp12 },
|
|
538
|
-
params: {
|
|
788
|
+
fields: Object.freeze({ Fr, Fp, Fp2, Fp6, Fp12 }),
|
|
789
|
+
params: Object.freeze({
|
|
539
790
|
ateLoopSize: params.ateLoopSize,
|
|
540
791
|
twistType: params.twistType,
|
|
541
|
-
},
|
|
542
|
-
utils: {
|
|
792
|
+
}),
|
|
793
|
+
utils: Object.freeze({
|
|
543
794
|
randomSecretKey,
|
|
544
795
|
calcPairingPrecomputes,
|
|
545
|
-
},
|
|
796
|
+
}),
|
|
546
797
|
});
|
|
547
798
|
}
|
|
548
799
|
|
|
549
800
|
// We can export this too, but seems there is not much reasons for now? If user wants hasher, they can just create hasher.
|
|
550
801
|
function blsHashers(
|
|
551
|
-
fields: BlsFields
|
|
802
|
+
fields: TArg<BlsFields>,
|
|
552
803
|
G1_Point: WeierstrassPointCons<Fp>,
|
|
553
804
|
G2_Point: WeierstrassPointCons<Fp2>,
|
|
554
|
-
params: BlsPairingParams
|
|
555
|
-
hasherParams: BlsHasherParams
|
|
805
|
+
params: TArg<BlsPairingParams>,
|
|
806
|
+
hasherParams: TArg<BlsHasherParams>
|
|
556
807
|
): BlsCurvePairWithHashers {
|
|
557
808
|
const base = blsBasic(fields, G1_Point, G2_Point, params);
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
809
|
+
// Missing map hooks intentionally fail closed via notImplemented on first hash use.
|
|
810
|
+
const G1Hasher = createHasher(
|
|
811
|
+
G1_Point,
|
|
812
|
+
hasherParams.mapToG1 === undefined ? notImplemented : hasherParams.mapToG1,
|
|
813
|
+
{
|
|
814
|
+
...hasherParams.hasherOpts,
|
|
815
|
+
...hasherParams.hasherOptsG1,
|
|
816
|
+
}
|
|
817
|
+
);
|
|
818
|
+
const G2Hasher = createHasher(
|
|
819
|
+
G2_Point,
|
|
820
|
+
hasherParams.mapToG2 === undefined ? notImplemented : hasherParams.mapToG2,
|
|
821
|
+
{
|
|
822
|
+
...hasherParams.hasherOpts,
|
|
823
|
+
...hasherParams.hasherOptsG2,
|
|
824
|
+
}
|
|
825
|
+
);
|
|
566
826
|
return Object.freeze({ ...base, G1: G1Hasher, G2: G2Hasher });
|
|
567
827
|
}
|
|
568
828
|
|
|
569
829
|
// G1_Point: ProjConstructor<bigint>, G2_Point: ProjConstructor<Fp2>,
|
|
570
830
|
// Rename to blsSignatures?
|
|
831
|
+
/**
|
|
832
|
+
* @param fields - Tower field implementations.
|
|
833
|
+
* @param G1_Point - G1 point constructor.
|
|
834
|
+
* @param G2_Point - G2 point constructor.
|
|
835
|
+
* @param params - Pairing parameters. See {@link BlsPairingParams}.
|
|
836
|
+
* @param hasherParams - Hash-to-curve configuration. See {@link BlsHasherParams}.
|
|
837
|
+
* @param signatureCoders - Signature codecs.
|
|
838
|
+
* @returns BLS helpers with signers. The inherited pairing surface still rejects infinity inputs,
|
|
839
|
+
* and empty `pairingBatch(...)` calls still return the multiplicative identity in GT. Aggregate
|
|
840
|
+
* verification still requires proof of possession or another rogue-key defense from the caller.
|
|
841
|
+
* @throws If the pairing, hashing, or signature helpers are configured inconsistently. {@link Error}
|
|
842
|
+
* @example
|
|
843
|
+
* ```ts
|
|
844
|
+
* import { bls } from '@noble/curves/abstract/bls.js';
|
|
845
|
+
* import { bls12_381 } from '@noble/curves/bls12-381.js';
|
|
846
|
+
* const sigs = bls12_381.longSignatures;
|
|
847
|
+
* // Use the full BLS helper set when you need hashing, keygen, signing, and verification.
|
|
848
|
+
* const { secretKey, publicKey } = sigs.keygen();
|
|
849
|
+
* const msg = sigs.hash(new TextEncoder().encode('hello noble'));
|
|
850
|
+
* const sig = sigs.sign(msg, secretKey);
|
|
851
|
+
* const isValid = sigs.verify(sig, msg, publicKey);
|
|
852
|
+
* ```
|
|
853
|
+
*/
|
|
571
854
|
export function bls(
|
|
572
|
-
fields: BlsFields
|
|
855
|
+
fields: TArg<BlsFields>,
|
|
573
856
|
G1_Point: WeierstrassPointCons<Fp>,
|
|
574
857
|
G2_Point: WeierstrassPointCons<Fp2>,
|
|
575
|
-
params: BlsPairingParams
|
|
576
|
-
hasherParams: BlsHasherParams
|
|
858
|
+
params: TArg<BlsPairingParams>,
|
|
859
|
+
hasherParams: TArg<BlsHasherParams>,
|
|
577
860
|
signatureCoders: BlsSignatureCoders
|
|
578
861
|
): BlsCurvePairWithSignatures {
|
|
579
862
|
const base = blsHashers(fields, G1_Point, G2_Point, params, hasherParams);
|