@noble/curves 1.8.0 → 1.8.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 +282 -419
- package/_shortw_utils.d.ts +2 -2
- package/_shortw_utils.d.ts.map +1 -1
- package/_shortw_utils.js +2 -2
- package/_shortw_utils.js.map +1 -1
- package/abstract/bls.d.ts +5 -5
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +14 -15
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +10 -2
- 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 +55 -69
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +5 -4
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +20 -18
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +9 -9
- package/abstract/montgomery.js +12 -12
- package/abstract/poseidon.d.ts +1 -1
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +3 -3
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +2 -2
- package/abstract/tower.js +13 -13
- package/abstract/utils.d.ts +4 -2
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +25 -14
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +19 -6
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +97 -80
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +1 -1
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +48 -49
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +2 -2
- package/bn254.d.ts.map +1 -1
- package/bn254.js +29 -30
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +8 -6
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +65 -66
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +6 -6
- package/ed448.d.ts.map +1 -1
- package/ed448.js +50 -52
- package/ed448.js.map +1 -1
- package/esm/_shortw_utils.d.ts +2 -2
- package/esm/_shortw_utils.d.ts.map +1 -1
- package/esm/_shortw_utils.js +1 -1
- package/esm/_shortw_utils.js.map +1 -1
- package/esm/abstract/bls.d.ts +5 -5
- package/esm/abstract/bls.d.ts.map +1 -1
- package/esm/abstract/bls.js +5 -6
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.d.ts +10 -2
- 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 +36 -50
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/hash-to-curve.d.ts +5 -4
- package/esm/abstract/hash-to-curve.d.ts.map +1 -1
- package/esm/abstract/hash-to-curve.js +4 -2
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.d.ts.map +1 -1
- package/esm/abstract/modular.js +1 -1
- package/esm/abstract/montgomery.js +2 -2
- package/esm/abstract/poseidon.d.ts +1 -1
- package/esm/abstract/poseidon.d.ts.map +1 -1
- package/esm/abstract/poseidon.js +1 -1
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/tower.d.ts +2 -2
- package/esm/abstract/tower.js +5 -5
- package/esm/abstract/utils.d.ts +4 -2
- package/esm/abstract/utils.d.ts.map +1 -1
- package/esm/abstract/utils.js +24 -13
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.d.ts +19 -6
- package/esm/abstract/weierstrass.d.ts.map +1 -1
- package/esm/abstract/weierstrass.js +77 -60
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.d.ts +1 -1
- package/esm/bls12-381.d.ts.map +1 -1
- package/esm/bls12-381.js +16 -17
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn254.d.ts +2 -2
- package/esm/bn254.d.ts.map +1 -1
- package/esm/bn254.js +7 -8
- package/esm/bn254.js.map +1 -1
- package/esm/ed25519.d.ts +8 -6
- package/esm/ed25519.d.ts.map +1 -1
- package/esm/ed25519.js +20 -21
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.d.ts +6 -6
- package/esm/ed448.d.ts.map +1 -1
- package/esm/ed448.js +13 -15
- package/esm/ed448.js.map +1 -1
- package/esm/index.js +13 -1
- package/esm/index.js.map +1 -1
- package/esm/jubjub.d.ts +1 -4
- package/esm/jubjub.d.ts.map +1 -1
- package/esm/jubjub.js +1 -60
- package/esm/jubjub.js.map +1 -1
- package/esm/misc.d.ts +15 -0
- package/esm/misc.d.ts.map +1 -0
- package/esm/misc.js +101 -0
- package/esm/misc.js.map +1 -0
- package/esm/p256.d.ts +8 -5
- package/esm/p256.d.ts.map +1 -1
- package/esm/p256.js +13 -12
- package/esm/p256.js.map +1 -1
- package/esm/p384.d.ts +8 -5
- package/esm/p384.d.ts.map +1 -1
- package/esm/p384.js +14 -15
- package/esm/p384.js.map +1 -1
- package/esm/p521.d.ts +6 -5
- package/esm/p521.d.ts.map +1 -1
- package/esm/p521.js +19 -28
- package/esm/p521.js.map +1 -1
- package/esm/pasta.d.ts +1 -7
- package/esm/pasta.d.ts.map +1 -1
- package/esm/pasta.js +1 -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 +18 -14
- package/esm/secp256k1.js.map +1 -1
- package/index.js +13 -1
- package/index.js.map +1 -1
- package/jubjub.d.ts +1 -4
- package/jubjub.d.ts.map +1 -1
- package/jubjub.js +5 -63
- package/jubjub.js.map +1 -1
- package/misc.d.ts +15 -0
- package/misc.d.ts.map +1 -0
- package/misc.js +106 -0
- package/misc.js.map +1 -0
- package/p256.d.ts +8 -5
- package/p256.d.ts.map +1 -1
- package/p256.js +19 -18
- package/p256.js.map +1 -1
- package/p384.d.ts +8 -5
- package/p384.d.ts.map +1 -1
- package/p384.js +19 -20
- package/p384.js.map +1 -1
- package/p521.d.ts +6 -5
- package/p521.d.ts.map +1 -1
- package/p521.js +23 -32
- package/p521.js.map +1 -1
- package/package.json +21 -16
- package/pasta.d.ts +1 -7
- package/pasta.d.ts.map +1 -1
- package/pasta.js +4 -34
- package/pasta.js.map +1 -1
- package/secp256k1.d.ts +15 -10
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +57 -53
- package/secp256k1.js.map +1 -1
- package/src/_shortw_utils.ts +2 -2
- package/src/abstract/bls.ts +14 -12
- package/src/abstract/curve.ts +88 -79
- package/src/abstract/edwards.ts +52 -59
- package/src/abstract/hash-to-curve.ts +7 -5
- package/src/abstract/modular.ts +1 -1
- package/src/abstract/montgomery.ts +2 -2
- package/src/abstract/poseidon.ts +1 -1
- package/src/abstract/tower.ts +6 -6
- package/src/abstract/utils.ts +26 -15
- package/src/abstract/weierstrass.ts +99 -77
- package/src/bls12-381.ts +30 -28
- package/src/bn254.ts +11 -13
- package/src/ed25519.ts +27 -26
- package/src/ed448.ts +21 -20
- package/src/index.ts +13 -1
- package/src/jubjub.ts +5 -63
- package/src/misc.ts +117 -0
- package/src/p256.ts +13 -12
- package/src/p384.ts +18 -15
- package/src/p521.ts +27 -32
- package/src/pasta.ts +1 -39
- package/src/secp256k1.ts +20 -16
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 =
|
|
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 =
|
|
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
332
|
if (py == null || !Fp.isValid(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.
|
|
@@ -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,19 +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
637
|
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
|
625
638
|
const _bits = CURVE.nBitLength;
|
|
626
|
-
const wnaf = (0,
|
|
639
|
+
const wnaf = (0, curve_ts_1.wNAF)(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
|
627
640
|
// Validate if generator point is on curve
|
|
628
641
|
return {
|
|
629
642
|
CURVE,
|
|
@@ -634,8 +647,8 @@ function weierstrassPoints(opts) {
|
|
|
634
647
|
};
|
|
635
648
|
}
|
|
636
649
|
function validateOpts(curve) {
|
|
637
|
-
const opts = (0,
|
|
638
|
-
|
|
650
|
+
const opts = (0, curve_ts_1.validateBasic)(curve);
|
|
651
|
+
(0, utils_ts_1.validateObject)(opts, {
|
|
639
652
|
hash: 'hash',
|
|
640
653
|
hmac: 'function',
|
|
641
654
|
randomBytes: 'function',
|
|
@@ -659,18 +672,18 @@ function weierstrass(curveDef) {
|
|
|
659
672
|
const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
|
|
660
673
|
const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
|
|
661
674
|
function modN(a) {
|
|
662
|
-
return
|
|
675
|
+
return (0, modular_ts_1.mod)(a, CURVE_ORDER);
|
|
663
676
|
}
|
|
664
677
|
function invN(a) {
|
|
665
|
-
return
|
|
678
|
+
return (0, modular_ts_1.invert)(a, CURVE_ORDER);
|
|
666
679
|
}
|
|
667
680
|
const { ProjectivePoint: Point, normPrivateKeyToScalar, weierstrassEquation, isWithinCurveOrder, } = weierstrassPoints({
|
|
668
681
|
...CURVE,
|
|
669
682
|
toBytes(_c, point, isCompressed) {
|
|
670
683
|
const a = point.toAffine();
|
|
671
684
|
const x = Fp.toBytes(a.x);
|
|
672
|
-
const cat =
|
|
673
|
-
(0,
|
|
685
|
+
const cat = utils_ts_1.concatBytes;
|
|
686
|
+
(0, utils_ts_1.abool)('isCompressed', isCompressed);
|
|
674
687
|
if (isCompressed) {
|
|
675
688
|
return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
|
|
676
689
|
}
|
|
@@ -684,8 +697,8 @@ function weierstrass(curveDef) {
|
|
|
684
697
|
const tail = bytes.subarray(1);
|
|
685
698
|
// this.assertValidity() is done inside of fromHex
|
|
686
699
|
if (len === compressedLen && (head === 0x02 || head === 0x03)) {
|
|
687
|
-
const x =
|
|
688
|
-
if (!
|
|
700
|
+
const x = (0, utils_ts_1.bytesToNumberBE)(tail);
|
|
701
|
+
if (!(0, utils_ts_1.inRange)(x, _1n, Fp.ORDER))
|
|
689
702
|
throw new Error('Point is not on curve');
|
|
690
703
|
const y2 = weierstrassEquation(x); // y² = x³ + ax + b
|
|
691
704
|
let y;
|
|
@@ -715,7 +728,7 @@ function weierstrass(curveDef) {
|
|
|
715
728
|
}
|
|
716
729
|
},
|
|
717
730
|
});
|
|
718
|
-
const
|
|
731
|
+
const numToNByteHex = (num) => (0, utils_ts_1.bytesToHex)((0, utils_ts_1.numberToBytesBE)(num, CURVE.nByteLength));
|
|
719
732
|
function isBiggerThanHalfOrder(number) {
|
|
720
733
|
const HALF = CURVE_ORDER >> _1n;
|
|
721
734
|
return number > HALF;
|
|
@@ -724,46 +737,50 @@ function weierstrass(curveDef) {
|
|
|
724
737
|
return isBiggerThanHalfOrder(s) ? modN(-s) : s;
|
|
725
738
|
}
|
|
726
739
|
// slice bytes num
|
|
727
|
-
const slcNum = (b, from, to) =>
|
|
740
|
+
const slcNum = (b, from, to) => (0, utils_ts_1.bytesToNumberBE)(b.slice(from, to));
|
|
728
741
|
/**
|
|
729
742
|
* ECDSA signature with its (r, s) properties. Supports DER & compact representations.
|
|
730
743
|
*/
|
|
731
744
|
class Signature {
|
|
732
745
|
constructor(r, s, recovery) {
|
|
746
|
+
(0, utils_ts_1.aInRange)('r', r, _1n, CURVE_ORDER); // r in [1..N]
|
|
747
|
+
(0, utils_ts_1.aInRange)('s', s, _1n, CURVE_ORDER); // s in [1..N]
|
|
733
748
|
this.r = r;
|
|
734
749
|
this.s = s;
|
|
735
|
-
|
|
736
|
-
|
|
750
|
+
if (recovery != null)
|
|
751
|
+
this.recovery = recovery;
|
|
752
|
+
Object.freeze(this);
|
|
737
753
|
}
|
|
738
754
|
// pair (bytes of r, bytes of s)
|
|
739
755
|
static fromCompact(hex) {
|
|
740
756
|
const l = CURVE.nByteLength;
|
|
741
|
-
hex = (0,
|
|
757
|
+
hex = (0, utils_ts_1.ensureBytes)('compactSignature', hex, l * 2);
|
|
742
758
|
return new Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));
|
|
743
759
|
}
|
|
744
760
|
// DER encoded ECDSA signature
|
|
745
761
|
// https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script
|
|
746
762
|
static fromDER(hex) {
|
|
747
|
-
const { r, s } = exports.DER.toSig((0,
|
|
763
|
+
const { r, s } = exports.DER.toSig((0, utils_ts_1.ensureBytes)('DER', hex));
|
|
748
764
|
return new Signature(r, s);
|
|
749
765
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
766
|
+
/**
|
|
767
|
+
* @todo remove
|
|
768
|
+
* @deprecated
|
|
769
|
+
*/
|
|
770
|
+
assertValidity() { }
|
|
754
771
|
addRecoveryBit(recovery) {
|
|
755
772
|
return new Signature(this.r, this.s, recovery);
|
|
756
773
|
}
|
|
757
774
|
recoverPublicKey(msgHash) {
|
|
758
775
|
const { r, s, recovery: rec } = this;
|
|
759
|
-
const h = bits2int_modN((0,
|
|
776
|
+
const h = bits2int_modN((0, utils_ts_1.ensureBytes)('msgHash', msgHash)); // Truncate hash
|
|
760
777
|
if (rec == null || ![0, 1, 2, 3].includes(rec))
|
|
761
778
|
throw new Error('recovery id invalid');
|
|
762
779
|
const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;
|
|
763
780
|
if (radj >= Fp.ORDER)
|
|
764
781
|
throw new Error('recovery id 2 or 3 invalid');
|
|
765
782
|
const prefix = (rec & 1) === 0 ? '02' : '03';
|
|
766
|
-
const R = Point.fromHex(prefix +
|
|
783
|
+
const R = Point.fromHex(prefix + numToNByteHex(radj));
|
|
767
784
|
const ir = invN(radj); // r^-1
|
|
768
785
|
const u1 = modN(-h * ir); // -hr^-1
|
|
769
786
|
const u2 = modN(s * ir); // sr^-1
|
|
@@ -782,17 +799,17 @@ function weierstrass(curveDef) {
|
|
|
782
799
|
}
|
|
783
800
|
// DER-encoded
|
|
784
801
|
toDERRawBytes() {
|
|
785
|
-
return
|
|
802
|
+
return (0, utils_ts_1.hexToBytes)(this.toDERHex());
|
|
786
803
|
}
|
|
787
804
|
toDERHex() {
|
|
788
805
|
return exports.DER.hexFromSig({ r: this.r, s: this.s });
|
|
789
806
|
}
|
|
790
807
|
// padded bytes of r, then padded bytes of s
|
|
791
808
|
toCompactRawBytes() {
|
|
792
|
-
return
|
|
809
|
+
return (0, utils_ts_1.hexToBytes)(this.toCompactHex());
|
|
793
810
|
}
|
|
794
811
|
toCompactHex() {
|
|
795
|
-
return
|
|
812
|
+
return numToNByteHex(this.r) + numToNByteHex(this.s);
|
|
796
813
|
}
|
|
797
814
|
}
|
|
798
815
|
const utils = {
|
|
@@ -811,8 +828,8 @@ function weierstrass(curveDef) {
|
|
|
811
828
|
* (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.
|
|
812
829
|
*/
|
|
813
830
|
randomPrivateKey: () => {
|
|
814
|
-
const length =
|
|
815
|
-
return
|
|
831
|
+
const length = (0, modular_ts_1.getMinHashLength)(CURVE.n);
|
|
832
|
+
return (0, modular_ts_1.mapHashToField)(CURVE.randomBytes(length), CURVE.n);
|
|
816
833
|
},
|
|
817
834
|
/**
|
|
818
835
|
* Creates precompute table for an arbitrary EC point. Makes point "cached".
|
|
@@ -841,7 +858,7 @@ function weierstrass(curveDef) {
|
|
|
841
858
|
* Quick and dirty check for item being public key. Does not validate hex, or being on-curve.
|
|
842
859
|
*/
|
|
843
860
|
function isProbPub(item) {
|
|
844
|
-
const arr =
|
|
861
|
+
const arr = (0, utils_ts_1.isBytes)(item);
|
|
845
862
|
const str = typeof item === 'string';
|
|
846
863
|
const len = (arr || str) && item.length;
|
|
847
864
|
if (arr)
|
|
@@ -881,7 +898,7 @@ function weierstrass(curveDef) {
|
|
|
881
898
|
throw new Error('input is too large');
|
|
882
899
|
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
|
883
900
|
// for some cases, since bytes.length * 8 is not actual bitLength.
|
|
884
|
-
const num =
|
|
901
|
+
const num = (0, utils_ts_1.bytesToNumberBE)(bytes); // check for == u8 done here
|
|
885
902
|
const delta = bytes.length * 8 - CURVE.nBitLength; // truncate to nBitLength leftmost bits
|
|
886
903
|
return delta > 0 ? num >> BigInt(delta) : num;
|
|
887
904
|
};
|
|
@@ -890,14 +907,14 @@ function weierstrass(curveDef) {
|
|
|
890
907
|
return modN(bits2int(bytes)); // can't use bytesToNumberBE here
|
|
891
908
|
};
|
|
892
909
|
// NOTE: pads output with zero as per spec
|
|
893
|
-
const ORDER_MASK =
|
|
910
|
+
const ORDER_MASK = (0, utils_ts_1.bitMask)(CURVE.nBitLength);
|
|
894
911
|
/**
|
|
895
912
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
|
896
913
|
*/
|
|
897
914
|
function int2octets(num) {
|
|
898
|
-
|
|
915
|
+
(0, utils_ts_1.aInRange)('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
|
|
899
916
|
// works with order, can have different size than numToField!
|
|
900
|
-
return
|
|
917
|
+
return (0, utils_ts_1.numberToBytesBE)(num, CURVE.nByteLength);
|
|
901
918
|
}
|
|
902
919
|
// Steps A, D of RFC6979 3.2
|
|
903
920
|
// Creates RFC6979 seed; converts msg/privKey to numbers.
|
|
@@ -911,10 +928,10 @@ function weierstrass(curveDef) {
|
|
|
911
928
|
let { lowS, prehash, extraEntropy: ent } = opts; // generates low-s sigs by default
|
|
912
929
|
if (lowS == null)
|
|
913
930
|
lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
|
|
914
|
-
msgHash = (0,
|
|
931
|
+
msgHash = (0, utils_ts_1.ensureBytes)('msgHash', msgHash);
|
|
915
932
|
validateSigVerOpts(opts);
|
|
916
933
|
if (prehash)
|
|
917
|
-
msgHash = (0,
|
|
934
|
+
msgHash = (0, utils_ts_1.ensureBytes)('prehashed msgHash', hash(msgHash));
|
|
918
935
|
// We can't later call bits2octets, since nested bits2int is broken for curves
|
|
919
936
|
// with nBitLength % 8 !== 0. Because of that, we unwrap it here as int2octets call.
|
|
920
937
|
// const bits2octets = (bits) => int2octets(bits2int_modN(bits))
|
|
@@ -925,9 +942,9 @@ function weierstrass(curveDef) {
|
|
|
925
942
|
if (ent != null && ent !== false) {
|
|
926
943
|
// K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
|
|
927
944
|
const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is
|
|
928
|
-
seedArgs.push((0,
|
|
945
|
+
seedArgs.push((0, utils_ts_1.ensureBytes)('extraEntropy', e)); // check for being bytes
|
|
929
946
|
}
|
|
930
|
-
const seed =
|
|
947
|
+
const seed = (0, utils_ts_1.concatBytes)(...seedArgs); // Step D of RFC6979 3.2
|
|
931
948
|
const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!
|
|
932
949
|
// Converts signature params into point w r/s, checks result for validity.
|
|
933
950
|
function k2sig(kBytes) {
|
|
@@ -974,7 +991,7 @@ function weierstrass(curveDef) {
|
|
|
974
991
|
function sign(msgHash, privKey, opts = defaultSigOpts) {
|
|
975
992
|
const { seed, k2sig } = prepSig(msgHash, privKey, opts); // Steps A, D of RFC6979 3.2.
|
|
976
993
|
const C = CURVE;
|
|
977
|
-
const drbg =
|
|
994
|
+
const drbg = (0, utils_ts_1.createHmacDrbg)(C.hash.outputLen, C.nByteLength, C.hmac);
|
|
978
995
|
return drbg(seed, k2sig); // Steps B, C, D, E, F, G
|
|
979
996
|
}
|
|
980
997
|
// Enable precomputes. Slows down first publicKey computation by 20ms.
|
|
@@ -995,8 +1012,8 @@ function weierstrass(curveDef) {
|
|
|
995
1012
|
*/
|
|
996
1013
|
function verify(signature, msgHash, publicKey, opts = defaultVerOpts) {
|
|
997
1014
|
const sg = signature;
|
|
998
|
-
msgHash = (0,
|
|
999
|
-
publicKey = (0,
|
|
1015
|
+
msgHash = (0, utils_ts_1.ensureBytes)('msgHash', msgHash);
|
|
1016
|
+
publicKey = (0, utils_ts_1.ensureBytes)('publicKey', publicKey);
|
|
1000
1017
|
const { lowS, prehash, format } = opts;
|
|
1001
1018
|
// Verify opts, deduce signature format
|
|
1002
1019
|
validateSigVerOpts(opts);
|
|
@@ -1004,7 +1021,7 @@ function weierstrass(curveDef) {
|
|
|
1004
1021
|
throw new Error('options.strict was renamed to lowS');
|
|
1005
1022
|
if (format !== undefined && format !== 'compact' && format !== 'der')
|
|
1006
1023
|
throw new Error('format must be compact or der');
|
|
1007
|
-
const isHex = typeof sg === 'string' ||
|
|
1024
|
+
const isHex = typeof sg === 'string' || (0, utils_ts_1.isBytes)(sg);
|
|
1008
1025
|
const isObj = !isHex &&
|
|
1009
1026
|
!format &&
|
|
1010
1027
|
typeof sg === 'object' &&
|
|
@@ -1148,7 +1165,7 @@ function SWUFpSqrtRatio(Fp, Z) {
|
|
|
1148
1165
|
* https://www.rfc-editor.org/rfc/rfc9380#section-6.6.2
|
|
1149
1166
|
*/
|
|
1150
1167
|
function mapToCurveSimpleSWU(Fp, opts) {
|
|
1151
|
-
|
|
1168
|
+
(0, modular_ts_1.validateField)(Fp);
|
|
1152
1169
|
if (!Fp.isValid(opts.A) || !Fp.isValid(opts.B) || !Fp.isValid(opts.Z))
|
|
1153
1170
|
throw new Error('mapToCurveSimpleSWU: invalid opts');
|
|
1154
1171
|
const sqrtRatio = SWUFpSqrtRatio(Fp, opts.Z);
|