@noble/curves 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +14 -19
  2. package/lib/crypto.d.ts +4 -0
  3. package/lib/crypto.js +8 -0
  4. package/lib/cryptoBrowser.d.ts +4 -0
  5. package/lib/cryptoBrowser.js +7 -0
  6. package/lib/definitions/_shortw_utils.d.ts +63 -0
  7. package/lib/definitions/_shortw_utils.js +18 -0
  8. package/lib/definitions/bn.d.ts +7 -0
  9. package/lib/definitions/bn.js +23 -0
  10. package/lib/definitions/ed25519.d.ts +49 -0
  11. package/lib/definitions/ed25519.js +308 -0
  12. package/lib/definitions/ed448.d.ts +3 -0
  13. package/lib/definitions/ed448.js +127 -0
  14. package/lib/definitions/index.d.ts +0 -0
  15. package/lib/definitions/index.js +2 -0
  16. package/lib/definitions/jubjub.d.ts +7 -0
  17. package/lib/definitions/jubjub.js +55 -0
  18. package/lib/definitions/p192.d.ts +112 -0
  19. package/lib/definitions/p192.js +23 -0
  20. package/lib/definitions/p224.d.ts +112 -0
  21. package/lib/definitions/p224.js +24 -0
  22. package/lib/definitions/p256.d.ts +112 -0
  23. package/lib/definitions/p256.js +23 -0
  24. package/lib/definitions/p384.d.ts +112 -0
  25. package/lib/definitions/p384.js +24 -0
  26. package/lib/definitions/p521.d.ts +113 -0
  27. package/lib/definitions/p521.js +36 -0
  28. package/lib/definitions/pasta.d.ts +2 -0
  29. package/lib/definitions/pasta.js +32 -0
  30. package/lib/definitions/secp256k1.d.ts +87 -0
  31. package/lib/definitions/secp256k1.js +245 -0
  32. package/lib/definitions/stark.d.ts +62 -0
  33. package/lib/definitions/stark.js +248 -0
  34. package/lib/edwards.d.ts +2 -2
  35. package/lib/edwards.js +2 -6
  36. package/lib/esm/crypto.js +5 -0
  37. package/lib/esm/cryptoBrowser.js +4 -0
  38. package/lib/esm/definitions/_shortw_utils.js +13 -0
  39. package/lib/esm/definitions/bn.js +20 -0
  40. package/lib/esm/definitions/ed25519.js +304 -0
  41. package/lib/esm/definitions/ed448.js +124 -0
  42. package/lib/esm/definitions/index.js +2 -0
  43. package/lib/esm/definitions/jubjub.js +50 -0
  44. package/lib/esm/definitions/p192.js +20 -0
  45. package/lib/esm/definitions/p224.js +21 -0
  46. package/lib/esm/definitions/p256.js +20 -0
  47. package/lib/esm/definitions/p384.js +21 -0
  48. package/lib/esm/definitions/p521.js +33 -0
  49. package/lib/esm/definitions/pasta.js +29 -0
  50. package/lib/esm/definitions/secp256k1.js +241 -0
  51. package/lib/esm/definitions/stark.js +227 -0
  52. package/lib/esm/edwards.js +3 -7
  53. package/lib/esm/modular.js +14 -9
  54. package/lib/esm/utils.js +17 -0
  55. package/lib/esm/weierstrass.js +17 -9
  56. package/lib/modular.d.ts +8 -1
  57. package/lib/modular.js +14 -9
  58. package/lib/utils.d.ts +4 -0
  59. package/lib/utils.js +19 -1
  60. package/lib/weierstrass.d.ts +5 -3
  61. package/lib/weierstrass.js +16 -8
  62. package/package.json +38 -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
- // Calculates Legendre symbol: num^((P-1)/2)
114
- function legendre(num, fieldPrime) {
115
- return pow(num, (fieldPrime - _1n) / _2n, fieldPrime);
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 = 3 (mod 4)
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 = 5 (mod 8)
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;
@@ -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: (bytesLength?: number) => Uint8Array;
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
- readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
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;
@@ -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,6 @@ 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
197
205
  if (key.length !== 2 * groupLen)
198
206
  throw new Error(`Expected ${groupLen} bytes of private key`);
199
207
  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.2.1",
3
+ "version": "0.3.1",
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 curve-definitions/benchmark/index.js",
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}' 'curve-definitions/src/**/*.{js,ts}'",
15
- "format": "prettier --write 'src/**/*.{js,ts}' 'curve-definitions/src/**/*.{js,ts}'",
16
- "test": "cd curve-definitions; node test/index.test.js"
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",
@@ -56,8 +72,22 @@
56
72
  "types": "./lib/utils.d.ts",
57
73
  "import": "./lib/esm/utils.js",
58
74
  "default": "./lib/utils.js"
75
+ },
76
+ "./definitions/secp256k1": {
77
+ "types": "./lib/definitions/secp256k1.d.ts",
78
+ "import": "./lib/esm/definitions/secp256k1.js",
79
+ "default": "./lib/definitions/secp256k1.js"
80
+ },
81
+ "./definitions/ed25519": {
82
+ "types": "./lib/definitions/ed25519.d.ts",
83
+ "import": "./lib/esm/definitions/ed25519.js",
84
+ "default": "./lib/definitions/ed25519.js"
59
85
  }
60
86
  },
87
+ "browser": {
88
+ "crypto": false,
89
+ "./crypto": "./cryptoBrowser.js"
90
+ },
61
91
  "keywords": [
62
92
  "elliptic",
63
93
  "curve",
@@ -84,4 +114,4 @@
84
114
  "url": "https://paulmillr.com/funding/"
85
115
  }
86
116
  ]
87
- }
117
+ }