secp256k1Modinv64UpdateFg62Var static method

void secp256k1Modinv64UpdateFg62Var(
  1. int len,
  2. Secp256k1ModinvSigned f,
  3. Secp256k1ModinvSigned g,
  4. Secp256k1ModinvTrans t,
)

Implementation

static void secp256k1Modinv64UpdateFg62Var(int len, Secp256k1ModinvSigned f,
    Secp256k1ModinvSigned g, Secp256k1ModinvTrans t) {
  final BigInt m62 = Secp256k1Const.mask62;
  final BigInt u = t.u, v = t.v, q = t.q, r = t.r;
  BigInt fi, gi;
  Secp256k1Int128 cf = Secp256k1Int128(), cg = Secp256k1Int128();
  int i;
  _cond(len > 0, "secp256k1Modinv64UpdateFg62Var");

  /// Start computing t*[f,g].
  fi = f[0];
  gi = g[0];
  secp256k1I128Mul(cf, u, fi);
  secp256k1I128AccumMul(cf, v, gi);
  secp256k1I128Mul(cg, q, fi);
  secp256k1I128AccumMul(cg, r, gi);

  ///  Verify that the bottom 62 bits of the result are zero, and then throw them away.
  _cond((secp256k1I128ToU64(cf) & m62) == BigInt.zero,
      "secp256k1Modinv64UpdateFg62Var");
  secp256k1I128Rshift(cf, 62);
  _cond((secp256k1I128ToU64(cg) & m62) == BigInt.zero,
      "secp256k1Modinv64UpdateFg62Var");
  secp256k1I128Rshift(cg, 62);

  for (i = 1; i < len; ++i) {
    fi = f[i];
    gi = g[i];
    secp256k1I128AccumMul(cf, u, fi);
    secp256k1I128AccumMul(cf, v, gi);
    secp256k1I128AccumMul(cg, q, fi);
    secp256k1I128AccumMul(cg, r, gi);
    f[i - 1] = secp256k1I128ToU64(cf) & m62;
    secp256k1I128Rshift(cf, 62);
    g[i - 1] = secp256k1I128ToU64(cg) & m62;
    secp256k1I128Rshift(cg, 62);
  }

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