verifySchnorrSignature static method
Implementation
static bool verifySchnorrSignature(
{required List<int> xOnly,
required List<int> message,
required List<int> signature,
List<int>? tweak}) {
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 x = BigintUtils.fromBytes(xOnly);
final P =
tweak != null ? tweakKey(xBig: x, tweak: tweak) : P2TRUtils.liftX(x);
final r = BigintUtils.fromBytes(signature.sublist(0, 32));
final s = BigintUtils.fromBytes(signature.sublist(32, 64));
final ProjectiveECCPoint generator = BitcoinSignerUtils._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;
}
final ProjectiveECCPoint eP = P * e;
final R = sp + eP;
if (R.y.isOdd || R.x != r) {
return false;
}
return true;
}