verifyMessageSignature method
Verifies a Bitcoin-signed message signature.
This method checks if a given ECDSA signature is valid for the provided message. It supports both 64-byte and 65-byte signatures, where the latter includes a recovery ID for public key reconstruction.
message
: The original message that was signed.signature
: The ECDSA signature (64 or 65 bytes).messagePrefix
(optional): A custom prefix for the signed message (default is Bitcoin's standard prefix).
Implementation
bool verifyMessageSignature(
{required List<int> message,
required List<int> signature,
String messagePrefix = BitcoinSignerUtils.signMessagePrefix}) {
if (signature.length != 64 && signature.length != 65) {
throw const CryptoSignException(
"bitcoin signature must be 64 bytes without recover-id or 65 bytes with recover-id");
}
final List<int> messgaeHash = QuickCrypto.sha256Hash(
BitcoinSignerUtils.magicMessage(message, messagePrefix));
int? header;
if (signature.length == 65) {
header = signature[0] & 0xFF;
signature = signature.sublist(1);
}
final ecdsaSignature =
ECDSASignature.fromBytes(signature, BitcoinSignerUtils.generator);
if (header == null) {
return _verifyKey.verify(ecdsaSignature, messgaeHash);
}
if (header < 27 || header > 42) {
throw CryptoSignException("Header byte out of range");
}
if (header >= 39) {
header -= 12;
} else if (header >= 35) {
header -= 8;
} else if (header >= 31) {
header -= 4;
}
header -= 27;
if (header > 1) {
header -= 2;
}
final pubKey = ecdsaSignature.recoverPublicKey(
messgaeHash, _verifyKey.publicKey.generator, header);
return pubKey == _verifyKey.publicKey;
}