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 CryptoSignException("The message must be a 32-byte array.");
}
if (signature.length != 64 && signature.length != 65) {
throw const CryptoSignException(
"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;
}