@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/bls12-381.ts CHANGED
@@ -13,7 +13,7 @@ BLS can mean 2 different things:
13
13
  ### Summary
14
14
 
15
15
  1. BLS Relies on expensive bilinear pairing
16
- 2. Private Keys: 32 bytes
16
+ 2. Secret Keys: 32 bytes
17
17
  3. Public Keys: 48 OR 96 bytes - big-endian x coordinate of point on G1 OR G2 curve
18
18
  4. Signatures: 96 OR 48 bytes - big-endian x coordinate of point on G2 OR G1 curve
19
19
  5. The 12 stands for the Embedding degree.
@@ -66,7 +66,7 @@ More complicated math is done over polynominal extension fields.
66
66
 
67
67
  ### Compatibility and notes
68
68
  1. It is compatible with Algorand, Chia, Dfinity, Ethereum, Filecoin, ZEC.
69
- Filecoin uses little endian byte arrays for private keys - make sure to reverse byte order.
69
+ Filecoin uses little endian byte arrays for secret keys - make sure to reverse byte order.
70
70
  2. Make sure to correctly select mode: "long signature" or "short signature".
71
71
  3. Compatible with specs:
72
72
  RFC 9380,
@@ -98,9 +98,9 @@ import { psiFrobenius, tower12 } from './abstract/tower.ts';
98
98
  import {
99
99
  mapToCurveSimpleSWU,
100
100
  type AffinePoint,
101
- type ProjConstructor,
102
- type ProjPointType,
103
101
  type WeierstrassOpts,
102
+ type WeierstrassPoint,
103
+ type WeierstrassPointCons,
104
104
  } from './abstract/weierstrass.ts';
105
105
 
106
106
  // Be friendly to bad ECMAScript parsers by not using bigint literals
@@ -146,7 +146,7 @@ const bls12_381_CURVE_G1: WeierstrassOpts<bigint> = {
146
146
  };
147
147
 
148
148
  // CURVE FIELDS
