@noble/curves 0.4.0 → 0.5.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.
Files changed (72) hide show
  1. package/README.md +203 -162
  2. package/lib/_shortw_utils.d.ts +75 -0
  3. package/lib/_shortw_utils.js +20 -0
  4. package/lib/{bls.d.ts → abstract/bls.d.ts} +2 -1
  5. package/lib/{bls.js → abstract/bls.js} +28 -27
  6. package/lib/{edwards.d.ts → abstract/edwards.d.ts} +17 -0
  7. package/lib/{edwards.js → abstract/edwards.js} +45 -4
  8. package/lib/{group.d.ts → abstract/group.d.ts} +2 -1
  9. package/lib/{group.js → abstract/group.js} +4 -3
  10. package/lib/{hashToCurve.d.ts → abstract/hash-to-curve.d.ts} +6 -0
  11. package/lib/{hashToCurve.js → abstract/hash-to-curve.js} +15 -2
  12. package/lib/{modular.d.ts → abstract/modular.d.ts} +10 -4
  13. package/lib/{modular.js → abstract/modular.js} +110 -19
  14. package/lib/{montgomery.d.ts → abstract/montgomery.d.ts} +2 -1
  15. package/lib/{montgomery.js → abstract/montgomery.js} +17 -8
  16. package/lib/{utils.d.ts → abstract/utils.d.ts} +1 -1
  17. package/lib/{utils.js → abstract/utils.js} +1 -1
  18. package/lib/{weierstrass.d.ts → abstract/weierstrass.d.ts} +28 -16
  19. package/lib/{weierstrass.js → abstract/weierstrass.js} +261 -127
  20. package/lib/bls12-381.d.ts +66 -0
  21. package/lib/bls12-381.js +1132 -0
  22. package/lib/bn.d.ts +7 -0
  23. package/lib/bn.js +24 -0
  24. package/lib/ed25519.d.ts +48 -0
  25. package/lib/ed25519.js +322 -0
  26. package/lib/ed448.d.ts +3 -0
  27. package/lib/ed448.js +128 -0
  28. package/lib/esm/_shortw_utils.js +15 -0
  29. package/lib/esm/{bls.js → abstract/bls.js} +25 -24
  30. package/lib/esm/{edwards.js → abstract/edwards.js} +45 -4
  31. package/lib/esm/{group.js → abstract/group.js} +4 -3
  32. package/lib/esm/{hashToCurve.js → abstract/hash-to-curve.js} +13 -1
  33. package/lib/esm/{modular.js → abstract/modular.js} +108 -18
  34. package/lib/esm/{montgomery.js → abstract/montgomery.js} +17 -8
  35. package/lib/esm/{utils.js → abstract/utils.js} +1 -1
  36. package/lib/esm/{weierstrass.js → abstract/weierstrass.js} +255 -123
  37. package/lib/esm/bls12-381.js +1129 -0
  38. package/lib/esm/bn.js +21 -0
  39. package/lib/esm/ed25519.js +318 -0
  40. package/lib/esm/ed448.js +125 -0
  41. package/lib/esm/index.js +2 -0
  42. package/lib/esm/jubjub.js +52 -0
  43. package/lib/esm/p192.js +21 -0
  44. package/lib/esm/p224.js +21 -0
  45. package/lib/esm/p256.js +39 -0
  46. package/lib/esm/p384.js +44 -0
  47. package/lib/esm/p521.js +58 -0
  48. package/lib/esm/pasta.js +29 -0
  49. package/lib/esm/secp256k1.js +290 -0
  50. package/lib/esm/stark.js +222 -0
  51. package/lib/index.d.ts +0 -0
  52. package/lib/index.js +2 -0
  53. package/lib/jubjub.d.ts +7 -0
  54. package/lib/jubjub.js +57 -0
  55. package/lib/p192.d.ts +130 -0
  56. package/lib/p192.js +24 -0
  57. package/lib/p224.d.ts +130 -0
  58. package/lib/p224.js +24 -0
  59. package/lib/p256.d.ts +130 -0
  60. package/lib/p256.js +42 -0
  61. package/lib/p384.d.ts +130 -0
  62. package/lib/p384.js +47 -0
  63. package/lib/p521.d.ts +131 -0
  64. package/lib/p521.js +61 -0
  65. package/lib/pasta.d.ts +4 -0
  66. package/lib/pasta.js +32 -0
  67. package/lib/secp256k1.d.ts +96 -0
  68. package/lib/secp256k1.js +294 -0
  69. package/lib/stark.d.ts +72 -0
  70. package/lib/stark.js +243 -0
  71. package/package.json +146 -50
  72. package/index.js +0 -1
