@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.
Files changed (92) hide show
  1. package/README.md +143 -194
  2. package/abstract/bls.d.ts +29 -12
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +58 -8
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/curve.js.map +1 -1
  7. package/abstract/edwards.js.map +1 -1
  8. package/abstract/hash-to-curve.d.ts +1 -1
  9. package/abstract/hash-to-curve.d.ts.map +1 -1
  10. package/abstract/hash-to-curve.js +10 -21
  11. package/abstract/hash-to-curve.js.map +1 -1
  12. package/abstract/modular.js.map +1 -1
  13. package/abstract/montgomery.d.ts.map +1 -1
  14. package/abstract/montgomery.js +5 -7
  15. package/abstract/montgomery.js.map +1 -1
  16. package/abstract/poseidon.js.map +1 -1
  17. package/abstract/utils.d.ts +4 -2
  18. package/abstract/utils.d.ts.map +1 -1
  19. package/abstract/utils.js +61 -36
  20. package/abstract/utils.js.map +1 -1
  21. package/abstract/weierstrass.d.ts +24 -28
  22. package/abstract/weierstrass.d.ts.map +1 -1
  23. package/abstract/weierstrass.js +13 -7
  24. package/abstract/weierstrass.js.map +1 -1
  25. package/bls12-381.d.ts.map +1 -1
  26. package/bls12-381.js +138 -83
  27. package/bls12-381.js.map +1 -1
  28. package/bn254.d.ts +3 -2
  29. package/bn254.d.ts.map +1 -1
  30. package/bn254.js +3 -2
  31. package/bn254.js.map +1 -1
  32. package/ed25519.d.ts +4 -2
  33. package/ed25519.d.ts.map +1 -1
  34. package/ed25519.js +8 -2
  35. package/ed25519.js.map +1 -1
  36. package/ed448.d.ts +4 -2
  37. package/ed448.d.ts.map +1 -1
  38. package/ed448.js +10 -1
  39. package/ed448.js.map +1 -1
  40. package/esm/abstract/bls.js +58 -8
  41. package/esm/abstract/bls.js.map +1 -1
  42. package/esm/abstract/curve.js.map +1 -1
  43. package/esm/abstract/edwards.js.map +1 -1
  44. package/esm/abstract/hash-to-curve.js +11 -22
  45. package/esm/abstract/hash-to-curve.js.map +1 -1
  46. package/esm/abstract/modular.js.map +1 -1
  47. package/esm/abstract/montgomery.js +5 -7
  48. package/esm/abstract/montgomery.js.map +1 -1
  49. package/esm/abstract/poseidon.js.map +1 -1
  50. package/esm/abstract/utils.js +58 -35
  51. package/esm/abstract/utils.js.map +1 -1
  52. package/esm/abstract/weierstrass.js +13 -7
  53. package/esm/abstract/weierstrass.js.map +1 -1
  54. package/esm/bls12-381.js +139 -84
  55. package/esm/bls12-381.js.map +1 -1
  56. package/esm/bn254.js +3 -2
  57. package/esm/bn254.js.map +1 -1
  58. package/esm/ed25519.js +8 -2
  59. package/esm/ed25519.js.map +1 -1
  60. package/esm/ed448.js +10 -1
  61. package/esm/ed448.js.map +1 -1
  62. package/esm/index.js +1 -1
  63. package/esm/index.js.map +1 -1
  64. package/esm/jubjub.js.map +1 -1
  65. package/esm/p256.js +2 -2
  66. package/esm/p256.js.map +1 -1
  67. package/esm/p384.js +2 -2
  68. package/esm/p384.js.map +1 -1
  69. package/esm/p521.js +3 -3
  70. package/esm/p521.js.map +1 -1
  71. package/esm/secp256k1.js +6 -6
  72. package/esm/secp256k1.js.map +1 -1
  73. package/jubjub.js.map +1 -1
  74. package/p256.js +2 -2
  75. package/p256.js.map +1 -1
  76. package/p384.js +2 -2
  77. package/p384.js.map +1 -1
  78. package/p521.js +3 -3
  79. package/p521.js.map +1 -1
  80. package/package.json +7 -7
  81. package/secp256k1.js +6 -6
  82. package/secp256k1.js.map +1 -1
  83. package/src/abstract/bls.ts +119 -21
  84. package/src/abstract/hash-to-curve.ts +12 -20
  85. package/src/abstract/montgomery.ts +4 -6
  86. package/src/abstract/utils.ts +57 -28
  87. package/src/abstract/weierstrass.ts +25 -10
  88. package/src/bls12-381.ts +128 -70
  89. package/src/bn254.ts +3 -2
  90. package/src/ed25519.ts +10 -2
  91. package/src/ed448.ts +18 -3
  92. 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 an independent security firm
