@noble/curves 0.9.0 → 0.9.1

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.
@@ -275,7 +275,7 @@ export function FpPow<T>(f: IField<T>, num: T, power: bigint): T {
275
275
  while (power > _0n) {
276
276
  if (power & _1n) p = f.mul(p, d);
277
277
  d = f.sqr(d);
278
- power >>= 1n;
278
+ power >>= _1n;
279
279
  }
280
280
  return p;
281
281
  }
@@ -58,6 +58,8 @@ export interface ProjPointType<T> extends Group<ProjPointType<T>> {
58
58
  readonly px: T;
59
59
  readonly py: T;
60
60
  readonly pz: T;
61
+ get x(): T;
62
+ get y(): T;
61
63
  multiply(scalar: bigint): ProjPointType<T>;
62
64
  toAffine(iz?: T): AffinePoint<T>;
63
65
  isTorsionFree(): boolean;
@@ -176,9 +178,9 @@ const DER = {
176
178
  },
177
179
  };
178
180
 
179
- // Be friendly to bad ECMAScript parsers by not using bigint literals like 123n
180
- const _0n = BigInt(0);
181
- const _1n = BigInt(1);
181
+ // Be friendly to bad ECMAScript parsers by not using bigint literals
182
+ // prettier-ignore
183
+ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
182
184
 
183
185
  export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
184
186
  const CURVE = validatePointOpts(opts);
@@ -365,7 +367,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
365
367
  // Cost: 8M + 3S + 3*a + 2*b3 + 15add.
366
368
  double() {
367
369
  const { a, b } = CURVE;
368
- const b3 = Fp.mul(b, 3n);
370
+ const b3 = Fp.mul(b, _3n);
369
371
  const { px: X1, py: Y1, pz: Z1 } = this;
370
372
  let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
371
373
  let t0 = Fp.mul(X1, X1); // step 1
@@ -412,7 +414,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
412
414
  const { px: X2, py: Y2, pz: Z2 } = other;
413
415
  let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
414
416
  const a = CURVE.a;
415
- const b3 = Fp.mul(CURVE.b, 3n);
417
+ const b3 = Fp.mul(CURVE.b, _3n);
416
418
  let t0 = Fp.mul(X1, X2); // step 1
417
419
  let t1 = Fp.mul(Y1, Y2);
418
420
  let t2 = Fp.mul(Z1, Z2);
@@ -1078,15 +1080,15 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1078
1080
  export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
1079
1081
  // Generic implementation
1080
1082
  const q = Fp.ORDER;
1081
- let l = 0n;
1082
- for (let o = q - 1n; o % 2n === 0n; o /= 2n) l += 1n;
1083
+ let l = _0n;
1084
+ for (let o = q - _1n; o % _2n === _0n; o /= _2n) l += _1n;
1083
1085
  const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1.
1084
- const c2 = (q - 1n) / 2n ** c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic
1085
- const c3 = (c2 - 1n) / 2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic
1086
- const c4 = 2n ** c1 - 1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic
1087
- const c5 = 2n ** (c1 - 1n); // 5. c5 = 2^(c1 - 1) # Integer arithmetic
1086
+ const c2 = (q - _1n) / _2n ** c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic
1087
+ const c3 = (c2 - _1n) / _2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic
1088
+ const c4 = _2n ** c1 - _1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic
1089
+ const c5 = _2n ** (c1 - _1n); // 5. c5 = 2^(c1 - 1) # Integer arithmetic
1088
1090
  const c6 = Fp.pow(Z, c2); // 6. c6 = Z^c2
1089
- const c7 = Fp.pow(Z, (c2 + 1n) / 2n); // 7. c7 = Z^((c2 + 1) / 2)
1091
+ const c7 = Fp.pow(Z, (c2 + _1n) / _2n); // 7. c7 = Z^((c2 + 1) / 2)
1090
1092
  let sqrtRatio = (u: T, v: T): { isValid: boolean; value: T } => {
1091
1093
  let tv1 = c6; // 1. tv1 = c6
1092
1094
  let tv2 = Fp.pow(v, c4); // 2. tv2 = v^c4
@@ -1106,7 +1108,7 @@ export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
1106
1108
  tv4 = Fp.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR)
1107
1109
  // 17. for i in (c1, c1 - 1, ..., 2):
1108
1110
  for (let i = c1; i > 1; i--) {
1109
- let tv5 = 2n ** (i - 2n); // 18. tv5 = i - 2; 19. tv5 = 2^tv5
1111
+ let tv5 = _2n ** (i - _2n); // 18. tv5 = i - 2; 19. tv5 = 2^tv5
1110
1112
  let tvv5 = Fp.pow(tv4, tv5); // 20. tv5 = tv4^tv5
1111
1113
  const e1 = Fp.eql(tvv5, Fp.ONE); // 21. e1 = tv5 == 1
1112
1114
  tv2 = Fp.mul(tv3, tv1); // 22. tv2 = tv3 * tv1
@@ -1117,9 +1119,9 @@ export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
1117
1119
  }
1118
1120
  return { isValid: isQR, value: tv3 };
1119
1121
  };
