@noble/curves 2.0.1 → 2.2.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.
- package/README.md +214 -122
- package/abstract/bls.d.ts +299 -16
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +82 -22
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +274 -27
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +177 -23
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +166 -30
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +221 -86
- package/abstract/edwards.js.map +1 -1
- package/abstract/fft.d.ts +322 -10
- package/abstract/fft.d.ts.map +1 -1
- package/abstract/fft.js +154 -12
- package/abstract/fft.js.map +1 -1
- package/abstract/frost.d.ts +293 -0
- package/abstract/frost.d.ts.map +1 -0
- package/abstract/frost.js +704 -0
- package/abstract/frost.js.map +1 -0
- package/abstract/hash-to-curve.d.ts +173 -24
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +170 -31
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +429 -37
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +414 -119
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +83 -12
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +32 -7
- package/abstract/montgomery.js.map +1 -1
- package/abstract/oprf.d.ts +164 -91
- package/abstract/oprf.d.ts.map +1 -1
- package/abstract/oprf.js +88 -29
- package/abstract/oprf.js.map +1 -1
- package/abstract/poseidon.d.ts +138 -7
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +178 -15
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +122 -3
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +323 -139
- package/abstract/tower.js.map +1 -1
- package/abstract/weierstrass.d.ts +339 -76
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +395 -205
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +16 -2
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +199 -209
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +11 -2
- package/bn254.d.ts.map +1 -1
- package/bn254.js +93 -38
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +125 -14
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +202 -40
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +108 -14
- package/ed448.d.ts.map +1 -1
- package/ed448.js +194 -42
- package/ed448.js.map +1 -1
- package/index.js +7 -1
- package/index.js.map +1 -1
- package/misc.d.ts +106 -7
- package/misc.d.ts.map +1 -1
- package/misc.js +141 -32
- package/misc.js.map +1 -1
- package/nist.d.ts +112 -11
- package/nist.d.ts.map +1 -1
- package/nist.js +139 -17
- package/nist.js.map +1 -1
- package/package.json +11 -6
- package/secp256k1.d.ts +92 -15
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +211 -28
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +350 -67
- package/src/abstract/curve.ts +327 -44
- package/src/abstract/edwards.ts +367 -143
- package/src/abstract/fft.ts +369 -36
- package/src/abstract/frost.ts +1092 -0
- package/src/abstract/hash-to-curve.ts +255 -56
- package/src/abstract/modular.ts +591 -144
- package/src/abstract/montgomery.ts +114 -30
- package/src/abstract/oprf.ts +383 -194
- package/src/abstract/poseidon.ts +235 -35
- package/src/abstract/tower.ts +428 -159
- package/src/abstract/weierstrass.ts +710 -312
- package/src/bls12-381.ts +239 -236
- package/src/bn254.ts +107 -46
- package/src/ed25519.ts +227 -55
- package/src/ed448.ts +227 -57
- package/src/index.ts +7 -1
- package/src/misc.ts +154 -35
- package/src/nist.ts +143 -20
- package/src/secp256k1.ts +284 -41
- package/src/utils.ts +583 -81
- package/src/webcrypto.ts +302 -73
- package/utils.d.ts +457 -24
- package/utils.d.ts.map +1 -1
- package/utils.js +410 -53
- package/utils.js.map +1 -1
- package/webcrypto.d.ts +167 -25
- package/webcrypto.d.ts.map +1 -1
- package/webcrypto.js +165 -58
- package/webcrypto.js.map +1 -1
package/README.md
CHANGED
|
@@ -7,10 +7,10 @@ Audited & minimal JS implementation of elliptic curve cryptography.
|
|
|
7
7
|
- 🏎 Fast: hand-optimized for caveats of JS engines
|
|
8
8
|
- 🔍 Reliable: cross-library / wycheproof tests and fuzzing ensure correctness
|
|
9
9
|
- ➰ Weierstrass, Edwards, Montgomery curves; ECDSA, EdDSA, Schnorr, BLS signatures
|
|
10
|
-
- ✍️ ECDH, hash-to-curve, OPRF, Poseidon
|
|
10
|
+
- ✍️ ECDH, hash-to-curve, OPRF, FROST, Poseidon hash, FFT
|
|
11
11
|
- 🔖 Non-repudiation (SUF-CMA, SBS) & consensus-friendliness (ZIP215) in ed25519, ed448
|
|
12
12
|
- 🥈 Optional, friendly wrapper over native WebCrypto
|
|
13
|
-
- 🪶
|
|
13
|
+
- 🪶 32KB (gzipped) including bundled hashes, 11KB for single-curve build
|
|
14
14
|
|
|
15
15
|
Curves have 5kb sister projects
|
|
16
16
|
[secp256k1](https://github.com/paulmillr/noble-secp256k1) & [ed25519](https://github.com/paulmillr/noble-ed25519).
|
|
@@ -32,8 +32,8 @@ Take a glance at [GitHub Discussions](https://github.com/paulmillr/noble-curves/
|
|
|
32
32
|
[post-quantum](https://github.com/paulmillr/noble-post-quantum),
|
|
33
33
|
5kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /
|
|
34
34
|
[ed25519](https://github.com/paulmillr/noble-ed25519)
|
|
35
|
-
- [Check out homepage](https://paulmillr.com/noble/)
|
|
36
|
-
for reading resources, documentation and apps built with noble
|
|
35
|
+
- [Check out the homepage](https://paulmillr.com/noble/)
|
|
36
|
+
for reading resources, documentation, and apps built with noble
|
|
37
37
|
|
|
38
38
|
## Usage
|
|
39
39
|
|
|
@@ -67,7 +67,7 @@ import { ristretto255_oprf } from '@noble/curves/ed25519.js';
|
|
|
67
67
|
import { decaf448_oprf } from '@noble/curves/ed448.js';
|
|
68
68
|
|
|
69
69
|
// utils
|
|
70
|
-
import { bytesToHex, hexToBytes, concatBytes } from '@noble/curves/
|
|
70
|
+
import { bytesToHex, hexToBytes, concatBytes } from '@noble/curves/utils.js';
|
|
71
71
|
import { Field } from '@noble/curves/abstract/modular.js';
|
|
72
72
|
import { weierstrass, ecdsa } from '@noble/curves/abstract/weierstrass.js';
|
|
73
73
|
import { edwards, eddsa } from '@noble/curves/abstract/edwards.js';
|
|
@@ -80,6 +80,7 @@ import { FFT, poly } from '@noble/curves/abstract/fft.js';
|
|
|
80
80
|
- [secp256k1, p256, p384, p521, ed25519, ed448, brainpool](#secp256k1-p256-p384-p521-ed25519-ed448-brainpool)
|
|
81
81
|
- [ristretto255, decaf448](#ristretto255-decaf448)
|
|
82
82
|
- [Prehashed signing](#prehashed-signing)
|
|
83
|
+
- [Recovering public keys from signatures](#recovering-public-keys-from-signatures)
|
|
83
84
|
- [Hedged ECDSA with noise](#hedged-ecdsa-with-noise)
|
|
84
85
|
- [Consensus-friendliness vs e-voting](#consensus-friendliness-vs-e-voting)
|
|
85
86
|
- [ECDH: Diffie-Hellman shared secrets](#ecdh-diffie-hellman-shared-secrets)
|
|
@@ -87,6 +88,7 @@ import { FFT, poly } from '@noble/curves/abstract/fft.js';
|
|
|
87
88
|
- [BLS signatures, bls12-381, bn254 aka alt\_bn128](#bls-signatures-bls12-381-bn254-aka-alt_bn128)
|
|
88
89
|
- [Hashing to curve points](#hash-to-curve-hashing-to-curve-points)
|
|
89
90
|
- [OPRFs](#oprfs)
|
|
91
|
+
- [FROST threshold signatures](#frost-threshold-signatures)
|
|
90
92
|
- [Poseidon hash](#poseidon-poseidon-hash)
|
|
91
93
|
- [Fast Fourier Transform](#fft-fast-fourier-transform)
|
|
92
94
|
- [utils](#utils-byte-shuffling-conversion)
|
|
@@ -134,6 +136,8 @@ ECDSA signatures use deterministic k, conforming to [RFC 6979](https://www.rfc-e
|
|
|
134
136
|
EdDSA conforms to [RFC 8032](https://www.rfc-editor.org/rfc/rfc8032).
|
|
135
137
|
Schnorr (secp256k1-only) conforms to [BIP 340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
|
|
136
138
|
|
|
139
|
+
Messages are always hashed first.
|
|
140
|
+
|
|
137
141
|
#### ristretto255, decaf448
|
|
138
142
|
|
|
139
143
|
```ts
|
|
@@ -150,36 +154,60 @@ Check out separate documentation for [Point](#elliptic-curve-point-math), [hashe
|
|
|
150
154
|
|
|
151
155
|
```js
|
|
152
156
|
import { secp256k1 } from '@noble/curves/secp256k1.js';
|
|
153
|
-
import {
|
|
154
|
-
const { secretKey } =
|
|
157
|
+
import { keccak_256 } from '@noble/hashes/sha3.js';
|
|
158
|
+
const { secretKey } = secp256k1.keygen();
|
|
155
159
|
const msg = new TextEncoder().encode('hello noble');
|
|
156
160
|
// prehash: true (default) - hash using secp256k1.hash (sha256)
|
|
157
161
|
const sig = secp256k1.sign(msg, secretKey);
|
|
158
162
|
// prehash: false - hash using custom hash
|
|
159
|
-
const sigKeccak = secp256k1.sign(
|
|
163
|
+
const sigKeccak = secp256k1.sign(keccak_256(msg), secretKey, { prehash: false });
|
|
160
164
|
```
|
|
161
165
|
|
|
162
|
-
|
|
166
|
+
Default sign() and verify() behavior (`prehash: true`) applies built-in hash function to message first.
|
|
167
|
+
For secp256k1 that's sha256, for p521 that's sha512.
|
|
163
168
|
|
|
164
|
-
|
|
165
|
-
It's actually math + hashing: p256 is in fact p256 point + sha256 hash.
|
|
166
|
-
By default, we hash messages. To use custom hash methods,
|
|
167
|
-
make sure to disable prehashing.
|
|
169
|
+
Providing `prehash: false` allows user to specify their own hash function (e.g. use secp256k1 + keccak_256).
|
|
168
170
|
|
|
169
171
|
> [!NOTE]
|
|
170
172
|
> Previously, in noble-curves v1, `prehash: false` was the default.
|
|
171
173
|
> Some other libraries (like libsecp256k1) have no prehashing.
|
|
172
174
|
|
|
175
|
+
#### Recovering public keys from signatures
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
import { secp256k1 } from '@noble/curves/secp256k1.js';
|
|
179
|
+
const { secretKey, publicKey } = secp256k1.keygen();
|
|
180
|
+
const msg = new TextEncoder().encode('hello noble');
|
|
181
|
+
const sigRec = secp256k1.sign(msg, secretKey, { format: 'recovered' });
|
|
182
|
+
const publicKey_ = secp256k1.recoverPublicKey(sigRec, msg); // == publicKey
|
|
183
|
+
|
|
184
|
+
// recovered sig is compact sig with an extra byte
|
|
185
|
+
const sigNoRec = secp256k1.sign(msg, secretKey, { format: 'compact' });
|
|
186
|
+
// sigNoRec == sigRec.slice(1)
|
|
187
|
+
|
|
188
|
+
// Signature instance
|
|
189
|
+
const sigInstance = secp256k1.Signature.fromBytes(sigRec, 'recovered');
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Public key recovery - only supported with ECDSA.
|
|
193
|
+
|
|
194
|
+
> [!NOTE]
|
|
195
|
+
> Key recovery is a simple math operation.
|
|
196
|
+
> There are no guarantees the signing was actually done.
|
|
197
|
+
> It's possible to forge signature and msg hash (r, s, h), which would
|
|
198
|
+
> recover into a random public key, but it's not feasible
|
|
199
|
+
> to find m which would lead to this specific forged h.
|
|
200
|
+
|
|
173
201
|
#### Hedged ECDSA with noise
|
|
174
202
|
|
|
175
203
|
```js
|
|
176
204
|
import { secp256k1 } from '@noble/curves/secp256k1.js';
|
|
177
|
-
const { secretKey } =
|
|
205
|
+
const { secretKey } = secp256k1.keygen();
|
|
178
206
|
const msg = new TextEncoder().encode('hello noble');
|
|
179
207
|
// extraEntropy: false - default, hedging disabled
|
|
180
208
|
const sigNoisy = secp256k1.sign(msg, secretKey);
|
|
181
209
|
// extraEntropy: true - fetch 32 random bytes from CSPRNG
|
|
182
|
-
const
|
|
210
|
+
const sigNoisyA = secp256k1.sign(msg, secretKey, { extraEntropy: true });
|
|
183
211
|
// extraEntropy: bytes - specific extra entropy
|
|
184
212
|
const ent = Uint8Array.from([0xca, 0xfe, 0x01, 0x23]);
|
|
185
213
|
const sigNoisy2 = secp256k1.sign(msg, secretKey, { extraEntropy: ent });
|
|
@@ -206,24 +234,24 @@ const { secretKey, publicKey } = ed25519.keygen();
|
|
|
206
234
|
const msg = new TextEncoder().encode('hello noble');
|
|
207
235
|
const sig = ed25519.sign(msg, secretKey);
|
|
208
236
|
// zip215: true
|
|
209
|
-
const isValid = ed25519.verify(sig, msg,
|
|
237
|
+
const isValid = ed25519.verify(sig, msg, publicKey);
|
|
210
238
|
// SBS / e-voting / RFC8032 / FIPS 186-5
|
|
211
|
-
const isValidRfc = ed25519.verify(sig, msg,
|
|
239
|
+
const isValidRfc = ed25519.verify(sig, msg, publicKey, { zip215: false });
|
|
212
240
|
```
|
|
213
241
|
|
|
242
|
+
> [!NOTE]
|
|
243
|
+
> Most other libraries don't have SUF-CMA & SBS - less optimal choice for their security.
|
|
244
|
+
|
|
214
245
|
In ed25519, there is an ability to choose between consensus-friendliness vs e-voting mode.
|
|
215
246
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
which is useful for:
|
|
222
|
-
- Contract Signing: if A signed an agreement with B using key that allows repudiation, it can later claim that it signed a different contract
|
|
223
|
-
- E-voting: malicious voters may pick keys that allow repudiation in order to deny results
|
|
224
|
-
- Blockchains: transaction of amount X might also be valid for a different amount Y
|
|
247
|
+
* `zip215: true` (default) uses the more permissive, [consensus-friendly](https://hdevalence.ca/blog/2020-10-04-its-25519am) verification rules defined in [ZIP215](https://zips.z.cash/zip-0215).
|
|
248
|
+
* `zip215: false` enforces strict [RFC 8032](https://www.rfc-editor.org/rfc/rfc8032) / [FIPS 186-5](https://csrc.nist.gov/publications/detail/fips/186/5/final) verification and adds SBS-based non-repudiation, which is useful for:
|
|
249
|
+
* **Contract signing:** prevents a signer from later claiming they signed a different document
|
|
250
|
+
* **E-voting:** stops voters from choosing keys that let them repudiate their vote
|
|
251
|
+
* **Blockchains:** avoids signatures valid for multiple transactions (e.g., amount X also validating amount Y)
|
|
225
252
|
|
|
226
253
|
Both modes have SUF-CMA (strong unforgeability under chosen message attacks).
|
|
254
|
+
See [Taming the many EdDSAs](https://eprint.iacr.org/2020/1244) for more info.
|
|
227
255
|
|
|
228
256
|
### ECDH: Diffie-Hellman shared secrets
|
|
229
257
|
|
|
@@ -233,7 +261,7 @@ import { x25519 } from '@noble/curves/ed25519.js';
|
|
|
233
261
|
import { x448 } from '@noble/curves/ed448.js';
|
|
234
262
|
import { p256, p384, p521 } from '@noble/curves/nist.js';
|
|
235
263
|
|
|
236
|
-
for (const curve of [secp256k1,
|
|
264
|
+
for (const curve of [secp256k1, x25519, x448, p256, p384, p521]) {
|
|
237
265
|
const alice = curve.keygen();
|
|
238
266
|
const bob = curve.keygen();
|
|
239
267
|
const sharedKey = curve.getSharedSecret(alice.secretKey, bob.publicKey);
|
|
@@ -265,7 +293,7 @@ In Weierstrass curves, shared secrets:
|
|
|
265
293
|
##### webcrypto signatures
|
|
266
294
|
|
|
267
295
|
```js
|
|
268
|
-
import { ed25519, ed448, p256, p384, p521 } from '
|
|
296
|
+
import { ed25519, ed448, p256, p384, p521 } from '@noble/curves/webcrypto.js';
|
|
269
297
|
|
|
270
298
|
(async () => {
|
|
271
299
|
for (let [name, curve] of Object.entries({ p256, p384, p521, ed25519, ed448 })) {
|
|
@@ -288,7 +316,7 @@ import { ed25519, ed448, p256, p384, p521 } from './src/webcrypto.ts';
|
|
|
288
316
|
##### webcrypto ecdh
|
|
289
317
|
|
|
290
318
|
```js
|
|
291
|
-
import { p256, p384, p521, x25519, x448 } from '
|
|
319
|
+
import { p256, p384, p521, x25519, x448 } from '@noble/curves/webcrypto.js';
|
|
292
320
|
|
|
293
321
|
(async () => {
|
|
294
322
|
for (let [name, curve] of Object.entries({ p256, p384, p521, x25519, x448 })) {
|
|
@@ -309,8 +337,8 @@ import { p256, p384, p521, x25519, x448 } from './src/webcrypto.ts';
|
|
|
309
337
|
##### Key conversion from noble to webcrypto and back
|
|
310
338
|
|
|
311
339
|
```js
|
|
312
|
-
import { p256 as p256n } from '
|
|
313
|
-
import { p256 } from '
|
|
340
|
+
import { p256 as p256n } from '@noble/curves/nist.js';
|
|
341
|
+
import { p256 } from '@noble/curves/webcrypto.js';
|
|
314
342
|
(async () => {
|
|
315
343
|
const nobleKeys = p256n.keygen();
|
|
316
344
|
// convert noble keys to webcrypto
|
|
@@ -352,13 +380,13 @@ const blss = bls12_381.shortSignatures;
|
|
|
352
380
|
const publicKey2 = blss.getPublicKey(secretKey);
|
|
353
381
|
const msgp2 = blss.hash(msg, 'BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_');
|
|
354
382
|
const signature2 = blss.sign(msgp2, secretKey);
|
|
355
|
-
const isValid2 = blss.verify(signature2, msgp2,
|
|
383
|
+
const isValid2 = blss.verify(signature2, msgp2, publicKey2);
|
|
356
384
|
console.log({ publicKey2, signature2, isValid2 });
|
|
357
385
|
|
|
358
386
|
// Aggregation
|
|
359
387
|
const aggregatedKey = bls12_381.longSignatures.aggregatePublicKeys([
|
|
360
|
-
bls12_381.utils.randomSecretKey(),
|
|
361
|
-
bls12_381.utils.randomSecretKey(),
|
|
388
|
+
blsl.getPublicKey(bls12_381.utils.randomSecretKey()),
|
|
389
|
+
blsl.getPublicKey(bls12_381.utils.randomSecretKey()),
|
|
362
390
|
]);
|
|
363
391
|
// const aggregatedSig = bls.aggregateSignatures(sigs)
|
|
364
392
|
|
|
@@ -390,11 +418,11 @@ Points of divergence:
|
|
|
390
418
|
### hash-to-curve: hashing to curve points
|
|
391
419
|
|
|
392
420
|
```ts
|
|
393
|
-
import { bls12_381 } from '
|
|
394
|
-
import { ed25519_hasher, ristretto255_hasher } from '
|
|
395
|
-
import { decaf448_hasher, ed448_hasher } from '
|
|
396
|
-
import { p256_hasher, p384_hasher, p521_hasher } from '
|
|
397
|
-
import { secp256k1_hasher } from '
|
|
421
|
+
import { bls12_381 } from '@noble/curves/bls12-381.js';
|
|
422
|
+
import { ed25519_hasher, ristretto255_hasher } from '@noble/curves/ed25519.js';
|
|
423
|
+
import { decaf448_hasher, ed448_hasher } from '@noble/curves/ed448.js';
|
|
424
|
+
import { p256_hasher, p384_hasher, p521_hasher } from '@noble/curves/nist.js';
|
|
425
|
+
import { secp256k1_hasher } from '@noble/curves/secp256k1.js';
|
|
398
426
|
|
|
399
427
|
const h = {
|
|
400
428
|
secp256k1_hasher,
|
|
@@ -438,7 +466,7 @@ The module allows to hash arbitrary strings to elliptic curve points. Implements
|
|
|
438
466
|
```js
|
|
439
467
|
import { p256_oprf, p384_oprf, p521_oprf } from '@noble/curves/nist.js';
|
|
440
468
|
import { ristretto255_oprf } from '@noble/curves/ed25519.js';
|
|
441
|
-
import {
|
|
469
|
+
import { decaf448_oprf } from '@noble/curves/ed448.js';
|
|
442
470
|
```
|
|
443
471
|
|
|
444
472
|
We provide OPRFs (oblivious pseudorandom functions),
|
|
@@ -451,6 +479,84 @@ OPRF allows to interactively create an `Output = PRF(Input, serverSecretKey)`:
|
|
|
451
479
|
- An attacker interception the communication can't restore Input/Output/serverSecretKey and can't
|
|
452
480
|
link Input to some value.
|
|
453
481
|
|
|
482
|
+
### FROST threshold signatures
|
|
483
|
+
|
|
484
|
+
FROST implements [RFC 9591](https://www.rfc-editor.org/rfc/rfc9591) threshold Schnorr signing.
|
|
485
|
+
It is similar to multisig from the application point of view: any `min` of `max` participants
|
|
486
|
+
can jointly produce one Schnorr signature under a shared public key.
|
|
487
|
+
Supported ciphersuites are `p256_FROST`, `ed25519_FROST`, `ed448_FROST`, `ristretto255_FROST`,
|
|
488
|
+
`secp256k1_FROST`, and `schnorr_FROST` (Taproot-compatible secp256k1).
|
|
489
|
+
Signing has two rounds: selected signers commit first, then produce signature shares.
|
|
490
|
+
|
|
491
|
+
> [!WARNING]
|
|
492
|
+
> The FROST code is new and has not been audited yet.
|
|
493
|
+
> It passes the imported `frost-rs` vectors/examples and local regression tests.
|
|
494
|
+
|
|
495
|
+
```js
|
|
496
|
+
import { p256_FROST } from '@noble/curves/nist.js';
|
|
497
|
+
|
|
498
|
+
const signers = { min: 2, max: 3 };
|
|
499
|
+
const alice = p256_FROST.Identifier.derive('alice@example.com');
|
|
500
|
+
const bob = p256_FROST.Identifier.derive('bob@example.com');
|
|
501
|
+
const carol = p256_FROST.Identifier.derive('carol@example.com');
|
|
502
|
+
// trusted dealer
|
|
503
|
+
const deal = p256_FROST.trustedDealer(signers, [alice, bob, carol]);
|
|
504
|
+
for (const id of [alice, bob, carol]) p256_FROST.validateSecret(deal.secretShares[id], deal.public);
|
|
505
|
+
|
|
506
|
+
const msg = new TextEncoder().encode('hello threshold');
|
|
507
|
+
// round 1: selected signers commit
|
|
508
|
+
const aliceRound1 = p256_FROST.commit(deal.secretShares[alice]);
|
|
509
|
+
const bobRound1 = p256_FROST.commit(deal.secretShares[bob]);
|
|
510
|
+
const commitmentList = [aliceRound1.commitments, bobRound1.commitments];
|
|
511
|
+
// round 2: signers produce signature shares
|
|
512
|
+
const sigShares = {
|
|
513
|
+
[alice]: p256_FROST.signShare(
|
|
514
|
+
deal.secretShares[alice],
|
|
515
|
+
deal.public,
|
|
516
|
+
aliceRound1.nonces,
|
|
517
|
+
commitmentList,
|
|
518
|
+
msg
|
|
519
|
+
),
|
|
520
|
+
[bob]: p256_FROST.signShare(
|
|
521
|
+
deal.secretShares[bob],
|
|
522
|
+
deal.public,
|
|
523
|
+
bobRound1.nonces,
|
|
524
|
+
commitmentList,
|
|
525
|
+
msg
|
|
526
|
+
),
|
|
527
|
+
};
|
|
528
|
+
const sig = p256_FROST.aggregate(deal.public, commitmentList, msg, sigShares);
|
|
529
|
+
const isValid = p256_FROST.verify(sig, msg, deal.public.commitments[0]);
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
Key generation can be done with a trusted dealer or with DKG.
|
|
533
|
+
DKG has three rounds: participants commit to key generation, exchange private shares, then derive final participant keys.
|
|
534
|
+
|
|
535
|
+
```js
|
|
536
|
+
import { p256_FROST } from '@noble/curves/nist.js';
|
|
537
|
+
|
|
538
|
+
const signers = { min: 2, max: 3 };
|
|
539
|
+
const alice = p256_FROST.DKG.round1(p256_FROST.Identifier.fromNumber(1), signers);
|
|
540
|
+
const bob = p256_FROST.DKG.round1(p256_FROST.Identifier.fromNumber(2), signers);
|
|
541
|
+
const carol = p256_FROST.DKG.round1(p256_FROST.Identifier.fromNumber(3), signers);
|
|
542
|
+
|
|
543
|
+
// round 1: participants commit to key generation
|
|
544
|
+
const aliceRound2 = p256_FROST.DKG.round2(alice.secret, [bob.public, carol.public]);
|
|
545
|
+
const bobRound2 = p256_FROST.DKG.round2(bob.secret, [alice.public, carol.public]);
|
|
546
|
+
const carolRound2 = p256_FROST.DKG.round2(carol.secret, [alice.public, bob.public]);
|
|
547
|
+
|
|
548
|
+
// round 2: private shares for each recipient
|
|
549
|
+
const aliceKey = p256_FROST.DKG.round3(alice.secret, [bob.public, carol.public], [
|
|
550
|
+
bobRound2[p256_FROST.Identifier.fromNumber(1)],
|
|
551
|
+
carolRound2[p256_FROST.Identifier.fromNumber(1)],
|
|
552
|
+
]);
|
|
553
|
+
// round 3: final participant key package
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
DKG helpers are intended for interoperable testing and practical key generation.
|
|
557
|
+
The library implements the cryptographic steps, not the surrounding application protocol:
|
|
558
|
+
callers still need authenticated communication, coordination, retries, session handling, and policy.
|
|
559
|
+
|
|
454
560
|
### poseidon: Poseidon hash
|
|
455
561
|
|
|
456
562
|
Implements [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash:
|
|
@@ -461,11 +567,13 @@ We don't provide them: you should construct them manually.
|
|
|
461
567
|
Check out [scure-starknet](https://github.com/paulmillr/scure-starknet) package for a proper example.
|
|
462
568
|
|
|
463
569
|
```ts
|
|
464
|
-
import {
|
|
570
|
+
import { bn254 } from '@noble/curves/bn254.js';
|
|
571
|
+
import { grainGenConstants, poseidon, poseidonSponge } from '@noble/curves/abstract/poseidon.js';
|
|
465
572
|
|
|
466
573
|
const rate = 2;
|
|
467
574
|
const capacity = 1;
|
|
468
|
-
const
|
|
575
|
+
const Fp = bn254.fields.Fr;
|
|
576
|
+
const { mds, roundConstants } = grainGenConstants({
|
|
469
577
|
Fp,
|
|
470
578
|
t: rate + capacity,
|
|
471
579
|
roundsFull: 8,
|
|
@@ -481,8 +589,8 @@ const opts = {
|
|
|
481
589
|
roundsFull: 8,
|
|
482
590
|
roundsPartial: 31,
|
|
483
591
|
};
|
|
484
|
-
const permutation = poseidon
|
|
485
|
-
const sponge =
|
|
592
|
+
const permutation = poseidon({ ...opts, t: rate + capacity });
|
|
593
|
+
const sponge = poseidonSponge(opts); // use carefully, not specced
|
|
486
594
|
```
|
|
487
595
|
|
|
488
596
|
### fft: Fast Fourier Transform
|
|
@@ -501,7 +609,7 @@ API may change at any time. The code has not been audited. Feature requests are
|
|
|
501
609
|
### utils: byte shuffling, conversion
|
|
502
610
|
|
|
503
611
|
```ts
|
|
504
|
-
import { bytesToHex, concatBytes, equalBytes, hexToBytes } from '@noble/curves/
|
|
612
|
+
import { bytesToHex, concatBytes, equalBytes, hexToBytes } from '@noble/curves/utils.js';
|
|
505
613
|
|
|
506
614
|
bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23]));
|
|
507
615
|
hexToBytes('cafe0123');
|
|
@@ -514,30 +622,32 @@ equalBytes(Uint8Array.of(0xca), Uint8Array.of(0xca));
|
|
|
514
622
|
#### Elliptic curve Point math
|
|
515
623
|
|
|
516
624
|
```js
|
|
625
|
+
import { pippenger } from '@noble/curves/abstract/curve.js';
|
|
517
626
|
import { secp256k1, schnorr } from '@noble/curves/secp256k1.js';
|
|
518
627
|
import { p256, p384, p521 } from '@noble/curves/nist.js';
|
|
519
628
|
import { ed25519, ristretto255 } from '@noble/curves/ed25519.js';
|
|
520
629
|
import { ed448, decaf448 } from '@noble/curves/ed448.js';
|
|
521
|
-
import { bls12_381 } from '@noble/curves/bls12-381.js'
|
|
630
|
+
import { bls12_381 } from '@noble/curves/bls12-381.js';
|
|
522
631
|
import { bn254 } from '@noble/curves/bn254.js';
|
|
523
632
|
import { jubjub, babyjubjub } from '@noble/curves/misc.js';
|
|
524
633
|
|
|
525
634
|
const curves = [
|
|
526
635
|
secp256k1, schnorr, p256, p384, p521, ed25519, ed448,
|
|
527
636
|
ristretto255, decaf448,
|
|
528
|
-
bls12_381.G1, bls12_381.G2, bn254.G1,
|
|
637
|
+
bls12_381.G1, bls12_381.G2, bn254.G1,
|
|
529
638
|
jubjub, babyjubjub
|
|
530
639
|
];
|
|
531
640
|
for (const curve of curves) {
|
|
532
641
|
const { Point } = curve;
|
|
533
642
|
const { BASE, ZERO, Fp, Fn } = Point;
|
|
643
|
+
const info = Point.CURVE?.();
|
|
534
644
|
const p = BASE.multiply(2n);
|
|
535
645
|
|
|
536
646
|
// Initialization
|
|
537
|
-
if (info
|
|
647
|
+
if (info?.type === 'weierstrass') {
|
|
538
648
|
// projective (homogeneous) coordinates: (X, Y, Z) ∋ (x=X/Z, y=Y/Z)
|
|
539
649
|
const p_ = new Point(BASE.X, BASE.Y, BASE.Z);
|
|
540
|
-
} else if (info
|
|
650
|
+
} else if (info?.type === 'edwards') {
|
|
541
651
|
// extended coordinates: (X, Y, Z, T) ∋ (x=X/Z, y=Y/Z)
|
|
542
652
|
const p_ = new Point(BASE.X, BASE.Y, BASE.Z, BASE.T);
|
|
543
653
|
}
|
|
@@ -551,11 +661,11 @@ for (const curve of curves) {
|
|
|
551
661
|
|
|
552
662
|
// MSM (multi-scalar multiplication)
|
|
553
663
|
const pa = [BASE, BASE.multiply(2n), BASE.multiply(4n), BASE.multiply(8n)];
|
|
554
|
-
const p6 = Point
|
|
664
|
+
const p6 = pippenger(Point, pa, [3n, 5n, 7n, 11n]);
|
|
555
665
|
const _true3 = p6.equals(BASE.multiply(129n)); // 129*G
|
|
556
666
|
|
|
557
667
|
const pcl = p.clearCofactor();
|
|
558
|
-
|
|
668
|
+
const isTorsionFree = p.isTorsionFree();
|
|
559
669
|
|
|
560
670
|
const r1 = p.toBytes();
|
|
561
671
|
const r1_ = Point.fromBytes(r1);
|
|
@@ -576,7 +686,7 @@ fp.mul(591n, 932n); // multiplication
|
|
|
576
686
|
fp.pow(481n, 11024858120n); // exponentiation
|
|
577
687
|
fp.div(5n, 17n); // division: 5/17 mod 2^255-19 == 5 * invert(17)
|
|
578
688
|
fp.inv(5n); // modular inverse
|
|
579
|
-
fp.sqrt(
|
|
689
|
+
fp.sqrt(4n); // square root
|
|
580
690
|
|
|
581
691
|
// Non-Field generic utils are also available
|
|
582
692
|
mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
|
|
@@ -634,11 +744,21 @@ cofactor `h` and coordinates `Gx`, `Gy` of generator point.
|
|
|
634
744
|
#### Custom ECDSA instance
|
|
635
745
|
|
|
636
746
|
```js
|
|
637
|
-
import { ecdsa } from '@noble/curves/abstract/weierstrass.js';
|
|
638
|
-
import { sha256 } from '@noble/hashes/sha2.js';
|
|
747
|
+
import { weierstrass, ecdsa } from '@noble/curves/abstract/weierstrass.js';
|
|
748
|
+
import { sha224, sha256 } from '@noble/hashes/sha2.js';
|
|
749
|
+
const p192_CURVE = {
|
|
750
|
+
p: 0xfffffffffffffffffffffffffffffffeffffffffffffffffn,
|
|
751
|
+
n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n,
|
|
752
|
+
h: 1n,
|
|
753
|
+
a: 0xfffffffffffffffffffffffffffffffefffffffffffffffcn,
|
|
754
|
+
b: 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n,
|
|
755
|
+
Gx: 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012n,
|
|
756
|
+
Gy: 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n,
|
|
757
|
+
};
|
|
758
|
+
const p192_Point = weierstrass(p192_CURVE);
|
|
639
759
|
const p192_sha256 = ecdsa(p192_Point, sha256);
|
|
640
760
|
// or
|
|
641
|
-
const p192_sha224 = ecdsa(
|
|
761
|
+
const p192_sha224 = ecdsa(p192_Point, sha224);
|
|
642
762
|
|
|
643
763
|
const keys = p192_sha256.keygen();
|
|
644
764
|
const msg = new TextEncoder().encode('custom curve');
|
|
@@ -648,21 +768,24 @@ const isValid = p192_sha256.verify(sig, msg, keys.publicKey);
|
|
|
648
768
|
|
|
649
769
|
## Security
|
|
650
770
|
|
|
651
|
-
The library has been
|
|
771
|
+
The library has been audited:
|
|
652
772
|
|
|
653
|
-
- at version
|
|
773
|
+
- at version 2.2.0, in Apr 2026, by ourselves (self-audited)
|
|
774
|
+
- Scope: everything
|
|
775
|
+
- [Changes since audit](https://github.com/paulmillr/noble-curves/compare/2.2.0..main)
|
|
776
|
+
- at version 1.6.0, in Sep 2024, independently, by [Cure53](https://cure53.de)
|
|
654
777
|
- PDFs: [website](https://cure53.de/audit-report_noble-crypto-libs.pdf), [in-repo](./audit/2024-09-cure53-audit-nbl4.pdf)
|
|
655
778
|
- [Changes since audit](https://github.com/paulmillr/noble-curves/compare/1.6.0..main)
|
|
656
779
|
- Scope: ed25519, ed448, their add-ons, bls12-381, bn254,
|
|
657
780
|
hash-to-curve, low-level primitives bls, tower, edwards, montgomery.
|
|
658
781
|
- The audit has been funded by [OpenSats](https://opensats.org)
|
|
659
|
-
- at version 1.2.0, in Sep 2023, by [Kudelski Security](https://kudelskisecurity.com)
|
|
782
|
+
- at version 1.2.0, in Sep 2023, independently, by [Kudelski Security](https://kudelskisecurity.com)
|
|
660
783
|
- PDFs: [in-repo](./audit/2023-09-kudelski-audit-starknet.pdf)
|
|
661
784
|
- [Changes since audit](https://github.com/paulmillr/noble-curves/compare/1.2.0..main)
|
|
662
785
|
- Scope: [scure-starknet](https://github.com/paulmillr/scure-starknet) and its related
|
|
663
786
|
abstract modules of noble-curves: `curve`, `modular`, `poseidon`, `weierstrass`
|
|
664
787
|
- The audit has been funded by [Starkware](https://starkware.co)
|
|
665
|
-
- at version 0.7.3, in Feb 2023, by [Trail of Bits](https://www.trailofbits.com)
|
|
788
|
+
- at version 0.7.3, in Feb 2023, independently, by [Trail of Bits](https://www.trailofbits.com)
|
|
666
789
|
- PDFs: [website](https://github.com/trailofbits/publications/blob/master/reviews/2023-01-ryanshea-noblecurveslibrary-securityreview.pdf),
|
|
667
790
|
[in-repo](./audit/2023-01-trailofbits-audit-curves.pdf)
|
|
668
791
|
- [Changes since audit](https://github.com/paulmillr/noble-curves/compare/0.7.3..main)
|
|
@@ -711,31 +834,27 @@ test-suite in the actual application that consumes the library.
|
|
|
711
834
|
|
|
712
835
|
### Supply chain security
|
|
713
836
|
|
|
714
|
-
- **Commits** are signed with PGP keys
|
|
715
|
-
- **Releases** are
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
-
|
|
719
|
-
-
|
|
720
|
-
|
|
721
|
-
- Automatic dep updates are prevented by locking-down version ranges; diffs are checked with `npm-diff`
|
|
722
|
-
- **Dev Dependencies** are disabled for end-users; they are only used to develop / build the source code
|
|
837
|
+
- **Commits** are signed with PGP keys to prevent forgery. Be sure to verify the commit signatures
|
|
838
|
+
- **Releases** are made transparently through token-less GitHub CI and Trusted Publishing. Be sure to verify the [provenance logs](https://docs.npmjs.com/generating-provenance-statements) for authenticity.
|
|
839
|
+
- **Rare releasing** is practiced to minimize the need for re-audits by end-users.
|
|
840
|
+
- **Dependencies** are minimized and strictly pinned to reduce supply-chain risk.
|
|
841
|
+
- We use as few dependencies as possible.
|
|
842
|
+
- Version ranges are locked, and changes are checked with npm-diff.
|
|
843
|
+
- **Dev dependencies** are excluded from end-user installs; they’re only used for development and build steps.
|
|
723
844
|
|
|
724
845
|
For this package, there is 1 dependency; and a few dev dependencies:
|
|
725
846
|
|
|
726
847
|
- [noble-hashes](https://github.com/paulmillr/noble-hashes) provides cryptographic hashing functionality
|
|
727
|
-
-
|
|
728
|
-
- prettier, fast-check and typescript are used for code quality / test generation / ts compilation
|
|
848
|
+
- jsbt is used for benchmarking / testing / build tooling and developed by the same author
|
|
849
|
+
- prettier, fast-check and typescript are used for code quality / test generation / ts compilation
|
|
729
850
|
|
|
730
851
|
### Randomness
|
|
731
852
|
|
|
732
|
-
We
|
|
733
|
-
[crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)
|
|
734
|
-
which is considered cryptographically secure
|
|
853
|
+
We rely on the built-in
|
|
854
|
+
[`crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues),
|
|
855
|
+
which is considered a cryptographically secure PRNG.
|
|
735
856
|
|
|
736
|
-
|
|
737
|
-
Implementing a userspace CSPRNG to get resilient to the weakness
|
|
738
|
-
is even worse: there is no reliable userspace source of quality entropy.
|
|
857
|
+
Browsers have had weaknesses in the past - and could again - but implementing a userspace CSPRNG is even worse, as there’s no reliable userspace source of high-quality entropy.
|
|
739
858
|
|
|
740
859
|
### Quantum computers
|
|
741
860
|
|
|
@@ -895,13 +1014,15 @@ Changes:
|
|
|
895
1014
|
- Most methods now expect Uint8Array, string hex inputs are prohibited
|
|
896
1015
|
- The change simplifies reasoning, improves security and reduces malleability
|
|
897
1016
|
- `Point.fromHex` now expects string-only hex inputs, use `Point.fromBytes` for Uint8Array
|
|
1017
|
+
- Many methods were renamed, upgrade to curves v1.9 first to highlight deprecated old names
|
|
898
1018
|
- Breaking changes of ECDSA (secp256k1, p256, p384...):
|
|
1019
|
+
- To bring back old behavior, pass `{ prehash: false, lowS: false }` to sign / verify
|
|
899
1020
|
- sign, verify: Switch to **prehashed messages**. Instead of
|
|
900
1021
|
messageHash, the methods now expect unhashed message.
|
|
901
1022
|
To bring back old behavior, use option `{prehash: false}`
|
|
902
1023
|
- sign, verify: Switch to **lowS signatures** by default.
|
|
903
1024
|
This change doesn't affect secp256k1, which has been using lowS since beginning.
|
|
904
|
-
To bring back old behavior, use option `{lowS:
|
|
1025
|
+
To bring back old behavior, use option `{lowS: false}`
|
|
905
1026
|
- sign, verify: Switch to **Uint8Array signatures** (format: 'compact') by default.
|
|
906
1027
|
- verify: **der format must be explicitly specified** in `{format: 'der'}`.
|
|
907
1028
|
This reduces malleability
|
|
@@ -949,13 +1070,13 @@ Renamings:
|
|
|
949
1070
|
Removed features:
|
|
950
1071
|
|
|
951
1072
|
- Point#multiplyAndAddUnsafe, Point#hasEvenY
|
|
952
|
-
- CURVE property with all kinds of random stuff. Point.CURVE() now replaces it, but only provides
|
|
1073
|
+
- `CURVE` property with all kinds of random stuff. Point.CURVE() now replaces it, but only provides
|
|
953
1074
|
curve parameters
|
|
954
1075
|
- Remove `pasta`, `bn254_weierstrass` (NOT pairing-based bn254) curves
|
|
1076
|
+
- utils.normPrivateKeyToScalar - use `Point.Fn.fromBytes`
|
|
955
1077
|
- Field.MASK
|
|
956
|
-
- utils.normPrivateKeyToScalar
|
|
957
1078
|
|
|
958
|
-
###
|
|
1079
|
+
### secp256k1 v1, ed25519 v1, bls12-381 v1 to curves v1
|
|
959
1080
|
|
|
960
1081
|
Previously, the library was split into single-feature packages
|
|
961
1082
|
[noble-secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
|
@@ -964,55 +1085,26 @@ Previously, the library was split into single-feature packages
|
|
|
964
1085
|
|
|
965
1086
|
Curves continue their original work. The single-feature packages changed their
|
|
966
1087
|
direction towards providing minimal 5kb implementations of cryptography,
|
|
967
|
-
which means they have less features.
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
- `
|
|
974
|
-
|
|
975
|
-
- now returns `Signature` instance with `{ r, s, recovery }` properties
|
|
976
|
-
- `canonical` option was renamed to `lowS`
|
|
977
|
-
- `recovered` option has been removed because recovery bit is always returned now
|
|
978
|
-
- `der` option has been removed. There are 2 options:
|
|
979
|
-
1. Use compact encoding: `fromCompact`, `toCompactRawBytes`, `toCompactHex`.
|
|
980
|
-
Compact encoding is simply a concatenation of 32-byte r and 32-byte s.
|
|
981
|
-
2. If you must use DER encoding, switch to noble-curves (see above).
|
|
982
|
-
- `verify`
|
|
983
|
-
- is now sync
|
|
984
|
-
- `strict` option was renamed to `lowS`
|
|
985
|
-
- `getSharedSecret`
|
|
986
|
-
- now produce 33-byte compressed signatures by default
|
|
987
|
-
- to use old behavior, which produced 65-byte uncompressed keys, set
|
|
988
|
-
argument `isCompressed` to `false`: `getSharedSecret(a, b, false)`
|
|
1088
|
+
which means they have less features. Separate bls package had been deprecated.
|
|
1089
|
+
|
|
1090
|
+
secp256k1:
|
|
1091
|
+
|
|
1092
|
+
- `getPublicKey`: defaults to compressed sigs (use second argument to adjust)
|
|
1093
|
+
- `sign`: renamed options `canonical` => `lowS`; `der` => `format: 'der'`
|
|
1094
|
+
- `verify`: renamed option `strict` => `lowS`
|
|
1095
|
+
- `getSharedSecret`: defaults to compressed sigs (use third argument to adjust)
|
|
989
1096
|
- `recoverPublicKey(msg, sig, rec)` was changed to `sig.recoverPublicKey(msg)`
|
|
990
|
-
- `number` type for private keys have been removed: use `bigint` instead
|
|
991
1097
|
- `Point` (2d xy) has been changed to `ProjectivePoint` (3d xyz)
|
|
992
|
-
- `utils` were split into `utils` (same api as in noble-curves) and
|
|
993
|
-
`etc` (`hmacSha256Sync` and others)
|
|
994
|
-
|
|
995
|
-
### noble-ed25519 v1 to curves v1
|
|
996
1098
|
|
|
997
|
-
|
|
1099
|
+
ed25519:
|
|
998
1100
|
|
|
999
|
-
-
|
|
1000
|
-
- `bigint` is no longer allowed in `getPublicKey`, `sign`, `verify`. Reason: ed25519 is LE, can lead to bugs
|
|
1001
|
-
- `Point` (2d xy) has been changed to `ExtendedPoint` (xyzt)
|
|
1002
|
-
- `Signature` was removed: just use raw bytes or hex now
|
|
1003
|
-
- `utils` were split into `utils` (same api as in noble-curves) and
|
|
1004
|
-
`etc` (`sha512Sync` and others)
|
|
1101
|
+
- `Signature` was removed in favor of raw bytes
|
|
1005
1102
|
- `getSharedSecret` was moved to `x25519` module
|
|
1006
|
-
- `toX25519` has been moved to `edwardsToMontgomeryPub` and `edwardsToMontgomeryPriv` methods
|
|
1007
|
-
|
|
1008
|
-
### noble-bls12-381 to curves v1
|
|
1009
1103
|
|
|
1010
|
-
|
|
1104
|
+
bls12-381:
|
|
1011
1105
|
|
|
1012
|
-
-
|
|
1013
|
-
|
|
1014
|
-
- PointG2.fromSignature -> Signature.decode, PointG2.toSignature -> Signature.encode
|
|
1015
|
-
- Fp2 ORDER was corrected
|
|
1106
|
+
- Renamed PointG1 -> G1.Point, PointG2 -> G2.Point
|
|
1107
|
+
- Renamed PointG2.fromSignature -> Signature.decode, PointG2.toSignature -> Signature.encode
|
|
1016
1108
|
|
|
1017
1109
|
## Contributing & testing
|
|
1018
1110
|
|