@noble/curves 1.9.1 → 1.9.3

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 (223) hide show
  1. package/README.md +238 -227
  2. package/_shortw_utils.d.ts +8 -5
  3. package/_shortw_utils.d.ts.map +1 -1
  4. package/_shortw_utils.js +3 -8
  5. package/_shortw_utils.js.map +1 -1
  6. package/abstract/bls.d.ts +123 -62
  7. package/abstract/bls.d.ts.map +1 -1
  8. package/abstract/bls.js +219 -163
  9. package/abstract/bls.js.map +1 -1
  10. package/abstract/curve.d.ts +142 -21
  11. package/abstract/curve.d.ts.map +1 -1
  12. package/abstract/curve.js +224 -143
  13. package/abstract/curve.js.map +1 -1
  14. package/abstract/edwards.d.ts +190 -49
  15. package/abstract/edwards.d.ts.map +1 -1
  16. package/abstract/edwards.js +322 -136
  17. package/abstract/edwards.js.map +1 -1
  18. package/abstract/fft.d.ts +12 -10
  19. package/abstract/fft.d.ts.map +1 -1
  20. package/abstract/fft.js +12 -13
  21. package/abstract/fft.js.map +1 -1
  22. package/abstract/hash-to-curve.d.ts +31 -13
  23. package/abstract/hash-to-curve.d.ts.map +1 -1
  24. package/abstract/hash-to-curve.js +34 -19
  25. package/abstract/hash-to-curve.js.map +1 -1
  26. package/abstract/modular.d.ts +31 -13
  27. package/abstract/modular.d.ts.map +1 -1
  28. package/abstract/modular.js +125 -52
  29. package/abstract/modular.js.map +1 -1
  30. package/abstract/montgomery.d.ts +18 -5
  31. package/abstract/montgomery.d.ts.map +1 -1
  32. package/abstract/montgomery.js +23 -6
  33. package/abstract/montgomery.js.map +1 -1
  34. package/abstract/poseidon.d.ts +5 -13
  35. package/abstract/poseidon.d.ts.map +1 -1
  36. package/abstract/poseidon.js +12 -7
  37. package/abstract/poseidon.js.map +1 -1
  38. package/abstract/tower.d.ts +23 -49
  39. package/abstract/tower.d.ts.map +1 -1
  40. package/abstract/tower.js +9 -3
  41. package/abstract/tower.js.map +1 -1
  42. package/abstract/utils.d.ts +1 -115
  43. package/abstract/utils.d.ts.map +1 -1
  44. package/abstract/utils.js +17 -371
  45. package/abstract/utils.js.map +1 -1
  46. package/abstract/weierstrass.d.ts +206 -124
  47. package/abstract/weierstrass.d.ts.map +1 -1
  48. package/abstract/weierstrass.js +747 -604
  49. package/abstract/weierstrass.js.map +1 -1
  50. package/bls12-381.d.ts +2 -0
  51. package/bls12-381.d.ts.map +1 -1
  52. package/bls12-381.js +504 -466
  53. package/bls12-381.js.map +1 -1
  54. package/bn254.d.ts +2 -0
  55. package/bn254.d.ts.map +1 -1
  56. package/bn254.js +44 -32
  57. package/bn254.js.map +1 -1
  58. package/ed25519.d.ts +55 -66
  59. package/ed25519.d.ts.map +1 -1
  60. package/ed25519.js +172 -186
  61. package/ed25519.js.map +1 -1
  62. package/ed448.d.ts +60 -57
  63. package/ed448.d.ts.map +1 -1
  64. package/ed448.js +172 -166
  65. package/ed448.js.map +1 -1
  66. package/esm/_shortw_utils.d.ts +8 -5
  67. package/esm/_shortw_utils.d.ts.map +1 -1
  68. package/esm/_shortw_utils.js +3 -8
  69. package/esm/_shortw_utils.js.map +1 -1
  70. package/esm/abstract/bls.d.ts +123 -62
  71. package/esm/abstract/bls.d.ts.map +1 -1
  72. package/esm/abstract/bls.js +220 -164
  73. package/esm/abstract/bls.js.map +1 -1
  74. package/esm/abstract/curve.d.ts +142 -21
  75. package/esm/abstract/curve.d.ts.map +1 -1
  76. package/esm/abstract/curve.js +219 -143
  77. package/esm/abstract/curve.js.map +1 -1
  78. package/esm/abstract/edwards.d.ts +190 -49
  79. package/esm/abstract/edwards.d.ts.map +1 -1
  80. package/esm/abstract/edwards.js +320 -138
  81. package/esm/abstract/edwards.js.map +1 -1
  82. package/esm/abstract/fft.d.ts +12 -10
  83. package/esm/abstract/fft.d.ts.map +1 -1
  84. package/esm/abstract/fft.js +10 -11
  85. package/esm/abstract/fft.js.map +1 -1
  86. package/esm/abstract/hash-to-curve.d.ts +31 -13
  87. package/esm/abstract/hash-to-curve.d.ts.map +1 -1
  88. package/esm/abstract/hash-to-curve.js +33 -19
  89. package/esm/abstract/hash-to-curve.js.map +1 -1
  90. package/esm/abstract/modular.d.ts +31 -13
  91. package/esm/abstract/modular.d.ts.map +1 -1
  92. package/esm/abstract/modular.js +124 -51
  93. package/esm/abstract/modular.js.map +1 -1
  94. package/esm/abstract/montgomery.d.ts +18 -5
  95. package/esm/abstract/montgomery.d.ts.map +1 -1
  96. package/esm/abstract/montgomery.js +23 -6
  97. package/esm/abstract/montgomery.js.map +1 -1
  98. package/esm/abstract/poseidon.d.ts +5 -13
  99. package/esm/abstract/poseidon.d.ts.map +1 -1
  100. package/esm/abstract/poseidon.js +12 -7
  101. package/esm/abstract/poseidon.js.map +1 -1
  102. package/esm/abstract/tower.d.ts +23 -49
  103. package/esm/abstract/tower.d.ts.map +1 -1
  104. package/esm/abstract/tower.js +9 -3
  105. package/esm/abstract/tower.js.map +1 -1
  106. package/esm/abstract/utils.d.ts +1 -115
  107. package/esm/abstract/utils.d.ts.map +1 -1
  108. package/esm/abstract/utils.js +3 -344
  109. package/esm/abstract/utils.js.map +1 -1
  110. package/esm/abstract/weierstrass.d.ts +206 -124
  111. package/esm/abstract/weierstrass.d.ts.map +1 -1
  112. package/esm/abstract/weierstrass.js +743 -605
  113. package/esm/abstract/weierstrass.js.map +1 -1
  114. package/esm/bls12-381.d.ts +2 -0
  115. package/esm/bls12-381.d.ts.map +1 -1
  116. package/esm/bls12-381.js +503 -465
  117. package/esm/bls12-381.js.map +1 -1
  118. package/esm/bn254.d.ts +2 -0
  119. package/esm/bn254.d.ts.map +1 -1
  120. package/esm/bn254.js +41 -29
  121. package/esm/bn254.js.map +1 -1
  122. package/esm/ed25519.d.ts +55 -66
  123. package/esm/ed25519.d.ts.map +1 -1
  124. package/esm/ed25519.js +170 -183
  125. package/esm/ed25519.js.map +1 -1
  126. package/esm/ed448.d.ts +60 -57
  127. package/esm/ed448.d.ts.map +1 -1
  128. package/esm/ed448.js +169 -162
  129. package/esm/ed448.js.map +1 -1
  130. package/esm/index.js +7 -9
  131. package/esm/index.js.map +1 -1
  132. package/esm/jubjub.d.ts +3 -3
  133. package/esm/jubjub.d.ts.map +1 -1
  134. package/esm/jubjub.js +3 -3
  135. package/esm/jubjub.js.map +1 -1
  136. package/esm/misc.d.ts +3 -5
  137. package/esm/misc.d.ts.map +1 -1
  138. package/esm/misc.js +31 -29
  139. package/esm/misc.js.map +1 -1
  140. package/esm/nist.d.ts +7 -22
  141. package/esm/nist.d.ts.map +1 -1
  142. package/esm/nist.js +106 -101
  143. package/esm/nist.js.map +1 -1
  144. package/esm/p256.d.ts +7 -3
  145. package/esm/p256.d.ts.map +1 -1
  146. package/esm/p256.js +4 -0
  147. package/esm/p256.js.map +1 -1
  148. package/esm/p384.d.ts +7 -4
  149. package/esm/p384.d.ts.map +1 -1
  150. package/esm/p384.js +4 -1
  151. package/esm/p384.js.map +1 -1
  152. package/esm/p521.d.ts +7 -3
  153. package/esm/p521.d.ts.map +1 -1
  154. package/esm/p521.js +4 -0
  155. package/esm/p521.js.map +1 -1
  156. package/esm/secp256k1.d.ts +38 -21
  157. package/esm/secp256k1.d.ts.map +1 -1
  158. package/esm/secp256k1.js +112 -104
  159. package/esm/secp256k1.js.map +1 -1
  160. package/esm/utils.d.ts +96 -0
  161. package/esm/utils.d.ts.map +1 -0
  162. package/esm/utils.js +279 -0
  163. package/esm/utils.js.map +1 -0
  164. package/index.js +7 -9
  165. package/index.js.map +1 -1
  166. package/jubjub.d.ts +3 -3
  167. package/jubjub.d.ts.map +1 -1
  168. package/jubjub.js +3 -3
  169. package/jubjub.js.map +1 -1
  170. package/misc.d.ts +3 -5
  171. package/misc.d.ts.map +1 -1
  172. package/misc.js +35 -33
  173. package/misc.js.map +1 -1
  174. package/nist.d.ts +7 -22
  175. package/nist.d.ts.map +1 -1
  176. package/nist.js +106 -101
  177. package/nist.js.map +1 -1
  178. package/p256.d.ts +7 -3
  179. package/p256.d.ts.map +1 -1
  180. package/p256.js +4 -0
  181. package/p256.js.map +1 -1
  182. package/p384.d.ts +7 -4
  183. package/p384.d.ts.map +1 -1
  184. package/p384.js +4 -1
  185. package/p384.js.map +1 -1
  186. package/p521.d.ts +7 -3
  187. package/p521.d.ts.map +1 -1
  188. package/p521.js +4 -0
  189. package/p521.js.map +1 -1
  190. package/package.json +17 -6
  191. package/secp256k1.d.ts +38 -21
  192. package/secp256k1.d.ts.map +1 -1
  193. package/secp256k1.js +112 -104
  194. package/secp256k1.js.map +1 -1
  195. package/src/_shortw_utils.ts +6 -15
  196. package/src/abstract/bls.ts +428 -251
  197. package/src/abstract/curve.ts +307 -149
  198. package/src/abstract/edwards.ts +555 -203
  199. package/src/abstract/fft.ts +30 -19
  200. package/src/abstract/hash-to-curve.ts +75 -34
  201. package/src/abstract/modular.ts +131 -59
  202. package/src/abstract/montgomery.ts +44 -15
  203. package/src/abstract/poseidon.ts +22 -18
  204. package/src/abstract/tower.ts +40 -71
  205. package/src/abstract/utils.ts +3 -378
  206. package/src/abstract/weierstrass.ts +1086 -746
  207. package/src/bls12-381.ts +549 -490
  208. package/src/bn254.ts +47 -35
  209. package/src/ed25519.ts +214 -216
  210. package/src/ed448.ts +251 -220
  211. package/src/index.ts +7 -9
  212. package/src/jubjub.ts +3 -3
  213. package/src/misc.ts +41 -40
  214. package/src/nist.ts +161 -126
  215. package/src/p256.ts +7 -3
  216. package/src/p384.ts +7 -5
  217. package/src/p521.ts +7 -3
  218. package/src/secp256k1.ts +145 -115
  219. package/src/utils.ts +328 -0
  220. package/utils.d.ts +96 -0
  221. package/utils.d.ts.map +1 -0
  222. package/utils.js +313 -0
  223. package/utils.js.map +1 -0
