@noble/curves 1.9.5 → 2.0.0-beta.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 (211) hide show
  1. package/README.md +267 -421
  2. package/abstract/bls.d.ts +49 -111
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +108 -152
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/curve.d.ts +7 -48
  7. package/abstract/curve.d.ts.map +1 -1
  8. package/abstract/curve.js +22 -47
  9. package/abstract/curve.js.map +1 -1
  10. package/abstract/edwards.d.ts +17 -68
  11. package/abstract/edwards.d.ts.map +1 -1
  12. package/abstract/edwards.js +98 -175
  13. package/abstract/edwards.js.map +1 -1
  14. package/abstract/fft.js +14 -27
  15. package/abstract/fft.js.map +1 -1
  16. package/abstract/hash-to-curve.d.ts +11 -24
  17. package/abstract/hash-to-curve.d.ts.map +1 -1
  18. package/abstract/hash-to-curve.js +30 -35
  19. package/abstract/hash-to-curve.js.map +1 -1
  20. package/abstract/modular.d.ts +5 -17
  21. package/abstract/modular.d.ts.map +1 -1
  22. package/abstract/modular.js +166 -167
  23. package/abstract/modular.js.map +1 -1
  24. package/abstract/montgomery.d.ts +4 -9
  25. package/abstract/montgomery.d.ts.map +1 -1
  26. package/abstract/montgomery.js +17 -20
  27. package/abstract/montgomery.js.map +1 -1
  28. package/abstract/oprf.d.ts +282 -0
  29. package/abstract/oprf.d.ts.map +1 -0
  30. package/abstract/oprf.js +297 -0
  31. package/abstract/oprf.js.map +1 -0
  32. package/abstract/poseidon.js +20 -24
  33. package/abstract/poseidon.js.map +1 -1
  34. package/abstract/tower.d.ts +9 -7
  35. package/abstract/tower.d.ts.map +1 -1
  36. package/abstract/tower.js +600 -364
  37. package/abstract/tower.js.map +1 -1
  38. package/abstract/weierstrass.d.ts +12 -145
  39. package/abstract/weierstrass.d.ts.map +1 -1
  40. package/abstract/weierstrass.js +153 -377
  41. package/abstract/weierstrass.js.map +1 -1
  42. package/bls12-381.d.ts +2 -2
  43. package/bls12-381.d.ts.map +1 -1
  44. package/bls12-381.js +174 -216
  45. package/bls12-381.js.map +1 -1
  46. package/bn254.d.ts +58 -10
  47. package/bn254.d.ts.map +1 -1
  48. package/bn254.js +70 -130
  49. package/bn254.js.map +1 -1
  50. package/ed25519.d.ts +12 -31
  51. package/ed25519.d.ts.map +1 -1
  52. package/ed25519.js +104 -146
  53. package/ed25519.js.map +1 -1
  54. package/ed448.d.ts +14 -33
  55. package/ed448.d.ts.map +1 -1
  56. package/ed448.js +105 -132
  57. package/ed448.js.map +1 -1
  58. package/index.js +1 -1
  59. package/misc.d.ts +10 -14
  60. package/misc.d.ts.map +1 -1
  61. package/misc.js +51 -60
  62. package/misc.js.map +1 -1
  63. package/nist.d.ts +11 -14
  64. package/nist.d.ts.map +1 -1
  65. package/nist.js +46 -55
  66. package/nist.js.map +1 -1
  67. package/package.json +9 -224
  68. package/secp256k1.d.ts +7 -23
  69. package/secp256k1.d.ts.map +1 -1
  70. package/secp256k1.js +72 -83
  71. package/secp256k1.js.map +1 -1
  72. package/src/abstract/bls.ts +197 -344
  73. package/src/abstract/curve.ts +10 -83
  74. package/src/abstract/edwards.ts +96 -223
  75. package/src/abstract/hash-to-curve.ts +32 -45
  76. package/src/abstract/modular.ts +144 -130
  77. package/src/abstract/montgomery.ts +21 -22
  78. package/src/abstract/oprf.ts +600 -0
  79. package/src/abstract/tower.ts +627 -382
  80. package/src/abstract/weierstrass.ts +101 -482
  81. package/src/bls12-381.ts +148 -176
  82. package/src/bn254.ts +67 -122
  83. package/src/ed25519.ts +65 -118
  84. package/src/ed448.ts +63 -113
  85. package/src/index.ts +1 -1
  86. package/src/misc.ts +66 -49
  87. package/src/nist.ts +48 -57
  88. package/src/secp256k1.ts +56 -88
  89. package/src/utils.ts +41 -61
  90. package/src/webcrypto.ts +362 -0
  91. package/utils.d.ts +28 -19
  92. package/utils.d.ts.map +1 -1
  93. package/utils.js +45 -121
  94. package/utils.js.map +1 -1
  95. package/webcrypto.d.ts +47 -0
  96. package/webcrypto.d.ts.map +1 -0
  97. package/webcrypto.js +231 -0
  98. package/webcrypto.js.map +1 -0
  99. package/esm/_shortw_utils.d.ts +0 -19
  100. package/esm/_shortw_utils.d.ts.map +0 -1
  101. package/esm/_shortw_utils.js +0 -16
  102. package/esm/_shortw_utils.js.map +0 -1
  103. package/esm/abstract/bls.d.ts +0 -190
  104. package/esm/abstract/bls.d.ts.map +0 -1
  105. package/esm/abstract/bls.js +0 -408
  106. package/esm/abstract/bls.js.map +0 -1
  107. package/esm/abstract/curve.d.ts +0 -231
  108. package/esm/abstract/curve.d.ts.map +0 -1
  109. package/esm/abstract/curve.js +0 -465
  110. package/esm/abstract/curve.js.map +0 -1
  111. package/esm/abstract/edwards.d.ts +0 -237
  112. package/esm/abstract/edwards.d.ts.map +0 -1
  113. package/esm/abstract/edwards.js +0 -632
  114. package/esm/abstract/edwards.js.map +0 -1
  115. package/esm/abstract/fft.d.ts +0 -122
  116. package/esm/abstract/fft.d.ts.map +0 -1
  117. package/esm/abstract/fft.js +0 -425
  118. package/esm/abstract/fft.js.map +0 -1
  119. package/esm/abstract/hash-to-curve.d.ts +0 -102
  120. package/esm/abstract/hash-to-curve.d.ts.map +0 -1
  121. package/esm/abstract/hash-to-curve.js +0 -203
  122. package/esm/abstract/hash-to-curve.js.map +0 -1
  123. package/esm/abstract/modular.d.ts +0 -171
  124. package/esm/abstract/modular.d.ts.map +0 -1
  125. package/esm/abstract/modular.js +0 -530
  126. package/esm/abstract/modular.js.map +0 -1
  127. package/esm/abstract/montgomery.d.ts +0 -30
  128. package/esm/abstract/montgomery.d.ts.map +0 -1
  129. package/esm/abstract/montgomery.js +0 -157
  130. package/esm/abstract/montgomery.js.map +0 -1
  131. package/esm/abstract/poseidon.d.ts +0 -68
  132. package/esm/abstract/poseidon.d.ts.map +0 -1
  133. package/esm/abstract/poseidon.js +0 -296
  134. package/esm/abstract/poseidon.js.map +0 -1
  135. package/esm/abstract/tower.d.ts +0 -93
  136. package/esm/abstract/tower.d.ts.map +0 -1
  137. package/esm/abstract/tower.js +0 -502
  138. package/esm/abstract/tower.js.map +0 -1
  139. package/esm/abstract/utils.d.ts +0 -5
  140. package/esm/abstract/utils.d.ts.map +0 -1
  141. package/esm/abstract/utils.js +0 -7
  142. package/esm/abstract/utils.js.map +0 -1
  143. package/esm/abstract/weierstrass.d.ts +0 -412
  144. package/esm/abstract/weierstrass.d.ts.map +0 -1
  145. package/esm/abstract/weierstrass.js +0 -1428
  146. package/esm/abstract/weierstrass.js.map +0 -1
  147. package/esm/bls12-381.d.ts +0 -16
  148. package/esm/bls12-381.d.ts.map +0 -1
  149. package/esm/bls12-381.js +0 -738
  150. package/esm/bls12-381.js.map +0 -1
  151. package/esm/bn254.d.ts +0 -18
  152. package/esm/bn254.d.ts.map +0 -1
  153. package/esm/bn254.js +0 -246
  154. package/esm/bn254.js.map +0 -1
  155. package/esm/ed25519.d.ts +0 -106
  156. package/esm/ed25519.d.ts.map +0 -1
  157. package/esm/ed25519.js +0 -467
  158. package/esm/ed25519.js.map +0 -1
  159. package/esm/ed448.d.ts +0 -101
  160. package/esm/ed448.d.ts.map +0 -1
  161. package/esm/ed448.js +0 -448
  162. package/esm/ed448.js.map +0 -1
  163. package/esm/index.d.ts +0 -2
  164. package/esm/index.d.ts.map +0 -1
  165. package/esm/index.js +0 -17
  166. package/esm/index.js.map +0 -1
  167. package/esm/jubjub.d.ts +0 -12
  168. package/esm/jubjub.d.ts.map +0 -1
  169. package/esm/jubjub.js +0 -12
  170. package/esm/jubjub.js.map +0 -1
  171. package/esm/misc.d.ts +0 -19
  172. package/esm/misc.d.ts.map +0 -1
  173. package/esm/misc.js +0 -109
  174. package/esm/misc.js.map +0 -1
  175. package/esm/nist.d.ts +0 -21
  176. package/esm/nist.d.ts.map +0 -1
  177. package/esm/nist.js +0 -132
  178. package/esm/nist.js.map +0 -1
  179. package/esm/p256.d.ts +0 -16
  180. package/esm/p256.d.ts.map +0 -1
  181. package/esm/p256.js +0 -16
  182. package/esm/p256.js.map +0 -1
  183. package/esm/p384.d.ts +0 -16
  184. package/esm/p384.d.ts.map +0 -1
  185. package/esm/p384.js +0 -16
  186. package/esm/p384.js.map +0 -1
  187. package/esm/p521.d.ts +0 -16
  188. package/esm/p521.d.ts.map +0 -1
  189. package/esm/p521.js +0 -16
  190. package/esm/p521.js.map +0 -1
  191. package/esm/package.json +0 -4
  192. package/esm/pasta.d.ts +0 -10
  193. package/esm/pasta.d.ts.map +0 -1
  194. package/esm/pasta.js +0 -10
  195. package/esm/pasta.js.map +0 -1
  196. package/esm/secp256k1.d.ts +0 -89
  197. package/esm/secp256k1.d.ts.map +0 -1
  198. package/esm/secp256k1.js +0 -292
  199. package/esm/secp256k1.js.map +0 -1
  200. package/esm/utils.d.ts +0 -110
  201. package/esm/utils.d.ts.map +0 -1
  202. package/esm/utils.js +0 -322
  203. package/esm/utils.js.map +0 -1
  204. package/src/_shortw_utils.ts +0 -21
  205. package/src/abstract/utils.ts +0 -7
  206. package/src/jubjub.ts +0 -12
  207. package/src/p256.ts +0 -15
  208. package/src/p384.ts +0 -15
  209. package/src/p521.ts +0 -15
  210. package/src/package.json +0 -3
  211. package/src/pasta.ts +0 -9
