@noble/curves 1.9.1 → 1.9.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 +56 -25
- package/_shortw_utils.d.ts +7 -5
- package/_shortw_utils.d.ts.map +1 -1
- package/_shortw_utils.js +2 -8
- package/_shortw_utils.js.map +1 -1
- package/abstract/bls.d.ts +60 -24
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +158 -109
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +44 -9
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +86 -7
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +112 -25
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +138 -102
- package/abstract/edwards.js.map +1 -1
- package/abstract/fft.d.ts +12 -10
- package/abstract/fft.d.ts.map +1 -1
- package/abstract/fft.js +12 -13
- package/abstract/fft.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +25 -11
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +17 -14
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +24 -11
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +49 -20
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +1 -1
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +5 -4
- package/abstract/montgomery.js.map +1 -1
- package/abstract/poseidon.d.ts +5 -13
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +12 -7
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +20 -46
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +9 -3
- package/abstract/tower.js.map +1 -1
- package/abstract/utils.d.ts +1 -115
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +17 -371
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +132 -76
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +462 -398
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +2 -0
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +504 -466
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +2 -0
- package/bn254.d.ts.map +1 -1
- package/bn254.js +44 -32
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +8 -5
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +67 -54
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +10 -6
- package/ed448.d.ts.map +1 -1
- package/ed448.js +80 -57
- package/ed448.js.map +1 -1
- package/esm/_shortw_utils.d.ts +7 -5
- package/esm/_shortw_utils.d.ts.map +1 -1
- package/esm/_shortw_utils.js +2 -8
- package/esm/_shortw_utils.js.map +1 -1
- package/esm/abstract/bls.d.ts +60 -24
- package/esm/abstract/bls.d.ts.map +1 -1
- package/esm/abstract/bls.js +158 -109
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.d.ts +44 -9
- package/esm/abstract/curve.d.ts.map +1 -1
- package/esm/abstract/curve.js +83 -8
- package/esm/abstract/curve.js.map +1 -1
- package/esm/abstract/edwards.d.ts +112 -25
- package/esm/abstract/edwards.d.ts.map +1 -1
- package/esm/abstract/edwards.js +138 -104
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/fft.d.ts +12 -10
- package/esm/abstract/fft.d.ts.map +1 -1
- package/esm/abstract/fft.js +10 -11
- package/esm/abstract/fft.js.map +1 -1
- package/esm/abstract/hash-to-curve.d.ts +25 -11
- package/esm/abstract/hash-to-curve.d.ts.map +1 -1
- package/esm/abstract/hash-to-curve.js +17 -14
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.d.ts +24 -11
- package/esm/abstract/modular.d.ts.map +1 -1
- package/esm/abstract/modular.js +48 -19
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/montgomery.d.ts +1 -1
- package/esm/abstract/montgomery.d.ts.map +1 -1
- package/esm/abstract/montgomery.js +5 -4
- package/esm/abstract/montgomery.js.map +1 -1
- package/esm/abstract/poseidon.d.ts +5 -13
- package/esm/abstract/poseidon.d.ts.map +1 -1
- package/esm/abstract/poseidon.js +12 -7
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/tower.d.ts +20 -46
- package/esm/abstract/tower.d.ts.map +1 -1
- package/esm/abstract/tower.js +9 -3
- package/esm/abstract/tower.js.map +1 -1
- package/esm/abstract/utils.d.ts +1 -115
- package/esm/abstract/utils.d.ts.map +1 -1
- package/esm/abstract/utils.js +3 -344
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.d.ts +132 -76
- package/esm/abstract/weierstrass.d.ts.map +1 -1
- package/esm/abstract/weierstrass.js +460 -400
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.d.ts +2 -0
- package/esm/bls12-381.d.ts.map +1 -1
- package/esm/bls12-381.js +503 -465
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn254.d.ts +2 -0
- package/esm/bn254.d.ts.map +1 -1
- package/esm/bn254.js +41 -29
- package/esm/bn254.js.map +1 -1
- package/esm/ed25519.d.ts +8 -5
- package/esm/ed25519.d.ts.map +1 -1
- package/esm/ed25519.js +62 -49
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.d.ts +10 -6
- package/esm/ed448.d.ts.map +1 -1
- package/esm/ed448.js +74 -51
- package/esm/ed448.js.map +1 -1
- package/esm/misc.d.ts.map +1 -1
- package/esm/misc.js +31 -26
- package/esm/misc.js.map +1 -1
- package/esm/nist.d.ts +7 -16
- package/esm/nist.d.ts.map +1 -1
- package/esm/nist.js +86 -97
- package/esm/nist.js.map +1 -1
- package/esm/p256.d.ts +3 -3
- package/esm/p384.d.ts +3 -3
- package/esm/p521.d.ts +3 -3
- package/esm/secp256k1.d.ts +6 -6
- package/esm/secp256k1.d.ts.map +1 -1
- package/esm/secp256k1.js +43 -40
- package/esm/secp256k1.js.map +1 -1
- package/esm/utils.d.ts +96 -0
- package/esm/utils.d.ts.map +1 -0
- package/esm/utils.js +279 -0
- package/esm/utils.js.map +1 -0
- package/misc.d.ts.map +1 -1
- package/misc.js +35 -30
- package/misc.js.map +1 -1
- package/nist.d.ts +7 -16
- package/nist.d.ts.map +1 -1
- package/nist.js +86 -97
- package/nist.js.map +1 -1
- package/p256.d.ts +3 -3
- package/p384.d.ts +3 -3
- package/p521.d.ts +3 -3
- package/package.json +14 -5
- package/secp256k1.d.ts +6 -6
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +46 -43
- package/secp256k1.js.map +1 -1
- package/src/_shortw_utils.ts +5 -15
- package/src/abstract/bls.ts +260 -145
- package/src/abstract/curve.ts +115 -13
- package/src/abstract/edwards.ts +279 -138
- package/src/abstract/fft.ts +30 -19
- package/src/abstract/hash-to-curve.ts +51 -27
- package/src/abstract/modular.ts +49 -28
- package/src/abstract/montgomery.ts +9 -7
- package/src/abstract/poseidon.ts +22 -18
- package/src/abstract/tower.ts +36 -67
- package/src/abstract/utils.ts +3 -378
- package/src/abstract/weierstrass.ts +700 -453
- package/src/bls12-381.ts +540 -489
- package/src/bn254.ts +47 -35
- package/src/ed25519.ts +80 -64
- package/src/ed448.ts +129 -92
- package/src/misc.ts +39 -34
- package/src/nist.ts +138 -127
- package/src/p256.ts +3 -3
- package/src/p384.ts +3 -3
- package/src/p521.ts +3 -3
- package/src/secp256k1.ts +58 -46
- package/src/utils.ts +328 -0
- package/utils.d.ts +96 -0
- package/utils.d.ts.map +1 -0
- package/utils.js +313 -0
- package/utils.js.map +1 -0
package/src/abstract/curve.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { bitLen, bitMask, validateObject } from '../utils.ts';
|
|
8
|
+
import { Field, FpInvertBatch, type IField, nLength, validateField } from './modular.ts';
|
|
9
9
|
|
|
10
10
|
const _0n = BigInt(0);
|
|
11
11
|
const _1n = BigInt(1);
|
|
@@ -22,19 +22,43 @@ export interface Group<T extends Group<T>> {
|
|
|
22
22
|
subtract(other: T): T;
|
|
23
23
|
equals(other: T): boolean;
|
|
24
24
|
multiply(scalar: bigint): T;
|
|
25
|
+
toAffine?(invertedZ?: any): AffinePoint<any>;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export type GroupConstructor<T> = {
|
|
28
29
|
BASE: T;
|
|
29
30
|
ZERO: T;
|
|
30
31
|
};
|
|
32
|
+
export type ExtendedGroupConstructor<T> = GroupConstructor<T> & {
|
|
33
|
+
Fp: IField<any>;
|
|
34
|
+
Fn: IField<bigint>;
|
|
35
|
+
fromAffine(ap: AffinePoint<any>): T;
|
|
36
|
+
};
|
|
31
37
|
export type Mapper<T> = (i: T[]) => T[];
|
|
32
38
|
|
|
33
|
-
function
|
|
39
|
+
export function negateCt<T extends Group<T>>(condition: boolean, item: T): T {
|
|
34
40
|
const neg = item.negate();
|
|
35
41
|
return condition ? neg : item;
|
|
36
42
|
}
|
|
37
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Takes a bunch of Projective Points but executes only one
|
|
46
|
+
* inversion on all of them. Inversion is very slow operation,
|
|
47
|
+
* so this improves performance massively.
|
|
48
|
+
* Optimization: converts a list of projective points to a list of identical points with Z=1.
|
|
49
|
+
*/
|
|
50
|
+
export function normalizeZ<T>(
|
|
51
|
+
c: ExtendedGroupConstructor<T>,
|
|
52
|
+
property: 'pz' | 'ez',
|
|
53
|
+
points: T[]
|
|
54
|
+
): T[] {
|
|
55
|
+
const getz = property === 'pz' ? (p: any) => p.pz : (p: any) => p.ez;
|
|
56
|
+
const toInv = FpInvertBatch(c.Fp, points.map(getz));
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
const affined = points.map((p, i) => p.toAffine(toInv[i]));
|
|
59
|
+
return affined.map(c.fromAffine);
|
|
60
|
+
}
|
|
61
|
+
|
|
38
62
|
function validateW(W: number, bits: number) {
|
|
39
63
|
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
|
40
64
|
throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);
|
|
@@ -107,16 +131,20 @@ function getW(P: any): number {
|
|
|
107
131
|
return pointWindowSizes.get(P) || 1;
|
|
108
132
|
}
|
|
109
133
|
|
|
134
|
+
function assert0(n: bigint): void {
|
|
135
|
+
if (n !== _0n) throw new Error('invalid wNAF');
|
|
136
|
+
}
|
|
137
|
+
|
|
110
138
|
export type IWNAF<T extends Group<T>> = {
|
|
111
139
|
constTimeNegate: <T extends Group<T>>(condition: boolean, item: T) => T;
|
|
112
140
|
hasPrecomputes(elm: T): boolean;
|
|
113
141
|
unsafeLadder(elm: T, n: bigint, p?: T): T;
|
|
114
142
|
precomputeWindow(elm: T, W: number): Group<T>[];
|
|
115
|
-
getPrecomputes(W: number, P: T, transform
|
|
143
|
+
getPrecomputes(W: number, P: T, transform?: Mapper<T>): T[];
|
|
116
144
|
wNAF(W: number, precomputes: T[], n: bigint): { p: T; f: T };
|
|
117
145
|
wNAFUnsafe(W: number, precomputes: T[], n: bigint, acc?: T): T;
|
|
118
|
-
wNAFCached(P: T, n: bigint, transform
|
|
119
|
-
wNAFCachedUnsafe(P: T, n: bigint, transform
|
|
146
|
+
wNAFCached(P: T, n: bigint, transform?: Mapper<T>): { p: T; f: T };
|
|
147
|
+
wNAFCachedUnsafe(P: T, n: bigint, transform?: Mapper<T>, prev?: T): T;
|
|
120
148
|
setWindowSize(P: T, W: number): void;
|
|
121
149
|
};
|
|
122
150
|
|
|
@@ -136,7 +164,7 @@ export type IWNAF<T extends Group<T>> = {
|
|
|
136
164
|
*/
|
|
137
165
|
export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number): IWNAF<T> {
|
|
138
166
|
return {
|
|
139
|
-
constTimeNegate,
|
|
167
|
+
constTimeNegate: negateCt,
|
|
140
168
|
|
|
141
169
|
hasPrecomputes(elm: T) {
|
|
142
170
|
return getW(elm) !== 1;
|
|
@@ -212,12 +240,13 @@ export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number):
|
|
|
212
240
|
if (isZero) {
|
|
213
241
|
// bits are 0: add garbage to fake point
|
|
214
242
|
// Important part for const-time getPublicKey: add random "noise" point to f.
|
|
215
|
-
f = f.add(
|
|
243
|
+
f = f.add(negateCt(isNegF, precomputes[offsetF]));
|
|
216
244
|
} else {
|
|
217
245
|
// bits are 1: add to result point
|
|
218
|
-
p = p.add(
|
|
246
|
+
p = p.add(negateCt(isNeg, precomputes[offset]));
|
|
219
247
|
}
|
|
220
248
|
}
|
|
249
|
+
assert0(n);
|
|
221
250
|
// Return both real and fake points: JIT won't eliminate f.
|
|
222
251
|
// At this point there is a way to F be infinity-point even if p is not,
|
|
223
252
|
// which makes it less const-time: around 1 bigint multiply.
|
|
@@ -247,25 +276,30 @@ export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number):
|
|
|
247
276
|
acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM
|
|
248
277
|
}
|
|
249
278
|
}
|
|
279
|
+
assert0(n);
|
|
250
280
|
return acc;
|
|
251
281
|
},
|
|
252
282
|
|
|
253
|
-
getPrecomputes(W: number, P: T, transform
|
|
283
|
+
getPrecomputes(W: number, P: T, transform?: Mapper<T>): T[] {
|
|
254
284
|
// Calculate precomputes on a first run, reuse them after
|
|
255
285
|
let comp = pointPrecomputes.get(P);
|
|
256
286
|
if (!comp) {
|
|
257
287
|
comp = this.precomputeWindow(P, W) as T[];
|
|
258
|
-
if (W !== 1)
|
|
288
|
+
if (W !== 1) {
|
|
289
|
+
// Doing transform outside of if brings 15% perf hit
|
|
290
|
+
if (typeof transform === 'function') comp = transform(comp);
|
|
291
|
+
pointPrecomputes.set(P, comp);
|
|
292
|
+
}
|
|
259
293
|
}
|
|
260
294
|
return comp;
|
|
261
295
|
},
|
|
262
296
|
|
|
263
|
-
wNAFCached(P: T, n: bigint, transform
|
|
297
|
+
wNAFCached(P: T, n: bigint, transform?: Mapper<T>): { p: T; f: T } {
|
|
264
298
|
const W = getW(P);
|
|
265
299
|
return this.wNAF(W, this.getPrecomputes(W, P, transform), n);
|
|
266
300
|
},
|
|
267
301
|
|
|
268
|
-
wNAFCachedUnsafe(P: T, n: bigint, transform
|
|
302
|
+
wNAFCachedUnsafe(P: T, n: bigint, transform?: Mapper<T>, prev?: T): T {
|
|
269
303
|
const W = getW(P);
|
|
270
304
|
if (W === 1) return this.unsafeLadder(P, n, prev); // For W=1 ladder is ~x2 faster
|
|
271
305
|
return this.wNAFUnsafe(W, this.getPrecomputes(W, P, transform), n, prev);
|
|
@@ -283,6 +317,29 @@ export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number):
|
|
|
283
317
|
};
|
|
284
318
|
}
|
|
285
319
|
|
|
320
|
+
/**
|
|
321
|
+
* Endomorphism-specific multiplication for Koblitz curves.
|
|
322
|
+
* Cost: 128 dbl, 0-256 adds.
|
|
323
|
+
*/
|
|
324
|
+
export function mulEndoUnsafe<T extends Group<T>>(
|
|
325
|
+
c: GroupConstructor<T>,
|
|
326
|
+
point: T,
|
|
327
|
+
k1: bigint,
|
|
328
|
+
k2: bigint
|
|
329
|
+
): { p1: T; p2: T } {
|
|
330
|
+
let acc = point;
|
|
331
|
+
let p1 = c.ZERO;
|
|
332
|
+
let p2 = c.ZERO;
|
|
333
|
+
while (k1 > _0n || k2 > _0n) {
|
|
334
|
+
if (k1 & _1n) p1 = p1.add(acc);
|
|
335
|
+
if (k2 & _1n) p2 = p2.add(acc);
|
|
336
|
+
acc = acc.double();
|
|
337
|
+
k1 >>= _1n;
|
|
338
|
+
k2 >>= _1n;
|
|
339
|
+
}
|
|
340
|
+
return { p1, p2 };
|
|
341
|
+
}
|
|
342
|
+
|
|
286
343
|
/**
|
|
287
344
|
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
|
288
345
|
* 30x faster vs naive addition on L=4096, 10x faster than precomputes.
|
|
@@ -437,6 +494,8 @@ export type BasicCurve<T> = {
|
|
|
437
494
|
allowInfinityPoint?: boolean; // bls12-381 requires it. ZERO point is valid, but invalid pubkey
|
|
438
495
|
};
|
|
439
496
|
|
|
497
|
+
// TODO: remove
|
|
498
|
+
/** @deprecated */
|
|
440
499
|
export function validateBasic<FP, T>(
|
|
441
500
|
curve: BasicCurve<FP> & T
|
|
442
501
|
): Readonly<
|
|
@@ -469,3 +528,46 @@ export function validateBasic<FP, T>(
|
|
|
469
528
|
...{ p: curve.Fp.ORDER },
|
|
470
529
|
} as const);
|
|
471
530
|
}
|
|
531
|
+
|
|
532
|
+
export type ValidCurveParams<T> = {
|
|
533
|
+
a: T;
|
|
534
|
+
p: bigint;
|
|
535
|
+
n: bigint;
|
|
536
|
+
h: bigint;
|
|
537
|
+
Gx: T;
|
|
538
|
+
Gy: T;
|
|
539
|
+
} & ({ b: T } | { d: T });
|
|
540
|
+
|
|
541
|
+
function createField<T>(order: bigint, field?: IField<T>): IField<T> {
|
|
542
|
+
if (field) {
|
|
543
|
+
if (field.ORDER !== order) throw new Error('Field.ORDER must match order: Fp == p, Fn == n');
|
|
544
|
+
validateField(field);
|
|
545
|
+
return field;
|
|
546
|
+
} else {
|
|
547
|
+
return Field(order) as unknown as IField<T>;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
export type FpFn<T> = { Fp: IField<T>; Fn: IField<bigint> };
|
|
551
|
+
/** Validates CURVE opts and creates fields */
|
|
552
|
+
export function _createCurveFields<T>(
|
|
553
|
+
type: 'weierstrass' | 'edwards',
|
|
554
|
+
CURVE: ValidCurveParams<T>,
|
|
555
|
+
curveOpts: Partial<FpFn<T>> = {}
|
|
556
|
+
): FpFn<T> {
|
|
557
|
+
if (!CURVE || typeof CURVE !== 'object') throw new Error(`expected valid ${type} CURVE object`);
|
|
558
|
+
for (const p of ['p', 'n', 'h'] as const) {
|
|
559
|
+
const val = CURVE[p];
|
|
560
|
+
if (!(typeof val === 'bigint' && val > _0n))
|
|
561
|
+
throw new Error(`CURVE.${p} must be positive bigint`);
|
|
562
|
+
}
|
|
563
|
+
const Fp = createField(CURVE.p, curveOpts.Fp);
|
|
564
|
+
const Fn = createField(CURVE.n, curveOpts.Fn);
|
|
565
|
+
const _b: 'b' | 'd' = type === 'weierstrass' ? 'b' : 'd';
|
|
566
|
+
const params = ['Gx', 'Gy', 'a', _b] as const;
|
|
567
|
+
for (const p of params) {
|
|
568
|
+
// @ts-ignore
|
|
569
|
+
if (!Fp.isValid(CURVE[p]))
|
|
570
|
+
throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
|
|
571
|
+
}
|
|
572
|
+
return { Fp, Fn };
|
|
573
|
+
}
|