1120
- if (Fp.ORDER % 4n === 3n) {
1122
+ if (Fp.ORDER % _4n === _3n) {
1121
1123
  // sqrt_ratio_3mod4(u, v)
1122
- const c1 = (Fp.ORDER - 3n) / 4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic
1124
+ const c1 = (Fp.ORDER - _3n) / _4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic
1123
1125
  const c2 = Fp.sqrt(Fp.neg(Z)); // 2. c2 = sqrt(-Z)
1124
1126
  sqrtRatio = (u: T, v: T) => {
1125
1127
  let tv1 = Fp.sqr(v); // 1. tv1 = v^2
@@ -1135,7 +1137,7 @@ export function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T) {
1135
1137
  };
1136
1138
  }
1137
1139
  // No curves uses that
1138
- // if (Fp.ORDER % 8n === 5n) // sqrt_ratio_5mod8
1140
+ // if (Fp.ORDER % _8n === _5n) // sqrt_ratio_5mod8
1139
1141
  return sqrtRatio;
1140
1142
  }
1141
1143
  // From draft-irtf-cfrg-hash-to-curve-16
package/src/bls12-381.ts CHANGED
@@ -69,16 +69,23 @@ import {
69
69
  } from './abstract/weierstrass.js';
70
70
  import { isogenyMap } from './abstract/hash-to-curve.js';
71
71
 
72
+ // Be friendly to bad ECMAScript parsers by not using bigint literals
73
+ // prettier-ignore
74
+ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
75
+ const _8n = BigInt(8),
76
+ _16n = BigInt(16);
77
+
72
78
  // CURVE FIELDS
73
79
  // Finite field over p.
74
- const Fp =
75
- mod.Field(
76
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn
77
- );
80
+ const Fp = mod.Field(
81
+ BigInt(
82
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'
83
+ )
84
+ );
78
85
  type Fp = bigint;
79
86
  // Finite field over r.
80
87
  // This particular field is not used anywhere in bls12-381, but it is still useful.