@@ -7,33 +7,31 @@
7
7
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
8
8
  import {
9
9
  _validateObject,
10
- _abool2 as abool,
11
- _abytes2 as abytes,
10
+ abool,
11
+ abytes,
12
12
  aInRange,
13
13
  bytesToHex,
14
14
  bytesToNumberLE,
15
15
  concatBytes,
16
16
  copyBytes,
17
- ensureBytes,
17
+ hexToBytes,
18
+ isBytes,
18
19
  memoized,
19
20
  notImplemented,
20
- numberToBytesLE,
21
- randomBytes,
21
+ randomBytes as wcRandomBytes,
22
22
  type FHash,
23
- type Hex,
23
+ type Signer,
24
24
  } from '../utils.ts';
25
25
  import {
26
26
  _createCurveFields,
27
27
  normalizeZ,
28
- pippenger,
29
28
  wNAF,
30
29
  type AffinePoint,
31
- type BasicCurve,
32
30
  type CurveLengths,
33
31
  type CurvePoint,
34
32
  type CurvePointCons,
35
33
  } from './curve.ts';
36
- import { Field, type IField, type NLength } from './modular.ts';
34
+ import { type IField } from './modular.ts';
37
35
 
38
36
  // Be friendly to bad ECMAScript parsers by not using bigint literals
