@noble/curves 0.5.0 ā 0.5.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 +62 -14
- package/lib/_shortw_utils.d.ts +2 -6
- package/lib/abstract/bls.d.ts +17 -8
- package/lib/abstract/bls.js +15 -78
- package/lib/abstract/edwards.d.ts +7 -16
- package/lib/abstract/edwards.js +89 -106
- package/lib/abstract/hash-to-curve.d.ts +10 -1
- package/lib/abstract/hash-to-curve.js +32 -10
- package/lib/abstract/modular.d.ts +8 -17
- package/lib/abstract/modular.js +134 -152
- package/lib/abstract/montgomery.js +1 -1
- package/lib/abstract/utils.d.ts +8 -4
- package/lib/abstract/utils.js +22 -14
- package/lib/abstract/weierstrass.d.ts +8 -8
- package/lib/abstract/weierstrass.js +209 -168
- package/lib/bls12-381.d.ts +2 -1
- package/lib/bls12-381.js +14 -9
- package/lib/ed25519.js +75 -12
- package/lib/ed448.js +86 -2
- package/lib/esm/abstract/bls.js +19 -82
- package/lib/esm/abstract/edwards.js +90 -107
- package/lib/esm/abstract/hash-to-curve.js +30 -9
- package/lib/esm/abstract/modular.js +128 -148
- package/lib/esm/abstract/montgomery.js +2 -4
- package/lib/esm/abstract/utils.js +20 -13
- package/lib/esm/abstract/weierstrass.js +210 -169
- package/lib/esm/bls12-381.js +13 -8
- package/lib/esm/ed25519.js +76 -13
- package/lib/esm/ed448.js +87 -3
- package/lib/esm/jubjub.js +5 -4
- package/lib/esm/p256.js +1 -1
- package/lib/esm/p384.js +1 -1
- package/lib/esm/p521.js +1 -1
- package/lib/esm/secp256k1.js +27 -27
- package/lib/esm/stark.js +5 -2
- package/lib/jubjub.d.ts +1 -0
- package/lib/jubjub.js +5 -4
- package/lib/p192.d.ts +4 -12
- package/lib/p224.d.ts +4 -12
- package/lib/p256.d.ts +4 -12
- package/lib/p256.js +1 -1
- package/lib/p384.d.ts +4 -12
- package/lib/p384.js +1 -1
- package/lib/p521.d.ts +4 -12
- package/lib/p521.js +1 -1
- package/lib/secp256k1.d.ts +2 -6
- package/lib/secp256k1.js +27 -27
- package/lib/stark.d.ts +1 -3
- package/lib/stark.js +5 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@ Minimal, auditable JS implementation of elliptic curve cryptography.
|
|
|
7
7
|
- [hash to curve](https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/)
|
|
8
8
|
for encoding or hashing an arbitrary string to a point on an elliptic curve
|
|
9
9
|
- Auditable, [fast](#speed)
|
|
10
|
-
- š» Tree-shaking-friendly: there is no entry point, which ensures small size of your app
|
|
11
10
|
- š Unique tests ensure correctness. Wycheproof vectors included
|
|
11
|
+
- š» Tree-shaking-friendly: there is no entry point, which ensures small size of your app
|
|
12
12
|
|
|
13
13
|
There are two parts of the package:
|
|
14
14
|
|
|
@@ -84,11 +84,12 @@ To define a custom curve, check out API below.
|
|
|
84
84
|
## API
|
|
85
85
|
|
|
86
86
|
- [Overview](#overview)
|
|
87
|
-
- [abstract/edwards: Twisted Edwards curve](#
|
|
88
|
-
- [abstract/montgomery: Montgomery curve](#
|
|
89
|
-
- [abstract/weierstrass: Short Weierstrass curve](#
|
|
90
|
-
- [abstract/
|
|
91
|
-
- [abstract/
|
|
87
|
+
- [abstract/edwards: Twisted Edwards curve](#abstractedwards-twisted-edwards-curve)
|
|
88
|
+
- [abstract/montgomery: Montgomery curve](#abstractmontgomery-montgomery-curve)
|
|
89
|
+
- [abstract/weierstrass: Short Weierstrass curve](#abstractweierstrass-short-weierstrass-curve)
|
|
90
|
+
- [abstract/hash-to-curve: Hashing strings to curve points](#abstracthash-to-curve-hashing-strings-to-curve-points)
|
|
91
|
+
- [abstract/modular](#abstractmodular)
|
|
92
|
+
- [abstract/utils](#abstractutils)
|
|
92
93
|
|
|
93
94
|
### Overview
|
|
94
95
|
|
|
@@ -200,8 +201,6 @@ export type CurveFn = {
|
|
|
200
201
|
ExtendedPoint: ExtendedPointConstructor;
|
|
201
202
|
Signature: SignatureConstructor;
|
|
202
203
|
utils: {
|
|
203
|
-
mod: (a: bigint, b?: bigint) => bigint;
|
|
204
|
-
invert: (number: bigint, modulo?: bigint) => bigint;
|
|
205
204
|
randomPrivateKey: () => Uint8Array;
|
|
206
205
|
getExtendedPublicKey: (key: PrivKey) => {
|
|
207
206
|
head: Uint8Array;
|
|
@@ -305,6 +304,7 @@ export type CurveFn = {
|
|
|
305
304
|
getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
|
|
306
305
|
getSharedSecret: (privateA: PrivKey, publicB: PubKey, isCompressed?: boolean) => Uint8Array;
|
|
307
306
|
sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
|
|
307
|
+
signUnhashed: (msg: Uint8Array, privKey: PrivKey, opts?: SignOpts) => SignatureType;
|
|
308
308
|
verify: (
|
|
309
309
|
signature: Hex | SignatureType,
|
|
310
310
|
msgHash: Hex,
|
|
@@ -315,8 +315,6 @@ export type CurveFn = {
|
|
|
315
315
|
ProjectivePoint: ProjectivePointConstructor;
|
|
316
316
|
Signature: SignatureConstructor;
|
|
317
317
|
utils: {
|
|
318
|
-
mod: (a: bigint) => bigint;
|
|
319
|
-
invert: (number: bigint) => bigint;
|
|
320
318
|
isValidPrivateKey(privateKey: PrivKey): boolean;
|
|
321
319
|
hashToPrivateKey: (hash: Hex) => Uint8Array;
|
|
322
320
|
randomPrivateKey: () => Uint8Array;
|
|
@@ -324,20 +322,70 @@ export type CurveFn = {
|
|
|
324
322
|
};
|
|
325
323
|
```
|
|
326
324
|
|
|
325
|
+
### abstract/hash-to-curve: Hashing strings to curve points
|
|
326
|
+
|
|
327
|
+
The module allows to hash arbitrary strings to elliptic curve points.
|
|
328
|
+
|
|
329
|
+
- `expand_message_xmd` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.4.1) produces a uniformly random byte string using a cryptographic hash function H that outputs b bits..
|
|
330
|
+
|
|
331
|
+
```ts
|
|
332
|
+
function expand_message_xmd(
|
|
333
|
+
msg: Uint8Array, DST: Uint8Array, lenInBytes: number, H: CHash
|
|
334
|
+
): Uint8Array;
|
|
335
|
+
function expand_message_xof(
|
|
336
|
+
msg: Uint8Array, DST: Uint8Array, lenInBytes: number, k: number, H: CHash
|
|
337
|
+
): Uint8Array;
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
- `hash_to_field(msg, count, options)` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3)
|
|
341
|
+
hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
|
|
342
|
+
* `msg` a byte string containing the message to hash
|
|
343
|
+
* `count` the number of elements of F to output
|
|
344
|
+
* `options` `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`
|
|
345
|
+
* Returns `[u_0, ..., u_(count - 1)]`, a list of field elements.
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
function hash_to_field(msg: Uint8Array, count: number, options: htfOpts): bigint[][];
|
|
349
|
+
type htfOpts = {
|
|
350
|
+
// DST: a domain separation tag
|
|
351
|
+
// defined in section 2.2.5
|
|
352
|
+
DST: string;
|
|
353
|
+
// p: the characteristic of F
|
|
354
|
+
// where F is a finite field of characteristic p and order q = p^m
|
|
355
|
+
p: bigint;
|
|
356
|
+
// m: the extension degree of F, m >= 1
|
|
357
|
+
// where F is a finite field of characteristic p and order q = p^m
|
|
358
|
+
m: number;
|
|
359
|
+
// k: the target security level for the suite in bits
|
|
360
|
+
// defined in section 5.1
|
|
361
|
+
k: number;
|
|
362
|
+
// option to use a message that has already been processed by
|
|
363
|
+
// expand_message_xmd
|
|
364
|
+
expand?: 'xmd' | 'xof';
|
|
365
|
+
// Hash functions for: expand_message_xmd is appropriate for use with a
|
|
366
|
+
// wide range of hash functions, including SHA-2, SHA-3, BLAKE2, and others.
|
|
367
|
+
// BBS+ uses blake2: https://github.com/hyperledger/aries-framework-go/issues/2247
|
|
368
|
+
// TODO: verify that hash is shake if expand==='xof' via types
|
|
369
|
+
hash: CHash;
|
|
370
|
+
};
|
|
371
|
+
```
|
|
372
|
+
|
|
327
373
|
### abstract/modular
|
|
328
374
|
|
|
329
375
|
Modular arithmetics utilities.
|
|
330
376
|
|
|
331
377
|
```typescript
|
|
332
|
-
import { mod, invert, div, invertBatch, sqrt
|
|
378
|
+
import { Fp, mod, invert, div, invertBatch, sqrt } from '@noble/curves/abstract/modular';
|
|
379
|
+
const fp = Fp(2n ** 255n - 19n); // Finite field over 2^255-19
|
|
380
|
+
fp.mul(591n, 932n);
|
|
381
|
+
fp.pow(481n, 11024858120n);
|
|
382
|
+
|
|
383
|
+
// Generic non-FP utils are also available
|
|
333
384
|
mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
|
|
334
385
|
invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse
|
|
335
386
|
div(5n, 17n, 10n); // 5/17 mod 10 == 5 * invert(17) mod 10; division
|
|
336
387
|
invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion
|
|
337
388
|
sqrt(21n, 73n); // ā21 mod 73; square root
|
|
338
|
-
const fp = Fp(2n ** 255n - 19n); // Finite field over 2^255-19
|
|
339
|
-
fp.mul(591n, 932n);
|
|
340
|
-
fp.pow(481n, 11024858120n);
|
|
341
389
|
```
|
|
342
390
|
|
|
343
391
|
### abstract/utils
|
package/lib/_shortw_utils.d.ts
CHANGED
|
@@ -47,10 +47,8 @@ export declare function createCurve(curveDef: CurveDef, defHash: CHash): Readonl
|
|
|
47
47
|
}>;
|
|
48
48
|
getPublicKey: (privateKey: import("./abstract/utils.js").PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
49
49
|
getSharedSecret: (privateA: import("./abstract/utils.js").PrivKey, publicB: import("./abstract/weierstrass.js").PubKey, isCompressed?: boolean | undefined) => Uint8Array;
|
|
50
|
-
sign: (msgHash: import("./abstract/utils.js").Hex, privKey: import("./abstract/utils.js").PrivKey, opts?:
|
|
51
|
-
|
|
52
|
-
extraEntropy?: (true | import("./abstract/utils.js").Hex) | undefined;
|
|
53
|
-
} | undefined) => import("./abstract/weierstrass.js").SignatureType;
|
|
50
|
+
sign: (msgHash: import("./abstract/utils.js").Hex, privKey: import("./abstract/utils.js").PrivKey, opts?: import("./abstract/weierstrass.js").SignOpts | undefined) => import("./abstract/weierstrass.js").SignatureType;
|
|
51
|
+
signUnhashed: (msg: Uint8Array, privKey: import("./abstract/utils.js").PrivKey, opts?: import("./abstract/weierstrass.js").SignOpts | undefined) => import("./abstract/weierstrass.js").SignatureType;
|
|
54
52
|
verify: (signature: import("./abstract/utils.js").Hex | import("./abstract/weierstrass.js").SignatureType, msgHash: import("./abstract/utils.js").Hex, publicKey: import("./abstract/weierstrass.js").PubKey, opts?: {
|
|
55
53
|
lowS?: boolean | undefined;
|
|
56
54
|
} | undefined) => boolean;
|
|
@@ -58,8 +56,6 @@ export declare function createCurve(curveDef: CurveDef, defHash: CHash): Readonl
|
|
|
58
56
|
ProjectivePoint: import("./abstract/weierstrass.js").ProjectiveConstructor<bigint>;
|
|
59
57
|
Signature: import("./abstract/weierstrass.js").SignatureConstructor;
|
|
60
58
|
utils: {
|
|
61
|
-
mod: (a: bigint, b?: bigint | undefined) => bigint;
|
|
62
|
-
invert: (number: bigint, modulo?: bigint | undefined) => bigint;
|
|
63
59
|
_bigintToBytes: (num: bigint) => Uint8Array;
|
|
64
60
|
_bigintToString: (num: bigint) => string;
|
|
65
61
|
_normalizePrivateKey: (key: import("./abstract/utils.js").PrivKey) => bigint;
|
package/lib/abstract/bls.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
|
+
/**
|
|
3
|
+
* BLS (Barreto-Lynn-Scott) family of pairing-friendly curves.
|
|
4
|
+
* Implements BLS (Boneh-Lynn-Shacham) signatures.
|
|
5
|
+
* Consists of two curves: G1 and G2:
|
|
6
|
+
* - G1 is a subgroup of (x, y) E(Fq) over y² = x³ + 4.
|
|
7
|
+
* - G2 is a subgroup of ((xā, xā+i), (yā, yā+i)) E(Fq²) over y² = x³ + 4(1 + i) where i is ā-1
|
|
8
|
+
* - Gt, created by bilinear (ate) pairing e(G1, G2), consists of p-th roots of unity in
|
|
9
|
+
* Fq^k where k is embedding degree. Only degree 12 is currently supported, 24 is not.
|
|
10
|
+
* Pairing is used to aggregate and verify signatures.
|
|
11
|
+
* We are using Fp for private keys (shorter) and Fpā for signatures (longer).
|
|
12
|
+
* Some projects may prefer to swap this relation, it is not supported for now.
|
|
13
|
+
*/
|
|
2
14
|
import * as mod from './modular.js';
|
|
3
|
-
import * as
|
|
15
|
+
import * as ut from './utils.js';
|
|
4
16
|
import { Hex, PrivKey } from './utils.js';
|
|
5
|
-
import { htfOpts, stringToBytes, hash_to_field, expand_message_xmd } from './hash-to-curve.js';
|
|
17
|
+
import { htfOpts, stringToBytes, hash_to_field as hashToField, expand_message_xmd as expandMessageXMD } from './hash-to-curve.js';
|
|
6
18
|
import { CurvePointsType, PointType, CurvePointsRes } from './weierstrass.js';
|
|
7
19
|
declare type Fp = bigint;
|
|
8
20
|
export declare type SignatureCoder<Fp2> = {
|
|
@@ -34,7 +46,7 @@ export declare type CurveType<Fp, Fp2, Fp6, Fp12> = {
|
|
|
34
46
|
finalExponentiate(num: Fp12): Fp12;
|
|
35
47
|
};
|
|
36
48
|
htfDefaults: htfOpts;
|
|
37
|
-
hash:
|
|
49
|
+
hash: ut.CHash;
|
|
38
50
|
randomBytes: (bytesLength?: number) => Uint8Array;
|
|
39
51
|
};
|
|
40
52
|
export declare type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
|
@@ -66,12 +78,9 @@ export declare type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
|
|
66
78
|
};
|
|
67
79
|
verifyBatch: (signature: Hex | PointType<Fp2>, messages: (Hex | PointType<Fp2>)[], publicKeys: (Hex | PointType<Fp>)[]) => boolean;
|
|
68
80
|
utils: {
|
|
69
|
-
bytesToHex: typeof utils.bytesToHex;
|
|
70
|
-
hexToBytes: typeof utils.hexToBytes;
|
|
71
81
|
stringToBytes: typeof stringToBytes;
|
|
72
|
-
hashToField: typeof
|
|
73
|
-
expandMessageXMD: typeof
|
|
74
|
-
mod: typeof mod.mod;
|
|
82
|
+
hashToField: typeof hashToField;
|
|
83
|
+
expandMessageXMD: typeof expandMessageXMD;
|
|
75
84
|
getDSTLabel: () => string;
|
|
76
85
|
setDSTLabel(newLabel: string): void;
|
|
77
86
|
};
|
package/lib/abstract/bls.js
CHANGED
|
@@ -1,24 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.bls = void 0;
|
|
4
|
-
|
|
5
|
-
// Barreto-Lynn-Scott Curves. A family of pairing friendly curves, with embedding degree = 12 or 24
|
|
6
|
-
// NOTE: only 12 supported for now
|
|
7
|
-
// Constructed from pair of weierstrass curves, based pairing logic
|
|
8
|
-
const mod = require("./modular.js");
|
|
9
|
-
const utils_js_1 = require("./utils.js");
|
|
10
|
-
// Types
|
|
11
|
-
const utils_js_2 = require("./utils.js");
|
|
4
|
+
const ut = require("./utils.js");
|
|
12
5
|
const hash_to_curve_js_1 = require("./hash-to-curve.js");
|
|
13
6
|
const weierstrass_js_1 = require("./weierstrass.js");
|
|
14
7
|
function bls(CURVE) {
|
|
15
8
|
// Fields looks pretty specific for curve, so for now we need to pass them with options
|
|
16
|
-
const Fp = CURVE
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const Fp6 = CURVE.Fp6;
|
|
20
|
-
const Fp12 = CURVE.Fp12;
|
|
21
|
-
const BLS_X_LEN = (0, utils_js_1.bitLen)(CURVE.x);
|
|
9
|
+
const { Fp, Fr, Fp2, Fp6, Fp12 } = CURVE;
|
|
10
|
+
const BLS_X_LEN = ut.bitLen(CURVE.x);
|
|
11
|
+
const groupLen = 32; // TODO: calculate; hardcoded for now
|
|
22
12
|
// Pre-compute coefficients for sparse multiplication
|
|
23
13
|
// Point addition and point double calculations is reused for coefficients
|
|
24
14
|
function calcPairingPrecomputes(x, y) {
|
|
@@ -42,7 +32,7 @@ function bls(CURVE) {
|
|
|
42
32
|
Rx = Fp2.div(Fp2.mul(Fp2.mul(Fp2.sub(t0, t3), Rx), Ry), 2n); // ((T0 - T3) * Rx * Ry) / 2
|
|
43
33
|
Ry = Fp2.sub(Fp2.square(Fp2.div(Fp2.add(t0, t3), 2n)), Fp2.mul(Fp2.square(t2), 3n)); // ((T0 + T3) / 2)² - 3 * T2²
|
|
44
34
|
Rz = Fp2.mul(t0, t4); // T0 * T4
|
|
45
|
-
if (
|
|
35
|
+
if (ut.bitGet(CURVE.x, i)) {
|
|
46
36
|
// Addition
|
|
47
37
|
let t0 = Fp2.sub(Ry, Fp2.mul(Qy, Rz)); // Ry - Qy * Rz
|
|
48
38
|
let t1 = Fp2.sub(Rx, Fp2.mul(Qx, Rz)); // Rx - Qx * Rz
|
|
@@ -63,13 +53,14 @@ function bls(CURVE) {
|
|
|
63
53
|
return ell_coeff;
|
|
64
54
|
}
|
|
65
55
|
function millerLoop(ell, g1) {
|
|
56
|
+
const { x } = CURVE;
|
|
66
57
|
const Px = g1[0];
|
|
67
58
|
const Py = g1[1];
|
|
68
59
|
let f12 = Fp12.ONE;
|
|
69
60
|
for (let j = 0, i = BLS_X_LEN - 2; i >= 0; i--, j++) {
|
|
70
61
|
const E = ell[j];
|
|
71
62
|
f12 = Fp12.multiplyBy014(f12, E[0], Fp2.mul(E[1], Px), Fp2.mul(E[2], Py));
|
|
72
|
-
if (
|
|
63
|
+
if (ut.bitGet(x, i)) {
|
|
73
64
|
j += 1;
|
|
74
65
|
const F = ell[j];
|
|
75
66
|
f12 = Fp12.multiplyBy014(f12, F[0], Fp2.mul(F[1], Px), Fp2.mul(F[2], Py));
|
|
@@ -79,79 +70,25 @@ function bls(CURVE) {
|
|
|
79
70
|
}
|
|
80
71
|
return Fp12.conjugate(f12);
|
|
81
72
|
}
|
|
82
|
-
// bls12-381 is a construction of two curves:
|
|
83
|
-
// 1. Fp: (x, y)
|
|
84
|
-
// 2. Fpā: ((xā, xā+i), (yā, yā+i)) - (complex numbers)
|
|
85
|
-
//
|
|
86
|
-
// Bilinear Pairing (ate pairing) is used to combine both elements into a paired one:
|
|
87
|
-
// Fpāā = e(Fp, Fp2)
|
|
88
|
-
// where Fpāā = 12-degree polynomial
|
|
89
|
-
// Pairing is used to verify signatures.
|
|
90
|
-
//
|
|
91
|
-
// We are using Fp for private keys (shorter) and Fp2 for signatures (longer).
|
|
92
|
-
// Some projects may prefer to swap this relation, it is not supported for now.
|
|
93
|
-
const htfDefaults = { ...CURVE.htfDefaults };
|
|
94
|
-
function isWithinCurveOrder(num) {
|
|
95
|
-
return 0 < num && num < CURVE.r;
|
|
96
|
-
}
|
|
97
73
|
const utils = {
|
|
98
|
-
hexToBytes:
|
|
99
|
-
bytesToHex:
|
|
100
|
-
mod: mod.mod,
|
|
74
|
+
hexToBytes: ut.hexToBytes,
|
|
75
|
+
bytesToHex: ut.bytesToHex,
|
|
101
76
|
stringToBytes: hash_to_curve_js_1.stringToBytes,
|
|
102
77
|
// TODO: do we need to export it here?
|
|
103
78
|
hashToField: (msg, count, options = {}) => (0, hash_to_curve_js_1.hash_to_field)(msg, count, { ...CURVE.htfDefaults, ...options }),
|
|
104
79
|
expandMessageXMD: (msg, DST, lenInBytes, H = CURVE.hash) => (0, hash_to_curve_js_1.expand_message_xmd)(msg, DST, lenInBytes, H),
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
* https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
|
|
110
|
-
* @param hash hash output from sha512, or a similar function
|
|
111
|
-
* @returns valid private key
|
|
112
|
-
*/
|
|
113
|
-
hashToPrivateKey: (hash) => {
|
|
114
|
-
hash = (0, utils_js_1.ensureBytes)(hash);
|
|
115
|
-
if (hash.length < 40 || hash.length > 1024)
|
|
116
|
-
throw new Error('Expected 40-1024 bytes of private key as per FIPS 186');
|
|
117
|
-
// hashToPrivateScalar(hash, CURVE.r)
|
|
118
|
-
// NOTE: doesn't add +/-1
|
|
119
|
-
const num = mod.mod((0, utils_js_1.bytesToNumberBE)(hash), CURVE.r);
|
|
120
|
-
// This should never happen
|
|
121
|
-
if (num === 0n || num === 1n)
|
|
122
|
-
throw new Error('Invalid private key');
|
|
123
|
-
return (0, utils_js_1.numberToBytesBE)(num, 32);
|
|
124
|
-
},
|
|
125
|
-
randomBytes: (bytesLength = 32) => CURVE.randomBytes(bytesLength),
|
|
126
|
-
// NIST SP 800-56A rev 3, section 5.6.1.2.2
|
|
127
|
-
// https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
|
|
128
|
-
randomPrivateKey: () => utils.hashToPrivateKey(utils.randomBytes(40)),
|
|
129
|
-
getDSTLabel: () => htfDefaults.DST,
|
|
80
|
+
hashToPrivateKey: (hash) => Fr.toBytes(ut.hashToPrivateScalar(hash, CURVE.r)),
|
|
81
|
+
randomBytes: (bytesLength = groupLen) => CURVE.randomBytes(bytesLength),
|
|
82
|
+
randomPrivateKey: () => utils.hashToPrivateKey(utils.randomBytes(groupLen + 8)),
|
|
83
|
+
getDSTLabel: () => CURVE.htfDefaults.DST,
|
|
130
84
|
setDSTLabel(newLabel) {
|
|
131
85
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3.1
|
|
132
86
|
if (typeof newLabel !== 'string' || newLabel.length > 2048 || newLabel.length === 0) {
|
|
133
87
|
throw new TypeError('Invalid DST');
|
|
134
88
|
}
|
|
135
|
-
htfDefaults.DST = newLabel;
|
|
89
|
+
CURVE.htfDefaults.DST = newLabel;
|
|
136
90
|
},
|
|
137
91
|
};
|
|
138
|
-
function normalizePrivKey(key) {
|
|
139
|
-
let int;
|
|
140
|
-
if (key instanceof Uint8Array && key.length === 32)
|
|
141
|
-
int = (0, utils_js_1.bytesToNumberBE)(key);
|
|
142
|
-
else if (typeof key === 'string' && key.length === 64)
|
|
143
|
-
int = BigInt(`0x${key}`);
|
|
144
|
-
else if (typeof key === 'number' && key > 0 && Number.isSafeInteger(key))
|
|
145
|
-
int = BigInt(key);
|
|
146
|
-
else if (typeof key === 'bigint' && key > 0n)
|
|
147
|
-
int = key;
|
|
148
|
-
else
|
|
149
|
-
throw new TypeError('Expected valid private key');
|
|
150
|
-
int = mod.mod(int, CURVE.r);
|
|
151
|
-
if (!isWithinCurveOrder(int))
|
|
152
|
-
throw new Error('Private key must be 0 < key < CURVE.r');
|
|
153
|
-
return int;
|
|
154
|
-
}
|
|
155
92
|
// Point on G1 curve: (x, y)
|
|
156
93
|
const G1 = (0, weierstrass_js_1.weierstrassPoints)({
|
|
157
94
|
n: Fr.ORDER,
|
|
@@ -205,7 +142,7 @@ function bls(CURVE) {
|
|
|
205
142
|
function sign(message, privateKey) {
|
|
206
143
|
const msgPoint = normP2Hash(message);
|
|
207
144
|
msgPoint.assertValidity();
|
|
208
|
-
const sigPoint = msgPoint.multiply(
|
|
145
|
+
const sigPoint = msgPoint.multiply(G1.normalizePrivateKey(privateKey));
|
|
209
146
|
if (message instanceof G2.Point)
|
|
210
147
|
return sigPoint;
|
|
211
148
|
return Signature.encode(sigPoint);
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
2
|
import * as mod from './modular.js';
|
|
3
|
-
import
|
|
3
|
+
import * as ut from './utils.js';
|
|
4
|
+
import { Hex, PrivKey } from './utils.js';
|
|
4
5
|
import { Group, GroupConstructor } from './group.js';
|
|
5
6
|
import { htfOpts } from './hash-to-curve.js';
|
|
6
|
-
export declare type
|
|
7
|
-
(message: Uint8Array | string): Uint8Array;
|
|
8
|
-
blockLen: number;
|
|
9
|
-
outputLen: number;
|
|
10
|
-
create(): any;
|
|
11
|
-
};
|
|
12
|
-
export declare type CurveType = BasicCurve<bigint> & {
|
|
7
|
+
export declare type CurveType = ut.BasicCurve<bigint> & {
|
|
13
8
|
a: bigint;
|
|
14
9
|
d: bigint;
|
|
15
|
-
hash: CHash;
|
|
10
|
+
hash: ut.CHash;
|
|
16
11
|
randomBytes: (bytesLength?: number) => Uint8Array;
|
|
17
12
|
adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array;
|
|
18
13
|
domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
|
|
@@ -20,8 +15,7 @@ export declare type CurveType = BasicCurve<bigint> & {
|
|
|
20
15
|
isValid: boolean;
|
|
21
16
|
value: bigint;
|
|
22
17
|
};
|
|
23
|
-
preHash?: CHash;
|
|
24
|
-
clearCofactor?: (c: ExtendedPointConstructor, point: ExtendedPointType) => ExtendedPointType;
|
|
18
|
+
preHash?: ut.CHash;
|
|
25
19
|
htfDefaults?: htfOpts;
|
|
26
20
|
mapToCurve?: (scalar: bigint[]) => {
|
|
27
21
|
x: bigint;
|
|
@@ -41,7 +35,7 @@ declare function validateOpts(curve: CurveType): Readonly<{
|
|
|
41
35
|
readonly allowInfinityPoint?: boolean | undefined;
|
|
42
36
|
readonly a: bigint;
|
|
43
37
|
readonly d: bigint;
|
|
44
|
-
readonly hash: CHash;
|
|
38
|
+
readonly hash: ut.CHash;
|
|
45
39
|
readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
|
|
46
40
|
readonly adjustScalarBytes?: ((bytes: Uint8Array) => Uint8Array) | undefined;
|
|
47
41
|
readonly domain?: ((data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array) | undefined;
|
|
@@ -49,8 +43,7 @@ declare function validateOpts(curve: CurveType): Readonly<{
|
|
|
49
43
|
isValid: boolean;
|
|
50
44
|
value: bigint;
|
|
51
45
|
}) | undefined;
|
|
52
|
-
readonly preHash?: CHash | undefined;
|
|
53
|
-
readonly clearCofactor?: ((c: ExtendedPointConstructor, point: ExtendedPointType) => ExtendedPointType) | undefined;
|
|
46
|
+
readonly preHash?: ut.CHash | undefined;
|
|
54
47
|
readonly htfDefaults?: htfOpts | undefined;
|
|
55
48
|
readonly mapToCurve?: ((scalar: bigint[]) => {
|
|
56
49
|
x: bigint;
|
|
@@ -113,8 +106,6 @@ export declare type CurveFn = {
|
|
|
113
106
|
ExtendedPoint: ExtendedPointConstructor;
|
|
114
107
|
Signature: SignatureConstructor;
|
|
115
108
|
utils: {
|
|
116
|
-
mod: (a: bigint) => bigint;
|
|
117
|
-
invert: (number: bigint) => bigint;
|
|
118
109
|
randomPrivateKey: () => Uint8Array;
|
|
119
110
|
getExtendedPublicKey: (key: PrivKey) => {
|
|
120
111
|
head: Uint8Array;
|