key_io.cpp
1 // Copyright (c) 2014-present 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 <script/interpreter.h> 10 #include <script/solver.h> 11 #include <tinyformat.h> 12 #include <util/strencodings.h> 13 14 #include <algorithm> 15 #include <cassert> 16 #include <cstring> 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 WitnessUnknown& id) const 69 { 70 const std::vector<unsigned char>& program = id.GetWitnessProgram(); 71 if (id.GetWitnessVersion() < 1 || id.GetWitnessVersion() > 16 || program.size() < 2 || program.size() > 40) { 72 return {}; 73 } 74 std::vector<unsigned char> data = {(unsigned char)id.GetWitnessVersion()}; 75 data.reserve(1 + (program.size() * 8 + 4) / 5); 76 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, program.begin(), program.end()); 77 return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data); 78 } 79 80 std::string operator()(const CNoDestination& no) const { return {}; } 81 std::string operator()(const PubKeyDestination& pk) const { return {}; } 82 }; 83 84 CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, std::string& error_str, std::vector<int>* error_locations) 85 { 86 std::vector<unsigned char> data; 87 uint160 hash; 88 error_str = ""; 89 90 // Note this will be false if it is a valid Bech32 address for a different network 91 bool is_bech32 = (ToLower(str.substr(0, params.Bech32HRP().size())) == params.Bech32HRP()); 92 93 if (!is_bech32 && DecodeBase58Check(str, data, 21)) { 94 // base58-encoded Bitcoin addresses. 95 // Public-key-hash-addresses have version 0 (or 111 testnet). 96 // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. 97 const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); 98 if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) { 99 std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin()); 100 return PKHash(hash); 101 } 102 // Script-hash-addresses have version 5 (or 196 testnet). 103 // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. 104 const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); 105 if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) { 106 std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin()); 107 return ScriptHash(hash); 108 } 109 110 // If the prefix of data matches either the script or pubkey prefix, the length must have been wrong 111 if ((data.size() >= script_prefix.size() && 112 std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) || 113 (data.size() >= pubkey_prefix.size() && 114 std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin()))) { 115 error_str = "Invalid length for Base58 address (P2PKH or P2SH)"; 116 } else { 117 error_str = "Invalid or unsupported Base58-encoded address."; 118 } 119 return CNoDestination(); 120 } else if (!is_bech32) { 121 // Try Base58 decoding without the checksum, using a much larger max length 122 if (!DecodeBase58(str, data, 100)) { 123 error_str = "Invalid or unsupported Segwit (Bech32) or Base58 encoding."; 124 } else { 125 error_str = "Invalid checksum or length of Base58 address (P2PKH or P2SH)"; 126 } 127 return CNoDestination(); 128 } 129 130 data.clear(); 131 const auto dec = bech32::Decode(str); 132 if (dec.encoding == bech32::Encoding::BECH32 || dec.encoding == bech32::Encoding::BECH32M) { 133 if (dec.data.empty()) { 134 error_str = "Empty Bech32 data section"; 135 return CNoDestination(); 136 } 137 // Bech32 decoding 138 if (dec.hrp != params.Bech32HRP()) { 139 error_str = strprintf("Invalid or unsupported prefix for Segwit (Bech32) address (expected %s, got %s).", params.Bech32HRP(), dec.hrp); 140 return CNoDestination(); 141 } 142 int version = dec.data[0]; // The first 5 bit symbol is the witness version (0-16) 143 if (version == 0 && dec.encoding != bech32::Encoding::BECH32) { 144 error_str = "Version 0 witness address must use Bech32 checksum"; 145 return CNoDestination(); 146 } 147 if (version != 0 && dec.encoding != bech32::Encoding::BECH32M) { 148 error_str = "Version 1+ witness address must use Bech32m checksum"; 149 return CNoDestination(); 150 } 151 // The rest of the symbols are converted witness program bytes. 152 data.reserve(((dec.data.size() - 1) * 5) / 8); 153 if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, dec.data.begin() + 1, dec.data.end())) { 154 155 std::string_view byte_str{data.size() == 1 ? "byte" : "bytes"}; 156 157 if (version == 0) { 158 { 159 WitnessV0KeyHash keyid; 160 if (data.size() == keyid.size()) { 161 std::copy(data.begin(), data.end(), keyid.begin()); 162 return keyid; 163 } 164 } 165 { 166 WitnessV0ScriptHash scriptid; 167 if (data.size() == scriptid.size()) { 168 std::copy(data.begin(), data.end(), scriptid.begin()); 169 return scriptid; 170 } 171 } 172 173 error_str = strprintf("Invalid Bech32 v0 address program size (%d %s), per BIP141", data.size(), byte_str); 174 return CNoDestination(); 175 } 176 177 if (version == 1 && data.size() == WITNESS_V1_TAPROOT_SIZE) { 178 static_assert(WITNESS_V1_TAPROOT_SIZE == WitnessV1Taproot::size()); 179 WitnessV1Taproot tap; 180 std::copy(data.begin(), data.end(), tap.begin()); 181 return tap; 182 } 183 184 if (CScript::IsPayToAnchor(version, data)) { 185 return PayToAnchor(); 186 } 187 188 if (version > 16) { 189 error_str = "Invalid Bech32 address witness version"; 190 return CNoDestination(); 191 } 192 193 if (data.size() < 2 || data.size() > BECH32_WITNESS_PROG_MAX_LEN) { 194 error_str = strprintf("Invalid Bech32 address program size (%d %s)", data.size(), byte_str); 195 return CNoDestination(); 196 } 197 198 return WitnessUnknown{version, data}; 199 } else { 200 error_str = strprintf("Invalid padding in Bech32 data section"); 201 return CNoDestination(); 202 } 203 } 204 205 // Perform Bech32 error location 206 auto res = bech32::LocateErrors(str); 207 error_str = res.first; 208 if (error_locations) *error_locations = std::move(res.second); 209 return CNoDestination(); 210 } 211 } // namespace 212 213 CKey DecodeSecret(const std::string& str) 214 { 215 CKey key; 216 std::vector<unsigned char> data; 217 if (DecodeBase58Check(str, data, 34)) { 218 const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY); 219 if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) && 220 std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) { 221 bool compressed = data.size() == 33 + privkey_prefix.size(); 222 key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed); 223 } 224 } 225 if (!data.empty()) { 226 memory_cleanse(data.data(), data.size()); 227 } 228 return key; 229 } 230 231 std::string EncodeSecret(const CKey& key) 232 { 233 assert(key.IsValid()); 234 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY); 235 data.insert(data.end(), UCharCast(key.begin()), UCharCast(key.end())); 236 if (key.IsCompressed()) { 237 data.push_back(1); 238 } 239 std::string ret = EncodeBase58Check(data); 240 memory_cleanse(data.data(), data.size()); 241 return ret; 242 } 243 244 CExtPubKey DecodeExtPubKey(const std::string& str) 245 { 246 CExtPubKey key; 247 std::vector<unsigned char> data; 248 if (DecodeBase58Check(str, data, 78)) { 249 const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); 250 if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) { 251 key.Decode(data.data() + prefix.size()); 252 } 253 } 254 return key; 255 } 256 257 std::string EncodeExtPubKey(const CExtPubKey& key) 258 { 259 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); 260 size_t size = data.size(); 261 data.resize(size + BIP32_EXTKEY_SIZE); 262 key.Encode(data.data() + size); 263 std::string ret = EncodeBase58Check(data); 264 return ret; 265 } 266 267 CExtKey DecodeExtKey(const std::string& str) 268 { 269 CExtKey key; 270 std::vector<unsigned char> data; 271 if (DecodeBase58Check(str, data, 78)) { 272 const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); 273 if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) { 274 key.Decode(data.data() + prefix.size()); 275 } 276 } 277 if (!data.empty()) { 278 memory_cleanse(data.data(), data.size()); 279 } 280 return key; 281 } 282 283 std::string EncodeExtKey(const CExtKey& key) 284 { 285 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); 286 size_t size = data.size(); 287 data.resize(size + BIP32_EXTKEY_SIZE); 288 key.Encode(data.data() + size); 289 std::string ret = EncodeBase58Check(data); 290 memory_cleanse(data.data(), data.size()); 291 return ret; 292 } 293 294 std::string EncodeDestination(const CTxDestination& dest) 295 { 296 return std::visit(DestinationEncoder(Params()), dest); 297 } 298 299 CTxDestination DecodeDestination(const std::string& str, std::string& error_msg, std::vector<int>* error_locations) 300 { 301 return DecodeDestination(str, Params(), error_msg, error_locations); 302 } 303 304 CTxDestination DecodeDestination(const std::string& str) 305 { 306 std::string error_msg; 307 return DecodeDestination(str, error_msg); 308 } 309 310 bool IsValidDestinationString(const std::string& str, const CChainParams& params) 311 { 312 std::string error_msg; 313 return IsValidDestination(DecodeDestination(str, params, error_msg, nullptr)); 314 } 315 316 bool IsValidDestinationString(const std::string& str) 317 { 318 return IsValidDestinationString(str, Params()); 319 }