LCOV - code coverage report
Current view: top level - src - key_io.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 137 140 97.9 %
Date: 2020-09-26 01:30:44 Functions: 22 23 95.7 %

          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 <boost/variant/apply_visitor.hpp>
      12             : #include <boost/variant/static_visitor.hpp>
      13             : 
      14             : #include <assert.h>
      15             : #include <string.h>
      16             : #include <algorithm>
      17             : 
      18             : namespace
      19             : {
      20             : class DestinationEncoder : public boost::static_visitor<std::string>
      21             : {
      22             : private:
      23             :     const CChainParams& m_params;
      24             : 
      25             : public:
      26      223144 :     explicit DestinationEncoder(const CChainParams& params) : m_params(params) {}
      27             : 
      28       55684 :     std::string operator()(const PKHash& id) const
      29             :     {
      30       55684 :         std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
      31       55684 :         data.insert(data.end(), id.begin(), id.end());
      32       55684 :         return EncodeBase58Check(data);
      33       55684 :     }
      34             : 
      35       13704 :     std::string operator()(const ScriptHash& id) const
      36             :     {
      37       13704 :         std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
      38       13704 :         data.insert(data.end(), id.begin(), id.end());
      39       13704 :         return EncodeBase58Check(data);
      40       13704 :     }
      41             : 
      42       41258 :     std::string operator()(const WitnessV0KeyHash& id) const
      43             :     {
      44       41258 :         std::vector<unsigned char> data = {0};
      45       41258 :         data.reserve(33);
      46     1361514 :         ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
      47       41258 :         return bech32::Encode(m_params.Bech32HRP(), data);
      48       41258 :     }
      49             : 
      50         904 :     std::string operator()(const WitnessV0ScriptHash& id) const
      51             :     {
      52         904 :         std::vector<unsigned char> data = {0};
      53         904 :         data.reserve(53);
      54       47912 :         ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
      55         904 :         return bech32::Encode(m_params.Bech32HRP(), data);
      56         904 :     }
      57             : 
      58          22 :     std::string operator()(const WitnessUnknown& id) const
      59             :     {
      60          22 :         if (id.version < 1 || id.version > 16 || id.length < 2 || id.length > 40) {
      61           0 :             return {};
      62             :         }
      63          22 :         std::vector<unsigned char> data = {(unsigned char)id.version};
      64          22 :         data.reserve(1 + (id.length * 8 + 4) / 5);
      65         558 :         ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.program, id.program + id.length);
      66          22 :         return bech32::Encode(m_params.Bech32HRP(), data);
      67          22 :     }
      68             : 
      69           0 :     std::string operator()(const CNoDestination& no) const { return {}; }
      70             : };
      71             : 
      72       22750 : CTxDestination DecodeDestination(const std::string& str, const CChainParams& params)
      73             : {
      74       22750 :     std::vector<unsigned char> data;
      75       22750 :     uint160 hash;
      76       22750 :     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        5460 :         const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
      81        5460 :         if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
      82        3491 :             std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
      83        3491 :             return PKHash(hash);
      84             :         }
      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        1969 :         const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
      88        1969 :         if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
      89        1944 :             std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
      90        1944 :             return ScriptHash(hash);
      91             :         }
      92          25 :     }
      93       17315 :     data.clear();
      94       17315 :     auto bech = bech32::Decode(str);
      95       17315 :     if (bech.second.size() > 0 && bech.first == params.Bech32HRP()) {
      96             :         // Bech32 decoding
      97       17027 :         int version = bech.second[0]; // The first 5 bit symbol is the witness version (0-16)
      98             :         // The rest of the symbols are converted witness program bytes.
      99       17027 :         data.reserve(((bech.second.size() - 1) * 5) / 8);
     100      367131 :         if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin() + 1, bech.second.end())) {
     101       17025 :             if (version == 0) {
     102             :                 {
     103       16999 :                     WitnessV0KeyHash keyid;
     104       16999 :                     if (data.size() == keyid.size()) {
     105       16195 :                         std::copy(data.begin(), data.end(), keyid.begin());
     106       16195 :                         return keyid;
     107             :                     }
     108       16999 :                 }
     109             :                 {
     110         804 :                     WitnessV0ScriptHash scriptid;
     111         804 :                     if (data.size() == scriptid.size()) {
     112         803 :                         std::copy(data.begin(), data.end(), scriptid.begin());
     113         803 :                         return scriptid;
     114             :                     }
     115         804 :                 }
     116           1 :                 return CNoDestination();
     117             :             }
     118          26 :             if (version > 16 || data.size() < 2 || data.size() > 40) {
     119           7 :                 return CNoDestination();
     120             :             }
     121          19 :             WitnessUnknown unk;
     122          19 :             unk.version = version;
     123          19 :             std::copy(data.begin(), data.end(), unk.program);
     124          19 :             unk.length = data.size();
     125          19 :             return unk;
     126          19 :         }
     127           2 :     }
     128         290 :     return CNoDestination();
     129       22750 : }
     130             : } // namespace
     131             : 
     132        2787 : CKey DecodeSecret(const std::string& str)
     133             : {
     134        2787 :     CKey key;
     135        2787 :     std::vector<unsigned char> data;
     136        2787 :     if (DecodeBase58Check(str, data, 34)) {
     137        1736 :         const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
     138        3435 :         if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
     139        1699 :             std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
     140        1681 :             bool compressed = data.size() == 33 + privkey_prefix.size();
     141        1681 :             key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
     142        1681 :         }
     143        1736 :     }
     144        2787 :     if (!data.empty()) {
     145        1736 :         memory_cleanse(data.data(), data.size());
     146             :     }
     147             :     return key;
     148        2787 : }
     149             : 
     150        1586 : std::string EncodeSecret(const CKey& key)
     151             : {
     152        1586 :     assert(key.IsValid());
     153        1586 :     std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
     154        1586 :     data.insert(data.end(), key.begin(), key.end());
     155        1586 :     if (key.IsCompressed()) {
     156        1560 :         data.push_back(1);
     157        1560 :     }
     158        1586 :     std::string ret = EncodeBase58Check(data);
     159        1586 :     memory_cleanse(data.data(), data.size());
     160             :     return ret;
     161        1586 : }
     162             : 
     163         588 : CExtPubKey DecodeExtPubKey(const std::string& str)
     164             : {
     165         588 :     CExtPubKey key;
     166         588 :     std::vector<unsigned char> data;
     167         588 :     if (DecodeBase58Check(str, data, 78)) {
     168         587 :         const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
     169         587 :         if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
     170         464 :             key.Decode(data.data() + prefix.size());
     171             :         }
     172         587 :     }
     173             :     return key;
     174         588 : }
     175             : 
     176       18620 : std::string EncodeExtPubKey(const CExtPubKey& key)
     177             : {
     178       18620 :     std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
     179       18620 :     size_t size = data.size();
     180       18620 :     data.resize(size + BIP32_EXTKEY_SIZE);
     181       18620 :     key.Encode(data.data() + size);
     182       18620 :     std::string ret = EncodeBase58Check(data);
     183             :     return ret;
     184       18620 : }
     185             : 
     186         588 : CExtKey DecodeExtKey(const std::string& str)
     187             : {
     188         588 :     CExtKey key;
     189         588 :     std::vector<unsigned char> data;
     190         588 :     if (DecodeBase58Check(str, data, 78)) {
     191         587 :         const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
     192         587 :         if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
     193         137 :             key.Decode(data.data() + prefix.size());
     194             :         }
     195         587 :     }
     196             :     return key;
     197         588 : }
     198             : 
     199         125 : std::string EncodeExtKey(const CExtKey& key)
     200             : {
     201         125 :     std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
     202         125 :     size_t size = data.size();
     203         125 :     data.resize(size + BIP32_EXTKEY_SIZE);
     204         125 :     key.Encode(data.data() + size);
     205         125 :     std::string ret = EncodeBase58Check(data);
     206         125 :     memory_cleanse(data.data(), data.size());
     207             :     return ret;
     208         125 : }
     209             : 
     210      111572 : std::string EncodeDestination(const CTxDestination& dest)
     211             : {
     212      111572 :     return boost::apply_visitor(DestinationEncoder(Params()), dest);
     213             : }
     214             : 
     215       22420 : CTxDestination DecodeDestination(const std::string& str)
     216             : {
     217       22420 :     return DecodeDestination(str, Params());
     218             : }
     219             : 
     220         330 : bool IsValidDestinationString(const std::string& str, const CChainParams& params)
     221             : {
     222         330 :     return IsValidDestination(DecodeDestination(str, params));
     223           0 : }
     224             : 
     225         330 : bool IsValidDestinationString(const std::string& str)
     226             : {
     227         330 :     return IsValidDestinationString(str, Params());
     228             : }

Generated by: LCOV version 1.15