@noble/curves 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +399 -247
  2. package/_shortw_utils.d.ts +1 -1
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +2 -2
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/edwards.d.ts +7 -2
  7. package/abstract/edwards.d.ts.map +1 -1
  8. package/abstract/edwards.js +7 -2
  9. package/abstract/edwards.js.map +1 -1
  10. package/abstract/hash-to-curve.d.ts +1 -1
  11. package/abstract/hash-to-curve.d.ts.map +1 -1
  12. package/abstract/hash-to-curve.js +14 -8
  13. package/abstract/hash-to-curve.js.map +1 -1
  14. package/abstract/modular.d.ts +55 -13
  15. package/abstract/modular.d.ts.map +1 -1
  16. package/abstract/modular.js +82 -22
  17. package/abstract/modular.js.map +1 -1
  18. package/abstract/poseidon.d.ts.map +1 -1
  19. package/abstract/poseidon.js +39 -41
  20. package/abstract/poseidon.js.map +1 -1
  21. package/abstract/utils.d.ts +43 -5
  22. package/abstract/utils.d.ts.map +1 -1
  23. package/abstract/utils.js +70 -26
  24. package/abstract/utils.js.map +1 -1
  25. package/abstract/weierstrass.d.ts +18 -2
  26. package/abstract/weierstrass.d.ts.map +1 -1
  27. package/abstract/weierstrass.js +40 -22
  28. package/abstract/weierstrass.js.map +1 -1
  29. package/bls12-381.d.ts.map +1 -1
  30. package/bls12-381.js +11 -11
  31. package/bls12-381.js.map +1 -1
  32. package/ed25519.d.ts +33 -20
  33. package/ed25519.d.ts.map +1 -1
  34. package/ed25519.js +60 -38
  35. package/ed25519.js.map +1 -1
  36. package/ed448.d.ts +53 -4
  37. package/ed448.d.ts.map +1 -1
  38. package/ed448.js +217 -38
  39. package/ed448.js.map +1 -1
  40. package/esm/abstract/bls.js +3 -3
  41. package/esm/abstract/bls.js.map +1 -1
  42. package/esm/abstract/edwards.js +7 -2
  43. package/esm/abstract/edwards.js.map +1 -1
  44. package/esm/abstract/hash-to-curve.js +14 -8
  45. package/esm/abstract/hash-to-curve.js.map +1 -1
  46. package/esm/abstract/modular.js +78 -21
  47. package/esm/abstract/modular.js.map +1 -1
  48. package/esm/abstract/poseidon.js +39 -41
  49. package/esm/abstract/poseidon.js.map +1 -1
  50. package/esm/abstract/utils.js +70 -26
  51. package/esm/abstract/utils.js.map +1 -1
  52. package/esm/abstract/weierstrass.js +40 -22
  53. package/esm/abstract/weierstrass.js.map +1 -1
  54. package/esm/bls12-381.js +11 -11
  55. package/esm/bls12-381.js.map +1 -1
  56. package/esm/ed25519.js +60 -38
  57. package/esm/ed25519.js.map +1 -1
  58. package/esm/ed448.js +217 -38
  59. package/esm/ed448.js.map +1 -1
  60. package/esm/jubjub.js +1 -1
  61. package/esm/jubjub.js.map +1 -1
  62. package/esm/p256.js +10 -9
  63. package/esm/p256.js.map +1 -1
  64. package/esm/p384.js +7 -6
  65. package/esm/p384.js.map +1 -1
  66. package/esm/p521.js +7 -6
  67. package/esm/p521.js.map +1 -1
  68. package/esm/package.json +1 -4
  69. package/esm/secp256k1.js +11 -9
  70. package/esm/secp256k1.js.map +1 -1
  71. package/jubjub.js.map +1 -1
  72. package/p256.d.ts +4 -5
  73. package/p256.d.ts.map +1 -1
  74. package/p256.js +10 -10
  75. package/p256.js.map +1 -1
  76. package/p384.d.ts +4 -5
  77. package/p384.d.ts.map +1 -1
  78. package/p384.js +7 -7
  79. package/p384.js.map +1 -1
  80. package/p521.d.ts +4 -5
  81. package/p521.d.ts.map +1 -1
  82. package/p521.js +7 -7
  83. package/p521.js.map +1 -1
  84. package/package.json +7 -9
  85. package/secp256k1.d.ts +5 -5
  86. package/secp256k1.d.ts.map +1 -1
  87. package/secp256k1.js +11 -10
  88. package/secp256k1.js.map +1 -1
  89. package/src/abstract/bls.ts +3 -3
  90. package/src/abstract/edwards.ts +13 -4
  91. package/src/abstract/hash-to-curve.ts +14 -8
  92. package/src/abstract/modular.ts +84 -27
  93. package/src/abstract/poseidon.ts +39 -40
  94. package/src/abstract/utils.ts +77 -33
  95. package/src/abstract/weierstrass.ts +51 -29
  96. package/src/bls12-381.ts +12 -17
  97. package/src/ed25519.ts +105 -75
  98. package/src/ed448.ts +286 -64
  99. package/src/jubjub.ts +1 -1
  100. package/src/p256.ts +13 -14
  101. package/src/p384.ts +12 -13
  102. package/src/p521.ts +12 -13
  103. package/src/secp256k1.ts +60 -55