5
+ - 🔒 [**Audited**](#security) by independent security firms
6
6
  - 🔻 Tree-shaking-friendly: use only what's necessary, other code won't be included
7
7
  - 🏎 Ultra-fast, hand-optimized for caveats of JS engines
8
8
  - 🔍 Unique tests ensure correctness: property-based, cross-library and Wycheproof vectors, fuzzing
9
9
  - ➰ Short Weierstrass, Edwards, Montgomery curves
10
- - ✍️ 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 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
- ### This library belongs to _noble_ crypto
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
- > **noble-crypto** high-security, easily auditable set of contained cryptographic libraries and tools.
19
+ ### This library belongs to _noble_ cryptography
18
20
 
19
- - No dependencies, protection against supply chain attacks
20
- - Auditable TypeScript / JS code
21
- - Supported on all major platforms
22
- - Releases are signed with PGP keys and built transparently with NPM provenance
23
- - Check out [homepage](https://paulmillr.com/noble/) & all libraries:
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 crypto.getRandomValues](https://github.com/LinusU/react-native-get-random-values).
37
- If you don't like NPM, a standalone [noble-curves.js](https://github.com/paulmillr/noble-curves/releases) is also available.
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 (Elliptic Curve Diffie-Hellman)](#ecdh-elliptic-curve-diffie-hellman)
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
- - [abstract/weierstrass: Short Weierstrass curve](#abstractweierstrass-short-weierstrass-curve)
51
- - [abstract/edwards: Twisted Edwards curve](#abstractedwards-twisted-edwards-curve)
52
- - [abstract/montgomery: Montgomery curve](#abstractmontgomery-montgomery-curve)
53
- - [abstract/bls: Barreto-Lynn-Scott curves](#abstractbls-barreto-lynn-scott-curves)
54
- - [abstract/hash-to-curve: Hashing strings to curve points](#abstracthash-to-curve-hashing-strings-to-curve-points)
55
- - [abstract/poseidon: Poseidon hash](#abstractposeidon-poseidon-hash)
56
- - [abstract/modular: Modular arithmetics utilities](#abstractmodular-modular-arithmetics-utilities)
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
- - [abstract/utils: Useful utilities](#abstractutils-useful-utilities)
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 are utilizing [noble-hashes](https://github.com/paulmillr/noble-hashes).
71
- [Abstract API](#abstract-api) doesn't depend on them: you can use a different hashing library.
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
- // import * from '@noble/curves'; // Error: use sub-imports, to ensure small app size
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 (Elliptic Curve Diffie-Hellman)
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](#abstractbls-barreto-lynn-scott-curves).
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
- ### abstract/weierstrass: Short Weierstrass curve
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
- ### abstract/edwards: Twisted Edwards curve
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
- ### abstract/montgomery: Montgomery curve
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
- ### abstract/bls: Barreto-Lynn-Scott curves
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
- Right now we only implement BLS12-381 (compatible with ETH and others),
583
- but in theory defining BLS12-377, BLS24 should be straightforward. An example:
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
- // bls.pairing(PointG1, PointG2);
616
- // bls.pairing(PointG1, PointG2, false);
617
- // bls.fields.Fp12.finalExponentiate(bls.fields.Fp12.mul(eGS, ePHm));
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
- // bls.G1.ProjectivePoint.BASE, bls.G2.ProjectivePoint.BASE
621
- // bls.fields.Fp, bls.fields.Fp2, bls.fields.Fp12, bls.fields.Fr
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
- Full types:
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
- ### abstract/poseidon: Poseidon hash
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
- ### abstract/modular: Modular arithmetics utilities
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](#abstracthash-to-curve-hashing-strings-to-curve-points)
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
- ### abstract/utils: Useful utilities
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
- 1. The library has been independently audited:
830
-
831
- - in Feb 2023 by [Trail of Bits](https://www.trailofbits.com):
832
- [PDF](https://github.com/trailofbits/publications/blob/master/reviews/2023-01-ryanshea-noblecurveslibrary-securityreview.pdf).
833
- The audit has been funded by [Ryan Shea](https://www.shea.io).
834
- Audit scope was abstract modules `curve`, `hash-to-curve`, `modular`, `poseidon`, `utils`, `weierstrass`,
835
- and top-level modules `_shortw_utils` and `secp256k1`.
836
- See [changes since v0.7.3 audit](https://github.com/paulmillr/noble-curves/compare/0.7.3..main).
837
-
838
- 2. The library has been fuzzed by [Guido Vranken's cryptofuzz](https://github.com/guidovranken/cryptofuzz).
839
- You can run the fuzzer by yourself to check it.
840
- 3. [Timing attack](https://en.wikipedia.org/wiki/Timing_attack) considerations:
841
- _JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to
842
- achieve in a scripting language. Which means _any other JS library can't have
843
- constant-timeness_. Even statically typed Rust, a language without GC,
844
- [makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)
845
- for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones.
846
- Use low-level libraries & languages. Nonetheless we're targetting algorithmic constant time.
847
-
848
- We consider infrastructure attacks like rogue NPM modules very important;
849
- that's why it's crucial to minimize the amount of 3rd-party dependencies & native bindings.
850
- If your app uses 500 dependencies, any dep could get hacked and you'll be
851
- downloading malware with every `npm install`. Our goal is to minimize this attack vector.
852
- As for devDependencies used by the library:
853
-
854
- - `@scure` base, bip32, bip39 (used in tests), micro-bmark (benchmark), micro-should (testing)
855
- are developed by us and follow the same practices such as: minimal library size, auditability,
856
- signed releases
857
- - prettier (linter), fast-check (property-based testing), typescript versions
858
- are locked and rarely updated. Every update is checked with `npm-diff`.
859
- The packages are big, which makes it hard to audit their source code thoroughly and fully.
860
- - They are only used if you clone the git repo and want to add some feature to it. End-users won't use them.
861
-
862
- As for key generation, we're deferring to built-in
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; use `signAsync` for async version
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
- - [Learning fast elliptic-curve cryptography](https://paulmillr.com/posts/noble-secp256k1-fast-ecc/)
1015
- - EdDSA
1016
- - [A Deep dive into Ed25519 Signatures](https://cendyne.dev/posts/2022-03-06-ed25519-signatures.html)
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 * as htf from './hash-to-curve.js';
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
- mapToCurve: htf.MapToCurve<Fp>;
28
- htfDefaults: htf.Opts;
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: htf.MapToCurve<Fp2>;
33
- htfDefaults: htf.Opts;
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: htf.Opts;
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>) => boolean;
69
- verifyBatch: (signature: Hex | ProjPointType<Fp2>, messages: (Hex | ProjPointType<Fp2>)[], publicKeys: (Hex | ProjPointType<Fp>)[]) => boolean;
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 htf.createHasher<Fp>>;
81
- G2: CurvePointsRes<Fp2> & ReturnType<typeof htf.createHasher<Fp2>>;
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;