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