@noble/curves 0.5.1 → 0.6.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 (60) hide show
  1. package/README.md +49 -8
  2. package/lib/_shortw_utils.d.ts +11 -26
  3. package/lib/abstract/bls.d.ts +51 -35
  4. package/lib/abstract/bls.js +77 -139
  5. package/lib/abstract/{group.d.ts → curve.d.ts} +31 -1
  6. package/lib/abstract/{group.js → curve.js} +39 -2
  7. package/lib/abstract/edwards.d.ts +30 -81
  8. package/lib/abstract/edwards.js +225 -420
  9. package/lib/abstract/hash-to-curve.d.ts +25 -6
  10. package/lib/abstract/hash-to-curve.js +40 -12
  11. package/lib/abstract/modular.d.ts +20 -7
  12. package/lib/abstract/modular.js +80 -51
  13. package/lib/abstract/montgomery.js +3 -4
  14. package/lib/abstract/poseidon.d.ts +29 -0
  15. package/lib/abstract/poseidon.js +115 -0
  16. package/lib/abstract/utils.d.ts +5 -34
  17. package/lib/abstract/utils.js +23 -63
  18. package/lib/abstract/weierstrass.d.ts +56 -79
  19. package/lib/abstract/weierstrass.js +509 -641
  20. package/lib/bls12-381.d.ts +1 -0
  21. package/lib/bls12-381.js +75 -65
  22. package/lib/bn.js +1 -1
  23. package/lib/ed25519.d.ts +7 -5
  24. package/lib/ed25519.js +87 -84
  25. package/lib/ed448.d.ts +3 -0
  26. package/lib/ed448.js +88 -84
  27. package/lib/esm/abstract/bls.js +77 -139
  28. package/lib/esm/abstract/{group.js → curve.js} +37 -1
  29. package/lib/esm/abstract/edwards.js +223 -418
  30. package/lib/esm/abstract/hash-to-curve.js +38 -11
  31. package/lib/esm/abstract/modular.js +77 -50
  32. package/lib/esm/abstract/montgomery.js +4 -7
  33. package/lib/esm/abstract/poseidon.js +109 -0
  34. package/lib/esm/abstract/utils.js +21 -59
  35. package/lib/esm/abstract/weierstrass.js +508 -640
  36. package/lib/esm/bls12-381.js +86 -76
  37. package/lib/esm/bn.js +1 -1
  38. package/lib/esm/ed25519.js +85 -83
  39. package/lib/esm/ed448.js +86 -83
  40. package/lib/esm/jubjub.js +6 -5
  41. package/lib/esm/p256.js +11 -9
  42. package/lib/esm/p384.js +11 -9
  43. package/lib/esm/p521.js +13 -12
  44. package/lib/esm/secp256k1.js +118 -157
  45. package/lib/esm/stark.js +104 -39
  46. package/lib/jubjub.d.ts +3 -2
  47. package/lib/jubjub.js +6 -5
  48. package/lib/p192.d.ts +22 -52
  49. package/lib/p224.d.ts +22 -52
  50. package/lib/p256.d.ts +25 -52
  51. package/lib/p256.js +13 -10
  52. package/lib/p384.d.ts +25 -52
  53. package/lib/p384.js +13 -10
  54. package/lib/p521.d.ts +25 -52
  55. package/lib/p521.js +15 -13
  56. package/lib/secp256k1.d.ts +26 -42
  57. package/lib/secp256k1.js +118 -157
  58. package/lib/stark.d.ts +36 -21
  59. package/lib/stark.js +107 -39
  60. package/package.json +14 -9
package/README.md CHANGED
@@ -6,7 +6,9 @@ Minimal, auditable JS implementation of elliptic curve cryptography.
6
6
  - ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
7
7
  - [hash to curve](https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/)
8
8
  for encoding or hashing an arbitrary string to a point on an elliptic curve
