signMessage method

List<int> signMessage({
  1. required List<int> message,
  2. bool hashMessage = true,
  3. String messagePrefix = BitcoinSignerUtils.signMessagePrefix,
  4. List<int> extraEntropy = const [],
})

Signs a message using Bitcoin's message signing format.

This method produces a compact ECDSA signature for a given message, following the Bitcoin Signed Message standard.

  • message: The raw message to be signed.
  • messagePrefix: The prefix used for Bitcoin's message signing.
  • extraEntropy: Optional extra entropy to modify the signature.

Implementation

List<int> signMessage({
  required List<int> message,
  bool hashMessage = true,
  String messagePrefix = BitcoinSignerUtils.signMessagePrefix,
  List<int> extraEntropy = const [],
}) {
  List<int> messgaeHash = message;
  if (hashMessage) {
    messgaeHash = QuickCrypto.sha256Hash(
        BitcoinSignerUtils.magicMessage(message, messagePrefix));
  }
  if (messgaeHash.length != BitcoinSignerUtils.baselen) {
    throw CryptoSignException(
        "The message must be a ${BitcoinSignerUtils.baselen}-byte array.");
  }

  final ECDSASignature ecdsaSign = _signingKey.signDigestDeterminstic(
      digest: messgaeHash,
      hashFunc: () => SHA256(),
      extraEntropy: extraEntropy);
  BigInt newS;
  if (ecdsaSign.s.compareTo(CryptoSignerConst.secp256k1OrderHalf) > 0) {
    newS = BitcoinSignerUtils.order - ecdsaSign.s;
  } else {
    newS = ecdsaSign.s;
  }
  final newSignature = ECDSASignature(ecdsaSign.r, newS);
  final recId = newSignature.recoverId(
      hash: messgaeHash, publicKey: verifierKey._verifyKey.publicKey);
  if (recId == null) {
    throw const CryptoSignException(
        'The created signature does not pass verification.');
  }
  return [27 + recId, ...newSignature.toBytes(BitcoinSignerUtils.baselen)];
}