@noble/curves 1.1.0 → 1.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.
Files changed (101) hide show
  1. package/README.md +295 -258
  2. package/abstract/bls.d.ts +27 -10
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +60 -10
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/curve.js.map +1 -1
  7. package/abstract/edwards.js.map +1 -1
  8. package/abstract/hash-to-curve.d.ts +2 -2
  9. package/abstract/hash-to-curve.d.ts.map +1 -1
  10. package/abstract/hash-to-curve.js +22 -16
  11. package/abstract/hash-to-curve.js.map +1 -1
  12. package/abstract/modular.d.ts +51 -11
  13. package/abstract/modular.d.ts.map +1 -1
  14. package/abstract/modular.js +79 -21
  15. package/abstract/modular.js.map +1 -1
  16. package/abstract/montgomery.d.ts.map +1 -1
  17. package/abstract/montgomery.js +5 -7
  18. package/abstract/montgomery.js.map +1 -1
  19. package/abstract/poseidon.d.ts.map +1 -1
  20. package/abstract/poseidon.js +39 -41
  21. package/abstract/poseidon.js.map +1 -1
  22. package/abstract/utils.d.ts +3 -1
  23. package/abstract/utils.d.ts.map +1 -1
  24. package/abstract/utils.js +56 -31
  25. package/abstract/utils.js.map +1 -1
  26. package/abstract/weierstrass.d.ts +25 -28
  27. package/abstract/weierstrass.d.ts.map +1 -1
  28. package/abstract/weierstrass.js +17 -15
  29. package/abstract/weierstrass.js.map +1 -1
  30. package/bls12-381.d.ts.map +1 -1
  31. package/bls12-381.js +142 -88
  32. package/bls12-381.js.map +1 -1
  33. package/bn254.d.ts +3 -2
  34. package/bn254.d.ts.map +1 -1
  35. package/bn254.js +3 -2
  36. package/bn254.js.map +1 -1
  37. package/ed25519.d.ts +5 -2
  38. package/ed25519.d.ts.map +1 -1
  39. package/ed25519.js +17 -8
  40. package/ed25519.js.map +1 -1
  41. package/ed448.d.ts +53 -2
  42. package/ed448.d.ts.map +1 -1
  43. package/ed448.js +216 -29
  44. package/ed448.js.map +1 -1
  45. package/esm/abstract/bls.js +61 -11
  46. package/esm/abstract/bls.js.map +1 -1
  47. package/esm/abstract/curve.js.map +1 -1
  48. package/esm/abstract/edwards.js.map +1 -1
  49. package/esm/abstract/hash-to-curve.js +23 -17
  50. package/esm/abstract/hash-to-curve.js.map +1 -1
  51. package/esm/abstract/modular.js +75 -20
  52. package/esm/abstract/modular.js.map +1 -1
  53. package/esm/abstract/montgomery.js +5 -7
  54. package/esm/abstract/montgomery.js.map +1 -1
  55. package/esm/abstract/poseidon.js +39 -41
  56. package/esm/abstract/poseidon.js.map +1 -1
  57. package/esm/abstract/utils.js +54 -30
  58. package/esm/abstract/utils.js.map +1 -1
  59. package/esm/abstract/weierstrass.js +17 -15
  60. package/esm/abstract/weierstrass.js.map +1 -1
  61. package/esm/bls12-381.js +143 -89
  62. package/esm/bls12-381.js.map +1 -1
  63. package/esm/bn254.js +3 -2
  64. package/esm/bn254.js.map +1 -1
  65. package/esm/ed25519.js +17 -8
  66. package/esm/ed25519.js.map +1 -1
  67. package/esm/ed448.js +218 -32
  68. package/esm/ed448.js.map +1 -1
  69. package/esm/jubjub.js +1 -1
  70. package/esm/jubjub.js.map +1 -1
  71. package/esm/p256.js +2 -2
  72. package/esm/p256.js.map +1 -1
  73. package/esm/p384.js +2 -2
  74. package/esm/p384.js.map +1 -1
  75. package/esm/p521.js +3 -3
  76. package/esm/p521.js.map +1 -1
  77. package/esm/package.json +1 -4
  78. package/esm/secp256k1.js +6 -6
  79. package/esm/secp256k1.js.map +1 -1
  80. package/jubjub.js.map +1 -1
  81. package/p256.js +2 -2
  82. package/p256.js.map +1 -1
  83. package/p384.js +2 -2
  84. package/p384.js.map +1 -1
  85. package/p521.js +3 -3
  86. package/p521.js.map +1 -1
  87. package/package.json +7 -6
  88. package/secp256k1.js +6 -6
  89. package/secp256k1.js.map +1 -1
  90. package/src/abstract/bls.ts +120 -22
  91. package/src/abstract/hash-to-curve.ts +24 -17
  92. package/src/abstract/modular.ts +81 -22
  93. package/src/abstract/montgomery.ts +4 -6
  94. package/src/abstract/poseidon.ts +39 -40
  95. package/src/abstract/utils.ts +55 -26
  96. package/src/abstract/weierstrass.ts +29 -18
  97. package/src/bls12-381.ts +132 -75
  98. package/src/bn254.ts +3 -2
  99. package/src/ed25519.ts +19 -8
  100. package/src/ed448.ts +267 -34
  101. package/src/jubjub.ts +1 -1
package/README.md CHANGED
@@ -2,33 +2,29 @@
2
2
 
3
3
  Audited & minimal JS implementation of elliptic curve cryptography.
4
4
 
