@noble/curves 1.9.1 → 1.9.3

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 (223) hide show
  1. package/README.md +238 -227
  2. package/_shortw_utils.d.ts +8 -5
  3. package/_shortw_utils.d.ts.map +1 -1
  4. package/_shortw_utils.js +3 -8
  5. package/_shortw_utils.js.map +1 -1
  6. package/abstract/bls.d.ts +123 -62
  7. package/abstract/bls.d.ts.map +1 -1
  8. package/abstract/bls.js +219 -163
  9. package/abstract/bls.js.map +1 -1
  10. package/abstract/curve.d.ts +142 -21
  11. package/abstract/curve.d.ts.map +1 -1
  12. package/abstract/curve.js +224 -143
  13. package/abstract/curve.js.map +1 -1
  14. package/abstract/edwards.d.ts +190 -49
  15. package/abstract/edwards.d.ts.map +1 -1
  16. package/abstract/edwards.js +322 -136
  17. package/abstract/edwards.js.map +1 -1
  18. package/abstract/fft.d.ts +12 -10
  19. package/abstract/fft.d.ts.map +1 -1
  20. package/abstract/fft.js +12 -13
  21. package/abstract/fft.js.map +1 -1
  22. package/abstract/hash-to-curve.d.ts +31 -13
  23. package/abstract/hash-to-curve.d.ts.map +1 -1
  24. package/abstract/hash-to-curve.js +34 -19
  25. package/abstract/hash-to-curve.js.map +1 -1
  26. package/abstract/modular.d.ts +31 -13
  27. package/abstract/modular.d.ts.map +1 -1
  28. package/abstract/modular.js +125 -52
  29. package/abstract/modular.js.map +1 -1
  30. package/abstract/montgomery.d.ts +18 -5
  31. package/abstract/montgomery.d.ts.map +1 -1
  32. package/abstract/montgomery.js +23 -6
  33. package/abstract/montgomery.js.map +1 -1
  34. package/abstract/poseidon.d.ts +5 -13
  35. package/abstract/poseidon.d.ts.map +1 -1
  36. package/abstract/poseidon.js +12 -7
  37. package/abstract/poseidon.js.map +1 -1
  38. package/abstract/tower.d.ts +23 -49
  39. package/abstract/tower.d.ts.map +1 -1
  40. package/abstract/tower.js +9 -3
  41. package/abstract/tower.js.map +1 -1
  42. package/abstract/utils.d.ts +1 -115
  43. package/abstract/utils.d.ts.map +1 -1
  44. package/abstract/utils.js +17 -371
  45. package/abstract/utils.js.map +1 -1
  46. package/abstract/weierstrass.d.ts +206 -124
  47. package/abstract/weierstrass.d.ts.map +1 -1
  48. package/abstract/weierstrass.js +747 -604
  49. package/abstract/weierstrass.js.map +1 -1
  50. package/bls12-381.d.ts +2 -0
  51. package/bls12-381.d.ts.map +1 -1
  52. package/bls12-381.js +504 -466
  53. package/bls12-381.js.map +1 -1
  54. package/bn254.d.ts +2 -0
  55. package/bn254.d.ts.map +1 -1
  56. package/bn254.js +44 -32
  57. package/bn254.js.map +1 -1
  58. package/ed25519.d.ts +55 -66
  59. package/ed25519.d.ts.map +1 -1
  60. package/ed25519.js +172 -186
  61. package/ed25519.js.map +1 -1
  62. package/ed448.d.ts +60 -57
  63. package/ed448.d.ts.map +1 -1
  64. package/ed448.js +172 -166
  65. package/ed448.js.map +1 -1
  66. package/esm/_shortw_utils.d.ts +8 -5
  67. package/esm/_shortw_utils.d.ts.map +1 -1
  68. package/esm/_shortw_utils.js +3 -8
  69. package/esm/_shortw_utils.js.map +1 -1
  70. package/esm/abstract/bls.d.ts +123 -62
  71. package/esm/abstract/bls.d.ts.map +1 -1
  72. package/esm/abstract/bls.js +220 -164
  73. package/esm/abstract/bls.js.map +1 -1
  74. package/esm/abstract/curve.d.ts +142 -21
  75. package/esm/abstract/curve.d.ts.map +1 -1
  76. package/esm/abstract/curve.js +219 -143
  77. package/esm/abstract/curve.js.map +1 -1
  78. package/esm/abstract/edwards.d.ts +190 -49
  79. package/esm/abstract/edwards.d.ts.map +1 -1
  80. package/esm/abstract/edwards.js +320 -138
  81. package/esm/abstract/edwards.js.map +1 -1
  82. package/esm/abstract/fft.d.ts +12 -10
  83. package/esm/abstract/fft.d.ts.map +1 -1
  84. package/esm/abstract/fft.js +10 -11
  85. package/esm/abstract/fft.js.map +1 -1
  86. package/esm/abstract/hash-to-curve.d.ts +31 -13
  87. package/esm/abstract/hash-to-curve.d.ts.map +1 -1
  88. package/esm/abstract/hash-to-curve.js +33 -19
  89. package/esm/abstract/hash-to-curve.js.map +1 -1
  90. package/esm/abstract/modular.d.ts +31 -13
  91. package/esm/abstract/modular.d.ts.map +1 -1
  92. package/esm/abstract/modular.js +124 -51
  93. package/esm/abstract/modular.js.map +1 -1
  94. package/esm/abstract/montgomery.d.ts +18 -5
  95. package/esm/abstract/montgomery.d.ts.map +1 -1
  96. package/esm/abstract/montgomery.js +23 -6
  97. package/esm/abstract/montgomery.js.map +1 -1
  98. package/esm/abstract/poseidon.d.ts +5 -13
  99. package/esm/abstract/poseidon.d.ts.map +1 -1
  100. package/esm/abstract/poseidon.js +12 -7
  101. package/esm/abstract/poseidon.js.map +1 -1
  102. package/esm/abstract/tower.d.ts +23 -49
  103. package/esm/abstract/tower.d.ts.map +1 -1
  104. package/esm/abstract/tower.js +9 -3
  105. package/esm/abstract/tower.js.map +1 -1
  106. package/esm/abstract/utils.d.ts +1 -115
  107. package/esm/abstract/utils.d.ts.map +1 -1
  108. package/esm/abstract/utils.js +3 -344
  109. package/esm/abstract/utils.js.map +1 -1
  110. package/esm/abstract/weierstrass.d.ts +206 -124
  111. package/esm/abstract/weierstrass.d.ts.map +1 -1
  112. package/esm/abstract/weierstrass.js +743 -605
  113. package/esm/abstract/weierstrass.js.map +1 -1
  114. package/esm/bls12-381.d.ts +2 -0
  115. package/esm/bls12-381.d.ts.map +1 -1
  116. package/esm/bls12-381.js +503 -465
  117. package/esm/bls12-381.js.map +1 -1
  118. package/esm/bn254.d.ts +2 -0
  119. package/esm/bn254.d.ts.map +1 -1
  120. package/esm/bn254.js +41 -29
  121. package/esm/bn254.js.map +1 -1
  122. package/esm/ed25519.d.ts +55 -66
  123. package/esm/ed25519.d.ts.map +1 -1
  124. package/esm/ed25519.js +170 -183
  125. package/esm/ed25519.js.map +1 -1
  126. package/esm/ed448.d.ts +60 -57
  127. package/esm/ed448.d.ts.map +1 -1
  128. package/esm/ed448.js +169 -162
  129. package/esm/ed448.js.map +1 -1
  130. package/esm/index.js +7 -9
  131. package/esm/index.js.map +1 -1
  132. package/esm/jubjub.d.ts +3 -3
  133. package/esm/jubjub.d.ts.map +1 -1
  134. package/esm/jubjub.js +3 -3
  135. package/esm/jubjub.js.map +1 -1
  136. package/esm/misc.d.ts +3 -5
  137. package/esm/misc.d.ts.map +1 -1
  138. package/esm/misc.js +31 -29
  139. package/esm/misc.js.map +1 -1
  140. package/esm/nist.d.ts +7 -22
  141. package/esm/nist.d.ts.map +1 -1
  142. package/esm/nist.js +106 -101
  143. package/esm/nist.js.map +1 -1
  144. package/esm/p256.d.ts +7 -3
  145. package/esm/p256.d.ts.map +1 -1
  146. package/esm/p256.js +4 -0
  147. package/esm/p256.js.map +1 -1
  148. package/esm/p384.d.ts +7 -4
  149. package/esm/p384.d.ts.map +1 -1
  150. package/esm/p384.js +4 -1
  151. package/esm/p384.js.map +1 -1
  152. package/esm/p521.d.ts +7 -3
  153. package/esm/p521.d.ts.map +1 -1
  154. package/esm/p521.js +4 -0
  155. package/esm/p521.js.map +1 -1
  156. package/esm/secp256k1.d.ts +38 -21
  157. package/esm/secp256k1.d.ts.map +1 -1
  158. package/esm/secp256k1.js +112 -104
  159. package/esm/secp256k1.js.map +1 -1
  160. package/esm/utils.d.ts +96 -0
  161. package/esm/utils.d.ts.map +1 -0
  162. package/esm/utils.js +279 -0
  163. package/esm/utils.js.map +1 -0
  164. package/index.js +7 -9
  165. package/index.js.map +1 -1
  166. package/jubjub.d.ts +3 -3
  167. package/jubjub.d.ts.map +1 -1
  168. package/jubjub.js +3 -3
  169. package/jubjub.js.map +1 -1
  170. package/misc.d.ts +3 -5
  171. package/misc.d.ts.map +1 -1
  172. package/misc.js +35 -33
  173. package/misc.js.map +1 -1
  174. package/nist.d.ts +7 -22
  175. package/nist.d.ts.map +1 -1
  176. package/nist.js +106 -101
  177. package/nist.js.map +1 -1
  178. package/p256.d.ts +7 -3
  179. package/p256.d.ts.map +1 -1
  180. package/p256.js +4 -0
  181. package/p256.js.map +1 -1
  182. package/p384.d.ts +7 -4
  183. package/p384.d.ts.map +1 -1
  184. package/p384.js +4 -1
  185. package/p384.js.map +1 -1
  186. package/p521.d.ts +7 -3
  187. package/p521.d.ts.map +1 -1
  188. package/p521.js +4 -0
  189. package/p521.js.map +1 -1
  190. package/package.json +17 -6
  191. package/secp256k1.d.ts +38 -21
  192. package/secp256k1.d.ts.map +1 -1
  193. package/secp256k1.js +112 -104
  194. package/secp256k1.js.map +1 -1
  195. package/src/_shortw_utils.ts +6 -15
  196. package/src/abstract/bls.ts +428 -251
  197. package/src/abstract/curve.ts +307 -149
  198. package/src/abstract/edwards.ts +555 -203
  199. package/src/abstract/fft.ts +30 -19
  200. package/src/abstract/hash-to-curve.ts +75 -34
  201. package/src/abstract/modular.ts +131 -59
  202. package/src/abstract/montgomery.ts +44 -15
  203. package/src/abstract/poseidon.ts +22 -18
  204. package/src/abstract/tower.ts +40 -71
  205. package/src/abstract/utils.ts +3 -378
  206. package/src/abstract/weierstrass.ts +1086 -746
  207. package/src/bls12-381.ts +549 -490
  208. package/src/bn254.ts +47 -35
  209. package/src/ed25519.ts +214 -216
  210. package/src/ed448.ts +251 -220
  211. package/src/index.ts +7 -9
  212. package/src/jubjub.ts +3 -3
  213. package/src/misc.ts +41 -40
  214. package/src/nist.ts +161 -126
  215. package/src/p256.ts +7 -3
  216. package/src/p384.ts +7 -5
  217. package/src/p521.ts +7 -3
  218. package/src/secp256k1.ts +145 -115
  219. package/src/utils.ts +328 -0
  220. package/utils.d.ts +96 -0
  221. package/utils.d.ts.map +1 -0
  222. package/utils.js +313 -0
  223. package/utils.js.map +1 -0