9
- - Auditable, [fast](#speed)
9
+ - [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash
10
+ - Auditable
11
+ - 🏎 [Ultra-fast](#speed), hand-optimized for caveats of JS engines
10
12
  - 🔍 Unique tests ensure correctness. Wycheproof vectors included
11
13
  - 🔻 Tree-shaking-friendly: there is no entry point, which ensures small size of your app
12
14
 
@@ -24,7 +26,6 @@ Curves incorporate work from previous noble packages
24
26
  [ed25519](https://github.com/paulmillr/noble-ed25519),
25
27
  [bls12-381](https://github.com/paulmillr/noble-bls12-381)),
26
28
  which had security audits and were developed from 2019 to 2022.
27
- The goal is to replace them with lean UMD builds based on single-codebase noble-curves.
28
29
 
29
30
  ### This library belongs to _noble_ crypto
30
31
 
@@ -88,6 +89,7 @@ To define a custom curve, check out API below.
88
89
  - [abstract/montgomery: Montgomery curve](#abstractmontgomery-montgomery-curve)
89
90
  - [abstract/weierstrass: Short Weierstrass curve](#abstractweierstrass-short-weierstrass-curve)
90
91
  - [abstract/hash-to-curve: Hashing strings to curve points](#abstracthash-to-curve-hashing-strings-to-curve-points)
92
+ - [abstract/poseidon: Poseidon hash](#abstractposeidon-poseidon-hash)
91
93
  - [abstract/modular](#abstractmodular)
92
94
  - [abstract/utils](#abstractutils)
93
95
 
@@ -201,8 +203,6 @@ export type CurveFn = {
201
203
  ExtendedPoint: ExtendedPointConstructor;
202
204
  Signature: SignatureConstructor;
203
205
  utils: {
204
- mod: (a: bigint, b?: bigint) => bigint;
205
- invert: (number: bigint, modulo?: bigint) => bigint;
206
206
  randomPrivateKey: () => Uint8Array;
207
207
  getExtendedPublicKey: (key: PrivKey) => {
208
208
  head: Uint8Array;
@@ -304,20 +304,18 @@ const shared = secp256k1.getSharedSecret(key, someonesPubkey);
304
304
  export type CurveFn = {
305
305
  CURVE: ReturnType<typeof validateOpts>;
306
306
  getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
307
- getSharedSecret: (privateA: PrivKey, publicB: PubKey, isCompressed?: boolean) => Uint8Array;
307
+ getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
308
308
  sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
309
309
  verify: (
310
310
  signature: Hex | SignatureType,
311
311
  msgHash: Hex,
312
- publicKey: PubKey,
312
+ publicKey: Hex,
313
313
  opts?: { lowS?: boolean }
314
314
  ) => boolean;
315
315
  Point: PointConstructor;
316
316
  ProjectivePoint: ProjectivePointConstructor;
317
317
  Signature: SignatureConstructor;
318
318
  utils: {
319
- mod: (a: bigint) => bigint;
320
- invert: (number: bigint) => bigint;
321
319
  isValidPrivateKey(privateKey: PrivKey): boolean;
322
320
  hashToPrivateKey: (hash: Hex) => Uint8Array;
323
321
  randomPrivateKey: () => Uint8Array;
@@ -373,6 +371,30 @@ hashes arbitrary-length byte strings to a list of one or more elements of a fini
373
371
  };
374
372
  ```
375
373
 
374
+ ### abstract/poseidon: Poseidon hash
375
+
376
+ Implements [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash.
377
+
378
+ There are many poseidon instances with different constants. We don't provide them,
379
+ but we provide ability to specify them manually. For actual usage, check out
380
+ stark curve source code.
381
+
382
+ ```ts
383
+ import { poseidon } from '@noble/curves/abstract/poseidon';
384
+
385
+ type PoseidonOpts = {
386
+ Fp: Field<bigint>;
387
+ t: number;
388
+ roundsFull: number;
389
+ roundsPartial: number;
390
+ sboxPower?: number;
391
+ reversePartialPowIdx?: boolean; // Hack for stark
392
+ mds: bigint[][];
393
+ roundConstants: bigint[][];
394
+ };
395
+ const instance = poseidon(opts: PoseidonOpts);
396
+ ```
397
+
376
398
  ### abstract/modular
377
399
 
378
400
  Modular arithmetics utilities.
@@ -462,6 +484,25 @@ verify
462
484
  noble x 698 ops/sec @ 1ms/op
463
485
  ```
464
486
 
487
+ ## Upgrading
488
+
489
+ Differences from @noble/secp256k1 1.7:
490
+
491
+ 1. Different double() formula (but same addition)
492
+ 2. Different sqrt() function
493
+ 3. DRBG supports outputLen bigger than outputLen of hmac
494
+ 4. Support for different hash functions
495
+
496
+ Differences from @noble/ed25519 1.7:
497
+
498
+ 1. Variable field element lengths between EDDSA/ECDH:
499
+ EDDSA (RFC8032) is 456 bits / 57 bytes, ECDH (RFC7748) is 448 bits / 56 bytes
500
+ 2. Different addition formula (doubling is same)
501
+ 3. uvRatio differs between curves (half-expected, not only pow fn changes)
502
+ 4. Point decompression code is different (unexpected), now using generalized formula
503
+ 5. Domain function was no-op for ed25519, but adds some data even with empty context for ed448
504
+
505
+
465
506
  ## Contributing & testing
466
507
 
467
508
  1. Clone the repository
@@ -32,41 +32,26 @@ export declare function createCurve(curveDef: CurveDef, defHash: CHash): Readonl
32
32
  k2: bigint;
33
33
  };
34
34
  } | undefined;
35
- readonly isTorsionFree?: ((c: import("./abstract/weierstrass.js").ProjectiveConstructor<bigint>, point: import("./abstract/weierstrass.js").ProjectivePointType<bigint>) => boolean) | undefined;
36
- readonly clearCofactor?: ((c: import("./abstract/weierstrass.js").ProjectiveConstructor<bigint>, point: import("./abstract/weierstrass.js").ProjectivePointType<bigint>) => import("./abstract/weierstrass.js").ProjectivePointType<bigint>) | undefined;
37
- readonly htfDefaults?: import("./abstract/hash-to-curve.js").htfOpts | undefined;
38
- readonly mapToCurve?: ((scalar: bigint[]) => {
39
- x: bigint;
40
- y: bigint;
41
- }) | undefined;
35
+ readonly isTorsionFree?: ((c: import("./abstract/weierstrass.js").ProjConstructor<bigint>, point: import("./abstract/weierstrass.js").ProjPointType<bigint>) => boolean) | undefined;
36
+ readonly clearCofactor?: ((c: import("./abstract/weierstrass.js").ProjConstructor<bigint>, point: import("./abstract/weierstrass.js").ProjPointType<bigint>) => import("./abstract/weierstrass.js").ProjPointType<bigint>) | undefined;
42
37
  lowS: boolean;
43
38
  readonly hash: CHash;
44
39
  readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
45
40
  readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
46
- readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
41
+ readonly bits2int?: ((bytes: Uint8Array) => bigint) | undefined;
42
+ readonly bits2int_modN?: ((bytes: Uint8Array) => bigint) | undefined;
47
43
  }>;
48
44
  getPublicKey: (privateKey: import("./abstract/utils.js").PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
49
- getSharedSecret: (privateA: import("./abstract/utils.js").PrivKey, publicB: import("./abstract/weierstrass.js").PubKey, isCompressed?: boolean | undefined) => Uint8Array;
50
- sign: (msgHash: import("./abstract/utils.js").Hex, privKey: import("./abstract/utils.js").PrivKey, opts?: {
51
- lowS?: boolean | undefined;
52
- extraEntropy?: (true | import("./abstract/utils.js").Hex) | undefined;
53
- } | undefined) => import("./abstract/weierstrass.js").SignatureType;
54
- verify: (signature: import("./abstract/utils.js").Hex | import("./abstract/weierstrass.js").SignatureType, msgHash: import("./abstract/utils.js").Hex, publicKey: import("./abstract/weierstrass.js").PubKey, opts?: {
55
- lowS?: boolean | undefined;
56
- } | undefined) => boolean;
57
- Point: import("./abstract/weierstrass.js").PointConstructor<bigint>;
58
- ProjectivePoint: import("./abstract/weierstrass.js").ProjectiveConstructor<bigint>;
45
+ getSharedSecret: (privateA: import("./abstract/utils.js").PrivKey, publicB: import("./abstract/utils.js").Hex, isCompressed?: boolean | undefined) => Uint8Array;
46
+ sign: (msgHash: import("./abstract/utils.js").Hex, privKey: import("./abstract/utils.js").PrivKey, opts?: import("./abstract/weierstrass.js").SignOpts | undefined) => import("./abstract/weierstrass.js").SignatureType;
47
+ verify: (signature: import("./abstract/utils.js").Hex | {
48
+ r: bigint;
49
+ s: bigint;
50
+ }, msgHash: import("./abstract/utils.js").Hex, publicKey: import("./abstract/utils.js").Hex, opts?: import("./abstract/weierstrass.js").VerOpts | undefined) => boolean;
51
+ ProjectivePoint: import("./abstract/weierstrass.js").ProjConstructor<bigint>;
59
52
  Signature: import("./abstract/weierstrass.js").SignatureConstructor;
60
53
  utils: {
61
- mod: (a: bigint, b?: bigint | undefined) => bigint;
62
- invert: (number: bigint, modulo?: bigint | undefined) => bigint;
63
- _bigintToBytes: (num: bigint) => Uint8Array;
64
- _bigintToString: (num: bigint) => string;
65
54
  _normalizePrivateKey: (key: import("./abstract/utils.js").PrivKey) => bigint;
66
- _normalizePublicKey: (publicKey: import("./abstract/weierstrass.js").PubKey) => import("./abstract/weierstrass.js").PointType<bigint>;
67
- _isWithinCurveOrder: (num: bigint) => boolean;
68
- _isValidFieldElement: (num: bigint) => boolean;
69
- _weierstrassEquation: (x: bigint) => bigint;
70
55
  isValidPrivateKey(privateKey: import("./abstract/utils.js").PrivKey): boolean;
71
56
  hashToPrivateKey: (hash: import("./abstract/utils.js").Hex) => Uint8Array;
72
57
  randomPrivateKey: () => Uint8Array;
@@ -1,24 +1,41 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
- import * as mod from './modular.js';
3
- import * as utils from './utils.js';
4
- import { Hex, PrivKey } from './utils.js';
5
- import { htfOpts, stringToBytes, hash_to_field, expand_message_xmd } from './hash-to-curve.js';
6
- import { CurvePointsType, PointType, CurvePointsRes } from './weierstrass.js';
2
+ /**
3
+ * BLS (Barreto-Lynn-Scott) family of pairing-friendly curves.
4
+ * Implements BLS (Boneh-Lynn-Shacham) signatures.
5
+ * Consists of two curves: G1 and G2:
6
+ * - G1 is a subgroup of (x, y) E(Fq) over y² = x³ + 4.
7
+ * - G2 is a subgroup of ((x₁, x₂+i), (y₁, y₂+i)) E(Fq²) over y² = x³ + 4(1 + i) where i is √-1
8
+ * - Gt, created by bilinear (ate) pairing e(G1, G2), consists of p-th roots of unity in
9
+ * Fq^k where k is embedding degree. Only degree 12 is currently supported, 24 is not.
10
+ * Pairing is used to aggregate and verify signatures.
11
+ * We are using Fp for private keys (shorter) and Fp₂ for signatures (longer).
12
+ * Some projects may prefer to swap this relation, it is not supported for now.
13
+ */
14
+ import { AffinePoint } from './curve.js';
15
+ import { Field } from './modular.js';
16
+ import { Hex, PrivKey, CHash } from './utils.js';
17
+ import * as htf from './hash-to-curve.js';
18
+ import { CurvePointsType, ProjPointType as ProjPointType, CurvePointsRes } from './weierstrass.js';
7
19
  declare type Fp = bigint;
8
20
  export declare type SignatureCoder<Fp2> = {
9
- decode(hex: Hex): PointType<Fp2>;
10
- encode(point: PointType<Fp2>): Uint8Array;
21
+ decode(hex: Hex): ProjPointType<Fp2>;
22
+ encode(point: ProjPointType<Fp2>): Uint8Array;
11
23
  };
12
24
  export declare type CurveType<Fp, Fp2, Fp6, Fp12> = {
13
25
  r: bigint;
14
- G1: Omit<CurvePointsType<Fp>, 'n'>;
26
+ G1: Omit<CurvePointsType<Fp>, 'n'> & {
27
+ mapToCurve: htf.MapToCurve<Fp>;
28
+ htfDefaults: htf.Opts;
29
+ };
15
30
  G2: Omit<CurvePointsType<Fp2>, 'n'> & {
16
31
  Signature: SignatureCoder<Fp2>;
32
+ mapToCurve: htf.MapToCurve<Fp2>;
33
+ htfDefaults: htf.Opts;
17
34
  };
18
35
  x: bigint;
19
- Fp: mod.Field<Fp>;
20
- Fr: mod.Field<bigint>;
21
- Fp2: mod.Field<Fp2> & {
36
+ Fp: Field<Fp>;
37
+ Fr: Field<bigint>;
38
+ Fp2: Field<Fp2> & {
22
39
  reim: (num: Fp2) => {
23
40
  re: bigint;
24
41
  im: bigint;
@@ -26,54 +43,53 @@ export declare type CurveType<Fp, Fp2, Fp6, Fp12> = {
26
43
  multiplyByB: (num: Fp2) => Fp2;
27
44
  frobeniusMap(num: Fp2, power: number): Fp2;
28
45
  };
29
- Fp6: mod.Field<Fp6>;
30
- Fp12: mod.Field<Fp12> & {
46
+ Fp6: Field<Fp6>;
47
+ Fp12: Field<Fp12> & {
31
48
  frobeniusMap(num: Fp12, power: number): Fp12;
32
49
  multiplyBy014(num: Fp12, o0: Fp2, o1: Fp2, o4: Fp2): Fp12;
33
50
  conjugate(num: Fp12): Fp12;
34
51
  finalExponentiate(num: Fp12): Fp12;
35
52
  };
36
- htfDefaults: htfOpts;
37
- hash: utils.CHash;
53
+ htfDefaults: htf.Opts;
54
+ hash: CHash;
38
55
  randomBytes: (bytesLength?: number) => Uint8Array;
39
56
  };
40
57
  export declare type CurveFn<Fp, Fp2, Fp6, Fp12> = {
41
58
  CURVE: CurveType<Fp, Fp2, Fp6, Fp12>;
42
- Fr: mod.Field<bigint>;
43
- Fp: mod.Field<Fp>;
44
- Fp2: mod.Field<Fp2>;
45
- Fp6: mod.Field<Fp6>;
46
- Fp12: mod.Field<Fp12>;
59
+ Fr: Field<bigint>;
60
+ Fp: Field<Fp>;
61
+ Fp2: Field<Fp2>;
62
+ Fp6: Field<Fp6>;
63
+ Fp12: Field<Fp12>;
47
64
  G1: CurvePointsRes<Fp>;
48
65
  G2: CurvePointsRes<Fp2>;
49
66
  Signature: SignatureCoder<Fp2>;
50
67
  millerLoop: (ell: [Fp2, Fp2, Fp2][], g1: [Fp, Fp]) => Fp12;
51
- calcPairingPrecomputes: (x: Fp2, y: Fp2) => [Fp2, Fp2, Fp2][];
52
- pairing: (P: PointType<Fp>, Q: PointType<Fp2>, withFinalExponent?: boolean) => Fp12;
68
+ calcPairingPrecomputes: (p: AffinePoint<Fp2>) => [Fp2, Fp2, Fp2][];
69
+ hashToCurve: {
70
+ G1: ReturnType<(typeof htf.hashToCurve<Fp>)>;
71
+ G2: ReturnType<(typeof htf.hashToCurve<Fp2>)>;
72
+ };
73
+ pairing: (P: ProjPointType<Fp>, Q: ProjPointType<Fp2>, withFinalExponent?: boolean) => Fp12;
53
74
  getPublicKey: (privateKey: PrivKey) => Uint8Array;
54
75
  sign: {
55
76
  (message: Hex, privateKey: PrivKey): Uint8Array;
56
- (message: PointType<Fp2>, privateKey: PrivKey): PointType<Fp2>;
77
+ (message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
57
78
  };
58
- verify: (signature: Hex | PointType<Fp2>, message: Hex | PointType<Fp2>, publicKey: Hex | PointType<Fp>) => boolean;
79
+ verify: (signature: Hex | ProjPointType<Fp2>, message: Hex | ProjPointType<Fp2>, publicKey: Hex | ProjPointType<Fp>) => boolean;
59
80
  aggregatePublicKeys: {
60
81
  (publicKeys: Hex[]): Uint8Array;
61
- (publicKeys: PointType<Fp>[]): PointType<Fp>;
82
+ (publicKeys: ProjPointType<Fp>[]): ProjPointType<Fp>;
62
83
  };
63
84
  aggregateSignatures: {
64
85
  (signatures: Hex[]): Uint8Array;
65
- (signatures: PointType<Fp2>[]): PointType<Fp2>;
86
+ (signatures: ProjPointType<Fp2>[]): ProjPointType<Fp2>;
66
87
  };
67
- verifyBatch: (signature: Hex | PointType<Fp2>, messages: (Hex | PointType<Fp2>)[], publicKeys: (Hex | PointType<Fp>)[]) => boolean;
88
+ verifyBatch: (signature: Hex | ProjPointType<Fp2>, messages: (Hex | ProjPointType<Fp2>)[], publicKeys: (Hex | ProjPointType<Fp>)[]) => boolean;
68
89
  utils: {
69
- bytesToHex: typeof utils.bytesToHex;
70
- hexToBytes: typeof utils.hexToBytes;
71
- stringToBytes: typeof stringToBytes;
72
- hashToField: typeof hash_to_field;
73
- expandMessageXMD: typeof expand_message_xmd;
74
- mod: typeof mod.mod;
75
- getDSTLabel: () => string;
76
- setDSTLabel(newLabel: string): void;
90
+ stringToBytes: typeof htf.stringToBytes;
91
+ hashToField: typeof htf.hash_to_field;
92
+ expandMessageXMD: typeof htf.expand_message_xmd;
77
93
  };
78
94
  };
79
95
  export declare function bls<Fp2, Fp6, Fp12>(CURVE: CurveType<Fp, Fp2, Fp6, Fp12>): CurveFn<Fp, Fp2, Fp6, Fp12>;