@noble/curves 0.2.1 → 0.3.1

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 (62) hide show
  1. package/README.md +14 -19
  2. package/lib/crypto.d.ts +4 -0
  3. package/lib/crypto.js +8 -0
  4. package/lib/cryptoBrowser.d.ts +4 -0
  5. package/lib/cryptoBrowser.js +7 -0
  6. package/lib/definitions/_shortw_utils.d.ts +63 -0
  7. package/lib/definitions/_shortw_utils.js +18 -0
  8. package/lib/definitions/bn.d.ts +7 -0
  9. package/lib/definitions/bn.js +23 -0
  10. package/lib/definitions/ed25519.d.ts +49 -0
  11. package/lib/definitions/ed25519.js +308 -0
  12. package/lib/definitions/ed448.d.ts +3 -0
  13. package/lib/definitions/ed448.js +127 -0
  14. package/lib/definitions/index.d.ts +0 -0
  15. package/lib/definitions/index.js +2 -0
  16. package/lib/definitions/jubjub.d.ts +7 -0
  17. package/lib/definitions/jubjub.js +55 -0
  18. package/lib/definitions/p192.d.ts +112 -0
  19. package/lib/definitions/p192.js +23 -0
  20. package/lib/definitions/p224.d.ts +112 -0
  21. package/lib/definitions/p224.js +24 -0
  22. package/lib/definitions/p256.d.ts +112 -0
  23. package/lib/definitions/p256.js +23 -0
  24. package/lib/definitions/p384.d.ts +112 -0
  25. package/lib/definitions/p384.js +24 -0
  26. package/lib/definitions/p521.d.ts +113 -0
  27. package/lib/definitions/p521.js +36 -0
  28. package/lib/definitions/pasta.d.ts +2 -0
  29. package/lib/definitions/pasta.js +32 -0
  30. package/lib/definitions/secp256k1.d.ts +87 -0
  31. package/lib/definitions/secp256k1.js +245 -0
  32. package/lib/definitions/stark.d.ts +62 -0
  33. package/lib/definitions/stark.js +248 -0
  34. package/lib/edwards.d.ts +2 -2
  35. package/lib/edwards.js +2 -6
  36. package/lib/esm/crypto.js +5 -0
  37. package/lib/esm/cryptoBrowser.js +4 -0
  38. package/lib/esm/definitions/_shortw_utils.js +13 -0
  39. package/lib/esm/definitions/bn.js +20 -0
  40. package/lib/esm/definitions/ed25519.js +304 -0
  41. package/lib/esm/definitions/ed448.js +124 -0
  42. package/lib/esm/definitions/index.js +2 -0
  43. package/lib/esm/definitions/jubjub.js +50 -0
  44. package/lib/esm/definitions/p192.js +20 -0
  45. package/lib/esm/definitions/p224.js +21 -0
  46. package/lib/esm/definitions/p256.js +20 -0
  47. package/lib/esm/definitions/p384.js +21 -0
  48. package/lib/esm/definitions/p521.js +33 -0
  49. package/lib/esm/definitions/pasta.js +29 -0
  50. package/lib/esm/definitions/secp256k1.js +241 -0
  51. package/lib/esm/definitions/stark.js +227 -0
  52. package/lib/esm/edwards.js +3 -7
  53. package/lib/esm/modular.js +14 -9
  54. package/lib/esm/utils.js +17 -0
  55. package/lib/esm/weierstrass.js +17 -9
  56. package/lib/modular.d.ts +8 -1
  57. package/lib/modular.js +14 -9
  58. package/lib/utils.d.ts +4 -0
  59. package/lib/utils.js +19 -1
  60. package/lib/weierstrass.d.ts +5 -3
  61. package/lib/weierstrass.js +16 -8
  62. package/package.json +38 -8
package/README.md CHANGED
@@ -45,9 +45,9 @@ The library does not have an entry point. It allows you to select specific primi
45
45
 
