@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
package/src/ed448.ts CHANGED
@@ -14,34 +14,31 @@ import {
14
14
  utf8ToBytes,
15
15
  createHasher as wrapConstructor,
16
16
  } from '@noble/hashes/utils.js';
17
- import type { AffinePoint, Group } from './abstract/curve.ts';
17
+ import type { AffinePoint } from './abstract/curve.ts';
18
18
  import { pippenger } from './abstract/curve.ts';
19
19
  import {
20
- type CurveFn,
21
20
  edwards,
22
- type EdwardsOpts,
23
- type ExtPointConstructor,
24
- type ExtPointType,
21
+ PrimeEdwardsPoint,
25
22
  twistedEdwards,
23
+ type CurveFn,
24
+ type EdwardsOpts,
25
+ type EdwardsPoint,
26
+ type EdwardsPointCons,
26
27
  } from './abstract/edwards.ts';
27
28
  import {
29
+ _DST_scalar,
28
30
  createHasher,
29
31
  expand_message_xof,
30
32
  type H2CHasher,
33
+ type H2CHasherBase,
31
34
  type H2CMethod,
32
35
  type htfBasicOpts,
33
36
  } from './abstract/hash-to-curve.ts';
34
- import { Field, FpInvertBatch, isNegativeLE, mod, pow2 } from './abstract/modular.ts';
35
- import { montgomery, type CurveFn as XCurveFn } from './abstract/montgomery.ts';
36
- import {
37
- bytesToHex,
38
- bytesToNumberLE,
39
- ensureBytes,
40
- equalBytes,
41
- type Hex,
42
- numberToBytesLE,
43
- } from './utils.ts';
37
+ import { Field, FpInvertBatch, isNegativeLE, mod, pow2, type IField } from './abstract/modular.ts';
38
+ import { montgomery, type MontgomeryECDH as XCurveFn } from './abstract/montgomery.ts';
39
+ import { bytesToNumberLE, ensureBytes, equalBytes, numberToBytesLE, type Hex } from './utils.ts';
44
40
 
41
+ // edwards448 curve
45
42
  // a = 1n
46
43
  // d = Fp.neg(39081n)
47
44
  // Finite field 2n**448n - 2n**224n - 1n
@@ -67,9 +64,7 @@ const ed448_CURVE: EdwardsOpts = {
67
64
  ),
68
65
  };
69
66
 
70
- // E448 != Edwards448 used in ed448
71
- // E448 is defined by NIST
72
- // It's birationally equivalent to edwards448
67
+ // E448 NIST curve is identical to edwards448, except for:
73
68
  // d = 39082/39081
74
69
  // Gx = 3/2
