@noble/curves 1.8.1 → 1.9.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 +305 -433
- package/_shortw_utils.d.ts +2 -2
- package/_shortw_utils.js +2 -2
- package/abstract/bls.d.ts +5 -5
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +15 -16
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +11 -3
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +81 -78
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +2 -2
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +58 -71
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +15 -9
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +49 -39
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +11 -8
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +79 -67
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +13 -12
- package/abstract/montgomery.js.map +1 -1
- package/abstract/poseidon.d.ts +40 -3
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +186 -7
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +2 -2
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +16 -17
- package/abstract/tower.js.map +1 -1
- package/abstract/utils.d.ts +5 -2
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +27 -14
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +21 -9
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +103 -86
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +1 -1
- package/bls12-381.js +41 -41
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +3 -2
- package/bn254.d.ts.map +1 -1
- package/bn254.js +39 -29
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +9 -6
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +70 -71
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +7 -6
- package/ed448.d.ts.map +1 -1
- package/ed448.js +54 -56
- package/ed448.js.map +1 -1
- package/esm/_shortw_utils.d.ts +2 -2
- package/esm/_shortw_utils.js +1 -1
- package/esm/abstract/bls.d.ts +5 -5
- package/esm/abstract/bls.d.ts.map +1 -1
- package/esm/abstract/bls.js +6 -7
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.d.ts +11 -3
- package/esm/abstract/curve.d.ts.map +1 -1
- package/esm/abstract/curve.js +77 -74
- package/esm/abstract/curve.js.map +1 -1
- package/esm/abstract/edwards.d.ts +2 -2
- package/esm/abstract/edwards.d.ts.map +1 -1
- package/esm/abstract/edwards.js +39 -52
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/hash-to-curve.d.ts +15 -9
- package/esm/abstract/hash-to-curve.d.ts.map +1 -1
- package/esm/abstract/hash-to-curve.js +33 -23
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.d.ts +11 -8
- package/esm/abstract/modular.d.ts.map +1 -1
- package/esm/abstract/modular.js +71 -59
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/montgomery.d.ts.map +1 -1
- package/esm/abstract/montgomery.js +4 -3
- package/esm/abstract/montgomery.js.map +1 -1
- package/esm/abstract/poseidon.d.ts +40 -3
- package/esm/abstract/poseidon.d.ts.map +1 -1
- package/esm/abstract/poseidon.js +180 -5
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/tower.d.ts +2 -2
- package/esm/abstract/tower.d.ts.map +1 -1
- package/esm/abstract/tower.js +8 -9
- package/esm/abstract/tower.js.map +1 -1
- package/esm/abstract/utils.d.ts +5 -2
- package/esm/abstract/utils.d.ts.map +1 -1
- package/esm/abstract/utils.js +26 -13
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.d.ts +21 -9
- package/esm/abstract/weierstrass.d.ts.map +1 -1
- package/esm/abstract/weierstrass.js +76 -59
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.d.ts +1 -1
- package/esm/bls12-381.js +9 -9
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn254.d.ts +3 -2
- package/esm/bn254.d.ts.map +1 -1
- package/esm/bn254.js +17 -7
- package/esm/bn254.js.map +1 -1
- package/esm/ed25519.d.ts +9 -6
- package/esm/ed25519.d.ts.map +1 -1
- package/esm/ed25519.js +25 -26
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.d.ts +7 -6
- package/esm/ed448.d.ts.map +1 -1
- package/esm/ed448.js +17 -19
- package/esm/ed448.js.map +1 -1
- package/esm/jubjub.d.ts +7 -4
- package/esm/jubjub.d.ts.map +1 -1
- package/esm/jubjub.js +7 -60
- package/esm/jubjub.js.map +1 -1
- package/esm/misc.d.ts +21 -0
- package/esm/misc.d.ts.map +1 -0
- package/esm/misc.js +107 -0
- package/esm/misc.js.map +1 -0
- package/esm/nist.d.ts +29 -0
- package/esm/nist.d.ts.map +1 -0
- package/esm/nist.js +120 -0
- package/esm/nist.js.map +1 -0
- package/esm/p256.d.ts +9 -8
- package/esm/p256.d.ts.map +1 -1
- package/esm/p256.js +6 -43
- package/esm/p256.js.map +1 -1
- package/esm/p384.d.ts +10 -8
- package/esm/p384.d.ts.map +1 -1
- package/esm/p384.js +7 -47
- package/esm/p384.js.map +1 -1
- package/esm/p521.d.ts +6 -6
- package/esm/p521.d.ts.map +1 -1
- package/esm/p521.js +6 -55
- package/esm/p521.js.map +1 -1
- package/esm/pasta.d.ts +5 -7
- package/esm/pasta.d.ts.map +1 -1
- package/esm/pasta.js +5 -33
- package/esm/pasta.js.map +1 -1
- package/esm/secp256k1.d.ts +15 -10
- package/esm/secp256k1.d.ts.map +1 -1
- package/esm/secp256k1.js +21 -18
- package/esm/secp256k1.js.map +1 -1
- package/jubjub.d.ts +7 -4
- package/jubjub.d.ts.map +1 -1
- package/jubjub.js +8 -63
- package/jubjub.js.map +1 -1
- package/misc.d.ts +21 -0
- package/misc.d.ts.map +1 -0
- package/misc.js +112 -0
- package/misc.js.map +1 -0
- package/nist.d.ts +29 -0
- package/nist.d.ts.map +1 -0
- package/nist.js +123 -0
- package/nist.js.map +1 -0
- package/p256.d.ts +9 -8
- package/p256.d.ts.map +1 -1
- package/p256.js +5 -48
- package/p256.js.map +1 -1
- package/p384.d.ts +10 -8
- package/p384.d.ts.map +1 -1
- package/p384.js +6 -52
- package/p384.js.map +1 -1
- package/p521.d.ts +6 -6
- package/p521.d.ts.map +1 -1
- package/p521.js +5 -60
- package/p521.js.map +1 -1
- package/package.json +116 -12
- package/pasta.d.ts +5 -7
- package/pasta.d.ts.map +1 -1
- package/pasta.js +6 -34
- package/pasta.js.map +1 -1
- package/secp256k1.d.ts +15 -10
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +60 -57
- package/secp256k1.js.map +1 -1
- package/src/_shortw_utils.ts +2 -2
- package/src/abstract/bls.ts +10 -10
- package/src/abstract/curve.ts +89 -80
- package/src/abstract/edwards.ts +56 -63
- package/src/abstract/hash-to-curve.ts +49 -39
- package/src/abstract/modular.ts +68 -59
- package/src/abstract/montgomery.ts +4 -3
- package/src/abstract/poseidon.ts +208 -13
- package/src/abstract/tower.ts +9 -10
- package/src/abstract/utils.ts +28 -15
- package/src/abstract/weierstrass.ts +105 -87
- package/src/bls12-381.ts +10 -10
- package/src/bn254.ts +18 -8
- package/src/ed25519.ts +31 -28
- package/src/ed448.ts +24 -21
- package/src/jubjub.ts +8 -63
- package/src/misc.ts +123 -0
- package/src/nist.ts +154 -0
- package/src/p256.ts +6 -49
- package/src/p384.ts +8 -53
- package/src/p521.ts +6 -70
- package/src/pasta.ts +5 -39
- package/src/secp256k1.ts +25 -20
package/abstract/weierstrass.js
CHANGED
|
@@ -8,6 +8,19 @@ exports.mapToCurveSimpleSWU = mapToCurveSimpleSWU;
|
|
|
8
8
|
/**
|
|
9
9
|
* Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
|
|
10
10
|
*
|
|
11
|
+
* ### Parameters
|
|
12
|
+
*
|
|
13
|
+
* To initialize a weierstrass curve, one needs to pass following params:
|
|
14
|
+
*
|
|
15
|
+
* * a: formula param
|
|
16
|
+
* * b: formula param
|
|
17
|
+
* * Fp: finite Field over which we'll do calculations. Can be complex (Fp2, Fp12)
|
|
18
|
+
* * n: Curve prime subgroup order, total count of valid points in the field
|
|
19
|
+
* * Gx: Base point (x, y) aka generator point x coordinate
|
|
20
|
+
* * Gy: ...y coordinate
|
|
21
|
+
* * h: cofactor, usually 1. h*n = curve group order (n is only subgroup order)
|
|
22
|
+
* * lowS: whether to enable (default) or disable "low-s" non-malleable signatures
|
|
23
|
+
*
|
|
11
24
|
* ### Design rationale for types
|
|
12
25
|
*
|
|
13
26
|
* * Interaction between classes from different curves should fail:
|
|
@@ -32,19 +45,21 @@ exports.mapToCurveSimpleSWU = mapToCurveSimpleSWU;
|
|
|
32
45
|
* @module
|
|
33
46
|
*/
|
|
34
47
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
const
|
|
48
|
+
// prettier-ignore
|
|
49
|
+
const curve_ts_1 = require("./curve.js");
|
|
50
|
+
// prettier-ignore
|
|
51
|
+
const modular_ts_1 = require("./modular.js");
|
|
52
|
+
// prettier-ignore
|
|
53
|
+
const utils_ts_1 = require("./utils.js");
|
|
39
54
|
function validateSigVerOpts(opts) {
|
|
40
55
|
if (opts.lowS !== undefined)
|
|
41
|
-
(0,
|
|
56
|
+
(0, utils_ts_1.abool)('lowS', opts.lowS);
|
|
42
57
|
if (opts.prehash !== undefined)
|
|
43
|
-
(0,
|
|
58
|
+
(0, utils_ts_1.abool)('prehash', opts.prehash);
|
|
44
59
|
}
|
|
45
60
|
function validatePointOpts(curve) {
|
|
46
|
-
const opts = (0,
|
|
47
|
-
|
|
61
|
+
const opts = (0, curve_ts_1.validateBasic)(curve);
|
|
62
|
+
(0, utils_ts_1.validateObject)(opts, {
|
|
48
63
|
a: 'field',
|
|
49
64
|
b: 'field',
|
|
50
65
|
}, {
|
|
@@ -69,7 +84,6 @@ function validatePointOpts(curve) {
|
|
|
69
84
|
}
|
|
70
85
|
return Object.freeze({ ...opts });
|
|
71
86
|
}
|
|
72
|
-
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
|
73
87
|
class DERErr extends Error {
|
|
74
88
|
constructor(m = '') {
|
|
75
89
|
super(m);
|
|
@@ -95,12 +109,12 @@ exports.DER = {
|
|
|
95
109
|
if (data.length & 1)
|
|
96
110
|
throw new E('tlv.encode: unpadded data');
|
|
97
111
|
const dataLen = data.length / 2;
|
|
98
|
-
const len =
|
|
112
|
+
const len = (0, utils_ts_1.numberToHexUnpadded)(dataLen);
|
|
99
113
|
if ((len.length / 2) & 128)
|
|
100
114
|
throw new E('tlv.encode: long form length too big');
|
|
101
115
|
// length of length with long form flag
|
|
102
|
-
const lenLen = dataLen > 127 ?
|
|
103
|
-
const t =
|
|
116
|
+
const lenLen = dataLen > 127 ? (0, utils_ts_1.numberToHexUnpadded)((len.length / 2) | 128) : '';
|
|
117
|
+
const t = (0, utils_ts_1.numberToHexUnpadded)(tag);
|
|
104
118
|
return t + lenLen + len + data;
|
|
105
119
|
},
|
|
106
120
|
// v - value, l - left bytes (unparsed)
|
|
@@ -149,7 +163,7 @@ exports.DER = {
|
|
|
149
163
|
const { Err: E } = exports.DER;
|
|
150
164
|
if (num < _0n)
|
|
151
165
|
throw new E('integer: negative integers are not allowed');
|
|
152
|
-
let hex =
|
|
166
|
+
let hex = (0, utils_ts_1.numberToHexUnpadded)(num);
|
|
153
167
|
// Pad with zero byte if negative flag is present
|
|
154
168
|
if (Number.parseInt(hex[0], 16) & 0b1000)
|
|
155
169
|
hex = '00' + hex;
|
|
@@ -163,14 +177,13 @@ exports.DER = {
|
|
|
163
177
|
throw new E('invalid signature integer: negative');
|
|
164
178
|
if (data[0] === 0x00 && !(data[1] & 128))
|
|
165
179
|
throw new E('invalid signature integer: unnecessary leading zero');
|
|
166
|
-
return
|
|
180
|
+
return (0, utils_ts_1.bytesToNumberBE)(data);
|
|
167
181
|
},
|
|
168
182
|
},
|
|
169
183
|
toSig(hex) {
|
|
170
184
|
// parse DER signature
|
|
171
185
|
const { Err: E, _int: int, _tlv: tlv } = exports.DER;
|
|
172
|
-
const data =
|
|
173
|
-
ut.abytes(data);
|
|
186
|
+
const data = (0, utils_ts_1.ensureBytes)('signature', hex);
|
|
174
187
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
|
175
188
|
if (seqLeftBytes.length)
|
|
176
189
|
throw new E('invalid signature: left bytes after parsing');
|
|
@@ -194,11 +207,11 @@ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n =
|
|
|
194
207
|
function weierstrassPoints(opts) {
|
|
195
208
|
const CURVE = validatePointOpts(opts);
|
|
196
209
|
const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
|
|
197
|
-
const Fn = (0,
|
|
210
|
+
const Fn = (0, modular_ts_1.Field)(CURVE.n, CURVE.nBitLength);
|
|
198
211
|
const toBytes = CURVE.toBytes ||
|
|
199
212
|
((_c, point, _isCompressed) => {
|
|
200
213
|
const a = point.toAffine();
|
|
201
|
-
return
|
|
214
|
+
return (0, utils_ts_1.concatBytes)(Uint8Array.from([0x04]), Fp.toBytes(a.x), Fp.toBytes(a.y));
|
|
202
215
|
});
|
|
203
216
|
const fromBytes = CURVE.fromBytes ||
|
|
204
217
|
((bytes) => {
|
|
@@ -210,7 +223,7 @@ function weierstrassPoints(opts) {
|
|
|
210
223
|
return { x, y };
|
|
211
224
|
});
|
|
212
225
|
/**
|
|
213
|
-
* y² = x³ + ax + b: Short weierstrass curve formula
|
|
226
|
+
* y² = x³ + ax + b: Short weierstrass curve formula. Takes x, returns y².
|
|
214
227
|
* @returns y²
|
|
215
228
|
*/
|
|
216
229
|
function weierstrassEquation(x) {
|
|
@@ -227,15 +240,15 @@ function weierstrassPoints(opts) {
|
|
|
227
240
|
throw new Error('bad generator point: equation left != right');
|
|
228
241
|
// Valid group elements reside in range 1..n-1
|
|
229
242
|
function isWithinCurveOrder(num) {
|
|
230
|
-
return
|
|
243
|
+
return (0, utils_ts_1.inRange)(num, _1n, CURVE.n);
|
|
231
244
|
}
|
|
232
245
|
// Validates if priv key is valid and converts it to bigint.
|
|
233
246
|
// Supports options allowedPrivateKeyLengths and wrapPrivateKey.
|
|
234
247
|
function normPrivateKeyToScalar(key) {
|
|
235
248
|
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
|
|
236
249
|
if (lengths && typeof key !== 'bigint') {
|
|
237
|
-
if (
|
|
238
|
-
key =
|
|
250
|
+
if ((0, utils_ts_1.isBytes)(key))
|
|
251
|
+
key = (0, utils_ts_1.bytesToHex)(key);
|
|
239
252
|
// Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
|
|
240
253
|
if (typeof key !== 'string' || !lengths.includes(key.length))
|
|
241
254
|
throw new Error('invalid private key');
|
|
@@ -246,17 +259,17 @@ function weierstrassPoints(opts) {
|
|
|
246
259
|
num =
|
|
247
260
|
typeof key === 'bigint'
|
|
248
261
|
? key
|
|
249
|
-
:
|
|
262
|
+
: (0, utils_ts_1.bytesToNumberBE)((0, utils_ts_1.ensureBytes)('private key', key, nByteLength));
|
|
250
263
|
}
|
|
251
264
|
catch (error) {
|
|
252
265
|
throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
|
|
253
266
|
}
|
|
254
267
|
if (wrapPrivateKey)
|
|
255
|
-
num = (0,
|
|
256
|
-
|
|
268
|
+
num = (0, modular_ts_1.mod)(num, N); // disabled by default, enabled for BLS
|
|
269
|
+
(0, utils_ts_1.aInRange)('private key', num, _1n, N); // num in range [1..N-1]
|
|
257
270
|
return num;
|
|
258
271
|
}
|
|
259
|
-
function
|
|
272
|
+
function aprjpoint(other) {
|
|
260
273
|
if (!(other instanceof Point))
|
|
261
274
|
throw new Error('ProjectivePoint expected');
|
|
262
275
|
}
|
|
@@ -264,7 +277,7 @@ function weierstrassPoints(opts) {
|
|
|
264
277
|
// Converts Projective point to affine (x, y) coordinates.
|
|
265
278
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
|
266
279
|
// (x, y, z) ∋ (x=x/z, y=y/z)
|
|
267
|
-
const toAffineMemo = (0,
|
|
280
|
+
const toAffineMemo = (0, utils_ts_1.memoized)((p, iz) => {
|
|
268
281
|
const { px: x, py: y, pz: z } = p;
|
|
269
282
|
// Fast-path for normalized points
|
|
270
283
|
if (Fp.eql(z, Fp.ONE))
|
|
@@ -285,7 +298,7 @@ function weierstrassPoints(opts) {
|
|
|
285
298
|
});
|
|
286
299
|
// NOTE: on exception this will crash 'cached' and no value will be set.
|
|
287
300
|
// Otherwise true will be return
|
|
288
|
-
const assertValidMemo = (0,
|
|
301
|
+
const assertValidMemo = (0, utils_ts_1.memoized)((p) => {
|
|
289
302
|
if (p.is0()) {
|
|
290
303
|
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
|
291
304
|
// In BLS, ZERO can be serialized, so we allow it.
|
|
@@ -314,15 +327,15 @@ function weierstrassPoints(opts) {
|
|
|
314
327
|
*/
|
|
315
328
|
class Point {
|
|
316
329
|
constructor(px, py, pz) {
|
|
317
|
-
this.px = px;
|
|
318
|
-
this.py = py;
|
|
319
|
-
this.pz = pz;
|
|
320
330
|
if (px == null || !Fp.isValid(px))
|
|
321
331
|
throw new Error('x required');
|
|
322
|
-
if (py == null || !Fp.isValid(py))
|
|
332
|
+
if (py == null || !Fp.isValid(py) || Fp.is0(py))
|
|
323
333
|
throw new Error('y required');
|
|
324
334
|
if (pz == null || !Fp.isValid(pz))
|
|
325
335
|
throw new Error('z required');
|
|
336
|
+
this.px = px;
|
|
337
|
+
this.py = py;
|
|
338
|
+
this.pz = pz;
|
|
326
339
|
Object.freeze(this);
|
|
327
340
|
}
|
|
328
341
|
// Does not validate if the point is on-curve.
|
|
@@ -352,7 +365,7 @@ function weierstrassPoints(opts) {
|
|
|
352
365
|
* Optimization: converts a list of projective points to a list of identical points with Z=1.
|
|
353
366
|
*/
|
|
354
367
|
static normalizeZ(points) {
|
|
355
|
-
const toInv =
|
|
368
|
+
const toInv = (0, modular_ts_1.FpInvertBatch)(Fp, points.map((p) => p.pz));
|
|
356
369
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
|
357
370
|
}
|
|
358
371
|
/**
|
|
@@ -360,7 +373,7 @@ function weierstrassPoints(opts) {
|
|
|
360
373
|
* @param hex short/long ECDSA hex
|
|
361
374
|
*/
|
|
362
375
|
static fromHex(hex) {
|
|
363
|
-
const P = Point.fromAffine(fromBytes((0,
|
|
376
|
+
const P = Point.fromAffine(fromBytes((0, utils_ts_1.ensureBytes)('pointHex', hex)));
|
|
364
377
|
P.assertValidity();
|
|
365
378
|
return P;
|
|
366
379
|
}
|
|
@@ -370,7 +383,7 @@ function weierstrassPoints(opts) {
|
|
|
370
383
|
}
|
|
371
384
|
// Multiscalar Multiplication
|
|
372
385
|
static msm(points, scalars) {
|
|
373
|
-
return (0,
|
|
386
|
+
return (0, curve_ts_1.pippenger)(Point, Fn, points, scalars);
|
|
374
387
|
}
|
|
375
388
|
// "Private method", don't use it directly
|
|
376
389
|
_setWindowSize(windowSize) {
|
|
@@ -390,7 +403,7 @@ function weierstrassPoints(opts) {
|
|
|
390
403
|
* Compare one point to another.
|
|
391
404
|
*/
|
|
392
405
|
equals(other) {
|
|
393
|
-
|
|
406
|
+
aprjpoint(other);
|
|
394
407
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
395
408
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
|
396
409
|
const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
|
@@ -450,7 +463,7 @@ function weierstrassPoints(opts) {
|
|
|
450
463
|
// https://eprint.iacr.org/2015/1060, algorithm 1
|
|
451
464
|
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
|
452
465
|
add(other) {
|
|
453
|
-
|
|
466
|
+
aprjpoint(other);
|
|
454
467
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
455
468
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
|
456
469
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
|
@@ -514,7 +527,7 @@ function weierstrassPoints(opts) {
|
|
|
514
527
|
*/
|
|
515
528
|
multiplyUnsafe(sc) {
|
|
516
529
|
const { endo, n: N } = CURVE;
|
|
517
|
-
|
|
530
|
+
(0, utils_ts_1.aInRange)('scalar', sc, _0n, N);
|
|
518
531
|
const I = Point.ZERO;
|
|
519
532
|
if (sc === _0n)
|
|
520
533
|
return I;
|
|
@@ -555,7 +568,7 @@ function weierstrassPoints(opts) {
|
|
|
555
568
|
*/
|
|
556
569
|
multiply(scalar) {
|
|
557
570
|
const { endo, n: N } = CURVE;
|
|
558
|
-
|
|
571
|
+
(0, utils_ts_1.aInRange)('scalar', scalar, _1n, N);
|
|
559
572
|
let point, fake; // Fake point is used to const-time mult
|
|
560
573
|
if (endo) {
|
|
561
574
|
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
|
|
@@ -611,20 +624,19 @@ function weierstrassPoints(opts) {
|
|
|
611
624
|
return this.multiplyUnsafe(CURVE.h);
|
|
612
625
|
}
|
|
613
626
|
toRawBytes(isCompressed = true) {
|
|
614
|
-
(0,
|
|
627
|
+
(0, utils_ts_1.abool)('isCompressed', isCompressed);
|
|
615
628
|
this.assertValidity();
|
|
616
629
|
return toBytes(Point, this, isCompressed);
|
|
617
630
|
}
|
|
618
631
|
toHex(isCompressed = true) {
|
|
619
|
-
(0,
|
|
620
|
-
return
|
|
632
|
+
(0, utils_ts_1.abool)('isCompressed', isCompressed);
|
|
633
|
+
return (0, utils_ts_1.bytesToHex)(this.toRawBytes(isCompressed));
|
|
621
634
|
}
|
|
622
635
|
}
|
|
623
636
|
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
|
624
|
-
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
|
637
|
+
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO); // 0, 1, 0
|
|
625
638
|
const _bits = CURVE.nBitLength;
|
|
626
|
-
const wnaf = (0,
|
|
627
|
-
// Validate if generator point is on curve
|
|
639
|
+
const wnaf = (0, curve_ts_1.wNAF)(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
|
628
640
|
return {
|
|
629
641
|
CURVE,
|
|
630
642
|
ProjectivePoint: Point,
|
|
@@ -634,8 +646,8 @@ function weierstrassPoints(opts) {
|
|
|
634
646
|
};
|
|
635
647
|
}
|
|
636
648
|
function validateOpts(curve) {
|
|
637
|
-
const opts = (0,
|
|
638
|
-
|
|
649
|
+
const opts = (0, curve_ts_1.validateBasic)(curve);
|
|
650
|
+
(0, utils_ts_1.validateObject)(opts, {
|
|
639
651
|
hash: 'hash',
|
|
640
652
|
hmac: 'function',
|
|
641
653
|
randomBytes: 'function',
|
|
@@ -659,18 +671,18 @@ function weierstrass(curveDef) {
|
|
|
659
671
|
const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
|
|
660
672
|
const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
|
|
661
673
|
function modN(a) {
|
|
662
|
-
return (0,
|
|
674
|
+
return (0, modular_ts_1.mod)(a, CURVE_ORDER);
|
|
663
675
|
}
|
|
664
676
|
function invN(a) {
|
|
665
|
-
return (0,
|
|
677
|
+
return (0, modular_ts_1.invert)(a, CURVE_ORDER);
|
|
666
678
|
}
|
|
667
679
|
const { ProjectivePoint: Point, normPrivateKeyToScalar, weierstrassEquation, isWithinCurveOrder, } = weierstrassPoints({
|
|
668
680
|
...CURVE,
|
|
669
681
|
toBytes(_c, point, isCompressed) {
|
|
670
682
|
const a = point.toAffine();
|
|
671
683
|
const x = Fp.toBytes(a.x);
|
|
672
|
-
const cat =
|
|
673
|
-
(0,
|
|
684
|
+
const cat = utils_ts_1.concatBytes;
|
|
685
|
+
(0, utils_ts_1.abool)('isCompressed', isCompressed);
|
|
674
686
|
if (isCompressed) {
|
|
675
687
|
return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
|
|
676
688
|
}
|
|
@@ -684,8 +696,8 @@ function weierstrass(curveDef) {
|
|
|
684
696
|
const tail = bytes.subarray(1);
|
|
685
697
|
// this.assertValidity() is done inside of fromHex
|
|
686
698
|
if (len === compressedLen && (head === 0x02 || head === 0x03)) {
|
|
687
|
-
const x =
|
|
688
|
-
if (!
|
|
699
|
+
const x = (0, utils_ts_1.bytesToNumberBE)(tail);
|
|
700
|
+
if (!(0, utils_ts_1.inRange)(x, _1n, Fp.ORDER))
|
|
689
701
|
throw new Error('Point is not on curve');
|
|
690
702
|
const y2 = weierstrassEquation(x); // y² = x³ + ax + b
|
|
691
703
|
let y;
|
|
@@ -715,7 +727,7 @@ function weierstrass(curveDef) {
|
|
|
715
727
|
}
|
|
716
728
|
},
|
|
717
729
|
});
|
|
718
|
-
const
|
|
730
|
+
const numToNByteHex = (num) => (0, utils_ts_1.bytesToHex)((0, utils_ts_1.numberToBytesBE)(num, CURVE.nByteLength));
|
|
719
731
|
function isBiggerThanHalfOrder(number) {
|
|
720
732
|
const HALF = CURVE_ORDER >> _1n;
|
|
721
733
|
return number > HALF;
|
|
@@ -724,46 +736,50 @@ function weierstrass(curveDef) {
|
|
|
724
736
|
return isBiggerThanHalfOrder(s) ? modN(-s) : s;
|
|
725
737
|
}
|
|
726
738
|
// slice bytes num
|
|
727
|
-
const slcNum = (b, from, to) =>
|
|
739
|
+
const slcNum = (b, from, to) => (0, utils_ts_1.bytesToNumberBE)(b.slice(from, to));
|
|
728
740
|
/**
|
|
729
741
|
* ECDSA signature with its (r, s) properties. Supports DER & compact representations.
|
|
730
742
|
*/
|
|
731
743
|
class Signature {
|
|
732
744
|
constructor(r, s, recovery) {
|
|
745
|
+
(0, utils_ts_1.aInRange)('r', r, _1n, CURVE_ORDER); // r in [1..N]
|
|
746
|
+
(0, utils_ts_1.aInRange)('s', s, _1n, CURVE_ORDER); // s in [1..N]
|
|
733
747
|
this.r = r;
|
|
734
748
|
this.s = s;
|
|
735
|
-
|
|
736
|
-
|
|
749
|
+
if (recovery != null)
|
|
750
|
+
this.recovery = recovery;
|
|
751
|
+
Object.freeze(this);
|
|
737
752
|
}
|
|
738
753
|
// pair (bytes of r, bytes of s)
|
|
739
754
|
static fromCompact(hex) {
|
|
740
755
|
const l = CURVE.nByteLength;
|
|
741
|
-
hex = (0,
|
|
756
|
+
hex = (0, utils_ts_1.ensureBytes)('compactSignature', hex, l * 2);
|
|
742
757
|
return new Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));
|
|
743
758
|
}
|
|
744
759
|
// DER encoded ECDSA signature
|
|
745
760
|
// https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script
|
|
746
761
|
static fromDER(hex) {
|
|
747
|
-
const { r, s } = exports.DER.toSig((0,
|
|
762
|
+
const { r, s } = exports.DER.toSig((0, utils_ts_1.ensureBytes)('DER', hex));
|
|
748
763
|
return new Signature(r, s);
|
|
749
764
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
765
|
+
/**
|
|
766
|
+
* @todo remove
|
|
767
|
+
* @deprecated
|
|
768
|
+
*/
|
|
769
|
+
assertValidity() { }
|
|
754
770
|
addRecoveryBit(recovery) {
|
|
755
771
|
return new Signature(this.r, this.s, recovery);
|
|
756
772
|
}
|
|
757
773
|
recoverPublicKey(msgHash) {
|
|
758
774
|
const { r, s, recovery: rec } = this;
|
|
759
|
-
const h = bits2int_modN((0,
|
|
775
|
+
const h = bits2int_modN((0, utils_ts_1.ensureBytes)('msgHash', msgHash)); // Truncate hash
|
|
760
776
|
if (rec == null || ![0, 1, 2, 3].includes(rec))
|
|
761
777
|
throw new Error('recovery id invalid');
|
|
762
778
|
const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;
|
|
763
779
|
if (radj >= Fp.ORDER)
|
|
764
780
|
throw new Error('recovery id 2 or 3 invalid');
|
|
765
781
|
const prefix = (rec & 1) === 0 ? '02' : '03';
|
|
766
|
-
const R = Point.fromHex(prefix +
|
|
782
|
+
const R = Point.fromHex(prefix + numToNByteHex(radj));
|
|
767
783
|
const ir = invN(radj); // r^-1
|
|
768
784
|
const u1 = modN(-h * ir); // -hr^-1
|
|
769
785
|
const u2 = modN(s * ir); // sr^-1
|
|
@@ -782,17 +798,17 @@ function weierstrass(curveDef) {
|
|
|
782
798
|
}
|
|
783
799
|
// DER-encoded
|
|
784
800
|
toDERRawBytes() {
|
|
785
|
-
return
|
|
801
|
+
return (0, utils_ts_1.hexToBytes)(this.toDERHex());
|
|
786
802
|
}
|
|
787
803
|
toDERHex() {
|
|
788
|
-
return exports.DER.hexFromSig(
|
|
804
|
+
return exports.DER.hexFromSig(this);
|
|
789
805
|
}
|
|
790
806
|
// padded bytes of r, then padded bytes of s
|
|
791
807
|
toCompactRawBytes() {
|
|
792
|
-
return
|
|
808
|
+
return (0, utils_ts_1.hexToBytes)(this.toCompactHex());
|
|
793
809
|
}
|
|
794
810
|
toCompactHex() {
|
|
795
|
-
return
|
|
811
|
+
return numToNByteHex(this.r) + numToNByteHex(this.s);
|
|
796
812
|
}
|
|
797
813
|
}
|
|
798
814
|
const utils = {
|
|
@@ -811,8 +827,8 @@ function weierstrass(curveDef) {
|
|
|
811
827
|
* (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.
|
|
812
828
|
*/
|
|
813
829
|
randomPrivateKey: () => {
|
|
814
|
-
const length = (0,
|
|
815
|
-
return (0,
|
|
830
|
+
const length = (0, modular_ts_1.getMinHashLength)(CURVE.n);
|
|
831
|
+
return (0, modular_ts_1.mapHashToField)(CURVE.randomBytes(length), CURVE.n);
|
|
816
832
|
},
|
|
817
833
|
/**
|
|
818
834
|
* Creates precompute table for an arbitrary EC point. Makes point "cached".
|
|
@@ -841,7 +857,7 @@ function weierstrass(curveDef) {
|
|
|
841
857
|
* Quick and dirty check for item being public key. Does not validate hex, or being on-curve.
|
|
842
858
|
*/
|
|
843
859
|
function isProbPub(item) {
|
|
844
|
-
const arr =
|
|
860
|
+
const arr = (0, utils_ts_1.isBytes)(item);
|
|
845
861
|
const str = typeof item === 'string';
|
|
846
862
|
const len = (arr || str) && item.length;
|
|
847
863
|
if (arr)
|
|
@@ -881,7 +897,7 @@ function weierstrass(curveDef) {
|
|
|
881
897
|
throw new Error('input is too large');
|
|
882
898
|
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
|
883
899
|
// for some cases, since bytes.length * 8 is not actual bitLength.
|
|
884
|
-
const num =
|
|
900
|
+
const num = (0, utils_ts_1.bytesToNumberBE)(bytes); // check for == u8 done here
|
|
885
901
|
const delta = bytes.length * 8 - CURVE.nBitLength; // truncate to nBitLength leftmost bits
|
|
886
902
|
return delta > 0 ? num >> BigInt(delta) : num;
|
|
887
903
|
};
|
|
@@ -890,14 +906,14 @@ function weierstrass(curveDef) {
|
|
|
890
906
|
return modN(bits2int(bytes)); // can't use bytesToNumberBE here
|
|
891
907
|
};
|
|
892
908
|
// NOTE: pads output with zero as per spec
|
|
893
|
-
const ORDER_MASK =
|
|
909
|
+
const ORDER_MASK = (0, utils_ts_1.bitMask)(CURVE.nBitLength);
|
|
894
910
|
/**
|
|
895
911
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
|
896
912
|
*/
|
|
897
913
|
function int2octets(num) {
|
|
898
|
-
|
|
914
|
+
(0, utils_ts_1.aInRange)('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
|
|
899
915
|
// works with order, can have different size than numToField!
|
|
900
|
-
return
|
|
916
|
+
return (0, utils_ts_1.numberToBytesBE)(num, CURVE.nByteLength);
|
|
901
917
|
}
|
|
902
918
|
// Steps A, D of RFC6979 3.2
|
|
903
919
|
// Creates RFC6979 seed; converts msg/privKey to numbers.
|
|
@@ -911,10 +927,10 @@ function weierstrass(curveDef) {
|
|
|
911
927
|
let { lowS, prehash, extraEntropy: ent } = opts; // generates low-s sigs by default
|
|
912
928
|
if (lowS == null)
|
|
913
929
|
lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
|
|
914
|
-
msgHash = (0,
|
|
930
|
+
msgHash = (0, utils_ts_1.ensureBytes)('msgHash', msgHash);
|
|
915
931
|
validateSigVerOpts(opts);
|
|
916
932
|
if (prehash)
|
|
917
|
-
msgHash = (0,
|
|
933
|
+
msgHash = (0, utils_ts_1.ensureBytes)('prehashed msgHash', hash(msgHash));
|
|
918
934
|
// We can't later call bits2octets, since nested bits2int is broken for curves
|
|
919
935
|
// with nBitLength % 8 !== 0. Because of that, we unwrap it here as int2octets call.
|
|
920
936
|
// const bits2octets = (bits) => int2octets(bits2int_modN(bits))
|
|
@@ -925,9 +941,9 @@ function weierstrass(curveDef) {
|
|
|
925
941
|
if (ent != null && ent !== false) {
|
|
926
942
|
// K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
|
|
927
943
|
const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is
|
|
928
|
-
seedArgs.push((0,
|
|
944
|
+
seedArgs.push((0, utils_ts_1.ensureBytes)('extraEntropy', e)); // check for being bytes
|
|
929
945
|
}
|
|
930
|
-
const seed =
|
|
946
|
+
const seed = (0, utils_ts_1.concatBytes)(...seedArgs); // Step D of RFC6979 3.2
|
|
931
947
|
const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!
|
|
932
948
|
// Converts signature params into point w r/s, checks result for validity.
|
|
933
949
|
function k2sig(kBytes) {
|
|
@@ -974,7 +990,7 @@ function weierstrass(curveDef) {
|
|
|
974
990
|
function sign(msgHash, privKey, opts = defaultSigOpts) {
|
|
975
991
|
const { seed, k2sig } = prepSig(msgHash, privKey, opts); // Steps A, D of RFC6979 3.2.
|
|
976
992
|
const C = CURVE;
|
|
977
|
-
const drbg =
|
|
993
|
+
const drbg = (0, utils_ts_1.createHmacDrbg)(C.hash.outputLen, C.nByteLength, C.hmac);
|
|
978
994
|
return drbg(seed, k2sig); // Steps B, C, D, E, F, G
|
|
979
995
|
}
|
|
980
996
|
// Enable precomputes. Slows down first publicKey computation by 20ms.
|
|
@@ -995,8 +1011,8 @@ function weierstrass(curveDef) {
|
|
|
995
1011
|
*/
|
|
996
1012
|
function verify(signature, msgHash, publicKey, opts = defaultVerOpts) {
|
|
997
1013
|
const sg = signature;
|
|
998
|
-
msgHash = (0,
|
|
999
|
-
publicKey = (0,
|
|
1014
|
+
msgHash = (0, utils_ts_1.ensureBytes)('msgHash', msgHash);
|
|
1015
|
+
publicKey = (0, utils_ts_1.ensureBytes)('publicKey', publicKey);
|
|
1000
1016
|
const { lowS, prehash, format } = opts;
|
|
1001
1017
|
// Verify opts, deduce signature format
|
|
1002
1018
|
validateSigVerOpts(opts);
|
|
@@ -1004,7 +1020,7 @@ function weierstrass(curveDef) {
|
|
|
1004
1020
|
throw new Error('options.strict was renamed to lowS');
|
|
1005
1021
|
if (format !== undefined && format !== 'compact' && format !== 'der')
|
|
1006
1022
|
throw new Error('format must be compact or der');
|
|
1007
|
-
const isHex = typeof sg === 'string' ||
|
|
1023
|
+
const isHex = typeof sg === 'string' || (0, utils_ts_1.isBytes)(sg);
|
|
1008
1024
|
const isObj = !isHex &&
|
|
1009
1025
|
!format &&
|
|
1010
1026
|
typeof sg === 'object' &&
|
|
@@ -1148,7 +1164,7 @@ function SWUFpSqrtRatio(Fp, Z) {
|
|
|
1148
1164
|
* https://www.rfc-editor.org/rfc/rfc9380#section-6.6.2
|
|
1149
1165
|
*/
|
|
1150
1166
|
function mapToCurveSimpleSWU(Fp, opts) {
|
|
1151
|
-
(0,
|
|
1167
|
+
(0, modular_ts_1.validateField)(Fp);
|
|
1152
1168
|
if (!Fp.isValid(opts.A) || !Fp.isValid(opts.B) || !Fp.isValid(opts.Z))
|
|
1153
1169
|
throw new Error('mapToCurveSimpleSWU: invalid opts');
|
|
1154
1170
|
const sqrtRatio = SWUFpSqrtRatio(Fp, opts.Z);
|
|
@@ -1183,7 +1199,8 @@ function mapToCurveSimpleSWU(Fp, opts) {
|
|
|
1183
1199
|
y = Fp.cmov(y, value, isValid); // 22. y = CMOV(y, y1, is_gx1_square)
|
|
1184
1200
|
const e1 = Fp.isOdd(u) === Fp.isOdd(y); // 23. e1 = sgn0(u) == sgn0(y)
|
|
1185
1201
|
y = Fp.cmov(Fp.neg(y), y, e1); // 24. y = CMOV(-y, y, e1)
|
|
1186
|
-
|
|
1202
|
+
const tv4_inv = (0, modular_ts_1.FpInvertBatch)(Fp, [tv4], true)[0];
|
|
1203
|
+
x = Fp.mul(x, tv4_inv); // 25. x = x / tv4
|
|
1187
1204
|
return { x, y };
|
|
1188
1205
|
};
|
|
1189
1206
|
}
|