Bitcoin Core  24.99.0
P2P Digital Currency
message.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2021 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 <script/standard.h>
11 #include <uint256.h>
12 #include <util/message.h>
13 #include <util/strencodings.h>
14 
15 #include <cassert>
16 #include <optional>
17 #include <string>
18 #include <variant>
19 #include <vector>
20 
25 const std::string MESSAGE_MAGIC = "Bitcoin Signed Message:\n";
26 
28  const std::string& address,
29  const std::string& signature,
30  const std::string& message)
31 {
32  CTxDestination destination = DecodeDestination(address);
33  if (!IsValidDestination(destination)) {
35  }
36 
37  if (std::get_if<PKHash>(&destination) == nullptr) {
39  }
40 
41  auto signature_bytes = DecodeBase64(signature);
42  if (!signature_bytes) {
44  }
45 
46  CPubKey pubkey;
47  if (!pubkey.RecoverCompact(MessageHash(message), *signature_bytes)) {
49  }
50 
51  if (!(CTxDestination(PKHash(pubkey)) == destination)) {
53  }
54 
56 }
57 
59  const CKey& privkey,
60  const std::string& message,
61  std::string& signature)
62 {
63  std::vector<unsigned char> signature_bytes;
64 
65  if (!privkey.SignCompact(MessageHash(message), signature_bytes)) {
66  return false;
67  }
68 
69  signature = EncodeBase64(signature_bytes);
70 
71  return true;
72 }
73 
74 uint256 MessageHash(const std::string& message)
75 {
76  HashWriter hasher{};
77  hasher << MESSAGE_MAGIC << message;
78 
79  return hasher.GetHash();
80 }
81 
82 std::string SigningResultString(const SigningResult res)
83 {
84  switch (res) {
85  case SigningResult::OK:
86  return "No error";
88  return "Private key not available";
90  return "Sign failed";
91  // no default case, so the compiler can warn about missing cases
92  }
93  assert(false);
94 }
An encapsulated private key.
Definition: key.h:27
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Create a compact signature (65 bytes), which allows reconstructing the used public key.
Definition: key.cpp:255
An encapsulated public key.
Definition: pubkey.h:34
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:271
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:100
256-bit opaque blob.
Definition: uint256.h:119
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:281
SigningResult
Definition: message.h:43
@ PRIVATE_KEY_NOT_AVAILABLE
@ OK
No error.
MessageVerificationResult
The result of a signed message verification.
Definition: message.h:23
@ ERR_MALFORMED_SIGNATURE
The provided signature couldn't be parsed (maybe invalid base64).
@ ERR_INVALID_ADDRESS
The provided address is invalid.
@ ERR_ADDRESS_NO_KEY
The provided address is valid but does not refer to a public key.
@ ERR_NOT_SIGNED
The message was not signed with the private key of the provided address.
@ OK
The message verification was successful.
@ ERR_PUBKEY_NOT_RECOVERED
A public key could not be recovered from the provided signature and message.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:356
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:149
uint256 MessageHash(const std::string &message)
Hashes a message for signing and verification in a manner that prevents inadvertently signing a trans...
Definition: message.cpp:74
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
Definition: message.cpp:58
const std::string MESSAGE_MAGIC
Text used to signify that a signed message follows and to prevent inadvertently signing a transaction...
Definition: message.cpp:25
std::string SigningResultString(const SigningResult res)
Definition: message.cpp:82
MessageVerificationResult MessageVerify(const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: message.cpp:27
std::string EncodeBase64(Span< const unsigned char > input)
std::optional< std::vector< unsigned char > > DecodeBase64(std::string_view str)
assert(!tx.IsCoinBase())