Line data Source code
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 161 : bool CMessageSigner::GetKeysFromSecret(const std::string& strSecret, CKey& keyRet, CPubKey& pubkeyRet)
17 : {
18 161 : keyRet = KeyIO::DecodeSecret(strSecret);
19 161 : if (!keyRet.IsValid())
20 : return false;
21 :
22 161 : pubkeyRet = keyRet.GetPubKey();
23 322 : return pubkeyRet.IsValid();
24 : }
25 :
26 0 : bool CMessageSigner::GetKeysFromSecret(const std::string& strSecret, CKey& keyRet, CKeyID& keyIDRet)
27 : {
28 0 : CPubKey pubkey;
29 0 : if (!GetKeysFromSecret(strSecret, keyRet, pubkey)) {
30 : return false;
31 : }
32 0 : keyIDRet = pubkey.GetID();
33 : return true;
34 : }
35 :
36 596 : uint256 CMessageSigner::GetMessageHash(const std::string& strMessage)
37 : {
38 596 : CHashWriter ss(SER_GETHASH, 0);
39 596 : ss << strMessageMagic;
40 596 : ss << strMessage;
41 596 : return ss.GetHash();
42 : }
43 :
44 46 : bool CMessageSigner::SignMessage(const std::string& strMessage, std::vector<unsigned char>& vchSigRet, const CKey& key)
45 : {
46 46 : return CHashSigner::SignHash(GetMessageHash(strMessage), key, vchSigRet);
47 : }
48 :
49 0 : bool CMessageSigner::SignMessage(const std::string& strMessage, std::vector<unsigned char>& vchSigRet, const CBLSSecretKey& key)
50 : {
51 0 : return CHashSigner::SignHash(GetMessageHash(strMessage), key, vchSigRet);
52 : }
53 :
54 82 : bool CMessageSigner::VerifyMessage(const CPubKey& pubkey, const std::vector<unsigned char>& vchSig, const std::string& strMessage, std::string& strErrorRet)
55 : {
56 82 : return VerifyMessage(pubkey.GetID(), vchSig, strMessage, strErrorRet);
57 : }
58 :
59 550 : bool CMessageSigner::VerifyMessage(const CKeyID& keyID, const std::vector<unsigned char>& vchSig, const std::string& strMessage, std::string& strErrorRet)
60 : {
61 550 : return CHashSigner::VerifyHash(GetMessageHash(strMessage), keyID, vchSig, strErrorRet);
62 : }
63 :
64 0 : bool CMessageSigner::VerifyMessage(const CBLSPublicKey& pk, const std::vector<unsigned char>& vchSig, const std::string& strMessage)
65 : {
66 0 : return CHashSigner::VerifyHash(GetMessageHash(strMessage), pk, vchSig);
67 : }
68 :
69 1736 : bool CHashSigner::SignHash(const uint256& hash, const CKey& key, std::vector<unsigned char>& vchSigRet)
70 : {
71 1736 : return key.SignCompact(hash, vchSigRet);
72 : }
73 :
74 122 : bool CHashSigner::SignHash(const uint256& hash, const CBLSSecretKey& key, std::vector<unsigned char>& vchSigRet)
75 : {
76 122 : if (!key.IsValid()) {
77 : return false;
78 : }
79 244 : vchSigRet = key.Sign(hash).ToByteVector();
80 122 : return true;
81 : }
82 :
83 0 : bool CHashSigner::VerifyHash(const uint256& hash, const CPubKey& pubkey, const std::vector<unsigned char>& vchSig, std::string& strErrorRet)
84 : {
85 0 : return VerifyHash(hash, pubkey.GetID(), vchSig, strErrorRet);
86 : }
87 :
88 5952 : bool CHashSigner::VerifyHash(const uint256& hash, const CKeyID& keyID, const std::vector<unsigned char>& vchSig, std::string& strErrorRet)
89 : {
90 5952 : CPubKey pubkeyFromSig;
91 5952 : if(!pubkeyFromSig.RecoverCompact(hash, vchSig)) {
92 0 : strErrorRet = "Error recovering public key.";
93 0 : return false;
94 : }
95 :
96 5952 : if(pubkeyFromSig.GetID() != keyID) {
97 21 : strErrorRet = strprintf("Keys don't match: pubkey=%s, pubkeyFromSig=%s, hash=%s, vchSig=%s",
98 21 : EncodeDestination(keyID), EncodeDestination(pubkeyFromSig.GetID()),
99 21 : hash.ToString(), EncodeBase64(vchSig));
100 7 : return false;
101 : }
102 :
103 : return true;
104 : }
105 :
106 690 : bool CHashSigner::VerifyHash(const uint256& hash, const CBLSPublicKey& pk, const std::vector<unsigned char>& vchSig)
107 : {
108 690 : return CBLSSignature(vchSig).VerifyInsecure(pk, hash);
109 : }
110 :
111 : /** CSignedMessage Class
112 : * Functions inherited by network signed-messages
113 : */
114 :
115 1673 : bool CSignedMessage::Sign(const CKey& key, const CKeyID& keyID)
116 : {
117 1673 : nMessVersion = MessageVersion::MESS_VER_HASH;
118 3346 : std::string strError = "";
119 1673 : uint256 hash = GetSignatureHash();
120 :
121 1673 : if(!CHashSigner::SignHash(hash, key, vchSig)) {
122 0 : return error("%s : SignHash() failed", __func__);
123 : }
124 :
125 1673 : if (!CHashSigner::VerifyHash(hash, keyID, vchSig, strError)) {
126 0 : return error("%s : VerifyHash() failed, error: %s", __func__, strError);
127 : }
128 :
129 : return true;
130 : }
131 :
132 126 : bool CSignedMessage::Sign(const std::string strSignKey)
133 : {
134 252 : CKey key;
135 126 : CPubKey pubkey;
136 :
137 126 : if (!CMessageSigner::GetKeysFromSecret(strSignKey, key, pubkey)) {
138 0 : return error("%s : Invalid strSignKey", __func__);
139 : }
140 :
141 126 : return Sign(key, pubkey.GetID());
142 : }
143 :
144 122 : bool CSignedMessage::Sign(const CBLSSecretKey& sk)
145 : {
146 122 : nMessVersion = MessageVersion::MESS_VER_HASH;
147 :
148 122 : if(!CHashSigner::SignHash(GetSignatureHash(), sk, vchSig)) {
149 0 : return error("%s : SignHash() failed", __func__);
150 : }
151 :
152 : return true;
153 : }
154 :
155 3642 : bool CSignedMessage::CheckSignature(const CKeyID& keyID) const
156 : {
157 7284 : std::string strError = "";
158 :
159 3642 : if (nMessVersion == MessageVersion::MESS_VER_HASH) {
160 3642 : uint256 hash = GetSignatureHash();
161 3642 : return CHashSigner::VerifyHash(hash, keyID, vchSig, strError);
162 : }
163 :
164 3642 : std::string strMessage = GetStrMessage();
165 0 : return CMessageSigner::VerifyMessage(keyID, vchSig, strMessage, strError);
166 : }
167 :
168 690 : bool CSignedMessage::CheckSignature(const CBLSPublicKey& pk) const
169 : {
170 : // Only MESS_VER_HASH allowed
171 690 : if (nMessVersion != MessageVersion::MESS_VER_HASH) {
172 : return false;
173 : }
174 :
175 690 : return CHashSigner::VerifyHash(GetSignatureHash(), pk, vchSig);
176 : }
177 :
178 0 : std::string CSignedMessage::GetSignatureBase64() const
179 : {
180 0 : return EncodeBase64(vchSig);
181 : }
182 :
|