bech32.h raw

   1  // Copyright (c) 2017, 2021 Pieter Wuille
   2  // Copyright (c) 2021-present The Bitcoin Core developers
   3  // Distributed under the MIT software license, see the accompanying
   4  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  
   6  // Bech32 and Bech32m are string encoding formats used in newer
   7  // address types. The outputs consist of a human-readable part
   8  // (alphanumeric), a separator character (1), and a base32 data
   9  // section, the last 6 characters of which are a checksum. The
  10  // module is namespaced under bech32 for historical reasons.
  11  //
  12  // For more information, see BIP 173 and BIP 350.
  13  
  14  #ifndef BITCOIN_BECH32_H
  15  #define BITCOIN_BECH32_H
  16  
  17  #include <cstddef>
  18  #include <cstdint>
  19  #include <string>
  20  #include <utility>
  21  #include <vector>
  22  
  23  namespace bech32
  24  {
  25  
  26  static constexpr size_t CHECKSUM_SIZE = 6;
  27  static constexpr char SEPARATOR = '1';
  28  
  29  enum class Encoding {
  30      INVALID, //!< Failed decoding
  31  
  32      BECH32,  //!< Bech32 encoding as defined in BIP173
  33      BECH32M, //!< Bech32m encoding as defined in BIP350
  34  };
  35  
  36  /** Character limits for Bech32(m) encoded strings. Character limits are how we provide error location guarantees.
  37   *  These values should never exceed 2^31 - 1 (max value for a 32-bit int), since there are places where we may need to
  38   *  convert the CharLimit::VALUE to an int. In practice, this should never happen since this CharLimit applies to an address encoding
  39   *  and we would never encode an address with such a massive value */
  40  enum CharLimit : size_t {
  41      BECH32 = 90,            //!< BIP173/350 imposed character limit for Bech32(m) encoded addresses. This guarantees finding up to 4 errors.
  42  };
  43  
  44  /** Encode a Bech32 or Bech32m string. If hrp contains uppercase characters, this will cause an
  45   *  assertion error. Encoding must be one of BECH32 or BECH32M. */
  46  std::string Encode(Encoding encoding, const std::string& hrp, const std::vector<uint8_t>& values);
  47  
  48  struct DecodeResult
  49  {
  50      Encoding encoding;         //!< What encoding was detected in the result; Encoding::INVALID if failed.
  51      std::string hrp;           //!< The human readable part
  52      std::vector<uint8_t> data; //!< The payload (excluding checksum)
  53  
  54      DecodeResult() : encoding(Encoding::INVALID) {}
  55      DecodeResult(Encoding enc, std::string&& h, std::vector<uint8_t>&& d) : encoding(enc), hrp(std::move(h)), data(std::move(d)) {}
  56  };
  57  
  58  /** Decode a Bech32 or Bech32m string. */
  59  DecodeResult Decode(const std::string& str, CharLimit limit = CharLimit::BECH32);
  60  
  61  /** Return the positions of errors in a Bech32 string. */
  62  std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str, CharLimit limit = CharLimit::BECH32);
  63  
  64  } // namespace bech32
  65  
  66  #endif // BITCOIN_BECH32_H
  67