verifySchnorr method
Verifies a Schnorr-based signature against a given message, considering optional Taproot scripts.
Implementation
bool verifySchnorr(List<int> message, List<int> signature,
{List<dynamic>? tapleafScripts, required bool isTweak}) {
if (message.length != 32) {
throw const ArgumentException("The message must be a 32-byte array.");
}
if (signature.length != 64 && signature.length != 65) {
throw const ArgumentException(
"The signature must be a 64-byte array or 65-bytes with sighash");
}
final P = isTweak
? P2TRUtils.tweakPublicKey(verifyKey.publicKey.point,
script: tapleafScripts)
: P2TRUtils.liftX(verifyKey.publicKey.point);
final r = BigintUtils.fromBytes(signature.sublist(0, 32));
final s = BigintUtils.fromBytes(signature.sublist(32, 64));
final ProjectiveECCPoint generator = verifyKey.publicKey.generator;
final BigInt prime = BitcoinSignerUtils._generator.curve.p;
if (r >= prime || s >= BitcoinSignerUtils._order) {
return false;
}
final eHash = P2TRUtils.taggedHash(
"BIP0340/challenge",
List<int>.from([
...signature.sublist(0, 32),
...BigintUtils.toBytes(P.x, length: BitcoinSignerUtils.baselen),
...message
]),
);
BigInt e = BigintUtils.fromBytes(eHash) % BitcoinSignerUtils._order;
final sp = generator * s;
if (P.y.isEven) {
e = BitcoinSignerUtils._order - e;
}
ProjectiveECCPoint eP = P * e;
final R = sp + eP;
if (R.y.isOdd || R.x != r) {
return false;
}
return true;
}