39
37
  // prettier-ignore
@@ -51,33 +49,14 @@ export interface EdwardsPoint extends CurvePoint<bigint, EdwardsPoint> {
51
49
  readonly Z: bigint;
52
50
  /** extended T coordinate */
53
51
  readonly T: bigint;
54
-
55
- /** @deprecated use `toBytes` */
56
- toRawBytes(): Uint8Array;
57
- /** @deprecated use `p.precompute(windowSize)` */
58
- _setWindowSize(windowSize: number): void;
59
- /** @deprecated use .X */
60
- readonly ex: bigint;
61
- /** @deprecated use .Y */
62
- readonly ey: bigint;
63
- /** @deprecated use .Z */
64
- readonly ez: bigint;
65
- /** @deprecated use .T */
66
- readonly et: bigint;
67
52
  }
68
53
  /** Static methods of Extended Point with coordinates in X, Y, Z, T. */
69
54
  export interface EdwardsPointCons extends CurvePointCons<EdwardsPoint> {
70
55
  new (X: bigint, Y: bigint, Z: bigint, T: bigint): EdwardsPoint;
71
56
  CURVE(): EdwardsOpts;
72
57
  fromBytes(bytes: Uint8Array, zip215?: boolean): EdwardsPoint;
73
- fromHex(hex: Hex, zip215?: boolean): EdwardsPoint;
74
- /** @deprecated use `import { pippenger } from '@noble/curves/abstract/curve.js';` */
75
- msm(points: EdwardsPoint[], scalars: bigint[]): EdwardsPoint;
58
+ fromHex(hex: string, zip215?: boolean): EdwardsPoint;
76
59
  }
77
- /** @deprecated use EdwardsPoint */
78
- export type ExtPointType = EdwardsPoint;
79
- /** @deprecated use EdwardsPointCons */
80
- export type ExtPointConstructor = EdwardsPointCons;
81
60
 
82
61
  /**
83
62
  * Twisted Edwards curve options.
@@ -139,13 +118,17 @@ export type EdDSAOpts = Partial<{
139
118
  */