75
70
  const E448_CURVE: EdwardsOpts = Object.assign({}, ed448_CURVE, {
@@ -83,7 +78,6 @@ const E448_CURVE: EdwardsOpts = Object.assign({}, ed448_CURVE, {
83
78
  '0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000001'
84
79
  ),
85
80
  });
86
- export const E448: ExtPointConstructor = edwards(E448_CURVE);
87
81
 
88
82
  const shake256_114 = /* @__PURE__ */ wrapConstructor(() => shake256.create({ dkLen: 114 }));
89
83
  const shake256_64 = /* @__PURE__ */ wrapConstructor(() => shake256.create({ dkLen: 64 }));
@@ -147,13 +141,16 @@ function uvRatio(u: bigint, v: bigint): { isValid: boolean; value: bigint } {
147
141
  }
148
142
 
149
143
  // Finite field 2n**448n - 2n**224n - 1n
150
- const Fp = /* @__PURE__ */ (() => Field(ed448_CURVE.p, 456, true))();
144
+ const Fp = /* @__PURE__ */ (() => Field(ed448_CURVE.p, { BITS: 456, isLE: true }))();
151
145
  // RFC 7748 has 56-byte keys, RFC 8032 has 57-byte keys
146
+ const Fn = /* @__PURE__ */ (() => Field(ed448_CURVE.n, { BITS: 448, isLE: true }))();
147
+ // const Fn456 = /* @__PURE__ */ (() => Field(ed448_CURVE.n, { BITS: 456, isLE: true }))();
148
+
152
149
  // SHAKE256(dom4(phflag,context)||x, 114)
153
150
  const ED448_DEF = /* @__PURE__ */ (() => ({
154
151
  ...ed448_CURVE,
155
152
  Fp,
156
- nBitLength: 456,
153
+ Fn,
157
154
  hash: shake256_114,
158
155
  adjustScalarBytes,
159
156
  // dom4
@@ -173,20 +170,28 @@ const ED448_DEF = /* @__PURE__ */ (() => ({
173
170
  * ed448 EdDSA curve and methods.
174
171
  * @example
175
172
  * import { ed448 } from '@noble/curves/ed448';
176
- * const priv = ed448.utils.randomPrivateKey();
177
- * const pub = ed448.getPublicKey(priv);
178
- * const msg = new TextEncoder().encode('whatsup');
179
- * const sig = ed448.sign(msg, priv);
180
- * ed448.verify(sig, msg, pub);
173
+ * const { secretKey, publicKey } = ed448.keygen();
174
+ * const msg = new TextEncoder().encode('hello');
175
+ * const sig = ed448.sign(msg, secretKey);
176
+ * const isValid = ed448.verify(sig, msg, publicKey);
181
177
  */
182
178
  export const ed448: CurveFn = twistedEdwards(ED448_DEF);
183
- // NOTE: there is no ed448ctx, since ed448 supports ctx by default
179
+
180
+ // There is no ed448ctx, since ed448 supports ctx by default
181
+ /** Prehashed version of ed448. Accepts already-hashed messages in sign() and verify(). */
184
182
  export const ed448ph: CurveFn = /* @__PURE__ */ (() =>
185
183
  twistedEdwards({
186
184
  ...ED448_DEF,
187
185
  prehash: shake256_64,
188
186
  }))();
189
187
 
188
+ /**
189
+ * E448 curve, defined by NIST.
190
+ * E448 != edwards448 used in ed448.
191
+ * E448 is birationally equivalent to edwards448.
192
+ */
193
+ export const E448: EdwardsPointCons = edwards(E448_CURVE);
194
+
190
195
  /**
191
196
  * ECDH using curve448 aka x448.
192
197
  * x448 has 56-byte keys as per RFC 7748, while
@@ -206,23 +211,13 @@ export const x448: XCurveFn = /* @__PURE__ */ (() => {
206
211
  });
207
212
  })();
208
213
 
209
- /**
210
- * Converts edwards448 public key to x448 public key. Uses formula:
211
- * * `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
212
- * * `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
213
- * @example
214
- * const aPub = ed448.getPublicKey(utils.randomPrivateKey());
215
- * x448.getSharedSecret(edwardsToMontgomery(aPub), edwardsToMontgomery(someonesPub))
216
- */
214
+ /** @deprecated use `ed448.utils.toMontgomery` */
217
215
  export function edwardsToMontgomeryPub(edwardsPub: string | Uint8Array): Uint8Array {
218
- const bpub = ensureBytes('pub', edwardsPub);
219
- const { y } = ed448.Point.fromHex(bpub);
220
- const _1n = BigInt(1);
221
- return Fp.toBytes(Fp.create((y - _1n) * Fp.inv(y + _1n)));
216
+ return ed448.utils.toMontgomery(ensureBytes('pub', edwardsPub));
222
217
  }
223
218
 
224
- export const edwardsToMontgomery: typeof edwardsToMontgomeryPub = edwardsToMontgomeryPub; // deprecated
225
- // TODO: add edwardsToMontgomeryPriv, similar to ed25519 version
219
+ /** @deprecated use `ed448.utils.toMontgomery` */
220
+ export const edwardsToMontgomery: typeof edwardsToMontgomeryPub = edwardsToMontgomeryPub;
226
221
 
227
222
  // Hash To Curve Elligator2 Map
228
223
  const ELL2_C1 = /* @__PURE__ */ (() => (Fp.ORDER - BigInt(3)) / BigInt(4))(); // 1. c1 = (q - 3) / 4 # Integer arithmetic
@@ -301,6 +296,7 @@ function map_to_curve_elligator2_edwards448(u: bigint) {
301
296
  return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
302
297
  }
303
298
 
299
+ /** Hashing / encoding to ed448 points / field. RFC 9380 methods. */
304
300
  export const ed448_hasher: H2CHasher<bigint> = /* @__PURE__ */ (() =>
305
301
  createHasher(ed448.Point, (scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]), {
306
302
  DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
@@ -311,13 +307,6 @@ export const ed448_hasher: H2CHasher<bigint> = /* @__PURE__ */ (() =>
311
307
  expand: 'xof',
312
308
  hash: shake256,
313
309
  }))();
314
- export const hashToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() => ed448_hasher.hashToCurve)();
315
- export const encodeToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() =>
316
- ed448_hasher.encodeToCurve)();
317
-
318
- function adecafp(other: unknown) {
319
- if (!(other instanceof DcfPoint)) throw new Error('DecafPoint expected');
320
- }
321
310
 
322
311
  // 1-d
323
312
  const ONE_MINUS_D = /* @__PURE__ */ BigInt('39082');
@@ -339,7 +328,7 @@ const MAX_448B = /* @__PURE__ */ BigInt(
339
328
  );
340
329
  const bytes448ToNumberLE = (bytes: Uint8Array) => Fp.create(bytesToNumberLE(bytes) & MAX_448B);
341
330
 
342
- type ExtendedPoint = ExtPointType;
331
+ type ExtendedPoint = EdwardsPoint;
343
332
 
344
333
  /**
345
334
  * Elligator map for hash-to-curve of decaf448.
@@ -375,6 +364,15 @@ function calcElligatorDecafMap(r0: bigint): ExtendedPoint {
375
364
  return new ed448.Point(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
376
365
  }
377
366
 
367
+ function decaf448_map(bytes: Uint8Array): _DecafPoint {
368
+ abytes(bytes, 112);
369
+ const r1 = bytes448ToNumberLE(bytes.slice(0, 56));
370
+ const R1 = calcElligatorDecafMap(r1);
371
+ const r2 = bytes448ToNumberLE(bytes.slice(56, 112));
372
+ const R2 = calcElligatorDecafMap(r2);
373
+ return new _DecafPoint(R1.add(R2));
374
+ }
375
+
378
376
  /**
379
377
  * Each ed448/ExtendedPoint has 4 different equivalent points. This can be
380
378
  * a source of bugs for protocols like ring signatures. Decaf was created to solve this.
@@ -382,58 +380,53 @@ function calcElligatorDecafMap(r0: bigint): ExtendedPoint {
382
380
  * but it should work in its own namespace: do not combine those two.
383
381
  * See [RFC9496](https://www.rfc-editor.org/rfc/rfc9496).
384
382
  */
385
- class DcfPoint implements Group<DcfPoint> {
386
- static BASE: DcfPoint;
387
- static ZERO: DcfPoint;
388
- private readonly ep: ExtendedPoint;
389
- // Private property to discourage combining ExtendedPoint + DecafPoint
390
- // Always use Decaf encoding/decoding instead.
383
+ class _DecafPoint extends PrimeEdwardsPoint<_DecafPoint> {
384
+ // The following gymnastics is done because typescript strips comments otherwise
385
+ // prettier-ignore
386
+ static BASE: _DecafPoint =
387
+ /* @__PURE__ */ (() => new _DecafPoint(ed448.Point.BASE).multiplyUnsafe(_2n))();
388
+ // prettier-ignore
389
+ static ZERO: _DecafPoint =
390
+ /* @__PURE__ */ (() => new _DecafPoint(ed448.Point.ZERO))();
391
+ // prettier-ignore
392
+ static Fp: IField<bigint> =
393
+ /* @__PURE__ */ Fp;
394
+ // prettier-ignore
395
+ static Fn: IField<bigint> =
396
+ /* @__PURE__ */ Fn;
397
+
391
398
  constructor(ep: ExtendedPoint) {
392
- this.ep = ep;
399
+ super(ep);
393
400
  }
394
401
 
395
- static fromAffine(ap: AffinePoint<bigint>): DcfPoint {
396
- return new DcfPoint(ed448.Point.fromAffine(ap));
402
+ static fromAffine(ap: AffinePoint<bigint>): _DecafPoint {
403
+ return new _DecafPoint(ed448.Point.fromAffine(ap));
397
404
  }
398
405
 
399
- /**
400
- * Takes uniform output of 112-byte hash function like shake256 and converts it to `DecafPoint`.
401
- * The hash-to-group operation applies Elligator twice and adds the results.
402
- * **Note:** this is one-way map, there is no conversion from point to hash.
403
- * Described in [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#appendix-C)
404
- * and [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-element-derivation-2).
405
- * @param hex 112-byte output of a hash function
406
- */
407
- static hashToCurve(hex: Hex): DcfPoint {
408
- hex = ensureBytes('decafHash', hex, 112);
409
- const r1 = bytes448ToNumberLE(hex.slice(0, 56));
410
- const R1 = calcElligatorDecafMap(r1);
411
- const r2 = bytes448ToNumberLE(hex.slice(56, 112));
412
- const R2 = calcElligatorDecafMap(r2);
413
- return new DcfPoint(R1.add(R2));
406
+ protected assertSame(other: _DecafPoint): void {
407
+ if (!(other instanceof _DecafPoint)) throw new Error('DecafPoint expected');
414
408
  }
415
409
 
416
- static fromBytes(bytes: Uint8Array): DcfPoint {
417
- abytes(bytes);
418
- return this.fromHex(bytes);
410
+ protected init(ep: EdwardsPoint): _DecafPoint {
411
+ return new _DecafPoint(ep);
419
412
  }
420
413
 
421
- /**
422
- * Converts decaf-encoded string to decaf point.
423
- * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode-2).
424
- * @param hex Decaf-encoded 56 bytes. Not every 56-byte string is valid decaf encoding
425
- */
426
- static fromHex(hex: Hex): DcfPoint {
427
- hex = ensureBytes('decafHex', hex, 56);
414
+ /** @deprecated use `import { decaf448_hasher } from '@noble/curves/ed448.js';` */
415
+ static hashToCurve(hex: Hex): _DecafPoint {
416
+ return decaf448_map(ensureBytes('decafHash', hex, 112));
417
+ }
418
+
419
+ static fromBytes(bytes: Uint8Array): _DecafPoint {
420
+ abytes(bytes, 56);
428
421
  const { d } = ed448.CURVE;
429
422
  const P = Fp.ORDER;
430
423
  const mod = Fp.create;
431
- const emsg = 'DecafPoint.fromHex: the hex is not valid encoding of DecafPoint';
432
- const s = bytes448ToNumberLE(hex);
424
+ const s = bytes448ToNumberLE(bytes);
433
425
 
434
426
  // 1. Check that s_bytes is the canonical encoding of a field element, or else abort.
435
427
  // 2. Check that s is non-negative, or else abort
436
- if (!equalBytes(numberToBytesLE(s, 56), hex) || isNegativeLE(s, P)) throw new Error(emsg);
428
+ if (!equalBytes(numberToBytesLE(s, 56), bytes) || isNegativeLE(s, P))
429
+ throw new Error('invalid decaf448 encoding 1');
437
430
 
438
431
  const s2 = mod(s * s); // 1
439
432
  const u1 = mod(_1n + s2); // 2
@@ -449,13 +442,22 @@ class DcfPoint implements Group<DcfPoint> {
449
442
  const y = mod((_1n - s2) * invsqrt * u1); // 7
450
443
  const t = mod(x * y); // 8
451
444
 
452
- if (!isValid) throw new Error(emsg);
453
- return new DcfPoint(new ed448.Point(x, y, _1n, t));
445
+ if (!isValid) throw new Error('invalid decaf448 encoding 2');
446
+ return new _DecafPoint(new ed448.Point(x, y, _1n, t));
447
+ }
448
+
449
+ /**
450
+ * Converts decaf-encoded string to decaf point.
451
+ * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode-2).
452
+ * @param hex Decaf-encoded 56 bytes. Not every 56-byte string is valid decaf encoding
453
+ */
454
+ static fromHex(hex: Hex): _DecafPoint {
455
+ return _DecafPoint.fromBytes(ensureBytes('decafHex', hex, 56));
454
456
  }
455
457
 
456
- static msm(points: DcfPoint[], scalars: bigint[]): DcfPoint {
457
- const Fn = Field(ed448.CURVE.n, ed448.CURVE.nBitLength);
458
- return pippenger(DcfPoint, Fn, points, scalars);
458
+ /** @deprecated use `import { pippenger } from '@noble/curves/abstract/curve.js';` */
459
+ static msm(points: _DecafPoint[], scalars: bigint[]): _DecafPoint {
460
+ return pippenger(_DecafPoint, Fn, points, scalars);
459
461
  }
460
462
 
461
463
  /**
@@ -463,99 +465,91 @@ class DcfPoint implements Group<DcfPoint> {
463
465
  * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode-2).
464
466
  */
465
467
  toBytes(): Uint8Array {
466
- let { ex: x, ey: _y, ez: z, et: t } = this.ep;
468
+ const { X, Z, T } = this.ep;
467
469
  const P = Fp.ORDER;
468
470
  const mod = Fp.create;
469
471
 
470
- const u1 = mod(mod(x + t) * mod(x - t)); // 1
471
- const x2 = mod(x * x);
472
+ const u1 = mod(mod(X + T) * mod(X - T)); // 1
473
+ const x2 = mod(X * X);
472
474
  const { value: invsqrt } = invertSqrt(mod(u1 * ONE_MINUS_D * x2)); // 2
473
475
 
474
476
  let ratio = mod(invsqrt * u1 * SQRT_MINUS_D); // 3
475
477
  if (isNegativeLE(ratio, P)) ratio = mod(-ratio);
476
478
 
477
- const u2 = mod(INVSQRT_MINUS_D * ratio * z - t); // 4
479
+ const u2 = mod(INVSQRT_MINUS_D * ratio * Z - T); // 4
478
480
 
479
- let s = mod(ONE_MINUS_D * invsqrt * x * u2); // 5
481
+ let s = mod(ONE_MINUS_D * invsqrt * X * u2); // 5
480
482
  if (isNegativeLE(s, P)) s = mod(-s);
481
483
 
482
484
  return numberToBytesLE(s, 56);
483
485
  }
484
486
 
485
- /** @deprecated use `toBytes` */
486
- toRawBytes(): Uint8Array {
487
- return this.toBytes();
488
- }
489
-
490
- toHex(): string {
491
- return bytesToHex(this.toBytes());
492
- }
493
-
494
- toString(): string {
495
- return this.toHex();
496
- }
497
-
498
487
  /**
499
488
  * Compare one point to another.
500
489
  * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals-2).
501
490
  */
502
- equals(other: DcfPoint): boolean {
503
- adecafp(other);
504
- const { ex: X1, ey: Y1 } = this.ep;
505
- const { ex: X2, ey: Y2 } = other.ep;
491
+ equals(other: _DecafPoint): boolean {
492
+ this.assertSame(other);
493
+ const { X: X1, Y: Y1 } = this.ep;
494
+ const { X: X2, Y: Y2 } = other.ep;
506
495
  const mod = Fp.create;
507
496
  // (x1 * y2 == y1 * x2)
508
497
  return mod(X1 * Y2) === mod(Y1 * X2);
509
498
  }
510
499
 
511
- add(other: DcfPoint): DcfPoint {
512
- adecafp(other);
513
- return new DcfPoint(this.ep.add(other.ep));
514
- }
515
-
516
- subtract(other: DcfPoint): DcfPoint {
517
- adecafp(other);
518
- return new DcfPoint(this.ep.subtract(other.ep));
519
- }
520
-
521
- multiply(scalar: bigint): DcfPoint {
522
- return new DcfPoint(this.ep.multiply(scalar));
500
+ is0(): boolean {
501
+ return this.equals(_DecafPoint.ZERO);
523
502
  }
503
+ }
524
504
 
525
- multiplyUnsafe(scalar: bigint): DcfPoint {
526
- return new DcfPoint(this.ep.multiplyUnsafe(scalar));
527
- }
505
+ /** @deprecated use `decaf448.Point` */
506
+ export const DecafPoint: typeof _DecafPoint = _DecafPoint;
507
+ export const decaf448: {
508
+ Point: typeof _DecafPoint;
509
+ } = { Point: _DecafPoint };
510
+
511
+ /** Hashing to decaf448 points / field. RFC 9380 methods. */
512
+ export const decaf448_hasher: H2CHasherBase<bigint> = {
513
+ hashToCurve(msg: Uint8Array, options?: htfBasicOpts): _DecafPoint {
514
+ const DST = options?.DST || 'decaf448_XOF:SHAKE256_D448MAP_RO_';
515
+ return decaf448_map(expand_message_xof(msg, DST, 112, 224, shake256));
516
+ },
517
+ hashToScalar(msg: Uint8Array, options: htfBasicOpts = { DST: _DST_scalar }) {
518
+ return Fn.create(bytesToNumberLE(expand_message_xof(msg, options.DST, 64, 256, shake256)));
519
+ },
520
+ };
528
521
 
529
- double(): DcfPoint {
530
- return new DcfPoint(this.ep.double());
531
- }
522
+ // export const decaf448_oprf: OPRF = createORPF({
523
+ // name: 'decaf448-SHAKE256',
524
+ // Point: DecafPoint,
525
+ // hash: (msg: Uint8Array) => shake256(msg, { dkLen: 64 }),
526
+ // hashToGroup: decaf448_hasher.hashToCurve,
527
+ // hashToScalar: decaf448_hasher.hashToScalar,
528
+ // });
532
529
 
533
- negate(): DcfPoint {
534
- return new DcfPoint(this.ep.negate());
535
- }
536
- }
530
+ type DcfHasher = (msg: Uint8Array, options: htfBasicOpts) => _DecafPoint;
537
531
 
538
- /**
539
- * Wrapper over Edwards Point for decaf448 from
540
- * [RFC9496](https://www.rfc-editor.org/rfc/rfc9496).
541
- */
542
- export const DecafPoint: typeof DcfPoint = /* @__PURE__ */ (() => {
543
- // decaf448 base point is ed448 base x 2
544
- // https://github.com/dalek-cryptography/curve25519-dalek/blob/59837c6ecff02b77b9d5ff84dbc239d0cf33ef90/vendor/ristretto.sage#L699
545
- if (!DcfPoint.BASE) DcfPoint.BASE = new DcfPoint(ed448.Point.BASE).multiply(_2n);
546
- if (!DcfPoint.ZERO) DcfPoint.ZERO = new DcfPoint(ed448.Point.ZERO);
547
- return DcfPoint;
548
- })();
532
+ /** @deprecated use `import { ed448_hasher } from '@noble/curves/ed448.js';` */
533
+ export const hashToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() => ed448_hasher.hashToCurve)();
534
+ /** @deprecated use `import { ed448_hasher } from '@noble/curves/ed448.js';` */
535
+ export const encodeToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() =>
536
+ ed448_hasher.encodeToCurve)();
537
+ /** @deprecated use `import { decaf448_hasher } from '@noble/curves/ed448.js';` */
538
+ export const hashToDecaf448: DcfHasher = /* @__PURE__ */ (() =>
539
+ decaf448_hasher.hashToCurve as DcfHasher)();
540
+ /** @deprecated use `import { decaf448_hasher } from '@noble/curves/ed448.js';` */
541
+ export const hash_to_decaf448: DcfHasher = /* @__PURE__ */ (() =>
542
+ decaf448_hasher.hashToCurve as DcfHasher)();
549
543
 
550
544
  /**
551
- * hash-to-curve for decaf448.
552
- * Described in [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#appendix-C).
545
+ * Weird / bogus points, useful for debugging.
546
+ * Unlike ed25519, there is no ed448 generator point which can produce full T subgroup.
547
+ * Instead, there is a Klein four-group, which spans over 2 independent 2-torsion points:
548
+ * (0, 1), (0, -1), (-1, 0), (1, 0).
553
549
  */
554
- export const hashToDecaf448 = (msg: Uint8Array, options: htfBasicOpts): DcfPoint => {
555
- const d = options.DST;
556
- const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
557
- const uniform_bytes = expand_message_xof(msg, DST, 112, 224, shake256);
558
- const P = DcfPoint.hashToCurve(uniform_bytes);
559
- return P;
560
- };
561
- export const hash_to_decaf448: typeof hashToDecaf448 = hashToDecaf448; // legacy
550
+ export const ED448_TORSION_SUBGROUP: string[] = [
551
+ '010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
552
+ 'fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff00',
553
+ '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
554
+ '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080',
555
+ ];
package/src/index.ts CHANGED
@@ -3,15 +3,13 @@
3
3
  * @module
4
4
  * @example
5
5
  ```js
6
- import { secp256k1, schnorr } from '@noble/curves/secp256k1';
7
- import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519';
8
- import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
9
- import { p256 } from '@noble/curves/p256';
10
- import { p384 } from '@noble/curves/p384';
11
- import { p521 } from '@noble/curves/p521';
12
- import { bls12_381 } from '@noble/curves/bls12-381';
13
- import { bn254 } from '@noble/curves/bn254';
14
- import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/abstract/utils';
6
+ import { secp256k1, schnorr } from '@noble/curves/secp256k1.js';
7
+ import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519.js';
8
+ import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448.js';
9
+ import { p256, p384, p521 } from '@noble/curves/nist.js';
10
+ import { bls12_381 } from '@noble/curves/bls12-381.js';
11
+ import { bn254 } from '@noble/curves/bn254.js';
12
+ import { bytesToHex, hexToBytes, concatBytes, utf8ToBytes } from '@noble/curves/abstract/utils.js';
15
13
  ```
16
14
  */
17
15
  throw new Error('root module cannot be imported: import submodules instead. Check out README');
package/src/jubjub.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  */
5
5
  import { jubjub_findGroupHash, jubjub_groupHash, jubjub as jubjubn } from './misc.ts';
6
6
 
7
- /** @deprecated Use `@noble/curves/misc` module directly. */
7
+ /** @deprecated use `import { jubjub } from '@noble/curves/misc.js';` */
8
8
  export const jubjub: typeof jubjubn = jubjubn;
9
- /** @deprecated Use `@noble/curves/misc` module directly. */
9
+ /** @deprecated use `import { jubjub_findGroupHash } from '@noble/curves/misc.js';` */
10
10
  export const findGroupHash: typeof jubjub_findGroupHash = jubjub_findGroupHash;
11
- /** @deprecated Use `@noble/curves/misc` module directly. */
11
+ /** @deprecated use `import { jubjub_groupHash } from '@noble/curves/misc.js';` */
12
12
  export const groupHash: typeof jubjub_groupHash = jubjub_groupHash;
package/src/misc.ts CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  twistedEdwards,
13
13
  type CurveFn,
14
14
  type EdwardsOpts,
15
- type ExtPointType,
15
+ type EdwardsPoint,
16
16
  } from './abstract/edwards.ts';
17
17
  import { Field, mod } from './abstract/modular.ts';
18
18
  import { weierstrass, type CurveFn as WCurveFn } from './abstract/weierstrass.ts';
@@ -22,8 +22,6 @@ import { bn254_Fr } from './bn254.ts';
22
22
  // Jubjub curves have 𝔽p over scalar fields of other curves. They are friendly to ZK proofs.
23
23
  // jubjub Fp = bls n. babyjubjub Fp = bn254 n.
24
24
  // verify manually, check bls12-381.ts and bn254.ts.
25
- // https://neuromancer.sk/std/other/JubJub
26
-
27
25
  const jubjub_CURVE: EdwardsOpts = {
28
26
  p: bls12_381_Fr.ORDER,
29
27
  n: BigInt('0xe7db4ea6533afa906673b0101343b00a6682093ccc81082d0970e5ed6f72cb7'),
@@ -61,7 +59,7 @@ const jubjub_gh_first_block = utf8ToBytes(
61
59
  );
62
60
 
63
61
  // Returns point at JubJub curve which is prime order and not zero
64
- export function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array): ExtPointType {
62
+ export function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array): EdwardsPoint {
65
63
  const h = blake2s.create({ personalization, dkLen: 32 });
66
64
  h.update(jubjub_gh_first_block);
67
65
  h.update(tag);
@@ -76,7 +74,7 @@ export function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array):
76
74
  // No secret data is leaked here at all.
77
75
  // It operates over public data:
78
76
  // const G_SPEND = jubjub.findGroupHash(Uint8Array.of(), utf8ToBytes('Item_G_'));
79
- export function jubjub_findGroupHash(m: Uint8Array, personalization: Uint8Array): ExtPointType {
77
+ export function jubjub_findGroupHash(m: Uint8Array, personalization: Uint8Array): EdwardsPoint {
80
78
  const tag = concatBytes(m, Uint8Array.of(0));
81
79
  const hashes = [];
82
80
  for (let i = 0; i < 256; i++) {
@@ -99,7 +97,6 @@ export const pasta_q: bigint = BigInt(
99
97
  );
100
98
 
101
99
  /**
102
- * https://neuromancer.sk/std/other/Pallas
103
100
  * @deprecated
104
101
  */
105
102
  export const pallas: WCurveFn = weierstrass({
@@ -113,7 +110,6 @@ export const pallas: WCurveFn = weierstrass({
113
110
  hash: sha256,
114
111
  });
115
112
  /**
116
- * https://neuromancer.sk/std/other/Vesta
117
113
  * @deprecated
118
114
  */
119
115
  export const vesta: WCurveFn = weierstrass({