81
- const Fr = mod.Field(0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n);
88
+ const Fr = mod.Field(BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'));
82
89
 
83
90
  // Fp₂ over complex plane
84
91
  type BigintTuple = [bigint, bigint];
@@ -121,8 +128,9 @@ type Fp2Utils = {
121
128
  // h2q
122
129
  // NOTE: ORDER was wrong!
123
130
  const FP2_ORDER =
124
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn **
125
- 2n;
131
+ BigInt(
132
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'
133
+ ) ** _2n;
126
134
 
127
135
  const Fp2: mod.IField<Fp2> & Fp2Utils = {
128
136
  ORDER: FP2_ORDER,
@@ -175,7 +183,7 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
175
183
  // https://github.com/zkcrypto/bls12_381/blob/080eaa74ec0e394377caa1ba302c8c121df08b07/src/fp2.rs#L250
176
184
  // https://github.com/supranational/blst/blob/aae0c7d70b799ac269ff5edf29d8191dbd357876/src/exp2.c#L1
177
185
  // Inspired by https://github.com/dalek-cryptography/curve25519-dalek/blob/17698df9d4c834204f83a3574143abacb4fc81a5/src/field.rs#L99
178
- const candidateSqrt = Fp2.pow(num, (Fp2.ORDER + 8n) / 16n);
186
+ const candidateSqrt = Fp2.pow(num, (Fp2.ORDER + _8n) / _16n);
179
187
  const check = Fp2.div(Fp2.sqr(candidateSqrt), num); // candidateSqrt.square().div(this);
180
188
  const R = FP2_ROOTS_OF_UNITY;
181
189
  const divisor = [R[0], R[2], R[4], R[6]].find((r) => Fp2.eql(r, check));
@@ -193,10 +201,10 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
193
201
  // Same as sgn0_fp2 in draft-irtf-cfrg-hash-to-curve-16
194
202
  isOdd: (x: Fp2) => {
195
203
  const { re: x0, im: x1 } = Fp2.reim(x);
196
- const sign_0 = x0 % 2n;
197
- const zero_0 = x0 === 0n;
198
- const sign_1 = x1 % 2n;
199
- return BigInt(sign_0 || (zero_0 && sign_1)) == 1n;
204
+ const sign_0 = x0 % _2n;
205
+ const zero_0 = x0 === _0n;
206
+ const sign_1 = x1 % _2n;
207
+ return BigInt(sign_0 || (zero_0 && sign_1)) == _1n;
200
208
  },
201
209
  // Bytes util
202
210
  fromBytes(b: Uint8Array): Fp2 {
@@ -216,8 +224,8 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
216
224
  // multiply by u + 1
217
225
  mulByNonresidue: ({ c0, c1 }) => ({ c0: Fp.sub(c0, c1), c1: Fp.add(c0, c1) }),
218
226
  multiplyByB: ({ c0, c1 }) => {
219
- let t0 = Fp.mul(c0, 4n); // 4 * c0
220
- let t1 = Fp.mul(c1, 4n); // 4 * c1
227
+ let t0 = Fp.mul(c0, _4n); // 4 * c0
228
+ let t1 = Fp.mul(c1, _4n); // 4 * c1
221
229
  // (T0-T1) + (T0+T1)*i
222
230
  return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
223
231
  },
@@ -234,33 +242,36 @@ const Fp2: mod.IField<Fp2> & Fp2Utils = {
234
242
  // Finite extension field over irreducible polynominal.
235
243
  // Fp(u) / (u² - β) where β = -1
236
244
  const FP2_FROBENIUS_COEFFICIENTS = [
237
- 0x1n,
238
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
245
+ BigInt('0x1'),
246
+ BigInt(
247
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
248
+ ),
239
249
  ].map((item) => Fp.create(item));
240
250
 
241
251
  // For Fp2 roots of unity.
242
- const rv1 =
243
- 0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n;
252
+ const rv1 = BigInt(
253
+ '0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
254
+ );
244
255
  // const ev1 =
245
- // 0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90n;
256
+ // BigInt('0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90');
246
257
  // const ev2 =
247
- // 0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5n;
258
+ // BigInt('0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5');
248
259
  // const ev3 =
249
- // 0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17n;
260
+ // BigInt('0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17');
250
261
  // const ev4 =
251
- // 0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1n;
262
+ // BigInt('0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1');
252
263
 
253
264
  // Eighth roots of unity, used for computing square roots in Fp2.
254
265
  // To verify or re-calculate:
255
266
  // Array(8).fill(new Fp2([1n, 1n])).map((fp2, k) => fp2.pow(Fp2.ORDER * BigInt(k) / 8n))
256
267
  const FP2_ROOTS_OF_UNITY = [
257
- [1n, 0n],
268
+ [_1n, _0n],
258
269
  [rv1, -rv1],
259
- [0n, 1n],
270
+ [_0n, _1n],
260
271
  [rv1, rv1],
261
- [-1n, 0n],
272
+ [-_1n, _0n],
262
273
  [-rv1, rv1],
263
- [0n, -1n],
274
+ [_0n, -_1n],
264
275
  [-rv1, -rv1],
265
276
  ].map((pair) => Fp2.fromBigTuple(pair));
266
277
  // eta values, used for computing sqrt(g(X1(t)))
@@ -314,8 +325,8 @@ const Fp6Multiply = ({ c0, c1, c2 }: Fp6, rhs: Fp6 | bigint) => {
314
325
  };
315
326
  const Fp6Square = ({ c0, c1, c2 }: Fp6) => {
316
327
  let t0 = Fp2.sqr(c0); // c0²
317
- let t1 = Fp2.mul(Fp2.mul(c0, c1), 2n); // 2 * c0 * c1
318
- let t3 = Fp2.mul(Fp2.mul(c1, c2), 2n); // 2 * c1 * c2
328
+ let t1 = Fp2.mul(Fp2.mul(c0, c1), _2n); // 2 * c0 * c1
329
+ let t3 = Fp2.mul(Fp2.mul(c1, c2), _2n); // 2 * c1 * c2
319
330
  let t4 = Fp2.sqr(c2); // c2²
320
331
  return {
321
332
  c0: Fp2.add(Fp2.mulByNonresidue(t3), t0), // T3 * (u + 1) + T0
@@ -440,46 +451,64 @@ const Fp6: mod.IField<Fp6> & Fp6Utils = {
440
451
  };
441
452
 
442
453
  const FP6_FROBENIUS_COEFFICIENTS_1 = [
443
- [0x1n, 0x0n],
454
+ [BigInt('0x1'), BigInt('0x0')],
444
455
  [
445
- 0x0n,
446
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
456
+ BigInt('0x0'),
457
+ BigInt(
458
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
459
+ ),
447
460
  ],
448
461
  [
449
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
450
- 0x0n,
462
+ BigInt(
463
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
464
+ ),
465
+ BigInt('0x0'),
451
466
  ],
452
- [0x0n, 0x1n],
467
+ [BigInt('0x0'), BigInt('0x1')],
453
468
  [
454
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
455
- 0x0n,
469
+ BigInt(
470
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
471
+ ),
472
+ BigInt('0x0'),
456
473
  ],
457
474
  [
458
- 0x0n,
459
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
475
+ BigInt('0x0'),
476
+ BigInt(
477
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
478
+ ),
460
479
  ],
461
480
  ].map((pair) => Fp2.fromBigTuple(pair));
462
481
  const FP6_FROBENIUS_COEFFICIENTS_2 = [
463
- [0x1n, 0x0n],
482
+ [BigInt('0x1'), BigInt('0x0')],
464
483
  [
465
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaadn,
466
- 0x0n,
484
+ BigInt(
485
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'
486
+ ),
487
+ BigInt('0x0'),
467
488
  ],
468
489
  [
469
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
470
- 0x0n,
490
+ BigInt(
491
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
492
+ ),
493
+ BigInt('0x0'),
471
494
  ],
472
495
  [
473
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
474
- 0x0n,
496
+ BigInt(
497
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
498
+ ),
499
+ BigInt('0x0'),
475
500
  ],
476
501
  [
477
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
478
- 0x0n,
502
+ BigInt(
503
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
504
+ ),
505
+ BigInt('0x0'),
479
506
  ],
480
507
  [
481
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffffn,
482
- 0x0n,
508
+ BigInt(
509
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'
510
+ ),
511
+ BigInt('0x0'),
483
512
  ],
484
513
  ].map((pair) => Fp2.fromBigTuple(pair));
485
514
 
@@ -488,7 +517,7 @@ const FP6_FROBENIUS_COEFFICIENTS_2 = [
488
517
  // Fp₆(w) / (w² - γ) where γ = v
489
518
  type Fp12 = { c0: Fp6; c1: Fp6 };
490
519
  // The BLS parameter x for BLS12-381
491
- const BLS_X = 0xd201000000010000n;
520
+ const BLS_X = BigInt('0xd201000000010000');
492
521
  const BLS_X_LEN = bitLen(BLS_X);
493
522
 
494
523
  // prettier-ignore
@@ -646,14 +675,14 @@ const Fp12: mod.IField<Fp12> & Fp12Utils = {
646
675
  let t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
647
676
  return {
648
677
  c0: Fp6.create({
649
- c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), 2n), t3), // 2 * (T3 - c0c0) + T3
650
- c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), 2n), t5), // 2 * (T5 - c0c1) + T5
651
- c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), 2n), t7),
678
+ c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3), // 2 * (T3 - c0c0) + T3
679
+ c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), _2n), t5), // 2 * (T5 - c0c1) + T5
680
+ c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), _2n), t7),
652
681
  }), // 2 * (T7 - c0c2) + T7