140
119
  export interface EdDSA {
141
120
  keygen: (seed?: Uint8Array) => { secretKey: Uint8Array; publicKey: Uint8Array };
142
- getPublicKey: (secretKey: Hex) => Uint8Array;
143
- sign: (message: Hex, secretKey: Hex, options?: { context?: Hex }) => Uint8Array;
121
+ getPublicKey: (secretKey: Uint8Array) => Uint8Array;
122
+ sign: (
123
+ message: Uint8Array,
124
+ secretKey: Uint8Array,
125
+ options?: { context?: Uint8Array }
126
+ ) => Uint8Array;
144
127
  verify: (
145
- sig: Hex,
146
- message: Hex,
147
- publicKey: Hex,
148
- options?: { context?: Hex; zip215: boolean }
128
+ sig: Uint8Array,
129
+ message: Uint8Array,
130
+ publicKey: Uint8Array,
131
+ options?: { context?: Uint8Array; zip215: boolean }
149
132
  ) => boolean;
150
133
  Point: EdwardsPointCons;
151
134
  utils: {
@@ -155,6 +138,12 @@ export interface EdDSA {
155
138
 
156
139
  /**
157
140
  * Converts ed public key to x public key.
141
+ *
142
+ * There is NO `fromMontgomery`:
143
+ * - There are 2 valid ed25519 points for every x25519, with flipped coordinate
144
+ * - Sometimes there are 0 valid ed25519 points, because x25519 *additionally*
145
+ * accepts inputs on the quadratic twist, which can't be moved to ed25519
146
+ *
158
147
  * @example
159
148
  * ```js
160
149
  * const someonesPub = ed25519.getPublicKey(ed25519.utils.randomSecretKey());
@@ -173,18 +162,13 @@ export interface EdDSA {
173
162
  * ```
174
163
  */
175
164
  toMontgomeryPriv: (privateKey: Uint8Array) => Uint8Array;
176
- getExtendedPublicKey: (key: Hex) => {
165
+ getExtendedPublicKey: (key: Uint8Array) => {
177
166
  head: Uint8Array;
178
167
  prefix: Uint8Array;
179
168
  scalar: bigint;
180
169
  point: EdwardsPoint;
181
170
  pointBytes: Uint8Array;
182
171
  };
183
-
184
- /** @deprecated use `randomSecretKey` */
185
- randomPrivateKey: (seed?: Uint8Array) => Uint8Array;
186
- /** @deprecated use `point.precompute()` */
187
- precompute: (windowSize?: number, point?: EdwardsPoint) => EdwardsPoint;
188
172
  };
189
173
  lengths: CurveLengths;
190
174
  }
@@ -201,7 +185,7 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
201
185
  const validated = _createCurveFields('edwards', params, extraOpts, extraOpts.FpFnLE);
202
186
  const { Fp, Fn } = validated;
203
187
  let CURVE = validated.CURVE as EdwardsOpts;
204
- const { h: cofactor, n: CURVE_ORDER } = CURVE;
188
+ const { h: cofactor } = CURVE;
205
189
  _validateObject(extraOpts, {}, { uvRatio: 'function' });
206
190
 
207
191
  // Important:
@@ -300,7 +284,7 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
300
284
  }
301
285
 
302
286
  static CURVE(): EdwardsOpts {
303
- return CURVE as EdwardsOpts;
287
+ return CURVE;
304
288
  }
305
289
 
306
290
  static fromAffine(p: AffinePoint<bigint>): Point {
@@ -327,7 +311,7 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
327
311
  // zip215=true: 0 <= y < MASK (2^256 for ed25519)
328
312
  // zip215=false: 0 <= y < P (2^255-19 for ed25519)
329
313
  const max = zip215 ? MASK : Fp.ORDER;
330
- aInRange('pointHex.y', y, _0n, max);
314
+ aInRange('point.y', y, _0n, max);
331
315
 
332
316
  // Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
333
317
  // ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
@@ -335,17 +319,18 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
335
319
  const u = modP(y2 - _1n); // u = y² - 1
336
320
  const v = modP(d * y2 - a); // v = d y² + 1.
337
321
  let { isValid, value: x } = uvRatio(u, v); // √(u/v)
338
- if (!isValid) throw new Error('Point.fromHex: invalid y coordinate');
322
+ if (!isValid) throw new Error('bad point: invalid y coordinate');
339
323
  const isXOdd = (x & _1n) === _1n; // There are 2 square roots. Use x_0 bit to select proper
340
324
  const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit
341
325
  if (!zip215 && x === _0n && isLastByteOdd)
342
326
  // if x=0 and x_0 = 1, fail
343
- throw new Error('Point.fromHex: x=0 and x_0=1');
327
+ throw new Error('bad point: x=0 and x_0=1');
344
328
  if (isLastByteOdd !== isXOdd) x = modP(-x); // if x_0 != x mod 2, set x = p-x
345
329
  return Point.fromAffine({ x, y });
346
330
  }
347
- static fromHex(bytes: Uint8Array, zip215 = false): Point {
348
- return Point.fromBytes(ensureBytes('point', bytes), zip215);
331
+
332
+ static fromHex(hex: string, zip215 = false): Point {
333
+ return Point.fromBytes(hexToBytes(hex), zip215);
349
334
  }
350
335
 
351
336
  get x(): bigint {
@@ -438,9 +423,9 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
438
423
 
439
424
  // Constant-time multiplication.
440
425
  multiply(scalar: bigint): Point {
441
- const n = scalar;
442
- aInRange('scalar', n, _1n, CURVE_ORDER); // 1 <= scalar < L
443
- const { p, f } = wnaf.cached(this, n, (p) => normalizeZ(Point, p));
426
+ // 1 <= scalar < L
427
+ if (!Fn.isValidNot0(scalar)) throw new Error('invalid scalar: expected 1 <= sc < curve.n');
428
+ const { p, f } = wnaf.cached(this, scalar, (p) => normalizeZ(Point, p));
444
429
  return normalizeZ(Point, [p, f])[0];
445
430
  }
446
431
 
@@ -450,11 +435,11 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
450
435
  // Does NOT allow scalars higher than CURVE.n.
451
436
  // Accepts optional accumulator to merge with multiply (important for sparse scalars)
452
437
  multiplyUnsafe(scalar: bigint, acc = Point.ZERO): Point {
453
- const n = scalar;
454
- aInRange('scalar', n, _0n, CURVE_ORDER); // 0 <= scalar < L
455
- if (n === _0n) return Point.ZERO;
456
- if (this.is0() || n === _1n) return this;
457
- return wnaf.unsafe(this, n, (p) => normalizeZ(Point, p), acc);
438
+ // 0 <= scalar < L
439
+ if (!Fn.isValid(scalar)) throw new Error('invalid scalar: expected 0 <= sc < curve.n');
440
+ if (scalar === _0n) return Point.ZERO;
441
+ if (this.is0() || scalar === _1n) return this;
442
+ return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point, p), acc);
458
443
  }
459
444
 
460
445
  // Checks if point is of small order.
@@ -468,7 +453,7 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
468
453
  // Multiplies point by curve order and checks if the result is 0.
469
454
  // Returns `false` is the point is dirty.
470
455
  isTorsionFree(): boolean {
471
- return wnaf.unsafe(this, CURVE_ORDER).is0();
456
+ return wnaf.unsafe(this, CURVE.n).is0();
472
457
  }
473
458
 
474
459
  // Converts Extended point to default (x, y) coordinates.
@@ -484,13 +469,12 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
484
469
 
485
470
  toBytes(): Uint8Array {
486
471
  const { x, y } = this.toAffine();
487
- const bytes = numberToBytesLE(y, Fp.BYTES); // each y has 2 x values (x, -y)
488
- bytes[bytes.length - 1] |= x & _1n ? 0x80 : 0; // when compressing, it's enough to store y
489
- return bytes; // and use the last byte to encode sign of x
490
- }
491
- /** @deprecated use `toBytes` */
492
- toRawBytes(): Uint8Array {
493
- return this.toBytes();
472
+ // Fp.toBytes() allows non-canonical encoding of y (>= p).
473
+ const bytes = Fp.toBytes(y);
474
+ // Each y has 2 valid points: (x, y), (x,-y).
475
+ // When compressing, it's enough to store y and use the last byte to encode sign of x
476
+ bytes[bytes.length - 1] |= x & _1n ? 0x80 : 0;
477
+ return bytes;
494
478
  }
495
479
  toHex(): string {
496
480
  return bytesToHex(this.toBytes());
@@ -499,31 +483,9 @@ export function edwards(params: EdwardsOpts, extraOpts: EdwardsExtraOpts = {}):
499
483
  toString() {
500
484
  return `<Point ${this.is0() ? 'ZERO' : this.toHex()}>`;
501
485
  }
502
-
503
- // TODO: remove
504
- get ex(): bigint {
505
- return this.X;
506
- }
507
- get ey(): bigint {
508
- return this.Y;
509
- }
510
- get ez(): bigint {
511
- return this.Z;
512
- }
513
- get et(): bigint {
514
- return this.T;
515
- }
516
- static normalizeZ(points: Point[]): Point[] {
517
- return normalizeZ(Point, points);
518
- }
519
- static msm(points: Point[], scalars: bigint[]): Point {
520
- return pippenger(Point, Fn, points, scalars);
521
- }
522
- _setWindowSize(windowSize: number) {
523
- this.precompute(windowSize);
524
- }
525
486
  }
526
- const wnaf = new wNAF(Point, Fn.BYTES * 8); // Fn.BITS?
487
+ const wnaf = new wNAF(Point, Fn.BITS);
488
+ Point.BASE.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
527
489
  return Point;
528
490
  }
