key_io.cpp raw
1 // Copyright (c) 2014-2021 The Limenka 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 <script/interpreter.h>
10 #include <script/solver.h>
11 #include <tinyformat.h>
12 #include <util/strencodings.h>
13
14 #include <algorithm>
15 #include <assert.h>
16 #include <string.h>
17
18 /// Maximum witness length for Bech32 addresses.
19 static constexpr std::size_t BECH32_WITNESS_PROG_MAX_LEN = 40;
20
21 namespace {
22 class DestinationEncoder
23 {
24 private:
25 const CChainParams& m_params;
26
27 public:
28 explicit DestinationEncoder(const CChainParams& params) : m_params(params) {}
29
30 std::string operator()(const PKHash& id) const
31 {
32 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
33 data.insert(data.end(), id.begin(), id.end());
34 return EncodeBase58Check(data);
35 }
36
37 std::string operator()(const ScriptHash& id) const
38 {
39 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
40 data.insert(data.end(), id.begin(), id.end());
41 return EncodeBase58Check(data);
42 }
43
44 std::string operator()(const WitnessV0KeyHash& id) const
45 {
46 std::vector<unsigned char> data = {0};
47 data.reserve(33);
48 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
49 return bech32::Encode(bech32::Encoding::BECH32, m_params.Bech32HRP(), data);
50 }
51
52 std::string operator()(const WitnessV0ScriptHash& id) const
53 {
54 std::vector<unsigned char> data = {0};
55 data.reserve(53);
56 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
57 return bech32::Encode(bech32::Encoding::BECH32, m_params.Bech32HRP(), data);
58 }
59
60 std::string operator()(const WitnessV1Taproot& tap) const
61 {
62 std::vector<unsigned char> data = {1};
63 data.reserve(53);
64 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, tap.begin(), tap.end());
65 return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
66 }
67
68 std::string operator()(const WitnessV3SpkHash& id) const
69 {
70 // HRP "lm1": the prefix identifies the type, so no version byte.
71 std::vector<unsigned char> data;
72 data.reserve(53);
73 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
74 return bech32::Encode(bech32::Encoding::BECH32M, "lm1", data);
75 }
76
77 std::string operator()(const WitnessV4StealthAddress& id) const
78 {
79 // HRP "lm2": 66-byte payload (view 33 || spend 33).
80 std::vector<unsigned char> data;
81 data.reserve(110);
82 data.insert(data.end(), id.view.begin(), id.view.end());
83 data.insert(data.end(), id.spend.begin(), id.spend.end());
84 std::vector<unsigned char> converted;
85 converted.reserve(110);
86 ConvertBits<8, 5, true>([&](unsigned char c) { converted.push_back(c); }, data.begin(), data.end());
87 return bech32::Encode(bech32::Encoding::BECH32M, "lm2", converted);
88 }
89
90 std::string operator()(const WitnessUnknown& id) const
91 {
92 const std::vector<unsigned char>& program = id.GetWitnessProgram();
93 if (id.GetWitnessVersion() < 1 || id.GetWitnessVersion() > 16 || program.size() < 2 || program.size() > 40) {
94 return {};
95 }
96 std::vector<unsigned char> data = {(unsigned char)id.GetWitnessVersion()};
97 data.reserve(1 + (program.size() * 8 + 4) / 5);
98 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, program.begin(), program.end());
99 return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
100 }
101
102 std::string operator()(const CNoDestination& no) const { return {}; }
103 std::string operator()(const PubKeyDestination& pk) const { return {}; }
104 };
105
106 CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, std::string& error_str, std::vector<int>* error_locations)
107 {
108 std::vector<unsigned char> data;
109 uint160 hash;
110 error_str = "";
111
112 // Fixed-HRP formats: lm1 (P2SPKH), lm2 (P2BPCT stealth). These are
113 // chain-independent and handled before the chain-specific HRP check.
114 // lm2 carries 66 bytes (~117 chars), so it decodes under CODEX32.
115 {
116 const auto dec = bech32::Decode(str, (ToLower(str.substr(0, 3)) == "lm2") ? bech32::CharLimit::CODEX32 : bech32::CharLimit::BECH32);
117 if (dec.encoding == bech32::Encoding::BECH32M && !dec.data.empty()) {
118 if (dec.hrp == "lm1") {
119 std::vector<unsigned char> payload;
120 payload.reserve(((dec.data.size()) * 5) / 8);
121 if (ConvertBits<5, 8, false>([&](unsigned char c) { payload.push_back(c); },
122 dec.data.begin(), dec.data.end()) &&
123 payload.size() == WITNESS_V3_SPKHASH_SIZE) {
124 WitnessV3SpkHash hash;
125 std::copy(payload.begin(), payload.end(), hash.begin());
126 return hash;
127 }
128 error_str = "Invalid lm1 (P2SPKH) address payload size";
129 return CNoDestination();
130 }
131 if (dec.hrp == "lm2" && dec.encoding == bech32::Encoding::BECH32M) {
132 std::vector<unsigned char> payload;
133 payload.reserve(((dec.data.size()) * 5) / 8);
134 if (ConvertBits<5, 8, false>([&](unsigned char c) { payload.push_back(c); },
135 dec.data.begin(), dec.data.end()) &&
136 payload.size() == 66) {
137 CPubKey view(payload.begin(), payload.begin() + 33);
138 CPubKey spend(payload.begin() + 33, payload.end());
139 if (view.IsFullyValid() && spend.IsFullyValid()) {
140 return WitnessV4StealthAddress{view, spend};
141 }
142 error_str = "Invalid lm2 (P2BPCT stealth) address keys";
143 return CNoDestination();
144 }
145 error_str = "Invalid lm2 (P2BPCT stealth) address payload size";
146 return CNoDestination();
147 }
148 }
149 }
150
151
152
153 // Note this will be false if it is a valid Bech32 address for a different network
154 bool is_bech32 = (ToLower(str.substr(0, params.Bech32HRP().size())) == params.Bech32HRP());
155
156 if (!is_bech32 && DecodeBase58Check(str, data, 21)) {
157 // base58-encoded Limenka addresses.
158 // Public-key-hash-addresses have version 0 (or 111 testnet).
159 // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
160 const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
161 if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
162 std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
163 return PKHash(hash);
164 }
165 // Script-hash-addresses have version 5 (or 196 testnet).
166 // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
167 const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
168 if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
169 std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
170 return ScriptHash(hash);
171 }
172
173 // If the prefix of data matches either the script or pubkey prefix, the length must have been wrong
174 if ((data.size() >= script_prefix.size() &&
175 std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) ||
176 (data.size() >= pubkey_prefix.size() &&
177 std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin()))) {
178 error_str = "Invalid length for Base58 address (P2PKH or P2SH)";
179 } else {
180 error_str = "Invalid or unsupported Base58-encoded address.";
181 }
182 return CNoDestination();
183 } else if (!is_bech32) {
184 // Try Base58 decoding without the checksum, using a much larger max length
185 if (!DecodeBase58(str, data, 100)) {
186 error_str = "Invalid or unsupported Segwit (Bech32) or Base58 encoding.";
187 } else {
188 error_str = "Invalid checksum or length of Base58 address (P2PKH or P2SH)";
189 }
190 return CNoDestination();
191 }
192
193 data.clear();
194 const auto dec = bech32::Decode(str);
195 if (dec.encoding == bech32::Encoding::BECH32 || dec.encoding == bech32::Encoding::BECH32M) {
196 if (dec.data.empty()) {
197 error_str = "Empty Bech32 data section";
198 return CNoDestination();
199 }
200 // Bech32 decoding
201 if (dec.hrp != params.Bech32HRP()) {
202 error_str = strprintf("Invalid or unsupported prefix for Segwit (Bech32) address (expected %s, got %s).", params.Bech32HRP(), dec.hrp);
203 return CNoDestination();
204 }
205 int version = dec.data[0]; // The first 5 bit symbol is the witness version (0-16)
206 if (version == 0 && dec.encoding != bech32::Encoding::BECH32) {
207 error_str = "Version 0 witness address must use Bech32 checksum";
208 return CNoDestination();
209 }
210 if (version != 0 && dec.encoding != bech32::Encoding::BECH32M) {
211 error_str = "Version 1+ witness address must use Bech32m checksum";
212 return CNoDestination();
213 }
214 // The rest of the symbols are converted witness program bytes.
215 data.reserve(((dec.data.size() - 1) * 5) / 8);
216 if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, dec.data.begin() + 1, dec.data.end())) {
217
218 std::string_view byte_str{data.size() == 1 ? "byte" : "bytes"};
219
220 if (version == 0) {
221 {
222 WitnessV0KeyHash keyid;
223 if (data.size() == keyid.size()) {
224 std::copy(data.begin(), data.end(), keyid.begin());
225 return keyid;
226 }
227 }
228 {
229 WitnessV0ScriptHash scriptid;
230 if (data.size() == scriptid.size()) {
231 std::copy(data.begin(), data.end(), scriptid.begin());
232 return scriptid;
233 }
234 }
235
236 error_str = strprintf("Invalid Bech32 v0 address program size (%d %s), per BIP141", data.size(), byte_str);
237 return CNoDestination();
238 }
239
240 if (version == 1 && data.size() == WITNESS_V1_TAPROOT_SIZE) {
241 static_assert(WITNESS_V1_TAPROOT_SIZE == WitnessV1Taproot::size());
242 WitnessV1Taproot tap;
243 std::copy(data.begin(), data.end(), tap.begin());
244 return tap;
245 }
246
247 if (version == 3 && data.size() == WITNESS_V3_SPKHASH_SIZE) {
248 WitnessV3SpkHash hash;
249 std::copy(data.begin(), data.end(), hash.begin());
250 return hash;
251 }
252
253 if (CScript::IsPayToAnchor(version, data)) {
254 return PayToAnchor();
255 }
256
257 if (version > 16) {
258 error_str = "Invalid Bech32 address witness version";
259 return CNoDestination();
260 }
261
262 if (data.size() < 2 || data.size() > BECH32_WITNESS_PROG_MAX_LEN) {
263 error_str = strprintf("Invalid Bech32 address program size (%d %s)", data.size(), byte_str);
264 return CNoDestination();
265 }
266
267 return WitnessUnknown{version, data};
268 } else {
269 error_str = strprintf("Invalid padding in Bech32 data section");
270 return CNoDestination();
271 }
272 }
273
274 // Perform Bech32 error location
275 auto res = bech32::LocateErrors(str);
276 error_str = res.first;
277 if (error_locations) *error_locations = std::move(res.second);
278 return CNoDestination();
279 }
280 } // namespace
281
282 CKey DecodeSecret(const std::string& str)
283 {
284 CKey key;
285 std::vector<unsigned char> data;
286 if (DecodeBase58Check(str, data, 34)) {
287 const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
288 if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
289 std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
290 bool compressed = data.size() == 33 + privkey_prefix.size();
291 key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
292 }
293 }
294 if (!data.empty()) {
295 memory_cleanse(data.data(), data.size());
296 }
297 return key;
298 }
299
300 std::string EncodeSecret(const CKey& key)
301 {
302 assert(key.IsValid());
303 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
304 data.insert(data.end(), UCharCast(key.begin()), UCharCast(key.end()));
305 if (key.IsCompressed()) {
306 data.push_back(1);
307 }
308 std::string ret = EncodeBase58Check(data);
309 memory_cleanse(data.data(), data.size());
310 return ret;
311 }
312
313 CExtPubKey DecodeExtPubKey(const std::string& str)
314 {
315 CExtPubKey key;
316 std::vector<unsigned char> data;
317 if (DecodeBase58Check(str, data, 78)) {
318 const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
319 if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
320 key.Decode(data.data() + prefix.size());
321 }
322 }
323 return key;
324 }
325
326 std::string EncodeExtPubKey(const CExtPubKey& key)
327 {
328 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
329 size_t size = data.size();
330 data.resize(size + BIP32_EXTKEY_SIZE);
331 key.Encode(data.data() + size);
332 std::string ret = EncodeBase58Check(data);
333 return ret;
334 }
335
336 CExtKey DecodeExtKey(const std::string& str)
337 {
338 CExtKey key;
339 std::vector<unsigned char> data;
340 if (DecodeBase58Check(str, data, 78)) {
341 const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
342 if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
343 key.Decode(data.data() + prefix.size());
344 }
345 }
346 if (!data.empty()) {
347 memory_cleanse(data.data(), data.size());
348 }
349 return key;
350 }
351
352 std::string EncodeExtKey(const CExtKey& key)
353 {
354 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
355 size_t size = data.size();
356 data.resize(size + BIP32_EXTKEY_SIZE);
357 key.Encode(data.data() + size);
358 std::string ret = EncodeBase58Check(data);
359 memory_cleanse(data.data(), data.size());
360 return ret;
361 }
362
363 std::string EncodeDestination(const CTxDestination& dest)
364 {
365 return std::visit(DestinationEncoder(Params()), dest);
366 }
367
368 CTxDestination DecodeDestination(const std::string& str, std::string& error_msg, std::vector<int>* error_locations)
369 {
370 return DecodeDestination(str, Params(), error_msg, error_locations);
371 }
372
373 CTxDestination DecodeDestination(const std::string& str)
374 {
375 std::string error_msg;
376 return DecodeDestination(str, error_msg);
377 }
378
379 bool IsValidDestinationString(const std::string& str, const CChainParams& params)
380 {
381 std::string error_msg;
382 return IsValidDestination(DecodeDestination(str, params, error_msg, nullptr));
383 }
384
385 bool IsValidDestinationString(const std::string& str)
386 {
387 return IsValidDestinationString(str, Params());
388 }
389