@noble/curves 1.2.0 → 1.4.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 +143 -194
- package/abstract/bls.d.ts +29 -12
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +58 -8
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +1 -1
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +10 -21
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +5 -7
- package/abstract/montgomery.js.map +1 -1
- package/abstract/poseidon.js.map +1 -1
- package/abstract/utils.d.ts +4 -2
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +61 -36
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +24 -28
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +13 -7
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +138 -83
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +3 -2
- package/bn254.d.ts.map +1 -1
- package/bn254.js +3 -2
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +4 -2
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +8 -2
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +4 -2
- package/ed448.d.ts.map +1 -1
- package/ed448.js +10 -1
- package/ed448.js.map +1 -1
- package/esm/abstract/bls.js +58 -8
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.js.map +1 -1
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/hash-to-curve.js +11 -22
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/montgomery.js +5 -7
- package/esm/abstract/montgomery.js.map +1 -1
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/utils.js +58 -35
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.js +13 -7
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.js +139 -84
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn254.js +3 -2
- package/esm/bn254.js.map +1 -1
- package/esm/ed25519.js +8 -2
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.js +10 -1
- package/esm/ed448.js.map +1 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/esm/jubjub.js.map +1 -1
- package/esm/p256.js +2 -2
- package/esm/p256.js.map +1 -1
- package/esm/p384.js +2 -2
- package/esm/p384.js.map +1 -1
- package/esm/p521.js +3 -3
- package/esm/p521.js.map +1 -1
- package/esm/secp256k1.js +6 -6
- package/esm/secp256k1.js.map +1 -1
- package/jubjub.js.map +1 -1
- package/p256.js +2 -2
- package/p256.js.map +1 -1
- package/p384.js +2 -2
- package/p384.js.map +1 -1
- package/p521.js +3 -3
- package/p521.js.map +1 -1
- package/package.json +7 -7
- package/secp256k1.js +6 -6
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +119 -21
- package/src/abstract/hash-to-curve.ts +12 -20
- package/src/abstract/montgomery.ts +4 -6
- package/src/abstract/utils.ts +57 -28
- package/src/abstract/weierstrass.ts +25 -10
- package/src/bls12-381.ts +128 -70
- package/src/bn254.ts +3 -2
- package/src/ed25519.ts +10 -2
- package/src/ed448.ts +18 -3
- package/src/package.json +3 -0
package/README.md
CHANGED
|
@@ -2,30 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
Audited & minimal JS implementation of elliptic curve cryptography.
|
|
4
4
|
|
|
5
|
-
- 🔒 [**Audited**](#security) by
|
|
5
|
+
- 🔒 [**Audited**](#security) by independent security firms
|
|
6
6
|
- 🔻 Tree-shaking-friendly: use only what's necessary, other code won't be included
|
|
7
7
|
- 🏎 Ultra-fast, hand-optimized for caveats of JS engines
|
|
8
8
|
- 🔍 Unique tests ensure correctness: property-based, cross-library and Wycheproof vectors, fuzzing
|
|
9
9
|
- ➰ Short Weierstrass, Edwards, Montgomery curves
|
|
10
|
-
- ✍️ ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
|
|
11
|
-
- 🔖 SUF-CMA
|
|
12
|
-
- #️⃣ hash-to-curve for encoding or hashing an arbitrary string to an elliptic curve point
|
|
10
|
+
- ✍️ ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement, hashing to curves
|
|
11
|
+
- 🔖 SUF-CMA, SBS (non-repudiation), ZIP215 (consensus friendliness) features for ed25519
|
|
13
12
|
- 🧜♂️ Poseidon ZK-friendly hash
|
|
13
|
+
- 🪶 178KB for everything, 25KB for single-curve build
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
For discussions, questions and support, visit
|
|
16
|
+
[GitHub Discussions](https://github.com/paulmillr/noble-curves/discussions)
|
|
17
|
+
section of the repository.
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
### This library belongs to _noble_ cryptography
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
21
|
+
> **noble cryptography** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
|
22
|
+
|
|
23
|
+
- Zero or minimal dependencies
|
|
24
|
+
- Highly readable TypeScript / JS code
|
|
25
|
+
- PGP-signed releases and transparent NPM builds
|
|
26
|
+
- All libraries:
|
|
24
27
|
[ciphers](https://github.com/paulmillr/noble-ciphers),
|
|
25
28
|
[curves](https://github.com/paulmillr/noble-curves),
|
|
26
29
|
[hashes](https://github.com/paulmillr/noble-hashes),
|
|
30
|
+
[post-quantum](https://github.com/paulmillr/noble-post-quantum),
|
|
27
31
|
4kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /
|
|
28
32
|
[ed25519](https://github.com/paulmillr/noble-ed25519)
|
|
33
|
+
- [Check out homepage](https://paulmillr.com/noble/)
|
|
34
|
+
for reading resources, documentation and apps built with noble
|
|
29
35
|
|
|
30
36
|
## Usage
|
|
31
37
|
|
|
@@ -33,13 +39,19 @@ Audited & minimal JS implementation of elliptic curve cryptography.
|
|
|
33
39
|
|
|
34
40
|
We support all major platforms and runtimes.
|
|
35
41
|
For [Deno](https://deno.land), ensure to use [npm specifier](https://deno.land/manual@v1.28.0/node/npm_specifiers).
|
|
36
|
-
For React Native, you may need a [polyfill for
|
|
37
|
-
|
|
42
|
+
For React Native, you may need a [polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values).
|
|
43
|
+
A standalone file [noble-curves.js](https://github.com/paulmillr/noble-curves/releases) is also available.
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
// import * from '@noble/curves'; // Error: use sub-imports, to ensure small app size
|
|
47
|
+
import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
|
|
48
|
+
// import { secp256k1 } from 'npm:@noble/curves@1.4.0/secp256k1'; // Deno
|
|
49
|
+
```
|
|
38
50
|
|
|
39
51
|
- [Implementations](#implementations)
|
|
40
52
|
- [ECDSA signature scheme](#ecdsa-signature-scheme)
|
|
41
53
|
- [ECDSA public key recovery & extra entropy](#ecdsa-public-key-recovery--extra-entropy)
|
|
42
|
-
- [ECDH
|
|
54
|
+
- [ECDH: Elliptic Curve Diffie-Hellman](#ecdh-elliptic-curve-diffie-hellman)
|
|
43
55
|
- [Schnorr signatures over secp256k1, BIP340](#schnorr-signatures-over-secp256k1-bip340)
|
|
44
56
|
- [ed25519, X25519, ristretto255](#ed25519-x25519-ristretto255)
|
|
45
57
|
- [ed448, X448, decaf448](#ed448-x448-decaf448)
|
|
@@ -47,37 +59,32 @@ If you don't like NPM, a standalone [noble-curves.js](https://github.com/paulmil
|
|
|
47
59
|
- [All available imports](#all-available-imports)
|
|
48
60
|
- [Accessing a curve's variables](#accessing-a-curves-variables)
|
|
49
61
|
- [Abstract API](#abstract-api)
|
|
50
|
-
- [
|
|
51
|
-
- [
|
|
52
|
-
- [
|
|
53
|
-
- [
|
|
54
|
-
- [
|
|
55
|
-
- [
|
|
56
|
-
- [
|
|
62
|
+
- [weierstrass: Short Weierstrass curve](#weierstrass-short-weierstrass-curve)
|
|
63
|
+
- [edwards: Twisted Edwards curve](#edwards-twisted-edwards-curve)
|
|
64
|
+
- [montgomery: Montgomery curve](#montgomery-montgomery-curve)
|
|
65
|
+
- [bls: Barreto-Lynn-Scott curves](#bls-barreto-lynn-scott-curves)
|
|
66
|
+
- [hash-to-curve: Hashing strings to curve points](#hash-to-curve-hashing-strings-to-curve-points)
|
|
67
|
+
- [poseidon: Poseidon hash](#poseidon-poseidon-hash)
|
|
68
|
+
- [modular: Modular arithmetics utilities](#modular-modular-arithmetics-utilities)
|
|
57
69
|
- [Creating private keys from hashes](#creating-private-keys-from-hashes)
|
|
58
|
-
- [
|
|
70
|
+
- [utils: Useful utilities](#utils-useful-utilities)
|
|
59
71
|
- [Security](#security)
|
|
60
72
|
- [Speed](#speed)
|
|
61
|
-
- [Contributing & testing](#contributing--testing)
|
|
62
73
|
- [Upgrading](#upgrading)
|
|
74
|
+
- [Contributing & testing](#contributing--testing)
|
|
63
75
|
- [Resources](#resources)
|
|
64
|
-
- [Demos](#demos)
|
|
65
|
-
- [Projects using curves](#projects-using-curves)
|
|
66
|
-
- [License](#license)
|
|
67
76
|
|
|
68
77
|
### Implementations
|
|
69
78
|
|
|
70
|
-
Implementations
|
|
71
|
-
[
|
|
79
|
+
Implementations use [noble-hashes](https://github.com/paulmillr/noble-hashes).
|
|
80
|
+
If you want to use a different hashing library, [abstract API](#abstract-api) doesn't depend on them.
|
|
72
81
|
|
|
73
82
|
#### ECDSA signature scheme
|
|
74
83
|
|
|
75
84
|
Generic example that works for all curves, shown for secp256k1:
|
|
76
85
|
|
|
77
86
|
```ts
|
|
78
|
-
|
|
79
|
-
import { secp256k1 } from '@noble/curves/secp256k1'; // ESM and Common.js
|
|
80
|
-
// import { secp256k1 } from 'npm:@noble/curves@1.2.0/secp256k1'; // Deno
|
|
87
|
+
import { secp256k1 } from '@noble/curves/secp256k1';
|
|
81
88
|
const priv = secp256k1.utils.randomPrivateKey();
|
|
82
89
|
const pub = secp256k1.getPublicKey(priv);
|
|
83
90
|
const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
|
|
@@ -89,16 +96,20 @@ const privHex = '46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c12623
|
|
|
89
96
|
const pub2 = secp256k1.getPublicKey(privHex);
|
|
90
97
|
```
|
|
91
98
|
|
|
99
|
+
We support P256 (secp256r1), P384 (secp384r1), P521 (secp521r1).
|
|
100
|
+
|
|
92
101
|
#### ECDSA public key recovery & extra entropy
|
|
93
102
|
|
|
94
103
|
```ts
|
|
104
|
+
// let sig = secp256k1.Signature.fromCompact(sigHex); // or .fromDER(sigDERHex)
|
|
105
|
+
// sig = sig.addRecoveryBit(bit); // bit is not serialized into compact / der format
|
|
95
106
|
sig.recoverPublicKey(msg).toRawBytes(); // === pub; // public key recovery
|
|
96
107
|
|
|
97
108
|
// extraEntropy https://moderncrypto.org/mail-archive/curves/2017/000925.html
|
|
98
109
|
const sigImprovedSecurity = secp256k1.sign(msg, priv, { extraEntropy: true });
|
|
99
110
|
```
|
|
100
111
|
|
|
101
|
-
#### ECDH
|
|
112
|
+
#### ECDH: Elliptic Curve Diffie-Hellman
|
|
102
113
|
|
|
103
114
|
```ts
|
|
104
115
|
// 1. The output includes parity byte. Strip it using shared.slice(1)
|
|
@@ -235,7 +246,7 @@ Same RFC7748 / RFC8032 / IRTF draft are followed.
|
|
|
235
246
|
|
|
236
247
|
#### bls12-381
|
|
237
248
|
|
|
238
|
-
See [abstract/bls](#
|
|
249
|
+
See [abstract/bls](#bls-barreto-lynn-scott-curves).
|
|
239
250
|
|
|
240
251
|
#### All available imports
|
|
241
252
|
|
|
@@ -274,7 +285,7 @@ Precomputes are enabled for weierstrass and edwards BASE points of a curve. You
|
|
|
274
285
|
could precompute any other point (e.g. for ECDH) using `utils.precompute()`
|
|
275
286
|
method: check out examples.
|
|
276
287
|
|
|
277
|
-
###
|
|
288
|
+
### weierstrass: Short Weierstrass curve
|
|
278
289
|
|
|
279
290
|
```ts
|
|
280
291
|
import { weierstrass } from '@noble/curves/abstract/weierstrass';
|
|
@@ -316,6 +327,10 @@ type CHash = {
|
|
|
316
327
|
outputLen: number;
|
|
317
328
|
create(): any;
|
|
318
329
|
};
|
|
330
|
+
|
|
331
|
+
// example
|
|
332
|
+
function sha256(message: Uint8Array) { return _internal_lowlvl(message) }
|
|
333
|
+
sha256.outputLen = 32; // 32 bytes of output for sha2-256
|
|
319
334
|
```
|
|
320
335
|
|
|
321
336
|
**Message hash** is expected instead of message itself:
|
|
@@ -441,7 +456,7 @@ const fast = secq256k1.utils.precompute(8, Point.fromHex(someonesPubKey));
|
|
|
441
456
|
fast.multiply(privKey); // much faster ECDH now
|
|
442
457
|
```
|
|
443
458
|
|
|
444
|
-
###
|
|
459
|
+
### edwards: Twisted Edwards curve
|
|
445
460
|
|
|
446
461
|
```ts
|
|
447
462
|
import { twistedEdwards } from '@noble/curves/abstract/edwards';
|
|
@@ -531,7 +546,7 @@ interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
|
|
|
531
546
|
}
|
|
532
547
|
```
|
|
533
548
|
|
|
534
|
-
###
|
|
549
|
+
### montgomery: Montgomery curve
|
|
535
550
|
|
|
536
551
|
```typescript
|
|
537
552
|
import { montgomery } from '@noble/curves/abstract/montgomery';
|
|
@@ -558,7 +573,7 @@ Proper Elliptic Curve Points are not implemented yet.
|
|
|
558
573
|
|
|
559
574
|
You must specify curve params `Fp`, `a`, `Gu` coordinate of u, `montgomeryBits` and `nByteLength`.
|
|
560
575
|
|
|
561
|
-
###
|
|
576
|
+
### bls: Barreto-Lynn-Scott curves
|
|
562
577
|
|
|
563
578
|
The module abstracts BLS (Barreto-Lynn-Scott) pairing-friendly elliptic curve construction.
|
|
564
579
|
They allow to construct [zk-SNARKs](https://z.cash/technology/zksnarks/) and
|
|
@@ -567,6 +582,8 @@ use aggregated, batch-verifiable
|
|
|
567
582
|
using Boneh-Lynn-Shacham signature scheme.
|
|
568
583
|
|
|
569
584
|
The module doesn't expose `CURVE` property: use `G1.CURVE`, `G2.CURVE` instead.
|
|
585
|
+
Only BLS12-381 is implemented currently.
|
|
586
|
+
Defining BLS12-377 and BLS24 should be straightforward.
|
|
570
587
|
|
|
571
588
|
Main methods and properties are:
|
|
572
589
|
|
|
@@ -579,8 +596,13 @@ Main methods and properties are:
|
|
|
579
596
|
- `Signature` property with `fromHex`, `toHex` methods
|
|
580
597
|
- `fields` containing `Fp`, `Fp2`, `Fp6`, `Fp12`, `Fr`
|
|
581
598
|
|
|
582
|
-
|
|
583
|
-
|
|
599
|
+
The default BLS uses short public keys (with public keys in G1 and signatures in G2).
|
|
600
|
+
Short signatures (public keys in G2 and signatures in G1) is also supported, using:
|
|
601
|
+
|
|
602
|
+
- `getPublicKeyForShortSignatures(privateKey)`
|
|
603
|
+
- `signShortSignature(message, privateKey)`
|
|
604
|
+
- `verifyShortSignature(signature, message, publicKey)`
|
|
605
|
+
- `aggregateShortSignatures(signatures)`
|
|
584
606
|
|
|
585
607
|
```ts
|
|
586
608
|
import { bls12_381 as bls } from '@noble/curves/bls12-381';
|
|
@@ -591,6 +613,12 @@ const signature = bls.sign(message, privateKey);
|
|
|
591
613
|
const isValid = bls.verify(signature, message, publicKey);
|
|
592
614
|
console.log({ publicKey, signature, isValid });
|
|
593
615
|
|
|
616
|
+
// Use custom DST, e.g. for Ethereum consensus layer
|
|
617
|
+
const htfEthereum = {DST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_'};
|
|
618
|
+
const signatureEth = bls.sign(message, privateKey, htfEthereum);
|
|
619
|
+
const isValidEth = bls.verify(signature, message, publicKey, htfEthereum);
|
|
620
|
+
console.log({ signatureEth, isValidEth });
|
|
621
|
+
|
|
594
622
|
// Sign 1 msg with 3 keys
|
|
595
623
|
const privateKeys = [
|
|
596
624
|
'18f020b98eb798752a50ed0563b079c125b0db5dd0b1060d1c1b47d4a193e1e4',
|
|
@@ -612,68 +640,19 @@ const isValid3 = bls.verifyBatch(aggSignature3, messages, publicKeys);
|
|
|
612
640
|
console.log({ publicKeys, signatures3, aggSignature3, isValid3 });
|
|
613
641
|
|
|
614
642
|
// Pairings, with and without final exponentiation
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
643
|
+
bls.pairing(PointG1, PointG2);
|
|
644
|
+
bls.pairing(PointG1, PointG2, false);
|
|
645
|
+
bls.fields.Fp12.finalExponentiate(bls.fields.Fp12.mul(PointG1, PointG2));
|
|
618
646
|
|
|
619
647
|
// Others
|
|
620
|
-
|
|
621
|
-
|
|
648
|
+
bls.G1.ProjectivePoint.BASE, bls.G2.ProjectivePoint.BASE
|
|
649
|
+
bls.fields.Fp, bls.fields.Fp2, bls.fields.Fp12, bls.fields.Fr
|
|
650
|
+
bls.params.x, bls.params.r, bls.params.G1b, bls.params.G2b
|
|
622
651
|
|
|
623
652
|
// hash-to-curve examples can be seen below
|
|
624
653
|
```
|
|
625
654
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
```ts
|
|
629
|
-
getPublicKey: (privateKey: PrivKey) => Uint8Array;
|
|
630
|
-
sign: {
|
|
631
|
-
(message: Hex, privateKey: PrivKey): Uint8Array;
|
|
632
|
-
(message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
|
|
633
|
-
};
|
|
634
|
-
verify: (
|
|
635
|
-
signature: Hex | ProjPointType<Fp2>,
|
|
636
|
-
message: Hex | ProjPointType<Fp2>,
|
|
637
|
-
publicKey: Hex | ProjPointType<Fp>
|
|
638
|
-
) => boolean;
|
|
639
|
-
verifyBatch: (
|
|
640
|
-
signature: Hex | ProjPointType<Fp2>,
|
|
641
|
-
messages: (Hex | ProjPointType<Fp2>)[],
|
|
642
|
-
publicKeys: (Hex | ProjPointType<Fp>)[]
|
|
643
|
-
) => boolean;
|
|
644
|
-
aggregatePublicKeys: {
|
|
645
|
-
(publicKeys: Hex[]): Uint8Array;
|
|
646
|
-
(publicKeys: ProjPointType<Fp>[]): ProjPointType<Fp>;
|
|
647
|
-
};
|
|
648
|
-
aggregateSignatures: {
|
|
649
|
-
(signatures: Hex[]): Uint8Array;
|
|
650
|
-
(signatures: ProjPointType<Fp2>[]): ProjPointType<Fp2>;
|
|
651
|
-
};
|
|
652
|
-
millerLoop: (ell: [Fp2, Fp2, Fp2][], g1: [Fp, Fp]) => Fp12;
|
|
653
|
-
pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
|
|
654
|
-
G1: CurvePointsRes<Fp> & ReturnType<typeof htf.createHasher<Fp>>;
|
|
655
|
-
G2: CurvePointsRes<Fp2> & ReturnType<typeof htf.createHasher<Fp2>>;
|
|
656
|
-
Signature: SignatureCoder<Fp2>;
|
|
657
|
-
params: {
|
|
658
|
-
x: bigint;
|
|
659
|
-
r: bigint;
|
|
660
|
-
G1b: bigint;
|
|
661
|
-
G2b: Fp2;
|
|
662
|
-
};
|
|
663
|
-
fields: {
|
|
664
|
-
Fp: IField<Fp>;
|
|
665
|
-
Fp2: IField<Fp2>;
|
|
666
|
-
Fp6: IField<Fp6>;
|
|
667
|
-
Fp12: IField<Fp12>;
|
|
668
|
-
Fr: IField<bigint>;
|
|
669
|
-
};
|
|
670
|
-
utils: {
|
|
671
|
-
randomPrivateKey: () => Uint8Array;
|
|
672
|
-
calcPairingPrecomputes: (p: AffinePoint<Fp2>) => [Fp2, Fp2, Fp2][];
|
|
673
|
-
};
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
### abstract/hash-to-curve: Hashing strings to curve points
|
|
655
|
+
### hash-to-curve: Hashing strings to curve points
|
|
677
656
|
|
|
678
657
|
The module allows to hash arbitrary strings to elliptic curve points. Implements [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380).
|
|
679
658
|
|
|
@@ -731,7 +710,7 @@ type Opts = {
|
|
|
731
710
|
};
|
|
732
711
|
```
|
|
733
712
|
|
|
734
|
-
###
|
|
713
|
+
### poseidon: Poseidon hash
|
|
735
714
|
|
|
736
715
|
Implements [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash.
|
|
737
716
|
|
|
@@ -755,7 +734,7 @@ type PoseidonOpts = {
|
|
|
755
734
|
const instance = poseidon(opts: PoseidonOpts);
|
|
756
735
|
```
|
|
757
736
|
|
|
758
|
-
###
|
|
737
|
+
### modular: Modular arithmetics utilities
|
|
759
738
|
|
|
760
739
|
```ts
|
|
761
740
|
import * as mod from '@noble/curves/abstract/modular';
|
|
@@ -792,19 +771,20 @@ and [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380#section-5.2).
|
|
|
792
771
|
This means, for 32-byte key, we would need 48-byte hash to get 2^-128 bias, which matches curve security level.
|
|
793
772
|
|
|
794
773
|
`hashToPrivateScalar()` that hashes to **private key** was created for this purpose.
|
|
795
|
-
Use [abstract/hash-to-curve](#
|
|
774
|
+
Use [abstract/hash-to-curve](#hash-to-curve-hashing-strings-to-curve-points)
|
|
796
775
|
if you need to hash to **public key**.
|
|
797
776
|
|
|
798
777
|
```ts
|
|
799
778
|
import { p256 } from '@noble/curves/p256';
|
|
800
779
|
import { sha256 } from '@noble/hashes/sha256';
|
|
801
780
|
import { hkdf } from '@noble/hashes/hkdf';
|
|
781
|
+
import * as mod from '@noble/curves/abstract/modular';
|
|
802
782
|
const someKey = new Uint8Array(32).fill(2); // Needs to actually be random, not .fill(2)
|
|
803
783
|
const derived = hkdf(sha256, someKey, undefined, 'application', 48); // 48 bytes for 32-byte priv
|
|
804
784
|
const validPrivateKey = mod.hashToPrivateScalar(derived, p256.CURVE.n);
|
|
805
785
|
```
|
|
806
786
|
|
|
807
|
-
###
|
|
787
|
+
### utils: Useful utilities
|
|
808
788
|
|
|
809
789
|
```ts
|
|
810
790
|
import * as utils from '@noble/curves/abstract/utils';
|
|
@@ -826,43 +806,61 @@ utils.equalBytes(Uint8Array.from([0xde]), Uint8Array.from([0xde]));
|
|
|
826
806
|
|
|
827
807
|
## Security
|
|
828
808
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
- in
|
|
832
|
-
[
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
809
|
+
The library has been independently audited:
|
|
810
|
+
|
|
811
|
+
- at version 1.2.0, in Sep 2023, by [Kudelski Security](https://kudelskisecurity.com)
|
|
812
|
+
- PDFs: [offline](./audit/2023-09-kudelski-audit-starknet.pdf)
|
|
813
|
+
- [Changes since audit](https://github.com/paulmillr/noble-curves/compare/1.2.0..main)
|
|
814
|
+
- Scope: [scure-starknet](https://github.com/paulmillr/scure-starknet) and its related
|
|
815
|
+
abstract modules of noble-curves: `curve`, `modular`, `poseidon`, `weierstrass`
|
|
816
|
+
- The audit has been funded by [Starkware](https://starkware.co)
|
|
817
|
+
- at version 0.7.3, in Feb 2023, by [Trail of Bits](https://www.trailofbits.com)
|
|
818
|
+
- PDFs: [online](https://github.com/trailofbits/publications/blob/master/reviews/2023-01-ryanshea-noblecurveslibrary-securityreview.pdf),
|
|
819
|
+
[offline](./audit/2023-01-trailofbits-audit-curves.pdf)
|
|
820
|
+
- [Changes since audit](https://github.com/paulmillr/noble-curves/compare/0.7.3..main)
|
|
821
|
+
- Scope: abstract modules `curve`, `hash-to-curve`, `modular`, `poseidon`, `utils`, `weierstrass` and
|
|
822
|
+
top-level modules `_shortw_utils` and `secp256k1`
|
|
823
|
+
- The audit has been funded by [Ryan Shea](https://www.shea.io)
|
|
824
|
+
|
|
825
|
+
It is tested against property-based, cross-library and Wycheproof vectors,
|
|
826
|
+
and has fuzzing by [Guido Vranken's cryptofuzz](https://github.com/guidovranken/cryptofuzz).
|
|
827
|
+
|
|
828
|
+
If you see anything unusual: investigate and report.
|
|
829
|
+
|
|
830
|
+
### Constant-timeness
|
|
831
|
+
|
|
832
|
+
_JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to
|
|
833
|
+
achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance
|
|
834
|
+
in a scripting language. Which means _any other JS library can't have
|
|
835
|
+
constant-timeness_. Even statically typed Rust, a language without GC,
|
|
836
|
+
[makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)
|
|
837
|
+
for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones.
|
|
838
|
+
Use low-level libraries & languages. Nonetheless we're targetting algorithmic constant time.
|
|
839
|
+
|
|
840
|
+
### Supply chain security
|
|
841
|
+
|
|
842
|
+
* **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures.
|
|
843
|
+
* **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs
|
|
844
|
+
* **Rare releasing** is followed to ensure less re-audit need for end-users
|
|
845
|
+
* **Dependencies** are minimized and locked-down:
|
|
846
|
+
- If your app has 500 dependencies, any dep could get hacked and you'll be downloading
|
|
847
|
+
malware with every install. We make sure to use as few dependencies as possible
|
|
848
|
+
- We prevent automatic dependency updates by locking-down version ranges. Every update is checked with `npm-diff`
|
|
849
|
+
- One dependency [noble-hashes](https://github.com/paulmillr/noble-hashes) is used, by the same author, to provide hashing functionality
|
|
850
|
+
* **Dev Dependencies** are only used if you want to contribute to the repo. They are disabled for end-users:
|
|
851
|
+
- scure-base, scure-bip32, scure-bip39, micro-bmark and micro-should are developed by the same author and follow identical security practices
|
|
852
|
+
- prettier (linter), fast-check (property-based testing) and typescript are used for code quality, vector generation and ts compilation. The packages are big, which makes it hard to audit their source code thoroughly and fully
|
|
853
|
+
|
|
854
|
+
### Randomness
|
|
855
|
+
|
|
856
|
+
We're deferring to built-in
|
|
863
857
|
[crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)
|
|
864
858
|
which is considered cryptographically secure (CSPRNG).
|
|
865
859
|
|
|
860
|
+
In the past, browsers had bugs that made it weak: it may happen again.
|
|
861
|
+
Implementing a userspace CSPRNG to get resilient to the weakness
|
|
862
|
+
is even worse: there is no reliable userspace source of quality entropy.
|
|
863
|
+
|
|
866
864
|
## Speed
|
|
867
865
|
|
|
868
866
|
Benchmark results on Apple M2 with node v20:
|
|
@@ -944,13 +942,6 @@ ed25519 x 3,088 ops/sec @ 323μs/op
|
|
|
944
942
|
ed448 x 1,247 ops/sec @ 801μs/op
|
|
945
943
|
```
|
|
946
944
|
|
|
947
|
-
## Contributing & testing
|
|
948
|
-
|
|
949
|
-
1. Clone the repository
|
|
950
|
-
2. `npm install` to install build dependencies like TypeScript
|
|
951
|
-
3. `npm run build` to compile TypeScript code
|
|
952
|
-
4. `npm run test` will execute all main tests
|
|
953
|
-
|
|
954
945
|
## Upgrading
|
|
955
946
|
|
|
956
947
|
Previously, the library was split into single-feature packages
|
|
@@ -971,7 +962,7 @@ Upgrading from noble-secp256k1 1.7:
|
|
|
971
962
|
- to use old behavior, which produced 65-byte uncompressed keys, set
|
|
972
963
|
argument `isCompressed` to `false`: `getPublicKey(priv, false)`
|
|
973
964
|
- `sign`
|
|
974
|
-
- is now sync
|
|
965
|
+
- is now sync
|
|
975
966
|
- now returns `Signature` instance with `{ r, s, recovery }` properties
|
|
976
967
|
- `canonical` option was renamed to `lowS`
|
|
977
968
|
- `recovered` option has been removed because recovery bit is always returned now
|
|
@@ -980,6 +971,7 @@ Upgrading from noble-secp256k1 1.7:
|
|
|
980
971
|
Compact encoding is simply a concatenation of 32-byte r and 32-byte s.
|
|
981
972
|
2. If you must use DER encoding, switch to noble-curves (see above).
|
|
982
973
|
- `verify`
|
|
974
|
+
- is now sync
|
|
983
975
|
- `strict` option was renamed to `lowS`
|
|
984
976
|
- `getSharedSecret`
|
|
985
977
|
- now produce 33-byte compressed signatures by default
|
|
@@ -1009,61 +1001,18 @@ Upgrading from [@noble/bls12-381](https://github.com/paulmillr/noble-bls12-381):
|
|
|
1009
1001
|
- PointG2.fromSignature -> Signature.decode, PointG2.toSignature -> Signature.encode
|
|
1010
1002
|
- Fp2 ORDER was corrected
|
|
1011
1003
|
|
|
1004
|
+
## Contributing & testing
|
|
1005
|
+
|
|
1006
|
+
1. Clone the repository
|
|
1007
|
+
2. `npm install` to install build dependencies like TypeScript
|
|
1008
|
+
3. `npm run build` to compile TypeScript code
|
|
1009
|
+
4. `npm run test` will execute all main tests
|
|
1010
|
+
|
|
1012
1011
|
## Resources
|
|
1013
1012
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
- [Ed25519 Deep Dive Addendum](https://cendyne.dev/posts/2022-09-11-ed25519-deep-dive-addendum.html)
|
|
1018
|
-
- [It’s 255:19AM. Do you know what your validation criteria are?](https://hdevalence.ca/blog/2020-10-04-its-25519am)
|
|
1019
|
-
- [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)
|
|
1020
|
-
that describes concepts of Strong UnForgeability under Chosen Message Attacks and Strongly Binding Signatures
|
|
1021
|
-
- [Cofactor Explained: Clearing Elliptic Curves’ dirty little secret](https://loup-vaillant.fr/tutorials/cofactor)
|
|
1022
|
-
- [Surrounded by Elligators](https://loup-vaillant.fr/articles/implementing-elligator)
|
|
1023
|
-
- Pairings and BLS
|
|
1024
|
-
- [BLS signatures for busy people](https://gist.github.com/paulmillr/18b802ad219b1aee34d773d08ec26ca2)
|
|
1025
|
-
- [BLS12-381 for the rest of us](https://hackmd.io/@benjaminion/bls12-381)
|
|
1026
|
-
- [Key concepts of pairings](https://medium.com/@alonmuroch_65570/bls-signatures-part-2-key-concepts-of-pairings-27a8a9533d0c)
|
|
1027
|
-
- Pairing over bls12-381:
|
|
1028
|
-
[fields](https://research.nccgroup.com/2020/07/06/pairing-over-bls12-381-part-1-fields/),
|
|
1029
|
-
[curves](https://research.nccgroup.com/2020/07/13/pairing-over-bls12-381-part-2-curves/),
|
|
1030
|
-
[pairings](https://research.nccgroup.com/2020/08/13/pairing-over-bls12-381-part-3-pairing/)
|
|
1031
|
-
- [Estimating the bit security of pairing-friendly curves](https://research.nccgroup.com/2022/02/03/estimating-the-bit-security-of-pairing-friendly-curves/)
|
|
1032
|
-
|
|
1033
|
-
### Demos
|
|
1034
|
-
|
|
1035
|
-
- [Elliptic Curve Calculator](https://paulmillr.com/noble): add / multiply points, sign messages
|
|
1036
|
-
- [BLS threshold signatures](https://genthresh.com)
|
|
1037
|
-
|
|
1038
|
-
### Projects using curves
|
|
1039
|
-
|
|
1040
|
-
- HDkey libraries: [scure-bip32](https://github.com/paulmillr/scure-bip32), [bip32](https://github.com/bitcoinjs/bip32)
|
|
1041
|
-
- Social networks: [nostr](https://github.com/nbd-wtf/nostr-tools), [bluesky](https://github.com/bluesky-social/atproto)
|
|
1042
|
-
- Ethereum libraries:
|
|
1043
|
-
- [ethereum-cryptography](https://github.com/ethereum/js-ethereum-cryptography)
|
|
1044
|
-
- [micro-eth-signer](https://github.com/paulmillr/micro-eth-signer),
|
|
1045
|
-
[ethers](https://github.com/ethers-io/ethers.js) (old noble),
|
|
1046
|
-
[viem.sh](https://viem.sh),
|
|
1047
|
-
[@ethereumjs](https://github.com/ethereumjs/ethereumjs-monorepo)
|
|
1048
|
-
- [metamask's eth-sig-util](https://github.com/MetaMask/eth-sig-util)
|
|
1049
|
-
- [gridplus lattice sdk](https://github.com/GridPlus/lattice-eth2-utils)
|
|
1050
|
-
- Bitcoin libraries:
|
|
1051
|
-
- [scure-btc-signer](https://github.com/paulmillr/scure-btc-signer)
|
|
1052
|
-
- [tapscript](https://github.com/cmdruid/tapscript)
|
|
1053
|
-
- Solana libraries: [micro-sol-signer](https://github.com/paulmillr/micro-sol-signer), [solana-web3.js](https://github.com/solana-labs/solana-web3.js)
|
|
1054
|
-
- Other web3 stuff:
|
|
1055
|
-
- [scure-starknet](https://github.com/paulmillr/scure-starknet)
|
|
1056
|
-
- [aztec](https://github.com/AztecProtocol/aztec-packages)
|
|
1057
|
-
- [polkadot.js](https://github.com/polkadot-js/common), [drand-client](https://github.com/drand/drand-client), [moneroj](https://github.com/beritani/moneroj), [tronlib](https://github.com/CoinSpace/tronlib)
|
|
1058
|
-
- [protonmail](https://github.com/ProtonMail/WebClients) (old noble for now)
|
|
1059
|
-
- [did-jwt](https://github.com/decentralized-identity/did-jwt), [hpke-js](https://github.com/dajiaji/hpke-js),
|
|
1060
|
-
[js-libp2p-noise](https://github.com/ChainSafe/js-libp2p-noise)
|
|
1061
|
-
- [ed25519-keygen](https://github.com/paulmillr/ed25519-keygen) SSH, PGP, TOR key generation
|
|
1062
|
-
- [secp256k1 compatibility layer](https://github.com/ethereum/js-ethereum-cryptography/blob/2.0.0/src/secp256k1-compat.ts)
|
|
1063
|
-
for users who want to switch from secp256k1-node or tiny-secp256k1. Allows to see which methods map to corresponding noble code.
|
|
1064
|
-
- [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)
|
|
1065
|
-
- [KZG trusted setup ceremony](https://github.com/dsrvlabs/czg-keremony)
|
|
1066
|
-
- See [full list of projects on GitHub](https://github.com/paulmillr/noble-curves/network/dependents).
|
|
1013
|
+
Check out [paulmillr.com/noble](https://paulmillr.com/noble/)
|
|
1014
|
+
for useful resources, articles, documentation and demos
|
|
1015
|
+
related to the library.
|
|
1067
1016
|
|
|
1068
1017
|
## License
|
|
1069
1018
|
|
package/abstract/bls.d.ts
CHANGED
|
@@ -14,9 +14,14 @@
|
|
|
14
14
|
import { AffinePoint } from './curve.js';
|
|
15
15
|
import { IField } from './modular.js';
|
|
16
16
|
import { Hex, PrivKey, CHash } from './utils.js';
|
|
17
|
-
import
|
|
17
|
+
import { MapToCurve, Opts as HTFOpts, htfBasicOpts, createHasher } from './hash-to-curve.js';
|
|
18
18
|
import { CurvePointsType, ProjPointType as ProjPointType, CurvePointsRes } from './weierstrass.js';
|
|
19
19
|
type Fp = bigint;
|
|
20
|
+
export type ShortSignatureCoder<Fp> = {
|
|
21
|
+
fromHex(hex: Hex): ProjPointType<Fp>;
|
|
22
|
+
toRawBytes(point: ProjPointType<Fp>): Uint8Array;
|
|
23
|
+
toHex(point: ProjPointType<Fp>): string;
|
|
24
|
+
};
|
|
20
25
|
export type SignatureCoder<Fp2> = {
|
|
21
26
|
fromHex(hex: Hex): ProjPointType<Fp2>;
|
|
22
27
|
toRawBytes(point: ProjPointType<Fp2>): Uint8Array;
|
|
@@ -24,13 +29,14 @@ export type SignatureCoder<Fp2> = {
|
|
|
24
29
|
};
|
|
25
30
|
export type CurveType<Fp, Fp2, Fp6, Fp12> = {
|
|
26
31
|
G1: Omit<CurvePointsType<Fp>, 'n'> & {
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
ShortSignature: SignatureCoder<Fp>;
|
|
33
|
+
mapToCurve: MapToCurve<Fp>;
|
|
34
|
+
htfDefaults: HTFOpts;
|
|
29
35
|
};
|
|
30
36
|
G2: Omit<CurvePointsType<Fp2>, 'n'> & {
|
|
31
37
|
Signature: SignatureCoder<Fp2>;
|
|
32
|
-
mapToCurve:
|
|
33
|
-
htfDefaults:
|
|
38
|
+
mapToCurve: MapToCurve<Fp2>;
|
|
39
|
+
htfDefaults: HTFOpts;
|
|
34
40
|
};
|
|
35
41
|
fields: {
|
|
36
42
|
Fp: IField<Fp>;
|
|
@@ -55,18 +61,24 @@ export type CurveType<Fp, Fp2, Fp6, Fp12> = {
|
|
|
55
61
|
x: bigint;
|
|
56
62
|
r: bigint;
|
|
57
63
|
};
|
|
58
|
-
htfDefaults:
|
|
64
|
+
htfDefaults: HTFOpts;
|
|
59
65
|
hash: CHash;
|
|
60
66
|
randomBytes: (bytesLength?: number) => Uint8Array;
|
|
61
67
|
};
|
|
62
68
|
export type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
|
63
69
|
getPublicKey: (privateKey: PrivKey) => Uint8Array;
|
|
70
|
+
getPublicKeyForShortSignatures: (privateKey: PrivKey) => Uint8Array;
|
|
64
71
|
sign: {
|
|
65
|
-
(message: Hex, privateKey: PrivKey): Uint8Array;
|
|
66
|
-
(message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
|
|
72
|
+
(message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
|
|
73
|
+
(message: ProjPointType<Fp2>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp2>;
|
|
74
|
+
};
|
|
75
|
+
signShortSignature: {
|
|
76
|
+
(message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
|
|
77
|
+
(message: ProjPointType<Fp>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp>;
|
|
67
78
|
};
|
|
68
|
-
verify: (signature: Hex | ProjPointType<Fp2>, message: Hex | ProjPointType<Fp2>, publicKey: Hex | ProjPointType<Fp
|
|
69
|
-
|
|
79
|
+
verify: (signature: Hex | ProjPointType<Fp2>, message: Hex | ProjPointType<Fp2>, publicKey: Hex | ProjPointType<Fp>, htfOpts?: htfBasicOpts) => boolean;
|
|
80
|
+
verifyShortSignature: (signature: Hex | ProjPointType<Fp>, message: Hex | ProjPointType<Fp>, publicKey: Hex | ProjPointType<Fp2>, htfOpts?: htfBasicOpts) => boolean;
|
|
81
|
+
verifyBatch: (signature: Hex | ProjPointType<Fp2>, messages: (Hex | ProjPointType<Fp2>)[], publicKeys: (Hex | ProjPointType<Fp>)[], htfOpts?: htfBasicOpts) => boolean;
|
|
70
82
|
aggregatePublicKeys: {
|
|
71
83
|
(publicKeys: Hex[]): Uint8Array;
|
|
72
84
|
(publicKeys: ProjPointType<Fp>[]): ProjPointType<Fp>;
|
|
@@ -75,11 +87,16 @@ export type CurveFn<Fp, Fp2, Fp6, Fp12> = {
|
|
|
75
87
|
(signatures: Hex[]): Uint8Array;
|
|
76
88
|
(signatures: ProjPointType<Fp2>[]): ProjPointType<Fp2>;
|
|
77
89
|
};
|
|
90
|
+
aggregateShortSignatures: {
|
|
91
|
+
(signatures: Hex[]): Uint8Array;
|
|
92
|
+
(signatures: ProjPointType<Fp>[]): ProjPointType<Fp>;
|
|
93
|
+
};
|
|
78
94
|
millerLoop: (ell: [Fp2, Fp2, Fp2][], g1: [Fp, Fp]) => Fp12;
|
|
79
95
|
pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
|
|
80
|
-
G1: CurvePointsRes<Fp> & ReturnType<typeof
|
|
81
|
-
G2: CurvePointsRes<Fp2> & ReturnType<typeof
|
|
96
|
+
G1: CurvePointsRes<Fp> & ReturnType<typeof createHasher<Fp>>;
|
|
97
|
+
G2: CurvePointsRes<Fp2> & ReturnType<typeof createHasher<Fp2>>;
|
|
82
98
|
Signature: SignatureCoder<Fp2>;
|
|
99
|
+
ShortSignature: ShortSignatureCoder<Fp>;
|
|
83
100
|
params: {
|
|
84
101
|
x: bigint;
|
|
85
102
|
r: bigint;
|