PIVX Core  5.6.99
P2P Digital Currency
messagesigner.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2018 The Dash Core developers
2 // Copyright (c) 2018-2021 The PIVX Core developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "bls/bls_wrapper.h"
7 #include "hash.h"
8 #include "key_io.h"
9 #include "messagesigner.h"
10 #include "tinyformat.h"
11 #include "util/system.h"
12 #include "util/validation.h"
13 #include "utilstrencodings.h"
14 
15 
16 bool CMessageSigner::GetKeysFromSecret(const std::string& strSecret, CKey& keyRet, CPubKey& pubkeyRet)
17 {
18  keyRet = KeyIO::DecodeSecret(strSecret);
19  if (!keyRet.IsValid())
20  return false;
21 
22  pubkeyRet = keyRet.GetPubKey();
23  return pubkeyRet.IsValid();
24 }
25 
26 bool CMessageSigner::GetKeysFromSecret(const std::string& strSecret, CKey& keyRet, CKeyID& keyIDRet)
27 {
28  CPubKey pubkey;
29  if (!GetKeysFromSecret(strSecret, keyRet, pubkey)) {
30  return false;
31  }
32  keyIDRet = pubkey.GetID();
33  return true;
34 }
35 
36 uint256 CMessageSigner::GetMessageHash(const std::string& strMessage)
37 {
38  CHashWriter ss(SER_GETHASH, 0);
39  ss << strMessageMagic;
40  ss << strMessage;
41  return ss.GetHash();
42 }
43 
44 bool CMessageSigner::SignMessage(const std::string& strMessage, std::vector<unsigned char>& vchSigRet, const CKey& key)
45 {
46  return CHashSigner::SignHash(GetMessageHash(strMessage), key, vchSigRet);
47 }
48 
49 bool CMessageSigner::SignMessage(const std::string& strMessage, std::vector<unsigned char>& vchSigRet, const CBLSSecretKey& key)
50 {
51  return CHashSigner::SignHash(GetMessageHash(strMessage), key, vchSigRet);
52 }
53 
54 bool CMessageSigner::VerifyMessage(const CPubKey& pubkey, const std::vector<unsigned char>& vchSig, const std::string& strMessage, std::string& strErrorRet)
55 {
56  return VerifyMessage(pubkey.GetID(), vchSig, strMessage, strErrorRet);
57 }
58 
59 bool CMessageSigner::VerifyMessage(const CKeyID& keyID, const std::vector<unsigned char>& vchSig, const std::string& strMessage, std::string& strErrorRet)
60 {
61  return CHashSigner::VerifyHash(GetMessageHash(strMessage), keyID, vchSig, strErrorRet);
62 }
63 
64 bool CMessageSigner::VerifyMessage(const CBLSPublicKey& pk, const std::vector<unsigned char>& vchSig, const std::string& strMessage)
65 {
66  return CHashSigner::VerifyHash(GetMessageHash(strMessage), pk, vchSig);
67 }
68 
69 bool CHashSigner::SignHash(const uint256& hash, const CKey& key, std::vector<unsigned char>& vchSigRet)
70 {
71  return key.SignCompact(hash, vchSigRet);
72 }
73 
74 bool CHashSigner::SignHash(const uint256& hash, const CBLSSecretKey& key, std::vector<unsigned char>& vchSigRet)
75 {
76  if (!key.IsValid()) {
77  return false;
78  }
79  vchSigRet = key.Sign(hash).ToByteVector();
80  return true;
81 }
82 
83 bool CHashSigner::VerifyHash(const uint256& hash, const CPubKey& pubkey, const std::vector<unsigned char>& vchSig, std::string& strErrorRet)
84 {
85  return VerifyHash(hash, pubkey.GetID(), vchSig, strErrorRet);
86 }
87 
88 bool CHashSigner::VerifyHash(const uint256& hash, const CKeyID& keyID, const std::vector<unsigned char>& vchSig, std::string& strErrorRet)
89 {
90  CPubKey pubkeyFromSig;
91  if(!pubkeyFromSig.RecoverCompact(hash, vchSig)) {
92  strErrorRet = "Error recovering public key.";
93  return false;
94  }
95 
96  if(pubkeyFromSig.GetID() != keyID) {
97  strErrorRet = strprintf("Keys don't match: pubkey=%s, pubkeyFromSig=%s, hash=%s, vchSig=%s",
98  EncodeDestination(keyID), EncodeDestination(pubkeyFromSig.GetID()),
99  hash.ToString(), EncodeBase64(vchSig));
100  return false;
101  }
102 
103  return true;
104 }
105 
106 bool CHashSigner::VerifyHash(const uint256& hash, const CBLSPublicKey& pk, const std::vector<unsigned char>& vchSig)
107 {
108  return CBLSSignature(vchSig).VerifyInsecure(pk, hash);
109 }
110 
115 bool CSignedMessage::Sign(const CKey& key, const CKeyID& keyID)
116 {
118  std::string strError = "";
119  uint256 hash = GetSignatureHash();
120 
121  if(!CHashSigner::SignHash(hash, key, vchSig)) {
122  return error("%s : SignHash() failed", __func__);
123  }
124 
125  if (!CHashSigner::VerifyHash(hash, keyID, vchSig, strError)) {
126  return error("%s : VerifyHash() failed, error: %s", __func__, strError);
127  }
128 
129  return true;
130 }
131 
132 bool CSignedMessage::Sign(const std::string strSignKey)
133 {
134  CKey key;
135  CPubKey pubkey;
136 
137  if (!CMessageSigner::GetKeysFromSecret(strSignKey, key, pubkey)) {
138  return error("%s : Invalid strSignKey", __func__);
139  }
140 
141  return Sign(key, pubkey.GetID());
142 }
143 
145 {
147 
149  return error("%s : SignHash() failed", __func__);
150  }
151 
152  return true;
153 }
154 
155 bool CSignedMessage::CheckSignature(const CKeyID& keyID) const
156 {
157  std::string strError = "";
158 
160  uint256 hash = GetSignatureHash();
161  return CHashSigner::VerifyHash(hash, keyID, vchSig, strError);
162  }
163 
164  std::string strMessage = GetStrMessage();
165  return CMessageSigner::VerifyMessage(keyID, vchSig, strMessage, strError);
166 }
167 
169 {
170  // Only MESS_VER_HASH allowed
172  return false;
173  }
174 
176 }
177 
179 {
180  return EncodeBase64(vchSig);
181 }
182 
CBLSSignature Sign(const uint256 &hash) const
bool VerifyInsecure(const CBLSPublicKey &pubKey, const uint256 &hash) const
bool IsValid() const
Definition: bls_wrapper.h:87
std::vector< uint8_t > ToByteVector() const
Definition: bls_wrapper.h:116
static bool SignHash(const uint256 &hash, const CKey &key, std::vector< unsigned char > &vchSigRet)
Sign the hash, returns true if successful.
static bool VerifyHash(const uint256 &hash, const CPubKey &pubkey, const std::vector< unsigned char > &vchSig, std::string &strErrorRet)
Verify the hash signature, returns true if successful.
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:216
uint256 GetHash()
Definition: hash.h:236
An encapsulated private key.
Definition: key.h:30
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:95
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:186
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:231
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
static bool SignMessage(const std::string &strMessage, std::vector< unsigned char > &vchSigRet, const CKey &key)
Sign the message, returns true if successful.
static bool VerifyMessage(const CPubKey &pubkey, const std::vector< unsigned char > &vchSig, const std::string &strMessage, std::string &strErrorRet)
Verify the message signature, returns true if successful.
static bool GetKeysFromSecret(const std::string &strSecret, CKey &keyRet, CPubKey &pubkeyRet)
Set the private/public key values, returns true if successful.
static uint256 GetMessageHash(const std::string &strMessage)
Get the hash based on the input message.
An encapsulated public key.
Definition: pubkey.h:44
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:188
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:167
bool IsValid() const
Definition: pubkey.h:183
bool Sign(const CKey &key, const CKeyID &keyID)
CSignedMessage Class Functions inherited by network signed-messages.
bool CheckSignature(const CKeyID &keyID) const
virtual std::string GetStrMessage() const =0
virtual uint256 GetSignatureHash() const =0
std::string GetSignatureBase64() const
std::vector< unsigned char > vchSig
Definition: messagesigner.h:65
std::string ToString() const
Definition: uint256.cpp:65
256-bit opaque blob.
Definition: uint256.h:138
@ MESS_VER_HASH
Definition: messagesigner.h:17
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:127
std::string EncodeDestination(const CWDestination &address, const CChainParams::Base58Type addrType)
@ SER_GETHASH
Definition: serialize.h:176
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
#define strprintf
Definition: tinyformat.h:1056
const std::string strMessageMagic
Definition: validation.cpp:27
std::string EncodeBase64(Span< const unsigned char > input)