Bitcoin Core 22.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-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
22const std::string MESSAGE_MAGIC = "Bitcoin Signed Message:\n";
23
25 const std::string& address,
26 const std::string& signature,
27 const std::string& message)
28{
29 CTxDestination destination = DecodeDestination(address);
30 if (!IsValidDestination(destination)) {
32 }
33
34 if (std::get_if<PKHash>(&destination) == nullptr) {
36 }
37
38 bool invalid = false;
39 std::vector<unsigned char> signature_bytes = DecodeBase64(signature.c_str(), &invalid);
40 if (invalid) {
42 }
43
44 CPubKey pubkey;
45 if (!pubkey.RecoverCompact(MessageHash(message), signature_bytes)) {
47 }
48
49 if (!(CTxDestination(PKHash(pubkey)) == destination)) {
51 }
52
54}
55
57 const CKey& privkey,
58 const std::string& message,
59 std::string& signature)
60{
61 std::vector<unsigned char> signature_bytes;
62
63 if (!privkey.SignCompact(MessageHash(message), signature_bytes)) {
64 return false;
65 }
66
67 signature = EncodeBase64(signature_bytes);
68
69 return true;
70}
71
72uint256 MessageHash(const std::string& message)
73{
74 CHashWriter hasher(SER_GETHASH, 0);
75 hasher << MESSAGE_MAGIC << message;
76
77 return hasher.GetHash();
78}
79
80std::string SigningResultString(const SigningResult res)
81{
82 switch (res) {
84 return "No error";
86 return "Private key not available";
88 return "Sign failed";
89 // no default case, so the compiler can warn about missing cases
90 }
91 assert(false);
92}
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:101
uint256 GetHash()
Compute the double-SHA256 hash of all data written to this object.
Definition: hash.h:122
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:249
An encapsulated public key.
Definition: pubkey.h:33
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:271
256-bit opaque blob.
Definition: uint256.h:124
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg)
Definition: key_io.cpp:261
SigningResult
Definition: message.h:42
@ PRIVATE_KEY_NOT_AVAILABLE
@ OK
No error.
MessageVerificationResult
The result of a signed message verification.
Definition: message.h:22
@ 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.
@ SER_GETHASH
Definition: serialize.h:140
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:332
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:157
std::vector< unsigned char > DecodeBase64(const char *p, bool *pf_invalid)
std::string EncodeBase64(Span< const unsigned char > input)
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:72
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
Definition: message.cpp:56
const std::string MESSAGE_MAGIC
Text used to signify that a signed message follows and to prevent inadvertently signing a transaction...
Definition: message.cpp:22
std::string SigningResultString(const SigningResult res)
Definition: message.cpp:80
MessageVerificationResult MessageVerify(const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: message.cpp:24
assert(!tx.IsCoinBase())