key_io.cpp raw

   1  // Copyright (c) 2014-2021 The Limenka 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 <assert.h>
  16  #include <string.h>
  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 WitnessV3SpkHash& id) const
  69      {
  70          // HRP "lm1": the prefix identifies the type, so no version byte.
  71          std::vector<unsigned char> data;
  72          data.reserve(53);
  73          ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
  74          return bech32::Encode(bech32::Encoding::BECH32M, "lm1", data);
  75      }
  76  
  77      std::string operator()(const WitnessV4StealthAddress& id) const
  78      {
  79          // HRP "lm2": 66-byte payload (view 33 || spend 33).
  80          std::vector<unsigned char> data;
  81          data.reserve(110);
  82          data.insert(data.end(), id.view.begin(), id.view.end());
  83          data.insert(data.end(), id.spend.begin(), id.spend.end());
  84          std::vector<unsigned char> converted;
  85          converted.reserve(110);
  86          ConvertBits<8, 5, true>([&](unsigned char c) { converted.push_back(c); }, data.begin(), data.end());
  87          return bech32::Encode(bech32::Encoding::BECH32M, "lm2", converted);
  88      }
  89  
  90      std::string operator()(const WitnessUnknown& id) const
  91      {
  92          const std::vector<unsigned char>& program = id.GetWitnessProgram();
  93          if (id.GetWitnessVersion() < 1 || id.GetWitnessVersion() > 16 || program.size() < 2 || program.size() > 40) {
  94              return {};
  95          }
  96          std::vector<unsigned char> data = {(unsigned char)id.GetWitnessVersion()};
  97          data.reserve(1 + (program.size() * 8 + 4) / 5);
  98          ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, program.begin(), program.end());
  99          return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
 100      }
 101  
 102      std::string operator()(const CNoDestination& no) const { return {}; }
 103      std::string operator()(const PubKeyDestination& pk) const { return {}; }
 104  };
 105  
 106  CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, std::string& error_str, std::vector<int>* error_locations)
 107  {
 108      std::vector<unsigned char> data;
 109      uint160 hash;
 110      error_str = "";
 111  
 112      // Fixed-HRP formats: lm1 (P2SPKH), lm2 (P2BPCT stealth).  These are
 113      // chain-independent and handled before the chain-specific HRP check.
 114      // lm2 carries 66 bytes (~117 chars), so it decodes under CODEX32.
 115      {
 116          const auto dec = bech32::Decode(str, (ToLower(str.substr(0, 3)) == "lm2") ? bech32::CharLimit::CODEX32 : bech32::CharLimit::BECH32);
 117          if (dec.encoding == bech32::Encoding::BECH32M && !dec.data.empty()) {
 118              if (dec.hrp == "lm1") {
 119                  std::vector<unsigned char> payload;
 120                  payload.reserve(((dec.data.size()) * 5) / 8);
 121                  if (ConvertBits<5, 8, false>([&](unsigned char c) { payload.push_back(c); },
 122                                               dec.data.begin(), dec.data.end()) &&
 123                      payload.size() == WITNESS_V3_SPKHASH_SIZE) {
 124                      WitnessV3SpkHash hash;
 125                      std::copy(payload.begin(), payload.end(), hash.begin());
 126                      return hash;
 127                  }
 128                  error_str = "Invalid lm1 (P2SPKH) address payload size";
 129                  return CNoDestination();
 130              }
 131              if (dec.hrp == "lm2" && dec.encoding == bech32::Encoding::BECH32M) {
 132                  std::vector<unsigned char> payload;
 133                  payload.reserve(((dec.data.size()) * 5) / 8);
 134                  if (ConvertBits<5, 8, false>([&](unsigned char c) { payload.push_back(c); },
 135                                               dec.data.begin(), dec.data.end()) &&
 136                      payload.size() == 66) {
 137                      CPubKey view(payload.begin(), payload.begin() + 33);
 138                      CPubKey spend(payload.begin() + 33, payload.end());
 139                      if (view.IsFullyValid() && spend.IsFullyValid()) {
 140                          return WitnessV4StealthAddress{view, spend};
 141                      }
 142                      error_str = "Invalid lm2 (P2BPCT stealth) address keys";
 143                      return CNoDestination();
 144                  }
 145                  error_str = "Invalid lm2 (P2BPCT stealth) address payload size";
 146                  return CNoDestination();
 147              }
 148          }
 149      }
 150  
 151  
 152  
 153      // Note this will be false if it is a valid Bech32 address for a different network
 154      bool is_bech32 = (ToLower(str.substr(0, params.Bech32HRP().size())) == params.Bech32HRP());
 155  
 156      if (!is_bech32 && DecodeBase58Check(str, data, 21)) {
 157          // base58-encoded Limenka addresses.
 158          // Public-key-hash-addresses have version 0 (or 111 testnet).
 159          // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
 160          const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
 161          if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
 162              std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
 163              return PKHash(hash);
 164          }
 165          // Script-hash-addresses have version 5 (or 196 testnet).
 166          // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
 167          const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
 168          if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
 169              std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
 170              return ScriptHash(hash);
 171          }
 172  
 173          // If the prefix of data matches either the script or pubkey prefix, the length must have been wrong
 174          if ((data.size() >= script_prefix.size() &&
 175                  std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) ||
 176              (data.size() >= pubkey_prefix.size() &&
 177                  std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin()))) {
 178              error_str = "Invalid length for Base58 address (P2PKH or P2SH)";
 179          } else {
 180              error_str = "Invalid or unsupported Base58-encoded address.";
 181          }
 182          return CNoDestination();
 183      } else if (!is_bech32) {
 184          // Try Base58 decoding without the checksum, using a much larger max length
 185          if (!DecodeBase58(str, data, 100)) {
 186              error_str = "Invalid or unsupported Segwit (Bech32) or Base58 encoding.";
 187          } else {
 188              error_str = "Invalid checksum or length of Base58 address (P2PKH or P2SH)";
 189          }
 190          return CNoDestination();
 191      }
 192  
 193      data.clear();
 194      const auto dec = bech32::Decode(str);
 195      if (dec.encoding == bech32::Encoding::BECH32 || dec.encoding == bech32::Encoding::BECH32M) {
 196          if (dec.data.empty()) {
 197              error_str = "Empty Bech32 data section";
 198              return CNoDestination();
 199          }
 200          // Bech32 decoding
 201          if (dec.hrp != params.Bech32HRP()) {
 202              error_str = strprintf("Invalid or unsupported prefix for Segwit (Bech32) address (expected %s, got %s).", params.Bech32HRP(), dec.hrp);
 203              return CNoDestination();
 204          }
 205          int version = dec.data[0]; // The first 5 bit symbol is the witness version (0-16)
 206          if (version == 0 && dec.encoding != bech32::Encoding::BECH32) {
 207              error_str = "Version 0 witness address must use Bech32 checksum";
 208              return CNoDestination();
 209          }
 210          if (version != 0 && dec.encoding != bech32::Encoding::BECH32M) {
 211              error_str = "Version 1+ witness address must use Bech32m checksum";
 212              return CNoDestination();
 213          }
 214          // The rest of the symbols are converted witness program bytes.
 215          data.reserve(((dec.data.size() - 1) * 5) / 8);
 216          if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, dec.data.begin() + 1, dec.data.end())) {
 217  
 218              std::string_view byte_str{data.size() == 1 ? "byte" : "bytes"};
 219  
 220              if (version == 0) {
 221                  {
 222                      WitnessV0KeyHash keyid;
 223                      if (data.size() == keyid.size()) {
 224                          std::copy(data.begin(), data.end(), keyid.begin());
 225                          return keyid;
 226                      }
 227                  }
 228                  {
 229                      WitnessV0ScriptHash scriptid;
 230                      if (data.size() == scriptid.size()) {
 231                          std::copy(data.begin(), data.end(), scriptid.begin());
 232                          return scriptid;
 233                      }
 234                  }
 235  
 236                  error_str = strprintf("Invalid Bech32 v0 address program size (%d %s), per BIP141", data.size(), byte_str);
 237                  return CNoDestination();
 238              }
 239  
 240              if (version == 1 && data.size() == WITNESS_V1_TAPROOT_SIZE) {
 241                  static_assert(WITNESS_V1_TAPROOT_SIZE == WitnessV1Taproot::size());
 242                  WitnessV1Taproot tap;
 243                  std::copy(data.begin(), data.end(), tap.begin());
 244                  return tap;
 245              }
 246  
 247              if (version == 3 && data.size() == WITNESS_V3_SPKHASH_SIZE) {
 248                  WitnessV3SpkHash hash;
 249                  std::copy(data.begin(), data.end(), hash.begin());
 250                  return hash;
 251              }
 252  
 253              if (CScript::IsPayToAnchor(version, data)) {
 254                  return PayToAnchor();
 255              }
 256  
 257              if (version > 16) {
 258                  error_str = "Invalid Bech32 address witness version";
 259                  return CNoDestination();
 260              }
 261  
 262              if (data.size() < 2 || data.size() > BECH32_WITNESS_PROG_MAX_LEN) {
 263                  error_str = strprintf("Invalid Bech32 address program size (%d %s)", data.size(), byte_str);
 264                  return CNoDestination();
 265              }
 266  
 267              return WitnessUnknown{version, data};
 268          } else {
 269              error_str = strprintf("Invalid padding in Bech32 data section");
 270              return CNoDestination();
 271          }
 272      }
 273  
 274      // Perform Bech32 error location
 275      auto res = bech32::LocateErrors(str);
 276      error_str = res.first;
 277      if (error_locations) *error_locations = std::move(res.second);
 278      return CNoDestination();
 279  }
 280  } // namespace
 281  
 282  CKey DecodeSecret(const std::string& str)
 283  {
 284      CKey key;
 285      std::vector<unsigned char> data;
 286      if (DecodeBase58Check(str, data, 34)) {
 287          const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
 288          if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
 289              std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
 290              bool compressed = data.size() == 33 + privkey_prefix.size();
 291              key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
 292          }
 293      }
 294      if (!data.empty()) {
 295          memory_cleanse(data.data(), data.size());
 296      }
 297      return key;
 298  }
 299  
 300  std::string EncodeSecret(const CKey& key)
 301  {
 302      assert(key.IsValid());
 303      std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
 304      data.insert(data.end(), UCharCast(key.begin()), UCharCast(key.end()));
 305      if (key.IsCompressed()) {
 306          data.push_back(1);
 307      }
 308      std::string ret = EncodeBase58Check(data);
 309      memory_cleanse(data.data(), data.size());
 310      return ret;
 311  }
 312  
 313  CExtPubKey DecodeExtPubKey(const std::string& str)
 314  {
 315      CExtPubKey key;
 316      std::vector<unsigned char> data;
 317      if (DecodeBase58Check(str, data, 78)) {
 318          const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
 319          if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
 320              key.Decode(data.data() + prefix.size());
 321          }
 322      }
 323      return key;
 324  }
 325  
 326  std::string EncodeExtPubKey(const CExtPubKey& key)
 327  {
 328      std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
 329      size_t size = data.size();
 330      data.resize(size + BIP32_EXTKEY_SIZE);
 331      key.Encode(data.data() + size);
 332      std::string ret = EncodeBase58Check(data);
 333      return ret;
 334  }
 335  
 336  CExtKey DecodeExtKey(const std::string& str)
 337  {
 338      CExtKey key;
 339      std::vector<unsigned char> data;
 340      if (DecodeBase58Check(str, data, 78)) {
 341          const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
 342          if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
 343              key.Decode(data.data() + prefix.size());
 344          }
 345      }
 346      if (!data.empty()) {
 347          memory_cleanse(data.data(), data.size());
 348      }
 349      return key;
 350  }
 351  
 352  std::string EncodeExtKey(const CExtKey& key)
 353  {
 354      std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
 355      size_t size = data.size();
 356      data.resize(size + BIP32_EXTKEY_SIZE);
 357      key.Encode(data.data() + size);
 358      std::string ret = EncodeBase58Check(data);
 359      memory_cleanse(data.data(), data.size());
 360      return ret;
 361  }
 362  
 363  std::string EncodeDestination(const CTxDestination& dest)
 364  {
 365      return std::visit(DestinationEncoder(Params()), dest);
 366  }
 367  
 368  CTxDestination DecodeDestination(const std::string& str, std::string& error_msg, std::vector<int>* error_locations)
 369  {
 370      return DecodeDestination(str, Params(), error_msg, error_locations);
 371  }
 372  
 373  CTxDestination DecodeDestination(const std::string& str)
 374  {
 375      std::string error_msg;
 376      return DecodeDestination(str, error_msg);
 377  }
 378  
 379  bool IsValidDestinationString(const std::string& str, const CChainParams& params)
 380  {
 381      std::string error_msg;
 382      return IsValidDestination(DecodeDestination(str, params, error_msg, nullptr));
 383  }
 384  
 385  bool IsValidDestinationString(const std::string& str)
 386  {
 387      return IsValidDestinationString(str, Params());
 388  }
 389