partialSigVerify static method
Verifies a MuSig2 partial signature
Implementation
static bool partialSigVerify(
{required List<int> signature,
required List<int> pubnonce,
required List<int> pk,
required MuSig2Session session}) {
if (pubnonce.length != MuSig2Const.pubnonceLength) {
throw MuSig2Exception("Invalid public nonce length.", details: {
"expected": MuSig2Const.pubnonceLength,
"length": pubnonce.length
});
}
final values = MuSig2Utils.decodeSession(session);
final sBig = BigintUtils.fromBytes(signature);
if (sBig >= MuSig2Const.order) return false;
final rS1 = MuSig2Utils.encodePointAsEven(
pubnonce.sublist(0, EcdsaKeysConst.pubKeyCompressedByteLen));
final rS2 = MuSig2Utils.encodePointAsEven(pubnonce.sublist(
EcdsaKeysConst.pubKeyCompressedByteLen,
EcdsaKeysConst.pubKeyCompressedByteLen * 2));
ProjectiveECCPoint reS =
(rS1 + (rS2 * values.b)).cast<ProjectiveECCPoint>();
if (values.r.isOdd) {
reS = -reS;
}
final p = MuSig2Utils.encodePoint(pk);
final a = MuSig2Utils.getSessionKeyAggCoeff(session: session, pk: p);
BigInt g = BigInt.one;
if (values.publicKey.isOdd) {
g = MuSig2Const.order - BigInt.one;
}
g = g * values.gacc % MuSig2Const.order;
final expected = MuSig2Const.generator * sBig;
final r = (reS + (p * (values.e * a * g % MuSig2Const.order)))
.cast<ProjectiveECCPoint>();
return expected == r;
}