5
- - 🔒 [**Audited**](#security) by an independent security firm
5
+ - 🔒 [**Audited**](#security) by independent security firms
6
6
  - 🔻 Tree-shaking-friendly: use only what's necessary, other code won't be included
7
7
  - 🏎 Ultra-fast, hand-optimized for caveats of JS engines
8
8
  - 🔍 Unique tests ensure correctness: property-based, cross-library and Wycheproof vectors, fuzzing
9
9
  - ➰ Short Weierstrass, Edwards, Montgomery curves
10
10
  - ✍️ ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
11
- - 🔖 SUF-CMA and SBS (non-repudiation) for ed25519, ed448 and others
12
- - #️⃣ Hash-to-curve
13
- for encoding or hashing an arbitrary string to an elliptic curve point
11
+ - 🔖 SUF-CMA, SBS (non-repudiation), ZIP215 (consensus friendliness) features for ed25519
12
+ - #️⃣ hash-to-curve for encoding or hashing an arbitrary string to an elliptic curve point
14
13
  - 🧜‍♂️ Poseidon ZK-friendly hash
15
14
 
16
- Check out [Upgrading](#upgrading) if you've previously used single-feature noble
17
- packages. See [Resources](#resources) for articles and real-world software that uses curves.
18
-
19
15
  ### This library belongs to _noble_ crypto
20
16
 
21
17
  > **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
22
18
 
23
- - No dependencies, protection against supply chain attacks
24
- - Auditable TypeScript / JS code
25
- - Supported in all major browsers and stable node.js versions
26
- - All releases are signed with PGP keys
27
- - Check out [homepage](https://paulmillr.com/noble/) & all libraries:
28
- [curves](https://github.com/paulmillr/noble-curves)
29
- (4kb versions [secp256k1](https://github.com/paulmillr/noble-secp256k1),
30
- [ed25519](https://github.com/paulmillr/noble-ed25519)),
19
+ - Zero or minimal dependencies
20
+ - Highly readable TypeScript / JS code
21
+ - PGP-signed releases and transparent NPM builds
22
+ - All libraries:
23
+ [ciphers](https://github.com/paulmillr/noble-ciphers),
24
+ [curves](https://github.com/paulmillr/noble-curves),
31
25
  [hashes](https://github.com/paulmillr/noble-hashes)
26
+ - [Check out homepage](https://paulmillr.com/noble/)
27
+ for reading resources, documentation and apps built with noble
32
28
 
33
29
  ## Usage
34
30
 
@@ -36,36 +32,56 @@ packages. See [Resources](#resources) for articles and real-world software that
36
32
 
37
33
  We support all major platforms and runtimes.
38
34
  For [Deno](https://deno.land), ensure to use [npm specifier](https://deno.land/manual@v1.28.0/node/npm_specifiers).
39
- For React Native, you may need a [polyfill for crypto.getRandomValues](https://github.com/LinusU/react-native-get-random-values).
40
- If you don't like NPM, a standalone [noble-curves.js](https://github.com/paulmillr/noble-curves/releases) is also available.
41
-
42
- The library is tree-shaking-friendly and does not expose root entry point as
43
- `@noble/curves`. Instead, you need to import specific primitives.
44
- This is done to ensure small size of your apps.
35
+ For React Native, you may need a [polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values).
36
+ A standalone file [noble-curves.js](https://github.com/paulmillr/noble-curves/releases) is also available.
45
37
 
46
- The package consists of two parts:
38
+ ```js
39
+ // import * from '@noble/curves'; // Error: use sub-imports, to ensure small app size
40
+ import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
41
+ // import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
42
+ ```
47
43
 
48
- * [Implementations](#implementations), utilizing one dependency [noble-hashes](https://github.com/paulmillr/noble-hashes),
49
- providing ready-to-use:
50
- - NIST curves secp256r1 / p256, secp384r1 / p384, secp521r1 / p521
51
- - SECG curve secp256k1
52
- - ed25519 / curve25519 / x25519 / ristretto255, edwards448 / curve448 / x448
53
- - pairing-friendly curves bls12-381, bn254
54
- - [pasta](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) curves
55
- 2. [Abstract](#abstract-api), zero-dependency elliptic curve algorithms
44
+ - [Implementations](#implementations)
45
+ - [ECDSA signature scheme](#ecdsa-signature-scheme)
46
+ - [ECDSA public key recovery & extra entropy](#ecdsa-public-key-recovery--extra-entropy)
47
+ - [ECDH: Elliptic Curve Diffie-Hellman](#ecdh-elliptic-curve-diffie-hellman)
48
+ - [Schnorr signatures over secp256k1, BIP340](#schnorr-signatures-over-secp256k1-bip340)
49
+ - [ed25519, X25519, ristretto255](#ed25519-x25519-ristretto255)
50
+ - [ed448, X448, decaf448](#ed448-x448-decaf448)
51
+ - [bls12-381](#bls12-381)
52
+ - [All available imports](#all-available-imports)
53
+ - [Accessing a curve's variables](#accessing-a-curves-variables)
54
+ - [Abstract API](#abstract-api)
55
+ - [weierstrass: Short Weierstrass curve](#weierstrass-short-weierstrass-curve)
56
+ - [edwards: Twisted Edwards curve](#edwards-twisted-edwards-curve)
57
+ - [montgomery: Montgomery curve](#montgomery-montgomery-curve)
58
+ - [bls: Barreto-Lynn-Scott curves](#bls-barreto-lynn-scott-curves)
59
+ - [hash-to-curve: Hashing strings to curve points](#hash-to-curve-hashing-strings-to-curve-points)
60
+ - [poseidon: Poseidon hash](#poseidon-poseidon-hash)
61
+ - [modular: Modular arithmetics utilities](#modular-modular-arithmetics-utilities)
62
+ - [Creating private keys from hashes](#creating-private-keys-from-hashes)
63
+ - [utils: Useful utilities](#utils-useful-utilities)
64
+ - [Security](#security)
65
+ - [Speed](#speed)
66
+ - [Upgrading](#upgrading)
67
+ - [Contributing & testing](#contributing--testing)
68
+ - [Resources](#resources)
56
69
 
57
70
  ### Implementations
58
71
 
59
- #### Generic example for all curves, secp256k1
72
+ Implementations use [noble-hashes](https://github.com/paulmillr/noble-hashes).
73
+ If you want to use a different hashing library, [abstract API](#abstract-api) doesn't depend on them.
74
+
75
+ #### ECDSA signature scheme
76
+
77
+ Generic example that works for all curves, shown for secp256k1:
60
78
 
61
79
  ```ts
62
- // Each curve has similar methods
63
- import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
64
- // import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
80
+ import { secp256k1 } from '@noble/curves/secp256k1';
65
81
  const priv = secp256k1.utils.randomPrivateKey();
66
82
  const pub = secp256k1.getPublicKey(priv);
67
- const msg = new Uint8Array(32).fill(1);
68
- const sig = secp256k1.sign(msg, priv);
83
+ const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
84
+ const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
69
85
  const isValid = secp256k1.verify(sig, msg, pub) === true;
70
86
 
71
87
  // hex strings are also supported besides Uint8Arrays:
@@ -73,29 +89,24 @@ const privHex = '46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c12623
73
89
  const pub2 = secp256k1.getPublicKey(privHex);
74
90
  ```
75
91
 
76
- #### All imports
92
+ #### ECDSA public key recovery & extra entropy
77
93
 
78
- ```typescript
79
- import { secp256k1, schnorr } from '@noble/curves/secp256k1';
80
- import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519';
81
- import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
82
- import { p256 } from '@noble/curves/p256';
83
- import { p384 } from '@noble/curves/p384';
84
- import { p521 } from '@noble/curves/p521';
85
- import { pallas, vesta } from '@noble/curves/pasta';
86
- import { bls12_381 } from '@noble/curves/bls12-381';
87
- import { bn254 } from '@noble/curves/bn254';
88
- import { jubjub } from '@noble/curves/jubjub';
94
+ ```ts
95
+ // let sig = secp256k1.Signature.fromCompact(sigHex); // or .fromDER(sigDERHex)
96
+ // sig = sig.addRecoveryBit(bit); // bit is not serialized into compact / der format
97
+ sig.recoverPublicKey(msg).toRawBytes(); // === pub; // public key recovery
98
+
99
+ // extraEntropy https://moderncrypto.org/mail-archive/curves/2017/000925.html
100
+ const sigImprovedSecurity = secp256k1.sign(msg, priv, { extraEntropy: true });
89
101
  ```
90
102
 
91
- #### ECDSA public key recovery & ECDH
103
+ #### ECDH: Elliptic Curve Diffie-Hellman
92
104
 
93
105
  ```ts
94
- // extraEntropy https://moderncrypto.org/mail-archive/curves/2017/000925.html
95
- const sigImprovedSecurity = secp256k1.sign(msg, priv, { extraEntropy: true });
96
- sig.recoverPublicKey(msg) === pub; // public key recovery
106
+ // 1. The output includes parity byte. Strip it using shared.slice(1)
107
+ // 2. The output is not hashed. More secure way is sha256(shared) or hkdf(shared)
97
108
  const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
98
- const shared = secp256k1.getSharedSecret(priv, someonesPub); // ECDH
109
+ const shared = secp256k1.getSharedSecret(priv, someonesPub);
99
110
  ```
100
111
 
101
112
  #### Schnorr signatures over secp256k1 (BIP340)
@@ -129,7 +140,6 @@ It has SUF-CMA (strong unforgeability under chosen message attacks).
129
140
  and additionally provides non-repudiation with SBS [(Strongly Binding Signatures)](https://eprint.iacr.org/2020/1244).
130
141
 
131
142
  X25519 follows [RFC7748](https://www.rfc-editor.org/rfc/rfc7748).
132
- ristretto255 follows [irtf draft](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448).
133
143
 
134
144
  ```ts
135
145
  // Variants from RFC8032: with context, prehashed
@@ -147,17 +157,36 @@ x25519.getPublicKey(x25519.utils.randomPrivateKey());
147
157
  import { edwardsToMontgomeryPub, edwardsToMontgomeryPriv } from '@noble/curves/ed25519';
148
158
  edwardsToMontgomeryPub(ed25519.getPublicKey(ed25519.utils.randomPrivateKey()));
149
159
  edwardsToMontgomeryPriv(ed25519.utils.randomPrivateKey());
160
+ ```
150
161
 
162
+ ristretto255 follows [irtf draft](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448).
163
+
164
+ ```ts
151
165
  // hash-to-curve, ristretto255
152
- import { hashToCurve, encodeToCurve, RistrettoPoint } from '@noble/curves/ed25519';
166
+ import { utf8ToBytes } from '@noble/hashes/utils';
167
+ import { sha512 } from '@noble/hashes/sha512';
168
+ import {
169
+ hashToCurve,
170
+ encodeToCurve,
171
+ RistrettoPoint,
172
+ hashToRistretto255,
173
+ } from '@noble/curves/ed25519';
174
+
175
+ const msg = utf8ToBytes('Ristretto is traditionally a short shot of espresso coffee');
176
+ hashToCurve(msg);
177
+
153
178
  const rp = RistrettoPoint.fromHex(
154
179
  '6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919'
155
180
  );
156
- RistrettoPoint.hashToCurve('Ristretto is traditionally a short shot of espresso coffee');
157
- // also has add(), equals(), multiply(), toRawBytes() methods
181
+ RistrettoPoint.BASE.multiply(2n).add(rp).subtract(RistrettoPoint.BASE).toRawBytes();
182
+ RistrettoPoint.ZERO.equals(dp) === false;
183
+ // pre-hashed hash-to-curve
184
+ RistrettoPoint.hashToCurve(sha512(msg));
185
+ // full hash-to-curve including domain separation tag
186
+ hashToRistretto255(msg, { DST: 'ristretto255_XMD:SHA-512_R255MAP_RO_' });
158
187
  ```
159
188
 
160
- #### ed448, X448
189
+ #### ed448, X448, decaf448
161
190
 
162
191
  ```ts
163
192
  import { ed448 } from '@noble/curves/ed448';
@@ -167,17 +196,65 @@ const msg = new TextEncoder().encode('whatsup');
167
196
  const sig = ed448.sign(msg, priv);
168
197
  ed448.verify(sig, msg, pub);
169
198
 
170
- import { ed448ph, ed448ctx, x448, hashToCurve, encodeToCurve } from '@noble/curves/ed448';
199
+ // Variants from RFC8032: prehashed
200
+ import { ed448ph } from '@noble/curves/ed448';
201
+ ```
202
+
203
+ ECDH using Curve448 aka X448, follows [RFC7748](https://www.rfc-editor.org/rfc/rfc7748).
204
+
205
+ ```ts
206
+ import { x448 } from '@noble/curves/ed448';
171
207
  x448.getSharedSecret(priv, pub) === x448.scalarMult(priv, pub); // aliases
172
208
  x448.getPublicKey(priv) === x448.scalarMultBase(priv);
209
+
210
+ // ed448 => x448 conversion
211
+ import { edwardsToMontgomeryPub } from '@noble/curves/ed448';
212
+ edwardsToMontgomeryPub(ed448.getPublicKey(ed448.utils.randomPrivateKey()));
213
+ ```
214
+
215
+ decaf448 follows [irtf draft](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448).
216
+
217
+ ```ts
218
+ import { utf8ToBytes } from '@noble/hashes/utils';
219
+ import { shake256 } from '@noble/hashes/sha3';
220
+ import { hashToCurve, encodeToCurve, DecafPoint, hashToDecaf448 } from '@noble/curves/ed448';
221
+
222
+ const msg = utf8ToBytes('Ristretto is traditionally a short shot of espresso coffee');
223
+ hashToCurve(msg);
224
+
225
+ const dp = DecafPoint.fromHex(
226
+ 'c898eb4f87f97c564c6fd61fc7e49689314a1f818ec85eeb3bd5514ac816d38778f69ef347a89fca817e66defdedce178c7cc709b2116e75'
227
+ );
228
+ DecafPoint.BASE.multiply(2n).add(dp).subtract(DecafPoint.BASE).toRawBytes();
229
+ DecafPoint.ZERO.equals(dp) === false;
230
+ // pre-hashed hash-to-curve
231
+ DecafPoint.hashToCurve(shake256(msg, { dkLen: 112 }));
232
+ // full hash-to-curve including domain separation tag
233
+ hashToDecaf448(msg, { DST: 'decaf448_XOF:SHAKE256_D448MAP_RO_' });
173
234
  ```
174
235
 
175
- Same RFC7748 / RFC8032 are followed.
236
+ Same RFC7748 / RFC8032 / IRTF draft are followed.
176
237
 
177
238
  #### bls12-381
178
239
 
179
240
  See [abstract/bls](#abstractbls-barreto-lynn-scott-curves).
180
241
 
242
+ #### All available imports
243
+
244
+ ```typescript
245
+ import { secp256k1, schnorr } from '@noble/curves/secp256k1';
246
+ import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519';
247
+ import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
248
+ import { p256 } from '@noble/curves/p256';
249
+ import { p384 } from '@noble/curves/p384';
250
+ import { p521 } from '@noble/curves/p521';
251
+ import { pallas, vesta } from '@noble/curves/pasta';
252
+ import { bls12_381 } from '@noble/curves/bls12-381';
253
+ import { bn254 } from '@noble/curves/bn254'; // also known as alt_bn128
254
+ import { jubjub } from '@noble/curves/jubjub';
255
+ import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/abstract/utils';
256
+ ```
257
+
181
258
  #### Accessing a curve's variables
182
259
 
183
260
  ```ts
@@ -199,18 +276,7 @@ Precomputes are enabled for weierstrass and edwards BASE points of a curve. You
199
276
  could precompute any other point (e.g. for ECDH) using `utils.precompute()`
200
277
  method: check out examples.
201
278
 
202
- There are following zero-dependency algorithms:
203
-
204
- - [abstract/weierstrass: Short Weierstrass curve](#abstractweierstrass-short-weierstrass-curve)
205
- - [abstract/edwards: Twisted Edwards curve](#abstractedwards-twisted-edwards-curve)
206
- - [abstract/montgomery: Montgomery curve](#abstractmontgomery-montgomery-curve)
207
- - [abstract/bls: Barreto-Lynn-Scott curves](#abstractbls-barreto-lynn-scott-curves)
208
- - [abstract/hash-to-curve: Hashing strings to curve points](#abstracthash-to-curve-hashing-strings-to-curve-points)
209
- - [abstract/poseidon: Poseidon hash](#abstractposeidon-poseidon-hash)
210
- - [abstract/modular: Modular arithmetics utilities](#abstractmodular-modular-arithmetics-utilities)
211
- - [abstract/utils: General utilities](#abstractutils-general-utilities)
212
-
213
- ### abstract/weierstrass: Short Weierstrass curve
279
+ ### weierstrass: Short Weierstrass curve
214
280
 
215
281
  ```ts
216
282
  import { weierstrass } from '@noble/curves/abstract/weierstrass';
@@ -233,7 +299,7 @@ const secq256k1 = weierstrass({
233
299
  randomBytes,
234
300
  });
235
301
 
236
- // Replace weierstrass with weierstrassPoints if you don't need ECDSA, hash, hmac, randomBytes
302
+ // Replace weierstrass() with weierstrassPoints() if you don't need ECDSA, hash, hmac, randomBytes
237
303
  ```
238
304
 
239
305
  Short Weierstrass curve's formula is `y² = x³ + ax + b`. `weierstrass`
@@ -252,8 +318,17 @@ type CHash = {
252
318
  outputLen: number;
253
319
  create(): any;
254
320
  };
321
+
322
+ // example
323
+ function sha256(message: Uint8Array) { return _internal_lowlvl(message) }
324
+ sha256.outputLen = 32; // 32 bytes of output for sha2-256
255
325
  ```
256
326
 
327
+ **Message hash** is expected instead of message itself:
328
+
329
+ - `sign(msgHash, privKey)` is default behavior, assuming you pre-hash msg with sha2, or other hash
330
+ - `sign(msg, privKey, {prehash: true})` option can be used if you want to pass the message itself
331
+
257
332
  **Weierstrass points:**
258
333
 
259
334
  1. Exported as `ProjectivePoint`
@@ -349,6 +424,7 @@ More examples:
349
424
  const priv = secq256k1.utils.randomPrivateKey();
350
425
  secq256k1.getPublicKey(priv); // Convert private key to public.
351
426
  const sig = secq256k1.sign(msg, priv); // Sign msg with private key.
427
+ const sig2 = secq256k1.sign(msg, priv, { prehash: true }); // hash(msg)
352
428
  secq256k1.verify(sig, msg, priv); // Verify if sig is correct.
353
429
 
354
430
  const Point = secq256k1.ProjectivePoint;
@@ -371,7 +447,7 @@ const fast = secq256k1.utils.precompute(8, Point.fromHex(someonesPubKey));
371
447
  fast.multiply(privKey); // much faster ECDH now
372
448
  ```
373
449
 
374
- ### abstract/edwards: Twisted Edwards curve
450
+ ### edwards: Twisted Edwards curve
375
451
 
376
452
  ```ts
377
453
  import { twistedEdwards } from '@noble/curves/abstract/edwards';
@@ -461,7 +537,7 @@ interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
461
537
  }
462
538
  ```
463
539
 
464
- ### abstract/montgomery: Montgomery curve
540
+ ### montgomery: Montgomery curve
465
541
 
466
542
  ```typescript
467
543
  import { montgomery } from '@noble/curves/abstract/montgomery';
@@ -488,7 +564,7 @@ Proper Elliptic Curve Points are not implemented yet.
488
564
 
489
565
  You must specify curve params `Fp`, `a`, `Gu` coordinate of u, `montgomeryBits` and `nByteLength`.
490
566
 
491
- ### abstract/bls: Barreto-Lynn-Scott curves
567
+ ### bls: Barreto-Lynn-Scott curves
492
568
 
493
569
  The module abstracts BLS (Barreto-Lynn-Scott) pairing-friendly elliptic curve construction.
494
570
  They allow to construct [zk-SNARKs](https://z.cash/technology/zksnarks/) and
@@ -496,6 +572,10 @@ use aggregated, batch-verifiable
496
572
  [threshold signatures](https://medium.com/snigirev.stepan/bls-signatures-better-than-schnorr-5a7fe30ea716),
497
573
  using Boneh-Lynn-Shacham signature scheme.
498
574
 
575
+ The module doesn't expose `CURVE` property: use `G1.CURVE`, `G2.CURVE` instead.
576
+ Only BLS12-381 is implemented currently.
577
+ Defining BLS12-377 and BLS24 should be straightforward.
578
+
499
579
  Main methods and properties are:
500
580
 
501
581
  - `getPublicKey(privateKey)`
@@ -507,8 +587,13 @@ Main methods and properties are:
507
587
  - `Signature` property with `fromHex`, `toHex` methods
508
588
  - `fields` containing `Fp`, `Fp2`, `Fp6`, `Fp12`, `Fr`
509
589
 
510
- Right now we only implement BLS12-381 (compatible with ETH and others),
511
- but in theory defining BLS12-377, BLS24 should be straightforward. An example:
590
+ The default BLS uses short public keys (with public keys in G1 and signatures in G2).
591
+ Short signatures (public keys in G2 and signatures in G1) is also supported, using:
592
+
593
+ - `getPublicKeyForShortSignatures(privateKey)`
594
+ - `signShortSignature(message, privateKey)`
595
+ - `verifyShortSignature(signature, message, publicKey)`
596
+ - `aggregateShortSignatures(signatures)`
512
597
 
513
598
  ```ts
514
599
  import { bls12_381 as bls } from '@noble/curves/bls12-381';
@@ -539,66 +624,22 @@ const aggSignature3 = bls.aggregateSignatures(signatures3);
539
624
  const isValid3 = bls.verifyBatch(aggSignature3, messages, publicKeys);
540
625
  console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
541
626
 
542
- // bls.pairing(PointG1, PointG2) // pairings
543
- // bls.G1.ProjectivePoint.BASE, bls.G2.ProjectivePoint.BASE
544
- // bls.fields.Fp, bls.fields.Fp2, bls.fields.Fp12, bls.fields.Fr
627
+ // Pairings, with and without final exponentiation
628
+ bls.pairing(PointG1, PointG2);
629
+ bls.pairing(PointG1, PointG2, false);
630
+ bls.fields.Fp12.finalExponentiate(bls.fields.Fp12.mul(PointG1, PointG2));
545
631
 
546
- // hash-to-curve examples can be seen below
547
- ```
548
-
549
- Full types:
632
+ // Others
633
+ bls.G1.ProjectivePoint.BASE, bls.G2.ProjectivePoint.BASE
634
+ bls.fields.Fp, bls.fields.Fp2, bls.fields.Fp12, bls.fields.Fr
635
+ bls.params.x, bls.params.r, bls.params.G1b, bls.params.G2b
550
636
 
551
- ```ts
552
- getPublicKey: (privateKey: PrivKey) => Uint8Array;
553
- sign: {
554
- (message: Hex, privateKey: PrivKey): Uint8Array;
555
- (message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
556
- };
557
- verify: (
558
- signature: Hex | ProjPointType<Fp2>,
559
- message: Hex | ProjPointType<Fp2>,
560
- publicKey: Hex | ProjPointType<Fp>
561
- ) => boolean;
562
- verifyBatch: (
563
- signature: Hex | ProjPointType<Fp2>,
564
- messages: (Hex | ProjPointType<Fp2>)[],
565
- publicKeys: (Hex | ProjPointType<Fp>)[]
566
- ) => boolean;
567
- aggregatePublicKeys: {
568
- (publicKeys: Hex[]): Uint8Array;
569
- (publicKeys: ProjPointType<Fp>[]): ProjPointType<Fp>;
570
- };
571
- aggregateSignatures: {
572
- (signatures: Hex[]): Uint8Array;
573
- (signatures: ProjPointType<Fp2>[]): ProjPointType<Fp2>;
574
- };
575
- millerLoop: (ell: [Fp2, Fp2, Fp2][], g1: [Fp, Fp]) => Fp12;
576
- pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
577
- G1: CurvePointsRes<Fp> & ReturnType<typeof htf.createHasher<Fp>>;
578
- G2: CurvePointsRes<Fp2> & ReturnType<typeof htf.createHasher<Fp2>>;
579
- Signature: SignatureCoder<Fp2>;
580
- params: {
581
- x: bigint;
582
- r: bigint;
583
- G1b: bigint;
584
- G2b: Fp2;
585
- };
586
- fields: {
587
- Fp: IField<Fp>;
588
- Fp2: IField<Fp2>;
589
- Fp6: IField<Fp6>;
590
- Fp12: IField<Fp12>;
591
- Fr: IField<bigint>;
592
- };
593
- utils: {
594
- randomPrivateKey: () => Uint8Array;
595
- calcPairingPrecomputes: (p: AffinePoint<Fp2>) => [Fp2, Fp2, Fp2][];
596
- };
637
+ // hash-to-curve examples can be seen below
597
638
  ```
598
639
 
599
- ### abstract/hash-to-curve: Hashing strings to curve points
640
+ ### hash-to-curve: Hashing strings to curve points
600
641
 
601
- The module allows to hash arbitrary strings to elliptic curve points. Implements [hash-to-curve v16](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16).
642
+ The module allows to hash arbitrary strings to elliptic curve points. Implements [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380).
602
643
 
603
644
  Every curve has exported `hashToCurve` and `encodeToCurve` methods. You should always prefer `hashToCurve` for security:
604
645
 
@@ -614,19 +655,17 @@ bls12_381.G1.hashToCurve(randomBytes(), { DST: 'another' });
614
655
  bls12_381.G2.hashToCurve(randomBytes(), { DST: 'custom' });
615
656
  ```
616
657
 
617
- If you need low-level methods from spec:
618
-
619
- `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.
620
-
621
- Hash must conform to `CHash` interface (see [weierstrass section](#abstractweierstrass-short-weierstrass-curve)).
658
+ Low-level methods from the spec:
622
659
 
623
660
  ```ts
661
+ // produces a uniformly random byte string using a cryptographic hash function H that outputs b bits.
624
662
  function expand_message_xmd(
625
663
  msg: Uint8Array,
626
664
  DST: Uint8Array,
627
665
  lenInBytes: number,
628
- H: CHash
666
+ H: CHash // For CHash see abstract/weierstrass docs section
629
667
  ): Uint8Array;
668
+ // produces a uniformly random byte string using an extendable-output function (XOF) H.
630
669
  function expand_message_xof(
631
670
  msg: Uint8Array,
632
671
  DST: Uint8Array,
@@ -634,13 +673,9 @@ function expand_message_xof(
634
673
  k: number,
635
674
  H: CHash
636
675
  ): Uint8Array;
637
- ```
638
-
639
- `hash_to_field(msg, count, options)`
640
- [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3)
641
- hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
676
+ // Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
677
+ function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][];
642
678
 
643
- ```ts
644
679
  /**
645
680
  * * `DST` is a domain separation tag, defined in section 2.2.5
646
681
  * * `p` characteristic of F, where F is a finite field of characteristic p and order q = p^m
@@ -651,26 +686,16 @@ hashes arbitrary-length byte strings to a list of one or more elements of a fini
651
686
  */
652
687
  type UnicodeOrBytes = string | Uint8Array;
653
688
  type Opts = {
654
- DST: UnicodeOrBytes;
655
- p: bigint;
656
- m: number;
657
- k: number;
658
- expand?: 'xmd' | 'xof';
659
- hash: CHash;
689
+ DST: UnicodeOrBytes;
690
+ p: bigint;
691
+ m: number;
692
+ k: number;
693
+ expand?: 'xmd' | 'xof';
694
+ hash: CHash;
660
695
  };
661
-
662
- /**
663
- * Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
664
- * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
665
- * @param msg a byte string containing the message to hash
666
- * @param count the number of elements of F to output
667
- * @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`, see above
668
- * @returns [u_0, ..., u_(count - 1)], a list of field elements.
669
- */
670
- function hash_to_field(msg: Uint8Array, count: number, options: Opts): bigint[][];
671
696
  ```
672
697
 
673
- ### abstract/poseidon: Poseidon hash
698
+ ### poseidon: Poseidon hash
674
699
 
675
700
  Implements [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash.
676
701
 
@@ -694,7 +719,7 @@ type PoseidonOpts = {
694
719
  const instance = poseidon(opts: PoseidonOpts);
695
720
  ```
696
721
 
697
- ### abstract/modular: Modular arithmetics utilities
722
+ ### modular: Modular arithmetics utilities
698
723
 
699
724
  ```ts
700
725
  import * as mod from '@noble/curves/abstract/modular';
@@ -710,30 +735,41 @@ mod.invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse
710
735
  mod.invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion
711
736
  ```
712
737
 
713
- #### Creating private keys from hashes
738
+ Field operations are not constant-time: they are using JS bigints, see [security](#security).
739
+ The fact is mostly irrelevant, but the important method to keep in mind is `pow`,
740
+ which may leak exponent bits, when used naïvely.
741
+
742
+ `mod.Field` is always **field over prime**. Non-prime fields aren't supported for now.
743
+ We don't test for prime-ness for speed and because algorithms are probabilistic anyway.
744
+ Initializing a non-prime field could make your app suspectible to
745
+ DoS (infilite loop) on Tonelli-Shanks square root calculation.
746
+
747
+ Unlike `mod.invert`, `mod.invertBatch` won't throw on `0`: make sure to throw an error yourself.
714
748
 
715
- Suppose you have `sha256(something)` (e.g. from HMAC) and you want to make a private key from it.
716
- Even though p256 or secp256k1 may have 32-byte private keys,
717
- and sha256 output is also 32-byte, you can't just use it and reduce it modulo `CURVE.n`.
749
+ #### Creating private keys from hashes
718
750
 
719
- Doing so will make the result key [biased](https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/).
751
+ You can't simply make a 32-byte private key from a 32-byte hash.
752
+ Doing so will make the key [biased](https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/).
720
753
 
721
- To avoid the bias, we implement FIPS 186 B.4.1, which allows to take arbitrary
722
- byte array and produce valid scalars / private keys with bias being neglible.
754
+ To make the bias negligible, we follow [FIPS 186-5 A.2](https://csrc.nist.gov/publications/detail/fips/186/5/final)
755
+ and [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380#section-5.2).
756
+ This means, for 32-byte key, we would need 48-byte hash to get 2^-128 bias, which matches curve security level.
723
757
 
724
- Use [hash-to-curve](#abstracthash-to-curve-hashing-strings-to-curve-points) if you need
725
- hashing to **public keys**; the function in the module instead operates on **private keys**.
758
+ `hashToPrivateScalar()` that hashes to **private key** was created for this purpose.
759
+ Use [abstract/hash-to-curve](#abstracthash-to-curve-hashing-strings-to-curve-points)
760
+ if you need to hash to **public key**.
726
761
 
727
762
  ```ts
728
763
  import { p256 } from '@noble/curves/p256';
729
764
  import { sha256 } from '@noble/hashes/sha256';
730
765
  import { hkdf } from '@noble/hashes/hkdf';
766
+ import * as mod from '@noble/curves/abstract/modular';
731
767
  const someKey = new Uint8Array(32).fill(2); // Needs to actually be random, not .fill(2)
732
- const derived = hkdf(sha256, someKey, undefined, 'application', 40); // 40 bytes
768
+ const derived = hkdf(sha256, someKey, undefined, 'application', 48); // 48 bytes for 32-byte priv
733
769
  const validPrivateKey = mod.hashToPrivateScalar(derived, p256.CURVE.n);
734
770
  ```
735
771
 
736
- ### abstract/utils: General utilities
772
+ ### utils: Useful utilities
737
773
 
738
774
  ```ts
739
775
  import * as utils from '@noble/curves/abstract/utils';
@@ -755,25 +791,61 @@ utils.equalBytes(Uint8Array.from([0xde]), Uint8Array.from([0xde]));
755
791
 
756
792
  ## Security
757
793
 
758
- 1. The library has been audited in Feb 2023 by an independent security firm [Trail of Bits](https://www.trailofbits.com):
759
- [PDF](https://github.com/trailofbits/publications/blob/master/reviews/2023-01-ryanshea-noblecurveslibrary-securityreview.pdf).
760
- The audit has been funded by [Ryan Shea](https://www.shea.io). Audit scope was abstract modules `curve`, `hash-to-curve`, `modular`, `poseidon`, `utils`, `weierstrass`, and top-level modules `_shortw_utils` and `secp256k1`. See [changes since audit](https://github.com/paulmillr/noble-curves/compare/0.7.3..main).
761
- 2. The library has been fuzzed by [Guido Vranken's cryptofuzz](https://github.com/guidovranken/cryptofuzz). You can run the fuzzer by yourself to check it.
762
- 3. [Timing attack](https://en.wikipedia.org/wiki/Timing_attack) considerations: _JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to achieve in a scripting language. Which means _any other JS library can't have constant-timeness_. Even statically typed Rust, a language without GC, [makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security) for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones. Use low-level libraries & languages. Nonetheless we're targetting algorithmic constant time.
763
-
764
- We consider infrastructure attacks like rogue NPM modules very important; that's why it's crucial to minimize the amount of 3rd-party dependencies & native bindings. If your app uses 500 dependencies, any dep could get hacked and you'll be downloading malware with every `npm install`. Our goal is to minimize this attack vector. As for devDependencies used by the library:
765
-
766
- - `@scure` base, bip32, bip39 (used in tests), micro-bmark (benchmark), micro-should (testing) are developed by us
767
- and follow the same practices such as: minimal library size, auditability, signed releases
768
- - prettier (linter), fast-check (property-based testing),
769
- typescript versions are locked and rarely updated. Every update is checked with `npm-diff`.
770
- The packages are big, which makes it hard to audit their source code thoroughly and fully.
771
- - They are only used if you clone the git repo and want to add some feature to it. End-users won't use them.
772
-
773
- As for key generation, we're deferring to built-in
794
+ The library has been independently audited:
795
+
796
+ - at version 1.2.0, in Sep 2023, by [Kudelski Security](https://kudelskisecurity.com)
797
+ - PDFs: [offline](./audit/2023-09-kudelski-audit-starknet.pdf)
798
+ - [Changes since audit](https://github.com/paulmillr/noble-curves/compare/1.2.0..main)
799
+ - Scope: [scure-starknet](https://github.com/paulmillr/scure-starknet) and its related
800
+ abstract modules of noble-curves: `curve`, `modular`, `poseidon`, `weierstrass`
801
+ - The audit has been funded by [Starkware](https://starkware.co)
802
+ - at version 0.7.3, in Feb 2023, by [Trail of Bits](https://www.trailofbits.com)
803
+ - PDFs: [online](https://github.com/trailofbits/publications/blob/master/reviews/2023-01-ryanshea-noblecurveslibrary-securityreview.pdf),
804
+ [offline](./audit/2023-01-trailofbits-audit-curves.pdf)
805
+ - [Changes since audit](https://github.com/paulmillr/noble-curves/compare/0.7.3..main)
806
+ - Scope: abstract modules `curve`, `hash-to-curve`, `modular`, `poseidon`, `utils`, `weierstrass` and
807
+ top-level modules `_shortw_utils` and `secp256k1`
808
+ - The audit has been funded by [Ryan Shea](https://www.shea.io)
809
+
810
+ It is tested against property-based, cross-library and Wycheproof vectors,
811
+ and has fuzzing by [Guido Vranken's cryptofuzz](https://github.com/guidovranken/cryptofuzz).
812
+
813
+ If you see anything unusual: investigate and report.
814
+
815
+ ### Constant-timeness
816
+
817
+ _JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to
818
+ achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance
819
+ in a scripting language. Which means _any other JS library can't have
820
+ constant-timeness_. Even statically typed Rust, a language without GC,
821
+ [makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)
822
+ for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones.
823
+ Use low-level libraries & languages. Nonetheless we're targetting algorithmic constant time.
824
+
825
+ ### Supply chain security
826
+
827
+ * **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures.
828
+ * **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs
829
+ * **Rare releasing** is followed to ensure less re-audit need for end-users
830
+ * **Dependencies** are minimized and locked-down:
831
+ - If your app has 500 dependencies, any dep could get hacked and you'll be downloading
832
+ malware with every install. We make sure to use as few dependencies as possible
833
+ - We prevent automatic dependency updates by locking-down version ranges. Every update is checked with `npm-diff`
834
+ - One dependency [noble-hashes](https://github.com/paulmillr/noble-hashes) is used, by the same author, to provide hashing functionality
835
+ * **Dev Dependencies** are only used if you want to contribute to the repo. They are disabled for end-users:
836
+ - scure-base, scure-bip32, scure-bip39, micro-bmark and micro-should are developed by the same author and follow identical security practices
837
+ - prettier (linter), fast-check (property-based testing) and typescript are used for code quality, vector generation and ts compilation. The packages are big, which makes it hard to audit their source code thoroughly and fully
838
+
839
+ ### Randomness
840
+
841
+ We're deferring to built-in
774
842
  [crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)
775
843
  which is considered cryptographically secure (CSPRNG).
776
844
 
845
+ In the past, browsers had bugs that made it weak: it may happen again.
846
+ Implementing a userspace CSPRNG to get resilient to the weakness
847
+ is even worse: there is no reliable userspace source of quality entropy.
848
+
777
849
  ## Speed
778
850
 
779
851
  Benchmark results on Apple M2 with node v20:
@@ -855,45 +927,41 @@ ed25519 x 3,088 ops/sec @ 323μs/op
855
927
  ed448 x 1,247 ops/sec @ 801μs/op
856
928
  ```
857
929
 
858
- ## Contributing & testing
859
-
860
- 1. Clone the repository
861
- 2. `npm install` to install build dependencies like TypeScript
862
- 3. `npm run build` to compile TypeScript code
863
- 4. `npm run test` will execute all main tests
864
-
865
930
  ## Upgrading
866
931
 
867
932
  Previously, the library was split into single-feature packages
868
- noble-secp256k1, noble-ed25519 and noble-bls12-381.
933
+ [noble-secp256k1](https://github.com/paulmillr/noble-secp256k1),
934
+ [noble-ed25519](https://github.com/paulmillr/noble-ed25519) and
935
+ [noble-bls12-381](https://github.com/paulmillr/noble-bls12-381).
869
936
 
870
937
  Curves continue their original work. The single-feature packages changed their
871
938
  direction towards providing minimal 4kb implementations of cryptography,
872
939
  which means they have less features.
873
940
 
874
- Upgrading from @noble/secp256k1 2.0 or @noble/ed25519 2.0: no changes, libraries are compatible.
941
+ Upgrading from noble-secp256k1 2.0 or noble-ed25519 2.0: no changes, libraries are compatible.
875
942
 
876
- Upgrading from [@noble/secp256k1](https://github.com/paulmillr/noble-secp256k1) 1.7:
943
+ Upgrading from noble-secp256k1 1.7:
877
944
 
878
945
  - `getPublicKey`
879
- - now produce 33-byte compressed signatures by default
880
- - to use old behavior, which produced 65-byte uncompressed keys, set
881
- argument `isCompressed` to `false`: `getPublicKey(priv, false)`
946
+ - now produce 33-byte compressed signatures by default
947
+ - to use old behavior, which produced 65-byte uncompressed keys, set
948
+ argument `isCompressed` to `false`: `getPublicKey(priv, false)`
882
949
  - `sign`
883
- - is now sync; use `signAsync` for async version
884
- - now returns `Signature` instance with `{ r, s, recovery }` properties
885
- - `canonical` option was renamed to `lowS`
886
- - `recovered` option has been removed because recovery bit is always returned now
887
- - `der` option has been removed. There are 2 options:
888
- 1. Use compact encoding: `fromCompact`, `toCompactRawBytes`, `toCompactHex`.
889
- Compact encoding is simply a concatenation of 32-byte r and 32-byte s.
890
- 2. If you must use DER encoding, switch to noble-curves (see above).
950
+ - is now sync
951
+ - now returns `Signature` instance with `{ r, s, recovery }` properties
952
+ - `canonical` option was renamed to `lowS`
953
+ - `recovered` option has been removed because recovery bit is always returned now
954
+ - `der` option has been removed. There are 2 options:
955
+ 1. Use compact encoding: `fromCompact`, `toCompactRawBytes`, `toCompactHex`.
956
+ Compact encoding is simply a concatenation of 32-byte r and 32-byte s.
957
+ 2. If you must use DER encoding, switch to noble-curves (see above).
891
958
  - `verify`
892
- - `strict` option was renamed to `lowS`
959
+ - is now sync
960
+ - `strict` option was renamed to `lowS`
893
961
  - `getSharedSecret`
894
- - now produce 33-byte compressed signatures by default
895
- - to use old behavior, which produced 65-byte uncompressed keys, set
896
- argument `isCompressed` to `false`: `getSharedSecret(a, b, false)`
962
+ - now produce 33-byte compressed signatures by default
963
+ - to use old behavior, which produced 65-byte uncompressed keys, set
964
+ argument `isCompressed` to `false`: `getSharedSecret(a, b, false)`
897
965
  - `recoverPublicKey(msg, sig, rec)` was changed to `sig.recoverPublicKey(msg)`
898
966
  - `number` type for private keys have been removed: use `bigint` instead
899
967
  - `Point` (2d xy) has been changed to `ProjectivePoint` (3d xyz)
@@ -914,53 +982,22 @@ Upgrading from [@noble/ed25519](https://github.com/paulmillr/noble-ed25519) 1.7:
914
982
  Upgrading from [@noble/bls12-381](https://github.com/paulmillr/noble-bls12-381):
915
983
 
916
984
  - Methods and classes were renamed:
917
- - PointG1 -> G1.Point, PointG2 -> G2.Point
918
- - PointG2.fromSignature -> Signature.decode, PointG2.toSignature -> Signature.encode
985
+ - PointG1 -> G1.Point, PointG2 -> G2.Point
986
+ - PointG2.fromSignature -> Signature.decode, PointG2.toSignature -> Signature.encode
919
987
  - Fp2 ORDER was corrected
920
988
 
989
+ ## Contributing & testing
990
+
991
+ 1. Clone the repository
992
+ 2. `npm install` to install build dependencies like TypeScript
993
+ 3. `npm run build` to compile TypeScript code
994
+ 4. `npm run test` will execute all main tests
995
+
921
996
  ## Resources
922
997
 
923
- Useful documentation and articles about the library or its primitives:
924
-
925
- - [Learning fast elliptic-curve cryptography](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/)
926
- - [Taming the many EdDSAs](https://csrc.nist.gov/csrc/media/Presentations/2023/crclub-2023-03-08/images-media/20230308-crypto-club-slides--taming-the-many-EdDSAs.pdf)
927
- that describes concepts of Strong UnForgeability under Chosen Message Attacks and Strongly Binding Signatures
928
- - Pairings and BLS
929
- - [BLS signatures for busy people](https://gist.github.com/paulmillr/18b802ad219b1aee34d773d08ec26ca2)
930
- - [BLS12-381 for the rest of us](https://hackmd.io/@benjaminion/bls12-381)
931
- - [Key concepts of pairings](https://medium.com/@alonmuroch_65570/bls-signatures-part-2-key-concepts-of-pairings-27a8a9533d0c)
932
- - Pairing over bls12-381:
933
- [part 1](https://research.nccgroup.com/2020/07/06/pairing-over-bls12-381-part-1-fields/),
934
- [part 2](https://research.nccgroup.com/2020/07/13/pairing-over-bls12-381-part-2-curves/),
935
- [part 3](https://research.nccgroup.com/2020/08/13/pairing-over-bls12-381-part-3-pairing/)
936
- - [Estimating the bit security of pairing-friendly curves](https://research.nccgroup.com/2022/02/03/estimating-the-bit-security-of-pairing-friendly-curves/)
937
-
938
- Online demos:
939
-
940
- - [Elliptic Curve Calculator](https://paulmillr.com/noble): add / multiply points, sign messages
941
- - [BLS threshold signatures](https://genthresh.com)
942
-
943
- Projects using noble-curves:
944
-
945
- - [scure-bip32](https://github.com/paulmillr/scure-bip32) and separate [bip32](https://github.com/bitcoinjs/bip32) HDkey libraries
946
- - Ethereum libraries:
947
- - [ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography)
948
- - [@ethereumjs](https://github.com/ethereumjs/ethereumjs-monorepo)
949
- - [micro-eth-signer](https://github.com/paulmillr/micro-eth-signer)
950
- - [ethers](https://github.com/ethers-io/ethers.js) (old noble-secp256k1 for now)
951
- - [viem.sh](https://viem.sh)
952
- - [metamask's eth-sig-util](https://github.com/MetaMask/eth-sig-util)
953
- - [gridplus lattice sdk](https://github.com/GridPlus/lattice-eth2-utils)
954
- - Bitcoin libraries: [scure-btc-signer](https://github.com/paulmillr/scure-btc-signer)
955
- - Solana libraries: [micro-sol-signer](https://github.com/paulmillr/micro-sol-signer), [solana-web3.js](https://github.com/solana-labs/solana-web3.js)
956
- - [polkadot.js](https://github.com/polkadot-js/common), [micro-starknet](https://github.com/paulmillr/micro-starknet)
957
- - [protonmail](https://github.com/ProtonMail/WebClients) (old noble-ed25519 for now)
958
- - [did-jwt](https://github.com/decentralized-identity/did-jwt), [hpke-js](https://github.com/dajiaji/hpke-js), [nostr-tools](https://github.com/nbd-wtf/nostr-tools)
959
- - [ed25519-keygen](https://github.com/paulmillr/ed25519-keygen) SSH, PGP, TOR key generation
960
- - [secp256k1 compatibility layer](https://github.com/ethereum/js-ethereum-cryptography/blob/2.0.0/src/secp256k1-compat.ts)
961
- for users who want to switch from secp256k1-node or tiny-secp256k1. Allows to see which methods map to corresponding noble code.
962
- - [BLS BBS signatures](https://github.com/Wind4Greg/BBS-Draft-Checks) following [draft-irtf-cfrg-bbs-signatures-latest](https://identity.foundation/bbs-signature/draft-irtf-cfrg-bbs-signatures.html)
963
- - [KZG trusted setup ceremony](https://github.com/dsrvlabs/czg-keremony)
998
+ Check out [paulmillr.com/noble](https://paulmillr.com/noble/)
999
+ for useful resources, articles, documentation and demos
1000
+ related to the library.
964
1001
 
965
1002
  ## License
966
1003