@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/ed25519.ts CHANGED
@@ -1,18 +1,18 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
2
  import { sha512 } from '@noble/hashes/sha512';
3
3
  import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils';
4
- import { twistedEdwards, ExtPointType } from './abstract/edwards.js';
4
+ import { ExtPointType, twistedEdwards } from './abstract/edwards.js';
5
5
  import { montgomery } from './abstract/montgomery.js';
6
- import { mod, pow2, isNegativeLE, Field, FpSqrtEven } from './abstract/modular.js';
6
+ import { Field, FpSqrtEven, isNegativeLE, mod, pow2 } from './abstract/modular.js';
7
7
  import {
8
- equalBytes,
9
8
  bytesToHex,
10
9
  bytesToNumberLE,
11
- numberToBytesLE,
12
- Hex,
13
10
  ensureBytes,
11
+ equalBytes,
12
+ Hex,
13
+ numberToBytesLE,
14
14
  } from './abstract/utils.js';
15
- import * as htf from './abstract/hash-to-curve.js';
15
+ import { createHasher, htfBasicOpts, expand_message_xmd } from './abstract/hash-to-curve.js';
16
16
  import { AffinePoint } from './abstract/curve.js';
17
17
 
18
18
  /**
@@ -34,6 +34,7 @@ const ED25519_SQRT_M1 = BigInt(
34
34
  const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _5n = BigInt(5);
35
35
  // prettier-ignore
36
36
  const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
37
+
37
38
  function ed25519_pow_2_252_3(x: bigint) {
38
39
  const P = ED25519_P;
39
40
  const x2 = (x * x) % P;
@@ -51,6 +52,7 @@ function ed25519_pow_2_252_3(x: bigint) {
51
52
  // ^ To pow to (p+3)/8, multiply it by x.
52
53
  return { pow_p_5_8, b2 };
53
54
  }
55
+
54
56
  function adjustScalarBytes(bytes: Uint8Array): Uint8Array {
55
57
  // Section 5: For X25519, in order to decode 32 random bytes as an integer scalar,
56
58
  // set the three least significant bits of the first byte
@@ -61,6 +63,7 @@ function adjustScalarBytes(bytes: Uint8Array): Uint8Array {
61
63
  bytes[31] |= 64; // 0b0100_0000
62
64
  return bytes;
63
65
  }
66
+
64
67
  // sqrt(u/v)
65
68
  function uvRatio(u: bigint, v: bigint): { isValid: boolean; value: bigint } {
66
69
  const P = ED25519_P;
@@ -101,10 +104,10 @@ const ed25519Defaults = {
101
104
  // d is equal to -121665/121666 over finite field.
102
105
  // Negative number is P - number, and division is invert(number, P)
103
106
  d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
104
- // Finite field 𝔽p over which we'll do calculations; 2n ** 255n - 19n
107
+ // Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
105
108
  Fp,
106
109
  // Subgroup order: how many points curve has
107
- // 2n ** 252n + 27742317777372353535851937790883648493n;
110
+ // 2n**252n + 27742317777372353535851937790883648493n;
108
111
  n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
109
112
  // Cofactor
110
113
  h: BigInt(8),
@@ -120,7 +123,8 @@ const ed25519Defaults = {
120
123
  uvRatio,
121
124
  } as const;
122
125
 
123
- export const ed25519 = twistedEdwards(ed25519Defaults);
126
+ export const ed25519 = /* @__PURE__ */ twistedEdwards(ed25519Defaults);
127
+
124
128
  function ed25519_domain(data: Uint8Array, ctx: Uint8Array, phflag: boolean) {
125
129
  if (ctx.length > 255) throw new Error('Context is too big');
126
130
  return concatBytes(
@@ -130,41 +134,60 @@ function ed25519_domain(data: Uint8Array, ctx: Uint8Array, phflag: boolean) {
130
134
  data
131
135
  );
132
136
  }
133
- export const ed25519ctx = twistedEdwards({ ...ed25519Defaults, domain: ed25519_domain });
134
- export const ed25519ph = twistedEdwards({
137
+
138
+ export const ed25519ctx = /* @__PURE__ */ twistedEdwards({
139
+ ...ed25519Defaults,
140
+ domain: ed25519_domain,
141
+ });
142
+ export const ed25519ph = /* @__PURE__ */ twistedEdwards({
135
143
  ...ed25519Defaults,
136
144
  domain: ed25519_domain,
137
145
  prehash: sha512,
138
146
  });
139
147
 
140
- export const x25519 = montgomery({
141
- P: ED25519_P,
142
- a: BigInt(486662),
143
- montgomeryBits: 255, // n is 253 bits
144
- nByteLength: 32,
145
- Gu: BigInt(9),
146
- powPminus2: (x: bigint): bigint => {
147
- const P = ED25519_P;
148
- // x^(p-2) aka x^(2^255-21)
149
- const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
150
- return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
151
- },
152
- adjustScalarBytes,
153
- randomBytes,
154
- });
148
+ export const x25519 = /* @__PURE__ */ (() =>
149
+ montgomery({
150
+ P: ED25519_P,
151
+ a: BigInt(486662),
152
+ montgomeryBits: 255, // n is 253 bits
153
+ nByteLength: 32,
154
+ Gu: BigInt(9),
155
+ powPminus2: (x: bigint): bigint => {
156
+ const P = ED25519_P;
157
+ // x^(p-2) aka x^(2^255-21)
158
+ const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
159
+ return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
160
+ },
161
+ adjustScalarBytes,
162
+ randomBytes,
163
+ }))();
155
164
 
156
165
  /**
157
166
  * Converts ed25519 public key to x25519 public key. Uses formula:
158
167
  * * `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
159
168
  * * `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
160
169
  * @example
161
- * const aPub = ed25519.getPublicKey(utils.randomPrivateKey());
162
- * x25519.getSharedSecret(edwardsToMontgomery(aPub), edwardsToMontgomery(someonesPub))
170
+ * const someonesPub = ed25519.getPublicKey(ed25519.utils.randomPrivateKey());
171
+ * const aPriv = x25519.utils.randomPrivateKey();
172
+ * x25519.getSharedSecret(aPriv, edwardsToMontgomeryPub(someonesPub))
163
173
  */
164
- export function edwardsToMontgomery(edwardsPub: Hex): Uint8Array {
174
+ export function edwardsToMontgomeryPub(edwardsPub: Hex): Uint8Array {
165
175
  const { y } = ed25519.ExtendedPoint.fromHex(edwardsPub);
166
176
  const _1n = BigInt(1);
167
- return Fp.toBytes(Fp.create((y - _1n) * Fp.inv(y + _1n)));
177
+ return Fp.toBytes(Fp.create((_1n + y) * Fp.inv(_1n - y)));
178
+ }
179
+ export const edwardsToMontgomery = edwardsToMontgomeryPub; // deprecated
180
+
181
+ /**
182
+ * Converts ed25519 secret key to x25519 secret key.
183
+ * @example
184
+ * const someonesPub = x25519.getPublicKey(x25519.utils.randomPrivateKey());
185
+ * const aPriv = ed25519.utils.randomPrivateKey();
186
+ * x25519.getSharedSecret(edwardsToMontgomeryPriv(aPriv), someonesPub)
187
+ */
188
+ export function edwardsToMontgomeryPriv(edwardsPriv: Uint8Array): Uint8Array {
189
+ const hashed = ed25519Defaults.hash(edwardsPriv.subarray(0, 32));
190
+ return ed25519Defaults.adjustScalarBytes(hashed).subarray(0, 32);
168
191
  }
169
192
 
170
193
  // Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
@@ -223,7 +246,8 @@ function map_to_curve_elligator2_curve25519(u: bigint) {
223
246
 
224
247
  const ELL2_C1_EDWARDS = FpSqrtEven(Fp, Fp.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
225
248
  function map_to_curve_elligator2_edwards25519(u: bigint) {
226
- const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); // 1. (xMn, xMd, yMn, yMd) = map_to_curve_elligator2_curve25519(u)
249
+ const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); // 1. (xMn, xMd, yMn, yMd) =
250
+ // map_to_curve_elligator2_curve25519(u)
227
251
  let xn = Fp.mul(xMn, yMd); // 2. xn = xMn * yMd
228
252
  xn = Fp.mul(xn, ELL2_C1_EDWARDS); // 3. xn = xn * c1
229
253
  let xd = Fp.mul(xMd, yMn); // 4. xd = xMd * yMn # xn / xd = c1 * xM / yM
@@ -239,28 +263,30 @@ function map_to_curve_elligator2_edwards25519(u: bigint) {
239
263
  const inv = Fp.invertBatch([xd, yd]); // batch division
240
264
  return { x: Fp.mul(xn, inv[0]), y: Fp.mul(yn, inv[1]) }; // 13. return (xn, xd, yn, yd)
241
265
  }
242
- const { hashToCurve, encodeToCurve } = htf.createHasher(
243
- ed25519.ExtendedPoint,
244
- (scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]),
245
- {
246
- DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
247
- encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',
248
- p: Fp.ORDER,
249
- m: 1,
250
- k: 128,
251
- expand: 'xmd',
252
- hash: sha512,
253
- }
254
- );
255
- export { hashToCurve, encodeToCurve };
266
+
267
+ const htf = /* @__PURE__ */ (() =>
268
+ createHasher(
269
+ ed25519.ExtendedPoint,
270
+ (scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]),
271
+ {
272
+ DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
273
+ encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',
274
+ p: Fp.ORDER,
275
+ m: 1,
276
+ k: 128,
277
+ expand: 'xmd',
278
+ hash: sha512,
279
+ }
280
+ ))();
281
+ export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
282
+ export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
256
283
 
257
284
  function assertRstPoint(other: unknown) {
258
- if (!(other instanceof RistrettoPoint)) throw new Error('RistrettoPoint expected');
285
+ if (!(other instanceof RistPoint)) throw new Error('RistrettoPoint expected');
259
286
  }
287
+
260
288
  // √(-1) aka √(a) aka 2^((p-1)/4)
261
- const SQRT_M1 = BigInt(
262
- '19681161376707505956807079304988542015446066515923890162744021073123829784752'
263
- );
289
+ const SQRT_M1 = ED25519_SQRT_M1;
264
290
  // √(ad - 1)
265
291
  const SQRT_AD_MINUS_ONE = BigInt(
266
292
  '25063068953384623474111414158702152701244531502492656460079210482610430750235'
@@ -317,32 +343,31 @@ function calcElligatorRistrettoMap(r0: bigint): ExtendedPoint {
317
343
  * but it should work in its own namespace: do not combine those two.
318
344
  * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
319
345
  */
320
- export class RistrettoPoint {
321
- static BASE = new RistrettoPoint(ed25519.ExtendedPoint.BASE);
322
- static ZERO = new RistrettoPoint(ed25519.ExtendedPoint.ZERO);
323
-
346
+ class RistPoint {
347
+ static BASE: RistPoint;
348
+ static ZERO: RistPoint;
324
349
  // Private property to discourage combining ExtendedPoint + RistrettoPoint
325
350
  // Always use Ristretto encoding/decoding instead.
326
351
  constructor(private readonly ep: ExtendedPoint) {}
327
352
 
328
353
  static fromAffine(ap: AffinePoint<bigint>) {
329
- return new RistrettoPoint(ed25519.ExtendedPoint.fromAffine(ap));
354
+ return new RistPoint(ed25519.ExtendedPoint.fromAffine(ap));
330
355
  }
331
356
 
332
357
  /**
333
- * Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
358
+ * Takes uniform output of 64-byte hash function like sha512 and converts it to `RistrettoPoint`.
334
359
  * The hash-to-group operation applies Elligator twice and adds the results.
335
360
  * **Note:** this is one-way map, there is no conversion from point to hash.
336
361
  * https://ristretto.group/formulas/elligator.html
337
- * @param hex 64-bit output of a hash function
362
+ * @param hex 64-byte output of a hash function
338
363
  */
339
- static hashToCurve(hex: Hex): RistrettoPoint {
364
+ static hashToCurve(hex: Hex): RistPoint {
340
365
  hex = ensureBytes('ristrettoHash', hex, 64);
341
366
  const r1 = bytes255ToNumberLE(hex.slice(0, 32));
342
367
  const R1 = calcElligatorRistrettoMap(r1);
343
368
  const r2 = bytes255ToNumberLE(hex.slice(32, 64));
344
369
  const R2 = calcElligatorRistrettoMap(r2);
345
- return new RistrettoPoint(R1.add(R2));
370
+ return new RistPoint(R1.add(R2));
346
371
  }
347
372
 
348
373
  /**
@@ -350,7 +375,7 @@ export class RistrettoPoint {
350
375
  * https://ristretto.group/formulas/decoding.html
351
376
  * @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
352
377
  */
353
- static fromHex(hex: Hex): RistrettoPoint {
378
+ static fromHex(hex: Hex): RistPoint {
354
379
  hex = ensureBytes('ristrettoHex', hex, 32);
355
380
  const { a, d } = ed25519.CURVE;
356
381
  const P = ed25519.CURVE.Fp.ORDER;
@@ -374,7 +399,7 @@ export class RistrettoPoint {
374
399
  const y = mod(u1 * Dy); // 11
375
400
  const t = mod(x * y); // 12
376
401
  if (!isValid || isNegativeLE(t, P) || y === _0n) throw new Error(emsg);
377
- return new RistrettoPoint(new ed25519.ExtendedPoint(x, y, _1n, t));
402
+ return new RistPoint(new ed25519.ExtendedPoint(x, y, _1n, t));
378
403
  }
379
404
 
380
405
  /**
@@ -418,7 +443,7 @@ export class RistrettoPoint {
418
443
  }
419
444
 
420
445
  // Compare one point to another.
421
- equals(other: RistrettoPoint): boolean {
446
+ equals(other: RistPoint): boolean {
422
447
  assertRstPoint(other);
423
448
  const { ex: X1, ey: Y1 } = this.ep;
424
449
  const { ex: X2, ey: Y2 } = other.ep;
@@ -429,31 +454,36 @@ export class RistrettoPoint {
429
454
  return one || two;
430
455
  }
431
456
 
432
- add(other: RistrettoPoint): RistrettoPoint {
457
+ add(other: RistPoint): RistPoint {
433
458
  assertRstPoint(other);
434
- return new RistrettoPoint(this.ep.add(other.ep));
459
+ return new RistPoint(this.ep.add(other.ep));
435
460
  }
436
461
 
437
- subtract(other: RistrettoPoint): RistrettoPoint {
462
+ subtract(other: RistPoint): RistPoint {
438
463
  assertRstPoint(other);
439
- return new RistrettoPoint(this.ep.subtract(other.ep));
464
+ return new RistPoint(this.ep.subtract(other.ep));
440
465
  }
441
466
 
442
- multiply(scalar: bigint): RistrettoPoint {
443
- return new RistrettoPoint(this.ep.multiply(scalar));
467
+ multiply(scalar: bigint): RistPoint {
468
+ return new RistPoint(this.ep.multiply(scalar));
444
469
  }
445
470
 
446
- multiplyUnsafe(scalar: bigint): RistrettoPoint {
447
- return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
471
+ multiplyUnsafe(scalar: bigint): RistPoint {
472
+ return new RistPoint(this.ep.multiplyUnsafe(scalar));
448
473
  }
449
474
  }
450
-
451
- // https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/
452
- // Appendix B. Hashing to ristretto255
453
- export const hash_to_ristretto255 = (msg: Uint8Array, options: htf.htfBasicOpts) => {
475
+ export const RistrettoPoint = /* @__PURE__ */ (() => {
476
+ if (!RistPoint.BASE) RistPoint.BASE = new RistPoint(ed25519.ExtendedPoint.BASE);
477
+ if (!RistPoint.ZERO) RistPoint.ZERO = new RistPoint(ed25519.ExtendedPoint.ZERO);
478
+ return RistPoint;
479
+ })();
480
+
481
+ // Hashing to ristretto255. https://www.rfc-editor.org/rfc/rfc9380#appendix-B
482
+ export const hashToRistretto255 = (msg: Uint8Array, options: htfBasicOpts) => {
454
483
  const d = options.DST;
455
484
  const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
456
- const uniform_bytes = htf.expand_message_xmd(msg, DST, 64, sha512);
457
- const P = RistrettoPoint.hashToCurve(uniform_bytes);
485
+ const uniform_bytes = expand_message_xmd(msg, DST, 64, sha512);
486
+ const P = RistPoint.hashToCurve(uniform_bytes);
458
487
  return P;
459
488
  };
489
+ export const hash_to_ristretto255 = hashToRistretto255; // legacy