package/README.md CHANGED
@@ -1,38 +1,44 @@
1
1
  # noble-curves
2
2
 
3
- Minimal, zero-dependency JS implementation of elliptic curve cryptography.
4
-
5
- - Short Weierstrass curve with ECDSA signatures
6
- - Twisted Edwards curve with EdDSA signatures
7
- - Montgomery curve for ECDH key agreement
8
-
9
- To keep the package minimal, no curve definitions are provided out-of-box. Use `micro-curve-definitions` module:
10
-
11
- - It provides P192, P224, P256, P384, P521, secp256k1, stark curve, bn254, pasta (pallas/vesta) short weierstrass curves
12
- - It also provides ed25519 and ed448 twisted edwards curves
13
- - Main reason for separate package is the fact hashing library (like `@noble/hashes`) is required for full functionality
14
- - We may reconsider merging packages in future, when a stable version would be ready
15
-
16
- Future plans:
17
-
18
- - hash to curve standard
19
- - point indistinguishability
20
- - pairings
3
+ Minimal, auditable JS implementation of elliptic curve cryptography.
4
+
5
+ - Short Weierstrass, Edwards, Montgomery curves
6
+ - ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
7
+ - [hash to curve](https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/)
8
+ for encoding or hashing an arbitrary string to a point on an elliptic curve
9
+ - Auditable, [fast](#speed)
10
+ - 🔻 Tree-shaking-friendly: there is no entry point, which ensures small size of your app
11
+ - 🔍 Unique tests ensure correctness. Wycheproof vectors included
12
+
13
+ There are two parts of the package:
14
+
15
+ 1. `abstract/` directory specifies zero-dependency EC algorithms
16
+ 2. root directory utilizes one dependency `@noble/hashes` and provides ready-to-use:
17
+ - NIST curves secp192r1/P192, secp224r1/P224, secp256r1/P256, secp384r1/P384, secp521r1/P521
18
+ - SECG curve secp256k1
19
+ - pairing-friendly curves bls12-381, bn254
20
+ - ed25519/curve25519/x25519/ristretto, edwards448/curve448/x448 RFC7748 / RFC8032 / ZIP215 stuff
21
+
22
+ Curves incorporate work from previous noble packages
23
+ ([secp256k1](https://github.com/paulmillr/noble-secp256k1),
24
+ [ed25519](https://github.com/paulmillr/noble-ed25519),
25
+ [bls12-381](https://github.com/paulmillr/noble-bls12-381)),
26
+ which had security audits and were developed from 2019 to 2022.
27
+ The goal is to replace them with lean UMD builds based on single-codebase noble-curves.
21
28
 
22
29
  ### This library belongs to _noble_ crypto
23
30
 
24
31
  > **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
25
32
 
26
- - No dependencies, small files
33
+ - Minimal dependencies, small files
27
34
  - Easily auditable TypeScript/JS code
28
35
  - Supported in all major browsers and stable node.js versions
29
36
  - All releases are signed with PGP keys
30
37
  - Check out [homepage](https://paulmillr.com/noble/) & all libraries:
31
- [secp256k1](https://github.com/paulmillr/noble-secp256k1),
38
+ [curves](https://github.com/paulmillr/noble-curves) ([secp256k1](https://github.com/paulmillr/noble-secp256k1),
32
39
  [ed25519](https://github.com/paulmillr/noble-ed25519),
33
- [bls12-381](https://github.com/paulmillr/noble-bls12-381),
34
- [hashes](https://github.com/paulmillr/noble-hashes),
35
- [curves](https://github.com/paulmillr/noble-curves)
40
+ [bls12-381](https://github.com/paulmillr/noble-bls12-381)),
41
+ [hashes](https://github.com/paulmillr/noble-hashes)
36
42
 
37
43
  ## Usage
38
44
 
@@ -44,82 +50,122 @@ Use NPM in node.js / browser, or include single file from
44
50
  The library does not have an entry point. It allows you to select specific primitives and drop everything else. If you only want to use secp256k1, just use the library with rollup or other bundlers. This is done to make your bundles tiny.
45
51
 
46
52
  ```ts
47
- import { weierstrass } from '@noble/curves/weierstrass'; // Short Weierstrass curve
48
- import { sha256 } from '@noble/hashes/sha256';
49
- import { hmac } from '@noble/hashes/hmac';
50
- import { concatBytes, randomBytes } from '@noble/hashes/utils';
51
-
52
- const secp256k1 = weierstrass({
53
- a: 0n,
54
- b: 7n,
55
- P: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,
56
- n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,
57
- Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
58
- Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
59
- hash: sha256,
60
- hmac: (k: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)),
61
- });
53
+ // Common.js and ECMAScript Modules (ESM)
54
+ import { secp256k1 } from '@noble/curves/secp256k1';
62
55
 
63
56
  const key = secp256k1.utils.randomPrivateKey();
64
57
  const pub = secp256k1.getPublicKey(key);
65
- const msg = randomBytes(32);
58
+ const msg = new Uint8Array(32).fill(1);
66
59
  const sig = secp256k1.sign(msg, key);
67
- secp256k1.verify(sig, msg, pub); // true
68
- sig.recoverPublicKey(msg); // == pub
69
- const someonesPubkey = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
70
- const shared = secp256k1.getSharedSecret(key, someonesPubkey);
60
+ secp256k1.verify(sig, msg, pub) === true;
61
+ sig.recoverPublicKey(msg) === pub;
62
+ const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
63
+ const shared = secp256k1.getSharedSecret(key, someonesPub);
64
+ ```
65
+
66
+ All curves:
67
+
68
+ ```ts
69
+ import { secp256k1 } from '@noble/curves/secp256k1';
70
+ import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519';
71
+ import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
72
+ import { p256 } from '@noble/curves/p256';
73
+ import { p384 } from '@noble/curves/p384';
74
+ import { p521 } from '@noble/curves/p521';
75
+ import { pallas, vesta } from '@noble/curves/pasta';
76
+ import * as stark from '@noble/curves/stark';
77
+ import { bls12_381 } from '@noble/curves/bls12-381';
78
+ import { bn254 } from '@noble/curves/bn';
79
+ import { jubjub } from '@noble/curves/jubjub';
71
80
  ```
72
81
 
82
+ To define a custom curve, check out API below.
83
+
73
84
  ## API
74
85
 
75
86
  - [Overview](#overview)
76
- - [edwards: Twisted Edwards curve](#edwards-twisted-edwards-curve)
77
- - [montgomery: Montgomery curve](#montgomery-montgomery-curve)
78
- - [weierstrass: Short Weierstrass curve](#weierstrass-short-weierstrass-curve)
79
- - [modular](#modular)
80
- - [utils](#utils)
87
+ - [abstract/edwards: Twisted Edwards curve](#abstract/edwards-twisted-edwards-curve)
88
+ - [abstract/montgomery: Montgomery curve](#abstract/montgomery-montgomery-curve)
89
+ - [abstract/weierstrass: Short Weierstrass curve](#abstract/weierstrass-short-weierstrass-curve)
90
+ - [abstract/modular](#abstract/modular)
91
+ - [abstract/utils](#abstract/utils)
81
92
 
82
93
  ### Overview
83
94
 
84
- * To initialize new curve, you must specify its variables, order (number of points on curve), field prime (over which the modular division would be done)
85
- * All curves expose same generic interface:
86
- * `getPublicKey()`, `sign()`, `verify()` functions
87
- * `Point` conforming to `Group` interface with add/multiply/double/negate/add/equals methods
88
- * `CURVE` object with curve variables like `Gx`, `Gy`, `P` (field), `n` (order)
89
- * `utils` object with `randomPrivateKey()`, `mod()`, `invert()` methods (`mod CURVE.P`)
90
- * All arithmetics is done with JS bigints over finite fields
91
- * Many features require hashing, which is not provided. `@noble/hashes` can be used for this purpose.
95
+ There are following zero-dependency abstract algorithms:
96
+
97
+ ```ts
98
+ import { bls } from '@noble/curves/abstract/bls';
99
+ import { twistedEdwards } from '@noble/curves/abstract/edwards';
100
+ import { montgomery } from '@noble/curves/abstract/montgomery';
101
+ import { weierstrass } from '@noble/curves/abstract/weierstrass';
102
+ import * as mod from '@noble/curves/abstract/modular';
103
+ import * as utils from '@noble/curves/abstract/utils';
104
+ ```
105
+
106
+ They allow to define a new curve in a few lines of code:
107
+
108
+ ```ts
109
+ import { Fp } from '@noble/curves/abstract/modular';
110
+ import { weierstrass } from '@noble/curves/abstract/weierstrass';
111
+ import { hmac } from '@noble/hashes/hmac';
112
+ import { sha256 } from '@noble/hashes/sha256';
113
+ import { concatBytes, randomBytes } from '@noble/hashes/utils';
114
+
115
+ const secp256k1 = weierstrass({
116
+ a: 0n,
117
+ b: 7n,
118
+ Fp: Fp(2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n),
119
+ n: 2n ** 256n - 432420386565659656852420866394968145599n,
120
+ Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
121
+ Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
122
+ hash: sha256,
123
+ hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)),
124
+ randomBytes,
125
+ });
126
+ ```
127
+
128
+ - To initialize new curve, you must specify its variables, order (number of points on curve), field prime (over which the modular division would be done)
129
+ - All curves expose same generic interface:
130
+ - `getPublicKey()`, `sign()`, `verify()` functions
131
+ - `Point` conforming to `Group` interface with add/multiply/double/negate/add/equals methods
132
+ - `CURVE` object with curve variables like `Gx`, `Gy`, `Fp` (field), `n` (order)
133
+ - `utils` object with `randomPrivateKey()`, `mod()`, `invert()` methods (`mod CURVE.P`)
134
+ - All arithmetics is done with JS bigints over finite fields, which is defined from `modular` sub-module
135
+ - Many features require hashing, which is not provided. `@noble/hashes` can be used for this purpose.
92
136
  Any other library must conform to the CHash interface:
93
- ```ts
94
- export type CHash = {
95
- (message: Uint8Array): Uint8Array;
96
- blockLen: number; outputLen: number; create(): any;
97
- };
98
- ```
99
- * w-ary non-adjacent form (wNAF) method with constant-time adjustments is used for point multiplication.
137
+ ```ts
138
+ export type CHash = {
139
+ (message: Uint8Array): Uint8Array;
140
+ blockLen: number;
141
+ outputLen: number;
142
+ create(): any;
143
+ };
144
+ ```
145
+ - w-ary non-adjacent form (wNAF) method with constant-time adjustments is used for point multiplication.
100
146
  It is possible to enable precomputes for edwards & weierstrass curves.
101
- Precomputes are calculated once (takes ~20-40ms), after that most `G` multiplications
102
- - for example, `getPublicKey()`, `sign()` and similar methods - would be much faster.
103
- Use `curve.utils.precompute()`
104
- * Special params that tune performance can be optionally provided. For example:
105
- * `sqrtMod` square root calculation, used for point decompression
106
- * `endo` endomorphism options for Koblitz curves
147
+ Precomputes are calculated once (takes ~20-40ms), after that most `G` base point multiplications:
148
+ for example, `getPublicKey()`, `sign()` and similar methods - would be much faster.
149
+ Use `curve.utils.precompute()` to adjust precomputation window size
150
+ - You could use optional special params to tune performance:
151
+ - `Fp({sqrt})` square root calculation, used for point decompression
152
+ - `endo` endomorphism options for Koblitz curves
107
153
 
108
- ### edwards: Twisted Edwards curve
154
+ ### abstract/edwards: Twisted Edwards curve
109
155
 
110
156
  Twisted Edwards curve's formula is: ax² + y² = 1 + dx²y².
111
157
 
112
- * You must specify curve params `a`, `d`, field `P`, order `n`, cofactor `h`, and coordinates `Gx`, `Gy` of generator point.
113
- * For EdDSA signatures, params `hash` is also required. `adjustScalarBytes` which instructs how to change private scalars could be specified.
158
+ - You must specify curve params `a`, `d`, field `Fp`, order `n`, cofactor `h` and coordinates `Gx`, `Gy` of generator point
159
+ - For EdDSA signatures, params `hash` is also required. `adjustScalarBytes` which instructs how to change private scalars could be specified
114
160
 
115
161
  ```typescript
116
- import { twistedEdwards } from '@noble/curves/edwards'; // Twisted Edwards curve
162
+ import { twistedEdwards } from '@noble/curves/abstract/edwards';
163
+ import { div } from '@noble/curves/abstract/modular';
117
164
  import { sha512 } from '@noble/hashes/sha512';
118
- import * as mod from '@noble/curves/modular';
119
165
 
120
166
  const ed25519 = twistedEdwards({
121
167
  a: -1n,
122
- d: mod.div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
168
+ d: div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
123
169
  P: 2n ** 255n - 19n,
124
170
  n: 2n ** 252n + 27742317777372353535851937790883648493n,
125
171
  h: 8n,
@@ -127,14 +173,19 @@ const ed25519 = twistedEdwards({
127
173
  Gy: 46316835694926478169428394003475163141307993866256225615783033603165251855960n,
128
174
  hash: sha512,
129
175
  randomBytes,
130
- adjustScalarBytes(bytes) { // optional
176
+ adjustScalarBytes(bytes) {
177
+ // optional in general, mandatory in ed25519
131
178
  bytes[0] &= 248;
132
179
  bytes[31] &= 127;
133
180
  bytes[31] |= 64;
134
181
  return bytes;
135
182
  },
136
183
  } as const);
137
- ed25519.getPublicKey(ed25519.utils.randomPrivateKey());
184
+ const key = ed25519.utils.randomPrivateKey();
185
+ const pub = ed25519.getPublicKey(key);
186
+ const msg = new TextEncoder().encode('hello world'); // strings not accepted, must be Uint8Array
187
+ const sig = ed25519.sign(msg, key);
188
+ ed25519.verify(sig, msg, pub) === true;
138
189
  ```
139
190
 
140
191
  `twistedEdwards()` returns `CurveFn` of following type:
@@ -163,7 +214,7 @@ export type CurveFn = {
163
214
  };
164
215
  ```
165
216
 
166
- ### montgomery: Montgomery curve
217
+ ### abstract/montgomery: Montgomery curve
167
218
 
168
219
  For now the module only contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748.
169
220
 
@@ -172,6 +223,8 @@ Proper Elliptic Curve Points are not implemented yet.
172
223
  You must specify curve field, `a24` special variable, `montgomeryBits`, `nByteLength`, and coordinate `u` of generator point.
173
224
 
174
225
  ```typescript
226
+ import { montgomery } from '@noble/curves/abstract/montgomery';
227
+
175
228
  const x25519 = montgomery({
176
229
  P: 2n ** 255n - 19n,
177
230
  a24: 121665n, // TODO: change to a
@@ -180,7 +233,9 @@ const x25519 = montgomery({
180
233
  Gu: '0900000000000000000000000000000000000000000000000000000000000000',
181
234
 
182
235
  // Optional params
183
- powPminus2: (x: bigint): bigint => { return mod.pow(x, P-2, P); },
236
+ powPminus2: (x: bigint): bigint => {
237
+ return mod.pow(x, P - 2, P);
238
+ },
184
239
  adjustScalarBytes(bytes) {
185
240
  bytes[0] &= 248;
186
241
  bytes[31] &= 127;
@@ -190,27 +245,27 @@ const x25519 = montgomery({
190
245
  });
191
246
  ```
192
247
 
193
- ### weierstrass: Short Weierstrass curve
248
+ ### abstract/weierstrass: Short Weierstrass curve
194
249
 
195
250
  Short Weierstrass curve's formula is: y² = x³ + ax + b. Uses deterministic ECDSA from RFC6979. You can also specify `extraEntropy` in `sign()`.
196
251
 
197
- * You must specify curve params: `a`, `b`; field `P`; curve order `n`; coordinates `Gx`, `Gy` of generator point
198
- * For ECDSA, you must specify `hash`, `hmac`. It is also possible to recover keys from signatures
199
- * For ECDH, use `getSharedSecret(privKeyA, pubKeyB)`
200
- * Optional params are `lowS` (default value), `sqrtMod` (square root chain) and `endo` (endomorphism)
252
+ - You must specify curve params: `a`, `b`, field `Fp`, order `n`, cofactor `h` and coordinates `Gx`, `Gy` of generator point
253
+ - For ECDSA, you must specify `hash`, `hmac`. It is also possible to recover keys from signatures
254
+ - For ECDH, use `getSharedSecret(privKeyA, pubKeyB)`
255
+ - Optional params are `lowS` (default value) and `endo` (endomorphism)
201
256
 
202
257
  ```typescript
203
- import { weierstrass } from '@noble/curves/weierstrass'; // Short Weierstrass curve
258
+ import { Fp } from '@noble/curves/abstract/modular';
259
+ import { weierstrass } from '@noble/curves/abstract/weierstrass'; // Short Weierstrass curve
204
260
  import { sha256 } from '@noble/hashes/sha256';
205
261
  import { hmac } from '@noble/hashes/hmac';
206
262
  import { concatBytes, randomBytes } from '@noble/hashes/utils';
207
263
 
208
264
  const secp256k1 = weierstrass({
209
- // Required params
210
265
  a: 0n,
211
266
  b: 7n,
212
- P: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,
213
- n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,
267
+ Fp: Fp(2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n),
268
+ n: 2n ** 256n - 432420386565659656852420866394968145599n,
214
269
  Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
215
270
  Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
216
271
  hash: sha256,
@@ -218,19 +273,15 @@ const secp256k1 = weierstrass({
218
273
  randomBytes,
219
274
 
220
275
  // Optional params
221
- // Cofactor
222
- h: BigInt(1),
223
- // Allow only low-S signatures by default in sign() and verify()
224
- lowS: true,
225
- // More efficient curve-specific implementation of square root
226
- sqrtMod(y: bigint) { return sqrt(y); },
227
- // Endomorphism options
276
+ h: 1n, // Cofactor
277
+ lowS: true, // Allow only low-S signatures by default in sign() and verify()
228
278
  endo: {
279
+ // Endomorphism options for Koblitz curve
229
280
  // Beta param
230
- beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
281
+ beta: 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501een,
231
282
  // Split scalar k into k1, k2
232
283
  splitScalar: (k: bigint) => {
233
- return { k1neg: true, k1: 512n, k2neg: false, k2: 448n };
284
+ // return { k1neg: true, k1: 512n, k2neg: false, k2: 448n };
234
285
  },
235
286
  },
236
287
  });
@@ -255,14 +306,17 @@ export type CurveFn = {
255
306
  getSharedSecret: (privateA: PrivKey, publicB: PubKey, isCompressed?: boolean) => Uint8Array;
256
307
  sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
257
308
  verify: (
258
- signature: Hex | SignatureType, msgHash: Hex, publicKey: PubKey, opts?: {lowS?: boolean;}
309
+ signature: Hex | SignatureType,
310
+ msgHash: Hex,
311
+ publicKey: PubKey,
312
+ opts?: { lowS?: boolean }
259
313
  ) => boolean;
260
314
  Point: PointConstructor;
261
- JacobianPoint: JacobianPointConstructor;
315
+ ProjectivePoint: ProjectivePointConstructor;
262
316
  Signature: SignatureConstructor;
263
317
  utils: {
264
- mod: (a: bigint, b?: bigint) => bigint;
265
- invert: (number: bigint, modulo?: bigint) => bigint;
318
+ mod: (a: bigint) => bigint;
319
+ invert: (number: bigint) => bigint;
266
320
  isValidPrivateKey(privateKey: PrivKey): boolean;
267
321
  hashToPrivateKey: (hash: Hex) => Uint8Array;
268
322
  randomPrivateKey: () => Uint8Array;
@@ -270,23 +324,26 @@ export type CurveFn = {
270
324
  };
271
325
  ```
272
326
 
273
- ### modular
327
+ ### abstract/modular
274
328
 
275
329
  Modular arithmetics utilities.
276
330
 
277
331
  ```typescript
278
- import * as mod from '@noble/curves/modular';
279
- mod.mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
280
- mod.invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse
281
- mod.div(5n, 17n, 10n); // 5/17 mod 10 == 5 * invert(17) mod 10; division
282
- mod.invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion
283
- mod.sqrt(21n, 73n); // sqrt(21) mod 73; square root
332
+ import { mod, invert, div, invertBatch, sqrt, Fp } from '@noble/curves/abstract/modular';
333
+ mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
334
+ invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse
335
+ div(5n, 17n, 10n); // 5/17 mod 10 == 5 * invert(17) mod 10; division
336
+ invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion
337
+ 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);
284
341
  ```
285
342
 
286
- ### utils
343
+ ### abstract/utils
287
344
 
288
345
  ```typescript
289
- import * as utils from '@noble/curves/utils';
346
+ import * as utils from '@noble/curves/abstract/utils';
290
347
 
291
348
  utils.bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
292
349
  utils.hexToBytes('deadbeef');
@@ -315,59 +372,43 @@ We consider infrastructure attacks like rogue NPM modules very important; that's
315
372
  Benchmark results on Apple M2 with node v18.10:
316
373
 
317
374
  ```
318
- ==== secp256k1 ====
319
- - getPublicKey1 (samples: 10000)
320
- noble_old x 8,131 ops/sec @ 122μs/op
321
- secp256k1 x 7,374 ops/sec @ 135μs/op
322
- - getPublicKey255 (samples: 10000)
323
- noble_old x 7,894 ops/sec @ 126μs/op
324
- secp256k1 x 7,327 ops/sec @ 136μs/op
325
- - sign (samples: 5000)
326
- noble_old x 5,243 ops/sec @ 190μs/op
327
- secp256k1 x 4,834 ops/sec @ 206μs/op
328
- - getSharedSecret (samples: 1000)
329
- noble_old x 653 ops/sec @ 1ms/op
330
- secp256k1 x 634 ops/sec @ 1ms/op
331
- - verify (samples: 1000)
332
- secp256k1_old x 1,038 ops/sec @ 962μs/op
333
- secp256k1 x 1,009 ops/sec @ 990μs/op
334
- ==== ed25519 ====
335
- - getPublicKey (samples: 10000)
336
- old x 8,632 ops/sec @ 115μs/op
337
- noble x 8,390 ops/sec @ 119μs/op
338
- - sign (samples: 5000)
339
- old x 4,376 ops/sec @ 228μs/op
340
- noble x 4,233 ops/sec @ 236μs/op
341
- - verify (samples: 1000)
342
- old x 865 ops/sec @ 1ms/op
343
- noble x 860 ops/sec @ 1ms/op
344
- ==== ed448 ====
345
- - getPublicKey (samples: 5000)
346
- noble x 3,224 ops/sec @ 310μs/op
347
- - sign (samples: 2500)
348
- noble x 1,561 ops/sec @ 640μs/op
349
- - verify (samples: 500)
350
- noble x 313 ops/sec @ 3ms/op
351
- ==== nist ====
352
- - getPublicKey (samples: 2500)
353
- P256 x 7,993 ops/sec @ 125μs/op
354
- P384 x 3,819 ops/sec @ 261μs/op
355
- P521 x 2,074 ops/sec @ 481μs/op
356
- - sign (samples: 1000)
357
- P256 x 5,327 ops/sec @ 187μs/op
358
- P384 x 2,728 ops/sec @ 366μs/op
359
- P521 x 1,594 ops/sec @ 626μs/op
360
- - verify (samples: 250)
361
- P256 x 806 ops/sec @ 1ms/op
362
- P384 x 353 ops/sec @ 2ms/op
363
- P521 x 171 ops/sec @ 5ms/op
375
+ getPublicKey
376
+ secp256k1 x 5,241 ops/sec @ 190μs/op
377
+ P256 x 7,993 ops/sec @ 125μs/op
378
+ P384 x 3,819 ops/sec @ 261μs/op
379
+ P521 x 2,074 ops/sec @ 481μs/op
380
+ ed25519 x 8,390 ops/sec @ 119μs/op
381
+ ed448 x 3,224 ops/sec @ 310μs/op
382
+ sign
383
+ secp256k1 x 3,934 ops/sec @ 254μs/op
384
+ P256 x 5,327 ops/sec @ 187μs/op
385
+ P384 x 2,728 ops/sec @ 366μs/op
386
+ P521 x 1,594 ops/sec @ 626μs/op
387
+ ed25519 x 4,233 ops/sec @ 236μs/op
388
+ ed448 x 1,561 ops/sec @ 640μs/op
389
+ verify
390
+ secp256k1 x 731 ops/sec @ 1ms/op
391
+ P256 x 806 ops/sec @ 1ms/op
392
+ P384 x 353 ops/sec @ 2ms/op
393
+ P521 x 171 ops/sec @ 5ms/op
394
+ ed25519 x 860 ops/sec @ 1ms/op
395
+ ed448 x 313 ops/sec @ 3ms/op
396
+ getSharedSecret
397
+ secp256k1 x 445 ops/sec @ 2ms/op
398
+ recoverPublicKey
399
+ secp256k1 x 732 ops/sec @ 1ms/op
400
+ ==== bls12-381 ====
401
+ getPublicKey x 817 ops/sec @ 1ms/op
402
+ sign x 50 ops/sec @ 19ms/op
403
+ verify x 34 ops/sec @ 28ms/op
404
+ pairing x 89 ops/sec @ 11ms/op
364
405
  ==== stark ====
365
- - pedersen (samples: 500)
366
- old x 85 ops/sec @ 11ms/op
367
- noble x 1,216 ops/sec @ 822μs/op
368
- - verify (samples: 500)
369
- old x 302 ops/sec @ 3ms/op
370
- noble x 698 ops/sec @ 1ms/op
406
+ pedersen
407
+ old x 85 ops/sec @ 11ms/op
408
+ noble x 1,216 ops/sec @ 822μs/op
409
+ verify
410
+ old x 302 ops/sec @ 3ms/op
411
+ noble x 698 ops/sec @ 1ms/op
371
412
  ```
372
413
 
373
414
  ## Contributing & testing
@@ -0,0 +1,75 @@
1
+ import { randomBytes } from '@noble/hashes/utils';
2
+ import { CurveType } from './abstract/weierstrass.js';
3
+ import { CHash } from './abstract/utils.js';
4
+ export declare function getHash(hash: CHash): {
5
+ hash: CHash;
6
+ hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => Uint8Array;
7
+ randomBytes: typeof randomBytes;
8
+ };
9
+ declare type CurveDef = Readonly<Omit<CurveType, 'hash' | 'hmac' | 'randomBytes'>>;
10
+ export declare function createCurve(curveDef: CurveDef, defHash: CHash): Readonly<{
11
+ create: (hash: CHash) => import("./abstract/weierstrass.js").CurveFn;
12
+ CURVE: Readonly<{
13
+ readonly nBitLength: number;
14
+ readonly nByteLength: number;
15
+ readonly Fp: import("./abstract/modular.js").Field<bigint>;
16
+ readonly n: bigint;
17
+ readonly h: bigint;
18
+ readonly hEff?: bigint | undefined;
19
+ readonly Gx: bigint;
20
+ readonly Gy: bigint;
21
+ readonly wrapPrivateKey?: boolean | undefined;
22
+ readonly allowInfinityPoint?: boolean | undefined;
23
+ readonly a: bigint;
24
+ readonly b: bigint;
25
+ readonly normalizePrivateKey?: ((key: import("./abstract/utils.js").PrivKey) => import("./abstract/utils.js").PrivKey) | undefined;
26
+ readonly endo?: {
27
+ beta: bigint;
28
+ splitScalar: (k: bigint) => {
29
+ k1neg: boolean;
30
+ k1: bigint;
31
+ k2neg: boolean;
32
+ k2: bigint;
33
+ };
34
+ } | undefined;
35
+ readonly isTorsionFree?: ((c: import("./abstract/weierstrass.js").ProjectiveConstructor<bigint>, point: import("./abstract/weierstrass.js").ProjectivePointType<bigint>) => boolean) | undefined;
36
+ readonly clearCofactor?: ((c: import("./abstract/weierstrass.js").ProjectiveConstructor<bigint>, point: import("./abstract/weierstrass.js").ProjectivePointType<bigint>) => import("./abstract/weierstrass.js").ProjectivePointType<bigint>) | undefined;
37
+ readonly htfDefaults?: import("./abstract/hash-to-curve.js").htfOpts | undefined;
38
+ readonly mapToCurve?: ((scalar: bigint[]) => {
39
+ x: bigint;
40
+ y: bigint;
41
+ }) | undefined;
42
+ lowS: boolean;
43
+ readonly hash: CHash;
44
+ readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
45
+ readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
46
+ readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
47
+ }>;
48
+ getPublicKey: (privateKey: import("./abstract/utils.js").PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
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
+ lowS?: boolean | undefined;
52
+ extraEntropy?: (true | import("./abstract/utils.js").Hex) | undefined;
53
+ } | undefined) => import("./abstract/weierstrass.js").SignatureType;
54
+ 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
+ lowS?: boolean | undefined;
56
+ } | undefined) => boolean;
57
+ Point: import("./abstract/weierstrass.js").PointConstructor<bigint>;
58
+ ProjectivePoint: import("./abstract/weierstrass.js").ProjectiveConstructor<bigint>;
59
+ Signature: import("./abstract/weierstrass.js").SignatureConstructor;
60
+ utils: {
61
+ mod: (a: bigint, b?: bigint | undefined) => bigint;
62
+ invert: (number: bigint, modulo?: bigint | undefined) => bigint;
63
+ _bigintToBytes: (num: bigint) => Uint8Array;
64
+ _bigintToString: (num: bigint) => string;
65
+ _normalizePrivateKey: (key: import("./abstract/utils.js").PrivKey) => bigint;
66
+ _normalizePublicKey: (publicKey: import("./abstract/weierstrass.js").PubKey) => import("./abstract/weierstrass.js").PointType<bigint>;
67
+ _isWithinCurveOrder: (num: bigint) => boolean;
68
+ _isValidFieldElement: (num: bigint) => boolean;
69
+ _weierstrassEquation: (x: bigint) => bigint;
70
+ isValidPrivateKey(privateKey: import("./abstract/utils.js").PrivKey): boolean;
71
+ hashToPrivateKey: (hash: import("./abstract/utils.js").Hex) => Uint8Array;
72
+ randomPrivateKey: () => Uint8Array;
73
+ };
74
+ }>;
75
+ export {};
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCurve = exports.getHash = void 0;
4
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5
+ const hmac_1 = require("@noble/hashes/hmac");
6
+ const utils_1 = require("@noble/hashes/utils");
7
+ const weierstrass_js_1 = require("./abstract/weierstrass.js");
8
+ function getHash(hash) {
9
+ return {
10
+ hash,
11
+ hmac: (key, ...msgs) => (0, hmac_1.hmac)(hash, key, (0, utils_1.concatBytes)(...msgs)),
12
+ randomBytes: utils_1.randomBytes,
13
+ };
14
+ }
15
+ exports.getHash = getHash;
16
+ function createCurve(curveDef, defHash) {
17
+ const create = (hash) => (0, weierstrass_js_1.weierstrass)({ ...curveDef, ...getHash(hash) });
18
+ return Object.freeze({ ...create(defHash), create });
19
+ }
20
+ exports.createCurve = createCurve;
@@ -1,7 +1,8 @@
1
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
1
2
  import * as mod from './modular.js';
2
3
  import * as utils from './utils.js';
3
4
  import { Hex, PrivKey } from './utils.js';
4
- import { htfOpts, stringToBytes, hash_to_field, expand_message_xmd } from './hashToCurve.js';
5
+ import { htfOpts, stringToBytes, hash_to_field, expand_message_xmd } from './hash-to-curve.js';
5
6
  import { CurvePointsType, PointType, CurvePointsRes } from './weierstrass.js';
6
7
  declare type Fp = bigint;
7
8
  export declare type SignatureCoder<Fp2> = {