46
46
  ```ts
47
47
  import { weierstrass } from '@noble/curves/weierstrass'; // Short Weierstrass curve
48
+ import { concatBytes, randomBytes } from '@noble/curves/utils';
48
49
  import { sha256 } from '@noble/hashes/sha256';
49
50
  import { hmac } from '@noble/hashes/hmac';
50
- import { concatBytes, randomBytes } from '@noble/hashes/utils';
51
51
 
52
52
  const secp256k1 = weierstrass({
53
53
  a: 0n,
@@ -81,9 +81,13 @@ const shared = secp256k1.getSharedSecret(key, someonesPubkey);
81
81
 
82
82
  ### Overview
83
83
 
84
- * All arithmetics is done with JS bigints in finite fields
85
- * Curve variables, order (number of points on curve), field prime (over which the modular division would be done)
86
- are required
84
+ * To initialize new curve, you must specify its variables, order (number of points on curve), field prime (over which the modular division would be done)
85
+ * All curves expose same generic interface:
86
+ * `getPublicKey()`, `sign()`, `verify()` functions
87
+ * `Point` conforming to `Group` interface with add/multiply/double/negate/add/equals methods
88
+ * `CURVE` object with curve variables like `Gx`, `Gy`, `P` (field), `n` (order)
89
+ * `utils` object with `randomPrivateKey()`, `mod()`, `invert()` methods (`mod CURVE.P`)
90
+ * All arithmetics is done with JS bigints over finite fields
87
91
  * Many features require hashing, which is not provided. `@noble/hashes` can be used for this purpose.
88
92
  Any other library must conform to the CHash interface:
89
93
  ```ts
@@ -97,17 +101,9 @@ const shared = secp256k1.getSharedSecret(key, someonesPubkey);
97
101
  Precomputes are calculated once (takes ~20-40ms), after that most `G` multiplications
98
102
  - for example, `getPublicKey()`, `sign()` and similar methods - would be much faster.
99
103
  Use `curve.utils.precompute()`
100
- * Special params that tune performance can be optionally provided.
101
- For example, square root calculation, which is commonly used in point decompression routines
102
- * Curves export `Point`, which conforms to `Group` interface, which has following methods:
103
- - `double()`, `negate()`
104
- - `add()`, `subtract()`, `equals()`
105
- - `multiply()`
106
- Every group also has `BASE` (generator) and `ZERO` (infinity) static properties.
107
- * Curves export `CURVE` object
108
- * Curves export `utils`:
109
- * `randomPrivateKey()` specific for the curve, avoiding modulo bias
110
- * `mod()` & `invert()` methods: function from `modular` with default `P` set to CURVE
104
+ * Special params that tune performance can be optionally provided. For example:
105
+ * `sqrtMod` square root calculation, used for point decompression
106
+ * `endo` endomorphism options for Koblitz curves
111
107
 
112
108
  ### edwards: Twisted Edwards curve
113
109
 