@@ -1,89 +1,61 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrimeEdwardsPoint = void 0;
4
+ exports.edwards = edwards;
5
+ exports.eddsa = eddsa;
3
6
  exports.twistedEdwards = twistedEdwards;
4
7
  /**
5
8
  * Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y².
6
9
  * For design rationale of types / exports, see weierstrass module documentation.
10
+ * Untwisted Edwards curves exist, but they aren't used in real-world protocols.
7
11
  * @module
8
12
  */
9
13
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
10
- // prettier-ignore
14
+ const utils_ts_1 = require("../utils.js");
11
15
  const curve_ts_1 = require("./curve.js");
12
16
  const modular_ts_1 = require("./modular.js");
13
- // prettier-ignore
14
- const utils_ts_1 = require("./utils.js");
15
17
  // Be friendly to bad ECMAScript parsers by not using bigint literals
16
18
  // prettier-ignore
17
19
  const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _8n = BigInt(8);
18
- // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
19
- const VERIFY_DEFAULT = { zip215: true };
20
- function validateOpts(curve) {
21
- const opts = (0, curve_ts_1.validateBasic)(curve);
22
- (0, utils_ts_1.validateObject)(curve, {
23
- hash: 'function',
24
- a: 'bigint',
25
- d: 'bigint',
26
- randomBytes: 'function',
27
- }, {
28
- adjustScalarBytes: 'function',
29
- domain: 'function',
30
- uvRatio: 'function',
31
- mapToCurve: 'function',
32
- });
33
- // Set defaults
34
- return Object.freeze({ ...opts });
20
+ function isEdValidXY(Fp, CURVE, x, y) {
21
+ const x2 = Fp.sqr(x);
22
+ const y2 = Fp.sqr(y);
23
+ const left = Fp.add(Fp.mul(CURVE.a, x2), y2);
24
+ const right = Fp.add(Fp.ONE, Fp.mul(CURVE.d, Fp.mul(x2, y2)));
25
+ return Fp.eql(left, right);
35
26
  }
36
- /**
37
- * Creates Twisted Edwards curve with EdDSA signatures.
38
- * @example
39
- * import { Field } from '@noble/curves/abstract/modular';
40
- * // Before that, define BigInt-s: a, d, p, n, Gx, Gy, h
41
- * const curve = twistedEdwards({ a, d, Fp: Field(p), n, Gx, Gy, h })
42
- */
43
- function twistedEdwards(curveDef) {
44
- const CURVE = validateOpts(curveDef);
45
- const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
27
+ function edwards(CURVE, curveOpts = {}) {
28
+ const { Fp, Fn } = (0, curve_ts_1._createCurveFields)('edwards', CURVE, curveOpts);
29
+ const { h: cofactor, n: CURVE_ORDER } = CURVE;
30
+ (0, utils_ts_1._validateObject)(curveOpts, {}, { uvRatio: 'function' });
46
31
  // Important:
47
32
  // There are some places where Fp.BYTES is used instead of nByteLength.
48
33
  // So far, everything has been tested with curves of Fp.BYTES == nByteLength.
49
34
  // TODO: test and find curves which behave otherwise.
50
- const MASK = _2n << (BigInt(nByteLength * 8) - _1n);
51
- const modP = Fp.create; // Function overrides
52
- const Fn = (0, modular_ts_1.Field)(CURVE.n, CURVE.nBitLength);
53
- function isEdValidXY(x, y) {
54
- const x2 = Fp.sqr(x);
55
- const y2 = Fp.sqr(y);
56
- const left = Fp.add(Fp.mul(CURVE.a, x2), y2);
57
- const right = Fp.add(Fp.ONE, Fp.mul(CURVE.d, Fp.mul(x2, y2)));
58
- return Fp.eql(left, right);
59
- }
60
- // Validate whether the passed curve params are valid.
61
- // equation ax² + y² = 1 + dx²y² should work for generator point.
62
- if (!isEdValidXY(CURVE.Gx, CURVE.Gy))
63
- throw new Error('bad curve params: generator point');
35
+ const MASK = _2n << (BigInt(Fn.BYTES * 8) - _1n);
36
+ const modP = (n) => Fp.create(n); // Function overrides
64
37
  // sqrt(u/v)
65
- const uvRatio = CURVE.uvRatio ||
38
+ const uvRatio = curveOpts.uvRatio ||
66
39
  ((u, v) => {
67
40
  try {
68
- return { isValid: true, value: Fp.sqrt(u * Fp.inv(v)) };
41
+ return { isValid: true, value: Fp.sqrt(Fp.div(u, v)) };
69
42
  }
70
43
  catch (e) {
71
44
  return { isValid: false, value: _0n };
72
45
  }
73
46
  });
74
- const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
75
- const domain = CURVE.domain ||
76
- ((data, ctx, phflag) => {
77
- (0, utils_ts_1.abool)('phflag', phflag);
78
- if (ctx.length || phflag)
79
- throw new Error('Contexts/pre-hash are not supported');
80
- return data;
81
- }); // NOOP
82
- // 0 <= n < MASK
83
- // Coordinates larger than Fp.ORDER are allowed for zip215
84
- function aCoordinate(title, n, banZero = false) {
47
+ // Validate whether the passed curve params are valid.
48
+ // equation ax² + y² = 1 + dx²y² should work for generator point.
49
+ if (!isEdValidXY(Fp, CURVE, CURVE.Gx, CURVE.Gy))
50
+ throw new Error('bad curve params: generator point');
51
+ /**
52
+ * Asserts coordinate is valid: 0 <= n < MASK.
53
+ * Coordinates >= Fp.ORDER are allowed for zip215.
54
+ */
55
+ function acoord(title, n, banZero = false) {
85
56
  const min = banZero ? _1n : _0n;
86
57
  (0, utils_ts_1.aInRange)('coordinate ' + title, n, min, MASK);
58
+ return n;
87
59
  }
88
60
  function aextpoint(other) {
89
61
  if (!(other instanceof Point))
@@ -92,18 +64,18 @@ function twistedEdwards(curveDef) {
92
64
  // Converts Extended point to default (x, y) coordinates.
93
65
  // Can accept precomputed Z^-1 - for example, from invertBatch.
94
66
  const toAffineMemo = (0, utils_ts_1.memoized)((p, iz) => {
95
- const { ex: x, ey: y, ez: z } = p;
67
+ const { X, Y, Z } = p;
96
68
  const is0 = p.is0();
97
69
  if (iz == null)
98
- iz = is0 ? _8n : Fp.inv(z); // 8 was chosen arbitrarily
99
- const ax = modP(x * iz);
100
- const ay = modP(y * iz);
101
- const zz = modP(z * iz);
70
+ iz = is0 ? _8n : Fp.inv(Z); // 8 was chosen arbitrarily
71
+ const x = modP(X * iz);
72
+ const y = modP(Y * iz);
73
+ const zz = Fp.mul(Z, iz);
102
74
  if (is0)
103
75
  return { x: _0n, y: _1n };
104
76
  if (zz !== _1n)
105
77
  throw new Error('invZ was invalid');
106
- return { x: ax, y: ay };
78
+ return { x, y };
107
79
  });
108
80
  const assertValidMemo = (0, utils_ts_1.memoized)((p) => {
109
81
  const { a, d } = CURVE;
@@ -111,7 +83,7 @@ function twistedEdwards(curveDef) {
111
83
  throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
112
84
  // Equation in affine coordinates: ax² + y² = 1 + dx²y²
113
85
  // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
114
- const { ex: X, ey: Y, ez: Z, et: T } = p;
86
+ const { X, Y, Z, T } = p;
115
87
  const X2 = modP(X * X); // X²
116
88
  const Y2 = modP(Y * Y); // Y²
117
89
  const Z2 = modP(Z * Z); // Z²
@@ -131,15 +103,11 @@ function twistedEdwards(curveDef) {
131
103
  // Extended Point works in extended coordinates: (X, Y, Z, T) ∋ (x=X/Z, y=Y/Z, T=xy).
132
104
  // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
133
105
  class Point {
134
- constructor(ex, ey, ez, et) {
135
- aCoordinate('x', ex);
136
- aCoordinate('y', ey);
137
- aCoordinate('z', ez, true);
138
- aCoordinate('t', et);
139
- this.ex = ex;
140
- this.ey = ey;
141
- this.ez = ez;
142
- this.et = et;
106
+ constructor(X, Y, Z, T) {
107
+ this.X = acoord('x', X);
108
+ this.Y = acoord('y', Y);
109
+ this.Z = acoord('z', Z, true);
110
+ this.T = acoord('t', T);
143
111
  Object.freeze(this);
144
112
  }
145
113
  get x() {
@@ -148,36 +116,51 @@ function twistedEdwards(curveDef) {
148
116
  get y() {
149
117
  return this.toAffine().y;
150
118
  }
151
- static fromAffine(p) {
152
- if (p instanceof Point)
153
- throw new Error('extended point not allowed');
154
- const { x, y } = p || {};
155
- aCoordinate('x', x);
156
- aCoordinate('y', y);
157
- return new Point(x, y, _1n, modP(x * y));
119
+ // TODO: remove
120
+ get ex() {
121
+ return this.X;
122
+ }
123
+ get ey() {
124
+ return this.Y;
125
+ }
126
+ get ez() {
127
+ return this.Z;
128
+ }
129
+ get et() {
130
+ return this.T;
158
131
  }
159
132
  static normalizeZ(points) {
160
- const toInv = (0, modular_ts_1.FpInvertBatch)(Fp, points.map((p) => p.ez));
161
- return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
133
+ return (0, curve_ts_1.normalizeZ)(Point, points);
162
134
  }
163
- // Multiscalar Multiplication
164
135
  static msm(points, scalars) {
165
136
  return (0, curve_ts_1.pippenger)(Point, Fn, points, scalars);
166
137
  }
167
- // "Private method", don't use it directly
168
138
  _setWindowSize(windowSize) {
169
- wnaf.setWindowSize(this, windowSize);
139
+ this.precompute(windowSize);
140
+ }
141
+ static fromAffine(p) {
142
+ if (p instanceof Point)
143
+ throw new Error('extended point not allowed');
144
+ const { x, y } = p || {};
145
+ acoord('x', x);
146
+ acoord('y', y);
147
+ return new Point(x, y, _1n, modP(x * y));
170
148
  }
171
- // Not required for fromHex(), which always creates valid points.
172
- // Could be useful for fromAffine().
149
+ precompute(windowSize = 8, isLazy = true) {
150
+ wnaf.createCache(this, windowSize);
151
+ if (!isLazy)
152
+ this.multiply(_2n); // random number
153
+ return this;
154
+ }
155
+ // Useful in fromAffine() - not for fromBytes(), which always created valid points.
173
156
  assertValidity() {
174
157
  assertValidMemo(this);
175
158
  }
176
159
  // Compare one point to another.
177
160
  equals(other) {
178
161
  aextpoint(other);
179
- const { ex: X1, ey: Y1, ez: Z1 } = this;
180
- const { ex: X2, ey: Y2, ez: Z2 } = other;
162
+ const { X: X1, Y: Y1, Z: Z1 } = this;
163
+ const { X: X2, Y: Y2, Z: Z2 } = other;
181
164
  const X1Z2 = modP(X1 * Z2);
182
165
  const X2Z1 = modP(X2 * Z1);
183
166
  const Y1Z2 = modP(Y1 * Z2);
@@ -189,14 +172,14 @@ function twistedEdwards(curveDef) {
189
172
  }
190
173
  negate() {
191
174
  // Flips point sign to a negative one (-x, y in affine coords)
192
- return new Point(modP(-this.ex), this.ey, this.ez, modP(-this.et));
175
+ return new Point(modP(-this.X), this.Y, this.Z, modP(-this.T));
193
176
  }
194
177
  // Fast algo for doubling Extended Point.
195
178
  // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
196
179
  // Cost: 4M + 4S + 1*a + 6add + 1*2.
197
180
  double() {
198
181
  const { a } = CURVE;
199
- const { ex: X1, ey: Y1, ez: Z1 } = this;
182
+ const { X: X1, Y: Y1, Z: Z1 } = this;
200
183
  const A = modP(X1 * X1); // A = X12
201
184
  const B = modP(Y1 * Y1); // B = Y12
202
185
  const C = modP(_2n * modP(Z1 * Z1)); // C = 2*Z12
@@ -218,8 +201,8 @@ function twistedEdwards(curveDef) {
218
201
  add(other) {
219
202
  aextpoint(other);
220
203
  const { a, d } = CURVE;
221
- const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
222
- const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
204
+ const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;
205
+ const { X: X2, Y: Y2, Z: Z2, T: T2 } = other;
223
206
  const A = modP(X1 * X2); // A = X1*X2
224
207
  const B = modP(Y1 * Y2); // B = Y1*Y2
225
208
  const C = modP(T1 * d * T2); // C = T1*d*T2
@@ -237,15 +220,12 @@ function twistedEdwards(curveDef) {
237
220
  subtract(other) {
238
221
  return this.add(other.negate());
239
222
  }
240
- wNAF(n) {
241
- return wnaf.wNAFCached(this, n, Point.normalizeZ);
242
- }
243
223
  // Constant-time multiplication.
244
224
  multiply(scalar) {
245
225
  const n = scalar;
246
226
  (0, utils_ts_1.aInRange)('scalar', n, _1n, CURVE_ORDER); // 1 <= scalar < L
247
- const { p, f } = this.wNAF(n);
248
- return Point.normalizeZ([p, f])[0];
227
+ const { p, f } = wnaf.cached(this, n, (p) => (0, curve_ts_1.normalizeZ)(Point, p));
228
+ return (0, curve_ts_1.normalizeZ)(Point, [p, f])[0];
249
229
  }
250
230
  // Non-constant-time multiplication. Uses double-and-add algorithm.
251
231
  // It's faster, but should only be used when you don't care about
@@ -256,10 +236,10 @@ function twistedEdwards(curveDef) {
256
236
  const n = scalar;
257
237
  (0, utils_ts_1.aInRange)('scalar', n, _0n, CURVE_ORDER); // 0 <= scalar < L
258
238
  if (n === _0n)
259
- return I;
239
+ return Point.ZERO;
260
240
  if (this.is0() || n === _1n)
261
241
  return this;
262
- return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
242
+ return wnaf.unsafe(this, n, (p) => (0, curve_ts_1.normalizeZ)(Point, p), acc);
263
243
  }
264
244
  // Checks if point is of small order.
265
245
  // If you add something to small order point, you will have "dirty"
@@ -271,19 +251,22 @@ function twistedEdwards(curveDef) {
271
251
  // Multiplies point by curve order and checks if the result is 0.
272
252
  // Returns `false` is the point is dirty.
273
253
  isTorsionFree() {
274
- return wnaf.unsafeLadder(this, CURVE_ORDER).is0();
254
+ return wnaf.unsafe(this, CURVE_ORDER).is0();
275
255
  }
276
256
  // Converts Extended point to default (x, y) coordinates.
277
257
  // Can accept precomputed Z^-1 - for example, from invertBatch.
278
- toAffine(iz) {
279
- return toAffineMemo(this, iz);
258
+ toAffine(invertedZ) {
259
+ return toAffineMemo(this, invertedZ);
280
260
  }
281
261
  clearCofactor() {
282
- const { h: cofactor } = CURVE;
283
262
  if (cofactor === _1n)
284
263
  return this;
285
264
  return this.multiplyUnsafe(cofactor);
286
265
  }
266
+ static fromBytes(bytes, zip215 = false) {
267
+ (0, utils_ts_1.abytes)(bytes);
268
+ return Point.fromHex(bytes, zip215);
269
+ }
287
270
  // Converts hash string or Uint8Array to Point.
288
271
  // Uses algo from RFC8032 5.1.3.
289
272
  static fromHex(hex, zip215 = false) {
@@ -318,31 +301,138 @@ function twistedEdwards(curveDef) {
318
301
  x = modP(-x); // if x_0 != x mod 2, set x = p-x
319
302
  return Point.fromAffine({ x, y });
320
303
  }
321
- static fromPrivateKey(privKey) {
322
- const { scalar } = getPrivateScalar(privKey);
323
- return G.multiply(scalar); // reduced one call of `toRawBytes`
324
- }
325
- toRawBytes() {
304
+ toBytes() {
326
305
  const { x, y } = this.toAffine();
327
306
  const bytes = (0, utils_ts_1.numberToBytesLE)(y, Fp.BYTES); // each y has 2 x values (x, -y)
328
307
  bytes[bytes.length - 1] |= x & _1n ? 0x80 : 0; // when compressing, it's enough to store y
329
308
  return bytes; // and use the last byte to encode sign of x
330
309
  }
310
+ /** @deprecated use `toBytes` */
311
+ toRawBytes() {
312
+ return this.toBytes();
313
+ }
331
314
  toHex() {
332
- return (0, utils_ts_1.bytesToHex)(this.toRawBytes()); // Same as toRawBytes, but returns string.
315
+ return (0, utils_ts_1.bytesToHex)(this.toBytes());
316
+ }
317
+ toString() {
318
+ return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;
333
319
  }
334
320
  }
335
321
  // base / generator point
336
322
  Point.BASE = new Point(CURVE.Gx, CURVE.Gy, _1n, modP(CURVE.Gx * CURVE.Gy));
337
323
  // zero / infinity / identity point
338
324
  Point.ZERO = new Point(_0n, _1n, _1n, _0n); // 0, 1, 1, 0
339
- const { BASE: G, ZERO: I } = Point;
340
- const wnaf = (0, curve_ts_1.wNAF)(Point, nByteLength * 8);
325
+ // fields
326
+ Point.Fp = Fp;
327
+ Point.Fn = Fn;
328
+ const wnaf = new curve_ts_1.wNAF(Point, Fn.BYTES * 8); // Fn.BITS?
329
+ return Point;
330
+ }
331
+ /**
332
+ * Base class for prime-order points like Ristretto255 and Decaf448.
333
+ * These points eliminate cofactor issues by representing equivalence classes
334
+ * of Edwards curve points.
335
+ */
336
+ class PrimeEdwardsPoint {
337
+ constructor(ep) {
338
+ this.ep = ep;
339
+ }
340
+ // Static methods that must be implemented by subclasses
341
+ static fromBytes(_bytes) {
342
+ throw new Error('fromBytes must be implemented by subclass');
343
+ }
344
+ static fromHex(_hex) {
345
+ throw new Error('fromHex must be implemented by subclass');
346
+ }
347
+ get x() {
348
+ return this.toAffine().x;
349
+ }
350
+ get y() {
351
+ return this.toAffine().y;
352
+ }
353
+ // Common implementations
354
+ clearCofactor() {
355
+ // no-op for prime-order groups
356
+ return this;
357
+ }
358
+ assertValidity() {
359
+ this.ep.assertValidity();
360
+ }
361
+ toAffine(invertedZ) {
362
+ return this.ep.toAffine(invertedZ);
363
+ }
364
+ /** @deprecated use `toBytes` */
365
+ toRawBytes() {
366
+ return this.toBytes();
367
+ }
368
+ toHex() {
369
+ return (0, utils_ts_1.bytesToHex)(this.toBytes());
370
+ }
371
+ toString() {
372
+ return this.toHex();
373
+ }
374
+ isTorsionFree() {
375
+ return true;
376
+ }
377
+ isSmallOrder() {
378
+ return false;
379
+ }
380
+ add(other) {
381
+ this.assertSame(other);
382
+ return this.init(this.ep.add(other.ep));
383
+ }
384
+ subtract(other) {
385
+ this.assertSame(other);
386
+ return this.init(this.ep.subtract(other.ep));
387
+ }
388
+ multiply(scalar) {
389
+ return this.init(this.ep.multiply(scalar));
390
+ }
391
+ multiplyUnsafe(scalar) {
392
+ return this.init(this.ep.multiplyUnsafe(scalar));
393
+ }
394
+ double() {
395
+ return this.init(this.ep.double());
396
+ }
397
+ negate() {
398
+ return this.init(this.ep.negate());
399
+ }
400
+ precompute(windowSize, isLazy) {
401
+ return this.init(this.ep.precompute(windowSize, isLazy));
402
+ }
403
+ }
404
+ exports.PrimeEdwardsPoint = PrimeEdwardsPoint;
405
+ /**
406
+ * Initializes EdDSA signatures over given Edwards curve.
407
+ */
408
+ function eddsa(Point, cHash, eddsaOpts) {
409
+ if (typeof cHash !== 'function')
410
+ throw new Error('"hash" function param is required');
411
+ (0, utils_ts_1._validateObject)(eddsaOpts, {}, {
412
+ adjustScalarBytes: 'function',
413
+ randomBytes: 'function',
414
+ domain: 'function',
415
+ prehash: 'function',
416
+ mapToCurve: 'function',
417
+ });
418
+ const { prehash } = eddsaOpts;
419
+ const { BASE: G, Fp, Fn } = Point;
420
+ const CURVE_ORDER = Fn.ORDER;
421
+ const randomBytes_ = eddsaOpts.randomBytes || utils_ts_1.randomBytes;
422
+ const adjustScalarBytes = eddsaOpts.adjustScalarBytes || ((bytes) => bytes); // NOOP
423
+ const domain = eddsaOpts.domain ||
424
+ ((data, ctx, phflag) => {
425
+ (0, utils_ts_1.abool)('phflag', phflag);
426
+ if (ctx.length || phflag)
427
+ throw new Error('Contexts/pre-hash are not supported');
428
+ return data;
429
+ }); // NOOP
341
430
  function modN(a) {
342
- return (0, modular_ts_1.mod)(a, CURVE_ORDER);
431
+ return Fn.create(a);
343
432
  }
344
433
  // Little-endian SHA512 with modulo n
345
434
  function modN_LE(hash) {
435
+ // Not using Fn.fromBytes: hash can be 2*Fn.BYTES
346
436
  return modN((0, utils_ts_1.bytesToNumberLE)(hash));
347
437
  }
348
438
  // Get the hashed private scalar per RFC8032 5.1.5
@@ -357,16 +447,16 @@ function twistedEdwards(curveDef) {
357
447
  const scalar = modN_LE(head); // The actual private scalar
358
448
  return { head, prefix, scalar };
359
449
  }
360
- // Convenience method that creates public key from scalar. RFC8032 5.1.5
361
- function getExtendedPublicKey(key) {
362
- const { head, prefix, scalar } = getPrivateScalar(key);
450
+ /** Convenience method that creates public key from scalar. RFC8032 5.1.5 */
451
+ function getExtendedPublicKey(secretKey) {
452
+ const { head, prefix, scalar } = getPrivateScalar(secretKey);
363
453
  const point = G.multiply(scalar); // Point on Edwards curve aka public key
364
- const pointBytes = point.toRawBytes(); // Uint8Array representation
454
+ const pointBytes = point.toBytes();
365
455
  return { head, prefix, scalar, point, pointBytes };
366
456
  }
367
- // Calculates EdDSA pub key. RFC8032 5.1.5. Privkey is hashed. Use first half with 3 bits cleared
368
- function getPublicKey(privKey) {
369
- return getExtendedPublicKey(privKey).pointBytes;
457
+ /** Calculates EdDSA pub key. RFC8032 5.1.5. */
458
+ function getPublicKey(secretKey) {
459
+ return getExtendedPublicKey(secretKey).pointBytes;
370
460
  }
371
461
  // int('LE', SHA512(dom2(F, C) || msgs)) mod N
372
462
  function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
@@ -374,20 +464,22 @@ function twistedEdwards(curveDef) {
374
464
  return modN_LE(cHash(domain(msg, (0, utils_ts_1.ensureBytes)('context', context), !!prehash)));
375
465
  }
376
466
  /** Signs message with privateKey. RFC8032 5.1.6 */
377
- function sign(msg, privKey, options = {}) {
467
+ function sign(msg, secretKey, options = {}) {
378
468
  msg = (0, utils_ts_1.ensureBytes)('message', msg);
379
469
  if (prehash)
380
470
  msg = prehash(msg); // for ed25519ph etc.
381
- const { prefix, scalar, pointBytes } = getExtendedPublicKey(privKey);
471
+ const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);
382
472
  const r = hashDomainToScalar(options.context, prefix, msg); // r = dom2(F, C) || prefix || PH(M)
383
- const R = G.multiply(r).toRawBytes(); // R = rG
473
+ const R = G.multiply(r).toBytes(); // R = rG
384
474
  const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
385
475
  const s = modN(r + k * scalar); // S = (r + k * s) mod L
386
476
  (0, utils_ts_1.aInRange)('signature.s', s, _0n, CURVE_ORDER); // 0 <= s < l
387
- const res = (0, utils_ts_1.concatBytes)(R, (0, utils_ts_1.numberToBytesLE)(s, Fp.BYTES));
388
- return (0, utils_ts_1.ensureBytes)('result', res, Fp.BYTES * 2); // 64-byte signature
477
+ const L = Fp.BYTES;
478
+ const res = (0, utils_ts_1.concatBytes)(R, (0, utils_ts_1.numberToBytesLE)(s, L));
479
+ return (0, utils_ts_1.ensureBytes)('result', res, L * 2); // 64-byte signature
389
480
  }
390
- const verifyOpts = VERIFY_DEFAULT;
481
+ // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
482
+ const verifyOpts = { zip215: true };
391
483
  /**
392
484
  * Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
393
485
  * An extended group equation is checked.
@@ -417,17 +509,57 @@ function twistedEdwards(curveDef) {
417
509
  }
418
510
  if (!zip215 && A.isSmallOrder())
419
511
  return false;
420
- const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
512
+ const k = hashDomainToScalar(context, R.toBytes(), A.toBytes(), msg);
421
513
  const RkA = R.add(A.multiplyUnsafe(k));
422
514
  // Extended group equation
423
515
  // [8][S]B = [8]R + [8][k]A'
424
- return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
516
+ return RkA.subtract(SB).clearCofactor().is0();
517
+ }
518
+ G.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
519
+ const size = Fp.BYTES;
520
+ const lengths = {
521
+ secret: size,
522
+ public: size,
523
+ signature: 2 * size,
524
+ seed: size,
525
+ };
526
+ function randomSecretKey(seed = randomBytes_(lengths.seed)) {
527
+ return seed;
425
528
  }
426
- G._setWindowSize(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
427
529
  const utils = {
428
530
  getExtendedPublicKey,
429
531
  /** ed25519 priv keys are uniform 32b. No need to check for modulo bias, like in secp256k1. */
430
- randomPrivateKey: () => randomBytes(Fp.BYTES),
532
+ randomSecretKey,
533
+ isValidSecretKey,
534
+ isValidPublicKey,
535
+ randomPrivateKey: randomSecretKey,
536
+ /**
537
+ * Converts ed public key to x public key. Uses formula:
538
+ * - ed25519:
539
+ * - `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
540
+ * - `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
541
+ * - ed448:
542
+ * - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
543
+ * - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
544
+ *
545
+ * There is NO `fromMontgomery`:
546
+ * - There are 2 valid ed25519 points for every x25519, with flipped coordinate
547
+ * - Sometimes there are 0 valid ed25519 points, because x25519 *additionally*
548
+ * accepts inputs on the quadratic twist, which can't be moved to ed25519
549
+ */
550
+ toMontgomery(publicKey) {
551
+ const { y } = Point.fromBytes(publicKey);
552
+ const is25519 = size === 32;
553
+ if (!is25519 && size !== 57)
554
+ throw new Error('only defined for 25519 and 448');
555
+ const u = is25519 ? Fp.div(_1n + y, _1n - y) : Fp.div(y - _1n, y + _1n);
556
+ return Fp.toBytes(u);
557
+ },
558
+ toMontgomeryPriv(privateKey) {
559
+ (0, utils_ts_1.abytes)(privateKey, size);
560
+ const hashed = cHash(privateKey.subarray(0, size));
561
+ return adjustScalarBytes(hashed).subarray(0, size);
562
+ },
431
563
  /**
432
564
  * We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
433
565
  * values. This slows down first getPublicKey() by milliseconds (see Speed section),
@@ -435,18 +567,72 @@ function twistedEdwards(curveDef) {
435
567
  * @param windowSize 2, 4, 8, 16
436
568
  */
437
569
  precompute(windowSize = 8, point = Point.BASE) {
438
- point._setWindowSize(windowSize);
439
- point.multiply(BigInt(3));
440
- return point;
570
+ return point.precompute(windowSize, false);
441
571
  },
442
572
  };
443
- return {
444
- CURVE,
573
+ function keygen(seed) {
574
+ const secretKey = utils.randomSecretKey(seed);
575
+ return { secretKey, publicKey: getPublicKey(secretKey) };
576
+ }
577
+ function isValidSecretKey(key) {
578
+ try {
579
+ return !!Fn.fromBytes(key, false);
580
+ }
581
+ catch (error) {
582
+ return false;
583
+ }
584
+ }
585
+ function isValidPublicKey(key, zip215) {
586
+ try {
587
+ return !!Point.fromBytes(key, zip215);
588
+ }
589
+ catch (error) {
590
+ return false;
591
+ }
592
+ }
593
+ return Object.freeze({
594
+ keygen,
445
595
  getPublicKey,
446
596
  sign,
447
597
  verify,
448
- ExtendedPoint: Point,
449
598
  utils,
599
+ Point,
600
+ info: { type: 'edwards', lengths },
601
+ });
602
+ }
603
+ // TODO: remove
604
+ function _eddsa_legacy_opts_to_new(c) {
605
+ const CURVE = {
606
+ a: c.a,
607
+ d: c.d,
608
+ p: c.Fp.ORDER,
609
+ n: c.n,
610
+ h: c.h,
611
+ Gx: c.Gx,
612
+ Gy: c.Gy,
450
613
  };
614
+ const Fp = c.Fp;
615
+ const Fn = (0, modular_ts_1.Field)(CURVE.n, c.nBitLength, true);
616
+ const curveOpts = { Fp, Fn, uvRatio: c.uvRatio };
617
+ const eddsaOpts = {
618
+ randomBytes: c.randomBytes,
619
+ adjustScalarBytes: c.adjustScalarBytes,
620
+ domain: c.domain,
621
+ prehash: c.prehash,
622
+ mapToCurve: c.mapToCurve,
623
+ };
624
+ return { CURVE, curveOpts, hash: c.hash, eddsaOpts };
625
+ }
626
+ // TODO: remove
627
+ function _eddsa_new_output_to_legacy(c, eddsa) {
628
+ const legacy = Object.assign({}, eddsa, { ExtendedPoint: eddsa.Point, CURVE: c });
629
+ return legacy;
630
+ }
631
+ // TODO: remove. Use eddsa
632
+ function twistedEdwards(c) {
633
+ const { CURVE, curveOpts, hash, eddsaOpts } = _eddsa_legacy_opts_to_new(c);
634
+ const Point = edwards(CURVE, curveOpts);
635
+ const EDDSA = eddsa(Point, hash, eddsaOpts);
636
+ return _eddsa_new_output_to_legacy(c, EDDSA);
451
637
  }
452
638
  //# sourceMappingURL=edwards.js.map