529
491
 
@@ -555,7 +517,7 @@ export abstract class PrimeEdwardsPoint<T extends PrimeEdwardsPoint<T>>
555
517
  notImplemented();
556
518
  }
557
519
 
558
- static fromHex(_hex: Hex): any {
520
+ static fromHex(_hex: string): any {
559
521
  notImplemented();
560
522
  }
561
523
 
@@ -580,11 +542,6 @@ export abstract class PrimeEdwardsPoint<T extends PrimeEdwardsPoint<T>>
580
542
  return this.ep.toAffine(invertedZ);
581
543
  }
582
544
 
583
- /** @deprecated use `toBytes` */
584
- toRawBytes(): Uint8Array {
585
- return this.toBytes();
586
- }
587
-
588
545
  toHex(): string {
589
546
  return bytesToHex(this.toBytes());
590
547
  }
@@ -655,11 +612,10 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
655
612
  );
656
613
 
657
614
  const { prehash } = eddsaOpts;
658
- const { BASE: G, Fp, Fn } = Point;
659
- const CURVE_ORDER = Fn.ORDER;
615
+ const { BASE, Fp, Fn } = Point;
660
616
 
661
- const randomBytes_ = eddsaOpts.randomBytes || randomBytes;
662
- const adjustScalarBytes = eddsaOpts.adjustScalarBytes || ((bytes: Uint8Array) => bytes); // NOOP
617
+ const randomBytes = eddsaOpts.randomBytes || wcRandomBytes;
618
+ const adjustScalarBytes = eddsaOpts.adjustScalarBytes || ((bytes: Uint8Array) => bytes);
663
619
  const domain =
