verifyMessageSignature method

bool verifyMessageSignature({
  1. required List<int> message,
  2. required List<int> signature,
  3. String messagePrefix = BitcoinSignerUtils.signMessagePrefix,
})

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