@noble/curves 1.9.2 → 1.9.4

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 (179) hide show
  1. package/README.md +186 -206
  2. package/_shortw_utils.d.ts +1 -0
  3. package/_shortw_utils.d.ts.map +1 -1
  4. package/_shortw_utils.js +1 -0
  5. package/_shortw_utils.js.map +1 -1
  6. package/abstract/bls.d.ts +87 -62
  7. package/abstract/bls.d.ts.map +1 -1
  8. package/abstract/bls.js +170 -163
  9. package/abstract/bls.js.map +1 -1
  10. package/abstract/curve.d.ts +109 -23
  11. package/abstract/curve.d.ts.map +1 -1
  12. package/abstract/curve.js +158 -156
  13. package/abstract/curve.js.map +1 -1
  14. package/abstract/edwards.d.ts +126 -70
  15. package/abstract/edwards.d.ts.map +1 -1
  16. package/abstract/edwards.js +212 -62
  17. package/abstract/edwards.js.map +1 -1
  18. package/abstract/hash-to-curve.d.ts +8 -4
  19. package/abstract/hash-to-curve.d.ts.map +1 -1
  20. package/abstract/hash-to-curve.js +23 -11
  21. package/abstract/hash-to-curve.js.map +1 -1
  22. package/abstract/modular.d.ts +8 -3
  23. package/abstract/modular.d.ts.map +1 -1
  24. package/abstract/modular.js +79 -35
  25. package/abstract/modular.js.map +1 -1
  26. package/abstract/montgomery.d.ts +17 -4
  27. package/abstract/montgomery.d.ts.map +1 -1
  28. package/abstract/montgomery.js +19 -3
  29. package/abstract/montgomery.js.map +1 -1
  30. package/abstract/tower.d.ts +3 -3
  31. package/abstract/tower.d.ts.map +1 -1
  32. package/abstract/tower.js.map +1 -1
  33. package/abstract/weierstrass.d.ts +145 -118
  34. package/abstract/weierstrass.d.ts.map +1 -1
  35. package/abstract/weierstrass.js +415 -336
  36. package/abstract/weierstrass.js.map +1 -1
  37. package/bls12-381.d.ts.map +1 -1
  38. package/bls12-381.js +4 -4
  39. package/bls12-381.js.map +1 -1
  40. package/ed25519.d.ts +52 -66
  41. package/ed25519.d.ts.map +1 -1
  42. package/ed25519.js +128 -155
  43. package/ed25519.js.map +1 -1
  44. package/ed448.d.ts +57 -58
  45. package/ed448.d.ts.map +1 -1
  46. package/ed448.js +114 -131
  47. package/ed448.js.map +1 -1
  48. package/esm/_shortw_utils.d.ts +1 -0
  49. package/esm/_shortw_utils.d.ts.map +1 -1
  50. package/esm/_shortw_utils.js +1 -0
  51. package/esm/_shortw_utils.js.map +1 -1
  52. package/esm/abstract/bls.d.ts +87 -62
  53. package/esm/abstract/bls.d.ts.map +1 -1
  54. package/esm/abstract/bls.js +171 -164
  55. package/esm/abstract/bls.js.map +1 -1
  56. package/esm/abstract/curve.d.ts +109 -23
  57. package/esm/abstract/curve.d.ts.map +1 -1
  58. package/esm/abstract/curve.js +156 -155
  59. package/esm/abstract/curve.js.map +1 -1
  60. package/esm/abstract/edwards.d.ts +126 -70
  61. package/esm/abstract/edwards.d.ts.map +1 -1
  62. package/esm/abstract/edwards.js +210 -62
  63. package/esm/abstract/edwards.js.map +1 -1
  64. package/esm/abstract/hash-to-curve.d.ts +8 -4
  65. package/esm/abstract/hash-to-curve.d.ts.map +1 -1
  66. package/esm/abstract/hash-to-curve.js +22 -11
  67. package/esm/abstract/hash-to-curve.js.map +1 -1
  68. package/esm/abstract/modular.d.ts +8 -3
  69. package/esm/abstract/modular.d.ts.map +1 -1
  70. package/esm/abstract/modular.js +79 -35
  71. package/esm/abstract/modular.js.map +1 -1
  72. package/esm/abstract/montgomery.d.ts +17 -4
  73. package/esm/abstract/montgomery.d.ts.map +1 -1
  74. package/esm/abstract/montgomery.js +19 -3
  75. package/esm/abstract/montgomery.js.map +1 -1
  76. package/esm/abstract/tower.d.ts +3 -3
  77. package/esm/abstract/tower.d.ts.map +1 -1
  78. package/esm/abstract/tower.js.map +1 -1
  79. package/esm/abstract/weierstrass.d.ts +145 -118
  80. package/esm/abstract/weierstrass.d.ts.map +1 -1
  81. package/esm/abstract/weierstrass.js +412 -334
  82. package/esm/abstract/weierstrass.js.map +1 -1
  83. package/esm/bls12-381.d.ts.map +1 -1
  84. package/esm/bls12-381.js +4 -4
  85. package/esm/bls12-381.js.map +1 -1
  86. package/esm/ed25519.d.ts +52 -66
  87. package/esm/ed25519.d.ts.map +1 -1
  88. package/esm/ed25519.js +131 -157
  89. package/esm/ed25519.js.map +1 -1
  90. package/esm/ed448.d.ts +57 -58
  91. package/esm/ed448.d.ts.map +1 -1
  92. package/esm/ed448.js +116 -132
  93. package/esm/ed448.js.map +1 -1
  94. package/esm/index.js +7 -9
  95. package/esm/index.js.map +1 -1
  96. package/esm/jubjub.d.ts +3 -3
  97. package/esm/jubjub.d.ts.map +1 -1
  98. package/esm/jubjub.js +3 -3
  99. package/esm/jubjub.js.map +1 -1
  100. package/esm/misc.d.ts +3 -5
  101. package/esm/misc.d.ts.map +1 -1
  102. package/esm/misc.js +0 -3
  103. package/esm/misc.js.map +1 -1
  104. package/esm/nist.d.ts +0 -6
  105. package/esm/nist.d.ts.map +1 -1
  106. package/esm/nist.js +31 -15
  107. package/esm/nist.js.map +1 -1
  108. package/esm/p256.d.ts +4 -0
  109. package/esm/p256.d.ts.map +1 -1
  110. package/esm/p256.js +4 -0
  111. package/esm/p256.js.map +1 -1
  112. package/esm/p384.d.ts +4 -1
  113. package/esm/p384.d.ts.map +1 -1
  114. package/esm/p384.js +4 -1
  115. package/esm/p384.js.map +1 -1
  116. package/esm/p521.d.ts +4 -0
  117. package/esm/p521.d.ts.map +1 -1
  118. package/esm/p521.js +4 -0
  119. package/esm/p521.js.map +1 -1
  120. package/esm/secp256k1.d.ts +32 -15
  121. package/esm/secp256k1.d.ts.map +1 -1
  122. package/esm/secp256k1.js +72 -67
  123. package/esm/secp256k1.js.map +1 -1
  124. package/esm/utils.d.ts +1 -1
  125. package/esm/utils.js +1 -1
  126. package/index.js +7 -9
  127. package/index.js.map +1 -1
  128. package/jubjub.d.ts +3 -3
  129. package/jubjub.d.ts.map +1 -1
  130. package/jubjub.js +3 -3
  131. package/jubjub.js.map +1 -1
  132. package/misc.d.ts +3 -5
  133. package/misc.d.ts.map +1 -1
  134. package/misc.js +0 -3
  135. package/misc.js.map +1 -1
  136. package/nist.d.ts +0 -6
  137. package/nist.d.ts.map +1 -1
  138. package/nist.js +31 -15
  139. package/nist.js.map +1 -1
  140. package/p256.d.ts +4 -0
  141. package/p256.d.ts.map +1 -1
  142. package/p256.js +4 -0
  143. package/p256.js.map +1 -1
  144. package/p384.d.ts +4 -1
  145. package/p384.d.ts.map +1 -1
  146. package/p384.js +4 -1
  147. package/p384.js.map +1 -1
  148. package/p521.d.ts +4 -0
  149. package/p521.d.ts.map +1 -1
  150. package/p521.js +4 -0
  151. package/p521.js.map +1 -1
  152. package/package.json +4 -2
  153. package/secp256k1.d.ts +32 -15
  154. package/secp256k1.d.ts.map +1 -1
  155. package/secp256k1.js +70 -65
  156. package/secp256k1.js.map +1 -1
  157. package/src/_shortw_utils.ts +1 -0
  158. package/src/abstract/bls.ts +319 -257
  159. package/src/abstract/curve.ts +226 -170
  160. package/src/abstract/edwards.ts +352 -139
  161. package/src/abstract/hash-to-curve.ts +33 -16
  162. package/src/abstract/modular.ts +86 -35
  163. package/src/abstract/montgomery.ts +36 -9
  164. package/src/abstract/tower.ts +4 -4
  165. package/src/abstract/weierstrass.ts +570 -476
  166. package/src/bls12-381.ts +28 -20
  167. package/src/ed25519.ts +161 -179
  168. package/src/ed448.ts +150 -156
  169. package/src/index.ts +7 -9
  170. package/src/jubjub.ts +3 -3
  171. package/src/misc.ts +3 -7
  172. package/src/nist.ts +40 -16
  173. package/src/p256.ts +4 -0
  174. package/src/p384.ts +4 -2
  175. package/src/p521.ts +4 -0
  176. package/src/secp256k1.ts +91 -73
  177. package/src/utils.ts +1 -1
  178. package/utils.d.ts +1 -1
  179. package/utils.js +1 -1