package/README.md CHANGED
@@ -5,11 +5,12 @@ Audited & minimal JS implementation of elliptic curve cryptography.
5
5
  - 🔒 [**Audited**](#security) by independent security firms
6
6
  - 🔻 Tree-shakeable: unused code is excluded from your builds
7
7
  - 🏎 Fast: hand-optimized for caveats of JS engines
8
- - 🔍 Reliable: cross-library / wycheproof tests and fuzzing ensure correctness
9
- - ➰ Short Weierstrass, Edwards, Montgomery curves
10
- - ✍️ ECDSA, EdDSA, Schnorr, BLS, ECDH, hashing to curves, Poseidon ZK-friendly hash
11
- - 🔖 SUF-CMA, SBS (non-repudiation), ZIP215 (consensus friendliness) features for ed25519 & ed448
12
- - 🪶 93KB (36KB gzipped) for everything with hashes, 26KB (11KB gzipped) for single-curve build
8
+ - 🔍 Reliable: tested against cross-library, wycheproof and acvp vectors
9
+ - ➰ Weierstrass, Edwards, Montgomery curves; ECDSA, EdDSA, Schnorr, BLS signatures
10
+ - ✍️ ECDH, hash-to-curve, OPRF, Poseidon ZK-friendly hash
11
+ - 🔖 Non-repudiation (SUF-CMA, SBS) & consensus-friendliness (ZIP215) in ed25519, ed448
12
+ - 🥈 Optional, friendly wrapper over native WebCrypto
13
+ - 🪶 36KB (gzipped) including bundled hashes, 11KB for single-curve build
13
14
 
14
15
  Curves have 4KB sister projects
15
16
  [secp256k1](https://github.com/paulmillr/noble-secp256k1) & [ed25519](https://github.com/paulmillr/noble-ed25519).
@@ -48,14 +49,14 @@ A standalone file [noble-curves.js](https://github.com/paulmillr/noble-curves/re
48
49
 
49
50
  ```ts
50
51
  // import * from '@noble/curves'; // Error: use sub-imports, to ensure small app size
51
- import { secp256k1, schnorr } from '@noble/curves/secp256k1';
52
- import { ed25519, ed25519ph, ed25519ctx, x25519 } from '@noble/curves/ed25519';
53
- import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
54
- import { p256, p384, p521 } from '@noble/curves/nist';
55
- import { bls12_381 } from '@noble/curves/bls12-381';
56
- import { bn254 } from '@noble/curves/bn254';
57
- import { jubjub, babyjubjub } from '@noble/curves/misc';
58
- import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/abstract/utils';
52
+ import { secp256k1, schnorr } from '@noble/curves/secp256k1.js';
53
+ import { ed25519, ed25519ph, ed25519ctx, x25519 } from '@noble/curves/ed25519.js';
54
+ import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448.js';
55
+ import { p256, p384, p521 } from '@noble/curves/nist.js';
56
+ import { bls12_381 } from '@noble/curves/bls12-381.js';
57
+ import { bn254 } from '@noble/curves/bn254.js';
58
+ import { jubjub, babyjubjub } from '@noble/curves/misc.js';
59
+ import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/abstract/utils.js';
59
60
  ```
60
61
 
61
62
  - [ECDSA signatures over secp256k1 and others](#ecdsa-signatures-over-secp256k1-and-others)
@@ -69,8 +70,12 @@ import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/
69
70
  - [misc curves](#misc-curves)
70
71
  - [Low-level methods](#low-level-methods)
71
72
  - [Abstract API](#abstract-api)
72
- - [weierstrass](#weierstrass-short-weierstrass-curve), [edwards](#edwards-twisted-edwards-curve), [montgomery](#montgomery-montgomery-curve), [bls](#bls-barreto-lynn-scott-curves)
73
- - [hash-to-curve](#hash-to-curve-hashing-strings-to-curve-points), [poseidon](#poseidon-poseidon-hash)
73
+ - [weierstrass](#weierstrass-short-weierstrass-curve), [Projective Point](#projective-weierstrass-point), [ECDSA signatures](#ecdsa-signatures)
74
+ - [edwards](#edwards-twisted-edwards-curve), [Extended Point](#extended-edwards-point), [EdDSA signatures](#eddsa-signatures)
75
+ - [montgomery](#montgomery-montgomery-curve)
76
+ - [bls](#bls-barreto-lynn-scott-curves)
77
+ - [hash-to-curve](#hash-to-curve-hashing-strings-to-curve-points)
78
+ - [poseidon](#poseidon-poseidon-hash)
74
79
  - [modular](#modular-modular-arithmetics-utilities)
75
80
  - [fft](#fft-fast-fourier-transform)
76
81
  - [Creating private keys from hashes](#creating-private-keys-from-hashes)
@@ -86,8 +91,8 @@ import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/
86
91
  #### ECDSA signatures over secp256k1 and others
87
92
 
88
93
  ```ts
89
- import { secp256k1 } from '@noble/curves/secp256k1';
90
- // import { p256 } from '@noble/curves/nist'; // or p384 / p521
94
+ import { secp256k1 } from '@noble/curves/secp256k1.js';
95
+ // import { p256 } from '@noble/curves/nist.js'; // or p384 / p521
91
96
 
92
97
  const priv = secp256k1.utils.randomPrivateKey();
93
98
  const pub = secp256k1.getPublicKey(priv);
@@ -134,7 +139,7 @@ const shared = secp256k1.getSharedSecret(priv, someonesPub);
134
139
  #### secp256k1 Schnorr signatures from BIP340
135
140
 
136
141
  ```ts
137
- import { schnorr } from '@noble/curves/secp256k1';
142
+ import { schnorr } from '@noble/curves/secp256k1.js';
138
143
  const priv = schnorr.utils.randomPrivateKey();
139
144
  const pub = schnorr.getPublicKey(priv);
140
145
  const msg = new TextEncoder().encode('hello');
@@ -145,7 +150,7 @@ const isValid = schnorr.verify(sig, msg, pub);
145
150
  #### ed25519
146
151
 
147
152
  ```ts
148
- import { ed25519 } from '@noble/curves/ed25519';
153
+ import { ed25519 } from '@noble/curves/ed25519.js';
149
154
  const priv = ed25519.utils.randomPrivateKey();
150
155
  const pub = ed25519.getPublicKey(priv);
151
156
  const msg = new TextEncoder().encode('hello');
@@ -154,7 +159,7 @@ ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
154
159
  ed25519.verify(sig, msg, pub, { zip215: false }); // SBS / e-voting / RFC8032 / FIPS 186-5
155
160
 
156
161
  // Variants from RFC8032: with context, prehashed
157
- import { ed25519ctx, ed25519ph } from '@noble/curves/ed25519';
162
+ import { ed25519ctx, ed25519ph } from '@noble/curves/ed25519.js';
158
163
  ```
159
164
 
160
165
  Default `verify` behavior follows ZIP215 and
@@ -167,7 +172,7 @@ Both options have SUF-CMA (strong unforgeability under chosen message attacks).
167
172
 
168
173
  ```ts
169
174
  // X25519 aka ECDH on Curve25519 from [RFC7748](https://www.rfc-editor.org/rfc/rfc7748)
170
- import { x25519 } from '@noble/curves/ed25519';
175
+ import { x25519 } from '@noble/curves/ed25519.js';
171
176
  const priv = 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4';
172
177
  const pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';
173
178
  x25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub); // aliases
@@ -175,7 +180,7 @@ x25519.getPublicKey(priv) === x25519.scalarMultBase(priv);
175
180
  x25519.getPublicKey(x25519.utils.randomPrivateKey());
176
181
 
177
182
  // ed25519 => x25519 conversion
178
- import { edwardsToMontgomeryPub, edwardsToMontgomeryPriv } from '@noble/curves/ed25519';
183
+ import { edwardsToMontgomeryPub, edwardsToMontgomeryPriv } from '@noble/curves/ed25519.js';
179
184
  edwardsToMontgomeryPub(ed25519.getPublicKey(ed25519.utils.randomPrivateKey()));
180
185
  edwardsToMontgomeryPriv(ed25519.utils.randomPrivateKey());
181
186
  ```
@@ -183,17 +188,15 @@ edwardsToMontgomeryPriv(ed25519.utils.randomPrivateKey());
183
188
  #### ristretto255
184
189
 
185
190
  ```ts
186
- // ristretto255 from [RFC9496](https://www.rfc-editor.org/rfc/rfc9496)
187
- import { utf8ToBytes } from '@noble/hashes/utils';
188
- import { sha512 } from '@noble/hashes/sha512';
191
+ import { sha512 } from '@noble/hashes/sha2.js';
189
192
  import {
190
193
  hashToCurve,
191
194
  encodeToCurve,
192
195
  RistrettoPoint,
193
196
  hashToRistretto255,
194
- } from '@noble/curves/ed25519';
197
+ } from '@noble/curves/ed25519.js';
195
198
 
196
- const msg = utf8ToBytes('Ristretto is traditionally a short shot of espresso coffee');
199
+ const msg = new TextEncoder().encode('Ristretto is traditionally a short shot of espresso coffee');
197
200
  hashToCurve(msg);
198
201
 
199
202
  const rp = RistrettoPoint.fromHex(
@@ -207,10 +210,12 @@ RistrettoPoint.hashToCurve(sha512(msg));
207
210
  hashToRistretto255(msg, { DST: 'ristretto255_XMD:SHA-512_R255MAP_RO_' });
208
211
  ```
209
212
 
213
+ Check out [RFC9496](https://www.rfc-editor.org/rfc/rfc9496) more info on ristretto255.
214
+
210
215
  #### ed448
211
216
 
212
217
  ```ts
213
- import { ed448 } from '@noble/curves/ed448';
218
+ import { ed448 } from '@noble/curves/ed448.js';
214
219
  const priv = ed448.utils.randomPrivateKey();
215
220
  const pub = ed448.getPublicKey(priv);
216
221
  const msg = new TextEncoder().encode('whatsup');
@@ -218,19 +223,19 @@ const sig = ed448.sign(msg, priv);
218
223
  ed448.verify(sig, msg, pub);
219
224
 
220
225
  // Variants from RFC8032: prehashed
221
- import { ed448ph } from '@noble/curves/ed448';
226
+ import { ed448ph } from '@noble/curves/ed448.js';
222
227
  ```
223
228
 
224
229
  #### X448
225
230
 
226
231
  ```ts
227
232
  // X448 aka ECDH on Curve448 from [RFC7748](https://www.rfc-editor.org/rfc/rfc7748)
228
- import { x448 } from '@noble/curves/ed448';
233
+ import { x448 } from '@noble/curves/ed448.js';
229
234
  x448.getSharedSecret(priv, pub) === x448.scalarMult(priv, pub); // aliases
230
235
  x448.getPublicKey(priv) === x448.scalarMultBase(priv);
231
236
 
232
237
  // ed448 => x448 conversion
233
- import { edwardsToMontgomeryPub } from '@noble/curves/ed448';
238
+ import { edwardsToMontgomeryPub } from '@noble/curves/ed448.js';
234
239
  edwardsToMontgomeryPub(ed448.getPublicKey(ed448.utils.randomPrivateKey()));
235
240
  ```
236
241
 
@@ -238,11 +243,10 @@ edwardsToMontgomeryPub(ed448.getPublicKey(ed448.utils.randomPrivateKey()));
238
243
 
239
244
  ```ts
240
245
  // decaf448 from [RFC9496](https://www.rfc-editor.org/rfc/rfc9496)
241
- import { utf8ToBytes } from '@noble/hashes/utils';
242
- import { shake256 } from '@noble/hashes/sha3';
243
- import { hashToCurve, encodeToCurve, DecafPoint, hashToDecaf448 } from '@noble/curves/ed448';
246
+ import { shake256 } from '@noble/hashes/sha3.js';
247
+ import { hashToCurve, encodeToCurve, DecafPoint, hashToDecaf448 } from '@noble/curves/ed448.js';
244
248
 
245
- const msg = utf8ToBytes('Ristretto is traditionally a short shot of espresso coffee');
249
+ const msg = new TextEncoder().encode('Ristretto is traditionally a short shot of espresso coffee');
246
250
  hashToCurve(msg);
247
251
 
248
252
  const dp = DecafPoint.fromHex(
@@ -256,34 +260,41 @@ DecafPoint.hashToCurve(shake256(msg, { dkLen: 112 }));
256
260
  hashToDecaf448(msg, { DST: 'decaf448_XOF:SHAKE256_D448MAP_RO_' });
257
261
  ```
258
262
 
263
+ Check out [RFC9496](https://www.rfc-editor.org/rfc/rfc9496) more info on decaf448.
264
+
259
265
  #### bls12-381
260
266
 
261
267
  ```ts
262
- import { bls12_381 as bls } from '@noble/curves/bls12-381';
263
-
264
- // G1 keys, G2 signatures
265
- const privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';
266
- const message = '64726e3da8';
267
- const publicKey = bls.getPublicKey(privateKey);
268
- const signature = bls.sign(message, privateKey);
269
- const isValid = bls.verify(signature, message, publicKey);
270
- console.log({ publicKey, signature, isValid });
268
+ import { bls12_381 } from '@noble/curves/bls12-381.js';
269
+ import { hexToBytes } from '@noble/curves/abstract/utils.js';
271
270
 
272
- // G2 keys, G1 signatures
273
- // getPublicKeyForShortSignatures(privateKey)
274
- // signShortSignature(message, privateKey)
275
- // verifyShortSignature(signature, message, publicKey)
276
- // aggregateShortSignatures(signatures)
271
+ // private keys are 32 bytes
272
+ const privKey = hexToBytes('67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c');
273
+ // const privKey = bls12_381.utils.randomPrivateKey();
277
274
 
278
- // Custom DST
279
- const htfEthereum = { DST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_' };
280
- const signatureEth = bls.sign(message, privateKey, htfEthereum);
281
- const isValidEth = bls.verify(signature, message, publicKey, htfEthereum);
275
+ // Long signatures (G2), short public keys (G1)
276
+ const blsl = bls12_381.longSignatures;
277
+ const publicKey = blsl.getPublicKey(privateKey);
278
+ // Sign msg with custom (Ethereum) DST
279
+ const msg = new TextEncoder().encode('hello');
280
+ const DST = 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_';
281
+ const msgp = blsl.hash(msg, DST);
282
+ const signature = blsl.sign(msgp, privateKey);
283
+ const isValid = blsl.verify(signature, msgp, publicKey);
284
+ console.log({ publicKey, signature, isValid });
285
+
286
+ // Short signatures (G1), long public keys (G2)
287
+ const blss = bls12_381.shortSignatures;
288
+ const publicKey2 = blss.getPublicKey(privateKey);
289
+ const msgp2 = blss.hash(new TextEncoder().encode('hello'), 'BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_')
290
+ const signature2 = blss.sign(msgp2, privateKey);
291
+ const isValid2 = blss.verify(signature2, msgp2, publicKey);
292
+ console.log({ publicKey2, signature2, isValid2 });
282
293
 
283
294
  // Aggregation
284
- const aggregatedKey = bls.aggregatePublicKeys([
285
- bls.utils.randomPrivateKey(),
286
- bls.utils.randomPrivateKey(),
295
+ const aggregatedKey = bls12_381.longSignatures.aggregatePublicKeys([
296
+ bls12_381.utils.randomPrivateKey(),
297
+ bls12_381.utils.randomPrivateKey(),
287
298
  ]);
288
299
  // const aggregatedSig = bls.aggregateSignatures(sigs)
289
300
 
@@ -303,7 +314,7 @@ For example usage, check out [the implementation of BLS EVM precompiles](https:/
303
314
  #### bn254 aka alt_bn128
304
315
 
305
316
  ```ts
306
- import { bn254 } from '@noble/curves/bn254';
317
+ import { bn254 } from '@noble/curves/bn254.js';
307
318
 
308
319
  console.log(bn254.G1, bn254.G2, bn254.pairing);
309
320
  ```
@@ -326,109 +337,89 @@ For example usage, check out [the implementation of bn254 EVM precompiles](https
326
337
  #### misc curves
327
338
 
328
339
  ```ts
329
- import { jubjub, babyjubjub } from '@noble/curves/misc';
340
+ import { jubjub, babyjubjub } from '@noble/curves/misc.js';
330
341
  ```
331
342
 
332
343
  Miscellaneous, rarely used curves are contained in the module.
333
344
  Jubjub curves have Fp over scalar fields of other curves. They are friendly to ZK proofs.
334
345
  jubjub Fp = bls n. babyjubjub Fp = bn254 n.
335
346
 
336
- #### Low-level methods
337
-
338
- ```ts
339
- import { secp256k1 } from '@noble/curves/secp256k1';
340
-
341
- // Curve's variables
342
- // Every curve has `CURVE` object that contains its parameters, field, and others
343
- console.log(secp256k1.CURVE.p); // field modulus
344
- console.log(secp256k1.CURVE.n); // curve order
345
- console.log(secp256k1.CURVE.a, secp256k1.CURVE.b); // equation params
346
- console.log(secp256k1.CURVE.Gx, secp256k1.CURVE.Gy); // base point coordinates
347
-
348
- // MSM
349
- const p = secp256k1.ProjectivePoint;
350
- const points = [p.BASE, p.BASE.multiply(2n), p.BASE.multiply(4n), p.BASE.multiply(8n)];
351
- p.msm(points, [3n, 5n, 7n, 11n]).equals(p.BASE.multiply(129n)); // 129*G
352
- ```
353
-
354
- Multi-scalar-multiplication (MSM) is basically `(Pa + Qb + Rc + ...)`.
355
- It's 10-30x faster vs naive addition for large amount of points.
356
- Pippenger algorithm is used underneath.
357
-
358
347
  ## Abstract API
359
348
 
360
- Implementations use [noble-hashes](https://github.com/paulmillr/noble-hashes).
361
- If you want to use a different hashing library, abstract API doesn't depend on them.
362
-
363
349
  Abstract API allows to define custom curves. All arithmetics is done with JS
364
- bigints over finite fields, which is defined from `modular` sub-module. For
365
- scalar multiplication, we use
350
+ bigints over finite fields, which is defined from `modular` sub-module.
351
+ For scalar multiplication, we use
366
352
  [precomputed tables with w-ary non-adjacent form (wNAF)](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/).
367
- Precomputes are enabled for weierstrass and edwards BASE points of a curve. You
368
- could precompute any other point (e.g. for ECDH) using `utils.precompute()`
369
- method: check out examples.
353
+ Precomputes are enabled for weierstrass and edwards BASE points of a curve.
354
+ Implementations use [noble-hashes](https://github.com/paulmillr/noble-hashes).
355
+ It's always possible to use different hashing library.
370
356
 
371
- ### weierstrass: Short Weierstrass curve
372
357
 
373
- ```ts
374
- import { weierstrass } from '@noble/curves/abstract/weierstrass';
375
- import { Field } from '@noble/curves/abstract/modular';
376
- import { sha256 } from '@noble/hashes/sha256';
377
- import { hmac } from '@noble/hashes/hmac';
378
- import { concatBytes, randomBytes } from '@noble/hashes/utils';
379
-
380
- const hmacSha256 = (key: Uint8Array, ...msgs: Uint8Array[]) =>
381
- hmac(sha256, key, concatBytes(...msgs));
382
-
383
- // secQ (not secP) - secq256k1 is a cycle of secp256k1 with Fp/N flipped.
384
- // https://personaelabs.org/posts/spartan-ecdsa
385
- // https://zcash.github.io/halo2/background/curves.html#cycles-of-curves
386
- const secq256k1 = weierstrass({
387
- a: 0n,
388
- b: 7n,
389
- Fp: Field(2n ** 256n - 432420386565659656852420866394968145599n),
390
- n: 2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n,
391
- Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
392
- Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
393
- hash: sha256,
394
- hmac: hmacSha256,
395
- randomBytes,
396
- });
358
+ ### weierstrass: Short Weierstrass curve
397
359
 
398
- // NIST secp192r1 aka p192
399
- // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/secg/secp192r1
400
- const secp192r1 = weierstrass({
360
+ ```js
361
+ import { weierstrass } from '@noble/curves/abstract/weierstrass.js';
362
+ // NIST secp192r1 aka p192. https://www.secg.org/sec2-v2.pdf
363
+ const p192_CURVE = {
364
+ p: 0xfffffffffffffffffffffffffffffffeffffffffffffffffn,
365
+ n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n,
366
+ h: 1n,
401
367
  a: 0xfffffffffffffffffffffffffffffffefffffffffffffffcn,
402
368
  b: 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n,
403
- Fp: Field(0xfffffffffffffffffffffffffffffffeffffffffffffffffn),
404
- n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n,
405
369
  Gx: 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012n,
406
370
  Gy: 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n,
407
- hash: sha256,
408
- hmac: hmacSha256,
409
- randomBytes,
410
- });
371
+ };
372
+ const p192_Point = weierstrass(p192_CURVE);
411
373
  ```
412
374
 
413
375
  Short Weierstrass curve's formula is `y² = x³ + ax + b`. `weierstrass`
414
- expects arguments `a`, `b`, field `Fp`, curve order `n`, cofactor `h`
415
- and coordinates `Gx`, `Gy` of generator point.
416
- `hmac` and `hash` must be specified for deterministic `k` generation.
417
-
418
- **Weierstrass points:**
376
+ expects arguments `a`, `b`, field characteristic `p`, curve order `n`,
377
+ cofactor `h` and coordinates `Gx`, `Gy` of generator point.
378
+
379
+ #### Projective Weierstrass Point
380
+
381
+ ```js
382
+ // # weierstrass Point methods
383
+ // projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
384
+ // const p = new Point(x, y, z);
385
+ const p = Point.BASE;
386
+ // arithmetics
387
+ p.add(p).equals(p.double());
388
+ p.subtract(p).equals(Point.ZERO);
389
+ p.negate();
390
+ p.multiply(31415n);
391
+
392
+ // decoding, encoding
393
+ const b = p.toBytes();
394
+ const p2 = Point.fromBytes(b);
395
+ // affine conversion
396
+ const { x, y } = p.toAffine();
397
+ const p3 = Point.fromAffine({ x, y });
398
+
399
+ // Multi-scalar-multiplication (MSM) is basically `(Pa + Qb + Rc + ...)`.
400
+ // It's 10-30x faster vs naive addition for large amount of points.
401
+ // Pippenger algorithm is used underneath.
402
+ const points = [Point.BASE, Point.BASE.multiply(2n), Point.BASE.multiply(4n), Point.BASE.multiply(8n)];
403
+ Point.msm(points, [3n, 5n, 7n, 11n]).equals(Point.BASE.multiply(129n)); // 129*G
404
+ ```
419
405
 
420
- - Are exported as `ProjectivePoint`
421
- - Are represented in projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
422
- - Use complete exception-free formulas for addition and doubling
423
- - Can be decoded/encoded from/to Uint8Array / hex strings using
424
- `ProjectivePoint.fromHex` and `ProjectivePoint#toRawBytes()`
425
- - Have `assertValidity()` which checks for being on-curve
426
- - Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates
406
+ #### ECDSA signatures
407
+
408
+ ```js
409
+ import { ecdsa } from '@noble/curves/abstract/weierstrass.js';
410
+ import { sha256 } from '@noble/hashes/sha2.js';
411
+ const p192 = ecdsa(p192_Point, sha256);
412
+ const priv = p192.utils.randomPrivateKey();
413
+ const pub = p192.getPublicKey(priv);
414
+ const msg = sha256(new TextEncoder().encode('custom curve'));
415
+ const sig = p192.sign(msg);
416
+ const isValid = p192.verify(sig, msg, pub);
417
+ ```
427
418
 
428
- **ECDSA signatures:**
419
+ ECDSA signatures:
429
420
 
430
421
  - Are represented by `Signature` instances with `r, s` and optional `recovery` properties
431
- - Have `recoverPublicKey()`, `toCompactRawBytes()` and `toDERRawBytes()` methods
422
+ - Have `recoverPublicKey()`, `toBytes()` with optional `format: 'compact' | 'der'`
432
423
  - Can be prehashed, or non-prehashed:
433
424
  - `sign(msgHash, privKey)` (default, prehash: false) - you did hashing before
434
425
  - `sign(msg, privKey, {prehash: true})` - curves will do hashing for you
@@ -436,85 +427,66 @@ and coordinates `Gx`, `Gy` of generator point.
436
427
  - Consider [hedged ECDSA with noise](#hedged-ecdsa-with-noise) for adding randomness into
437
428
  for signatures, to get improved security against fault attacks.
438
429
 
439
- More examples:
440
-
441
- ```typescript
442
- // All curves expose same generic interface.
443
- const priv = secq256k1.utils.randomPrivateKey();
444
- secq256k1.getPublicKey(priv); // Convert private key to public.
445
- const sig = secq256k1.sign(msg, priv); // Sign msg with private key.
446
- const sig2 = secq256k1.sign(msg, priv, { prehash: true }); // hash(msg)
447
- secq256k1.verify(sig, msg, priv); // Verify if sig is correct.
448
-
449
- // Default behavior is "try DER, then try compact if fails". Can be explicit:
450
- secq256k1.verify(sig.toCompactHex(), msg, priv, { format: 'compact' });
451
-
452
- const Point = secq256k1.ProjectivePoint;
453
- const point = Point.BASE; // Elliptic curve Point class and BASE point static var.
454
- point.add(point).equals(point.double()); // add(), equals(), double() methods
455
- point.subtract(point).equals(Point.ZERO); // subtract() method, ZERO static var
456
- point.negate(); // Flips point over x/y coordinate.
457
- point.multiply(31415n); // Multiplication of Point by scalar.
458
-
459
- point.assertValidity(); // Checks for being on-curve
460
- point.toAffine(); // Converts to 2d affine xy coordinates
461
-
462
- secq256k1.CURVE.n;
463
- secq256k1.CURVE.p;
464
- secq256k1.CURVE.Fp.mod();
465
- secq256k1.CURVE.hash();
466
-
467
- // precomputes
468
- const fast = secq256k1.utils.precompute(8, Point.fromHex(someonesPubKey));
469
- fast.multiply(privKey); // much faster ECDH now
470
- ```
471
-
472
430
  ### edwards: Twisted Edwards curve
473
431
 
474
432
  ```ts
475
- import { twistedEdwards } from '@noble/curves/abstract/edwards';
476
- import { Field } from '@noble/curves/abstract/modular';
477
- import { sha512 } from '@noble/hashes/sha512';
478
- import { randomBytes } from '@noble/hashes/utils';
479
-
480
- const Fp = Field(2n ** 255n - 19n);
481
- const ed25519 = twistedEdwards({
482
- a: Fp.create(-1n),
483
- d: Fp.div(-121665n, 121666n), // -121665n/121666n mod p
484
- Fp: Fp,
485
- n: 2n ** 252n + 27742317777372353535851937790883648493n,
433
+ import { edwards } from '@noble/curves/abstract/edwards.js';
434
+ const ed25519_CURVE = {
435
+ p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,
436
+ n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,
486
437
  h: 8n,
487
- Gx: 15112221349535400772501151409588531511454012693041857206046113283949847762202n,
488
- Gy: 46316835694926478169428394003475163141307993866256225615783033603165251855960n,
489
- hash: sha512,
490
- randomBytes,
491
- adjustScalarBytes(bytes) {
492
- // optional; but mandatory in ed25519
493
- bytes[0] &= 248;
494
- bytes[31] &= 127;
495
- bytes[31] |= 64;
496
- return bytes;
497
- },
498
- } as const);
438
+ a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,
439
+ d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,
440
+ Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,
441
+ Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n,
442
+ };
443
+ const ed25519_Point = edwards(ed25519_CURVE);
499
444
  ```
500
445
 
501
446
  Twisted Edwards curve's formula is `ax² + y² = 1 + dx²y²`.
502
- You must specify `a`, `d`, field `Fp`, order `n`, cofactor `h`
503
- and coordinates `Gx`, `Gy` of generator point.
504
- For EdDSA signatures, `hash` param required.
505
- `adjustScalarBytes` which instructs how to change private scalars could be specified.
447
+ You must specify `a`, `d`, field characteristic `p`, curve order `n` (sometimes named as `L`),
448
+ cofactor `h` and coordinates `Gx`, `Gy` of generator point.
449
+
450
+ #### Extended Edwards Point
451
+
452
+ ```js
453
+ const Point = ed25519_Point;
454
+ // extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z)
455
+ // const p = new Point(x, y, z, t);
456
+
457
+ const p = Point.BASE;
458
+ // arithmetics
459
+ p.add(p).equals(p.double());
460
+ p.subtract(p).equals(Point.ZERO);
461
+ p.negate();
462
+ p.multiply(31415n);
463
+
464
+ // decoding, encoding
465
+ const b = p.toBytes();
466
+ const p2 = Point.fromBytes(b);
467
+ // on-curve test
468
+ p.assertValidity();
469
+ // affine conversion
470
+ const { x, y } = p.toAffine();
471
+ const p3 = Point.fromAffine({ x, y });
472
+ // misc
473
+ const pcl = p.clearCofactor();
474
+ console.log(p.isTorsionFree(), p.isSmallOrder());
475
+ ```
476
+
477
+ #### EdDSA signatures
506
478
 
507
- **Edwards points:**
479
+ ```js
480
+ const ed25519 = eddsa(ed25519_Point, { hash: sha512 });
481
+ // ed25519.getPublicKey();
482
+ // ed25519.sign();
483
+ // ed25519.verify();
484
+ ```
508
485
 
509
- - Are exported as `ExtendedPoint`
510
- - Are represented in extended coordinates: (x, y, z, t) (x=x/z, y=y/z)
511
- - Use complete exception-free formulas for addition and doubling
512
- - Can be decoded/encoded from/to Uint8Array / hex strings using `ExtendedPoint.fromHex` and `ExtendedPoint#toRawBytes()`
513
- - Have `assertValidity()` which checks for being on-curve
514
- - Have `toAffine()` and `x` / `y` getters which convert to 2d xy affine coordinates
515
- - Have `isTorsionFree()`, `clearCofactor()` and `isSmallOrder()` utilities to handle torsions
486
+ We define ed25519, ed448; user can use custom curves with EdDSA,
487
+ but EdDSA in general is not defined. Check out `edwards.ts` source code.
516
488
 
517
- **EdDSA signatures:**
489
+ For EdDSA signatures:
518
490
 
519
491
  - `zip215: true` is default behavior. It has slightly looser verification logic
520
492
  to be [consensus-friendly](https://hdevalence.ca/blog/2020-10-04-its-25519am), following [ZIP215](https://zips.z.cash/zip-0215) rules
@@ -527,9 +499,6 @@ For EdDSA signatures, `hash` param required.
527
499
  - Blockchains: transaction of amount X might also be valid for a different amount Y
528
500
  - Both modes have SUF-CMA (strong unforgeability under chosen message attacks).
529
501
 
530
- Check out [RFC9496](https://www.rfc-editor.org/rfc/rfc9496) for description of
531
- ristretto and decaf groups which we implement.
532
-
533
502
  ### montgomery: Montgomery curve
534
503
 
535
504
  The module contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748.
@@ -557,13 +526,13 @@ The module allows to hash arbitrary strings to elliptic curve points. Implements
557
526
  Every curve has exported `hashToCurve` and `encodeToCurve` methods. You should always prefer `hashToCurve` for security:
558
527
 
559
528
  ```ts
560
- import { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1';
561
- import { randomBytes } from '@noble/hashes/utils';
529
+ import { hashToCurve, encodeToCurve } from '@noble/curves/secp256k1.js';
530
+ import { randomBytes } from '@noble/hashes/utils.js';
562
531
  hashToCurve('0102abcd');
563
532
  console.log(hashToCurve(randomBytes()));
564
533
  console.log(encodeToCurve(randomBytes()));
565
534
 
566
- import { bls12_381 } from '@noble/curves/bls12-381';
535
+ import { bls12_381 } from '@noble/curves/bls12-381.js';
567
536
  bls12_381.G1.hashToCurve(randomBytes(), { DST: 'another' });
568
537
  bls12_381.G2.hashToCurve(randomBytes(), { DST: 'custom' });
569
538
  ```
@@ -615,10 +584,10 @@ permutation and sponge.
615
584
 
616
585
  There are many poseidon variants with different constants.
617
586
  We don't provide them: you should construct them manually.
618
- Check out [micro-starknet](https://github.com/paulmillr/micro-starknet) package for a proper example.
587
+ Check out [scure-starknet](https://github.com/paulmillr/scure-starknet) package for a proper example.
619
588
 
620
589
  ```ts
621
- import { poseidon, poseidonSponge } from '@noble/curves/abstract/poseidon';
590
+ import { poseidon, poseidonSponge } from '@noble/curves/abstract/poseidon.js';
622
591
 
623
592
  const rate = 2;
624
593
  const capacity = 1;
@@ -645,7 +614,7 @@ const sponge = poseidon.poseidonSponge(opts); // use carefully, not specced
645
614
  ### modular: Modular arithmetics utilities
646
615
 
647
616
  ```ts
648
- import * as mod from '@noble/curves/abstract/modular';
617
+ import * as mod from '@noble/curves/abstract/modular.js';
649
618
 
650
619
  // Finite Field utils
651
620
  const fp = mod.Field(2n ** 255n - 19n); // Finite field over 2^255-19
@@ -695,10 +664,10 @@ Use [abstract/hash-to-curve](#hash-to-curve-hashing-strings-to-curve-points)
695
664
  if you need to hash to **public key**.
696
665
 
697
666
  ```ts
698
- import { p256 } from '@noble/curves/nist';
699
- import { sha256 } from '@noble/hashes/sha256';
700
- import { hkdf } from '@noble/hashes/hkdf';
701
- import * as mod from '@noble/curves/abstract/modular';
667
+ import { p256 } from '@noble/curves/nist.js';
668
+ import { sha256 } from '@noble/hashes/sha2.js';
669
+ import { hkdf } from '@noble/hashes/hkdf.js';
670
+ import * as mod from '@noble/curves/abstract/modular.js';
702
671
  const someKey = new Uint8Array(32).fill(2); // Needs to actually be random, not .fill(2)
703
672
  const derived = hkdf(sha256, someKey, undefined, 'application', 48); // 48 bytes for 32-byte priv
704
673
  const validPrivateKey = mod.hashToPrivateScalar(derived, p256.CURVE.n);
@@ -707,7 +676,7 @@ const validPrivateKey = mod.hashToPrivateScalar(derived, p256.CURVE.n);
707
676
  ### utils: Useful utilities
708
677
 
709
678
  ```ts
710
- import * as utils from '@noble/curves/abstract/utils';
679
+ import * as utils from '@noble/curves/abstract/utils.js';
711
680
 
712
681
  utils.bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
713
682
  utils.hexToBytes('deadbeef');
@@ -724,6 +693,11 @@ utils.nLength(255n);
724
693
  utils.equalBytes(Uint8Array.from([0xde]), Uint8Array.from([0xde]));
725
694
  ```
726
695
 
696
+ ### Unreleased bits
697
+
698
+ - `test/unreleased-xeddsa.ts` contains implementation of XEd25519, defined by Signal
699
+ - `test/misc/endomorphism.js` contains tool for generation of endomorphism params for Koblitz curves
700
+
727
701
  ## Security
728
702
 
729
703
  The library has been independently audited:
@@ -763,6 +737,30 @@ constant-timeness_. Even statically typed Rust, a language without GC,
763
737
  for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones.
764
738
  Use low-level libraries & languages.
765
739
 
740
+ ### Memory dumping
741
+
742
+ Use low-level languages instead of JS / WASM if your goal is absolute security.
743
+
744
+ The library mostly uses Uint8Arrays and bigints.
745
+
746
+ - Uint8Arrays have `.fill(0)` which instructs to fill content with zeroes
747
+ but there are no guarantees in JS
748
+ - bigints are immutable and don't have a method to zeroize their content:
749
+ a user needs to wait until the next garbage collection cycle
750
+ - hex strings are also immutable: there is no way to zeroize them
751
+ - `await fn()` will write all internal variables to memory. With
752
+ async functions there are no guarantees when the code
753
+ chunk would be executed. Which means attacker can have
754
+ plenty of time to read data from memory.
755
+
756
+ This means some secrets could stay in memory longer than anticipated.
757
+ However, if an attacker can read application memory, it's doomed anyway:
758
+ there is no way to guarantee anything about zeroizing sensitive data without
759
+ complex tests-suite which will dump process memory and verify that there is
760
+ no sensitive data left. For JS it means testing all browsers (including mobile).
761
+ And, of course, it will be useless without using the same
762
+ test-suite in the actual application that consumes the library.
763
+
766
764
  ### Supply chain security
767
765
 
768
766
  - **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures
@@ -807,10 +805,12 @@ NIST prohibits classical cryptography (RSA, DSA, ECDSA, ECDH) [after 2035](https
807
805
  npm run bench:install && npm run bench
808
806
  ```
809
807
 
810
- During first call of most methods, `init` is done, which calculates base point precomputes.
811
- The method consumes 20MB+ of memory and takes some time.
812
- You can adjust how many precomputes are generated,
813
- by using `_setWindowSize`. Check out the source code.
808
+ noble-curves spends 10+ ms to generate 20MB+ of base point precomputes.
809
+ This is done **one-time** per curve.
810
+
811
+ The generation is deferred until any method (pubkey, sign, verify) is called.
812
+ User can force precompute generation by manually calling `Point.BASE.precompute(windowSize, false)`.
813
+ Check out the source code.
814
814
 
815
815
  Benchmark results on Apple M4:
816
816
 
@@ -915,6 +915,17 @@ aggregateSignatures/2048 x 0 ops/sec @ 2823ms/op
915
915
 
916
916
  ## Upgrading
917
917
 
918
+ Supported node.js versions:
919
+
920
+ - v2: v20.19+ (ESM-only)
921
+ - v1: v14.21+ (ESM & CJS)
922
+
923
+ ### curves v1 => curves v2
924
+
925
+ WIP. Changelog of v2, when upgrading from curves v1.
926
+
927
+ ### noble-secp256k1 v1 => curves v1
928
+
918
929
  Previously, the library was split into single-feature packages
919
930
  [noble-secp256k1](https://github.com/paulmillr/noble-secp256k1),
920
931
  [noble-ed25519](https://github.com/paulmillr/noble-ed25519) and
@@ -924,10 +935,6 @@ Curves continue their original work. The single-feature packages changed their
924
935
  direction towards providing minimal 4kb implementations of cryptography,
925
936
  which means they have less features.
926
937
 
927
- Upgrading from noble-secp256k1 2.0 or noble-ed25519 2.0: no changes, libraries are compatible.
928
-
929
- Upgrading from noble-secp256k1 1.7:
930
-
931
938
  - `getPublicKey`
932
939
  - now produce 33-byte compressed signatures by default
933
940
  - to use old behavior, which produced 65-byte uncompressed keys, set
@@ -954,6 +961,8 @@ Upgrading from noble-secp256k1 1.7:
954
961
  - `utils` were split into `utils` (same api as in noble-curves) and
955
962
  `etc` (`hmacSha256Sync` and others)
956
963
 
964
+ ### noble-ed25519 v1 => curves v1
965
+
957
966
  Upgrading from [@noble/ed25519](https://github.com/paulmillr/noble-ed25519) 1.7:
958
967
 
959
968
  - Methods are now sync by default
@@ -965,6 +974,8 @@ Upgrading from [@noble/ed25519](https://github.com/paulmillr/noble-ed25519) 1.7:
965
974
  - `getSharedSecret` was moved to `x25519` module
966
975
  - `toX25519` has been moved to `edwardsToMontgomeryPub` and `edwardsToMontgomeryPriv` methods
967
976
 
977
+ ### noble-bls12-381 => curves v1
978
+
968
979
  Upgrading from [@noble/bls12-381](https://github.com/paulmillr/noble-bls12-381):
969
980
 
970
981
  - Methods and classes were renamed: