@noble/curves 0.9.1 → 1.1.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 (103) hide show
  1. package/README.md +324 -177
  2. package/_shortw_utils.d.ts +1 -1
  3. package/abstract/bls.d.ts +43 -31
  4. package/abstract/bls.d.ts.map +1 -1
  5. package/abstract/bls.js +37 -28
  6. package/abstract/bls.js.map +1 -1
  7. package/abstract/edwards.d.ts +9 -4
  8. package/abstract/edwards.d.ts.map +1 -1
  9. package/abstract/edwards.js +37 -20
  10. package/abstract/edwards.js.map +1 -1
  11. package/abstract/hash-to-curve.d.ts +1 -1
  12. package/abstract/hash-to-curve.d.ts.map +1 -1
  13. package/abstract/hash-to-curve.js +3 -2
  14. package/abstract/hash-to-curve.js.map +1 -1
  15. package/abstract/modular.d.ts +5 -3
  16. package/abstract/modular.d.ts.map +1 -1
  17. package/abstract/modular.js +6 -4
  18. package/abstract/modular.js.map +1 -1
  19. package/abstract/utils.d.ts +42 -5
  20. package/abstract/utils.d.ts.map +1 -1
  21. package/abstract/utils.js +69 -26
  22. package/abstract/utils.js.map +1 -1
  23. package/abstract/weierstrass.d.ts +38 -2
  24. package/abstract/weierstrass.d.ts.map +1 -1
  25. package/abstract/weierstrass.js +55 -26
  26. package/abstract/weierstrass.js.map +1 -1
  27. package/bls12-381.d.ts.map +1 -1
  28. package/bls12-381.js +61 -64
  29. package/bls12-381.js.map +1 -1
  30. package/{bn.d.ts → bn254.d.ts} +1 -1
  31. package/bn254.d.ts.map +1 -0
  32. package/{bn.js → bn254.js} +1 -1
  33. package/bn254.js.map +1 -0
  34. package/ed25519.d.ts +38 -17
  35. package/ed25519.d.ts.map +1 -1
  36. package/ed25519.js +68 -35
  37. package/ed25519.js.map +1 -1
  38. package/ed448.d.ts +12 -3
  39. package/ed448.d.ts.map +1 -1
  40. package/ed448.js +25 -24
  41. package/ed448.js.map +1 -1
  42. package/esm/abstract/bls.js +37 -28
  43. package/esm/abstract/bls.js.map +1 -1
  44. package/esm/abstract/edwards.js +37 -20
  45. package/esm/abstract/edwards.js.map +1 -1
  46. package/esm/abstract/hash-to-curve.js +3 -2
  47. package/esm/abstract/hash-to-curve.js.map +1 -1
  48. package/esm/abstract/modular.js +6 -4
  49. package/esm/abstract/modular.js.map +1 -1
  50. package/esm/abstract/utils.js +69 -26
  51. package/esm/abstract/utils.js.map +1 -1
  52. package/esm/abstract/weierstrass.js +47 -18
  53. package/esm/abstract/weierstrass.js.map +1 -1
  54. package/esm/bls12-381.js +62 -65
  55. package/esm/bls12-381.js.map +1 -1
  56. package/esm/{bn.js → bn254.js} +1 -1
  57. package/esm/bn254.js.map +1 -0
  58. package/esm/ed25519.js +67 -35
  59. package/esm/ed25519.js.map +1 -1
  60. package/esm/ed448.js +23 -22
  61. package/esm/ed448.js.map +1 -1
  62. package/esm/p256.js +15 -15
  63. package/esm/p256.js.map +1 -1
  64. package/esm/p384.js +15 -16
  65. package/esm/p384.js.map +1 -1
  66. package/esm/p521.js +27 -22
  67. package/esm/p521.js.map +1 -1
  68. package/esm/secp256k1.js +11 -9
  69. package/esm/secp256k1.js.map +1 -1
  70. package/p256.d.ts +5 -6
  71. package/p256.d.ts.map +1 -1
  72. package/p256.js +16 -17
  73. package/p256.js.map +1 -1
  74. package/p384.d.ts +5 -6
  75. package/p384.d.ts.map +1 -1
  76. package/p384.js +16 -18
  77. package/p384.js.map +1 -1
  78. package/p521.d.ts +5 -6
  79. package/p521.d.ts.map +1 -1
  80. package/p521.js +28 -24
  81. package/p521.js.map +1 -1
  82. package/package.json +9 -15
  83. package/secp256k1.d.ts +5 -5
  84. package/secp256k1.d.ts.map +1 -1
  85. package/secp256k1.js +11 -10
  86. package/secp256k1.js.map +1 -1
  87. package/src/abstract/bls.ts +83 -61
  88. package/src/abstract/edwards.ts +51 -20
  89. package/src/abstract/hash-to-curve.ts +4 -3
  90. package/src/abstract/modular.ts +6 -8
  91. package/src/abstract/utils.ts +74 -33
  92. package/src/abstract/weierstrass.ts +57 -26
  93. package/src/bls12-381.ts +68 -76
  94. package/src/ed25519.ts +114 -73
  95. package/src/ed448.ts +50 -46
  96. package/src/p256.ts +27 -32
  97. package/src/p384.ts +28 -33
  98. package/src/p521.ts +41 -30
  99. package/src/secp256k1.ts +60 -55
  100. package/bn.d.ts.map +0 -1
  101. package/bn.js.map +0 -1
  102. package/esm/bn.js.map +0 -1
  103. /package/src/{bn.ts → bn254.ts} +0 -0
package/README.md CHANGED
@@ -2,21 +2,19 @@
2
2
 
3
3
  Audited & minimal JS implementation of elliptic curve cryptography.
4
4
 
5
- - Short Weierstrass, Edwards, Montgomery curves
6
- - ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
7
5
  - 🔒 [**Audited**](#security) by an independent security firm
8
- - #️⃣ [hash to curve](#abstracthash-to-curve-hashing-strings-to-curve-points)
9
- for encoding or hashing an arbitrary string to an elliptic curve point
10
- - 🧜‍♂️ [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash
11
- - 🏎 [Ultra-fast](#speed), hand-optimized for caveats of JS engines
12
- - 🔍 Unique tests ensure correctness with Wycheproof vectors and
13
- [cryptofuzz](https://github.com/guidovranken/cryptofuzz) differential fuzzing
14
6
  - 🔻 Tree-shaking-friendly: use only what's necessary, other code won't be included
7
+ - 🏎 Ultra-fast, hand-optimized for caveats of JS engines
8
+ - 🔍 Unique tests ensure correctness: property-based, cross-library and Wycheproof vectors, fuzzing
9
+ - ➰ Short Weierstrass, Edwards, Montgomery curves
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
14
+ - 🧜‍♂️ Poseidon ZK-friendly hash
15
15
 
16
16
  Check out [Upgrading](#upgrading) if you've previously used single-feature noble
17
- packages ([secp256k1](https://github.com/paulmillr/noble-secp256k1),
18
- [ed25519](https://github.com/paulmillr/noble-ed25519)).
19
- See [Resources](#resources) for articles and real-world software that uses curves.
17
+ packages. See [Resources](#resources) for articles and real-world software that uses curves.
20
18
 
21
19
  ### This library belongs to _noble_ crypto
22
20
 
@@ -34,52 +32,48 @@ See [Resources](#resources) for articles and real-world software that uses curve
34
32
 
35
33
  ## Usage
36
34
 
37
- Browser, deno and node.js are supported:
38
-
39
35
  > npm install @noble/curves
40
36
 
41
- For [Deno](https://deno.land), use it with
42
- [npm specifier](https://deno.land/manual@v1.28.0/node/npm_specifiers).
43
- In browser, you could also include the single file from
44
- [GitHub's releases page](https://github.com/paulmillr/noble-curves/releases).
37
+ We support all major platforms and runtimes.
38
+ 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.
45
41
 
46
42
  The library is tree-shaking-friendly and does not expose root entry point as
47
- `import * from '@noble/curves'`. Instead, you need to import specific primitives.
43
+ `@noble/curves`. Instead, you need to import specific primitives.
48
44
  This is done to ensure small size of your apps.
49
45
 
50
- Package consists of two parts:
46
+ The package consists of two parts:
51
47
 
52
- 1. [Implementations](#implementations), utilizing one dependency `@noble/hashes`,
48
+ * [Implementations](#implementations), utilizing one dependency [noble-hashes](https://github.com/paulmillr/noble-hashes),
53
49
  providing ready-to-use:
54
- - NIST curves secp256r1/P256, secp384r1/P384, secp521r1/P521
50
+ - NIST curves secp256r1 / p256, secp384r1 / p384, secp521r1 / p521
55
51
  - SECG curve secp256k1
56
- - ed25519/curve25519/x25519/ristretto255, edwards448/curve448/x448
57
- implementing
58
- [RFC7748](https://www.rfc-editor.org/rfc/rfc7748) /
59
- [RFC8032](https://www.rfc-editor.org/rfc/rfc8032) /
60
- [ZIP215](https://zips.z.cash/zip-0215) standards
52
+ - ed25519 / curve25519 / x25519 / ristretto255, edwards448 / curve448 / x448
61
53
  - pairing-friendly curves bls12-381, bn254
62
- 2. [Abstract](#abstract-api), zero-dependency EC algorithms
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
63
56
 
64
57
  ### Implementations
65
58
 
66
- Each curve can be used in the following way:
59
+ #### Generic example for all curves, secp256k1
67
60
 
68
61
  ```ts
62
+ // Each curve has similar methods
69
63
  import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
70
64
  // import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
71
65
  const priv = secp256k1.utils.randomPrivateKey();
72
66
  const pub = secp256k1.getPublicKey(priv);
73
67
  const msg = new Uint8Array(32).fill(1);
74
68
  const sig = secp256k1.sign(msg, priv);
75
- secp256k1.verify(sig, msg, pub) === true;
69
+ const isValid = secp256k1.verify(sig, msg, pub) === true;
76
70
 
77
71
  // hex strings are also supported besides Uint8Arrays:
78
72
  const privHex = '46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c126236';
79
73
  const pub2 = secp256k1.getPublicKey(privHex);
80
74
  ```
81
75
 
82
- All curves:
76
+ #### All imports
83
77
 
84
78
  ```typescript
85
79
  import { secp256k1, schnorr } from '@noble/curves/secp256k1';
@@ -90,11 +84,11 @@ import { p384 } from '@noble/curves/p384';
90
84
  import { p521 } from '@noble/curves/p521';
91
85
  import { pallas, vesta } from '@noble/curves/pasta';
92
86
  import { bls12_381 } from '@noble/curves/bls12-381';
93
- import { bn254 } from '@noble/curves/bn';
87
+ import { bn254 } from '@noble/curves/bn254';
94
88
  import { jubjub } from '@noble/curves/jubjub';
95
89
  ```
96
90
 
97
- Weierstrass curves feature recovering public keys from signatures and ECDH key agreement:
91
+ #### ECDSA public key recovery & ECDH
98
92
 
99
93
  ```ts
100
94
  // extraEntropy https://moderncrypto.org/mail-archive/curves/2017/000925.html
@@ -104,8 +98,7 @@ const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
104
98
  const shared = secp256k1.getSharedSecret(priv, someonesPub); // ECDH
105
99
  ```
106
100
 
107
- secp256k1 has schnorr signature implementation which follows
108
- [BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki):
101
+ #### Schnorr signatures over secp256k1 (BIP340)
109
102
 
110
103
  ```ts
111
104
  import { schnorr } from '@noble/curves/secp256k1';
@@ -116,13 +109,29 @@ const sig = schnorr.sign(msg, priv);
116
109
  const isValid = schnorr.verify(sig, msg, pub);
117
110
  ```
118
111
 
119
- ed25519 module has ed25519ctx / ed25519ph variants,
120
- x25519 ECDH and [ristretto255](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448).
121
- It follows [ZIP215](https://zips.z.cash/zip-0215) and [can be used in consensus-critical applications](https://hdevalence.ca/blog/2020-10-04-its-25519am):
112
+ #### ed25519, X25519, ristretto255
122
113
 
123
114
  ```ts
124
115
  import { ed25519 } from '@noble/curves/ed25519';
116
+ const priv = ed25519.utils.randomPrivateKey();
117
+ const pub = ed25519.getPublicKey(priv);
118
+ const msg = new TextEncoder().encode('hello');
119
+ const sig = ed25519.sign(msg, priv);
120
+ ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
121
+ ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5
122
+ ```
123
+
124
+ Default `verify` behavior follows [ZIP215](https://zips.z.cash/zip-0215) and
125
+ [can be used in consensus-critical applications](https://hdevalence.ca/blog/2020-10-04-its-25519am).
126
+ It has SUF-CMA (strong unforgeability under chosen message attacks).
127
+ `zip215: false` option switches verification criteria to strict
128
+ [RFC8032](https://www.rfc-editor.org/rfc/rfc8032) / [FIPS 186-5](https://csrc.nist.gov/publications/detail/fips/186/5/final)
129
+ and additionally provides non-repudiation with SBS [(Strongly Binding Signatures)](https://eprint.iacr.org/2020/1244).
125
130
 
131
+ 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
+
134
+ ```ts
126
135
  // Variants from RFC8032: with context, prehashed
127
136
  import { ed25519ctx, ed25519ph } from '@noble/curves/ed25519';
128
137
 
@@ -132,11 +141,15 @@ const priv = 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4';
132
141
  const pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';
133
142
  x25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub); // aliases
134
143
  x25519.getPublicKey(priv) === x25519.scalarMultBase(priv);
144
+ x25519.getPublicKey(x25519.utils.randomPrivateKey());
135
145
 
136
- // hash-to-curve
137
- import { hashToCurve, encodeToCurve } from '@noble/curves/ed25519';
146
+ // ed25519 => x25519 conversion
147
+ import { edwardsToMontgomeryPub, edwardsToMontgomeryPriv } from '@noble/curves/ed25519';
148
+ edwardsToMontgomeryPub(ed25519.getPublicKey(ed25519.utils.randomPrivateKey()));
149
+ edwardsToMontgomeryPriv(ed25519.utils.randomPrivateKey());
138
150
 
139
- import { RistrettoPoint } from '@noble/curves/ed25519';
151
+ // hash-to-curve, ristretto255
152
+ import { hashToCurve, encodeToCurve, RistrettoPoint } from '@noble/curves/ed25519';
140
153
  const rp = RistrettoPoint.fromHex(
141
154
  '6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919'
142
155
  );
@@ -144,59 +157,36 @@ RistrettoPoint.hashToCurve('Ristretto is traditionally a short shot of espresso
144
157
  // also has add(), equals(), multiply(), toRawBytes() methods
145
158
  ```
146
159
 
147
- ed448 is similar:
160
+ #### ed448, X448
148
161
 
149
162
  ```ts
150
- import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
151
- import { hashToCurve, encodeToCurve } from '@noble/curves/ed448';
152
- ed448.getPublicKey(ed448.utils.randomPrivateKey());
163
+ import { ed448 } from '@noble/curves/ed448';
164
+ const priv = ed448.utils.randomPrivateKey();
165
+ const pub = ed448.getPublicKey(priv);
166
+ const msg = new TextEncoder().encode('whatsup');
167
+ const sig = ed448.sign(msg, priv);
168
+ ed448.verify(sig, msg, pub);
169
+
170
+ import { ed448ph, ed448ctx, x448, hashToCurve, encodeToCurve } from '@noble/curves/ed448';
171
+ x448.getSharedSecret(priv, pub) === x448.scalarMult(priv, pub); // aliases
172
+ x448.getPublicKey(priv) === x448.scalarMultBase(priv);
153
173
  ```
154
174
 
155
- Every curve has params:
175
+ Same RFC7748 / RFC8032 are followed.
156
176
 
157
- ```ts
158
- import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
159
- console.log(secp256k1.CURVE.p, secp256k1.CURVE.n, secp256k1.CURVE.a, secp256k1.CURVE.b);
160
- ```
177
+ #### bls12-381
161
178
 
162
- BLS12-381 pairing-friendly Barreto-Lynn-Scott elliptic curve construction allows to
163
- construct [zk-SNARKs](https://z.cash/technology/zksnarks/) at the 128-bit security
164
- and use aggregated, batch-verifiable
165
- [threshold signatures](https://medium.com/snigirev.stepan/bls-signatures-better-than-schnorr-5a7fe30ea716),
166
- using Boneh-Lynn-Shacham signature scheme. Compatible with ETH and others,
167
- just make sure to provide correct DST (domain separation tag argument).
168
-
169
- ```ts
170
- import { bls12_381 as bls } from '@noble/curves/bls12-381';
171
- const privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';
172
- const message = '64726e3da8';
173
- const publicKey = bls.getPublicKey(privateKey);
174
- const signature = bls.sign(message, privateKey);
175
- const isValid = bls.verify(signature, message, publicKey);
176
- console.log({ publicKey, signature, isValid });
177
-
178
- // Sign 1 msg with 3 keys
179
- const privateKeys = [
180
- '18f020b98eb798752a50ed0563b079c125b0db5dd0b1060d1c1b47d4a193e1e4',
181
- 'ed69a8c50cf8c9836be3b67c7eeff416612d45ba39a5c099d48fa668bf558c9c',
182
- '16ae669f3be7a2121e17d0c68c05a8f3d6bef21ec0f2315f1d7aec12484e4cf5',
183
- ];
184
- const messages = ['d2', '0d98', '05caf3'];
185
- const publicKeys = privateKeys.map(bls.getPublicKey);
186
- const signatures2 = privateKeys.map((p) => bls.sign(message, p));
187
- const aggPubKey2 = bls.aggregatePublicKeys(publicKeys);
188
- const aggSignature2 = bls.aggregateSignatures(signatures2);
189
- const isValid2 = bls.verify(aggSignature2, message, aggPubKey2);
190
- console.log({ signatures2, aggSignature2, isValid2 });
179
+ See [abstract/bls](#abstractbls-barreto-lynn-scott-curves).
191
180
 
192
- // Sign 3 msgs with 3 keys
193
- const signatures3 = privateKeys.map((p, i) => bls.sign(messages[i], p));
194
- const aggSignature3 = bls.aggregateSignatures(signatures3);
195
- const isValid3 = bls.verifyBatch(aggSignature3, messages, publicKeys);
196
- console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
197
- // bls.pairing(PointG1, PointG2) // pairings
181
+ #### Accessing a curve's variables
198
182
 
199
- // hash-to-curve examples can be seen below
183
+ ```ts
184
+ import { secp256k1 } from '@noble/curves/secp256k1';
185
+ // Every curve has `CURVE` object that contains its parameters, field, and others
186
+ console.log(secp256k1.CURVE.p); // field modulus
187
+ console.log(secp256k1.CURVE.n); // curve order
188
+ console.log(secp256k1.CURVE.a, secp256k1.CURVE.b); // equation params
189
+ console.log(secp256k1.CURVE.Gx, secp256k1.CURVE.Gy); // base point coordinates
200
190
  ```
201
191
 
202
192
  ## Abstract API
@@ -214,6 +204,7 @@ There are following zero-dependency algorithms:
214
204
  - [abstract/weierstrass: Short Weierstrass curve](#abstractweierstrass-short-weierstrass-curve)
215
205
  - [abstract/edwards: Twisted Edwards curve](#abstractedwards-twisted-edwards-curve)
216
206
  - [abstract/montgomery: Montgomery curve](#abstractmontgomery-montgomery-curve)
207
+ - [abstract/bls: Barreto-Lynn-Scott curves](#abstractbls-barreto-lynn-scott-curves)
217
208
  - [abstract/hash-to-curve: Hashing strings to curve points](#abstracthash-to-curve-hashing-strings-to-curve-points)
218
209
  - [abstract/poseidon: Poseidon hash](#abstractposeidon-poseidon-hash)
219
210
  - [abstract/modular: Modular arithmetics utilities](#abstractmodular-modular-arithmetics-utilities)
@@ -242,7 +233,7 @@ const secq256k1 = weierstrass({
242
233
  randomBytes,
243
234
  });
244
235
 
245
- // weierstrassPoints can also be used if you don't need ECDSA, hash, hmac, randomBytes
236
+ // Replace weierstrass with weierstrassPoints if you don't need ECDSA, hash, hmac, randomBytes
246
237
  ```
247
238
 
248
239
  Short Weierstrass curve's formula is `y² = x³ + ax + b`. `weierstrass`
@@ -303,6 +294,8 @@ interface ProjPointType<T> extends Group<ProjPointType<T>> {
303
294
  readonly px: T;
304
295
  readonly py: T;
305
296
  readonly pz: T;
297
+ get x(): bigint;
298
+ get y(): bigint;
306
299
  multiply(scalar: bigint): ProjPointType<T>;
307
300
  multiplyUnsafe(scalar: bigint): ProjPointType<T>;
308
301
  multiplyAndAddUnsafe(Q: ProjPointType<T>, a: bigint, b: bigint): ProjPointType<T> | undefined;
@@ -388,7 +381,7 @@ import { randomBytes } from '@noble/hashes/utils';
388
381
 
389
382
  const Fp = Field(2n ** 255n - 19n);
390
383
  const ed25519 = twistedEdwards({
391
- a: -1n,
384
+ a: Fp.create(-1n),
392
385
  d: Fp.div(-121665n, 121666n), // -121665n/121666n mod p
393
386
  Fp: Fp,
394
387
  n: 2n ** 252n + 27742317777372353535851937790883648493n,
@@ -447,6 +440,8 @@ interface ExtPointType extends Group<ExtPointType> {
447
440
  readonly ey: bigint;
448
441
  readonly ez: bigint;
449
442
  readonly et: bigint;
443
+ get x(): bigint;
444
+ get y(): bigint;
450
445
  assertValidity(): void;
451
446
  multiply(scalar: bigint): ExtPointType;
452
447
  multiplyUnsafe(scalar: bigint): ExtPointType;
@@ -454,6 +449,8 @@ interface ExtPointType extends Group<ExtPointType> {
454
449
  isTorsionFree(): boolean;
455
450
  clearCofactor(): ExtPointType;
456
451
  toAffine(iz?: bigint): AffinePoint<bigint>;
452
+ toRawBytes(isCompressed?: boolean): Uint8Array;
453
+ toHex(isCompressed?: boolean): string;
457
454
  }
458
455
  // Static methods of Extended Point with coordinates in X, Y, Z, T
459
456
  interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
@@ -491,6 +488,114 @@ Proper Elliptic Curve Points are not implemented yet.
491
488
 
492
489
  You must specify curve params `Fp`, `a`, `Gu` coordinate of u, `montgomeryBits` and `nByteLength`.
493
490
 
491
+ ### abstract/bls: Barreto-Lynn-Scott curves
492
+
493
+ The module abstracts BLS (Barreto-Lynn-Scott) pairing-friendly elliptic curve construction.
494
+ They allow to construct [zk-SNARKs](https://z.cash/technology/zksnarks/) and
495
+ use aggregated, batch-verifiable
496
+ [threshold signatures](https://medium.com/snigirev.stepan/bls-signatures-better-than-schnorr-5a7fe30ea716),
497
+ using Boneh-Lynn-Shacham signature scheme.
498
+
499
+ Main methods and properties are:
500
+
501
+ - `getPublicKey(privateKey)`
502
+ - `sign(message, privateKey)`
503
+ - `verify(signature, message, publicKey)`
504
+ - `aggregatePublicKeys(publicKeys)`
505
+ - `aggregateSignatures(signatures)`
506
+ - `G1` and `G2` curves containing `CURVE` and `ProjectivePoint`
507
+ - `Signature` property with `fromHex`, `toHex` methods
508
+ - `fields` containing `Fp`, `Fp2`, `Fp6`, `Fp12`, `Fr`
509
+
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:
512
+
513
+ ```ts
514
+ import { bls12_381 as bls } from '@noble/curves/bls12-381';
515
+ const privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';
516
+ const message = '64726e3da8';
517
+ const publicKey = bls.getPublicKey(privateKey);
518
+ const signature = bls.sign(message, privateKey);
519
+ const isValid = bls.verify(signature, message, publicKey);
520
+ console.log({ publicKey, signature, isValid });
521
+
522
+ // Sign 1 msg with 3 keys
523
+ const privateKeys = [
524
+ '18f020b98eb798752a50ed0563b079c125b0db5dd0b1060d1c1b47d4a193e1e4',
525
+ 'ed69a8c50cf8c9836be3b67c7eeff416612d45ba39a5c099d48fa668bf558c9c',
526
+ '16ae669f3be7a2121e17d0c68c05a8f3d6bef21ec0f2315f1d7aec12484e4cf5',
527
+ ];
528
+ const messages = ['d2', '0d98', '05caf3'];
529
+ const publicKeys = privateKeys.map(bls.getPublicKey);
530
+ const signatures2 = privateKeys.map((p) => bls.sign(message, p));
531
+ const aggPubKey2 = bls.aggregatePublicKeys(publicKeys);
532
+ const aggSignature2 = bls.aggregateSignatures(signatures2);
533
+ const isValid2 = bls.verify(aggSignature2, message, aggPubKey2);
534
+ console.log({ signatures2, aggSignature2, isValid2 });
535
+
536
+ // Sign 3 msgs with 3 keys
537
+ const signatures3 = privateKeys.map((p, i) => bls.sign(messages[i], p));
538
+ const aggSignature3 = bls.aggregateSignatures(signatures3);
539
+ const isValid3 = bls.verifyBatch(aggSignature3, messages, publicKeys);
540
+ console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
541
+
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
545
+
546
+ // hash-to-curve examples can be seen below
547
+ ```
548
+
549
+ Full types:
550
+
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
+ };
597
+ ```
598
+
494
599
  ### abstract/hash-to-curve: Hashing strings to curve points
495
600
 
496
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).
@@ -589,11 +694,6 @@ type PoseidonOpts = {
589
694
  const instance = poseidon(opts: PoseidonOpts);
590
695
  ```
591
696
 
592
- ### abstract/bls
593
-
594
- The module abstracts BLS (Barreto-Lynn-Scott) primitives. In theory you should be able to write BLS12-377, BLS24,
595
- and others with it.
596
-
597
697
  ### abstract/modular: Modular arithmetics utilities
598
698
 
599
699
  ```ts
@@ -640,12 +740,14 @@ import * as utils from '@noble/curves/abstract/utils';
640
740
 
641
741
  utils.bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
642
742
  utils.hexToBytes('deadbeef');
743
+ utils.numberToHexUnpadded(123n);
643
744
  utils.hexToNumber();
745
+
644
746
  utils.bytesToNumberBE(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
645
747
  utils.bytesToNumberLE(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
646
748
  utils.numberToBytesBE(123n, 32);
647
749
  utils.numberToBytesLE(123n, 64);
648
- utils.numberToHexUnpadded(123n);
750
+
649
751
  utils.concatBytes(Uint8Array.from([0xde, 0xad]), Uint8Array.from([0xbe, 0xef]));
650
752
  utils.nLength(255n);
651
753
  utils.equalBytes(Uint8Array.from([0xde]), Uint8Array.from([0xde]));
@@ -653,9 +755,9 @@ utils.equalBytes(Uint8Array.from([0xde]), Uint8Array.from([0xde]));
653
755
 
654
756
  ## Security
655
757
 
656
- 1. The library has been audited during Jan-Feb 2023 by an independent security firm [Trail of Bits](https://www.trailofbits.com):
758
+ 1. The library has been audited in Feb 2023 by an independent security firm [Trail of Bits](https://www.trailofbits.com):
657
759
  [PDF](https://github.com/trailofbits/publications/blob/master/reviews/2023-01-ryanshea-noblecurveslibrary-securityreview.pdf).
658
- The audit has been funded by Ryan Shea. 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).
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).
659
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.
660
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.
661
763
 
@@ -668,82 +770,89 @@ We consider infrastructure attacks like rogue NPM modules very important; that's
668
770
  The packages are big, which makes it hard to audit their source code thoroughly and fully.
669
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.
670
772
 
773
+ As for key generation, we're deferring to built-in
774
+ [crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)
775
+ which is considered cryptographically secure (CSPRNG).
776
+
671
777
  ## Speed
672
778
 
673
- Benchmark results on Apple M2 with node v19:
779
+ Benchmark results on Apple M2 with node v20:
674
780
 
675
781
  ```
676
782
  secp256k1
677
- init x 58 ops/sec @ 17ms/op
678
- getPublicKey x 5,640 ops/sec @ 177μs/op
679
- sign x 3,909 ops/sec @ 255μs/op
680
- verify x 780 ops/sec @ 1ms/op
681
- getSharedSecret x 465 ops/sec @ 2ms/op
682
- recoverPublicKey x 740 ops/sec @ 1ms/op
683
- schnorr.sign x 597 ops/sec @ 1ms/op
684
- schnorr.verify x 775 ops/sec @ 1ms/op
685
-
686
- P256
687
- init x 31 ops/sec @ 31ms/op
688
- getPublicKey x 5,607 ops/sec @ 178μs/op
689
- sign x 3,930 ops/sec @ 254μs/op
690
- verify x 540 ops/sec @ 1ms/op
691
-
692
- P384
693
- init x 15 ops/sec @ 63ms/op
694
- getPublicKey x 2,622 ops/sec @ 381μs/op
695
- sign x 1,913 ops/sec @ 522μs/op
696
- verify x 222 ops/sec @ 4ms/op
697
-
698
- P521
699
- init x 8 ops/sec @ 119ms/op
700
- getPublicKey x 1,371 ops/sec @ 729μs/op
701
- sign x 1,090 ops/sec @ 917μs/op
702
- verify x 118 ops/sec @ 8ms/op
783
+ init x 68 ops/sec @ 14ms/op
784
+ getPublicKey x 6,750 ops/sec @ 148μs/op
785
+ sign x 5,206 ops/sec @ 192μs/op
786
+ verify x 880 ops/sec @ 1ms/op
787
+ getSharedSecret x 536 ops/sec @ 1ms/op
788
+ recoverPublicKey x 852 ops/sec @ 1ms/op
789
+ schnorr.sign x 685 ops/sec @ 1ms/op
790
+ schnorr.verify x 908 ops/sec @ 1ms/op
791
+
792
+ p256
793
+ init x 38 ops/sec @ 26ms/op
794
+ getPublicKey x 6,530 ops/sec @ 153μs/op
795
+ sign x 5,074 ops/sec @ 197μs/op
796
+ verify x 626 ops/sec @ 1ms/op
797
+
798
+ p384
799
+ init x 17 ops/sec @ 57ms/op
800
+ getPublicKey x 2,883 ops/sec @ 346μs/op
801
+ sign x 2,358 ops/sec @ 424μs/op
802
+ verify x 245 ops/sec @ 4ms/op
803
+
804
+ p521
805
+ init x 9 ops/sec @ 109ms/op
806
+ getPublicKey x 1,516 ops/sec @ 659μs/op
807
+ sign x 1,271 ops/sec @ 786μs/op
808
+ verify x 123 ops/sec @ 8ms/op
703
809
 
704
810
  ed25519
705
- init x 47 ops/sec @ 20ms/op
706
- getPublicKey x 9,414 ops/sec @ 106μs/op
707
- sign x 4,516 ops/sec @ 221μs/op
708
- verify x 912 ops/sec @ 1ms/op
811
+ init x 54 ops/sec @ 18ms/op
812
+ getPublicKey x 10,269 ops/sec @ 97μs/op
813
+ sign x 5,110 ops/sec @ 195μs/op
814
+ verify x 1,049 ops/sec @ 952μs/op
709
815
 
710
816
  ed448
711
- init x 17 ops/sec @ 56ms/op
712
- getPublicKey x 3,363 ops/sec @ 297μs/op
713
- sign x 1,615 ops/sec @ 619μs/op
714
- verify x 319 ops/sec @ 3ms/op
817
+ init x 19 ops/sec @ 51ms/op
818
+ getPublicKey x 3,775 ops/sec @ 264μs/op
819
+ sign x 1,771 ops/sec @ 564μs/op
820
+ verify x 351 ops/sec @ 2ms/op
715
821
 
716
822
  ecdh
717
- ├─x25519 x 1,337 ops/sec @ 747μs/op
718
- ├─secp256k1 x 461 ops/sec @ 2ms/op
719
- ├─P256 x 441 ops/sec @ 2ms/op
720
- ├─P384 x 179 ops/sec @ 5ms/op
721
- ├─P521 x 93 ops/sec @ 10ms/op
722
- └─x448 x 496 ops/sec @ 2ms/op
823
+ ├─x25519 x 1,466 ops/sec @ 682μs/op
824
+ ├─secp256k1 x 539 ops/sec @ 1ms/op
825
+ ├─p256 x 511 ops/sec @ 1ms/op
826
+ ├─p384 x 199 ops/sec @ 5ms/op
827
+ ├─p521 x 103 ops/sec @ 9ms/op
828
+ └─x448 x 548 ops/sec @ 1ms/op
723
829
 
724
830
  bls12-381
725
- init x 32 ops/sec @ 30ms/op
726
- getPublicKey 1-bit x 858 ops/sec @ 1ms/op
727
- getPublicKey x 858 ops/sec @ 1ms/op
728
- sign x 49 ops/sec @ 20ms/op
729
- verify x 34 ops/sec @ 28ms/op
730
- pairing x 94 ops/sec @ 10ms/op
731
- aggregatePublicKeys/8 x 116 ops/sec @ 8ms/op
732
- aggregatePublicKeys/32 x 31 ops/sec @ 31ms/op
733
- aggregatePublicKeys/128 x 7 ops/sec @ 125ms/op
734
- aggregateSignatures/8 x 45 ops/sec @ 22ms/op
735
- aggregateSignatures/32 x 11 ops/sec @ 84ms/op
736
- aggregateSignatures/128 x 3 ops/sec @ 332ms/opp
831
+ init x 36 ops/sec @ 27ms/op
832
+ getPublicKey 1-bit x 973 ops/sec @ 1ms/op
833
+ getPublicKey x 970 ops/sec @ 1ms/op
834
+ sign x 55 ops/sec @ 17ms/op
835
+ verify x 39 ops/sec @ 25ms/op
836
+ pairing x 106 ops/sec @ 9ms/op
837
+ aggregatePublicKeys/8 x 129 ops/sec @ 7ms/op
838
+ aggregatePublicKeys/32 x 34 ops/sec @ 28ms/op
839
+ aggregatePublicKeys/128 x 8 ops/sec @ 112ms/op
840
+ aggregatePublicKeys/512 x 2 ops/sec @ 446ms/op
841
+ aggregatePublicKeys/2048 x 0 ops/sec @ 1778ms/op
842
+ aggregateSignatures/8 x 50 ops/sec @ 19ms/op
843
+ aggregateSignatures/32 x 13 ops/sec @ 74ms/op
844
+ aggregateSignatures/128 x 3 ops/sec @ 296ms/op
845
+ aggregateSignatures/512 x 0 ops/sec @ 1180ms/op
846
+ aggregateSignatures/2048 x 0 ops/sec @ 4715ms/op
737
847
 
738
848
  hash-to-curve
739
- hash_to_field x 850,340 ops/sec @ 1μs/op
740
- hashToCurve
741
- ├─secp256k1 x 1,850 ops/sec @ 540μs/op
742
- ├─P256 x 3,352 ops/sec @ 298μs/op
743
- ├─P384 x 1,367 ops/sec @ 731μs/op
744
- ├─P521 x 691 ops/sec @ 1ms/op
745
- ├─ed25519 x 2,492 ops/sec @ 401μs/op
746
- └─ed448 x 1,045 ops/sec @ 956μs/op
849
+ hash_to_field x 91,600 ops/sec @ 10μs/op
850
+ secp256k1 x 2,373 ops/sec @ 421μs/op
851
+ p256 x 4,310 ops/sec @ 231μs/op
852
+ p384 x 1,664 ops/sec @ 600μs/op
853
+ p521 x 807 ops/sec @ 1ms/op
854
+ ed25519 x 3,088 ops/sec @ 323μs/op
855
+ ed448 x 1,247 ops/sec @ 801μs/op
747
856
  ```
748
857
 
749
858
  ## Contributing & testing
@@ -753,30 +862,16 @@ hashToCurve
753
862
  3. `npm run build` to compile TypeScript code
754
863
  4. `npm run test` will execute all main tests
755
864
 
756
- ## Resources
757
-
758
- Article about some of library's features: [Learning fast elliptic-curve cryptography](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/)
759
-
760
- Projects using the library:
761
-
762
- - secp256k1
763
- - [btc-signer](https://github.com/paulmillr/scure-btc-signer), [eth-signer](https://github.com/paulmillr/micro-eth-signer)
764
- - ed25519
765
- - [sol-signer](https://github.com/paulmillr/micro-sol-signer)
766
- - BLS12-381
767
- - Check out `bls12-381.ts` for articles about the curve
768
- - Threshold sigs demo [genthresh.com](https://genthresh.com)
769
- - BBS signatures [github.com/Wind4Greg/BBS-Draft-Checks](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)
770
- - Others
771
- - All curves demo: Elliptic curve calculator [paulmillr.com/noble](https://paulmillr.com/noble)
772
- - [micro-starknet](https://github.com/paulmillr/micro-starknet) for stark-friendly elliptic curve.
773
-
774
865
  ## Upgrading
775
866
 
776
867
  Previously, the library was split into single-feature packages
777
- noble-secp256k1 and noble-ed25519. curves can be thought as a continuation of their
778
- original work. The libraries now changed their direction towards providing
779
- minimal 4kb implementations of cryptography and are not as feature-complete.
868
+ noble-secp256k1, noble-ed25519 and noble-bls12-381.
869
+
870
+ Curves continue their original work. The single-feature packages changed their
871
+ direction towards providing minimal 4kb implementations of cryptography,
872
+ which means they have less features.
873
+
874
+ Upgrading from @noble/secp256k1 2.0 or @noble/ed25519 2.0: no changes, libraries are compatible.
780
875
 
781
876
  Upgrading from [@noble/secp256k1](https://github.com/paulmillr/noble-secp256k1) 1.7:
782
877
 
@@ -814,6 +909,58 @@ Upgrading from [@noble/ed25519](https://github.com/paulmillr/noble-ed25519) 1.7:
814
909
  - `utils` were split into `utils` (same api as in noble-curves) and
815
910
  `etc` (`sha512Sync` and others)
816
911
  - `getSharedSecret` was moved to `x25519` module
912
+ - `toX25519` has been moved to `edwardsToMontgomeryPub` and `edwardsToMontgomeryPriv` methods
913
+
914
+ Upgrading from [@noble/bls12-381](https://github.com/paulmillr/noble-bls12-381):
915
+
916
+ - Methods and classes were renamed:
917
+ - PointG1 -> G1.Point, PointG2 -> G2.Point
918
+ - PointG2.fromSignature -> Signature.decode, PointG2.toSignature -> Signature.encode
919
+ - Fp2 ORDER was corrected
920
+
921
+ ## Resources
922
+
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)
817
964
 
818
965
  ## License
819
966