secp256k1Modinv64UpdateFg62 static method

void secp256k1Modinv64UpdateFg62(
  1. Secp256k1ModinvSigned f,
  2. Secp256k1ModinvSigned g,
  3. Secp256k1ModinvTrans t
)

Implementation

static void secp256k1Modinv64UpdateFg62(Secp256k1ModinvSigned f,
    Secp256k1ModinvSigned g, Secp256k1ModinvTrans t) {
  final BigInt m62 = Secp256k1Const.mask62;

  final BigInt f0 = f[0], f1 = f[1], f2 = f[2], f3 = f[3], f4 = f[4];
  final BigInt g0 = g[0], g1 = g[1], g2 = g[2], g3 = g[3], g4 = g[4];
  final BigInt u = t.u, v = t.v, q = t.q, r = t.r;
  Secp256k1Int128 cf = Secp256k1Int128(), cg = Secp256k1Int128();

  /// Start computing t*[f,g].
  secp256k1I128Mul(cf, u, f0);
  secp256k1I128AccumMul(cf, v, g0);
  secp256k1I128Mul(cg, q, f0);
  secp256k1I128AccumMul(cg, r, g0);
  // /// Verify that the bottom 62 bits of the result are zero, and then throw them away.
  _cond((secp256k1I128ToU64(cf) & m62) == BigInt.zero,
      "secp256k1Modinv64UpdateFg62");
  secp256k1I128Rshift(cf, 62);
  _cond((secp256k1I128ToU64(cg) & m62) == BigInt.zero,
      "secp256k1Modinv64UpdateFg62");
  secp256k1I128Rshift(cg, 62);
  // /// Compute limb 1 of t*[f,g], and store it as output limb 0 (= down shift).
  secp256k1I128AccumMul(cf, u, f1);
  secp256k1I128AccumMul(cf, v, g1);
  secp256k1I128AccumMul(cg, q, f1);
  secp256k1I128AccumMul(cg, r, g1);
  f[0] = secp256k1I128ToU64(cf) & m62;
  secp256k1I128Rshift(cf, 62);
  g[0] = secp256k1I128ToU64(cg) & m62;
  secp256k1I128Rshift(cg, 62);

  /// Compute limb 2 of t*[f,g], and store it as output limb 1.
  secp256k1I128AccumMul(cf, u, f2);
  secp256k1I128AccumMul(cf, v, g2);
  secp256k1I128AccumMul(cg, q, f2);
  secp256k1I128AccumMul(cg, r, g2);
  f[1] = secp256k1I128ToU64(cf) & m62;
  secp256k1I128Rshift(cf, 62);
  g[1] = secp256k1I128ToU64(cg) & m62;
  secp256k1I128Rshift(cg, 62);

  /// Compute limb 3 of t*[f,g], and store it as output limb 2.
  secp256k1I128AccumMul(cf, u, f3);
  secp256k1I128AccumMul(cf, v, g3);
  secp256k1I128AccumMul(cg, q, f3);
  secp256k1I128AccumMul(cg, r, g3);
  f[2] = secp256k1I128ToU64(cf) & m62;
  secp256k1I128Rshift(cf, 62);
  g[2] = secp256k1I128ToU64(cg) & m62;
  secp256k1I128Rshift(cg, 62);

  /// Compute limb 4 of t*[f,g], and store it as output limb 3.
  secp256k1I128AccumMul(cf, u, f4);
  secp256k1I128AccumMul(cf, v, g4);
  secp256k1I128AccumMul(cg, q, f4);
  secp256k1I128AccumMul(cg, r, g4);
  f[3] = secp256k1I128ToU64(cf) & m62;
  secp256k1I128Rshift(cf, 62);
  g[3] = secp256k1I128ToU64(cg) & m62;
  secp256k1I128Rshift(cg, 62);

  /// What remains is limb 5 of t*[f,g]; store it as output limb 4.
  f[4] = secp256k1I128ToI64(cf);
  g[4] = secp256k1I128ToI64(cg);
}