LCOV - code coverage report
Current view: top level - src/util - message.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 30 37 81.1 %
Date: 2020-09-26 01:30:44 Functions: 4 5 80.0 %

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

Generated by: LCOV version 1.15