653
682
  c1: Fp6.create({
654
- c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), 2n), t9), // 2 * (T9 + c1c0) + T9
655
- c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), 2n), t4), // 2 * (T4 + c1c1) + T4
656
- c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), 2n), t6),
683
+ c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), _2n), t9), // 2 * (T9 + c1c0) + T9
684
+ c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), _2n), t4), // 2 * (T4 + c1c1) + T4
685
+ c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), _2n), t6),
657
686
  }),
658
687
  }; // 2 * (T6 + c1c2) + T6
659
688
  },
@@ -688,50 +717,84 @@ const Fp12: mod.IField<Fp12> & Fp12Utils = {
688
717
  },
689
718
  };
690
719
  const FP12_FROBENIUS_COEFFICIENTS = [
691
- [0x1n, 0x0n],
720
+ [BigInt('0x1'), BigInt('0x0')],
692
721
  [
693
- 0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8n,
694
- 0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3n,
722
+ BigInt(
723
+ '0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'
724
+ ),
725
+ BigInt(
726
+ '0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'
727
+ ),
695
728
  ],
696
729
  [
697
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffffn,
698
- 0x0n,
730
+ BigInt(
731
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff'
732
+ ),
733
+ BigInt('0x0'),
699
734
  ],
700
735
  [
701
- 0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2n,
702
- 0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
736
+ BigInt(
737
+ '0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'
738
+ ),
739
+ BigInt(
740
+ '0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
741
+ ),
703
742
  ],
704
743
  [
705
- 0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
706
- 0x0n,
744
+ BigInt(
745
+ '0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
746
+ ),
747
+ BigInt('0x0'),
707
748
  ],
708
749
  [
709
- 0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995n,
710
- 0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116n,
750
+ BigInt(
751
+ '0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'
752
+ ),
753
+ BigInt(
754
+ '0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'
755
+ ),
711
756
  ],
712
757
  [
713
- 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
714
- 0x0n,
758
+ BigInt(
759
+ '0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa'
760
+ ),
761
+ BigInt('0x0'),
715
762
  ],
716
763
  [
717
- 0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3n,
718
- 0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8n,
764
+ BigInt(
765
+ '0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3'
766
+ ),
767
+ BigInt(
768
+ '0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8'
769
+ ),
719
770
  ],
720
771
  [
721
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
722
- 0x0n,
772
+ BigInt(
773
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
774
+ ),
775
+ BigInt('0x0'),
723
776
  ],
724
777
  [
725
- 0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
726
- 0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2n,
778
+ BigInt(
779
+ '0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09'
780
+ ),
781
+ BigInt(
782
+ '0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2'
783
+ ),
727
784
  ],
728
785
  [
729
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaadn,
730
- 0x0n,
786
+ BigInt(
787
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad'
788
+ ),
789
+ BigInt('0x0'),
731
790
  ],
732
791
  [
733
- 0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116n,
734
- 0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995n,
792
+ BigInt(
793
+ '0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116'
794
+ ),
795
+ BigInt(
796
+ '0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995'
797
+ ),
735
798
  ],
736
799
  ].map((n) => Fp2.fromBigTuple(n));
