@noble/curves 0.5.1 → 0.6.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 (60) hide show
  1. package/README.md +49 -8
  2. package/lib/_shortw_utils.d.ts +11 -26
  3. package/lib/abstract/bls.d.ts +51 -35
  4. package/lib/abstract/bls.js +77 -139
  5. package/lib/abstract/{group.d.ts → curve.d.ts} +31 -1
  6. package/lib/abstract/{group.js → curve.js} +39 -2
  7. package/lib/abstract/edwards.d.ts +30 -81
  8. package/lib/abstract/edwards.js +225 -420
  9. package/lib/abstract/hash-to-curve.d.ts +25 -6
  10. package/lib/abstract/hash-to-curve.js +40 -12
  11. package/lib/abstract/modular.d.ts +20 -7
  12. package/lib/abstract/modular.js +80 -51
  13. package/lib/abstract/montgomery.js +3 -4
  14. package/lib/abstract/poseidon.d.ts +29 -0
  15. package/lib/abstract/poseidon.js +115 -0
  16. package/lib/abstract/utils.d.ts +5 -34
  17. package/lib/abstract/utils.js +23 -63
  18. package/lib/abstract/weierstrass.d.ts +56 -79
  19. package/lib/abstract/weierstrass.js +509 -641
  20. package/lib/bls12-381.d.ts +1 -0
  21. package/lib/bls12-381.js +75 -65
  22. package/lib/bn.js +1 -1
  23. package/lib/ed25519.d.ts +7 -5
  24. package/lib/ed25519.js +87 -84
  25. package/lib/ed448.d.ts +3 -0
  26. package/lib/ed448.js +88 -84
  27. package/lib/esm/abstract/bls.js +77 -139
  28. package/lib/esm/abstract/{group.js → curve.js} +37 -1
  29. package/lib/esm/abstract/edwards.js +223 -418
  30. package/lib/esm/abstract/hash-to-curve.js +38 -11
  31. package/lib/esm/abstract/modular.js +77 -50
  32. package/lib/esm/abstract/montgomery.js +4 -7
  33. package/lib/esm/abstract/poseidon.js +109 -0
  34. package/lib/esm/abstract/utils.js +21 -59
  35. package/lib/esm/abstract/weierstrass.js +508 -640
  36. package/lib/esm/bls12-381.js +86 -76
  37. package/lib/esm/bn.js +1 -1
  38. package/lib/esm/ed25519.js +85 -83
  39. package/lib/esm/ed448.js +86 -83
  40. package/lib/esm/jubjub.js +6 -5
  41. package/lib/esm/p256.js +11 -9
  42. package/lib/esm/p384.js +11 -9
  43. package/lib/esm/p521.js +13 -12
  44. package/lib/esm/secp256k1.js +118 -157
  45. package/lib/esm/stark.js +104 -39
  46. package/lib/jubjub.d.ts +3 -2
  47. package/lib/jubjub.js +6 -5
  48. package/lib/p192.d.ts +22 -52
  49. package/lib/p224.d.ts +22 -52
  50. package/lib/p256.d.ts +25 -52
  51. package/lib/p256.js +13 -10
  52. package/lib/p384.d.ts +25 -52
  53. package/lib/p384.js +13 -10
  54. package/lib/p521.d.ts +25 -52
  55. package/lib/p521.js +15 -13
  56. package/lib/secp256k1.d.ts +26 -42
  57. package/lib/secp256k1.js +118 -157
  58. package/lib/stark.d.ts +36 -21
  59. package/lib/stark.js +107 -39
  60. package/package.json +14 -9
@@ -1,19 +1,22 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ // The pairing-friendly Barreto-Lynn-Scott elliptic curve construction allows to:
3
+ // - Construct zk-SNARKs at the 128-bit security
4
+ // - Use threshold signatures, which allows a user to sign lots of messages with one signature and verify them swiftly in a batch, using Boneh-Lynn-Shacham signature scheme.
5
+ // Differences from @noble/bls12-381 1.4:
6
+ // - PointG1 -> G1.Point
7
+ // - PointG2 -> G2.Point
8
+ // - PointG2.fromSignature -> Signature.decode
9
+ // - PointG2.toSignature -> Signature.encode
10
+ // - Fixed Fp2 ORDER
11
+ // - Points now have only two coordinates
2
12
  import { sha256 } from '@noble/hashes/sha256';
3
13
  import { randomBytes } from '@noble/hashes/utils';
