secp256k1ScalarMul512 static method

void secp256k1ScalarMul512(
  1. List<BigInt> l8,
  2. Secp256k1Scalar a,
  3. Secp256k1Scalar b
)

Implementation

static void secp256k1ScalarMul512(
    List<BigInt> l8, Secp256k1Scalar a, Secp256k1Scalar b) {
  /// 160 bit accumulator.
  BigInt c0 = BigInt.zero, c1 = BigInt.zero;
  int c2 = 0;

  BigInt extractFast() {
    final n = c0;
    c0 = c1;
    c1 = BigInt.zero;
    _cond(c2 == 0, "secp256k1ScalarMul512");
    return n;
  }

  void muladd(BigInt a, BigInt b) {
    BigInt tl, th = BigInt.zero;
    Secp256k1Uint128 t = Secp256k1Uint128();
    secp256k1U128Mul(t, a, b);
    th = secp256k1U128HiU64(t);
    tl = secp256k1U128ToU64(t);
    c0 = (c0 + tl).toUnsigned64;
    th = (th + (c0 < tl).toBigInt).toUnsigned64;
    c1 = (c1 + th).toUnsigned64;
    c2 += (c1 < th).toInt;

    _cond((c1 >= th) || (c2 != 0), "secp256k1ScalarMul512");
  }

  void muladdFast(BigInt a, BigInt b) {
    BigInt tl, th = BigInt.zero;
    Secp256k1Uint128 t = Secp256k1Uint128();
    secp256k1U128Mul(t, a, b);
    th = secp256k1U128HiU64(t);
    tl = secp256k1U128ToU64(t);
    c0 = (c0 + tl).toUnsigned64;
    th = (th + (c0 < tl).toBigInt).toUnsigned64;
    c1 = (c1 + th).toUnsigned64;
  }

  BigInt extract() {
    final n = c0;
    c0 = c1;
    c1 = c2.toBigInt;
    c2 = 0;
    return n;
  }

  muladdFast(a[0], b[0]);
  l8[0] = extractFast();
  muladd(a[0], b[1]);
  muladd(a[1], b[0]);
  l8[1] = extract();
  muladd(a[0], b[2]);
  muladd(a[1], b[1]);
  muladd(a[2], b[0]);
  l8[2] = extract();
  muladd(a[0], b[3]);
  muladd(a[1], b[2]);
  muladd(a[2], b[1]);
  muladd(a[3], b[0]);
  l8[3] = extract();
  muladd(a[1], b[3]);
  muladd(a[2], b[2]);
  muladd(a[3], b[1]);
  l8[4] = extract();
  muladd(a[2], b[3]);
  muladd(a[3], b[2]);
  l8[5] = extract();
  muladdFast(a[3], b[3]);
  l8[6] = extractFast();
  _cond(c1 == BigInt.zero, "secp256k1ScalarMul512");
  l8[7] = c0;
}