partialSigVerify static method

bool partialSigVerify({
  1. required List<int> signature,
  2. required List<int> pubnonce,
  3. required List<int> pk,
  4. required MuSig2Session session,
})

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;
}