@@ -27,8 +27,9 @@ import {
27
27
  wNAF,
28
28
  type AffinePoint,
29
29
  type BasicCurve,
30
- type Group,
31
- type GroupConstructor,
30
+ type CurveInfo,
31
+ type CurvePoint,
32
+ type CurvePointCons,
32
33
  } from './curve.ts';
33
34
  import { Field, type IField, type NLength } from './modular.ts';
34
35
 
@@ -38,10 +39,11 @@ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _8n = BigInt(8);
38
39
 
39
40
  export type UVRatio = (u: bigint, v: bigint) => { isValid: boolean; value: bigint };
40
41
 
41
- /** Edwards curves must declare params a & d. */
42
+ // TODO: remove
42
43
  export type CurveType = BasicCurve<bigint> & {
43
44
  a: bigint; // curve param a
44
45
  d: bigint; // curve param d
46
+ /** @deprecated the property will be removed in next release */
45
47
  hash: FHash; // Hashing
46
48
  randomBytes?: (bytesLength?: number) => Uint8Array; // CSPRNG
47
49
  adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array; // clears bits to get valid field elemtn
@@ -51,45 +53,45 @@ export type CurveType = BasicCurve<bigint> & {
51
53
  mapToCurve?: (scalar: bigint[]) => AffinePoint<bigint>; // for hash-to-curve standard
52
54
  };
53
55
 
56
+ // TODO: remove
54
57
  export type CurveTypeWithLength = Readonly<CurveType & Partial<NLength>>;
55
58
 
56
- // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
57
- const VERIFY_DEFAULT = { zip215: true };
58
-
59
59
  /** Instance of Extended Point with coordinates in X, Y, Z, T. */
60
- export interface ExtPointType extends Group<ExtPointType> {
61
- readonly ex: bigint;
62
- readonly ey: bigint;
63
- readonly ez: bigint;
64
- readonly et: bigint;
65
- get x(): bigint;
66
- get y(): bigint;
67
- assertValidity(): void;
68
- multiply(scalar: bigint): ExtPointType;
69
- multiplyUnsafe(scalar: bigint): ExtPointType;
70
- is0(): boolean;
71
- isSmallOrder(): boolean;
72
- isTorsionFree(): boolean;
73
- clearCofactor(): ExtPointType;
74
- toAffine(iz?: bigint): AffinePoint<bigint>;
75
- toBytes(): Uint8Array;
60
+ export interface EdwardsPoint extends CurvePoint<bigint, EdwardsPoint> {
61
+ /** extended X coordinate. Different from affine x. */
62
+ readonly X: bigint;
63
+ /** extended Y coordinate. Different from affine y. */
64
+ readonly Y: bigint;
65
+ /** extended Z coordinate */
66
+ readonly Z: bigint;
67
+ /** extended T coordinate */
68
+ readonly T: bigint;
69
+
76
70
  /** @deprecated use `toBytes` */
77
71
  toRawBytes(): Uint8Array;
78
- toHex(): string;
79
- precompute(windowSize?: number, isLazy?: boolean): ExtPointType;
80
72
  /** @deprecated use `p.precompute(windowSize)` */
81
73
  _setWindowSize(windowSize: number): void;
74
+ /** @deprecated use .X */
75
+ readonly ex: bigint;
76
+ /** @deprecated use .Y */
77
+ readonly ey: bigint;
78
+ /** @deprecated use .Z */
79
+ readonly ez: bigint;
80
+ /** @deprecated use .T */
81
+ readonly et: bigint;
82
82
  }
83
83
  /** Static methods of Extended Point with coordinates in X, Y, Z, T. */
84
- export interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
85
- new (x: bigint, y: bigint, z: bigint, t: bigint): ExtPointType;
86
- Fp: IField<bigint>;
87
- Fn: IField<bigint>;
88
- fromAffine(p: AffinePoint<bigint>): ExtPointType;
89
- fromBytes(bytes: Uint8Array, zip215?: boolean): ExtPointType;
90
- fromHex(hex: Hex, zip215?: boolean): ExtPointType;
91
- msm(points: ExtPointType[], scalars: bigint[]): ExtPointType;
84
+ export interface EdwardsPointCons extends CurvePointCons<bigint, EdwardsPoint> {
85
+ new (X: bigint, Y: bigint, Z: bigint, T: bigint): EdwardsPoint;
86
+ fromBytes(bytes: Uint8Array, zip215?: boolean): EdwardsPoint;
87
+ fromHex(hex: Hex, zip215?: boolean): EdwardsPoint;
88
+ /** @deprecated use `import { pippenger } from '@noble/curves/abstract/curve.js';` */
89
+ msm(points: EdwardsPoint[], scalars: bigint[]): EdwardsPoint;
92
90
  }
91
+ /** @deprecated use EdwardsPoint */
92
+ export type ExtPointType = EdwardsPoint;
93
+ /** @deprecated use EdwardsPointCons */
94
+ export type ExtPointConstructor = EdwardsPointCons;
93
95
 
94
96
  /**
95
97
  * Twisted Edwards curve options.
@@ -103,11 +105,11 @@ export interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
103
105
  * * Gy: y coordinate of generator point
104
106
  */
105
107
  export type EdwardsOpts = Readonly<{
106
- a: bigint;
107
- d: bigint;
108
108
  p: bigint;
109
109
  n: bigint;
110
110
  h: bigint;
111
+ a: bigint;
112
+ d: bigint;
111
113
  Gx: bigint;
112
114
  Gy: bigint;
113
115
  }>;
@@ -128,76 +130,91 @@ export type EdwardsExtraOpts = Partial<{
128
130
  /**
129
131
  * EdDSA (Edwards Digital Signature algorithm) options.
130
132
  *
131
- * * hash: hash function used to hash private keys and messages
133
+ * * hash: hash function used to hash secret keys and messages
132
134
  * * adjustScalarBytes: clears bits to get valid field element
133
135
  * * domain: Used for hashing
134
136
  * * mapToCurve: for hash-to-curve standard
135
137
  * * prehash: RFC 8032 pre-hashing of messages to sign() / verify()
136
- * * randomBytes: function generating random bytes, used for randomPrivateKey
138
+ * * randomBytes: function generating random bytes, used for randomSecretKey
137
139
  */
138
- export type EdDSAOpts = {
139
- hash: FHash;
140
- adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array;
141
- domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
142
- mapToCurve?: (scalar: bigint[]) => AffinePoint<bigint>;
143
- prehash?: FHash;
144
- randomBytes?: (bytesLength?: number) => Uint8Array;
145
- };
140
+ export type EdDSAOpts = Partial<{
141
+ adjustScalarBytes: (bytes: Uint8Array) => Uint8Array;
142
+ domain: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
143
+ mapToCurve: (scalar: bigint[]) => AffinePoint<bigint>;
144
+ prehash: FHash;
145
+ randomBytes: (bytesLength?: number) => Uint8Array;
146
+ }>;
146
147
 
147
148
  /**
148
149
  * EdDSA (Edwards Digital Signature algorithm) interface.
149
150
  *
150
- * Allows to create and verify signatures, create public and private keys.
151
+ * Allows to create and verify signatures, create public and secret keys.
151
152
  */
152
153
  export interface EdDSA {
153
- getPublicKey: (privateKey: Hex) => Uint8Array;
154
- sign: (message: Hex, privateKey: Hex, options?: { context?: Hex }) => Uint8Array;
154
+ keygen: (seed?: Uint8Array) => { secretKey: Uint8Array; publicKey: Uint8Array };
155
+ getPublicKey: (secretKey: Hex) => Uint8Array;
156
+ sign: (message: Hex, secretKey: Hex, options?: { context?: Hex }) => Uint8Array;
155
157
  verify: (
156
158
  sig: Hex,
157
159
  message: Hex,
158
160
  publicKey: Hex,
159
161
  options?: { context?: Hex; zip215: boolean }
160
162
  ) => boolean;
161
- Point: ExtPointConstructor;
163
+ Point: EdwardsPointCons;
162
164
  utils: {
163
- randomPrivateKey: () => Uint8Array;
165
+ randomSecretKey: (seed?: Uint8Array) => Uint8Array;
166
+ isValidSecretKey: (secretKey: Uint8Array) => boolean;
167
+ isValidPublicKey: (publicKey: Uint8Array, zip215?: boolean) => boolean;
168
+
169
+ /**
170
+ * Converts ed public key to x public key.
171
+ * @example
172
+ * ```js
173
+ * const someonesPub = ed25519.getPublicKey(ed25519.utils.randomSecretKey());
174
+ * const aPriv = x25519.utils.randomSecretKey();
175
+ * x25519.getSharedSecret(aPriv, ed25519.utils.toMontgomery(someonesPub))
176
+ * ```
177
+ */
178
+ toMontgomery: (publicKey: Uint8Array) => Uint8Array;
179
+ /**
180
+ * Converts ed secret key to x secret key.
181
+ * @example
182
+ * ```js
183
+ * const someonesPub = x25519.getPublicKey(x25519.utils.randomSecretKey());
184
+ * const aPriv = ed25519.utils.randomSecretKey();
185
+ * x25519.getSharedSecret(ed25519.utils.toMontgomeryPriv(aPriv), someonesPub)
186
+ * ```
187
+ */
188
+ toMontgomeryPriv: (privateKey: Uint8Array) => Uint8Array;
164
189
  getExtendedPublicKey: (key: Hex) => {
165
190
  head: Uint8Array;
166
191
  prefix: Uint8Array;
167
192
  scalar: bigint;
168
- point: ExtPointType;
193
+ point: EdwardsPoint;
169
194
  pointBytes: Uint8Array;
170
195
  };
196
+
197
+ /** @deprecated use `randomSecretKey` */
198
+ randomPrivateKey: (seed?: Uint8Array) => Uint8Array;
171
199
  /** @deprecated use `point.precompute()` */
172
- precompute: (windowSize?: number, point?: ExtPointType) => ExtPointType;
200
+ precompute: (windowSize?: number, point?: EdwardsPoint) => EdwardsPoint;
173
201
  };
202
+ info: CurveInfo;
174
203
  }
175
204
 
176
205
  // Legacy params. TODO: remove
177
206
  export type CurveFn = {
207
+ /** @deprecated the property will be removed in next release */
178
208
  CURVE: CurveType;
179
- getPublicKey: (privateKey: Hex) => Uint8Array;
180
- sign: (message: Hex, privateKey: Hex, options?: { context?: Hex }) => Uint8Array;
181
- verify: (
182
- sig: Hex,
183
- message: Hex,
184
- publicKey: Hex,
185
- options?: { context?: Hex; zip215: boolean }
186
- ) => boolean;
187
- Point: ExtPointConstructor;
209
+ keygen: EdDSA['keygen'];
210
+ getPublicKey: EdDSA['getPublicKey'];
211
+ sign: EdDSA['sign'];
212
+ verify: EdDSA['verify'];
213
+ Point: EdwardsPointCons;
188
214
  /** @deprecated use `Point` */
189
- ExtendedPoint: ExtPointConstructor;
190
- utils: {
191
- randomPrivateKey: () => Uint8Array;
192
- getExtendedPublicKey: (key: Hex) => {
193
- head: Uint8Array;
194
- prefix: Uint8Array;
195
- scalar: bigint;
196
- point: ExtPointType;
197
- pointBytes: Uint8Array;
198
- };
199
- precompute: (windowSize?: number, point?: ExtPointType) => ExtPointType;
200
- };
215
+ ExtendedPoint: EdwardsPointCons;
216
+ utils: EdDSA['utils'];
217
+ info: CurveInfo;
201
218
  };
202
219
 
203
220
  function isEdValidXY(Fp: IField<bigint>, CURVE: EdwardsOpts, x: bigint, y: bigint): boolean {
@@ -208,7 +225,7 @@ function isEdValidXY(Fp: IField<bigint>, CURVE: EdwardsOpts, x: bigint, y: bigin
208
225
  return Fp.eql(left, right);
209
226
  }
210
227
 
211
- export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): ExtPointConstructor {
228
+ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): EdwardsPointCons {
212
229
  const { Fp, Fn } = _createCurveFields('edwards', CURVE, curveOpts);
213
230
  const { h: cofactor, n: CURVE_ORDER } = CURVE;
214
231
  _validateObject(curveOpts, {}, { uvRatio: 'function' });
@@ -252,22 +269,22 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
252
269
  // Converts Extended point to default (x, y) coordinates.
253
270
  // Can accept precomputed Z^-1 - for example, from invertBatch.
254
271
  const toAffineMemo = memoized((p: Point, iz?: bigint): AffinePoint<bigint> => {
255
- const { ex: x, ey: y, ez: z } = p;
272
+ const { X, Y, Z } = p;
256
273
  const is0 = p.is0();
257
- if (iz == null) iz = is0 ? _8n : (Fp.inv(z) as bigint); // 8 was chosen arbitrarily
258
- const ax = modP(x * iz);
259
- const ay = modP(y * iz);
260
- const zz = modP(z * iz);
274
+ if (iz == null) iz = is0 ? _8n : (Fp.inv(Z) as bigint); // 8 was chosen arbitrarily
275
+ const x = modP(X * iz);
276
+ const y = modP(Y * iz);
277
+ const zz = Fp.mul(Z, iz);
261
278
  if (is0) return { x: _0n, y: _1n };
262
279
  if (zz !== _1n) throw new Error('invZ was invalid');
263
- return { x: ax, y: ay };
280
+ return { x, y };
264
281
  });
265
282
  const assertValidMemo = memoized((p: Point) => {
266
283
  const { a, d } = CURVE;
267
284
  if (p.is0()) throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
268
285
  // Equation in affine coordinates: ax² + y² = 1 + dx²y²
269
286
  // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
270
- const { ex: X, ey: Y, ez: Z, et: T } = p;
287
+ const { X, Y, Z, T } = p;
271
288
  const X2 = modP(X * X); // X²
272
289
  const Y2 = modP(Y * Y); // Y²
273
290
  const Z2 = modP(Z * Z); // Z²
@@ -285,7 +302,7 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
285
302
 
286
303
  // Extended Point works in extended coordinates: (X, Y, Z, T) ∋ (x=X/Z, y=Y/Z, T=xy).
287
304
  // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
288
- class Point implements ExtPointType {
305
+ class Point implements EdwardsPoint {
289
306
  // base / generator point
290
307
  static readonly BASE = new Point(CURVE.Gx, CURVE.Gy, _1n, modP(CURVE.Gx * CURVE.Gy));
291
308
  // zero / infinity / identity point
@@ -294,16 +311,16 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
294
311
  static readonly Fp = Fp;
295
312
  static readonly Fn = Fn;
296
313
 
297
- readonly ex: bigint;
298
- readonly ey: bigint;
299
- readonly ez: bigint;
300
- readonly et: bigint;
314
+ readonly X: bigint;
315
+ readonly Y: bigint;
316
+ readonly Z: bigint;
317
+ readonly T: bigint;
301
318
 
302
- constructor(ex: bigint, ey: bigint, ez: bigint, et: bigint) {
303
- this.ex = acoord('x', ex);
304
- this.ey = acoord('y', ey);
305
- this.ez = acoord('z', ez, true);
306
- this.et = acoord('t', et);
319
+ constructor(X: bigint, Y: bigint, Z: bigint, T: bigint) {
320
+ this.X = acoord('x', X);
321
+ this.Y = acoord('y', Y);
322
+ this.Z = acoord('z', Z, true);
323
+ this.T = acoord('t', T);
307
324
  Object.freeze(this);
308
325
  }
309
326
 
@@ -314,32 +331,44 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
314
331
  return this.toAffine().y;
315
332
  }
316
333
 
317
- static fromAffine(p: AffinePoint<bigint>): Point {
318
- if (p instanceof Point) throw new Error('extended point not allowed');
319
- const { x, y } = p || {};
320
- acoord('x', x);
321
- acoord('y', y);
322
- return new Point(x, y, _1n, modP(x * y));
334
+ // TODO: remove
335
+ get ex(): bigint {
336
+ return this.X;
337
+ }
338
+ get ey(): bigint {
339
+ return this.Y;
340
+ }
341
+ get ez(): bigint {
342
+ return this.Z;
343
+ }
344
+ get et(): bigint {
345
+ return this.T;
323
346
  }
324
347
  static normalizeZ(points: Point[]): Point[] {
325
- return normalizeZ(Point, 'ez', points);
348
+ return normalizeZ(Point, points);
326
349
  }
327
- // Multiscalar Multiplication
328
350
  static msm(points: Point[], scalars: bigint[]): Point {
329
351
  return pippenger(Point, Fn, points, scalars);
330
352
  }
331
-
332
- // "Private method", don't use it directly
333
353
  _setWindowSize(windowSize: number) {
334
354
  this.precompute(windowSize);
335
355
  }
356
+
357
+ static fromAffine(p: AffinePoint<bigint>): Point {
358
+ if (p instanceof Point) throw new Error('extended point not allowed');
359
+ const { x, y } = p || {};
360
+ acoord('x', x);
361
+ acoord('y', y);
362
+ return new Point(x, y, _1n, modP(x * y));
363
+ }
364
+
336
365
  precompute(windowSize: number = 8, isLazy = true) {
337
- wnaf.setWindowSize(this, windowSize);
366
+ wnaf.createCache(this, windowSize);
338
367
  if (!isLazy) this.multiply(_2n); // random number
339
368
  return this;
340
369
  }
341
- // Not required for fromHex(), which always creates valid points.
342
- // Could be useful for fromAffine().
370
+
371
+ // Useful in fromAffine() - not for fromBytes(), which always created valid points.
343
372
  assertValidity(): void {
344
373
  assertValidMemo(this);
345
374
  }
@@ -347,8 +376,8 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
347
376
  // Compare one point to another.
348
377
  equals(other: Point): boolean {
349
378
  aextpoint(other);
350
- const { ex: X1, ey: Y1, ez: Z1 } = this;
351
- const { ex: X2, ey: Y2, ez: Z2 } = other;
379
+ const { X: X1, Y: Y1, Z: Z1 } = this;
380
+ const { X: X2, Y: Y2, Z: Z2 } = other;
352
381
  const X1Z2 = modP(X1 * Z2);
353
382
  const X2Z1 = modP(X2 * Z1);
354
383
  const Y1Z2 = modP(Y1 * Z2);
@@ -362,7 +391,7 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
362
391
 
363
392
  negate(): Point {
364
393
  // Flips point sign to a negative one (-x, y in affine coords)
365
- return new Point(modP(-this.ex), this.ey, this.ez, modP(-this.et));
394
+ return new Point(modP(-this.X), this.Y, this.Z, modP(-this.T));
366
395
  }
367
396
 
368
397
  // Fast algo for doubling Extended Point.
@@ -370,7 +399,7 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
370
399
  // Cost: 4M + 4S + 1*a + 6add + 1*2.
371
400
  double(): Point {
372
401
  const { a } = CURVE;
373
- const { ex: X1, ey: Y1, ez: Z1 } = this;
402
+ const { X: X1, Y: Y1, Z: Z1 } = this;
374
403
  const A = modP(X1 * X1); // A = X12
375
404
  const B = modP(Y1 * Y1); // B = Y12
376
405
  const C = modP(_2n * modP(Z1 * Z1)); // C = 2*Z12
@@ -393,8 +422,8 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
393
422
  add(other: Point) {
394
423
  aextpoint(other);
395
424
  const { a, d } = CURVE;
396
- const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
397
- const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
425
+ const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;
426
+ const { X: X2, Y: Y2, Z: Z2, T: T2 } = other;
398
427
  const A = modP(X1 * X2); // A = X1*X2
399
428
  const B = modP(Y1 * Y2); // B = Y1*Y2
400
429
  const C = modP(T1 * d * T2); // C = T1*d*T2
@@ -418,8 +447,8 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
418
447
  multiply(scalar: bigint): Point {
419
448
  const n = scalar;
420
449
  aInRange('scalar', n, _1n, CURVE_ORDER); // 1 <= scalar < L
421
- const { p, f } = wnaf.wNAFCached(this, n, Point.normalizeZ);
422
- return Point.normalizeZ([p, f])[0];
450
+ const { p, f } = wnaf.cached(this, n, (p) => normalizeZ(Point, p));
451
+ return normalizeZ(Point, [p, f])[0];
423
452
  }
424
453
 
425
454
  // Non-constant-time multiplication. Uses double-and-add algorithm.
@@ -432,7 +461,7 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
432
461
  aInRange('scalar', n, _0n, CURVE_ORDER); // 0 <= scalar < L
433
462
  if (n === _0n) return Point.ZERO;
434
463
  if (this.is0() || n === _1n) return this;
435
- return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
464
+ return wnaf.unsafe(this, n, (p) => normalizeZ(Point, p), acc);
436
465
  }
437
466
 
438
467
  // Checks if point is of small order.
@@ -446,7 +475,7 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
446
475
  // Multiplies point by curve order and checks if the result is 0.
447
476
  // Returns `false` is the point is dirty.
448
477
  isTorsionFree(): boolean {
449
- return wnaf.wNAFCachedUnsafe(this, CURVE_ORDER).is0();
478
+ return wnaf.unsafe(this, CURVE_ORDER).is0();
450
479
  }
451
480
 
452
481
  // Converts Extended point to default (x, y) coordinates.
@@ -462,7 +491,7 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
462
491
 
463
492
  static fromBytes(bytes: Uint8Array, zip215 = false): Point {
464
493
  abytes(bytes);
465
- return this.fromHex(bytes, zip215);
494
+ return Point.fromHex(bytes, zip215);
466
495
  }
467
496
 
468
497
  // Converts hash string or Uint8Array to Point.
@@ -499,9 +528,6 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
499
528
  if (isLastByteOdd !== isXOdd) x = modP(-x); // if x_0 != x mod 2, set x = p-x
500
529
  return Point.fromAffine({ x, y });
501
530
  }
502
- static fromPrivateScalar(scalar: bigint): Point {
503
- return Point.BASE.multiply(scalar);
504
- }
505
531
  toBytes(): Uint8Array {
506
532
  const { x, y } = this.toAffine();
507
533
  const bytes = numberToBytesLE(y, Fp.BYTES); // each y has 2 x values (x, -y)
@@ -520,19 +546,128 @@ export function edwards(CURVE: EdwardsOpts, curveOpts: EdwardsExtraOpts = {}): E
520
546
  return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;
521
547
  }
522
548
  }
523
- const wnaf = wNAF(Point, Fn.BYTES * 8); // Fn.BITS?
549
+ const wnaf = new wNAF(Point, Fn.BYTES * 8); // Fn.BITS?
524
550
  return Point;
525
551
  }
526
552
 
553
+ /**
554
+ * Base class for prime-order points like Ristretto255 and Decaf448.
555
+ * These points eliminate cofactor issues by representing equivalence classes
556
+ * of Edwards curve points.
557
+ */
558
+ export abstract class PrimeEdwardsPoint<T extends PrimeEdwardsPoint<T>>
559
+ implements CurvePoint<bigint, T>
560
+ {
561
+ static BASE: PrimeEdwardsPoint<any>;
562
+ static ZERO: PrimeEdwardsPoint<any>;
563
+ static Fp: IField<bigint>;
564
+ static Fn: IField<bigint>;
565
+
566
+ protected readonly ep: EdwardsPoint;
567
+
568
+ constructor(ep: EdwardsPoint) {
569
+ this.ep = ep;
570
+ }
571
+
572
+ // Abstract methods that must be implemented by subclasses
573
+ abstract toBytes(): Uint8Array;
574
+ abstract equals(other: T): boolean;
575
+
576
+ // Static methods that must be implemented by subclasses
577
+ static fromBytes(_bytes: Uint8Array): any {
578
+ throw new Error('fromBytes must be implemented by subclass');
579
+ }
580
+
581
+ static fromHex(_hex: Hex): any {
582
+ throw new Error('fromHex must be implemented by subclass');
583
+ }
584
+
585
+ get x(): bigint {
586
+ return this.toAffine().x;
587
+ }
588
+ get y(): bigint {
589
+ return this.toAffine().y;
590
+ }
591
+
592
+ // Common implementations
593
+ clearCofactor(): T {
594
+ // no-op for prime-order groups
595
+ return this as any;
596
+ }
597
+
598
+ assertValidity(): void {
599
+ this.ep.assertValidity();
600
+ }
601
+
602
+ toAffine(invertedZ?: bigint): AffinePoint<bigint> {
603
+ return this.ep.toAffine(invertedZ);
604
+ }
605
+
606
+ /** @deprecated use `toBytes` */
607
+ toRawBytes(): Uint8Array {
608
+ return this.toBytes();
609
+ }
610
+
611
+ toHex(): string {
612
+ return bytesToHex(this.toBytes());
613
+ }
614
+
615
+ toString(): string {
616
+ return this.toHex();
617
+ }
618
+
619
+ isTorsionFree(): boolean {
620
+ return true;
621
+ }
622
+
623
+ isSmallOrder(): boolean {
624
+ return false;
625
+ }
626
+
627
+ add(other: T): T {
628
+ this.assertSame(other);
629
+ return this.init(this.ep.add(other.ep));
630
+ }
631
+
632
+ subtract(other: T): T {
633
+ this.assertSame(other);
634
+ return this.init(this.ep.subtract(other.ep));
635
+ }
636
+
637
+ multiply(scalar: bigint): T {
638
+ return this.init(this.ep.multiply(scalar));
639
+ }
640
+
641
+ multiplyUnsafe(scalar: bigint): T {
642
+ return this.init(this.ep.multiplyUnsafe(scalar));
643
+ }
644
+
645
+ double(): T {
646
+ return this.init(this.ep.double());
647
+ }
648
+
649
+ negate(): T {
650
+ return this.init(this.ep.negate());
651
+ }
652
+
653
+ precompute(windowSize?: number, isLazy?: boolean): T {
654
+ return this.init(this.ep.precompute(windowSize, isLazy));
655
+ }
656
+
657
+ // Helper methods
658
+ abstract is0(): boolean;
659
+ protected abstract assertSame(other: T): void;
660
+ protected abstract init(ep: EdwardsPoint): T;
661
+ }
662
+
527
663
  /**
528
664
  * Initializes EdDSA signatures over given Edwards curve.
529
665
  */
530
- export function eddsa(Point: ExtPointConstructor, eddsaOpts: EdDSAOpts): EdDSA {
666
+ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpts): EdDSA {
667
+ if (typeof cHash !== 'function') throw new Error('"hash" function param is required');
531
668
  _validateObject(
532
669
  eddsaOpts,
533
- {
534
- hash: 'function',
535
- },
670
+ {},
536
671
  {
537
672
  adjustScalarBytes: 'function',
538
673
  randomBytes: 'function',
@@ -542,7 +677,7 @@ export function eddsa(Point: ExtPointConstructor, eddsaOpts: EdDSAOpts): EdDSA {
542
677
  }
543
678
  );
544
679
 
545
- const { prehash, hash: cHash } = eddsaOpts;
680
+ const { prehash } = eddsaOpts;
546
681
  const { BASE: G, Fp, Fn } = Point;
547
682
  const CURVE_ORDER = Fn.ORDER;
548
683
 
@@ -559,6 +694,7 @@ export function eddsa(Point: ExtPointConstructor, eddsaOpts: EdDSAOpts): EdDSA {
559
694
  function modN(a: bigint) {
560
695
  return Fn.create(a);
561
696
  }
697
+
562
698
  // Little-endian SHA512 with modulo n
563
699
  function modN_LE(hash: Uint8Array): bigint {
564
700
  // Not using Fn.fromBytes: hash can be 2*Fn.BYTES
@@ -578,17 +714,17 @@ export function eddsa(Point: ExtPointConstructor, eddsaOpts: EdDSAOpts): EdDSA {
578
714
  return { head, prefix, scalar };
579
715
  }
580
716
 
581
- // Convenience method that creates public key from scalar. RFC8032 5.1.5
582
- function getExtendedPublicKey(key: Hex) {
583
- const { head, prefix, scalar } = getPrivateScalar(key);
717
+ /** Convenience method that creates public key from scalar. RFC8032 5.1.5 */
718
+ function getExtendedPublicKey(secretKey: Hex) {
719
+ const { head, prefix, scalar } = getPrivateScalar(secretKey);
584
720
  const point = G.multiply(scalar); // Point on Edwards curve aka public key
585
721
  const pointBytes = point.toBytes();
586
722
  return { head, prefix, scalar, point, pointBytes };
587
723
  }
588
724
 
589
- // Calculates EdDSA pub key. RFC8032 5.1.5. Privkey is hashed. Use first half with 3 bits cleared
590
- function getPublicKey(privKey: Hex): Uint8Array {
591
- return getExtendedPublicKey(privKey).pointBytes;
725
+ /** Calculates EdDSA pub key. RFC8032 5.1.5. */
726
+ function getPublicKey(secretKey: Hex): Uint8Array {
727
+ return getExtendedPublicKey(secretKey).pointBytes;
592
728
  }
593
729
 
594
730
  // int('LE', SHA512(dom2(F, C) || msgs)) mod N
@@ -598,10 +734,10 @@ export function eddsa(Point: ExtPointConstructor, eddsaOpts: EdDSAOpts): EdDSA {
598
734
  }
599
735
 
600
736
  /** Signs message with privateKey. RFC8032 5.1.6 */
601
- function sign(msg: Hex, privKey: Hex, options: { context?: Hex } = {}): Uint8Array {
737
+ function sign(msg: Hex, secretKey: Hex, options: { context?: Hex } = {}): Uint8Array {
602
738
  msg = ensureBytes('message', msg);
603
739
  if (prehash) msg = prehash(msg); // for ed25519ph etc.
604
- const { prefix, scalar, pointBytes } = getExtendedPublicKey(privKey);
740
+ const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);
605
741
  const r = hashDomainToScalar(options.context, prefix, msg); // r = dom2(F, C) || prefix || PH(M)
606
742
  const R = G.multiply(r).toBytes(); // R = rG
607
743
  const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
@@ -612,7 +748,8 @@ export function eddsa(Point: ExtPointConstructor, eddsaOpts: EdDSAOpts): EdDSA {
612
748
  return ensureBytes('result', res, L * 2); // 64-byte signature
613
749
  }
614
750
 
615
- const verifyOpts: { context?: Hex; zip215?: boolean } = VERIFY_DEFAULT;
751
+ // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
752
+ const verifyOpts: { context?: Hex; zip215?: boolean } = { zip215: true };
616
753
 
617
754
  /**
618
755
  * Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
@@ -650,10 +787,54 @@ export function eddsa(Point: ExtPointConstructor, eddsaOpts: EdDSAOpts): EdDSA {
650
787
 
651
788
  G.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
652
789
 
790
+ const size = Fp.BYTES;
791
+ const lengths = {
792
+ secret: size,
793
+ public: size,
794
+ signature: 2 * size,
795
+ seed: size,
796
+ };
797
+ function randomSecretKey(seed = randomBytes_!(lengths.seed)): Uint8Array {
798
+ return seed;
799
+ }
800
+
653
801
  const utils = {
654
802
  getExtendedPublicKey,
655
803
  /** ed25519 priv keys are uniform 32b. No need to check for modulo bias, like in secp256k1. */
656
- randomPrivateKey: (): Uint8Array => randomBytes_!(Fp.BYTES),
804
+ randomSecretKey,
805
+
806
+ isValidSecretKey,
807
+ isValidPublicKey,
808
+
809
+ randomPrivateKey: randomSecretKey,
810
+
811
+ /**
812
+ * Converts ed public key to x public key. Uses formula:
813
+ * - ed25519:
814
+ * - `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
815
+ * - `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
816
+ * - ed448:
817
+ * - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
818
+ * - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
819
+ *
820
+ * There is NO `fromMontgomery`:
821
+ * - There are 2 valid ed25519 points for every x25519, with flipped coordinate
822
+ * - Sometimes there are 0 valid ed25519 points, because x25519 *additionally*
823
+ * accepts inputs on the quadratic twist, which can't be moved to ed25519
824
+ */
825
+ toMontgomery(publicKey: Uint8Array): Uint8Array {
826
+ const { y } = Point.fromBytes(publicKey);
827
+ const is25519 = size === 32;
828
+ if (!is25519 && size !== 57) throw new Error('only defined for 25519 and 448');
829
+ const u = is25519 ? Fp.div(_1n + y, _1n - y) : Fp.div(y - _1n, y + _1n);
830
+ return Fp.toBytes(u);
831
+ },
832
+
833
+ toMontgomeryPriv(privateKey: Uint8Array): Uint8Array {
834
+ abytes(privateKey, size);
835
+ const hashed = cHash(privateKey.subarray(0, size));
836
+ return adjustScalarBytes(hashed).subarray(0, size);
837
+ },
657
838
 
658
839
  /**
659
840
  * We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
@@ -661,19 +842,51 @@ export function eddsa(Point: ExtPointConstructor, eddsaOpts: EdDSAOpts): EdDSA {
661
842
  * but allows to speed-up subsequent getPublicKey() calls up to 20x.
662
843
  * @param windowSize 2, 4, 8, 16
663
844
  */
664
- precompute(windowSize = 8, point: ExtPointType = Point.BASE): ExtPointType {
845
+ precompute(windowSize = 8, point: EdwardsPoint = Point.BASE): EdwardsPoint {
665
846
  return point.precompute(windowSize, false);
666
847
  },
667
848
  };
668
849
 
669
- return { getPublicKey, sign, verify, utils, Point };
850
+ function keygen(seed?: Uint8Array) {
851
+ const secretKey = utils.randomSecretKey(seed);
852
+ return { secretKey, publicKey: getPublicKey(secretKey) };
853
+ }
854
+
855
+ function isValidSecretKey(key: Uint8Array): boolean {
856
+ try {
857
+ return !!Fn.fromBytes(key, false);
858
+ } catch (error) {
859
+ return false;
860
+ }
861
+ }
862
+
863
+ function isValidPublicKey(key: Uint8Array, zip215?: boolean): boolean {
864
+ try {
865
+ return !!Point.fromBytes(key, zip215);
866
+ } catch (error) {
867
+ return false;
868
+ }
869
+ }
870
+
871
+ return Object.freeze({
872
+ keygen,
873
+ getPublicKey,
874
+ sign,
875
+ verify,
876
+ utils,
877
+ Point,
878
+ info: { type: 'edwards' as const, lengths },
879
+ });
670
880
  }
671
881
 
882
+ // TODO: remove
672
883
  export type EdComposed = {
673
884
  CURVE: EdwardsOpts;
674
885
  curveOpts: EdwardsExtraOpts;
886
+ hash: FHash;
675
887
  eddsaOpts: EdDSAOpts;
676
888
  };
889
+ // TODO: remove
677
890
  function _eddsa_legacy_opts_to_new(c: CurveTypeWithLength): EdComposed {
678
891
  const CURVE: EdwardsOpts = {
679
892
  a: c.a,
@@ -688,23 +901,23 @@ function _eddsa_legacy_opts_to_new(c: CurveTypeWithLength): EdComposed {
688
901
  const Fn = Field(CURVE.n, c.nBitLength, true);
689
902
  const curveOpts: EdwardsExtraOpts = { Fp, Fn, uvRatio: c.uvRatio };
690
903
  const eddsaOpts: EdDSAOpts = {
691
- hash: c.hash,
692
904
  randomBytes: c.randomBytes,
693
905
  adjustScalarBytes: c.adjustScalarBytes,
694
906
  domain: c.domain,
695
907
  prehash: c.prehash,
696
908
  mapToCurve: c.mapToCurve,
697
909
  };
698
- return { CURVE, curveOpts, eddsaOpts };
910
+ return { CURVE, curveOpts, hash: c.hash, eddsaOpts };
699
911
  }
912
+ // TODO: remove
700
913
  function _eddsa_new_output_to_legacy(c: CurveTypeWithLength, eddsa: EdDSA): CurveFn {
701
914
  const legacy = Object.assign({}, eddsa, { ExtendedPoint: eddsa.Point, CURVE: c });
702
915
  return legacy;
703
916
  }
704
917
  // TODO: remove. Use eddsa
705
918
  export function twistedEdwards(c: CurveTypeWithLength): CurveFn {
706
- const { CURVE, curveOpts, eddsaOpts } = _eddsa_legacy_opts_to_new(c);
919
+ const { CURVE, curveOpts, hash, eddsaOpts } = _eddsa_legacy_opts_to_new(c);
707
920
  const Point = edwards(CURVE, curveOpts);
708
- const EDDSA = eddsa(Point, eddsaOpts);
921
+ const EDDSA = eddsa(Point, hash, eddsaOpts);
709
922
  return _eddsa_new_output_to_legacy(c, EDDSA);
710
923
  }