LCOV - code coverage report
Current view: top level - src/util - message.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 1 35 2.9 %
Date: 2023-09-26 12:08:55 Functions: 1 5 20.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2022 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #include <hash.h>
       7             : #include <key.h>
       8             : #include <key_io.h>
       9             : #include <pubkey.h>
      10             : #include <uint256.h>
      11             : #include <util/message.h>
      12             : #include <util/strencodings.h>
      13             : 
      14             : #include <cassert>
      15             : #include <optional>
      16             : #include <string>
      17             : #include <variant>
      18             : #include <vector>
      19             : 
      20             : /**
      21             :  * Text used to signify that a signed message follows and to prevent
      22             :  * inadvertently signing a transaction.
      23             :  */
      24           2 : const std::string MESSAGE_MAGIC = "Bitcoin Signed Message:\n";
      25             : 
      26           0 : MessageVerificationResult MessageVerify(
      27             :     const std::string& address,
      28             :     const std::string& signature,
      29             :     const std::string& message)
      30             : {
      31           0 :     CTxDestination destination = DecodeDestination(address);
      32           0 :     if (!IsValidDestination(destination)) {
      33           0 :         return MessageVerificationResult::ERR_INVALID_ADDRESS;
      34             :     }
      35             : 
      36           0 :     if (std::get_if<PKHash>(&destination) == nullptr) {
      37           0 :         return MessageVerificationResult::ERR_ADDRESS_NO_KEY;
      38             :     }
      39             : 
      40           0 :     auto signature_bytes = DecodeBase64(signature);
      41           0 :     if (!signature_bytes) {
      42           0 :         return MessageVerificationResult::ERR_MALFORMED_SIGNATURE;
      43             :     }
      44             : 
      45           0 :     CPubKey pubkey;
      46           0 :     if (!pubkey.RecoverCompact(MessageHash(message), *signature_bytes)) {
      47           0 :         return MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED;
      48             :     }
      49             : 
      50           0 :     if (!(PKHash(pubkey) == *std::get_if<PKHash>(&destination))) {
      51           0 :         return MessageVerificationResult::ERR_NOT_SIGNED;
      52             :     }
      53             : 
      54           0 :     return MessageVerificationResult::OK;
      55           0 : }
      56             : 
      57           0 : bool MessageSign(
      58             :     const CKey& privkey,
      59             :     const std::string& message,
      60             :     std::string& signature)
      61             : {
      62           0 :     std::vector<unsigned char> signature_bytes;
      63             : 
      64           0 :     if (!privkey.SignCompact(MessageHash(message), signature_bytes)) {
      65           0 :         return false;
      66             :     }
      67             : 
      68           0 :     signature = EncodeBase64(signature_bytes);
      69             : 
      70           0 :     return true;
      71           0 : }
      72             : 
      73           0 : uint256 MessageHash(const std::string& message)
      74             : {
      75           0 :     HashWriter hasher{};
      76           0 :     hasher << MESSAGE_MAGIC << message;
      77             : 
      78           0 :     return hasher.GetHash();
      79             : }
      80             : 
      81           0 : std::string SigningResultString(const SigningResult res)
      82             : {
      83           0 :     switch (res) {
      84             :         case SigningResult::OK:
      85           0 :             return "No error";
      86             :         case SigningResult::PRIVATE_KEY_NOT_AVAILABLE:
      87           0 :             return "Private key not available";
      88             :         case SigningResult::SIGNING_FAILED:
      89           0 :             return "Sign failed";
      90             :         // no default case, so the compiler can warn about missing cases
      91             :     }
      92           0 :     assert(false);
      93           0 : }

Generated by: LCOV version 1.14