664
620
  eddsaOpts.domain ||
665
621
  ((data: Uint8Array, ctx: Uint8Array, phflag: boolean) => {
@@ -668,23 +624,18 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
668
624
  return data;
669
625
  }); // NOOP
670
626
 
671
- function modN(a: bigint) {
672
- return Fn.create(a);
673
- }
674
-
675
627
  // Little-endian SHA512 with modulo n
676
628
  function modN_LE(hash: Uint8Array): bigint {
677
- // Not using Fn.fromBytes: hash can be 2*Fn.BYTES
678
- return modN(bytesToNumberLE(hash));
629
+ return Fn.create(bytesToNumberLE(hash)); // Not Fn.fromBytes: it has length limit
679
630
  }
680
631
 
681
632
  // Get the hashed private scalar per RFC8032 5.1.5
682
- function getPrivateScalar(key: Hex) {
683
- const len = lengths.secret;
684
- key = ensureBytes('private key', key, len);
633
+ function getPrivateScalar(key: Uint8Array) {
634
+ const len = lengths.secretKey;
635
+ abytes(key, lengths.secretKey, 'secretKey');
685
636
  // Hash private key with curve's hash function to produce uniformingly random input
686
637
  // Check byte lengths: ensure(64, h(ensure(32, key)))
687
- const hashed = ensureBytes('hashed private key', cHash(key), 2 * len);
638
+ const hashed = abytes(cHash(key), 2 * len, 'hashedSecretKey');
688
639
  const head = adjustScalarBytes(hashed.slice(0, len)); // clear first half bits, produce FE
689
640
  const prefix = hashed.slice(len, 2 * len); // second half is called key prefix (5.1.6)
690
641
  const scalar = modN_LE(head); // The actual private scalar
@@ -692,52 +643,60 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
692
643
  }
693
644
 
694
645
  /** Convenience method that creates public key from scalar. RFC8032 5.1.5 */
695
- function getExtendedPublicKey(secretKey: Hex) {
646
+ function getExtendedPublicKey(secretKey: Uint8Array) {
696
647
  const { head, prefix, scalar } = getPrivateScalar(secretKey);
697
- const point = G.multiply(scalar); // Point on Edwards curve aka public key
648
+ const point = BASE.multiply(scalar); // Point on Edwards curve aka public key
698
649
  const pointBytes = point.toBytes();
699
650
  return { head, prefix, scalar, point, pointBytes };
700
651
  }
701
652
 
702
653
  /** Calculates EdDSA pub key. RFC8032 5.1.5. */
703
- function getPublicKey(secretKey: Hex): Uint8Array {
654
+ function getPublicKey(secretKey: Uint8Array): Uint8Array {
704
655
  return getExtendedPublicKey(secretKey).pointBytes;
705
656
  }
706
657
 
707
658
  // int('LE', SHA512(dom2(F, C) || msgs)) mod N
708
- function hashDomainToScalar(context: Hex = Uint8Array.of(), ...msgs: Uint8Array[]) {
659
+ function hashDomainToScalar(context: Uint8Array = Uint8Array.of(), ...msgs: Uint8Array[]) {
709
660
  const msg = concatBytes(...msgs);
710
- return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash)));
661
+ return modN_LE(cHash(domain(msg, abytes(context, undefined, 'context'), !!prehash)));
711
662
  }
712
663
 
713
664
  /** Signs message with privateKey. RFC8032 5.1.6 */
714
- function sign(msg: Hex, secretKey: Hex, options: { context?: Hex } = {}): Uint8Array {
715
- msg = ensureBytes('message', msg);
665
+ function sign(
666
+ msg: Uint8Array,
667
+ secretKey: Uint8Array,
668
+ options: { context?: Uint8Array } = {}
669
+ ): Uint8Array {
670
+ msg = abytes(msg, undefined, 'message');
716
671
  if (prehash) msg = prehash(msg); // for ed25519ph etc.
717
672
  const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);
718
673
  const r = hashDomainToScalar(options.context, prefix, msg); // r = dom2(F, C) || prefix || PH(M)
719
- const R = G.multiply(r).toBytes(); // R = rG
674
+ const R = BASE.multiply(r).toBytes(); // R = rG
720
675
  const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
721
- const s = modN(r + k * scalar); // S = (r + k * s) mod L
722
- aInRange('signature.s', s, _0n, CURVE_ORDER); // 0 <= s < l
723
- const L = Fp.BYTES;
724
- const res = concatBytes(R, numberToBytesLE(s, L));
725
- return ensureBytes('result', res, L * 2); // 64-byte signature
676
+ const s = Fn.create(r + k * scalar); // S = (r + k * s) mod L
677
+ if (!Fn.isValid(s)) throw new Error('sign failed: invalid s'); // 0 <= s < L
678
+ const rs = concatBytes(R, Fn.toBytes(s));
679
+ return abytes(rs, lengths.signature, 'result');
726
680
  }
727
681
 
728
682
  // verification rule is either zip215 or rfc8032 / nist186-5. Consult fromHex:
729
- const verifyOpts: { context?: Hex; zip215?: boolean } = { zip215: true };
683
+ const verifyOpts: { context?: Uint8Array; zip215?: boolean } = { zip215: true };
730
684
 
731
685
  /**
732
686
  * Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
733
687
  * An extended group equation is checked.
734
688
  */
735
- function verify(sig: Hex, msg: Hex, publicKey: Hex, options = verifyOpts): boolean {
689
+ function verify(
690
+ sig: Uint8Array,
691
+ msg: Uint8Array,
692
+ publicKey: Uint8Array,
693
+ options = verifyOpts
694
+ ): boolean {
736
695
  const { context, zip215 } = options;
737
- const len = lengths.signature; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
738
- sig = ensureBytes('signature', sig, len); // An extended group equation is checked.
739
- msg = ensureBytes('message', msg);
740
- publicKey = ensureBytes('publicKey', publicKey, lengths.public);
696
+ const len = lengths.signature;
697
+ sig = abytes(sig, len, 'signature');
698
+ msg = abytes(msg, undefined, 'message');
699
+ publicKey = abytes(publicKey, lengths.publicKey, 'publicKey');
741
700
  if (zip215 !== undefined) abool(zip215, 'zip215');
742
701
  if (prehash) msg = prehash(msg); // for ed25519ph, etc
743
702
 
@@ -751,11 +710,11 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
751
710
  // zip215=false: 0 <= y < P (2^255-19 for ed25519)
752
711
  A = Point.fromBytes(publicKey, zip215);
753
712
  R = Point.fromBytes(r, zip215);
754
- SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
713
+ SB = BASE.multiplyUnsafe(s); // 0 <= s < l is done inside
755
714
  } catch (error) {
756
715
  return false;
757
716
  }
758
- if (!zip215 && A.isSmallOrder()) return false;
717
+ if (!zip215 && A.isSmallOrder()) return false; // zip215 allows public keys of small order
759
718
 
760
719
  const k = hashDomainToScalar(context, R.toBytes(), A.toBytes(), msg);
761
720
  const RkA = R.add(A.multiplyUnsafe(k));
@@ -764,16 +723,14 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
764
723
  return RkA.subtract(SB).clearCofactor().is0();
765
724
  }
766
725
 
767
- G.precompute(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
768
-
769
- const _size = Fp.BYTES;
726
+ const _size = Fp.BYTES; // 32 for ed25519, 57 for ed448
770
727
  const lengths = {
771
- secret: _size,
772
- public: _size,
728
+ secretKey: _size,
729
+ publicKey: _size,
773
730
  signature: 2 * _size,
774
731
  seed: _size,
775
732
  };
776
- function randomSecretKey(seed = randomBytes_!(lengths.seed)): Uint8Array {
733
+ function randomSecretKey(seed = randomBytes(lengths.seed)): Uint8Array {
777
734
  return abytes(seed, lengths.seed, 'seed');
778
735
  }
779
736
  function keygen(seed?: Uint8Array) {
@@ -782,11 +739,7 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
782
739
  }
783
740
 
784
741
  function isValidSecretKey(key: Uint8Array): boolean {
785
- try {
786
- return !!Fn.fromBytes(key, false);
787
- } catch (error) {
788
- return false;
789
- }
742
+ return isBytes(key) && key.length === Fn.BYTES;
790
743
  }
791
744
 
792
745
  function isValidPublicKey(key: Uint8Array, zip215?: boolean): boolean {
@@ -810,34 +763,21 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
810
763
  * - ed448:
811
764
  * - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
812
765
  * - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
813
- *
814
- * There is NO `fromMontgomery`:
815
- * - There are 2 valid ed25519 points for every x25519, with flipped coordinate
816
- * - Sometimes there are 0 valid ed25519 points, because x25519 *additionally*
817
- * accepts inputs on the quadratic twist, which can't be moved to ed25519
818
766
  */
819
767
  toMontgomery(publicKey: Uint8Array): Uint8Array {
820
768
  const { y } = Point.fromBytes(publicKey);
821
- const size = lengths.public;
769
+ const size = lengths.publicKey;
822
770
  const is25519 = size === 32;
823
771
  if (!is25519 && size !== 57) throw new Error('only defined for 25519 and 448');
824
772
  const u = is25519 ? Fp.div(_1n + y, _1n - y) : Fp.div(y - _1n, y + _1n);
825
773
  return Fp.toBytes(u);
826
774
  },
827
-
828
775
  toMontgomeryPriv(secretKey: Uint8Array): Uint8Array {
829
- const size = lengths.secret;
776
+ const size = lengths.secretKey;
830
777
  abytes(secretKey, size);
831
778
  const hashed = cHash(secretKey.subarray(0, size));
832
779
  return adjustScalarBytes(hashed).subarray(0, size);
833
780
  },
834
-
835
- /** @deprecated */
836
- randomPrivateKey: randomSecretKey,
837
- /** @deprecated */
838
- precompute(windowSize = 8, point: EdwardsPoint = Point.BASE): EdwardsPoint {
839
- return point.precompute(windowSize, false);
840
- },
841
781
  };
842
782
 
843
783
  return Object.freeze({
@@ -848,72 +788,5 @@ export function eddsa(Point: EdwardsPointCons, cHash: FHash, eddsaOpts: EdDSAOpt
848
788
  utils,
849
789
  Point,
850
790
  lengths,
851
- });
852
- }
853
-
854
- // TODO: remove everything below
855
- export type CurveType = BasicCurve<bigint> & {
856
- a: bigint; // curve param a
857
- d: bigint; // curve param d
858
- /** @deprecated the property will be removed in next release */
859
- hash: FHash; // Hashing
860
- randomBytes?: (bytesLength?: number) => Uint8Array; // CSPRNG
861
- adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array; // clears bits to get valid field elemtn
862
- domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array; // Used for hashing
863
- uvRatio?: UVRatio; // Ratio √(u/v)
864
- prehash?: FHash; // RFC 8032 pre-hashing of messages to sign() / verify()
865
- mapToCurve?: (scalar: bigint[]) => AffinePoint<bigint>; // for hash-to-curve standard
866
- };
867
- export type CurveTypeWithLength = Readonly<CurveType & Partial<NLength>>;
868
- export type CurveFn = {
869
- /** @deprecated the property will be removed in next release */
870
- CURVE: CurveType;
871
- keygen: EdDSA['keygen'];
872
- getPublicKey: EdDSA['getPublicKey'];
873
- sign: EdDSA['sign'];
874
- verify: EdDSA['verify'];
875
- Point: EdwardsPointCons;
876
- /** @deprecated use `Point` */
877
- ExtendedPoint: EdwardsPointCons;
878
- utils: EdDSA['utils'];
879
- lengths: CurveLengths;
880
- };
881
- export type EdComposed = {
882
- CURVE: EdwardsOpts;
883
- curveOpts: EdwardsExtraOpts;
884
- hash: FHash;
885
- eddsaOpts: EdDSAOpts;
886
- };
887
- function _eddsa_legacy_opts_to_new(c: CurveTypeWithLength): EdComposed {
888
- const CURVE: EdwardsOpts = {
889
- a: c.a,
890
- d: c.d,
891
- p: c.Fp.ORDER,
892
- n: c.n,
893
- h: c.h,
894
- Gx: c.Gx,
895
- Gy: c.Gy,
896
- };
897
- const Fp = c.Fp;
898
- const Fn = Field(CURVE.n, c.nBitLength, true);
899
- const curveOpts: EdwardsExtraOpts = { Fp, Fn, uvRatio: c.uvRatio };
900
- const eddsaOpts: EdDSAOpts = {
901
- randomBytes: c.randomBytes,
902
- adjustScalarBytes: c.adjustScalarBytes,
903
- domain: c.domain,
904
- prehash: c.prehash,
905
- mapToCurve: c.mapToCurve,
906
- };
907
- return { CURVE, curveOpts, hash: c.hash, eddsaOpts };
908
- }
909
- function _eddsa_new_output_to_legacy(c: CurveTypeWithLength, eddsa: EdDSA): CurveFn {
910
- const legacy = Object.assign({}, eddsa, { ExtendedPoint: eddsa.Point, CURVE: c });
911
- return legacy;
912
- }
913
- // TODO: remove. Use eddsa
914
- export function twistedEdwards(c: CurveTypeWithLength): CurveFn {
915
- const { CURVE, curveOpts, hash, eddsaOpts } = _eddsa_legacy_opts_to_new(c);
916
- const Point = edwards(CURVE, curveOpts);
917
- const EDDSA = eddsa(Point, hash, eddsaOpts);
918
- return _eddsa_new_output_to_legacy(c, EDDSA);
791
+ }) satisfies Signer;
919
792
  }