149
- export const bls12_381_Fr: IField<bigint> = Field(bls12_381_CURVE_G1.n);
149
+ export const bls12_381_Fr: IField<bigint> = Field(bls12_381_CURVE_G1.n, { modOnDecode: true });
150
150
  const { Fp, Fp2, Fp6, Fp4Square, Fp12 } = tower12({
151
151
  // Order of Fp
152
152
  ORDER: bls12_381_CURVE_G1.p,
@@ -294,7 +294,11 @@ function setMask(
294
294
  return bytes;
295
295
  }
296
296
 
297
- function pointG1ToBytes(_c: ProjConstructor<Fp>, point: ProjPointType<Fp>, isComp: boolean) {
297
+ function pointG1ToBytes(
298
+ _c: WeierstrassPointCons<Fp>,
299
+ point: WeierstrassPoint<Fp>,
300
+ isComp: boolean
301
+ ) {
298
302
  const { BYTES: L, ORDER: P } = Fp;
299
303
  const is0 = point.is0();
300
304
  const { x, y } = point.toAffine();
@@ -311,7 +315,7 @@ function pointG1ToBytes(_c: ProjConstructor<Fp>, point: ProjPointType<Fp>, isCom
311
315
  }
312
316
  }
313
317
 
314
- function signatureG1ToBytes(point: ProjPointType<Fp>) {
318
+ function signatureG1ToBytes(point: WeierstrassPoint<Fp>) {
315
319
  point.assertValidity();
316
320
  const { BYTES: L, ORDER: P } = Fp;
317
321
  const { x, y } = point.toAffine();
@@ -350,7 +354,7 @@ function pointG1FromBytes(bytes: Uint8Array): AffinePoint<Fp> {
350
354
  }
351
355
  }
352
356
 
353
- function signatureG1FromBytes(hex: Hex): ProjPointType<Fp> {
357
+ function signatureG1FromBytes(hex: Hex): WeierstrassPoint<Fp> {
354
358
  const { infinity, sort, value } = parseMask(ensureBytes('signatureHex', hex, 48));
355
359
  const P = Fp.ORDER;
356
360
  const Point = bls12_381.G1.Point;
@@ -368,7 +372,11 @@ function signatureG1FromBytes(hex: Hex): ProjPointType<Fp> {
368
372
  return point;
369
373
  }
370
374
 
371
- function pointG2ToBytes(_c: ProjConstructor<Fp2>, point: ProjPointType<Fp2>, isComp: boolean) {
375
+ function pointG2ToBytes(
376
+ _c: WeierstrassPointCons<Fp2>,
377
+ point: WeierstrassPoint<Fp2>,
378
+ isComp: boolean
379
+ ) {
372
380
  const { BYTES: L, ORDER: P } = Fp;
373
381
  const is0 = point.is0();
374
382
  const { x, y } = point.toAffine();
@@ -392,7 +400,7 @@ function pointG2ToBytes(_c: ProjConstructor<Fp2>, point: ProjPointType<Fp2>, isC
392
400
  }
393
401
  }
394
402
 
395
- function signatureG2ToBytes(point: ProjPointType<Fp2>) {
403
+ function signatureG2ToBytes(point: WeierstrassPoint<Fp2>) {
396
404
  point.assertValidity();
397
405
  const { BYTES: L } = Fp;
398
406
  if (point.is0()) return concatBytes(COMPZERO, numberToBytesBE(_0n, L));
@@ -520,7 +528,7 @@ export const bls12_381: CurveFn = bls({
520
528
  const beta = BigInt(
521
529
  '0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
522
530
  );
523
- const phi = new c(Fp.mul(point.px, beta), point.py, point.pz);
531
+ const phi = new c(Fp.mul(point.X, beta), point.Y, point.Z);
524
532
  // TODO: unroll
525
533
  const xP = point.multiplyUnsafe(BLS_X).negate(); // [x]P
526
534
  const u2P = xP.multiplyUnsafe(BLS_X); // [u2]P
@@ -540,16 +548,16 @@ export const bls12_381: CurveFn = bls({
540
548
  abytes(bytes);
541
549
  return signatureG1FromBytes(bytes);
542
550
  },
543
- fromHex(hex: Hex): ProjPointType<Fp> {
551
+ fromHex(hex: Hex): WeierstrassPoint<Fp> {
544
552
  return signatureG1FromBytes(hex);
545
553
  },
546
- toBytes(point: ProjPointType<Fp>) {
554
+ toBytes(point: WeierstrassPoint<Fp>) {
547
555
  return signatureG1ToBytes(point);
548
556
  },
549
- toRawBytes(point: ProjPointType<Fp>) {
557
+ toRawBytes(point: WeierstrassPoint<Fp>) {
550
558
  return signatureG1ToBytes(point);
551
559
  },
552
- toHex(point: ProjPointType<Fp>) {
560
+ toHex(point: WeierstrassPoint<Fp>) {
553
561
  return bytesToHex(signatureG1ToBytes(point));
554
562
  },
555
563
  },
@@ -595,20 +603,20 @@ export const bls12_381: CurveFn = bls({
595
603
  fromBytes: pointG2FromBytes,
596
604
  toBytes: pointG2ToBytes,
597
605
  Signature: {
598
- fromBytes(bytes: Uint8Array): ProjPointType<Fp2> {
606
+ fromBytes(bytes: Uint8Array): WeierstrassPoint<Fp2> {
599
607
  abytes(bytes);
600
608
  return signatureG2FromBytes(bytes);
601
609
  },
602
- fromHex(hex: Hex): ProjPointType<Fp2> {
610
+ fromHex(hex: Hex): WeierstrassPoint<Fp2> {
603
611
  return signatureG2FromBytes(hex);
604
612
  },
605
- toBytes(point: ProjPointType<Fp2>) {
613
+ toBytes(point: WeierstrassPoint<Fp2>) {
606
614
  return signatureG2ToBytes(point);
607
615
  },
608
- toRawBytes(point: ProjPointType<Fp2>) {
616
+ toRawBytes(point: WeierstrassPoint<Fp2>) {
609
617
  return signatureG2ToBytes(point);
610
618
  },
611
- toHex(point: ProjPointType<Fp2>) {
619
+ toHex(point: WeierstrassPoint<Fp2>) {
612
620
  return bytesToHex(signatureG2ToBytes(point));
613
621
  },
614
622
  },
package/src/ed25519.ts CHANGED
@@ -8,42 +8,44 @@
8
8
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
9
9
  import { sha512 } from '@noble/hashes/sha2.js';
10
10
  import { abytes, concatBytes, utf8ToBytes } from '@noble/hashes/utils.js';
11
- import { type AffinePoint, type Group, pippenger } from './abstract/curve.ts';
11
+ import { pippenger, type AffinePoint } from './abstract/curve.ts';
12
12
  import {
13
+ PrimeEdwardsPoint,
14
+ twistedEdwards,
13
15
  type CurveFn,
14
16
  type EdwardsOpts,
15
- type ExtPointType,
16
- twistedEdwards,
17
+ type EdwardsPoint,
17
18
  } from './abstract/edwards.ts';
18
19
  import {
20
+ _DST_scalar,
19
21
  createHasher,
20
22
  expand_message_xmd,
21
23
  type H2CHasher,
24
+ type H2CHasherBase,
22
25
  type H2CMethod,
23
26
  type htfBasicOpts,
24
27
  } from './abstract/hash-to-curve.ts';
25
- import { Field, FpInvertBatch, FpSqrtEven, isNegativeLE, mod, pow2 } from './abstract/modular.ts';
26
- import { montgomery, type CurveFn as XCurveFn } from './abstract/montgomery.ts';
27
28
  import {
28
- bytesToHex,
29
- bytesToNumberLE,
30
- ensureBytes,
31
- equalBytes,
32
- type Hex,
33
- numberToBytesLE,
34
- } from './utils.ts';
29
+ Field,
30
+ FpInvertBatch,
31
+ FpSqrtEven,
32
+ isNegativeLE,
33
+ mod,
34
+ pow2,
35
+ type IField,
36
+ } from './abstract/modular.ts';
37
+ import { montgomery, type MontgomeryECDH as XCurveFn } from './abstract/montgomery.ts';
38
+ import { bytesToNumberLE, ensureBytes, equalBytes, numberToBytesLE, type Hex } from './utils.ts';
35
39
 
36
40
  // prettier-ignore
37
41
  const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
38
42
  // prettier-ignore
39
43
  const _5n = BigInt(5), _8n = BigInt(8);
40
44
 
41
- // 2n**255n - 19n
42
- // Removing Fp.create() will still work, and is 10% faster on sign
43
- // a: Fp.create(BigInt(-1)),
44
- // d is -121665/121666 a.k.a. Fp.neg(121665 * Fp.inv(121666))
45
- // Finite field 2n**255n - 19n
46
- // Subgroup order 2n**252n + 27742317777372353535851937790883648493n;
45
+ // P = 2n**255n - 19n
46
+ // N = 2n**252n + 27742317777372353535851937790883648493n
47
+ // a = Fp.create(BigInt(-1))
48
+ // d = -121665/121666 a.k.a. Fp.neg(121665 * Fp.inv(121666))
47
49
  const ed25519_CURVE: EdwardsOpts = {
48
50
  p: BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed'),
49
51
  n: BigInt('0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed'),
@@ -110,19 +112,8 @@ function uvRatio(u: bigint, v: bigint): { isValid: boolean; value: bigint } {
110
112
  return { isValid: useRoot1 || useRoot2, value: x };
111
113
  }
112
114
 
113
- /** Weird / bogus points, useful for debugging. */
114
- export const ED25519_TORSION_SUBGROUP: string[] = [
115
- '0100000000000000000000000000000000000000000000000000000000000000',
116
- 'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',
117
- '0000000000000000000000000000000000000000000000000000000000000080',
118
- '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',
119
- 'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
120
- '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',
121
- '0000000000000000000000000000000000000000000000000000000000000000',
122
- 'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
123
- ];
124
-
125
- const Fp = /* @__PURE__ */ (() => Field(ed25519_CURVE.p, undefined, true))();
115
+ const Fp = /* @__PURE__ */ (() => Field(ed25519_CURVE.p, { isLE: true }))();
116
+ const Fn = /* @__PURE__ */ (() => Field(ed25519_CURVE.n, { isLE: true }))();
126
117
 
127
118
  const ed25519Defaults = /* @__PURE__ */ (() => ({
128
119
  ...ed25519_CURVE,
@@ -139,8 +130,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
139
130
  * ed25519 curve with EdDSA signatures.
140
131
  * @example
141
132
  * import { ed25519 } from '@noble/curves/ed25519';
142
- * const priv = ed25519.utils.randomPrivateKey();
143
- * const pub = ed25519.getPublicKey(priv);
133
+ * const { secretKey, publicKey } = ed25519.keygen();
144
134
  * const msg = new TextEncoder().encode('hello');
145
135
  * const sig = ed25519.sign(msg, priv);
146
136
  * ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
@@ -158,11 +148,14 @@ function ed25519_domain(data: Uint8Array, ctx: Uint8Array, phflag: boolean) {
158
148
  );
159
149
  }
160
150
 
151
+ /** Context of ed25519. Uses context for domain separation. */
161
152
  export const ed25519ctx: CurveFn = /* @__PURE__ */ (() =>
162
153
  twistedEdwards({
163
154
  ...ed25519Defaults,
164
155
  domain: ed25519_domain,
165
156
  }))();
157
+
158
+ /** Prehashed version of ed25519. Accepts already-hashed messages in sign() and verify(). */
166
159
  export const ed25519ph: CurveFn = /* @__PURE__ */ (() =>
167
160
  twistedEdwards(
168
161
  Object.assign({}, ed25519Defaults, {
@@ -179,7 +172,7 @@ export const ed25519ph: CurveFn = /* @__PURE__ */ (() =>
179
172
  * const pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';
180
173
  * x25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub); // aliases
181
174
  * x25519.getPublicKey(priv) === x25519.scalarMultBase(priv);
182
- * x25519.getPublicKey(x25519.utils.randomPrivateKey());
175
+ * x25519.getPublicKey(x25519.utils.randomSecretKey());
183
176
  */
184
177
  export const x25519: XCurveFn = /* @__PURE__ */ (() => {
185
178
  const P = ed25519_CURVE.p;
@@ -195,33 +188,16 @@ export const x25519: XCurveFn = /* @__PURE__ */ (() => {
195
188
  });
196
189
  })();
197
190
 
198
- /**
199
- * Converts ed25519 public key to x25519 public key. Uses formula:
200
- * * `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
201
- * * `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
202
- * @example
203
- * const someonesPub = ed25519.getPublicKey(ed25519.utils.randomPrivateKey());
204
- * const aPriv = x25519.utils.randomPrivateKey();
205
- * x25519.getSharedSecret(aPriv, edwardsToMontgomeryPub(someonesPub))
206
- */
191
+ /** @deprecated use `ed25519.utils.toMontgomery` */
207
192
  export function edwardsToMontgomeryPub(edwardsPub: Hex): Uint8Array {
208
- const bpub = ensureBytes('pub', edwardsPub);
209
- const { y } = ed25519.Point.fromHex(bpub);
210
- const _1n = BigInt(1);
211
- return Fp.toBytes(Fp.create((_1n + y) * Fp.inv(_1n - y)));
193
+ return ed25519.utils.toMontgomery(ensureBytes('pub', edwardsPub));
212
194
  }
213
- export const edwardsToMontgomery: typeof edwardsToMontgomeryPub = edwardsToMontgomeryPub; // deprecated
195
+ /** @deprecated use `ed25519.utils.toMontgomery` */
196
+ export const edwardsToMontgomery: typeof edwardsToMontgomeryPub = edwardsToMontgomeryPub;
214
197
 
215
- /**
216
- * Converts ed25519 secret key to x25519 secret key.
217
- * @example
218
- * const someonesPub = x25519.getPublicKey(x25519.utils.randomPrivateKey());
219
- * const aPriv = ed25519.utils.randomPrivateKey();
220
- * x25519.getSharedSecret(edwardsToMontgomeryPriv(aPriv), someonesPub)
221
- */
198
+ /** @deprecated use `ed25519.utils.toMontgomeryPriv` */
222
199
  export function edwardsToMontgomeryPriv(edwardsPriv: Uint8Array): Uint8Array {
223
- const hashed = ed25519Defaults.hash(edwardsPriv.subarray(0, 32));
224
- return ed25519Defaults.adjustScalarBytes(hashed).subarray(0, 32);
200
+ return ed25519.utils.toMontgomeryPriv(ensureBytes('pub', edwardsPriv));
225
201
  }
226
202
 
227
203
  // Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
@@ -297,6 +273,7 @@ function map_to_curve_elligator2_edwards25519(u: bigint) {
297
273
  return { x: Fp.mul(xn, xd_inv), y: Fp.mul(yn, yd_inv) }; // 13. return (xn, xd, yn, yd)
298
274
  }
299
275
 
276
+ /** Hashing to ed25519 points / field. RFC 9380 methods. */
300
277
  export const ed25519_hasher: H2CHasher<bigint> = /* @__PURE__ */ (() =>
301
278
  createHasher(
302
279
  ed25519.Point,
@@ -311,13 +288,6 @@ export const ed25519_hasher: H2CHasher<bigint> = /* @__PURE__ */ (() =>
311
288
  hash: sha512,
312
289
  }
313
290
  ))();
314
- export const hashToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() => ed25519_hasher.hashToCurve)();
315
- export const encodeToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() =>
316
- ed25519_hasher.encodeToCurve)();
317
-
318
- function aristp(other: unknown) {
319
- if (!(other instanceof RistPoint)) throw new Error('RistrettoPoint expected');
320
- }
321
291
 
322
292
  // √(-1) aka √(a) aka 2^((p-1)/4)
323
293
  const SQRT_M1 = ED25519_SQRT_M1;
@@ -346,7 +316,7 @@ const MAX_255B = /* @__PURE__ */ BigInt(
346
316
  const bytes255ToNumberLE = (bytes: Uint8Array) =>
347
317
  ed25519.CURVE.Fp.create(bytesToNumberLE(bytes) & MAX_255B);
348
318
 
349
- type ExtendedPoint = ExtPointType;
319
+ type ExtendedPoint = EdwardsPoint;
350
320
 
351
321
  /**
352
322
  * Computes Elligator map for Ristretto255.
@@ -375,64 +345,71 @@ function calcElligatorRistrettoMap(r0: bigint): ExtendedPoint {
375
345
  return new ed25519.Point(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
376
346
  }
377
347
 
348
+ function ristretto255_map(bytes: Uint8Array): _RistrettoPoint {
349
+ abytes(bytes, 64);
350
+ const r1 = bytes255ToNumberLE(bytes.subarray(0, 32));
351
+ const R1 = calcElligatorRistrettoMap(r1);
352
+ const r2 = bytes255ToNumberLE(bytes.subarray(32, 64));
353
+ const R2 = calcElligatorRistrettoMap(r2);
354
+ return new _RistrettoPoint(R1.add(R2));
355
+ }
356
+
378
357
  /**
358
+ * Wrapper over Edwards Point for ristretto255.
359
+ *
379
360
  * Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
380
361
  * a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
381
362
  * Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
382
363
  * but it should work in its own namespace: do not combine those two.
383
364
  * See [RFC9496](https://www.rfc-editor.org/rfc/rfc9496).
384
365
  */
385
- class RistPoint implements Group<RistPoint> {
386
- static BASE: RistPoint;
387
- static ZERO: RistPoint;
388
- private readonly ep: ExtendedPoint;
389
- // Private property to discourage combining ExtendedPoint + RistrettoPoint
390
- // Always use Ristretto encoding/decoding instead.
366
+ class _RistrettoPoint extends PrimeEdwardsPoint<_RistrettoPoint> {
367
+ // Do NOT change syntax: the following gymnastics is done,
368
+ // because typescript strips comments, which makes bundlers disable tree-shaking.
369
+ // prettier-ignore
370
+ static BASE: _RistrettoPoint =
371
+ /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.BASE))();
372
+ // prettier-ignore
373
+ static ZERO: _RistrettoPoint =
374
+ /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.ZERO))();
375
+ // prettier-ignore
376
+ static Fp: IField<bigint> =
377
+ /* @__PURE__ */ Fp;
378
+ // prettier-ignore
379
+ static Fn: IField<bigint> =
380
+ /* @__PURE__ */ Fn;
381
+
391
382
  constructor(ep: ExtendedPoint) {
392
- this.ep = ep;
383
+ super(ep);
393
384
  }
394
385
 
395
- static fromAffine(ap: AffinePoint<bigint>): RistPoint {
396
- return new RistPoint(ed25519.Point.fromAffine(ap));
386
+ static fromAffine(ap: AffinePoint<bigint>): _RistrettoPoint {
387
+ return new _RistrettoPoint(ed25519.Point.fromAffine(ap));
397
388
  }
398
389
 
399
- /**
400
- * Takes uniform output of 64-byte hash function like sha512 and converts it to `RistrettoPoint`.
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-B) and on
404
- * the [website](https://ristretto.group/formulas/elligator.html).
405
- * @param hex 64-byte output of a hash function
406
- */
407
- static hashToCurve(hex: Hex): RistPoint {
408
- hex = ensureBytes('ristrettoHash', hex, 64);
409
- const r1 = bytes255ToNumberLE(hex.slice(0, 32));
410
- const R1 = calcElligatorRistrettoMap(r1);
411
- const r2 = bytes255ToNumberLE(hex.slice(32, 64));
412
- const R2 = calcElligatorRistrettoMap(r2);
413
- return new RistPoint(R1.add(R2));
390
+ protected assertSame(other: _RistrettoPoint): void {
391
+ if (!(other instanceof _RistrettoPoint)) throw new Error('RistrettoPoint expected');
414
392
  }
415
393
 
416
- static fromBytes(bytes: Uint8Array): RistPoint {
417
- abytes(bytes);
418
- return this.fromHex(bytes);
394
+ protected init(ep: EdwardsPoint): _RistrettoPoint {
395
+ return new _RistrettoPoint(ep);
419
396
  }
420
397
 
421
- /**
422
- * Converts ristretto-encoded string to ristretto point.
423
- * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).
424
- * @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
425
- */
426
- static fromHex(hex: Hex): RistPoint {
427
- hex = ensureBytes('ristrettoHex', hex, 32);
398
+ /** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
399
+ static hashToCurve(hex: Hex): _RistrettoPoint {
400
+ return ristretto255_map(ensureBytes('ristrettoHash', hex, 64));
401
+ }
402
+
403
+ static fromBytes(bytes: Uint8Array): _RistrettoPoint {
404
+ abytes(bytes, 32);
428
405
  const { a, d } = ed25519.CURVE;
429
406
  const P = Fp.ORDER;
430
407
  const mod = Fp.create;
431
- const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
432
- const s = bytes255ToNumberLE(hex);
408
+ const s = bytes255ToNumberLE(bytes);
433
409
  // 1. Check that s_bytes is the canonical encoding of a field element, or else abort.
434
410
  // 3. Check that s is non-negative, or else abort
435
- if (!equalBytes(numberToBytesLE(s, 32), hex) || isNegativeLE(s, P)) throw new Error(emsg);
411
+ if (!equalBytes(numberToBytesLE(s, 32), bytes) || isNegativeLE(s, P))
412
+ throw new Error('invalid ristretto255 encoding 1');
436
413
  const s2 = mod(s * s);
437
414
  const u1 = mod(_1n + a * s2); // 4 (a is -1)
438
415
  const u2 = mod(_1n - a * s2); // 5
@@ -446,13 +423,22 @@ class RistPoint implements Group<RistPoint> {
446
423
  if (isNegativeLE(x, P)) x = mod(-x); // 10
447
424
  const y = mod(u1 * Dy); // 11
448
425
  const t = mod(x * y); // 12
449
- if (!isValid || isNegativeLE(t, P) || y === _0n) throw new Error(emsg);
450
- return new RistPoint(new ed25519.Point(x, y, _1n, t));
426
+ if (!isValid || isNegativeLE(t, P) || y === _0n)
427
+ throw new Error('invalid ristretto255 encoding 2');
428
+ return new _RistrettoPoint(new ed25519.Point(x, y, _1n, t));
451
429
  }
452
430
 
453
- static msm(points: RistPoint[], scalars: bigint[]): RistPoint {
454
- const Fn = Field(ed25519.CURVE.n, ed25519.CURVE.nBitLength);
455
- return pippenger(RistPoint, Fn, points, scalars);
431
+ /**
432
+ * Converts ristretto-encoded string to ristretto point.
433
+ * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).
434
+ * @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
435
+ */
436
+ static fromHex(hex: Hex): _RistrettoPoint {
437
+ return _RistrettoPoint.fromBytes(ensureBytes('ristrettoHex', hex, 32));
438
+ }
439
+
440
+ static msm(points: _RistrettoPoint[], scalars: bigint[]): _RistrettoPoint {
441
+ return pippenger(_RistrettoPoint, ed25519.Point.Fn, points, scalars);
456
442
  }
457
443
 
458
444
  /**
@@ -460,54 +446,41 @@ class RistPoint implements Group<RistPoint> {
460
446
  * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode).
461
447
  */
462
448
  toBytes(): Uint8Array {
463
- let { ex: x, ey: y, ez: z, et: t } = this.ep;
449
+ let { X, Y, Z, T } = this.ep;
464
450
  const P = Fp.ORDER;
465
451
  const mod = Fp.create;
466
- const u1 = mod(mod(z + y) * mod(z - y)); // 1
467
- const u2 = mod(x * y); // 2
452
+ const u1 = mod(mod(Z + Y) * mod(Z - Y)); // 1
453
+ const u2 = mod(X * Y); // 2
468
454
  // Square root always exists
469
455
  const u2sq = mod(u2 * u2);
470
456
  const { value: invsqrt } = invertSqrt(mod(u1 * u2sq)); // 3
471
457
  const D1 = mod(invsqrt * u1); // 4
472
458
  const D2 = mod(invsqrt * u2); // 5
473
- const zInv = mod(D1 * D2 * t); // 6
459
+ const zInv = mod(D1 * D2 * T); // 6
474
460
  let D: bigint; // 7
475
- if (isNegativeLE(t * zInv, P)) {
476
- let _x = mod(y * SQRT_M1);
477
- let _y = mod(x * SQRT_M1);
478
- x = _x;
479
- y = _y;
461
+ if (isNegativeLE(T * zInv, P)) {
462
+ let _x = mod(Y * SQRT_M1);
463
+ let _y = mod(X * SQRT_M1);
464
+ X = _x;
465
+ Y = _y;
480
466
  D = mod(D1 * INVSQRT_A_MINUS_D);
481
467
  } else {
482
468
  D = D2; // 8
483
469
  }
484
- if (isNegativeLE(x * zInv, P)) y = mod(-y); // 9
485
- let s = mod((z - y) * D); // 10 (check footer's note, no sqrt(-a))
470
+ if (isNegativeLE(X * zInv, P)) Y = mod(-Y); // 9
471
+ let s = mod((Z - Y) * D); // 10 (check footer's note, no sqrt(-a))
486
472
  if (isNegativeLE(s, P)) s = mod(-s);
487
473
  return numberToBytesLE(s, 32); // 11
488
474
  }
489
475
 
490
- /** @deprecated use `toBytes` */
491
- toRawBytes(): Uint8Array {
492
- return this.toBytes();
493
- }
494
-
495
- toHex(): string {
496
- return bytesToHex(this.toBytes());
497
- }
498
-
499
- toString(): string {
500
- return this.toHex();
501
- }
502
-
503
476
  /**
504
477
  * Compares two Ristretto points.
505
478
  * Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals).
506
479
  */
507
- equals(other: RistPoint): boolean {
508
- aristp(other);
509
- const { ex: X1, ey: Y1 } = this.ep;
510
- const { ex: X2, ey: Y2 } = other.ep;
480
+ equals(other: _RistrettoPoint): boolean {
481
+ this.assertSame(other);
482
+ const { X: X1, Y: Y1 } = this.ep;
483
+ const { X: X2, Y: Y2 } = other.ep;
511
484
  const mod = Fp.create;
512
485
  // (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)
513
486
  const one = mod(X1 * Y2) === mod(Y1 * X2);
@@ -515,54 +488,63 @@ class RistPoint implements Group<RistPoint> {
515
488
  return one || two;
516
489
  }
517
490
 
518
- add(other: RistPoint): RistPoint {
519
- aristp(other);
520
- return new RistPoint(this.ep.add(other.ep));
521
- }
522
-
523
- subtract(other: RistPoint): RistPoint {
524
- aristp(other);
525
- return new RistPoint(this.ep.subtract(other.ep));
526
- }
527
-
528
- multiply(scalar: bigint): RistPoint {
529
- return new RistPoint(this.ep.multiply(scalar));
530
- }
531
-
532
- multiplyUnsafe(scalar: bigint): RistPoint {
533
- return new RistPoint(this.ep.multiplyUnsafe(scalar));
491
+ is0(): boolean {
492
+ return this.equals(_RistrettoPoint.ZERO);
534
493
  }
494
+ }
535
495
 
536
- double(): RistPoint {
537
- return new RistPoint(this.ep.double());
538
- }
496
+ /** @deprecated use `ristretto255.Point` */
497
+ export const RistrettoPoint: typeof _RistrettoPoint = _RistrettoPoint;
498
+
499
+ export const ristretto255: {
500
+ Point: typeof _RistrettoPoint;
501
+ } = { Point: _RistrettoPoint };
502
+
503
+ /** Hashing to ristretto255 points / field. RFC 9380 methods. */
504
+ export const ristretto255_hasher: H2CHasherBase<bigint> = {
505
+ hashToCurve(msg: Uint8Array, options?: htfBasicOpts): _RistrettoPoint {
506
+ const DST = options?.DST || 'ristretto255_XMD:SHA-512_R255MAP_RO_';
507
+ return ristretto255_map(expand_message_xmd(msg, DST, 64, sha512));
508
+ },
509
+ hashToScalar(msg: Uint8Array, options: htfBasicOpts = { DST: _DST_scalar }) {
510
+ return Fn.create(bytesToNumberLE(expand_message_xmd(msg, options.DST, 64, sha512)));
511
+ },
512
+ };
539
513
 
540
- negate(): RistPoint {
541
- return new RistPoint(this.ep.negate());
542
- }
543
- }
514
+ // export const ristretto255_oprf: OPRF = createORPF({
515
+ // name: 'ristretto255-SHA512',
516
+ // Point: RistrettoPoint,
517
+ // hash: sha512,
518
+ // hashToGroup: ristretto255_hasher.hashToCurve,
519
+ // hashToScalar: ristretto255_hasher.hashToScalar,
520
+ // });
544
521
 
545
- /**
546
- * Wrapper over Edwards Point for ristretto255 from
547
- * [RFC9496](https://www.rfc-editor.org/rfc/rfc9496).
548
- */
549
- export const RistrettoPoint: typeof RistPoint = /* @__PURE__ */ (() => {
550
- if (!RistPoint.BASE) RistPoint.BASE = new RistPoint(ed25519.Point.BASE);
551
- if (!RistPoint.ZERO) RistPoint.ZERO = new RistPoint(ed25519.Point.ZERO);
552
- return RistPoint;
553
- })();
522
+ /** @deprecated use `import { ed25519_hasher } from '@noble/curves/ed25519.js';` */
523
+ export const hashToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() => ed25519_hasher.hashToCurve)();
524
+ /** @deprecated use `import { ed25519_hasher } from '@noble/curves/ed25519.js';` */
525
+ export const encodeToCurve: H2CMethod<bigint> = /* @__PURE__ */ (() =>
526
+ ed25519_hasher.encodeToCurve)();
527
+ type RistHasher = (msg: Uint8Array, options: htfBasicOpts) => _RistrettoPoint;
528
+ /** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
529
+ export const hashToRistretto255: RistHasher = /* @__PURE__ */ (() =>
530
+ ristretto255_hasher.hashToCurve as RistHasher)();
531
+ /** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
532
+ export const hash_to_ristretto255: RistHasher = /* @__PURE__ */ (() =>
533
+ ristretto255_hasher.hashToCurve as RistHasher)();
554
534
 
555
535
  /**
556
- * hash-to-curve for ristretto255.
557
- * Described in [RFC9380](https://www.rfc-editor.org/rfc/rfc9380#appendix-B).
536
+ * Weird / bogus points, useful for debugging.
537
+ * All 8 ed25519 points of 8-torsion subgroup can be generated from the point
538
+ * T = `26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05`.
539
+ * ⟨T⟩ = { O, T, 2T, 3T, 4T, 5T, 6T, 7T }
558
540
  */
559
- export const hashToRistretto255 = (msg: Uint8Array, options: htfBasicOpts): RistPoint => {
560
- const d = options.DST;
561
- const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
562
- const uniform_bytes = expand_message_xmd(msg, DST, 64, sha512);
563
- const P = RistPoint.hashToCurve(uniform_bytes);
564
- return P;
565
- };
566
- /** @deprecated */
567
- export const hash_to_ristretto255: (msg: Uint8Array, options: htfBasicOpts) => RistPoint =
568
- hashToRistretto255; // legacy
541
+ export const ED25519_TORSION_SUBGROUP: string[] = [
542
+ '0100000000000000000000000000000000000000000000000000000000000000',
543
+ 'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',
544
+ '0000000000000000000000000000000000000000000000000000000000000080',
545
+ '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',
546
+ 'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
547
+ '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',
548
+ '0000000000000000000000000000000000000000000000000000000000000000',
549
+ 'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
550
+ ];