1 // Copyright (c) 2014-2019 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <key_io.h>
6 
7 #include <base58.h>
8 #include <bech32.h>
9 #include <util/strencodings.h>
10 
11 #include <algorithm>
12 #include <assert.h>
13 #include <string.h>
14 
15 /// Maximum witness length for Bech32 addresses.
16 static constexpr std::size_t BECH32_WITNESS_PROG_MAX_LEN = 40;
17 
18 namespace {
19 class DestinationEncoder
20 {
21 private:
22     const CChainParams& m_params;
23 
24 public:
DestinationEncoder(const CChainParams & params)25     explicit DestinationEncoder(const CChainParams& params) : m_params(params) {}
26 
operator ()(const PKHash & id) const27     std::string operator()(const PKHash& id) const
28     {
29         std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
30         data.insert(data.end(), id.begin(), id.end());
31         return EncodeBase58Check(data);
32     }
33 
operator ()(const ScriptHash & id) const34     std::string operator()(const ScriptHash& id) const
35     {
36         std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
37         data.insert(data.end(), id.begin(), id.end());
38         return EncodeBase58Check(data);
39     }
40 
operator ()(const WitnessV0KeyHash & id) const41     std::string operator()(const WitnessV0KeyHash& id) const
42     {
43         std::vector<unsigned char> data = {0};
44         data.reserve(33);
45         ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
46         return bech32::Encode(bech32::Encoding::BECH32, m_params.Bech32HRP(), data);
47     }
48 
operator ()(const WitnessV0ScriptHash & id) const49     std::string operator()(const WitnessV0ScriptHash& id) const
50     {
51         std::vector<unsigned char> data = {0};
52         data.reserve(53);
53         ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
54         return bech32::Encode(bech32::Encoding::BECH32, m_params.Bech32HRP(), data);
55     }
56 
operator ()(const WitnessV1Taproot & tap) const57     std::string operator()(const WitnessV1Taproot& tap) const
58     {
59         std::vector<unsigned char> data = {1};
60         data.reserve(53);
61         ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, tap.begin(), tap.end());
62         return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
63     }
64 
operator ()(const WitnessUnknown & id) const65     std::string operator()(const WitnessUnknown& id) const
66     {
67         if (id.version < 1 || id.version > 16 || id.length < 2 || id.length > 40) {
68             return {};
69         }
70         std::vector<unsigned char> data = {(unsigned char)id.version};
71         data.reserve(1 + (id.length * 8 + 4) / 5);
72         ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.program, id.program + id.length);
73         return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
74     }
75 
operator ()(const CNoDestination & no) const76     std::string operator()(const CNoDestination& no) const { return {}; }
77 };
78 
DecodeDestination(const std::string & str,const CChainParams & params,std::string & error_str)79 CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, std::string& error_str)
80 {
81     std::vector<unsigned char> data;
82     uint160 hash;
83     error_str = "";
84     if (DecodeBase58Check(str, data, 21)) {
85         // base58-encoded Bitcoin addresses.
86         // Public-key-hash-addresses have version 0 (or 111 testnet).
87         // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
88         const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
89         if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
90             std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
91             return PKHash(hash);
92         }
93         // Script-hash-addresses have version 5 (or 196 testnet).
94         // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
95         const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
96         if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
97             std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
98             return ScriptHash(hash);
99         }
100 
101         // Set potential error message.
102         // This message may be changed if the address can also be interpreted as a Bech32 address.
103         error_str = "Invalid prefix for Base58-encoded address";
104     }
105     data.clear();
106     const auto dec = bech32::Decode(str);
107     if ((dec.encoding == bech32::Encoding::BECH32 || dec.encoding == bech32::Encoding::BECH32M) && dec.data.size() > 0) {
108         // Bech32 decoding
109         error_str = "";
110         if (dec.hrp != params.Bech32HRP()) {
111             error_str = "Invalid prefix for Bech32 address";
112             return CNoDestination();
113         }
114         int version = dec.data[0]; // The first 5 bit symbol is the witness version (0-16)
115         if (version == 0 && dec.encoding != bech32::Encoding::BECH32) {
116             error_str = "Version 0 witness address must use Bech32 checksum";
117             return CNoDestination();
118         }
119         if (version != 0 && dec.encoding != bech32::Encoding::BECH32M) {
120             error_str = "Version 1+ witness address must use Bech32m checksum";
121             return CNoDestination();
122         }
123         // The rest of the symbols are converted witness program bytes.
124         data.reserve(((dec.data.size() - 1) * 5) / 8);
125         if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, dec.data.begin() + 1, dec.data.end())) {
126             if (version == 0) {
127                 {
128                     WitnessV0KeyHash keyid;
129                     if (data.size() == keyid.size()) {
130                         std::copy(data.begin(), data.end(), keyid.begin());
131                         return keyid;
132                     }
133                 }
134                 {
135                     WitnessV0ScriptHash scriptid;
136                     if (data.size() == scriptid.size()) {
137                         std::copy(data.begin(), data.end(), scriptid.begin());
138                         return scriptid;
139                     }
140                 }
141 
142                 error_str = "Invalid Bech32 v0 address data size";
143                 return CNoDestination();
144             }
145 
146             if (version == 1 && data.size() == WITNESS_V1_TAPROOT_SIZE) {
147                 static_assert(WITNESS_V1_TAPROOT_SIZE == WitnessV1Taproot::size());
148                 WitnessV1Taproot tap;
149                 std::copy(data.begin(), data.end(), tap.begin());
150                 return tap;
151             }
152 
153             if (version > 16) {
154                 error_str = "Invalid Bech32 address witness version";
155                 return CNoDestination();
156             }
157 
158             if (data.size() < 2 || data.size() > BECH32_WITNESS_PROG_MAX_LEN) {
159                 error_str = "Invalid Bech32 address data size";
160                 return CNoDestination();
161             }
162 
163             WitnessUnknown unk;
164             unk.version = version;
165             std::copy(data.begin(), data.end(), unk.program);
166             unk.length = data.size();
167             return unk;
168         }
169     }
170 
171     // Set error message if address can't be interpreted as Base58 or Bech32.
172     if (error_str.empty()) error_str = "Invalid address format";
173 
174     return CNoDestination();
175 }
176 } // namespace
177 
DecodeSecret(const std::string & str)178 CKey DecodeSecret(const std::string& str)
179 {
180     CKey key;
181     std::vector<unsigned char> data;
182     if (DecodeBase58Check(str, data, 34)) {
183         const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
184         if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
185             std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
186             bool compressed = data.size() == 33 + privkey_prefix.size();
187             key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
188         }
189     }
190     if (!data.empty()) {
191         memory_cleanse(data.data(), data.size());
192     }
193     return key;
194 }
195 
EncodeSecret(const CKey & key)196 std::string EncodeSecret(const CKey& key)
197 {
198     assert(key.IsValid());
199     std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
200     data.insert(data.end(), key.begin(), key.end());
201     if (key.IsCompressed()) {
202         data.push_back(1);
203     }
204     std::string ret = EncodeBase58Check(data);
205     memory_cleanse(data.data(), data.size());
206     return ret;
207 }
208 
DecodeExtPubKey(const std::string & str)209 CExtPubKey DecodeExtPubKey(const std::string& str)
210 {
211     CExtPubKey key;
212     std::vector<unsigned char> data;
213     if (DecodeBase58Check(str, data, 78)) {
214         const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
215         if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
216             key.Decode(data.data() + prefix.size());
217         }
218     }
219     return key;
220 }
221 
EncodeExtPubKey(const CExtPubKey & key)222 std::string EncodeExtPubKey(const CExtPubKey& key)
223 {
224     std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
225     size_t size = data.size();
226     data.resize(size + BIP32_EXTKEY_SIZE);
227     key.Encode(data.data() + size);
228     std::string ret = EncodeBase58Check(data);
229     return ret;
230 }
231 
DecodeExtKey(const std::string & str)232 CExtKey DecodeExtKey(const std::string& str)
233 {
234     CExtKey key;
235     std::vector<unsigned char> data;
236     if (DecodeBase58Check(str, data, 78)) {
237         const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
238         if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
239             key.Decode(data.data() + prefix.size());
240         }
241     }
242     return key;
243 }
244 
EncodeExtKey(const CExtKey & key)245 std::string EncodeExtKey(const CExtKey& key)
246 {
247     std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
248     size_t size = data.size();
249     data.resize(size + BIP32_EXTKEY_SIZE);
250     key.Encode(data.data() + size);
251     std::string ret = EncodeBase58Check(data);
252     memory_cleanse(data.data(), data.size());
253     return ret;
254 }
255 
EncodeDestination(const CTxDestination & dest)256 std::string EncodeDestination(const CTxDestination& dest)
257 {
258     return std::visit(DestinationEncoder(Params()), dest);
259 }
260 
DecodeDestination(const std::string & str,std::string & error_msg)261 CTxDestination DecodeDestination(const std::string& str, std::string& error_msg)
262 {
263     return DecodeDestination(str, Params(), error_msg);
264 }
265 
DecodeDestination(const std::string & str)266 CTxDestination DecodeDestination(const std::string& str)
267 {
268     std::string error_msg;
269     return DecodeDestination(str, error_msg);
270 }
271 
IsValidDestinationString(const std::string & str,const CChainParams & params)272 bool IsValidDestinationString(const std::string& str, const CChainParams& params)
273 {
274     std::string error_msg;
275     return IsValidDestination(DecodeDestination(str, params, error_msg));
276 }
277 
IsValidDestinationString(const std::string & str)278 bool IsValidDestinationString(const std::string& str)
279 {
280     return IsValidDestinationString(str, Params());
281 }
282