4
14
  import { bls } from './abstract/bls.js';
5
15
  import * as mod from './abstract/modular.js';
6
- import { concatBytes, ensureBytes, numberToBytesBE, bytesToNumberBE, bitLen, bitSet, bitGet, bitMask, } from './abstract/utils.js';
16
+ import { concatBytes as concatB, ensureBytes, numberToBytesBE, bytesToNumberBE, bitLen, bitSet, bitGet, bitMask, } from './abstract/utils.js';
7
17
  // Types
8
18
  import { mapToCurveSimpleSWU, } from './abstract/weierstrass.js';
9
19
  import { isogenyMap } from './abstract/hash-to-curve.js';
10
- // Differences from bls12-381:
11
- // - PointG1 -> G1.Point
12
- // - PointG2 -> G2.Point
13
- // - PointG2.fromSignature -> Signature.decode
14
- // - PointG2.toSignature -> Signature.encode
15
- // - Fixed Fp2 ORDER
16
- // Points now have only two coordinates
17
20
  // CURVE FIELDS
18
21
  // Finite field over p.
19
22
  const Fp = mod.Fp(0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn);
@@ -62,24 +65,24 @@ const Fp2 = {
62
65
  ONE: { c0: Fp.ONE, c1: Fp.ZERO },
63
66
  create: (num) => num,
64
67
  isValid: ({ c0, c1 }) => typeof c0 === 'bigint' && typeof c1 === 'bigint',
65
- isZero: ({ c0, c1 }) => Fp.isZero(c0) && Fp.isZero(c1),
66
- equals: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp.equals(c0, r0) && Fp.equals(c1, r1),
67
- negate: ({ c0, c1 }) => ({ c0: Fp.negate(c0), c1: Fp.negate(c1) }),
68
+ is0: ({ c0, c1 }) => Fp.is0(c0) && Fp.is0(c1),
69
+ eql: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp.eql(c0, r0) && Fp.eql(c1, r1),
70
+ neg: ({ c0, c1 }) => ({ c0: Fp.neg(c0), c1: Fp.neg(c1) }),
68
71
  pow: (num, power) => mod.FpPow(Fp2, num, power),
69
72
  invertBatch: (nums) => mod.FpInvertBatch(Fp2, nums),
70
73
  // Normalized
71
74
  add: Fp2Add,
72
75
  sub: Fp2Subtract,
73
76
  mul: Fp2Multiply,
74
- square: Fp2Square,
77
+ sqr: Fp2Square,
75
78
  // NonNormalized stuff
76
79
  addN: Fp2Add,
77
80
  subN: Fp2Subtract,
78
81
  mulN: Fp2Multiply,
79
- squareN: Fp2Square,
82
+ sqrN: Fp2Square,
80
83
  // Why inversion for bigint inside Fp instead of Fp2? it is even used in that context?
81
- div: (lhs, rhs) => Fp2.mul(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp2.invert(rhs)),
82
- invert: ({ c0: a, c1: b }) => {
84
+ div: (lhs, rhs) => Fp2.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp2.inv(rhs)),
85
+ inv: ({ c0: a, c1: b }) => {
83
86
  // We wish to find the multiplicative inverse of a nonzero
84
87
  // element a + bu in Fp2. We leverage an identity
85
88
  //
@@ -93,10 +96,12 @@ const Fp2 = {
93
96
  // This gives that (a - bu)/(a² + b²) is the inverse
94
97
  // of (a + bu). Importantly, this can be computing using
95
98
  // only a single inversion in Fp.
96
- const factor = Fp.invert(Fp.create(a * a + b * b));
99
+ const factor = Fp.inv(Fp.create(a * a + b * b));
97
100
  return { c0: Fp.mul(factor, Fp.create(a)), c1: Fp.mul(factor, Fp.create(-b)) };
98
101
  },
99
102
  sqrt: (num) => {
103
+ if (Fp2.eql(num, Fp2.ZERO))
104
+ return Fp2.ZERO; // Algo doesn't handles this case
100
105
  // TODO: Optimize this line. It's extremely slow.
101
106
  // Speeding this up would boost aggregateSignatures.
102
107
  // https://eprint.iacr.org/2012/685.pdf applicable?
@@ -104,9 +109,9 @@ const Fp2 = {
104
109
  // https://github.com/supranational/blst/blob/aae0c7d70b799ac269ff5edf29d8191dbd357876/src/exp2.c#L1
105
110
  // Inspired by https://github.com/dalek-cryptography/curve25519-dalek/blob/17698df9d4c834204f83a3574143abacb4fc81a5/src/field.rs#L99
106
111
  const candidateSqrt = Fp2.pow(num, (Fp2.ORDER + 8n) / 16n);
107
- const check = Fp2.div(Fp2.square(candidateSqrt), num); // candidateSqrt.square().div(this);
112
+ const check = Fp2.div(Fp2.sqr(candidateSqrt), num); // candidateSqrt.square().div(this);
108
113
  const R = FP2_ROOTS_OF_UNITY;
109
- const divisor = [R[0], R[2], R[4], R[6]].find((r) => Fp2.equals(r, check));
114
+ const divisor = [R[0], R[2], R[4], R[6]].find((r) => Fp2.eql(r, check));
110
115
  if (!divisor)
111
116
  throw new Error('No root');
112
117
  const index = R.indexOf(divisor);
@@ -114,7 +119,7 @@ const Fp2 = {
114
119
  if (!root)
115
120
  throw new Error('Invalid root');
116
121
  const x1 = Fp2.div(candidateSqrt, root);
117
- const x2 = Fp2.negate(x1);
122
+ const x2 = Fp2.neg(x1);
118
123
  const { re: re1, im: im1 } = Fp2.reim(x1);
119
124
  const { re: re2, im: im2 } = Fp2.reim(x2);
120
125
  if (im1 > im2 || (im1 === im2 && re1 > re2))
@@ -135,7 +140,7 @@ const Fp2 = {
135
140
  throw new Error(`fromBytes wrong length=${b.length}`);
136
141
  return { c0: Fp.fromBytes(b.subarray(0, Fp.BYTES)), c1: Fp.fromBytes(b.subarray(Fp.BYTES)) };
137
142
  },
138
- toBytes: ({ c0, c1 }) => concatBytes(Fp.toBytes(c0), Fp.toBytes(c1)),
143
+ toBytes: ({ c0, c1 }) => concatB(Fp.toBytes(c0), Fp.toBytes(c1)),
139
144
  cmov: ({ c0, c1 }, { c0: r0, c1: r1 }, c) => ({
140
145
  c0: Fp.cmov(c0, r0, c),
141
146
  c1: Fp.cmov(c1, r1, c),
@@ -225,15 +230,15 @@ const Fp6Multiply = ({ c0, c1, c2 }, rhs) => {
225
230
  };
226
231
  };
227
232
  const Fp6Square = ({ c0, c1, c2 }) => {
228
- let t0 = Fp2.square(c0); // c0²
233
+ let t0 = Fp2.sqr(c0); // c0²
229
234
  let t1 = Fp2.mul(Fp2.mul(c0, c1), 2n); // 2 * c0 * c1
230
235
  let t3 = Fp2.mul(Fp2.mul(c1, c2), 2n); // 2 * c1 * c2
231
- let t4 = Fp2.square(c2); // c2²
236
+ let t4 = Fp2.sqr(c2); // c2²
232
237
  return {
233
238
  c0: Fp2.add(Fp2.mulByNonresidue(t3), t0),
234
239
  c1: Fp2.add(Fp2.mulByNonresidue(t4), t1),
235
240
  // T1 + (c0 - c1 + c2)² + T3 - T0 - T4
236
- c2: Fp2.sub(Fp2.sub(Fp2.add(Fp2.add(t1, Fp2.square(Fp2.add(Fp2.sub(c0, c1), c2))), t3), t0), t4),
241
+ c2: Fp2.sub(Fp2.sub(Fp2.add(Fp2.add(t1, Fp2.sqr(Fp2.add(Fp2.sub(c0, c1), c2))), t3), t0), t4),
237
242
  };
238
243
  };
239
244
  const Fp6 = {
@@ -245,32 +250,32 @@ const Fp6 = {
245
250
  ONE: { c0: Fp2.ONE, c1: Fp2.ZERO, c2: Fp2.ZERO },
246
251
  create: (num) => num,
247
252
  isValid: ({ c0, c1, c2 }) => Fp2.isValid(c0) && Fp2.isValid(c1) && Fp2.isValid(c2),
248
- isZero: ({ c0, c1, c2 }) => Fp2.isZero(c0) && Fp2.isZero(c1) && Fp2.isZero(c2),
249
- negate: ({ c0, c1, c2 }) => ({ c0: Fp2.negate(c0), c1: Fp2.negate(c1), c2: Fp2.negate(c2) }),
250
- equals: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => Fp2.equals(c0, r0) && Fp2.equals(c1, r1) && Fp2.equals(c2, r2),
253
+ is0: ({ c0, c1, c2 }) => Fp2.is0(c0) && Fp2.is0(c1) && Fp2.is0(c2),
254
+ neg: ({ c0, c1, c2 }) => ({ c0: Fp2.neg(c0), c1: Fp2.neg(c1), c2: Fp2.neg(c2) }),
255
+ eql: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => Fp2.eql(c0, r0) && Fp2.eql(c1, r1) && Fp2.eql(c2, r2),
251
256
  sqrt: () => {
252
257
  throw new Error('Not implemented');
253
258
  },
254
259
  // Do we need division by bigint at all? Should be done via order:
255
- div: (lhs, rhs) => Fp6.mul(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp6.invert(rhs)),
260
+ div: (lhs, rhs) => Fp6.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp6.inv(rhs)),
256
261
  pow: (num, power) => mod.FpPow(Fp6, num, power),
257
262
  invertBatch: (nums) => mod.FpInvertBatch(Fp6, nums),
258
263
  // Normalized
259
264
  add: Fp6Add,
260
265
  sub: Fp6Subtract,
261
266
  mul: Fp6Multiply,
262
- square: Fp6Square,
267
+ sqr: Fp6Square,
263
268
  // NonNormalized stuff
264
269
  addN: Fp6Add,
265
270
  subN: Fp6Subtract,
266
271
  mulN: Fp6Multiply,
267
- squareN: Fp6Square,
268
- invert: ({ c0, c1, c2 }) => {
269
- let t0 = Fp2.sub(Fp2.square(c0), Fp2.mulByNonresidue(Fp2.mul(c2, c1))); // c0² - c2 * c1 * (u + 1)
270
- let t1 = Fp2.sub(Fp2.mulByNonresidue(Fp2.square(c2)), Fp2.mul(c0, c1)); // c2² * (u + 1) - c0 * c1
271
- let t2 = Fp2.sub(Fp2.square(c1), Fp2.mul(c0, c2)); // c1² - c0 * c2
272
+ sqrN: Fp6Square,
273
+ inv: ({ c0, c1, c2 }) => {
274
+ let t0 = Fp2.sub(Fp2.sqr(c0), Fp2.mulByNonresidue(Fp2.mul(c2, c1))); // c0² - c2 * c1 * (u + 1)
275
+ let t1 = Fp2.sub(Fp2.mulByNonresidue(Fp2.sqr(c2)), Fp2.mul(c0, c1)); // c2² * (u + 1) - c0 * c1
276
+ let t2 = Fp2.sub(Fp2.sqr(c1), Fp2.mul(c0, c2)); // c1² - c0 * c2
272
277
  // 1/(((c2 * T1 + c1 * T2) * v) + c0 * T0)
273
- let t4 = Fp2.invert(Fp2.add(Fp2.mulByNonresidue(Fp2.add(Fp2.mul(c2, t1), Fp2.mul(c1, t2))), Fp2.mul(c0, t0)));
278
+ let t4 = Fp2.inv(Fp2.add(Fp2.mulByNonresidue(Fp2.add(Fp2.mul(c2, t1), Fp2.mul(c1, t2))), Fp2.mul(c0, t0)));
274
279
  return { c0: Fp2.mul(t4, t0), c1: Fp2.mul(t4, t1), c2: Fp2.mul(t4, t2) };
275
280
  },
276
281
  // Bytes utils
@@ -283,7 +288,7 @@ const Fp6 = {
283
288
  c2: Fp2.fromBytes(b.subarray(2 * Fp2.BYTES)),
284
289
  };
285
290
  },
286
- toBytes: ({ c0, c1, c2 }) => concatBytes(Fp2.toBytes(c0), Fp2.toBytes(c1), Fp2.toBytes(c2)),
291
+ toBytes: ({ c0, c1, c2 }) => concatB(Fp2.toBytes(c0), Fp2.toBytes(c1), Fp2.toBytes(c2)),
287
292
  cmov: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }, c) => ({
288
293
  c0: Fp2.cmov(c0, r0, c),
289
294
  c1: Fp2.cmov(c1, r1, c),
@@ -411,11 +416,11 @@ const Fp12Square = ({ c0, c1 }) => {
411
416
  }; // AB + AB
412
417
  };
413
418
  function Fp4Square(a, b) {
414
- const a2 = Fp2.square(a);
415
- const b2 = Fp2.square(b);
419
+ const a2 = Fp2.sqr(a);
420
+ const b2 = Fp2.sqr(b);
416
421
  return {
417
422
  first: Fp2.add(Fp2.mulByNonresidue(b2), a2),
418
- second: Fp2.sub(Fp2.sub(Fp2.square(Fp2.add(a, b)), a2), b2), // (a + b)² - a² - b²
423
+ second: Fp2.sub(Fp2.sub(Fp2.sqr(Fp2.add(a, b)), a2), b2), // (a + b)² - a² - b²
419
424
  };
420
425
  }
421
426
  const Fp12 = {
@@ -427,29 +432,29 @@ const Fp12 = {
427
432
  ONE: { c0: Fp6.ONE, c1: Fp6.ZERO },
428
433
  create: (num) => num,
429
434
  isValid: ({ c0, c1 }) => Fp6.isValid(c0) && Fp6.isValid(c1),
430
- isZero: ({ c0, c1 }) => Fp6.isZero(c0) && Fp6.isZero(c1),
431
- negate: ({ c0, c1 }) => ({ c0: Fp6.negate(c0), c1: Fp6.negate(c1) }),
432
- equals: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp6.equals(c0, r0) && Fp6.equals(c1, r1),
435
+ is0: ({ c0, c1 }) => Fp6.is0(c0) && Fp6.is0(c1),
436
+ neg: ({ c0, c1 }) => ({ c0: Fp6.neg(c0), c1: Fp6.neg(c1) }),
437
+ eql: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp6.eql(c0, r0) && Fp6.eql(c1, r1),
433
438
  sqrt: () => {
434
439
  throw new Error('Not implemented');
435
440
  },
436
- invert: ({ c0, c1 }) => {
437
- let t = Fp6.invert(Fp6.sub(Fp6.square(c0), Fp6.mulByNonresidue(Fp6.square(c1)))); // 1 / (c0² - c1² * v)
438
- return { c0: Fp6.mul(c0, t), c1: Fp6.negate(Fp6.mul(c1, t)) }; // ((C0 * T) * T) + (-C1 * T) * w
441
+ inv: ({ c0, c1 }) => {
442
+ let t = Fp6.inv(Fp6.sub(Fp6.sqr(c0), Fp6.mulByNonresidue(Fp6.sqr(c1)))); // 1 / (c0² - c1² * v)
443
+ return { c0: Fp6.mul(c0, t), c1: Fp6.neg(Fp6.mul(c1, t)) }; // ((C0 * T) * T) + (-C1 * T) * w
439
444
  },
440
- div: (lhs, rhs) => Fp12.mul(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp12.invert(rhs)),
445
+ div: (lhs, rhs) => Fp12.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : Fp12.inv(rhs)),
441
446
  pow: (num, power) => mod.FpPow(Fp12, num, power),
442
447
  invertBatch: (nums) => mod.FpInvertBatch(Fp12, nums),
443
448
  // Normalized
444
449
  add: Fp12Add,
445
450
  sub: Fp12Subtract,
446
451
  mul: Fp12Multiply,
447
- square: Fp12Square,
452
+ sqr: Fp12Square,
448
453
  // NonNormalized stuff
449
454
  addN: Fp12Add,
450
455
  subN: Fp12Subtract,
451
456
  mulN: Fp12Multiply,
452
- squareN: Fp12Square,
457
+ sqrN: Fp12Square,
453
458
  // Bytes utils
454
459
  fromBytes: (b) => {
455
460
  if (b.length !== Fp12.BYTES)
@@ -459,7 +464,7 @@ const Fp12 = {
459
464
  c1: Fp6.fromBytes(b.subarray(Fp6.BYTES)),
460
465
  };
461
466
  },
462
- toBytes: ({ c0, c1 }) => concatBytes(Fp6.toBytes(c0), Fp6.toBytes(c1)),
467
+ toBytes: ({ c0, c1 }) => concatB(Fp6.toBytes(c0), Fp6.toBytes(c1)),
463
468
  cmov: ({ c0, c1 }, { c0: r0, c1: r1 }, c) => ({
464
469
  c0: Fp6.cmov(c0, r0, c),
465
470
  c1: Fp6.cmov(c1, r1, c),
@@ -503,7 +508,7 @@ const Fp12 = {
503
508
  c0: Fp6.multiplyByFp2(c0, rhs),
504
509
  c1: Fp6.multiplyByFp2(c1, rhs),
505
510
  }),
506
- conjugate: ({ c0, c1 }) => ({ c0, c1: Fp6.negate(c1) }),
511
+ conjugate: ({ c0, c1 }) => ({ c0, c1: Fp6.neg(c1) }),
507
512
  // A cyclotomic group is a subgroup of Fp^n defined by
508
513
  // GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) = 1}
509
514
  // The result of any pairing is in a cyclotomic subgroup
@@ -782,7 +787,7 @@ function G2psi(c, P) {
782
787
  // 1 / F2(2)^((p-1)/3) in GF(p²)
783
788
  const PSI2_C1 = 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn;
784
789
  function psi2(x, y) {
785
- return [Fp2.mul(x, PSI2_C1), Fp2.negate(y)];
790
+ return [Fp2.mul(x, PSI2_C1), Fp2.neg(y)];
786
791
  }
787
792
  function G2psi2(c, P) {
788
793
  const affine = P.toAffine();
@@ -804,6 +809,7 @@ const htfDefaults = {
804
809
  // defined in section 2.2.5
805
810
  // Use utils.getDSTLabel(), utils.setDSTLabel(value)
806
811
  DST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_',
812
+ encodeDST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_',
807
813
  // p: the characteristic of F
808
814
  // where F is a finite field of characteristic p and order q = p^m
809
815
  p: Fp.ORDER,
@@ -870,7 +876,7 @@ export const bls12_381 = bls({
870
876
  isTorsionFree: (c, point) => {
871
877
  // φ endomorphism
872
878
  const cubicRootOfUnityModP = 0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen;
873
- const phi = new c(Fp.mul(point.x, cubicRootOfUnityModP), point.y, point.z);
879
+ const phi = new c(Fp.mul(point.px, cubicRootOfUnityModP), point.py, point.pz);
874
880
  // todo: unroll
875
881
  const xP = point.multiplyUnsafe(bls12_381.CURVE.x).negate(); // [x]P
876
882
  const u2P = xP.multiplyUnsafe(bls12_381.CURVE.x); // [u2]P
@@ -912,13 +918,13 @@ export const bls12_381 = bls({
912
918
  throw new Error('Invalid compressed G1 point');
913
919
  const aflag = bitGet(compressedValue, C_BIT_POS);
914
920
  if ((y * 2n) / P !== aflag)
915
- y = Fp.negate(y);
921
+ y = Fp.neg(y);
916
922
  return { x: Fp.create(x), y: Fp.create(y) };
917
923
  }
918
924
  else if (bytes.length === 96) {
919
925
  // Check if the infinity flag is set
920
926
  if ((bytes[0] & (1 << 6)) !== 0)
921
- return bls12_381.G1.Point.ZERO;
927
+ return bls12_381.G1.ProjectivePoint.ZERO.toAffine();
922
928
  const x = bytesToNumberBE(bytes.slice(0, Fp.BYTES));
923
929
  const y = bytesToNumberBE(bytes.slice(Fp.BYTES));
924
930
  return { x: Fp.create(x), y: Fp.create(y) };
@@ -929,7 +935,7 @@ export const bls12_381 = bls({
929
935
  },
930
936
  toBytes: (c, point, isCompressed) => {
931
937
  const isZero = point.equals(c.ZERO);
932
- const { x, y } = point;
938
+ const { x, y } = point.toAffine();
933
939
  if (isCompressed) {
934
940
  if (isZero)
935
941
  return COMPRESSED_ZERO.slice();
@@ -942,11 +948,11 @@ export const bls12_381 = bls({
942
948
  else {
943
949
  if (isZero) {
944
950
  // 2x PUBLIC_KEY_LENGTH
945
- const x = concatBytes(new Uint8Array([0x40]), new Uint8Array(2 * Fp.BYTES - 1));
951
+ const x = concatB(new Uint8Array([0x40]), new Uint8Array(2 * Fp.BYTES - 1));
946
952
  return x;
947
953
  }
948
954
  else {
949
- return concatBytes(numberToBytesBE(x, Fp.BYTES), numberToBytesBE(y, Fp.BYTES));
955
+ return concatB(numberToBytesBE(x, Fp.BYTES), numberToBytesBE(y, Fp.BYTES));
950
956
  }
951
957
  }
952
958
  },
@@ -1016,6 +1022,8 @@ export const bls12_381 = bls({
1016
1022
  const bitC = m_byte & 0x80; // compression bit
1017
1023
  const bitI = m_byte & 0x40; // point at infinity bit
1018
1024
  const bitS = m_byte & 0x20; // sign bit
1025
+ const L = Fp.BYTES;
1026
+ const slc = (b, from, to) => bytesToNumberBE(b.slice(from, to));
1019
1027
  if (bytes.length === 96 && bitC) {
1020
1028
  const { b } = bls12_381.CURVE.G2;
1021
1029
  const P = Fp.ORDER;
@@ -1027,13 +1035,13 @@ export const bls12_381 = bls({
1027
1035
  }
1028
1036
  return { x: Fp2.ZERO, y: Fp2.ZERO };
1029
1037
  }
1030
- const x_1 = bytesToNumberBE(bytes.slice(0, Fp.BYTES));
1031
- const x_0 = bytesToNumberBE(bytes.slice(Fp.BYTES));
1038
+ const x_1 = slc(bytes, 0, L);
1039
+ const x_0 = slc(bytes, L, 2 * L);
1032
1040
  const x = Fp2.create({ c0: Fp.create(x_0), c1: Fp.create(x_1) });
1033
1041
  const right = Fp2.add(Fp2.pow(x, 3n), b); // y² = x³ + 4 * (u+1) = x³ + b
1034
1042
  let y = Fp2.sqrt(right);
1035
1043
  const Y_bit = y.c1 === 0n ? (y.c0 * 2n) / P : (y.c1 * 2n) / P ? 1n : 0n;
1036
- y = bitS > 0 && Y_bit > 0 ? y : Fp2.negate(y);
1044
+ y = bitS > 0 && Y_bit > 0 ? y : Fp2.neg(y);
1037
1045
  return { x, y };
1038
1046
  }
1039
1047
  else if (bytes.length === 192 && !bitC) {
@@ -1041,10 +1049,10 @@ export const bls12_381 = bls({
1041
1049
  if ((bytes[0] & (1 << 6)) !== 0) {
1042
1050
  return { x: Fp2.ZERO, y: Fp2.ZERO };
1043
1051
  }
1044
- const x1 = bytesToNumberBE(bytes.slice(0, Fp.BYTES));
1045
- const x0 = bytesToNumberBE(bytes.slice(Fp.BYTES, 2 * Fp.BYTES));
1046
- const y1 = bytesToNumberBE(bytes.slice(2 * Fp.BYTES, 3 * Fp.BYTES));
1047
- const y0 = bytesToNumberBE(bytes.slice(3 * Fp.BYTES));
1052
+ const x1 = slc(bytes, 0, L);
1053
+ const x0 = slc(bytes, L, 2 * L);
1054
+ const y1 = slc(bytes, 2 * L, 3 * L);
1055
+ const y0 = slc(bytes, 3 * L, 4 * L);
1048
1056
  return { x: Fp2.fromBigTuple([x0, x1]), y: Fp2.fromBigTuple([y0, y1]) };
1049
1057
  }
1050
1058
  else {
@@ -1053,23 +1061,23 @@ export const bls12_381 = bls({
1053
1061
  },
1054
1062
  toBytes: (c, point, isCompressed) => {
1055
1063
  const isZero = point.equals(c.ZERO);
1056
- const { x, y } = point;
1064
+ const { x, y } = point.toAffine();
1057
1065
  if (isCompressed) {
1058
1066
  const P = Fp.ORDER;
1059
1067
  if (isZero)
1060
- return concatBytes(COMPRESSED_ZERO, numberToBytesBE(0n, Fp.BYTES));
1068
+ return concatB(COMPRESSED_ZERO, numberToBytesBE(0n, Fp.BYTES));
1061
1069
  const flag = Boolean(y.c1 === 0n ? (y.c0 * 2n) / P : (y.c1 * 2n) / P);
1062
1070
  // set compressed & sign bits (looks like different offsets than for G1/Fp?)
1063
1071
  let x_1 = bitSet(x.c1, C_BIT_POS, flag);
1064
1072
  x_1 = bitSet(x_1, S_BIT_POS, true);
1065
- return concatBytes(numberToBytesBE(x_1, Fp.BYTES), numberToBytesBE(x.c0, Fp.BYTES));
1073
+ return concatB(numberToBytesBE(x_1, Fp.BYTES), numberToBytesBE(x.c0, Fp.BYTES));
1066
1074
  }
1067
1075
  else {
1068
1076
  if (isZero)
1069
- return concatBytes(new Uint8Array([0x40]), new Uint8Array(4 * Fp.BYTES - 1)); // bytes[0] |= 1 << 6;
1077
+ return concatB(new Uint8Array([0x40]), new Uint8Array(4 * Fp.BYTES - 1)); // bytes[0] |= 1 << 6;
1070
1078
  const { re: x0, im: x1 } = Fp2.reim(x);
1071
1079
  const { re: y0, im: y1 } = Fp2.reim(y);
1072
- return concatBytes(numberToBytesBE(x1, Fp.BYTES), numberToBytesBE(x0, Fp.BYTES), numberToBytesBE(y1, Fp.BYTES), numberToBytesBE(y0, Fp.BYTES));
1080
+ return concatB(numberToBytesBE(x1, Fp.BYTES), numberToBytesBE(x0, Fp.BYTES), numberToBytesBE(y1, Fp.BYTES), numberToBytesBE(y0, Fp.BYTES));
1073
1081
  }
1074
1082
  },
1075
1083
  Signature: {
@@ -1085,7 +1093,7 @@ export const bls12_381 = bls({
1085
1093
  // Indicates the infinity point
1086
1094
  const bflag1 = bitGet(z1, I_BIT_POS);
1087
1095
  if (bflag1 === 1n)
1088
- return bls12_381.G2.Point.ZERO;
1096
+ return bls12_381.G2.ProjectivePoint.ZERO;
1089
1097
  const x1 = Fp.create(z1 & Fp.MASK);
1090
1098
  const x2 = Fp.create(z2);
1091
1099
  const x = Fp2.create({ c0: x2, c1: x1 });
@@ -1101,23 +1109,25 @@ export const bls12_381 = bls({
1101
1109
  const isGreater = y1 > 0n && (y1 * 2n) / P !== aflag1;
1102
1110
  const isZero = y1 === 0n && (y0 * 2n) / P !== aflag1;
1103
1111
  if (isGreater || isZero)
1104
- y = Fp2.negate(y);
1105
- const point = new bls12_381.G2.Point(x, y);
1112
+ y = Fp2.neg(y);
1113
+ const point = bls12_381.G2.ProjectivePoint.fromAffine({ x, y });
1114
+ // console.log('Signature.decode', point);
1106
1115
  point.assertValidity();
1107
1116
  return point;
1108
1117
  },
1109
1118
  encode(point) {
1110
1119
  // NOTE: by some reasons it was missed in bls12-381, looks like bug
1111
1120
  point.assertValidity();
1112
- if (point.equals(bls12_381.G2.Point.ZERO))
1113
- return concatBytes(COMPRESSED_ZERO, numberToBytesBE(0n, Fp.BYTES));
1114
- const { re: x0, im: x1 } = Fp2.reim(point.x);
1115
- const { re: y0, im: y1 } = Fp2.reim(point.y);
1121
+ if (point.equals(bls12_381.G2.ProjectivePoint.ZERO))
1122
+ return concatB(COMPRESSED_ZERO, numberToBytesBE(0n, Fp.BYTES));
1123
+ const a = point.toAffine();
1124
+ const { re: x0, im: x1 } = Fp2.reim(a.x);
1125
+ const { re: y0, im: y1 } = Fp2.reim(a.y);
1116
1126
  const tmp = y1 > 0n ? y1 * 2n : y0 * 2n;
1117
1127
  const aflag1 = Boolean((tmp / Fp.ORDER) & 1n);
1118
1128
  const z1 = bitSet(bitSet(x1, 381, aflag1), S_BIT_POS, true);
1119
1129
  const z2 = x0;
1120
- return concatBytes(numberToBytesBE(z1, Fp.BYTES), numberToBytesBE(z2, Fp.BYTES));
1130
+ return concatB(numberToBytesBE(z1, Fp.BYTES), numberToBytesBE(z2, Fp.BYTES));
1121
1131
  },
1122
1132
  },
1123
1133
  },
package/lib/esm/bn.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
- import { weierstrass } from './abstract/weierstrass.js';
3
2
  import { sha256 } from '@noble/hashes/sha256';
3
+ import { weierstrass } from './abstract/weierstrass.js';
4
4
  import { getHash } from './_shortw_utils.js';
5
5
  import { Fp } from './abstract/modular.js';
6
6
  /**