@@ -119,19 +115,18 @@ Twisted Edwards curve's formula is: ax² + y² = 1 + dx²y².
119
115
  ```typescript
120
116
  import { twistedEdwards } from '@noble/curves/edwards'; // Twisted Edwards curve
121
117
  import { sha512 } from '@noble/hashes/sha512';
122
- import { div } from '@noble/curves/modular';
118
+ import * as mod from '@noble/curves/modular';
123
119
 
124
120
  const ed25519 = twistedEdwards({
125
121
  a: -1n,
126
- d: div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
122
+ d: mod.div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
127
123
  P: 2n ** 255n - 19n,
128
124
  n: 2n ** 252n + 27742317777372353535851937790883648493n,
129
125
  h: 8n,
130
126
  Gx: 15112221349535400772501151409588531511454012693041857206046113283949847762202n,
131
127
  Gy: 46316835694926478169428394003475163141307993866256225615783033603165251855960n,
132
128
  hash: sha512,
133
- randomBytes,
134
- adjustScalarBytes(bytes) { // could be no-op
129
+ adjustScalarBytes(bytes) { // optional
135
130
  bytes[0] &= 248;
136
131
  bytes[31] &= 127;
137
132
  bytes[31] |= 64;
@@ -0,0 +1,4 @@
1
+ export declare const crypto: {
2
+ node?: any;
3
+ web?: any;
4
+ };
package/lib/crypto.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.crypto = void 0;
4
+ const nodeCrypto = require("crypto");
5
+ exports.crypto = {
6
+ node: nodeCrypto,
7
+ web: undefined,
8
+ };
@@ -0,0 +1,4 @@
1
+ export declare const crypto: {
2
+ node?: any;
3
+ web?: any;
4
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.crypto = void 0;
4
+ exports.crypto = {
5
+ node: undefined,
6
+ web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
7
+ };
@@ -0,0 +1,63 @@
1
+ import { CurveType, CHash } from '../weierstrass';
2
+ export declare function getHash(hash: CHash): {
3
+ hash: CHash;
4
+ hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => Uint8Array;
5
+ };
6
+ declare type CurveDef = Readonly<Omit<CurveType, 'hash' | 'hmac'>>;
7
+ export declare function createCurve(curveDef: CurveDef, defHash: CHash): Readonly<{
8
+ create: (hash: CHash) => import("../weierstrass").CurveFn;
9
+ CURVE: Readonly<{
10
+ readonly nBitLength: number;
11
+ readonly nByteLength: number;
12
+ readonly P: bigint;
13
+ readonly n: bigint;
14
+ readonly h: bigint;
15
+ readonly Gx: bigint;
16
+ readonly Gy: bigint;
17
+ readonly a: bigint;
18
+ readonly b: bigint;
19
+ lowS: boolean;
20
+ readonly hash: CHash;
21
+ readonly hmac: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
22
+ randomBytes: typeof import("../utils").randomBytes;
23
+ readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
24
+ readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
25
+ readonly normalizePrivateKey?: ((key: import("../utils").PrivKey) => import("../utils").PrivKey) | undefined;
26
+ readonly endo?: {
27
+ beta: bigint;
28
+ splitScalar: (k: bigint) => {
29
+ k1neg: boolean;
30
+ k1: bigint;
31
+ k2neg: boolean;
32
+ k2: bigint;
33
+ };
34
+ } | undefined;
35
+ }>;
36
+ getPublicKey: (privateKey: import("../utils").PrivKey, isCompressed?: boolean | undefined) => Uint8Array;
37
+ getSharedSecret: (privateA: import("../utils").PrivKey, publicB: import("../weierstrass").PubKey, isCompressed?: boolean | undefined) => Uint8Array;
38
+ sign: (msgHash: import("../utils").Hex, privKey: import("../utils").PrivKey, opts?: {
39
+ lowS?: boolean | undefined;
40
+ extraEntropy?: (true | import("../utils").Hex) | undefined;
41
+ } | undefined) => import("../weierstrass").SignatureType;
42
+ verify: (signature: import("../utils").Hex | import("../weierstrass").SignatureType, msgHash: import("../utils").Hex, publicKey: import("../weierstrass").PubKey, opts?: {
43
+ lowS?: boolean | undefined;
44
+ } | undefined) => boolean;
45
+ Point: import("../weierstrass").PointConstructor;
46
+ JacobianPoint: import("../weierstrass").JacobianPointConstructor;
47
+ Signature: import("../weierstrass").SignatureConstructor;
48
+ utils: {
49
+ mod: (a: bigint, b?: bigint | undefined) => bigint;
50
+ invert: (number: bigint, modulo?: bigint | undefined) => bigint;
51
+ _bigintToBytes: (num: bigint) => Uint8Array;
52
+ _bigintToString: (num: bigint) => string;
53
+ _normalizePrivateKey: (key: import("../utils").PrivKey) => bigint;
54
+ _normalizePublicKey: (publicKey: import("../weierstrass").PubKey) => import("../weierstrass").PointType;
55
+ _isWithinCurveOrder: (num: bigint) => boolean;
56
+ _isValidFieldElement: (num: bigint) => boolean;
57
+ _weierstrassEquation: (x: bigint) => bigint;
58
+ isValidPrivateKey(privateKey: import("../utils").PrivKey): boolean;
59
+ hashToPrivateKey: (hash: import("../utils").Hex) => Uint8Array;
60
+ randomPrivateKey: () => Uint8Array;
61
+ };
62
+ }>;
63
+ export {};
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCurve = exports.getHash = void 0;
4
+ const hmac_1 = require("@noble/hashes/hmac");
5
+ const utils_1 = require("@noble/hashes/utils");
6
+ const weierstrass_1 = require("../weierstrass");
7
+ function getHash(hash) {
8
+ return {
9
+ hash,
10
+ hmac: (key, ...msgs) => (0, hmac_1.hmac)(hash, key, (0, utils_1.concatBytes)(...msgs)),
11
+ };
12
+ }
13
+ exports.getHash = getHash;
14
+ function createCurve(curveDef, defHash) {
15
+ const create = (hash) => (0, weierstrass_1.weierstrass)({ ...curveDef, ...getHash(hash) });
16
+ return Object.freeze({ ...create(defHash), create });
17
+ }
18
+ exports.createCurve = createCurve;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * bn254 pairing-friendly curve.
3
+ * Previously known as alt_bn_128, when it had 128-bit security.
4
+ * Recent research shown it's weaker, the naming has been adjusted to its prime bit count.
5
+ * https://github.com/zcash/zcash/issues/2502
6
+ */
7
+ export declare const bn254: import("../weierstrass").CurveFn;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bn254 = void 0;
4
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5
+ const weierstrass_1 = require("../weierstrass");
6
+ const sha256_1 = require("@noble/hashes/sha256");
7
+ const _shortw_utils_js_1 = require("./_shortw_utils.js");
8
+ /**
9
+ * bn254 pairing-friendly curve.
10
+ * Previously known as alt_bn_128, when it had 128-bit security.
11
+ * Recent research shown it's weaker, the naming has been adjusted to its prime bit count.
12
+ * https://github.com/zcash/zcash/issues/2502
13
+ */
14
+ exports.bn254 = (0, weierstrass_1.weierstrass)({
15
+ a: BigInt(0),
16
+ b: BigInt(3),
17
+ P: BigInt('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47'),
18
+ n: BigInt('0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001'),
19
+ Gx: BigInt(1),
20
+ Gy: BigInt(2),
21
+ h: BigInt(1),
22
+ ...(0, _shortw_utils_js_1.getHash)(sha256_1.sha256),
23
+ });
@@ -0,0 +1,49 @@
1
+ import { ExtendedPointType } from '../edwards';
2
+ import { Hex } from '../utils';
3
+ export declare const ED25519_TORSION_SUBGROUP: string[];
4
+ export declare const ed25519: import("../edwards").CurveFn;
5
+ export declare const ed25519ctx: import("../edwards").CurveFn;
6
+ export declare const ed25519ph: import("../edwards").CurveFn;
7
+ export declare const x25519: import("../montgomery").CurveFn;
8
+ declare type ExtendedPoint = ExtendedPointType;
9
+ /**
10
+ * Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
11
+ * a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
12
+ * Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
13
+ * but it should work in its own namespace: do not combine those two.
14
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
15
+ */
16
+ export declare class RistrettoPoint {
17
+ private readonly ep;
18
+ static BASE: RistrettoPoint;
19
+ static ZERO: RistrettoPoint;
20
+ constructor(ep: ExtendedPoint);
21
+ private static calcElligatorRistrettoMap;
22
+ /**
23
+ * Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
24
+ * The hash-to-group operation applies Elligator twice and adds the results.
25
+ * **Note:** this is one-way map, there is no conversion from point to hash.
26
+ * https://ristretto.group/formulas/elligator.html
27
+ * @param hex 64-bit output of a hash function
28
+ */
29
+ static hashToCurve(hex: Hex): RistrettoPoint;
30
+ /**
31
+ * Converts ristretto-encoded string to ristretto point.
32
+ * https://ristretto.group/formulas/decoding.html
33
+ * @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
34
+ */
35
+ static fromHex(hex: Hex): RistrettoPoint;
36
+ /**
37
+ * Encodes ristretto point to Uint8Array.
38
+ * https://ristretto.group/formulas/encoding.html
39
+ */
40
+ toRawBytes(): Uint8Array;
41
+ toHex(): string;
42
+ toString(): string;
43
+ equals(other: RistrettoPoint): boolean;
44
+ add(other: RistrettoPoint): RistrettoPoint;
45
+ subtract(other: RistrettoPoint): RistrettoPoint;
46
+ multiply(scalar: number | bigint): RistrettoPoint;
47
+ multiplyUnsafe(scalar: number | bigint): RistrettoPoint;
48
+ }
49
+ export {};
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RistrettoPoint = exports.x25519 = exports.ed25519ph = exports.ed25519ctx = exports.ed25519 = exports.ED25519_TORSION_SUBGROUP = void 0;
4
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5
+ const sha512_1 = require("@noble/hashes/sha512");
6
+ const utils_1 = require("@noble/hashes/utils");
7
+ const edwards_1 = require("../edwards");
8
+ const montgomery_1 = require("../montgomery");
9
+ const modular_1 = require("../modular");
10
+ const utils_2 = require("../utils");
11
+ /**
12
+ * ed25519 Twisted Edwards curve with following addons:
13
+ * - X25519 ECDH
14
+ * - Ristretto cofactor elimination
15
+ * - Elligator hash-to-group / point indistinguishability
16
+ */
17
+ const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
18
+ // √(-1) aka √(a) aka 2^((p-1)/4)
19
+ const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
20
+ // prettier-ignore
21
+ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _5n = BigInt(5);
22
+ // prettier-ignore
23
+ const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
24
+ function ed25519_pow_2_252_3(x) {
25
+ const P = ED25519_P;
26
+ const x2 = (x * x) % P;
27
+ const b2 = (x2 * x) % P; // x^3, 11
28
+ const b4 = ((0, modular_1.pow2)(b2, _2n, P) * b2) % P; // x^15, 1111
29
+ const b5 = ((0, modular_1.pow2)(b4, _1n, P) * x) % P; // x^31
30
+ const b10 = ((0, modular_1.pow2)(b5, _5n, P) * b5) % P;
31
+ const b20 = ((0, modular_1.pow2)(b10, _10n, P) * b10) % P;
32
+ const b40 = ((0, modular_1.pow2)(b20, _20n, P) * b20) % P;
33
+ const b80 = ((0, modular_1.pow2)(b40, _40n, P) * b40) % P;
34
+ const b160 = ((0, modular_1.pow2)(b80, _80n, P) * b80) % P;
35
+ const b240 = ((0, modular_1.pow2)(b160, _80n, P) * b80) % P;
36
+ const b250 = ((0, modular_1.pow2)(b240, _10n, P) * b10) % P;
37
+ const pow_p_5_8 = ((0, modular_1.pow2)(b250, _2n, P) * x) % P;
38
+ // ^ To pow to (p+3)/8, multiply it by x.
39
+ return { pow_p_5_8, b2 };
40
+ }
41
+ /**
42
+ * For X25519, in order to decode 32 random bytes as an integer scalar,
43
+ * set the
44
+ * three least significant bits of the first byte 0b1111_1000,
45
+ * and the most significant bit of the last to zero 0b0111_1111,
46
+ * set the second most significant bit of the last byte to 1 0b0100_0000
47
+ */
48
+ function adjustScalarBytes(bytes) {
49
+ bytes[0] &= 248;
50
+ bytes[31] &= 127;
51
+ bytes[31] |= 64;
52
+ return bytes;
53
+ }
54
+ // sqrt(u/v)
55
+ function uvRatio(u, v) {
56
+ const P = ED25519_P;
57
+ const v3 = (0, modular_1.mod)(v * v * v, P); // v³
58
+ const v7 = (0, modular_1.mod)(v3 * v3 * v, P); // v⁷
59
+ // (p+3)/8 and (p-5)/8
60
+ const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
61
+ let x = (0, modular_1.mod)(u * v3 * pow, P); // (uv³)(uv⁷)^(p-5)/8
62
+ const vx2 = (0, modular_1.mod)(v * x * x, P); // vx²
63
+ const root1 = x; // First root candidate
64
+ const root2 = (0, modular_1.mod)(x * ED25519_SQRT_M1, P); // Second root candidate
65
+ const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root
66
+ const useRoot2 = vx2 === (0, modular_1.mod)(-u, P); // If vx² = -u, set x <-- x * 2^((p-1)/4)
67
+ const noRoot = vx2 === (0, modular_1.mod)(-u * ED25519_SQRT_M1, P); // There is no valid root, vx² = -u√(-1)
68
+ if (useRoot1)
69
+ x = root1;
70
+ if (useRoot2 || noRoot)
71
+ x = root2; // We return root2 anyway, for const-time
72
+ if ((0, modular_1.isNegativeLE)(x, P))
73
+ x = (0, modular_1.mod)(-x, P);
74
+ return { isValid: useRoot1 || useRoot2, value: x };
75
+ }
76
+ // Just in case
77
+ exports.ED25519_TORSION_SUBGROUP = [
78
+ '0100000000000000000000000000000000000000000000000000000000000000',
79
+ 'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',
80
+ '0000000000000000000000000000000000000000000000000000000000000080',
81
+ '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',
82
+ 'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
83
+ '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',
84
+ '0000000000000000000000000000000000000000000000000000000000000000',
85
+ 'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
86
+ ];
87
+ const ED25519_DEF = {
88
+ // Param: a
89
+ a: BigInt(-1),
90
+ // Equal to -121665/121666 over finite field.
91
+ // Negative number is P - number, and division is invert(number, P)
92
+ d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
93
+ // Finite field 𝔽p over which we'll do calculations; 2n ** 255n - 19n
94
+ P: ED25519_P,
95
+ // Subgroup order: how many points ed25519 has
96
+ // 2n ** 252n + 27742317777372353535851937790883648493n;
97
+ n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
98
+ // Cofactor
99
+ h: BigInt(8),
100
+ // Base point (x, y) aka generator point
101
+ Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
102
+ Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
103
+ hash: sha512_1.sha512,
104
+ adjustScalarBytes,
105
+ // dom2
106
+ // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
107
+ // Constant-time, u/√v
108
+ uvRatio,
109
+ };
110
+ exports.ed25519 = (0, edwards_1.twistedEdwards)(ED25519_DEF);
111
+ function ed25519_domain(data, ctx, phflag) {
112
+ if (ctx.length > 255)
113
+ throw new Error('Context is too big');
114
+ return (0, utils_1.concatBytes)((0, utils_1.utf8ToBytes)('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
115
+ }
116
+ exports.ed25519ctx = (0, edwards_1.twistedEdwards)({ ...ED25519_DEF, domain: ed25519_domain });
117
+ exports.ed25519ph = (0, edwards_1.twistedEdwards)({
118
+ ...ED25519_DEF,
119
+ domain: ed25519_domain,
120
+ preHash: sha512_1.sha512,
121
+ });
122
+ exports.x25519 = (0, montgomery_1.montgomery)({
123
+ P: ED25519_P,
124
+ a24: BigInt('121665'),
125
+ montgomeryBits: 255,
126
+ nByteLength: 32,
127
+ Gu: '0900000000000000000000000000000000000000000000000000000000000000',
128
+ powPminus2: (x) => {
129
+ const P = ED25519_P;
130
+ // x^(p-2) aka x^(2^255-21)
131
+ const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
132
+ return (0, modular_1.mod)((0, modular_1.pow2)(pow_p_5_8, BigInt(3), P) * b2, P);
133
+ },
134
+ adjustScalarBytes,
135
+ });
136
+ function assertRstPoint(other) {
137
+ if (!(other instanceof RistrettoPoint))
138
+ throw new TypeError('RistrettoPoint expected');
139
+ }
140
+ // √(-1) aka √(a) aka 2^((p-1)/4)
141
+ const SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
142
+ // √(ad - 1)
143
+ const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
144
+ // 1 / √(a-d)
145
+ const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
146
+ // 1-d²
147
+ const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
148
+ // (d-1)²
149
+ const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
150
+ // Calculates 1/√(number)
151
+ const invertSqrt = (number) => uvRatio(_1n, number);
152
+ const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
153
+ const bytes255ToNumberLE = (bytes) => exports.ed25519.utils.mod((0, utils_2.bytesToNumberLE)(bytes) & MAX_255B);
154
+ /**
155
+ * Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
156
+ * a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
157
+ * Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
158
+ * but it should work in its own namespace: do not combine those two.
159
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
160
+ */
161
+ class RistrettoPoint {
162
+ // Private property to discourage combining ExtendedPoint + RistrettoPoint
163
+ // Always use Ristretto encoding/decoding instead.
164
+ constructor(ep) {
165
+ this.ep = ep;
166
+ }
167
+ // Computes Elligator map for Ristretto
168
+ // https://ristretto.group/formulas/elligator.html
169
+ static calcElligatorRistrettoMap(r0) {
170
+ const { d, P } = exports.ed25519.CURVE;
171
+ const { mod } = exports.ed25519.utils;
172
+ const r = mod(SQRT_M1 * r0 * r0); // 1
173
+ const Ns = mod((r + _1n) * ONE_MINUS_D_SQ); // 2
174
+ let c = BigInt(-1); // 3
175
+ const D = mod((c - d * r) * mod(r + d)); // 4
176
+ let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D); // 5
177
+ let s_ = mod(s * r0); // 6
178
+ if (!(0, modular_1.isNegativeLE)(s_, P))
179
+ s_ = mod(-s_);
180
+ if (!Ns_D_is_sq)
181
+ s = s_; // 7
182
+ if (!Ns_D_is_sq)
183
+ c = r; // 8
184
+ const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D); // 9
185
+ const s2 = s * s;
186
+ const W0 = mod((s + s) * D); // 10
187
+ const W1 = mod(Nt * SQRT_AD_MINUS_ONE); // 11
188
+ const W2 = mod(_1n - s2); // 12
189
+ const W3 = mod(_1n + s2); // 13
190
+ return new exports.ed25519.ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
191
+ }
192
+ /**
193
+ * Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
194
+ * The hash-to-group operation applies Elligator twice and adds the results.
195
+ * **Note:** this is one-way map, there is no conversion from point to hash.
196
+ * https://ristretto.group/formulas/elligator.html
197
+ * @param hex 64-bit output of a hash function
198
+ */
199
+ static hashToCurve(hex) {
200
+ hex = (0, utils_2.ensureBytes)(hex, 64);
201
+ const r1 = bytes255ToNumberLE(hex.slice(0, 32));
202
+ const R1 = this.calcElligatorRistrettoMap(r1);
203
+ const r2 = bytes255ToNumberLE(hex.slice(32, 64));
204
+ const R2 = this.calcElligatorRistrettoMap(r2);
205
+ return new RistrettoPoint(R1.add(R2));
206
+ }
207
+ /**
208
+ * Converts ristretto-encoded string to ristretto point.
209
+ * https://ristretto.group/formulas/decoding.html
210
+ * @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
211
+ */
212
+ static fromHex(hex) {
213
+ hex = (0, utils_2.ensureBytes)(hex, 32);
214
+ const { a, d, P } = exports.ed25519.CURVE;
215
+ const { mod } = exports.ed25519.utils;
216
+ const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
217
+ const s = bytes255ToNumberLE(hex);
218
+ // 1. Check that s_bytes is the canonical encoding of a field element, or else abort.
219
+ // 3. Check that s is non-negative, or else abort
220
+ if (!(0, utils_2.equalBytes)((0, utils_2.numberToBytesLE)(s, 32), hex) || (0, modular_1.isNegativeLE)(s, P))
221
+ throw new Error(emsg);
222
+ const s2 = mod(s * s);
223
+ const u1 = mod(_1n + a * s2); // 4 (a is -1)
224
+ const u2 = mod(_1n - a * s2); // 5
225
+ const u1_2 = mod(u1 * u1);
226
+ const u2_2 = mod(u2 * u2);
227
+ const v = mod(a * d * u1_2 - u2_2); // 6
228
+ const { isValid, value: I } = invertSqrt(mod(v * u2_2)); // 7
229
+ const Dx = mod(I * u2); // 8
230
+ const Dy = mod(I * Dx * v); // 9
231
+ let x = mod((s + s) * Dx); // 10
232
+ if ((0, modular_1.isNegativeLE)(x, P))
233
+ x = mod(-x); // 10
234
+ const y = mod(u1 * Dy); // 11
235
+ const t = mod(x * y); // 12
236
+ if (!isValid || (0, modular_1.isNegativeLE)(t, P) || y === _0n)
237
+ throw new Error(emsg);
238
+ return new RistrettoPoint(new exports.ed25519.ExtendedPoint(x, y, _1n, t));
239
+ }
240
+ /**
241
+ * Encodes ristretto point to Uint8Array.
242
+ * https://ristretto.group/formulas/encoding.html
243
+ */
244
+ toRawBytes() {
245
+ let { x, y, z, t } = this.ep;
246
+ const { P } = exports.ed25519.CURVE;
247
+ const { mod } = exports.ed25519.utils;
248
+ const u1 = mod(mod(z + y) * mod(z - y)); // 1
249
+ const u2 = mod(x * y); // 2
250
+ // Square root always exists
251
+ const u2sq = mod(u2 * u2);
252
+ const { value: invsqrt } = invertSqrt(mod(u1 * u2sq)); // 3
253
+ const D1 = mod(invsqrt * u1); // 4
254
+ const D2 = mod(invsqrt * u2); // 5
255
+ const zInv = mod(D1 * D2 * t); // 6
256
+ let D; // 7
257
+ if ((0, modular_1.isNegativeLE)(t * zInv, P)) {
258
+ let _x = mod(y * SQRT_M1);
259
+ let _y = mod(x * SQRT_M1);
260
+ x = _x;
261
+ y = _y;
262
+ D = mod(D1 * INVSQRT_A_MINUS_D);
263
+ }
264
+ else {
265
+ D = D2; // 8
266
+ }
267
+ if ((0, modular_1.isNegativeLE)(x * zInv, P))
268
+ y = mod(-y); // 9
269
+ let s = mod((z - y) * D); // 10 (check footer's note, no sqrt(-a))
270
+ if ((0, modular_1.isNegativeLE)(s, P))
271
+ s = mod(-s);
272
+ return (0, utils_2.numberToBytesLE)(s, 32); // 11
273
+ }
274
+ toHex() {
275
+ return (0, utils_2.bytesToHex)(this.toRawBytes());
276
+ }
277
+ toString() {
278
+ return this.toHex();
279
+ }
280
+ // Compare one point to another.
281
+ equals(other) {
282
+ assertRstPoint(other);
283
+ const a = this.ep;
284
+ const b = other.ep;
285
+ const { mod } = exports.ed25519.utils;
286
+ // (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)
287
+ const one = mod(a.x * b.y) === mod(a.y * b.x);
288
+ const two = mod(a.y * b.y) === mod(a.x * b.x);
289
+ return one || two;
290
+ }
291
+ add(other) {
292
+ assertRstPoint(other);
293
+ return new RistrettoPoint(this.ep.add(other.ep));
294
+ }
295
+ subtract(other) {
296
+ assertRstPoint(other);
297
+ return new RistrettoPoint(this.ep.subtract(other.ep));
298
+ }
299
+ multiply(scalar) {
300
+ return new RistrettoPoint(this.ep.multiply(scalar));
301
+ }
302
+ multiplyUnsafe(scalar) {
303
+ return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
304
+ }
305
+ }
306
+ exports.RistrettoPoint = RistrettoPoint;
307
+ RistrettoPoint.BASE = new RistrettoPoint(exports.ed25519.ExtendedPoint.BASE);
308
+ RistrettoPoint.ZERO = new RistrettoPoint(exports.ed25519.ExtendedPoint.ZERO);
@@ -0,0 +1,3 @@
1
+ export declare const ed448: import("../edwards").CurveFn;
2
+ export declare const ed448ph: import("../edwards").CurveFn;
3
+ export declare const x448: import("../montgomery").CurveFn;