secp256k1ECmultConst static method
Implementation
static void secp256k1ECmultConst(
Secp256k1Gej r, Secp256k1Ge a, Secp256k1Scalar q) {
/// The offset to add to s1 and s2 to make them non-negative. Equal to 2^128.
Secp256k1Scalar s = Secp256k1Scalar(),
v1 = Secp256k1Scalar(),
v2 = Secp256k1Scalar();
List<Secp256k1Ge> preA =
List.generate(Secp256k1Const.constTableSize, (_) => Secp256k1Ge());
List<Secp256k1Ge> preALam =
List.generate(Secp256k1Const.constTableSize, (_) => Secp256k1Ge());
Secp256k1Fe globalZ = Secp256k1Fe();
int group, i;
if (secp256k1GeIsInfinity(a).toBool) {
secp256k1GejSetInfinity(r);
return;
}
/// Compute v1 and v2.
secp256k1ScalarAdd(s, q, Secp256k1Const.secp256k1ECmultConstK);
secp256k1ScalarHalf(s, s);
secp256k1ScalarSplitLambda(v1, v2, s);
secp256k1ScalarAdd(v1, v1, Secp256k1Const.sOffset);
secp256k1ScalarAdd(v2, v2, Secp256k1Const.sOffset);
/// verify
for (i = 129; i < 256; ++i) {
_cond(
secp256k1ScalarGetBitsLimb32(v1, i, 1) == 0, "secp256k1ECmultConst");
_cond(
secp256k1ScalarGetBitsLimb32(v2, i, 1) == 0, "secp256k1ECmultConst");
}
secp256k1GejSetGe(r, a);
secp256k1ECmultConstOddMultiplesTableGlobalz(preA, globalZ, r);
for (i = 0; i < Secp256k1Const.constTableSize; i++) {
secp256k1GeMulLambda(preALam[i], preA[i]);
}
for (group = Secp256k1Const.constGroup - 1; group >= 0; --group) {
/// Using the _var get_bits function is ok here, since it's only variable in offset and count, not in the scalar.
int bits1 = secp256k1ScalarGetBitsVar(v1,
group * Secp256k1Const.constGroupSize, Secp256k1Const.constGroupSize);
int bits2 = secp256k1ScalarGetBitsVar(v2,
group * Secp256k1Const.constGroupSize, Secp256k1Const.constGroupSize);
Secp256k1Ge t = Secp256k1Ge();
int j;
//
ecmultConstTableGetGe(t, preA, bits1);
if (group == Secp256k1Const.constGroup - 1) {
/// Directly set r in the first iteration.
secp256k1GejSetGe(r, t);
} else {
/// Shift the result so far up.
for (j = 0; j < Secp256k1Const.constGroupSize; ++j) {
secp256k1GejDouble(r, r);
}
secp256k1GejAddGe(r, r, t);
}
ecmultConstTableGetGe(t, preALam, bits2);
secp256k1GejAddGe(r, r, t);
}
/// Map the result back to the secp256k1 curve from the isomorphic curve.
secp256k1FeMul(r.z, r.z, globalZ);
}