Bitcoin Core 28.99.0
P2P Digital Currency
signmessage.cpp
Go to the documentation of this file.
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
7#include <hash.h>
8#include <key.h>
9#include <key_io.h>
10#include <pubkey.h>
11#include <uint256.h>
12#include <util/strencodings.h>
13
14#include <cassert>
15#include <optional>
16#include <string>
17#include <variant>
18#include <vector>
19
24const std::string MESSAGE_MAGIC = "Bitcoin Signed Message:\n";
25
27 const std::string& address,
28 const std::string& signature,
29 const std::string& message)
30{
31 CTxDestination destination = DecodeDestination(address);
32 if (!IsValidDestination(destination)) {
34 }
35
36 if (std::get_if<PKHash>(&destination) == nullptr) {
38 }
39
40 auto signature_bytes = DecodeBase64(signature);
41 if (!signature_bytes) {
43 }
44
45 CPubKey pubkey;
46 if (!pubkey.RecoverCompact(MessageHash(message), *signature_bytes)) {
48 }
49
50 if (!(PKHash(pubkey) == *std::get_if<PKHash>(&destination))) {
52 }
53
55}
56
58 const CKey& privkey,
59 const std::string& message,
60 std::string& signature)
61{
62 std::vector<unsigned char> signature_bytes;
63
64 if (!privkey.SignCompact(MessageHash(message), signature_bytes)) {
65 return false;
66 }
67
68 signature = EncodeBase64(signature_bytes);
69
70 return true;
71}
72
73uint256 MessageHash(const std::string& message)
74{
75 HashWriter hasher{};
76 hasher << MESSAGE_MAGIC << message;
77
78 return hasher.GetHash();
79}
80
81std::string SigningResultString(const SigningResult res)
82{
83 switch (res) {
85 return "No error";
87 return "Private key not available";
89 return "Sign failed";
90 // no default case, so the compiler can warn about missing cases
91 }
92 assert(false);
93}
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:140
An encapsulated private key.
Definition: key.h:35
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:34
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:294
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:101
256-bit opaque blob.
Definition: uint256.h:190
uint256 MessageHash(const std::string &message)
Hashes a message for signing and verification in a manner that prevents inadvertently signing a trans...
Definition: signmessage.cpp:73
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
Definition: signmessage.cpp:57
const std::string MESSAGE_MAGIC
Text used to signify that a signed message follows and to prevent inadvertently signing a transaction...
Definition: signmessage.cpp:24
std::string SigningResultString(const SigningResult res)
Definition: signmessage.cpp:81
MessageVerificationResult MessageVerify(const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: signmessage.cpp:26
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:299
SigningResult
Definition: signmessage.h:43
@ PRIVATE_KEY_NOT_AVAILABLE
@ OK
No error.
MessageVerificationResult
The result of a signed message verification.
Definition: signmessage.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.
std::string EncodeBase64(Span< const unsigned char > input)
std::optional< std::vector< unsigned char > > DecodeBase64(std::string_view str)
assert(!tx.IsCoinBase())