@noble/curves 1.9.5 → 2.0.0-beta.1
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 +267 -421
- package/abstract/bls.d.ts +49 -111
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +108 -152
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +7 -48
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +22 -47
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +17 -68
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +98 -175
- package/abstract/edwards.js.map +1 -1
- package/abstract/fft.js +14 -27
- package/abstract/fft.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +11 -24
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +30 -35
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +5 -17
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +166 -167
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +4 -9
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +17 -20
- package/abstract/montgomery.js.map +1 -1
- package/abstract/oprf.d.ts +282 -0
- package/abstract/oprf.d.ts.map +1 -0
- package/abstract/oprf.js +297 -0
- package/abstract/oprf.js.map +1 -0
- package/abstract/poseidon.js +20 -24
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +9 -7
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +600 -364
- package/abstract/tower.js.map +1 -1
- package/abstract/weierstrass.d.ts +12 -145
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +153 -377
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +2 -2
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +174 -216
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +58 -10
- package/bn254.d.ts.map +1 -1
- package/bn254.js +70 -130
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +12 -31
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +104 -146
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +14 -33
- package/ed448.d.ts.map +1 -1
- package/ed448.js +105 -132
- package/ed448.js.map +1 -1
- package/index.js +1 -1
- package/misc.d.ts +10 -14
- package/misc.d.ts.map +1 -1
- package/misc.js +51 -60
- package/misc.js.map +1 -1
- package/nist.d.ts +11 -14
- package/nist.d.ts.map +1 -1
- package/nist.js +46 -55
- package/nist.js.map +1 -1
- package/package.json +9 -224
- package/secp256k1.d.ts +7 -23
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +72 -83
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +197 -344
- package/src/abstract/curve.ts +10 -83
- package/src/abstract/edwards.ts +96 -223
- package/src/abstract/hash-to-curve.ts +32 -45
- package/src/abstract/modular.ts +144 -130
- package/src/abstract/montgomery.ts +21 -22
- package/src/abstract/oprf.ts +600 -0
- package/src/abstract/tower.ts +627 -382
- package/src/abstract/weierstrass.ts +101 -482
- package/src/bls12-381.ts +148 -176
- package/src/bn254.ts +67 -122
- package/src/ed25519.ts +65 -118
- package/src/ed448.ts +63 -113
- package/src/index.ts +1 -1
- package/src/misc.ts +66 -49
- package/src/nist.ts +48 -57
- package/src/secp256k1.ts +56 -88
- package/src/utils.ts +41 -61
- package/src/webcrypto.ts +362 -0
- package/utils.d.ts +28 -19
- package/utils.d.ts.map +1 -1
- package/utils.js +45 -121
- package/utils.js.map +1 -1
- package/webcrypto.d.ts +47 -0
- package/webcrypto.d.ts.map +1 -0
- package/webcrypto.js +231 -0
- package/webcrypto.js.map +1 -0
- package/esm/_shortw_utils.d.ts +0 -19
- package/esm/_shortw_utils.d.ts.map +0 -1
- package/esm/_shortw_utils.js +0 -16
- package/esm/_shortw_utils.js.map +0 -1
- package/esm/abstract/bls.d.ts +0 -190
- package/esm/abstract/bls.d.ts.map +0 -1
- package/esm/abstract/bls.js +0 -408
- package/esm/abstract/bls.js.map +0 -1
- package/esm/abstract/curve.d.ts +0 -231
- package/esm/abstract/curve.d.ts.map +0 -1
- package/esm/abstract/curve.js +0 -465
- package/esm/abstract/curve.js.map +0 -1
- package/esm/abstract/edwards.d.ts +0 -237
- package/esm/abstract/edwards.d.ts.map +0 -1
- package/esm/abstract/edwards.js +0 -632
- package/esm/abstract/edwards.js.map +0 -1
- package/esm/abstract/fft.d.ts +0 -122
- package/esm/abstract/fft.d.ts.map +0 -1
- package/esm/abstract/fft.js +0 -425
- package/esm/abstract/fft.js.map +0 -1
- package/esm/abstract/hash-to-curve.d.ts +0 -102
- package/esm/abstract/hash-to-curve.d.ts.map +0 -1
- package/esm/abstract/hash-to-curve.js +0 -203
- package/esm/abstract/hash-to-curve.js.map +0 -1
- package/esm/abstract/modular.d.ts +0 -171
- package/esm/abstract/modular.d.ts.map +0 -1
- package/esm/abstract/modular.js +0 -530
- package/esm/abstract/modular.js.map +0 -1
- package/esm/abstract/montgomery.d.ts +0 -30
- package/esm/abstract/montgomery.d.ts.map +0 -1
- package/esm/abstract/montgomery.js +0 -157
- package/esm/abstract/montgomery.js.map +0 -1
- package/esm/abstract/poseidon.d.ts +0 -68
- package/esm/abstract/poseidon.d.ts.map +0 -1
- package/esm/abstract/poseidon.js +0 -296
- package/esm/abstract/poseidon.js.map +0 -1
- package/esm/abstract/tower.d.ts +0 -93
- package/esm/abstract/tower.d.ts.map +0 -1
- package/esm/abstract/tower.js +0 -502
- package/esm/abstract/tower.js.map +0 -1
- package/esm/abstract/utils.d.ts +0 -5
- package/esm/abstract/utils.d.ts.map +0 -1
- package/esm/abstract/utils.js +0 -7
- package/esm/abstract/utils.js.map +0 -1
- package/esm/abstract/weierstrass.d.ts +0 -412
- package/esm/abstract/weierstrass.d.ts.map +0 -1
- package/esm/abstract/weierstrass.js +0 -1428
- package/esm/abstract/weierstrass.js.map +0 -1
- package/esm/bls12-381.d.ts +0 -16
- package/esm/bls12-381.d.ts.map +0 -1
- package/esm/bls12-381.js +0 -738
- package/esm/bls12-381.js.map +0 -1
- package/esm/bn254.d.ts +0 -18
- package/esm/bn254.d.ts.map +0 -1
- package/esm/bn254.js +0 -246
- package/esm/bn254.js.map +0 -1
- package/esm/ed25519.d.ts +0 -106
- package/esm/ed25519.d.ts.map +0 -1
- package/esm/ed25519.js +0 -467
- package/esm/ed25519.js.map +0 -1
- package/esm/ed448.d.ts +0 -101
- package/esm/ed448.d.ts.map +0 -1
- package/esm/ed448.js +0 -448
- package/esm/ed448.js.map +0 -1
- package/esm/index.d.ts +0 -2
- package/esm/index.d.ts.map +0 -1
- package/esm/index.js +0 -17
- package/esm/index.js.map +0 -1
- package/esm/jubjub.d.ts +0 -12
- package/esm/jubjub.d.ts.map +0 -1
- package/esm/jubjub.js +0 -12
- package/esm/jubjub.js.map +0 -1
- package/esm/misc.d.ts +0 -19
- package/esm/misc.d.ts.map +0 -1
- package/esm/misc.js +0 -109
- package/esm/misc.js.map +0 -1
- package/esm/nist.d.ts +0 -21
- package/esm/nist.d.ts.map +0 -1
- package/esm/nist.js +0 -132
- package/esm/nist.js.map +0 -1
- package/esm/p256.d.ts +0 -16
- package/esm/p256.d.ts.map +0 -1
- package/esm/p256.js +0 -16
- package/esm/p256.js.map +0 -1
- package/esm/p384.d.ts +0 -16
- package/esm/p384.d.ts.map +0 -1
- package/esm/p384.js +0 -16
- package/esm/p384.js.map +0 -1
- package/esm/p521.d.ts +0 -16
- package/esm/p521.d.ts.map +0 -1
- package/esm/p521.js +0 -16
- package/esm/p521.js.map +0 -1
- package/esm/package.json +0 -4
- package/esm/pasta.d.ts +0 -10
- package/esm/pasta.d.ts.map +0 -1
- package/esm/pasta.js +0 -10
- package/esm/pasta.js.map +0 -1
- package/esm/secp256k1.d.ts +0 -89
- package/esm/secp256k1.d.ts.map +0 -1
- package/esm/secp256k1.js +0 -292
- package/esm/secp256k1.js.map +0 -1
- package/esm/utils.d.ts +0 -110
- package/esm/utils.d.ts.map +0 -1
- package/esm/utils.js +0 -322
- package/esm/utils.js.map +0 -1
- package/src/_shortw_utils.ts +0 -21
- package/src/abstract/utils.ts +0 -7
- package/src/jubjub.ts +0 -12
- package/src/p256.ts +0 -15
- package/src/p384.ts +0 -15
- package/src/p521.ts +0 -15
- package/src/package.json +0 -3
- package/src/pasta.ts +0 -9
package/src/abstract/edwards.ts
CHANGED
|
@@ -7,33 +7,31 @@
|
|
|
7
7
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
8
8
|
import {
|
|
9
9
|
_validateObject,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
abool,
|
|
11
|
+
abytes,
|
|
12
12
|
aInRange,
|
|
13
13
|
bytesToHex,
|
|
14
14
|
bytesToNumberLE,
|
|
15
15
|
concatBytes,
|
|
16
16
|
copyBytes,
|
|
17
|
-
|
|
17
|
+
hexToBytes,
|
|
18
|
+
isBytes,
|
|
18
19
|
memoized,
|
|
19
20
|
notImplemented,
|
|
20
|
-
|
|
21
|
-
randomBytes,
|
|
21
|
+
randomBytes as wcRandomBytes,
|
|
22
22
|
type FHash,
|
|
23
|
-
type
|
|
23
|
+
type Signer,
|
|
24
24
|
} from '../utils.ts';
|
|
25
25
|
import {
|
|
26
26
|
_createCurveFields,
|
|
27
27
|
normalizeZ,
|
|
28
|
-
pippenger,
|
|
29
28
|
wNAF,
|
|
30
29
|
type AffinePoint,
|
|
31
|
-
type BasicCurve,
|
|
32
30
|
type CurveLengths,
|
|
33
31
|
type CurvePoint,
|
|
34
32
|
type CurvePointCons,
|
|
35
33
|
} from './curve.ts';
|
|
36
|
-
import {
|
|
34
|
+
import { type IField } from './modular.ts';
|
|
37
35
|
|
|
38
36
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
39
37
|
// prettier-ignore
|
|
@@ -51,33 +49,14 @@ export interface EdwardsPoint extends CurvePoint<bigint, EdwardsPoint> {
|
|
|
51
49
|
readonly Z: bigint;
|
|
52
50
|
/** extended T coordinate */
|
|
53
51
|
readonly T: bigint;
|
|
54
|
-
|
|
55
|
-
/** @deprecated use `toBytes` */
|
|
56
|
-
toRawBytes(): Uint8Array;
|
|
57
|
-
/** @deprecated use `p.precompute(windowSize)` */
|
|
58
|
-
_setWindowSize(windowSize: number): void;
|
|
59
|
-
/** @deprecated use .X */
|
|
60
|
-
readonly ex: bigint;
|
|
61
|
-
/** @deprecated use .Y */
|
|
62
|
-
readonly ey: bigint;
|
|
63
|
-
/** @deprecated use .Z */
|
|
64
|
-
readonly ez: bigint;
|
|
65
|
-
/** @deprecated use .T */
|
|
66
|
-
readonly et: bigint;
|
|
67
52
|
}
|
|
68
53
|
/** Static methods of Extended Point with coordinates in X, Y, Z, T. */
|
|
69
54
|
export interface EdwardsPointCons extends CurvePointCons<EdwardsPoint> {
|
|
70
55
|
new (X: bigint, Y: bigint, Z: bigint, T: bigint): EdwardsPoint;
|
|
71
56
|
CURVE(): EdwardsOpts;
|
|
72
57
|
fromBytes(bytes: Uint8Array, zip215?: boolean): EdwardsPoint;
|
|
73
|
-
fromHex(hex:
|
|
74
|
-
/** @deprecated use `import { pippenger } from '@noble/curves/abstract/curve.js';` */
|
|
75
|
-
msm(points: EdwardsPoint[], scalars: bigint[]): EdwardsPoint;
|
|
58
|
+
fromHex(hex: string, zip215?: boolean): EdwardsPoint;
|
|
76
59
|
}
|
|
77
|
-
/** @deprecated use EdwardsPoint */
|
|
78
|
-
export type ExtPointType = EdwardsPoint;
|
|
79
|
-
/** @deprecated use EdwardsPointCons */
|
|
80
|
-
export type ExtPointConstructor = EdwardsPointCons;
|
|
81
60
|
|
|
82
61
|
/**
|
|
83
62
|
* Twisted Edwards curve options.
|
|
@@ -139,13 +118,17 @@ export type EdDSAOpts = Partial<{
|
|
|
139
118
|
*/
|
|
140
119
|
export interface EdDSA {
|
|
141
120
|
keygen: (seed?: Uint8Array) => { secretKey: Uint8Array; publicKey: Uint8Array };
|
|
142
|
-
getPublicKey: (secretKey:
|
|
143
|
-
sign: (
|
|
121
|
+
getPublicKey: (secretKey: Uint8Array) => Uint8Array;
|
|
122
|
+
sign: (
|
|
123
|
+
message: Uint8Array,
|
|
124
|
+
secretKey: Uint8Array,
|
|
125
|
+
options?: { context?: Uint8Array }
|
|
126
|
+
) => Uint8Array;
|
|
144
127
|
verify: (
|
|
145
|
-
sig:
|
|
146
|
-
message:
|
|
147
|
-
publicKey:
|
|
148
|
-
options?: { context?:
|
|
128
|
+
sig: Uint8Array,
|
|
129
|
+
message: Uint8Array,
|
|
130
|
+
publicKey: Uint8Array,
|
|
131
|
+
options?: { context?: Uint8Array; zip215: boolean }
|
|
149
132
|
) => boolean;
|
|
150
133
|
Point: EdwardsPointCons;
|
|
151
134
|
utils: {
|
|
@@ -155,6 +138,12 @@ export interface EdDSA {
|
|
|
155
138
|
|
|
156
139
|
/**
|
|
157
140
|
* Converts ed public key to x public key.
|
|
141
|
+
*
|
|
142
|
+
* There is NO `fromMontgomery`:
|
|
143
|
+
* - There are 2 valid ed25519 points for every x25519, with flipped coordinate
|
|
144
|
+
* - Sometimes there are 0 valid ed25519 points, because x25519 *additionally*
|
|
145
|
+
* accepts inputs on the quadratic twist, which can't be moved to ed25519
|
|
146
|
+
*
|
|
158
147
|
* @example
|
|
159
148
|
* ```js
|
|
160
149
|
* const someonesPub = ed25519.getPublicKey(ed25519.utils.randomSecretKey());
|
|
@@ -173,18 +162,13 @@ export interface EdDSA {
|
|
|
173
162
|
* ```
|
|
174
163
|
*/
|
|
175
164
|
toMontgomeryPriv: (privateKey: Uint8Array) => Uint8Array;
|
|
176
|
-
getExtendedPublicKey: (key:
|
|
165
|
+
getExtendedPublicKey: (key: Uint8Array) => {
|
|
177
166
|
head: Uint8Array;
|
|
178
167
|
prefix: Uint8Array;
|
|
179
168
|
scalar: bigint;
|
|
180
169
|
point: EdwardsPoint;
|
|
181
170
|
pointBytes: Uint8Array;
|
|
182
171
|
};
|
|
183
|
-
|
|
184
|
-
/** @deprecated use `randomSecretKey` */
|
|
185
|
-
randomPrivateKey: (seed?: Uint8Array) => Uint8Array;
|
|
186
|
-
/** @deprecated use `point.precompute()` */
|
|
187
|
-
precompute: (windowSize?: number, point?: EdwardsPoint) => EdwardsPoint;
|
|
188
172
|
};
|
|
189
173
|
lengths: CurveLengths;
|
|
190
174
|
}
|
|
@@ -201,7 +185,7 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
201
185
|
const validated = _createCurveFields('edwards', params, extraOpts, extraOpts.FpFnLE);
|
|
202
186
|
const { Fp, Fn } = validated;
|
|
203
187
|
let CURVE = validated.CURVE as EdwardsOpts;
|
|
204
|
-
const { h: cofactor
|
|
188
|
+
const { h: cofactor } = CURVE;
|
|
205
189
|
_validateObject(extraOpts, {}, { uvRatio: 'function' });
|
|
206
190
|
|
|
207
191
|
// Important:
|
|
@@ -300,7 +284,7 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
300
284
|
}
|
|
301
285
|
|
|
302
286
|
static CURVE(): EdwardsOpts {
|
|
303
|
-
return CURVE
|
|
287
|
+
return CURVE;
|
|
304
288
|
}
|
|
305
289
|
|
|
306
290
|
static fromAffine(p: AffinePoint<bigint>): Point {
|
|
@@ -327,7 +311,7 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
327
311
|
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
|
328
312
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
|
329
313
|
const max = zip215 ? MASK : Fp.ORDER;
|
|
330
|
-
aInRange('
|
|
314
|
+
aInRange('point.y', y, _0n, max);
|
|
331
315
|
|
|
332
316
|
// Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
|
|
333
317
|
// ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
|
|
@@ -335,17 +319,18 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
335
319
|
const u = modP(y2 - _1n); // u = y² - 1
|
|
336
320
|
const v = modP(d * y2 - a); // v = d y² + 1.
|
|
337
321
|
let { isValid, value: x } = uvRatio(u, v); // √(u/v)
|
|
338
|
-
if (!isValid) throw new Error('
|
|
322
|
+
if (!isValid) throw new Error('bad point: invalid y coordinate');
|
|
339
323
|
const isXOdd = (x & _1n) === _1n; // There are 2 square roots. Use x_0 bit to select proper
|
|
340
324
|
const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit
|
|
341
325
|
if (!zip215 && x === _0n && isLastByteOdd)
|
|
342
326
|
// if x=0 and x_0 = 1, fail
|
|
343
|
-
throw new Error('
|
|
327
|
+
throw new Error('bad point: x=0 and x_0=1');
|
|
344
328
|
if (isLastByteOdd !== isXOdd) x = modP(-x); // if x_0 != x mod 2, set x = p-x
|
|
345
329
|
return Point.fromAffine({ x, y });
|
|
346
330
|
}
|
|
347
|
-
|
|
348
|
-
|
|
331
|
+
|
|
332
|
+
static fromHex(hex: string, zip215 = false): Point {
|
|
333
|
+
return Point.fromBytes(hexToBytes(hex), zip215);
|
|
349
334
|
}
|
|
350
335
|
|
|
351
336
|
get x(): bigint {
|
|
@@ -438,9 +423,9 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
438
423
|
|
|
439
424
|
// Constant-time multiplication.
|
|
440
425
|
multiply(scalar: bigint): Point {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const { p, f } = wnaf.cached(this,
|
|
426
|
+
// 1 <= scalar < L
|
|
427
|
+
if (!Fn.isValidNot0(scalar)) throw new Error('invalid scalar: expected 1 <= sc < curve.n');
|
|
428
|
+
const { p, f } = wnaf.cached(this, scalar, (p) => normalizeZ(Point, p));
|
|
444
429
|
return normalizeZ(Point, [p, f])[0];
|
|
445
430
|
}
|
|
446
431
|
|
|
@@ -450,11 +435,11 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
450
435
|
// Does NOT allow scalars higher than CURVE.n.
|
|
451
436
|
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
|
452
437
|
multiplyUnsafe(scalar: bigint, acc = Point.ZERO): Point {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
if (
|
|
456
|
-
if (this.is0() ||
|
|
457
|
-
return wnaf.unsafe(this,
|
|
438
|
+
// 0 <= scalar < L
|
|
439
|
+
if (!Fn.isValid(scalar)) throw new Error('invalid scalar: expected 0 <= sc < curve.n');
|
|
440
|
+
if (scalar === _0n) return Point.ZERO;
|
|
441
|
+
if (this.is0() || scalar === _1n) return this;
|
|
442
|
+
return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point, p), acc);
|
|
458
443
|
}
|
|
459
444
|
|
|
460
445
|
// Checks if point is of small order.
|
|
@@ -468,7 +453,7 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
468
453
|
// Multiplies point by curve order and checks if the result is 0.
|
|
469
454
|
// Returns `false` is the point is dirty.
|
|
470
455
|
isTorsionFree(): boolean {
|
|
471
|
-
return wnaf.unsafe(this,
|
|
456
|
+
return wnaf.unsafe(this, CURVE.n).is0();
|
|
472
457
|
}
|
|
473
458
|
|
|
474
459
|
// Converts Extended point to default (x, y) coordinates.
|
|
@@ -484,13 +469,12 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
484
469
|
|
|
485
470
|
toBytes(): Uint8Array {
|
|
486
471
|
const { x, y } = this.toAffine();
|
|
487
|
-
|
|
488
|
-
bytes
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
return this.toBytes();
|
|
472
|
+
// Fp.toBytes() allows non-canonical encoding of y (>= p).
|
|
473
|
+
const bytes = Fp.toBytes(y);
|
|
474
|
+
// Each y has 2 valid points: (x, y), (x,-y).
|
|
475
|
+
// When compressing, it's enough to store y and use the last byte to encode sign of x
|
|
476
|
+
bytes[bytes.length - 1] |= x & _1n ? 0x80 : 0;
|
|
477
|
+
return bytes;
|
|
494
478
|
}
|
|
495
479
|
toHex(): string {
|
|
496
480
|
return bytesToHex(this.toBytes());
|
|
@@ -499,31 +483,9 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
|
|
|
499
483
|
toString() {
|
|
500
484
|
return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;
|
|
501
485
|
}
|
|
502
|
-
|
|
503
|
-
// TODO: remove
|
|
504
|
-
get ex(): bigint {
|
|
505
|
-
return this.X;
|
|
506
|
-
}
|
|
507
|
-
get ey(): bigint {
|
|
508
|
-
return this.Y;
|
|
509
|
-
}
|
|
510
|
-
get ez(): bigint {
|
|
511
|
-
return this.Z;
|
|
512
|
-
}
|
|
513
|
-
get et(): bigint {
|
|
514
|
-
return this.T;
|
|
515
|
-
}
|
|
516
|
-
static normalizeZ(points: Point[]): Point[] {
|
|
517
|
-
return normalizeZ(Point, points);
|
|
518
|
-
}
|
|
519
|
-
static msm(points: Point[], scalars: bigint[]): Point {
|
|
520
|
-
return pippenger(Point, Fn, points, scalars);
|
|
521
|
-
}
|
|
522
|
-
_setWindowSize(windowSize: number) {
|
|
523
|
-
this.precompute(windowSize);
|
|
524
|
-
}
|
|
525
486
|
}
|
|
526
|
-
const wnaf = new wNAF(Point, Fn.
|
|
487
|
+
const wnaf = new wNAF(Point, Fn.BITS);
|
|
488
|
+
Point.BASE.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
|
|
527
489
|
return Point;
|
|
528
490
|
}
|
|
529
491
|
|
|
@@ -555,7 +517,7 @@ export abstract class PrimeEdwardsPoint<T extends PrimeEdwardsPoint<T>>
|
|
|
555
517
|
notImplemented();
|
|
556
518
|
}
|
|
557
519
|
|
|
558
|
-
static fromHex(_hex:
|
|
520
|
+
static fromHex(_hex: string): any {
|
|
559
521
|
notImplemented();
|
|
560
522
|
}
|
|
561
523
|
|
|
@@ -580,11 +542,6 @@ export abstract class PrimeEdwardsPoint<T extends PrimeEdwardsPoint<T>>
|
|
|
580
542
|
return this.ep.toAffine(invertedZ);
|
|
581
543
|
}
|
|
582
544
|
|
|
583
|
-
/** @deprecated use `toBytes` */
|
|
584
|
-
toRawBytes(): Uint8Array {
|
|
585
|
-
return this.toBytes();
|
|
586
|
-
}
|
|
587
|
-
|
|
588
545
|
toHex(): string {
|
|
589
546
|
return bytesToHex(this.toBytes());
|
|
590
547
|
}
|
|
@@ -655,11 +612,10 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
|
|
|
655
612
|
);
|
|
656
613
|
|
|
657
614
|
const { prehash } = eddsaOpts;
|
|
658
|
-
const { BASE
|
|
659
|
-
const CURVE_ORDER = Fn.ORDER;
|
|
615
|
+
const { BASE, Fp, Fn } = Point;
|
|
660
616
|
|
|
661
|
-
const
|
|
662
|
-
const adjustScalarBytes = eddsaOpts.adjustScalarBytes || ((bytes: Uint8Array) => bytes);
|
|
617
|
+
const randomBytes = eddsaOpts.randomBytes || wcRandomBytes;
|
|
618
|
+
const adjustScalarBytes = eddsaOpts.adjustScalarBytes || ((bytes: Uint8Array) => bytes);
|
|
663
619
|
const domain =
|
|
664
620
|
eddsaOpts.domain ||
|
|
665
621
|
((data: Uint8Array, ctx: Uint8Array, phflag: boolean) => {
|
|
@@ -668,23 +624,18 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
|
|
|
668
624
|
return data;
|
|
669
625
|
}); // NOOP
|
|
670
626
|
|
|
671
|
-
function modN(a: bigint) {
|
|
672
|
-
return Fn.create(a);
|
|
673
|
-
}
|
|
674
|
-
|
|
675
627
|
// Little-endian SHA512 with modulo n
|
|
676
628
|
function modN_LE(hash: Uint8Array): bigint {
|
|
677
|
-
// Not
|
|
678
|
-
return modN(bytesToNumberLE(hash));
|
|
629
|
+
return Fn.create(bytesToNumberLE(hash)); // Not Fn.fromBytes: it has length limit
|
|
679
630
|
}
|
|
680
631
|
|
|
681
632
|
// Get the hashed private scalar per RFC8032 5.1.5
|
|
682
|
-
function getPrivateScalar(key:
|
|
683
|
-
const len = lengths.
|
|
684
|
-
|
|
633
|
+
function getPrivateScalar(key: Uint8Array) {
|
|
634
|
+
const len = lengths.secretKey;
|
|
635
|
+
abytes(key, lengths.secretKey, 'secretKey');
|
|
685
636
|
// Hash private key with curve's hash function to produce uniformingly random input
|
|
686
637
|
// Check byte lengths: ensure(64, h(ensure(32, key)))
|
|
687
|
-
const hashed =
|
|
638
|
+
const hashed = abytes(cHash(key), 2 * len, 'hashedSecretKey');
|
|
688
639
|
const head = adjustScalarBytes(hashed.slice(0, len)); // clear first half bits, produce FE
|
|
689
640
|
const prefix = hashed.slice(len, 2 * len); // second half is called key prefix (5.1.6)
|
|
690
641
|
const scalar = modN_LE(head); // The actual private scalar
|
|
@@ -692,52 +643,60 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
|
|
|
692
643
|
}
|
|
693
644
|
|
|
694
645
|
/** Convenience method that creates public key from scalar. RFC8032 5.1.5 */
|
|
695
|
-
function getExtendedPublicKey(secretKey:
|
|
646
|
+
function getExtendedPublicKey(secretKey: Uint8Array) {
|
|
696
647
|
const { head, prefix, scalar } = getPrivateScalar(secretKey);
|
|
697
|
-
const point =
|
|
648
|
+
const point = BASE.multiply(scalar); // Point on Edwards curve aka public key
|
|
698
649
|
const pointBytes = point.toBytes();
|
|
699
650
|
return { head, prefix, scalar, point, pointBytes };
|
|
700
651
|
}
|
|
701
652
|
|
|
702
653
|
/** Calculates EdDSA pub key. RFC8032 5.1.5. */
|
|
703
|
-
function getPublicKey(secretKey:
|
|
654
|
+
function getPublicKey(secretKey: Uint8Array): Uint8Array {
|
|
704
655
|
return getExtendedPublicKey(secretKey).pointBytes;
|
|
705
656
|
}
|
|
706
657
|
|
|
707
658
|
// int('LE', SHA512(dom2(F, C) || msgs)) mod N
|
|
708
|
-
function hashDomainToScalar(context:
|
|
659
|
+
function hashDomainToScalar(context: Uint8Array = Uint8Array.of(), ...msgs: Uint8Array[]) {
|
|
709
660
|
const msg = concatBytes(...msgs);
|
|
710
|
-
return modN_LE(cHash(domain(msg,
|
|
661
|
+
return modN_LE(cHash(domain(msg, abytes(context, undefined, 'context'), !!prehash)));
|
|
711
662
|
}
|
|
712
663
|
|
|
713
664
|
/** Signs message with privateKey. RFC8032 5.1.6 */
|
|
714
|
-
function sign(
|
|
715
|
-
msg
|
|
665
|
+
function sign(
|
|
666
|
+
msg: Uint8Array,
|
|
667
|
+
secretKey: Uint8Array,
|
|
668
|
+
options: { context?: Uint8Array } = {}
|
|
669
|
+
): Uint8Array {
|
|
670
|
+
msg = abytes(msg, undefined, 'message');
|
|
716
671
|
if (prehash) msg = prehash(msg); // for ed25519ph etc.
|
|
717
672
|
const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);
|
|
718
673
|
const r = hashDomainToScalar(options.context, prefix, msg); // r = dom2(F, C) || prefix || PH(M)
|
|
719
|
-
const R =
|
|
674
|
+
const R = BASE.multiply(r).toBytes(); // R = rG
|
|
720
675
|
const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
|
|
721
|
-
const s =
|
|
722
|
-
|
|
723
|
-
const
|
|
724
|
-
|
|
725
|
-
return ensureBytes('result', res, L * 2); // 64-byte signature
|
|
676
|
+
const s = Fn.create(r + k * scalar); // S = (r + k * s) mod L
|
|
677
|
+
if (!Fn.isValid(s)) throw new Error('sign failed: invalid s'); // 0 <= s < L
|
|
678
|
+
const rs = concatBytes(R, Fn.toBytes(s));
|
|
679
|
+
return abytes(rs, lengths.signature, 'result');
|
|
726
680
|
}
|
|
727
681
|
|
|
728
682
|
// verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
|
|
729
|
-
const verifyOpts: { context?:
|
|
683
|
+
const verifyOpts: { context?: Uint8Array; zip215?: boolean } = { zip215: true };
|
|
730
684
|
|
|
731
685
|
/**
|
|
732
686
|
* Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
|
733
687
|
* An extended group equation is checked.
|
|
734
688
|
*/
|
|
735
|
-
function verify(
|
|
689
|
+
function verify(
|
|
690
|
+
sig: Uint8Array,
|
|
691
|
+
msg: Uint8Array,
|
|
692
|
+
publicKey: Uint8Array,
|
|
693
|
+
options = verifyOpts
|
|
694
|
+
): boolean {
|
|
736
695
|
const { context, zip215 } = options;
|
|
737
|
-
const len = lengths.signature;
|
|
738
|
-
sig =
|
|
739
|
-
msg =
|
|
740
|
-
publicKey =
|
|
696
|
+
const len = lengths.signature;
|
|
697
|
+
sig = abytes(sig, len, 'signature');
|
|
698
|
+
msg = abytes(msg, undefined, 'message');
|
|
699
|
+
publicKey = abytes(publicKey, lengths.publicKey, 'publicKey');
|
|
741
700
|
if (zip215 !== undefined) abool(zip215, 'zip215');
|
|
742
701
|
if (prehash) msg = prehash(msg); // for ed25519ph, etc
|
|
743
702
|
|
|
@@ -751,11 +710,11 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
|
|
|
751
710
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
|
752
711
|
A = Point.fromBytes(publicKey, zip215);
|
|
753
712
|
R = Point.fromBytes(r, zip215);
|
|
754
|
-
SB =
|
|
713
|
+
SB = BASE.multiplyUnsafe(s); // 0 <= s < l is done inside
|
|
755
714
|
} catch (error) {
|
|
756
715
|
return false;
|
|
757
716
|
}
|
|
758
|
-
if (!zip215 && A.isSmallOrder()) return false;
|
|
717
|
+
if (!zip215 && A.isSmallOrder()) return false; // zip215 allows public keys of small order
|
|
759
718
|
|
|
760
719
|
const k = hashDomainToScalar(context, R.toBytes(), A.toBytes(), msg);
|
|
761
720
|
const RkA = R.add(A.multiplyUnsafe(k));
|
|
@@ -764,16 +723,14 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
|
|
|
764
723
|
return RkA.subtract(SB).clearCofactor().is0();
|
|
765
724
|
}
|
|
766
725
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
const _size = Fp.BYTES;
|
|
726
|
+
const _size = Fp.BYTES; // 32 for ed25519, 57 for ed448
|
|
770
727
|
const lengths = {
|
|
771
|
-
|
|
772
|
-
|
|
728
|
+
secretKey: _size,
|
|
729
|
+
publicKey: _size,
|
|
773
730
|
signature: 2 * _size,
|
|
774
731
|
seed: _size,
|
|
775
732
|
};
|
|
776
|
-
function randomSecretKey(seed =
|
|
733
|
+
function randomSecretKey(seed = randomBytes(lengths.seed)): Uint8Array {
|
|
777
734
|
return abytes(seed, lengths.seed, 'seed');
|
|
778
735
|
}
|
|
779
736
|
function keygen(seed?: Uint8Array) {
|
|
@@ -782,11 +739,7 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
|
|
|
782
739
|
}
|
|
783
740
|
|
|
784
741
|
function isValidSecretKey(key: Uint8Array): boolean {
|
|
785
|
-
|
|
786
|
-
return !!Fn.fromBytes(key, false);
|
|
787
|
-
} catch (error) {
|
|
788
|
-
return false;
|
|
789
|
-
}
|
|
742
|
+
return isBytes(key) && key.length === Fn.BYTES;
|
|
790
743
|
}
|
|
791
744
|
|
|
792
745
|
function isValidPublicKey(key: Uint8Array, zip215?: boolean): boolean {
|
|
@@ -810,34 +763,21 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
|
|
|
810
763
|
* - ed448:
|
|
811
764
|
* - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
|
|
812
765
|
* - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
|
|
813
|
-
*
|
|
814
|
-
* There is NO `fromMontgomery`:
|
|
815
|
-
* - There are 2 valid ed25519 points for every x25519, with flipped coordinate
|
|
816
|
-
* - Sometimes there are 0 valid ed25519 points, because x25519 *additionally*
|
|
817
|
-
* accepts inputs on the quadratic twist, which can't be moved to ed25519
|
|
818
766
|
*/
|
|
819
767
|
toMontgomery(publicKey: Uint8Array): Uint8Array {
|
|
820
768
|
const { y } = Point.fromBytes(publicKey);
|
|
821
|
-
const size = lengths.
|
|
769
|
+
const size = lengths.publicKey;
|
|
822
770
|
const is25519 = size === 32;
|
|
823
771
|
if (!is25519 && size !== 57) throw new Error('only defined for 25519 and 448');
|
|
824
772
|
const u = is25519 ? Fp.div(_1n + y, _1n - y) : Fp.div(y - _1n, y + _1n);
|
|
825
773
|
return Fp.toBytes(u);
|
|
826
774
|
},
|
|
827
|
-
|
|
828
775
|
toMontgomeryPriv(secretKey: Uint8Array): Uint8Array {
|
|
829
|
-
const size = lengths.
|
|
776
|
+
const size = lengths.secretKey;
|
|
830
777
|
abytes(secretKey, size);
|
|
831
778
|
const hashed = cHash(secretKey.subarray(0, size));
|
|
832
779
|
return adjustScalarBytes(hashed).subarray(0, size);
|
|
833
780
|
},
|
|
834
|
-
|
|
835
|
-
/** @deprecated */
|
|
836
|
-
randomPrivateKey: randomSecretKey,
|
|
837
|
-
/** @deprecated */
|
|
838
|
-
precompute(windowSize = 8, point: EdwardsPoint = Point.BASE): EdwardsPoint {
|
|
839
|
-
return point.precompute(windowSize, false);
|
|
840
|
-
},
|
|
841
781
|
};
|
|
842
782
|
|
|
843
783
|
return Object.freeze({
|
|
@@ -848,72 +788,5 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
|
|
|
848
788
|
utils,
|
|
849
789
|
Point,
|
|
850
790
|
lengths,
|
|
851
|
-
});
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
// TODO: remove everything below
|
|
855
|
-
export type CurveType = BasicCurve<bigint> & {
|
|
856
|
-
a: bigint; // curve param a
|
|
857
|
-
d: bigint; // curve param d
|
|
858
|
-
/** @deprecated the property will be removed in next release */
|
|
859
|
-
hash: FHash; // Hashing
|
|
860
|
-
randomBytes?: (bytesLength?: number) => Uint8Array; // CSPRNG
|
|
861
|
-
adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array; // clears bits to get valid field elemtn
|
|
862
|
-
domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array; // Used for hashing
|
|
863
|
-
uvRatio?: UVRatio; // Ratio √(u/v)
|
|
864
|
-
prehash?: FHash; // RFC 8032 pre-hashing of messages to sign() / verify()
|
|
865
|
-
mapToCurve?: (scalar: bigint[]) => AffinePoint<bigint>; // for hash-to-curve standard
|
|
866
|
-
};
|
|
867
|
-
export type CurveTypeWithLength = Readonly<CurveType & Partial<NLength>>;
|
|
868
|
-
export type CurveFn = {
|
|
869
|
-
/** @deprecated the property will be removed in next release */
|
|
870
|
-
CURVE: CurveType;
|
|
871
|
-
keygen: EdDSA['keygen'];
|
|
872
|
-
getPublicKey: EdDSA['getPublicKey'];
|
|
873
|
-
sign: EdDSA['sign'];
|
|
874
|
-
verify: EdDSA['verify'];
|
|
875
|
-
Point: EdwardsPointCons;
|
|
876
|
-
/** @deprecated use `Point` */
|
|
877
|
-
ExtendedPoint: EdwardsPointCons;
|
|
878
|
-
utils: EdDSA['utils'];
|
|
879
|
-
lengths: CurveLengths;
|
|
880
|
-
};
|
|
881
|
-
export type EdComposed = {
|
|
882
|
-
CURVE: EdwardsOpts;
|
|
883
|
-
curveOpts: EdwardsExtraOpts;
|
|
884
|
-
hash: FHash;
|
|
885
|
-
eddsaOpts: EdDSAOpts;
|
|
886
|
-
};
|
|
887
|
-
function _eddsa_legacy_opts_to_new(c: CurveTypeWithLength): EdComposed {
|
|
888
|
-
const CURVE: EdwardsOpts = {
|
|
889
|
-
a: c.a,
|
|
890
|
-
d: c.d,
|
|
891
|
-
p: c.Fp.ORDER,
|
|
892
|
-
n: c.n,
|
|
893
|
-
h: c.h,
|
|
894
|
-
Gx: c.Gx,
|
|
895
|
-
Gy: c.Gy,
|
|
896
|
-
};
|
|
897
|
-
const Fp = c.Fp;
|
|
898
|
-
const Fn = Field(CURVE.n, c.nBitLength, true);
|
|
899
|
-
const curveOpts: EdwardsExtraOpts = { Fp, Fn, uvRatio: c.uvRatio };
|
|
900
|
-
const eddsaOpts: EdDSAOpts = {
|
|
901
|
-
randomBytes: c.randomBytes,
|
|
902
|
-
adjustScalarBytes: c.adjustScalarBytes,
|
|
903
|
-
domain: c.domain,
|
|
904
|
-
prehash: c.prehash,
|
|
905
|
-
mapToCurve: c.mapToCurve,
|
|
906
|
-
};
|
|
907
|
-
return { CURVE, curveOpts, hash: c.hash, eddsaOpts };
|
|
908
|
-
}
|
|
909
|
-
function _eddsa_new_output_to_legacy(c: CurveTypeWithLength, eddsa: EdDSA): CurveFn {
|
|
910
|
-
const legacy = Object.assign({}, eddsa, { ExtendedPoint: eddsa.Point, CURVE: c });
|
|
911
|
-
return legacy;
|
|
912
|
-
}
|
|
913
|
-
// TODO: remove. Use eddsa
|
|
914
|
-
export function twistedEdwards(c: CurveTypeWithLength): CurveFn {
|
|
915
|
-
const { CURVE, curveOpts, hash, eddsaOpts } = _eddsa_legacy_opts_to_new(c);
|
|
916
|
-
const Point = edwards(CURVE, curveOpts);
|
|
917
|
-
const EDDSA = eddsa(Point, hash, eddsaOpts);
|
|
918
|
-
return _eddsa_new_output_to_legacy(c, EDDSA);
|
|
791
|
+
}) satisfies Signer;
|
|
919
792
|
}
|