package/src/ed448.ts CHANGED
@@ -1,14 +1,25 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
2
  import { shake256 } from '@noble/hashes/sha3';
3
3
  import { concatBytes, randomBytes, utf8ToBytes, wrapConstructor } from '@noble/hashes/utils';
4
- import { twistedEdwards } from './abstract/edwards.js';
5
- import { mod, pow2, Field } from './abstract/modular.js';
4
+ import { ExtPointType, twistedEdwards } from './abstract/edwards.js';
5
+ import { mod, pow2, Field, isNegativeLE } from './abstract/modular.js';
6
6
  import { montgomery } from './abstract/montgomery.js';
7
- import * as htf from './abstract/hash-to-curve.js';
7
+ import { createHasher, htfBasicOpts, expand_message_xof } from './abstract/hash-to-curve.js';
8
+ import {
9
+ bytesToHex,
10
+ bytesToNumberLE,
11
+ ensureBytes,
12
+ equalBytes,
13
+ Hex,
14
+ numberToBytesLE,
15
+ } from './abstract/utils.js';
16
+ import { AffinePoint } from './abstract/curve.js';
8
17
 
9
18
  /**
10
19
  * Edwards448 (not Ed448-Goldilocks) curve with following addons:
11
- * * X448 ECDH
20
+ * - X448 ECDH
21
+ * - Decaf cofactor elimination
22
+ * - Elligator hash-to-group / point indistinguishability
12
23
  * Conforms to RFC 8032 https://www.rfc-editor.org/rfc/rfc8032.html#section-5.2
13
24
  */
14
25
 
@@ -18,15 +29,16 @@ const ed448P = BigInt(
18
29
  '726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018365439'
19
30
  );
20
31
 
32
+ // prettier-ignore
33
+ const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4), _11n = BigInt(11);
34
+ // prettier-ignore
35
+ const _22n = BigInt(22), _44n = BigInt(44), _88n = BigInt(88), _223n = BigInt(223);
36
+
21
37
  // powPminus3div4 calculates z = x^k mod p, where k = (p-3)/4.
22
38
  // Used for efficient square root calculation.
23
39
  // ((P-3)/4).toString(2) would produce bits [223x 1, 0, 222x 1]
