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