@noble/curves 0.2.1 → 0.3.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 +14 -19
- package/lib/crypto.d.ts +4 -0
- package/lib/crypto.js +8 -0
- package/lib/cryptoBrowser.d.ts +4 -0
- package/lib/cryptoBrowser.js +7 -0
- package/lib/definitions/_shortw_utils.d.ts +63 -0
- package/lib/definitions/_shortw_utils.js +18 -0
- package/lib/definitions/bn.d.ts +7 -0
- package/lib/definitions/bn.js +23 -0
- package/lib/definitions/ed25519.d.ts +49 -0
- package/lib/definitions/ed25519.js +308 -0
- package/lib/definitions/ed448.d.ts +3 -0
- package/lib/definitions/ed448.js +127 -0
- package/lib/definitions/index.d.ts +0 -0
- package/lib/definitions/index.js +2 -0
- package/lib/definitions/jubjub.d.ts +7 -0
- package/lib/definitions/jubjub.js +55 -0
- package/lib/definitions/p192.d.ts +112 -0
- package/lib/definitions/p192.js +23 -0
- package/lib/definitions/p224.d.ts +112 -0
- package/lib/definitions/p224.js +24 -0
- package/lib/definitions/p256.d.ts +112 -0
- package/lib/definitions/p256.js +23 -0
- package/lib/definitions/p384.d.ts +112 -0
- package/lib/definitions/p384.js +24 -0
- package/lib/definitions/p521.d.ts +113 -0
- package/lib/definitions/p521.js +36 -0
- package/lib/definitions/pasta.d.ts +2 -0
- package/lib/definitions/pasta.js +32 -0
- package/lib/definitions/secp256k1.d.ts +87 -0
- package/lib/definitions/secp256k1.js +245 -0
- package/lib/definitions/stark.d.ts +62 -0
- package/lib/definitions/stark.js +248 -0
- package/lib/edwards.d.ts +2 -2
- package/lib/edwards.js +2 -6
- package/lib/esm/crypto.js +5 -0
- package/lib/esm/cryptoBrowser.js +4 -0
- package/lib/esm/definitions/_shortw_utils.js +13 -0
- package/lib/esm/definitions/bn.js +20 -0
- package/lib/esm/definitions/ed25519.js +304 -0
- package/lib/esm/definitions/ed448.js +124 -0
- package/lib/esm/definitions/index.js +2 -0
- package/lib/esm/definitions/jubjub.js +50 -0
- package/lib/esm/definitions/p192.js +20 -0
- package/lib/esm/definitions/p224.js +21 -0
- package/lib/esm/definitions/p256.js +20 -0
- package/lib/esm/definitions/p384.js +21 -0
- package/lib/esm/definitions/p521.js +33 -0
- package/lib/esm/definitions/pasta.js +29 -0
- package/lib/esm/definitions/secp256k1.js +241 -0
- package/lib/esm/definitions/stark.js +227 -0
- package/lib/esm/edwards.js +3 -7
- package/lib/esm/modular.js +14 -9
- package/lib/esm/utils.js +17 -0
- package/lib/esm/weierstrass.js +18 -9
- package/lib/modular.d.ts +8 -1
- package/lib/modular.js +14 -9
- package/lib/utils.d.ts +4 -0
- package/lib/utils.js +19 -1
- package/lib/weierstrass.d.ts +5 -3
- package/lib/weierstrass.js +17 -8
- package/package.json +28 -8
package/lib/modular.js
CHANGED
|
@@ -6,10 +6,6 @@ exports.isNegativeLE = exports.sqrt = exports.legendre = exports.invertBatch = e
|
|
|
6
6
|
const _0n = BigInt(0);
|
|
7
7
|
const _1n = BigInt(1);
|
|
8
8
|
const _2n = BigInt(2);
|
|
9
|
-
const _3n = BigInt(3);
|
|
10
|
-
const _4n = BigInt(4);
|
|
11
|
-
const _5n = BigInt(5);
|
|
12
|
-
const _8n = BigInt(8);
|
|
13
9
|
// Calculates a modulo b
|
|
14
10
|
function mod(a, b) {
|
|
15
11
|
const result = a % b;
|
|
@@ -18,6 +14,7 @@ function mod(a, b) {
|
|
|
18
14
|
exports.mod = mod;
|
|
19
15
|
/**
|
|
20
16
|
* Efficiently exponentiate num to power and do modular division.
|
|
17
|
+
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
|
21
18
|
* @example
|
|
22
19
|
* powMod(2n, 6n, 11n) // 64n % 11n == 9n
|
|
23
20
|
*/
|
|
@@ -110,23 +107,30 @@ function invertBatch(nums, modulo) {
|
|
|
110
107
|
return scratch;
|
|
111
108
|
}
|
|
112
109
|
exports.invertBatch = invertBatch;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Calculates Legendre symbol (a | p), which denotes the value of a^((p-1)/2) (mod p).
|
|
112
|
+
* * (a | p) ≡ 1 if a is a square (mod p)
|
|
113
|
+
* * (a | p) ≡ -1 if a is not a square (mod p)
|
|
114
|
+
* * (a | p) ≡ 0 if a ≡ 0 (mod p)
|
|
115
|
+
*/
|
|
116
|
+
function legendre(num, P) {
|
|
117
|
+
return pow(num, (P - _1n) / _2n, P);
|
|
116
118
|
}
|
|
117
119
|
exports.legendre = legendre;
|
|
118
120
|
/**
|
|
119
121
|
* Calculates square root of a number in a finite field.
|
|
120
122
|
*/
|
|
121
123
|
function sqrt(number, modulo) {
|
|
124
|
+
// prettier-ignore
|
|
125
|
+
const _3n = BigInt(3), _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);
|
|
122
126
|
const n = number;
|
|
123
127
|
const P = modulo;
|
|
124
128
|
const p1div4 = (P + _1n) / _4n;
|
|
125
|
-
// P
|
|
129
|
+
// P ≡ 3 (mod 4)
|
|
126
130
|
// sqrt n = n^((P+1)/4)
|
|
127
131
|
if (P % _4n === _3n)
|
|
128
132
|
return pow(n, p1div4, P);
|
|
129
|
-
// P
|
|
133
|
+
// P ≡ 5 (mod 8)
|
|
130
134
|
if (P % _8n === _5n) {
|
|
131
135
|
const n2 = mod(n * _2n, P);
|
|
132
136
|
const v = pow(n2, (P - _5n) / _8n, P);
|
|
@@ -136,6 +140,7 @@ function sqrt(number, modulo) {
|
|
|
136
140
|
return r;
|
|
137
141
|
}
|
|
138
142
|
// Other cases: Tonelli-Shanks algorithm
|
|
143
|
+
// Check whether n is square
|
|
139
144
|
if (legendre(n, P) !== _1n)
|
|
140
145
|
throw new Error('Cannot find square root');
|
|
141
146
|
let q, s, z;
|
package/lib/utils.d.ts
CHANGED
|
@@ -30,3 +30,7 @@ export declare function nLength(n: bigint, nBitLength?: number): {
|
|
|
30
30
|
};
|
|
31
31
|
export declare function hashToPrivateScalar(hash: Hex, CURVE_ORDER: bigint, isLE?: boolean): bigint;
|
|
32
32
|
export declare function equalBytes(b1: Uint8Array, b2: Uint8Array): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Cryptographically secure PRNG
|
|
35
|
+
*/
|
|
36
|
+
export declare function randomBytes(bytesLength?: number): Uint8Array;
|
package/lib/utils.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.equalBytes = exports.hashToPrivateScalar = exports.nLength = exports.concatBytes = exports.ensureBytes = exports.numberToBytesLE = exports.numberToBytesBE = exports.bytesToNumberLE = exports.bytesToNumberBE = exports.hexToBytes = exports.hexToNumber = exports.numberToHexUnpadded = exports.bytesToHex = exports.validateOpts = void 0;
|
|
4
|
+
exports.randomBytes = exports.equalBytes = exports.hashToPrivateScalar = exports.nLength = exports.concatBytes = exports.ensureBytes = exports.numberToBytesLE = exports.numberToBytesBE = exports.bytesToNumberLE = exports.bytesToNumberBE = exports.hexToBytes = exports.hexToNumber = exports.numberToHexUnpadded = exports.bytesToHex = exports.validateOpts = void 0;
|
|
5
|
+
// The import here is via the package name. This is to ensure
|
|
6
|
+
// that exports mapping/resolution does fall into place.
|
|
7
|
+
const crypto_1 = require("@noble/curves/crypto");
|
|
5
8
|
function validateOpts(curve) {
|
|
6
9
|
for (const i of ['P', 'n', 'h', 'Gx', 'Gy']) {
|
|
7
10
|
if (typeof curve[i] !== 'bigint')
|
|
@@ -139,3 +142,18 @@ function equalBytes(b1, b2) {
|
|
|
139
142
|
return true;
|
|
140
143
|
}
|
|
141
144
|
exports.equalBytes = equalBytes;
|
|
145
|
+
/**
|
|
146
|
+
* Cryptographically secure PRNG
|
|
147
|
+
*/
|
|
148
|
+
function randomBytes(bytesLength = 32) {
|
|
149
|
+
if (crypto_1.crypto.web) {
|
|
150
|
+
return crypto_1.crypto.web.getRandomValues(new Uint8Array(bytesLength));
|
|
151
|
+
}
|
|
152
|
+
else if (crypto_1.crypto.node) {
|
|
153
|
+
return new Uint8Array(crypto_1.crypto.node.randomBytes(bytesLength).buffer);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
throw new Error("The environment doesn't have randomBytes function");
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.randomBytes = randomBytes;
|
package/lib/weierstrass.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
|
-
import { BasicCurve, Hex, PrivKey } from './utils.js';
|
|
2
|
+
import { BasicCurve, Hex, PrivKey, randomBytes as utilRandomBytes } from './utils.js';
|
|
3
3
|
import { Group, GroupConstructor } from './group.js';
|
|
4
4
|
export declare type CHash = {
|
|
5
5
|
(message: Uint8Array | string): Uint8Array;
|
|
@@ -23,9 +23,10 @@ export declare type CurveType = BasicCurve & {
|
|
|
23
23
|
lowS?: boolean;
|
|
24
24
|
hash: CHash;
|
|
25
25
|
hmac: HmacFnSync;
|
|
26
|
-
randomBytes
|
|
26
|
+
randomBytes?: (bytesLength?: number) => Uint8Array;
|
|
27
27
|
truncateHash?: (hash: Uint8Array, truncateOnly?: boolean) => bigint;
|
|
28
28
|
sqrtMod?: (n: bigint) => bigint;
|
|
29
|
+
normalizePrivateKey?: (key: PrivKey) => PrivKey;
|
|
29
30
|
endo?: EndomorphismOpts;
|
|
30
31
|
};
|
|
31
32
|
declare function validateOpts(curve: CurveType): Readonly<{
|
|
@@ -41,9 +42,10 @@ declare function validateOpts(curve: CurveType): Readonly<{
|
|
|
41
42
|
lowS: boolean;
|
|
42
43
|
readonly hash: CHash;
|
|
43
44
|
readonly hmac: HmacFnSync;
|
|
44
|
-
|
|
45
|
+
randomBytes: typeof utilRandomBytes;
|
|
45
46
|
readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
|
|
46
47
|
readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
|
|
48
|
+
readonly normalizePrivateKey?: ((key: PrivKey) => PrivKey) | undefined;
|
|
47
49
|
readonly endo?: EndomorphismOpts | undefined;
|
|
48
50
|
}>;
|
|
49
51
|
declare type Entropy = Hex | true;
|
package/lib/weierstrass.js
CHANGED
|
@@ -16,16 +16,22 @@ const group_js_1 = require("./group.js");
|
|
|
16
16
|
// Should be separate from overrides, since overrides can use information about curve (for example nBits)
|
|
17
17
|
function validateOpts(curve) {
|
|
18
18
|
const opts = (0, utils_js_1.validateOpts)(curve);
|
|
19
|
-
if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
|
|
20
|
-
throw new Error('Invalid hash function');
|
|
21
|
-
if (typeof opts.hmac !== 'function')
|
|
22
|
-
throw new Error('Invalid hmac function');
|
|
23
|
-
if (typeof opts.randomBytes !== 'function')
|
|
24
|
-
throw new Error('Invalid randomBytes function');
|
|
25
19
|
for (const i of ['a', 'b']) {
|
|
26
20
|
if (typeof opts[i] !== 'bigint')
|
|
27
21
|
throw new Error(`Invalid curve param ${i}=${opts[i]} (${typeof opts[i]})`);
|
|
28
22
|
}
|
|
23
|
+
for (const fn of ['hash', 'hmac']) {
|
|
24
|
+
if (typeof opts[fn] !== 'function')
|
|
25
|
+
throw new Error(`Invalid ${fn} function`);
|
|
26
|
+
}
|
|
27
|
+
for (const fn of ['randomBytes']) {
|
|
28
|
+
if (opts[fn] === undefined)
|
|
29
|
+
continue; // Optional
|
|
30
|
+
if (typeof opts[fn] !== 'function')
|
|
31
|
+
throw new Error(`Invalid ${fn} function`);
|
|
32
|
+
}
|
|
33
|
+
if (!Number.isSafeInteger(opts.hash.outputLen))
|
|
34
|
+
throw new Error('Invalid hash function');
|
|
29
35
|
const endo = opts.endo;
|
|
30
36
|
if (endo) {
|
|
31
37
|
if (opts.a !== _0n) {
|
|
@@ -38,7 +44,7 @@ function validateOpts(curve) {
|
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
46
|
// Set defaults
|
|
41
|
-
return Object.freeze({ lowS: true, ...opts });
|
|
47
|
+
return Object.freeze({ lowS: true, randomBytes: utils_js_1.randomBytes, ...opts });
|
|
42
48
|
}
|
|
43
49
|
// TODO: convert bits to bytes aligned to 32 bits? (224 for example)
|
|
44
50
|
// DER encoding utilities
|
|
@@ -186,6 +192,9 @@ function weierstrass(curveDef) {
|
|
|
186
192
|
}
|
|
187
193
|
function normalizePrivateKey(key) {
|
|
188
194
|
let num;
|
|
195
|
+
if (typeof CURVE.normalizePrivateKey === 'function') {
|
|
196
|
+
key = CURVE.normalizePrivateKey(key);
|
|
197
|
+
}
|
|
189
198
|
if (typeof key === 'bigint') {
|
|
190
199
|
num = key;
|
|
191
200
|
}
|
|
@@ -193,7 +202,7 @@ function weierstrass(curveDef) {
|
|
|
193
202
|
num = BigInt(key);
|
|
194
203
|
}
|
|
195
204
|
else if (typeof key === 'string') {
|
|
196
|
-
key = key.padStart(2 * groupLen, '0'); // Eth-like hexes
|
|
205
|
+
// key = key.padStart(2 * groupLen, '0'); // Eth-like hexes
|
|
197
206
|
if (key.length !== 2 * groupLen)
|
|
198
207
|
throw new Error(`Expected ${groupLen} bytes of private key`);
|
|
199
208
|
num = (0, utils_js_1.hexToNumber)(key);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noble/curves",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Minimal, zero-dependency JS implementation of elliptic curve cryptography",
|
|
5
5
|
"files": [
|
|
6
6
|
"index.js",
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"lib/esm"
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
|
-
"bench": "node
|
|
11
|
+
"bench": "node benchmark/index.js",
|
|
12
12
|
"build": "tsc && tsc -p tsconfig.esm.json",
|
|
13
13
|
"build:release": "rollup -c rollup.config.js",
|
|
14
|
-
"lint": "prettier --check 'src/**/*.{js,ts}'
|
|
15
|
-
"format": "prettier --write 'src/**/*.{js,ts}'
|
|
16
|
-
"test": "
|
|
14
|
+
"lint": "prettier --check 'src/**/*.{js,ts}'",
|
|
15
|
+
"format": "prettier --write 'src/**/*.{js,ts}'",
|
|
16
|
+
"test": "node test/index.test.js"
|
|
17
17
|
},
|
|
18
18
|
"author": "Paul Miller (https://paulmillr.com)",
|
|
19
19
|
"homepage": "https://paulmillr.com/noble/",
|
|
@@ -22,16 +22,32 @@
|
|
|
22
22
|
"url": "https://github.com/paulmillr/noble-curves.git"
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@noble/hashes": "1.1.5"
|
|
27
|
+
},
|
|
25
28
|
"devDependencies": {
|
|
26
29
|
"@rollup/plugin-node-resolve": "13.3.0",
|
|
30
|
+
"@scure/base": "^1.1.1",
|
|
31
|
+
"@scure/bip32": "^1.1.1",
|
|
32
|
+
"@scure/bip39": "^1.1.0",
|
|
33
|
+
"fast-check": "^3.4.0",
|
|
27
34
|
"micro-bmark": "0.2.0",
|
|
28
|
-
"micro-should": "0.2.0",
|
|
29
|
-
"prettier": "2.6.2",
|
|
35
|
+
"micro-should": "^0.2.0",
|
|
36
|
+
"prettier": "^2.6.2",
|
|
30
37
|
"rollup": "2.75.5",
|
|
31
38
|
"typescript": "4.7.3"
|
|
32
39
|
},
|
|
33
40
|
"main": "index.js",
|
|
34
41
|
"exports": {
|
|
42
|
+
"./crypto": {
|
|
43
|
+
"types": "./lib/crypto.d.ts",
|
|
44
|
+
"browser": {
|
|
45
|
+
"import": "./lib/esm/cryptoBrowser.js",
|
|
46
|
+
"default": "./lib/cryptoBrowser.js"
|
|
47
|
+
},
|
|
48
|
+
"import": "./lib/esm/crypto.js",
|
|
49
|
+
"default": "./lib/crypto.js"
|
|
50
|
+
},
|
|
35
51
|
"./edwards": {
|
|
36
52
|
"types": "./lib/edwards.d.ts",
|
|
37
53
|
"import": "./lib/esm/edwards.js",
|
|
@@ -58,6 +74,10 @@
|
|
|
58
74
|
"default": "./lib/utils.js"
|
|
59
75
|
}
|
|
60
76
|
},
|
|
77
|
+
"browser": {
|
|
78
|
+
"crypto": false,
|
|
79
|
+
"./crypto": "./cryptoBrowser.js"
|
|
80
|
+
},
|
|
61
81
|
"keywords": [
|
|
62
82
|
"elliptic",
|
|
63
83
|
"curve",
|
|
@@ -84,4 +104,4 @@
|
|
|
84
104
|
"url": "https://paulmillr.com/funding/"
|
|
85
105
|
}
|
|
86
106
|
]
|
|
87
|
-
}
|
|
107
|
+
}
|