24
40
  function ed448_pow_Pminus3div4(x: bigint): bigint {
25
41
  const P = ed448P;
26
- // prettier-ignore
27
- const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _11n = BigInt(11);
28
- // prettier-ignore
29
- const _22n = BigInt(22), _44n = BigInt(44), _88n = BigInt(88), _223n = BigInt(223);
30
42
  const b2 = (x * x * x) % P;
31
43
  const b3 = (b2 * b2 * x) % P;
32
44
  const b6 = (pow2(b3, _3n, P) * b3) % P;
@@ -53,8 +65,29 @@ function adjustScalarBytes(bytes: Uint8Array): Uint8Array {
53
65
  return bytes;
54
66
  }
55
67
 
68
+ // Constant-time ratio of u to v. Allows to combine inversion and square root u/√v.
69
+ // Uses algo from RFC8032 5.1.3.
70
+ function uvRatio(u: bigint, v: bigint): { isValid: boolean; value: bigint } {
71
+ const P = ed448P;
72
+ // https://www.rfc-editor.org/rfc/rfc8032#section-5.2.3
73
+ // To compute the square root of (u/v), the first step is to compute the
74
+ // candidate root x = (u/v)^((p+1)/4). This can be done using the
75
+ // following trick, to use a single modular powering for both the
76
+ // inversion of v and the square root:
77
+ // x = (u/v)^((p+1)/4) = u³v(u⁵v³)^((p-3)/4) (mod p)
78
+ const u2v = mod(u * u * v, P); // u²v
79
+ const u3v = mod(u2v * u, P); // u³v
80
+ const u5v3 = mod(u3v * u2v * v, P); // u⁵v³
81
+ const root = ed448_pow_Pminus3div4(u5v3);
82
+ const x = mod(u3v * root, P);
83
+ // Verify that root is exists
84
+ const x2 = mod(x * x, P); // x²
85
+ // If vx² = u, the recovered x-coordinate is x. Otherwise, no
86
+ // square root exists, and the decoding fails.
87
+ return { isValid: mod(x2 * v, P) === u, value: x };
88
+ }
89
+
56
90
  const Fp = Field(ed448P, 456, true);
57
- const _4n = BigInt(4);
58
91
 
59
92
  const ED448_DEF = {
60
93
  // Param: a
@@ -63,7 +96,7 @@ const ED448_DEF = {
63
96
  d: BigInt(
64
97
  '726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358'
65
98
  ),
66
- // Finite field 𝔽p over which we'll do calculations; 2n ** 448n - 2n ** 224n - 1n
99
+ // Finite field 𝔽p over which we'll do calculations; 2n**448n - 2n**224n - 1n
67
100
  Fp,
68
101
  // Subgroup order: how many points curve has;
69
102
  // 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
@@ -94,49 +127,29 @@ const ED448_DEF = {
94
127
  data
95
128
  );
96
129
  },
97
-
98
- // Constant-time ratio of u to v. Allows to combine inversion and square root u/√v.
99
- // Uses algo from RFC8032 5.1.3.
100
- uvRatio: (u: bigint, v: bigint): { isValid: boolean; value: bigint } => {
101
- const P = ed448P;
102
- // https://datatracker.ietf.org/doc/html/rfc8032#section-5.2.3
103
- // To compute the square root of (u/v), the first step is to compute the
104
- // candidate root x = (u/v)^((p+1)/4). This can be done using the
105
- // following trick, to use a single modular powering for both the
106
- // inversion of v and the square root:
107
- // x = (u/v)^((p+1)/4) = u³v(u⁵v³)^((p-3)/4) (mod p)
108
- const u2v = mod(u * u * v, P); // u²v
109
- const u3v = mod(u2v * u, P); // u³v
110
- const u5v3 = mod(u3v * u2v * v, P); // u⁵v³
111
- const root = ed448_pow_Pminus3div4(u5v3);
112
- const x = mod(u3v * root, P);
113
- // Verify that root is exists
114
- const x2 = mod(x * x, P); // x²
115
- // If vx² = u, the recovered x-coordinate is x. Otherwise, no
116
- // square root exists, and the decoding fails.
117
- return { isValid: mod(x2 * v, P) === u, value: x };
118
- },
130
+ uvRatio,
119
131
  } as const;
120
132
 
121
- export const ed448 = twistedEdwards(ED448_DEF);
133
+ export const ed448 = /* @__PURE__ */ twistedEdwards(ED448_DEF);
122
134
  // NOTE: there is no ed448ctx, since ed448 supports ctx by default
123
- export const ed448ph = twistedEdwards({ ...ED448_DEF, prehash: shake256_64 });
124
-
125
- export const x448 = montgomery({
126
- a: BigInt(156326),
127
- montgomeryBits: 448,
128
- nByteLength: 57,
129
- P: ed448P,
130
- Gu: BigInt(5),
131
- powPminus2: (x: bigint): bigint => {
132
- const P = ed448P;
133
- const Pminus3div4 = ed448_pow_Pminus3div4(x);
134
- const Pminus3 = pow2(Pminus3div4, BigInt(2), P);
135
- return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
136
- },
137
- adjustScalarBytes,
138
- randomBytes,
139
- });
135
+ export const ed448ph = /* @__PURE__ */ twistedEdwards({ ...ED448_DEF, prehash: shake256_64 });
136
+
137
+ export const x448 = /* @__PURE__ */ (() =>
138
+ montgomery({
139
+ a: BigInt(156326),
140
+ montgomeryBits: 448,
141
+ nByteLength: 57,
142
+ P: ed448P,
143
+ Gu: BigInt(5),
144
+ powPminus2: (x: bigint): bigint => {
145
+ const P = ed448P;
146
+ const Pminus3div4 = ed448_pow_Pminus3div4(x);
147
+ const Pminus3 = pow2(Pminus3div4, BigInt(2), P);
148
+ return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
149
+ },
150
+ adjustScalarBytes,
151
+ randomBytes,
152
+ }))();
140
153
 
141
154
  /**
142
155
  * Converts edwards448 public key to x448 public key. Uses formula:
@@ -146,11 +159,12 @@ export const x448 = montgomery({
146
159
  * const aPub = ed448.getPublicKey(utils.randomPrivateKey());
147
160
  * x448.getSharedSecret(edwardsToMontgomery(aPub), edwardsToMontgomery(someonesPub))
148
161
  */
149
- export function edwardsToMontgomery(edwardsPub: string | Uint8Array): Uint8Array {
162
+ export function edwardsToMontgomeryPub(edwardsPub: string | Uint8Array): Uint8Array {
150
163
  const { y } = ed448.ExtendedPoint.fromHex(edwardsPub);
151
164
  const _1n = BigInt(1);
152
165
  return Fp.toBytes(Fp.create((y - _1n) * Fp.inv(y + _1n)));
153
166
  }
167
+ export const edwardsToMontgomery = edwardsToMontgomeryPub; // deprecated
154
168
 
155
169
  // Hash To Curve Elligator2 Map
156
170
  const ELL2_C1 = (Fp.ORDER - BigInt(3)) / BigInt(4); // 1. c1 = (q - 3) / 4 # Integer arithmetic
@@ -227,17 +241,225 @@ function map_to_curve_elligator2_edwards448(u: bigint) {
227
241
  return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
228
242
  }
229
243
 
230
- const { hashToCurve, encodeToCurve } = htf.createHasher(
231
- ed448.ExtendedPoint,
232
- (scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]),
233
- {
234
- DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
235
- encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_',
236
- p: Fp.ORDER,
237
- m: 1,
238
- k: 224,
239
- expand: 'xof',
240
- hash: shake256,
241
- }
244
+ const htf = /* @__PURE__ */ (() =>
245
+ createHasher(
246
+ ed448.ExtendedPoint,
247
+ (scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]),
248
+ {
249
+ DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
250
+ encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_',
251
+ p: Fp.ORDER,
252
+ m: 1,
253
+ k: 224,
254
+ expand: 'xof',
255
+ hash: shake256,
256
+ }
257
+ ))();
258
+ export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
259
+ export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
260
+
261
+ function assertDcfPoint(other: unknown) {
262
+ if (!(other instanceof DcfPoint)) throw new Error('DecafPoint expected');
263
+ }
264
+
265
+ // 1-d
266
+ const ONE_MINUS_D = BigInt('39082');
267
+ // 1-2d
268
+ const ONE_MINUS_TWO_D = BigInt('78163');
269
+ // √(-d)
270
+ const SQRT_MINUS_D = BigInt(
271
+ '98944233647732219769177004876929019128417576295529901074099889598043702116001257856802131563896515373927712232092845883226922417596214'
272
+ );
273
+ // 1 / √(-d)
274
+ const INVSQRT_MINUS_D = BigInt(
275
+ '315019913931389607337177038330951043522456072897266928557328499619017160722351061360252776265186336876723201881398623946864393857820716'
276
+ );
277
+ // Calculates 1/√(number)
278
+ const invertSqrt = (number: bigint) => uvRatio(_1n, number);
279
+
280
+ const MAX_448B = BigInt(
281
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
242
282
  );
243
- export { hashToCurve, encodeToCurve };
283
+ const bytes448ToNumberLE = (bytes: Uint8Array) =>
284
+ ed448.CURVE.Fp.create(bytesToNumberLE(bytes) & MAX_448B);
285
+
286
+ type ExtendedPoint = ExtPointType;
287
+
288
+ // Computes Elligator map for Decaf
289
+ // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448-07#name-element-derivation-2
290
+ function calcElligatorDecafMap(r0: bigint): ExtendedPoint {
291
+ const { d } = ed448.CURVE;
292
+ const P = ed448.CURVE.Fp.ORDER;
293
+ const mod = ed448.CURVE.Fp.create;
294
+
295
+ const r = mod(-(r0 * r0)); // 1
296
+ const u0 = mod(d * (r - _1n)); // 2
297
+ const u1 = mod((u0 + _1n) * (u0 - r)); // 3
298
+
299
+ const { isValid: was_square, value: v } = uvRatio(ONE_MINUS_TWO_D, mod((r + _1n) * u1)); // 4
300
+
301
+ let v_prime = v; // 5
302
+ if (!was_square) v_prime = mod(r0 * v);
303
+
304
+ let sgn = _1n; // 6
305
+ if (!was_square) sgn = mod(-_1n);
306
+
307
+ const s = mod(v_prime * (r + _1n)); // 7
308
+ let s_abs = s;
309
+ if (isNegativeLE(s, P)) s_abs = mod(-s);
310
+
311
+ const s2 = s * s;
312
+ const W0 = mod(s_abs * _2n); // 8
313
+ const W1 = mod(s2 + _1n); // 9
314
+ const W2 = mod(s2 - _1n); // 10
315
+ const W3 = mod(v_prime * s * (r - _1n) * ONE_MINUS_TWO_D + sgn); // 11
316
+ return new ed448.ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
317
+ }
318
+
319
+ /**
320
+ * Each ed448/ExtendedPoint has 4 different equivalent points. This can be
321
+ * a source of bugs for protocols like ring signatures. Decaf was created to solve this.
322
+ * Decaf point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
323
+ * but it should work in its own namespace: do not combine those two.
324
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
325
+ */
326
+ class DcfPoint {
327
+ static BASE: DcfPoint;
328
+ static ZERO: DcfPoint;
329
+ // Private property to discourage combining ExtendedPoint + DecafPoint
330
+ // Always use Decaf encoding/decoding instead.
331
+ constructor(private readonly ep: ExtendedPoint) {}
332
+
333
+ static fromAffine(ap: AffinePoint<bigint>) {
334
+ return new DcfPoint(ed448.ExtendedPoint.fromAffine(ap));
335
+ }
336
+
337
+ /**
338
+ * Takes uniform output of 112-byte hash function like shake256 and converts it to `DecafPoint`.
339
+ * The hash-to-group operation applies Elligator twice and adds the results.
340
+ * **Note:** this is one-way map, there is no conversion from point to hash.
341
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448-07#name-element-derivation-2
342
+ * @param hex 112-byte output of a hash function
343
+ */
344
+ static hashToCurve(hex: Hex): DcfPoint {
345
+ hex = ensureBytes('decafHash', hex, 112);
346
+ const r1 = bytes448ToNumberLE(hex.slice(0, 56));
347
+ const R1 = calcElligatorDecafMap(r1);
348
+ const r2 = bytes448ToNumberLE(hex.slice(56, 112));
349
+ const R2 = calcElligatorDecafMap(r2);
350
+ return new DcfPoint(R1.add(R2));
351
+ }
352
+
353
+ /**
354
+ * Converts decaf-encoded string to decaf point.
355
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448-07#name-decode-2
356
+ * @param hex Decaf-encoded 56 bytes. Not every 56-byte string is valid decaf encoding
357
+ */
358
+ static fromHex(hex: Hex): DcfPoint {
359
+ hex = ensureBytes('decafHex', hex, 56);
360
+ const { d } = ed448.CURVE;
361
+ const P = ed448.CURVE.Fp.ORDER;
362
+ const mod = ed448.CURVE.Fp.create;
363
+ const emsg = 'DecafPoint.fromHex: the hex is not valid encoding of DecafPoint';
364
+ const s = bytes448ToNumberLE(hex);
365
+
366
+ // 1. Check that s_bytes is the canonical encoding of a field element, or else abort.
367
+ // 2. Check that s is non-negative, or else abort
368
+ if (!equalBytes(numberToBytesLE(s, 56), hex) || isNegativeLE(s, P)) throw new Error(emsg);
369
+
370
+ const s2 = mod(s * s); // 1
371
+ const u1 = mod(_1n + s2); // 2
372
+ const u1sq = mod(u1 * u1);
373
+ const u2 = mod(u1sq - _4n * d * s2); // 3
374
+
375
+ const { isValid, value: invsqrt } = invertSqrt(mod(u2 * u1sq)); // 4
376
+
377
+ let u3 = mod((s + s) * invsqrt * u1 * SQRT_MINUS_D); // 5
378
+ if (isNegativeLE(u3, P)) u3 = mod(-u3);
379
+
380
+ const x = mod(u3 * invsqrt * u2 * INVSQRT_MINUS_D); // 6
381
+ const y = mod((_1n - s2) * invsqrt * u1); // 7
382
+ const t = mod(x * y); // 8
383
+
384
+ if (!isValid) throw new Error(emsg);
385
+ return new DcfPoint(new ed448.ExtendedPoint(x, y, _1n, t));
386
+ }
387
+
388
+ /**
389
+ * Encodes decaf point to Uint8Array.
390
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448-07#name-encode-2
391
+ */
392
+ toRawBytes(): Uint8Array {
393
+ let { ex: x, ey: _y, ez: z, et: t } = this.ep;
394
+ const P = ed448.CURVE.Fp.ORDER;
395
+ const mod = ed448.CURVE.Fp.create;
396
+
397
+ const u1 = mod(mod(x + t) * mod(x - t)); // 1
398
+ const x2 = mod(x * x);
399
+ const { value: invsqrt } = invertSqrt(mod(u1 * ONE_MINUS_D * x2)); // 2
400
+
401
+ let ratio = mod(invsqrt * u1 * SQRT_MINUS_D); // 3
402
+ if (isNegativeLE(ratio, P)) ratio = mod(-ratio);
403
+
404
+ const u2 = mod(INVSQRT_MINUS_D * ratio * z - t); // 4
405
+
406
+ let s = mod(ONE_MINUS_D * invsqrt * x * u2); // 5
407
+ if (isNegativeLE(s, P)) s = mod(-s);
408
+
409
+ return numberToBytesLE(s, 56);
410
+ }
411
+
412
+ toHex(): string {
413
+ return bytesToHex(this.toRawBytes());
414
+ }
415
+
416
+ toString(): string {
417
+ return this.toHex();
418
+ }
419
+
420
+ // Compare one point to another.
421
+ // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448-07#name-equals-2
422
+ equals(other: DcfPoint): boolean {
423
+ assertDcfPoint(other);
424
+ const { ex: X1, ey: Y1 } = this.ep;
425
+ const { ex: X2, ey: Y2 } = other.ep;
426
+ const mod = ed448.CURVE.Fp.create;
427
+ // (x1 * y2 == y1 * x2)
428
+ return mod(X1 * Y2) === mod(Y1 * X2);
429
+ }
430
+
431
+ add(other: DcfPoint): DcfPoint {
432
+ assertDcfPoint(other);
433
+ return new DcfPoint(this.ep.add(other.ep));
434
+ }
435
+
436
+ subtract(other: DcfPoint): DcfPoint {
437
+ assertDcfPoint(other);
438
+ return new DcfPoint(this.ep.subtract(other.ep));
439
+ }
440
+
441
+ multiply(scalar: bigint): DcfPoint {
442
+ return new DcfPoint(this.ep.multiply(scalar));
443
+ }
444
+
445
+ multiplyUnsafe(scalar: bigint): DcfPoint {
446
+ return new DcfPoint(this.ep.multiplyUnsafe(scalar));
447
+ }
448
+ }
449
+ export const DecafPoint = /* @__PURE__ */ (() => {
450
+ // decaf448 base point is ed448 base x 2
451
+ // https://github.com/dalek-cryptography/curve25519-dalek/blob/59837c6ecff02b77b9d5ff84dbc239d0cf33ef90/vendor/ristretto.sage#L699
452
+ if (!DcfPoint.BASE) DcfPoint.BASE = new DcfPoint(ed448.ExtendedPoint.BASE).multiply(_2n);
453
+ if (!DcfPoint.ZERO) DcfPoint.ZERO = new DcfPoint(ed448.ExtendedPoint.ZERO);
454
+ return DcfPoint;
455
+ })();
456
+
457
+ // Hashing to decaf448. https://www.rfc-editor.org/rfc/rfc9380#appendix-C
458
+ export const hashToDecaf448 = (msg: Uint8Array, options: htfBasicOpts) => {
459
+ const d = options.DST;
460
+ const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
461
+ const uniform_bytes = expand_message_xof(msg, DST, 112, 224, shake256);
462
+ const P = DcfPoint.hashToCurve(uniform_bytes);
463
+ return P;
464
+ };
465
+ export const hash_to_decaf448 = hashToDecaf448; // legacy
package/src/jubjub.ts CHANGED
@@ -11,7 +11,7 @@ import { Field } from './abstract/modular.js';
11
11
  * jubjub does not use EdDSA, so `hash`/sha512 params are passed because interface expects them.
12
12
  */
13
13
 
14
- export const jubjub = twistedEdwards({
14
+ export const jubjub = /* @__PURE__ */ twistedEdwards({
15
15
  // Params: a, d
16
16
  a: BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000'),
17
17
  d: BigInt('0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1'),
package/src/p256.ts CHANGED
@@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
3
3
  import { sha256 } from '@noble/hashes/sha256';
4
4
  import { Field } from './abstract/modular.js';
5
5
  import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
6
- import * as htf from './abstract/hash-to-curve.js';
6
+ import { createHasher } from './abstract/hash-to-curve.js';
7
7
 
8
8
  // NIST secp256r1 aka p256
9
9
  // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256
@@ -12,12 +12,6 @@ const Fp = Field(BigInt('0xffffffff00000001000000000000000000000000fffffffffffff
12
12
  const CURVE_A = Fp.create(BigInt('-3'));
13
13
  const CURVE_B = BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b');
14
14
 
15
- const mapSWU = mapToCurveSimpleSWU(Fp, {
16
- A: CURVE_A,
17
- B: CURVE_B,
18
- Z: Fp.create(BigInt('-10')),
19
- });
20
-
21
15
  // prettier-ignore
22
16
  export const p256 = createCurve({
23
17
  a: CURVE_A, // Equation params: a, b
@@ -33,10 +27,15 @@ export const p256 = createCurve({
33
27
  } as const, sha256);
34
28
  export const secp256r1 = p256;
35
29
 
36
- const { hashToCurve, encodeToCurve } = htf.createHasher(
37
- secp256r1.ProjectivePoint,
38
- (scalars: bigint[]) => mapSWU(scalars[0]),
39
- {
30
+ const mapSWU = /* @__PURE__ */ (() =>
31
+ mapToCurveSimpleSWU(Fp, {
32
+ A: CURVE_A,
33
+ B: CURVE_B,
34
+ Z: Fp.create(BigInt('-10')),
35
+ }))();
36
+
37
+ const htf = /* @__PURE__ */ (() =>
38
+ createHasher(secp256r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
40
39
  DST: 'P256_XMD:SHA-256_SSWU_RO_',
41
40
  encodeDST: 'P256_XMD:SHA-256_SSWU_NU_',
42
41
  p: Fp.ORDER,
@@ -44,6 +43,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
44
43
  k: 128,
45
44
  expand: 'xmd',
46
45
  hash: sha256,
47
- }
48
- );
49
- export { hashToCurve, encodeToCurve };
46
+ }))();
47
+ export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
48
+ export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
package/src/p384.ts CHANGED
@@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
3
3
  import { sha384 } from '@noble/hashes/sha512';
4
4
  import { Field } from './abstract/modular.js';
5
5
  import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
6
- import * as htf from './abstract/hash-to-curve.js';
6
+ import { createHasher } from './abstract/hash-to-curve.js';
7
7
 
8
8
  // NIST secp384r1 aka p384
9
9
  // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-384
@@ -31,16 +31,15 @@ export const p384 = createCurve({
31
31
  } as const, sha384);
32
32
  export const secp384r1 = p384;
33
33
 
34
- const mapSWU = mapToCurveSimpleSWU(Fp, {
35
- A: CURVE_A,
36
- B: CURVE_B,
37
- Z: Fp.create(BigInt('-12')),
38
- });
34
+ const mapSWU = /* @__PURE__ */ (() =>
35
+ mapToCurveSimpleSWU(Fp, {
36
+ A: CURVE_A,
37
+ B: CURVE_B,
38
+ Z: Fp.create(BigInt('-12')),
39
+ }))();
39
40
 
40
- const { hashToCurve, encodeToCurve } = htf.createHasher(
41
- secp384r1.ProjectivePoint,
42
- (scalars: bigint[]) => mapSWU(scalars[0]),
43
- {
41
+ const htf = /* @__PURE__ */ (() =>
42
+ createHasher(secp384r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
44
43
  DST: 'P384_XMD:SHA-384_SSWU_RO_',
45
44
  encodeDST: 'P384_XMD:SHA-384_SSWU_NU_',
46
45
  p: Fp.ORDER,
@@ -48,6 +47,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
48
47
  k: 192,
49
48
  expand: 'xmd',
50
49
  hash: sha384,
51
- }
52
- );
53
- export { hashToCurve, encodeToCurve };
50
+ }))();
51
+ export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
52
+ export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
package/src/p521.ts CHANGED
@@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
3
3
  import { sha512 } from '@noble/hashes/sha512';
4
4
  import { Field } from './abstract/modular.js';
5
5
  import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
6
- import * as htf from './abstract/hash-to-curve.js';
6
+ import { createHasher } from './abstract/hash-to-curve.js';
7
7
 
8
8
  // NIST secp521r1 aka p521
9
9
  // Note that it's 521, which differs from 512 of its hash function.
@@ -47,16 +47,15 @@ export const p521 = createCurve({
47
47
  } as const, sha512);
48
48
  export const secp521r1 = p521;
49
49
 
50
- const mapSWU = mapToCurveSimpleSWU(Fp, {
51
- A: CURVE.a,
52
- B: CURVE.b,
53
- Z: Fp.create(BigInt('-4')),
54
- });
50
+ const mapSWU = /* @__PURE__ */ (() =>
51
+ mapToCurveSimpleSWU(Fp, {
52
+ A: CURVE.a,
53
+ B: CURVE.b,
54
+ Z: Fp.create(BigInt('-4')),
55
+ }))();
55
56
 
56
- const { hashToCurve, encodeToCurve } = htf.createHasher(
57
- secp521r1.ProjectivePoint,
58
- (scalars: bigint[]) => mapSWU(scalars[0]),
59
- {
57
+ const htf = /* @__PURE__ */ (() =>
58
+ createHasher(secp521r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
60
59
  DST: 'P521_XMD:SHA-512_SSWU_RO_',
61
60
  encodeDST: 'P521_XMD:SHA-512_SSWU_NU_',
62
61
  p: Fp.ORDER,
@@ -64,6 +63,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
64
63
  k: 256,
65
64
  expand: 'xmd',
66
65
  hash: sha512,
67
- }
68
- );
69
- export { hashToCurve, encodeToCurve };
66
+ }))();
67
+ export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
68
+ export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();