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