Branch data Line data Source code
# 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:
# 25 : 100260 : explicit DestinationEncoder(const CChainParams& params) : m_params(params) {}
# 26 : :
# 27 : : std::string operator()(const PKHash& id) const
# 28 : 34864 : {
# 29 : 34864 : std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
# 30 : 34864 : data.insert(data.end(), id.begin(), id.end());
# 31 : 34864 : return EncodeBase58Check(data);
# 32 : 34864 : }
# 33 : :
# 34 : : std::string operator()(const ScriptHash& id) const
# 35 : 6732 : {
# 36 : 6732 : std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
# 37 : 6732 : data.insert(data.end(), id.begin(), id.end());
# 38 : 6732 : return EncodeBase58Check(data);
# 39 : 6732 : }
# 40 : :
# 41 : : std::string operator()(const WitnessV0KeyHash& id) const
# 42 : 57571 : {
# 43 : 57571 : std::vector<unsigned char> data = {0};
# 44 : 57571 : data.reserve(33);
# 45 : 1842272 : ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
# 46 : 57571 : return bech32::Encode(bech32::Encoding::BECH32, m_params.Bech32HRP(), data);
# 47 : 57571 : }
# 48 : :
# 49 : : std::string operator()(const WitnessV0ScriptHash& id) const
# 50 : 994 : {
# 51 : 994 : std::vector<unsigned char> data = {0};
# 52 : 994 : data.reserve(53);
# 53 : 51688 : ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
# 54 : 994 : return bech32::Encode(bech32::Encoding::BECH32, m_params.Bech32HRP(), data);
# 55 : 994 : }
# 56 : :
# 57 : : std::string operator()(const WitnessUnknown& id) const
# 58 : 99 : {
# 59 [ - + ][ - + ]: 99 : if (id.version < 1 || id.version > 16 || id.length < 2 || id.length > 40) {
# [ - + ][ - + ]
# 60 : 0 : return {};
# 61 : 0 : }
# 62 : 99 : std::vector<unsigned char> data = {(unsigned char)id.version};
# 63 : 99 : data.reserve(1 + (id.length * 8 + 4) / 5);
# 64 : 3206 : ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.program, id.program + id.length);
# 65 : 99 : return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
# 66 : 99 : }
# 67 : :
# 68 : 0 : std::string operator()(const CNoDestination& no) const { return {}; }
# 69 : : };
# 70 : :
# 71 : : CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, std::string& error_str)
# 72 : 32648 : {
# 73 : 32648 : std::vector<unsigned char> data;
# 74 : 32648 : uint160 hash;
# 75 : 32648 : error_str = "";
# 76 [ + + ]: 32648 : if (DecodeBase58Check(str, data, 21)) {
# 77 : : // base58-encoded Bitcoin addresses.
# 78 : : // Public-key-hash-addresses have version 0 (or 111 testnet).
# 79 : : // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
# 80 : 4964 : const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
# 81 [ + - ][ + + ]: 4964 : if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
# 82 : 2946 : std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
# 83 : 2946 : return PKHash(hash);
# 84 : 2946 : }
# 85 : : // Script-hash-addresses have version 5 (or 196 testnet).
# 86 : : // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
# 87 : 2018 : const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
# 88 [ + - ][ + + ]: 2018 : if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
# 89 : 1986 : std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
# 90 : 1986 : return ScriptHash(hash);
# 91 : 1986 : }
# 92 : :
# 93 : : // Set potential error message.
# 94 : : // This message may be changed if the address can also be interpreted as a Bech32 address.
# 95 : 32 : error_str = "Invalid prefix for Base58-encoded address";
# 96 : 32 : }
# 97 : 32648 : data.clear();
# 98 : 27716 : const auto dec = bech32::Decode(str);
# 99 [ + + ][ + + ]: 27716 : if ((dec.encoding == bech32::Encoding::BECH32 || dec.encoding == bech32::Encoding::BECH32M) && dec.data.size() > 0) {
# [ + + ]
# 100 : : // Bech32 decoding
# 101 : 27286 : error_str = "";
# 102 [ + + ]: 27286 : if (dec.hrp != params.Bech32HRP()) {
# 103 : 200 : error_str = "Invalid prefix for Bech32 address";
# 104 : 200 : return CNoDestination();
# 105 : 200 : }
# 106 : 27086 : int version = dec.data[0]; // The first 5 bit symbol is the witness version (0-16)
# 107 [ + + ][ + + ]: 27086 : if (version == 0 && dec.encoding != bech32::Encoding::BECH32) {
# 108 : 23 : error_str = "Version 0 witness address must use Bech32 checksum";
# 109 : 23 : return CNoDestination();
# 110 : 23 : }
# 111 [ + + ][ + + ]: 27063 : if (version != 0 && dec.encoding != bech32::Encoding::BECH32M) {
# 112 : 15 : error_str = "Version 1+ witness address must use Bech32m checksum";
# 113 : 15 : return CNoDestination();
# 114 : 15 : }
# 115 : : // The rest of the symbols are converted witness program bytes.
# 116 : 27048 : data.reserve(((dec.data.size() - 1) * 5) / 8);
# 117 [ + + ]: 548139 : if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, dec.data.begin() + 1, dec.data.end())) {
# 118 [ + + ]: 27036 : if (version == 0) {
# 119 : 26931 : {
# 120 : 26931 : WitnessV0KeyHash keyid;
# 121 [ + + ]: 26931 : if (data.size() == keyid.size()) {
# 122 : 26372 : std::copy(data.begin(), data.end(), keyid.begin());
# 123 : 26372 : return keyid;
# 124 : 26372 : }
# 125 : 559 : }
# 126 : 559 : {
# 127 : 559 : WitnessV0ScriptHash scriptid;
# 128 [ + + ]: 559 : if (data.size() == scriptid.size()) {
# 129 : 546 : std::copy(data.begin(), data.end(), scriptid.begin());
# 130 : 546 : return scriptid;
# 131 : 546 : }
# 132 : 13 : }
# 133 : :
# 134 : 13 : error_str = "Invalid Bech32 v0 address data size";
# 135 : 13 : return CNoDestination();
# 136 : 13 : }
# 137 : :
# 138 [ + + ]: 105 : if (version > 16) {
# 139 : 12 : error_str = "Invalid Bech32 address witness version";
# 140 : 12 : return CNoDestination();
# 141 : 12 : }
# 142 : :
# 143 [ + + ][ + + ]: 93 : if (data.size() < 2 || data.size() > BECH32_WITNESS_PROG_MAX_LEN) {
# 144 : 16 : error_str = "Invalid Bech32 address data size";
# 145 : 16 : return CNoDestination();
# 146 : 16 : }
# 147 : :
# 148 : 77 : WitnessUnknown unk;
# 149 : 77 : unk.version = version;
# 150 : 77 : std::copy(data.begin(), data.end(), unk.program);
# 151 : 77 : unk.length = data.size();
# 152 : 77 : return unk;
# 153 : 77 : }
# 154 : 27048 : }
# 155 : :
# 156 : : // Set error message if address can't be interpreted as Base58 or Bech32.
# 157 [ + + ]: 442 : if (error_str.empty()) error_str = "Invalid address format";
# 158 : :
# 159 : 442 : return CNoDestination();
# 160 : 442 : }
# 161 : : } // namespace
# 162 : :
# 163 : : CKey DecodeSecret(const std::string& str)
# 164 : 3481 : {
# 165 : 3481 : CKey key;
# 166 : 3481 : std::vector<unsigned char> data;
# 167 [ + + ]: 3481 : if (DecodeBase58Check(str, data, 34)) {
# 168 : 1975 : const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
# 169 [ + + ][ + + ]: 1975 : if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
# [ + + ]
# 170 [ + + ]: 1975 : std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
# 171 : 1893 : bool compressed = data.size() == 33 + privkey_prefix.size();
# 172 : 1893 : key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
# 173 : 1893 : }
# 174 : 1975 : }
# 175 [ + + ]: 3481 : if (!data.empty()) {
# 176 : 1975 : memory_cleanse(data.data(), data.size());
# 177 : 1975 : }
# 178 : 3481 : return key;
# 179 : 3481 : }
# 180 : :
# 181 : : std::string EncodeSecret(const CKey& key)
# 182 : 2135 : {
# 183 : 2135 : assert(key.IsValid());
# 184 : 2135 : std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
# 185 : 2135 : data.insert(data.end(), key.begin(), key.end());
# 186 [ + + ]: 2135 : if (key.IsCompressed()) {
# 187 : 2071 : data.push_back(1);
# 188 : 2071 : }
# 189 : 2135 : std::string ret = EncodeBase58Check(data);
# 190 : 2135 : memory_cleanse(data.data(), data.size());
# 191 : 2135 : return ret;
# 192 : 2135 : }
# 193 : :
# 194 : : CExtPubKey DecodeExtPubKey(const std::string& str)
# 195 : 1882 : {
# 196 : 1882 : CExtPubKey key;
# 197 : 1882 : std::vector<unsigned char> data;
# 198 [ + + ]: 1882 : if (DecodeBase58Check(str, data, 78)) {
# 199 : 1880 : const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
# 200 [ + - ][ + + ]: 1880 : if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
# 201 : 1611 : key.Decode(data.data() + prefix.size());
# 202 : 1611 : }
# 203 : 1880 : }
# 204 : 1882 : return key;
# 205 : 1882 : }
# 206 : :
# 207 : : std::string EncodeExtPubKey(const CExtPubKey& key)
# 208 : 108973 : {
# 209 : 108973 : std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
# 210 : 108973 : size_t size = data.size();
# 211 : 108973 : data.resize(size + BIP32_EXTKEY_SIZE);
# 212 : 108973 : key.Encode(data.data() + size);
# 213 : 108973 : std::string ret = EncodeBase58Check(data);
# 214 : 108973 : return ret;
# 215 : 108973 : }
# 216 : :
# 217 : : CExtKey DecodeExtKey(const std::string& str)
# 218 : 1882 : {
# 219 : 1882 : CExtKey key;
# 220 : 1882 : std::vector<unsigned char> data;
# 221 [ + + ]: 1882 : if (DecodeBase58Check(str, data, 78)) {
# 222 : 1880 : const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
# 223 [ + - ][ + + ]: 1880 : if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
# 224 : 303 : key.Decode(data.data() + prefix.size());
# 225 : 303 : }
# 226 : 1880 : }
# 227 : 1882 : return key;
# 228 : 1882 : }
# 229 : :
# 230 : : std::string EncodeExtKey(const CExtKey& key)
# 231 : 495 : {
# 232 : 495 : std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
# 233 : 495 : size_t size = data.size();
# 234 : 495 : data.resize(size + BIP32_EXTKEY_SIZE);
# 235 : 495 : key.Encode(data.data() + size);
# 236 : 495 : std::string ret = EncodeBase58Check(data);
# 237 : 495 : memory_cleanse(data.data(), data.size());
# 238 : 495 : return ret;
# 239 : 495 : }
# 240 : :
# 241 : : std::string EncodeDestination(const CTxDestination& dest)
# 242 : 100260 : {
# 243 : 100260 : return std::visit(DestinationEncoder(Params()), dest);
# 244 : 100260 : }
# 245 : :
# 246 : : CTxDestination DecodeDestination(const std::string& str, std::string& error_msg)
# 247 : 32312 : {
# 248 : 32312 : return DecodeDestination(str, Params(), error_msg);
# 249 : 32312 : }
# 250 : :
# 251 : : CTxDestination DecodeDestination(const std::string& str)
# 252 : 30851 : {
# 253 : 30851 : std::string error_msg;
# 254 : 30851 : return DecodeDestination(str, error_msg);
# 255 : 30851 : }
# 256 : :
# 257 : : bool IsValidDestinationString(const std::string& str, const CChainParams& params)
# 258 : 336 : {
# 259 : 336 : std::string error_msg;
# 260 : 336 : return IsValidDestination(DecodeDestination(str, params, error_msg));
# 261 : 336 : }
# 262 : :
# 263 : : bool IsValidDestinationString(const std::string& str)
# 264 : 336 : {
# 265 : 336 : return IsValidDestinationString(str, Params());
# 266 : 336 : }
|