737
800
  // END OF CURVE FIELDS
@@ -887,17 +950,21 @@ const isogenyMapG1 = isogenyMap(
887
950
 
888
951
  // SWU Map - Fp2 to G2': y² = x³ + 240i * x + 1012 + 1012i
889
952
  const G2_SWU = mapToCurveSimpleSWU(Fp2, {
890
- A: Fp2.create({ c0: Fp.create(0n), c1: Fp.create(240n) }), // A' = 240 * I
953
+ A: Fp2.create({ c0: Fp.create(_0n), c1: Fp.create(240n) }), // A' = 240 * I
891
954
  B: Fp2.create({ c0: Fp.create(1012n), c1: Fp.create(1012n) }), // B' = 1012 * (1 + I)
892
955
  Z: Fp2.create({ c0: Fp.create(-2n), c1: Fp.create(-1n) }), // Z: -(2 + I)
893
956
  });
894
957
  // Optimized SWU Map - Fp to G1
895
958
  const G1_SWU = mapToCurveSimpleSWU(Fp, {
896
959
  A: Fp.create(
897
- 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1dn
960
+ BigInt(
961
+ '0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d'
962
+ )
898
963
  ),
899
964
  B: Fp.create(
900
- 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0n
965
+ BigInt(
966
+ '0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0'
967
+ )
901
968
  ),
902
969
  Z: Fp.create(11n),
903
970
  });
@@ -922,8 +989,9 @@ function G2psi(c: ProjConstructor<Fp2>, P: ProjPointType<Fp2>) {
922
989
  }
923
990
  // Ψ²(P) endomorphism
924
991
  // 1 / F2(2)^((p-1)/3) in GF(p²)
925
- const PSI2_C1 =
926
- 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn;
992
+ const PSI2_C1 = BigInt(
993
+ '0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac'
994
+ );
927
995
 
928
996
  function psi2(x: Fp2, y: Fp2): [Fp2, Fp2] {
929
997
  return [Fp2.mul(x, PSI2_C1), Fp2.neg(y)];
@@ -1000,14 +1068,18 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1000
1068
  G1: {
1001
1069
  Fp,
1002
1070
  // cofactor; (z - 1)²/3
1003
- h: 0x396c8c005555e1568c00aaab0000aaabn,
1071
+ h: BigInt('0x396c8c005555e1568c00aaab0000aaab'),
1004
1072
  // generator's coordinates
1005
1073
  // x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
1006
1074
  // y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
1007
- Gx: 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bbn,
1008
- Gy: 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1n,
1075
+ Gx: BigInt(
1076
+ '0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb'
1077
+ ),
1078
+ Gy: BigInt(
1079
+ '0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1'
1080
+ ),
1009
1081
  a: Fp.ZERO,
1010
- b: 4n,
1082
+ b: _4n,
1011
1083
  htfDefaults: { ...htfDefaults, m: 1 },
1012
1084
  wrapPrivateKey: true,
1013
1085
  allowInfinityPoint: true,
@@ -1017,8 +1089,9 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1017
1089
  // https://eprint.iacr.org/2021/1130.pdf
1018
1090
  isTorsionFree: (c, point): boolean => {
1019
1091
  // φ endomorphism
1020
- const cubicRootOfUnityModP =
1021
- 0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen;
1092
+ const cubicRootOfUnityModP = BigInt(
1093
+ '0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe'
1094
+ );
1022
1095
  const phi = new c(Fp.mul(point.px, cubicRootOfUnityModP), point.py, point.pz);
1023
1096
 
1024
1097
  // todo: unroll
@@ -1028,7 +1101,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1028
1101
 
1029
1102
  // https://eprint.iacr.org/2019/814.pdf
1030
1103
  // (z² − 1)/3
1031
- // const c1 = 0x396c8c005555e1560000000055555555n;
1104
+ // const c1 = BigInt('0x396c8c005555e1560000000055555555');
1032
1105
  // const P = this;
1033
1106
  // const S = P.sigma();
1034
1107
  // const Q = S.double();
@@ -1054,13 +1127,13 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1054
1127
  const compressedValue = bytesToNumberBE(bytes);
1055
1128
  const bflag = bitGet(compressedValue, I_BIT_POS);
1056
1129
  // Zero
1057
- if (bflag === 1n) return { x: 0n, y: 0n };
1130
+ if (bflag === _1n) return { x: _0n, y: _0n };
1058
1131
  const x = Fp.create(compressedValue & Fp.MASK);
1059
- const right = Fp.add(Fp.pow(x, 3n), Fp.create(bls12_381.CURVE.G1.b)); // y² = x³ + b
1132
+ const right = Fp.add(Fp.pow(x, _3n), Fp.create(bls12_381.CURVE.G1.b)); // y² = x³ + b
1060
1133
  let y = Fp.sqrt(right);
1061
1134
  if (!y) throw new Error('Invalid compressed G1 point');
1062
1135
  const aflag = bitGet(compressedValue, C_BIT_POS);
1063
- if ((y * 2n) / P !== aflag) y = Fp.neg(y);
1136
+ if ((y * _2n) / P !== aflag) y = Fp.neg(y);
1064
1137
  return { x: Fp.create(x), y: Fp.create(y) };
1065
1138
  } else if (bytes.length === 96) {
1066
1139
  // Check if the infinity flag is set
@@ -1079,7 +1152,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1079
1152
  if (isZero) return COMPRESSED_ZERO.slice();
1080
1153
  const P = Fp.ORDER;
1081
1154
  let num;
1082
- num = bitSet(x, C_BIT_POS, Boolean((y * 2n) / P)); // set aflag
1155
+ num = bitSet(x, C_BIT_POS, Boolean((y * _2n) / P)); // set aflag
1083
1156
  num = bitSet(num, S_BIT_POS, true);
1084
1157
  return numberToBytesBE(num, Fp.BYTES);
1085
1158
  } else {
@@ -1100,21 +1173,33 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1100
1173
  G2: {
1101
1174
  Fp: Fp2,
1102
1175
  // cofactor
1103
- h: 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5n,
1176
+ h: BigInt(
1177
+ '0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5'
1178
+ ),
1104
1179
  Gx: Fp2.fromBigTuple([
1105
- 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8n,
1106
- 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7en,
1180
+ BigInt(
1181
+ '0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8'
1182
+ ),
1183
+ BigInt(
1184
+ '0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e'
1185
+ ),
1107
1186
  ]),
1108
1187
  // y =
1109
1188
  // 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582,
1110
1189
  // 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
1111
1190
  Gy: Fp2.fromBigTuple([
1112
- 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801n,
1113
- 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79ben,
1191
+ BigInt(
1192
+ '0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801'
1193
+ ),
1194
+ BigInt(
1195
+ '0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be'
1196
+ ),
1114
1197
  ]),
1115
1198
  a: Fp2.ZERO,
1116
- b: Fp2.fromBigTuple([4n, 4n]),
1117
- hEff: 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551n,
1199
+ b: Fp2.fromBigTuple([4n, _4n]),
1200
+ hEff: BigInt(
1201
+ '0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551'
1202
+ ),
1118
1203
  htfDefaults: { ...htfDefaults },
1119
1204
  wrapPrivateKey: true,
1120
1205
  allowInfinityPoint: true,
@@ -1175,9 +1260,9 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1175
1260
  const x_1 = slc(bytes, 0, L);
1176
1261
  const x_0 = slc(bytes, L, 2 * L);
1177
1262
  const x = Fp2.create({ c0: Fp.create(x_0), c1: Fp.create(x_1) });
1178
- const right = Fp2.add(Fp2.pow(x, 3n), b); // y² = x³ + 4 * (u+1) = x³ + b
1263
+ const right = Fp2.add(Fp2.pow(x, _3n), b); // y² = x³ + 4 * (u+1) = x³ + b
1179
1264
  let y = Fp2.sqrt(right);
1180
- const Y_bit = y.c1 === 0n ? (y.c0 * 2n) / P : (y.c1 * 2n) / P ? 1n : 0n;
1265
+ const Y_bit = y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P ? _1n : _0n;
1181
1266
  y = bitS > 0 && Y_bit > 0 ? y : Fp2.neg(y);
1182
1267
  return { x, y };
1183
1268
  } else if (bytes.length === 192 && !bitC) {
@@ -1200,7 +1285,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1200
1285
  if (isCompressed) {
1201
1286
  const P = Fp.ORDER;
1202
1287
  if (isZero) return concatB(COMPRESSED_ZERO, numberToBytesBE(0n, Fp.BYTES));
1203
- const flag = Boolean(y.c1 === 0n ? (y.c0 * 2n) / P : (y.c1 * 2n) / P);
1288
+ const flag = Boolean(y.c1 === _0n ? (y.c0 * _2n) / P : (y.c1 * _2n) / P);
1204
1289
  // set compressed & sign bits (looks like different offsets than for G1/Fp?)
1205
1290
  let x_1 = bitSet(x.c1, C_BIT_POS, flag);
1206
1291
  x_1 = bitSet(x_1, S_BIT_POS, true);
@@ -1229,12 +1314,12 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1229
1314
  const z2 = bytesToNumberBE(hex.slice(half));
1230
1315
  // Indicates the infinity point
1231
1316
  const bflag1 = bitGet(z1, I_BIT_POS);
1232
- if (bflag1 === 1n) return bls12_381.G2.ProjectivePoint.ZERO;
1317
+ if (bflag1 === _1n) return bls12_381.G2.ProjectivePoint.ZERO;
1233
1318
 
1234
1319
  const x1 = Fp.create(z1 & Fp.MASK);
1235
1320
  const x2 = Fp.create(z2);
1236
1321
  const x = Fp2.create({ c0: x2, c1: x1 });
1237
- const y2 = Fp2.add(Fp2.pow(x, 3n), bls12_381.CURVE.G2.b); // y² = x³ + 4
1322
+ const y2 = Fp2.add(Fp2.pow(x, _3n), bls12_381.CURVE.G2.b); // y² = x³ + 4
1238
1323
  // The slow part
1239
1324
  let y = Fp2.sqrt(y2);
1240
1325
  if (!y) throw new Error('Failed to find a square root');
@@ -1243,8 +1328,8 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1243
1328
  // If y1 happens to be zero, then use the bit of y0
1244
1329
  const { re: y0, im: y1 } = Fp2.reim(y);
1245
1330
  const aflag1 = bitGet(z1, 381);
1246
- const isGreater = y1 > 0n && (y1 * 2n) / P !== aflag1;
1247
- const isZero = y1 === 0n && (y0 * 2n) / P !== aflag1;
1331
+ const isGreater = y1 > _0n && (y1 * _2n) / P !== aflag1;
1332
+ const isZero = y1 === _0n && (y0 * _2n) / P !== aflag1;
1248
1333
  if (isGreater || isZero) y = Fp2.neg(y);
1249
1334
  const point = bls12_381.G2.ProjectivePoint.fromAffine({ x, y });
1250
1335
  point.assertValidity();
@@ -1258,8 +1343,8 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1258
1343
  const a = point.toAffine();
1259
1344
  const { re: x0, im: x1 } = Fp2.reim(a.x);
1260
1345
  const { re: y0, im: y1 } = Fp2.reim(a.y);
1261
- const tmp = y1 > 0n ? y1 * 2n : y0 * 2n;
1262
- const aflag1 = Boolean((tmp / Fp.ORDER) & 1n);
1346
+ const tmp = y1 > _0n ? y1 * _2n : y0 * _2n;
1347
+ const aflag1 = Boolean((tmp / Fp.ORDER) & _1n);
1263
1348
  const z1 = bitSet(bitSet(x1, 381, aflag1), S_BIT_POS, true);
1264
1349
  const z2 = x0;
1265
1350
  return concatB(numberToBytesBE(z1, Fp.BYTES), numberToBytesBE(z2, Fp.BYTES));