1 // Copyright (c) 2017, 2021 Pieter Wuille
2 // Copyright (c) 2021 The Limenka 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 LIMENKA_BECH32_H
15 #define LIMENKA_BECH32_H
16 17 #include <stdint.h>
18 #include <string>
19 #include <vector>
20 21 namespace bech32
22 {
23 24 static constexpr size_t CHECKSUM_SIZE = 6;
25 static constexpr char SEPARATOR = '1';
26 27 enum class Encoding {
28 INVALID, //!< Failed decoding
29 30 BECH32, //!< Bech32 encoding as defined in BIP173
31 BECH32M, //!< Bech32m encoding as defined in BIP350
32 };
33 34 /** Character limits for Bech32(m) encoded strings. Character limits are how we provide error location guarantees.
35 * These values should never exceed 2^31 - 1 (max value for a 32-bit int), since there are places where we may need to
36 * convert the CharLimit::VALUE to an int. In practice, this should never happen since this CharLimit applies to an address encoding
37 * and we would never encode an address with such a massive value */
38 enum CharLimit : size_t {
39 BECH32 = 90, //!< BIP173/350 imposed character limit for Bech32(m) encoded addresses. This guarantees finding up to 4 errors.
40 CODEX32 = 127,
41 };
42 43 /** Encode a Bech32 or Bech32m string. If hrp contains uppercase characters, this will cause an
44 * assertion error. Encoding must be one of BECH32 or BECH32M. */
45 std::string Encode(Encoding encoding, const std::string& hrp, const std::vector<uint8_t>& values);
46 47 struct DecodeResult
48 {
49 Encoding encoding; //!< What encoding was detected in the result; Encoding::INVALID if failed.
50 std::string hrp; //!< The human readable part
51 std::vector<uint8_t> data; //!< The payload (excluding checksum)
52 53 DecodeResult() : encoding(Encoding::INVALID) {}
54 DecodeResult(Encoding enc, std::string&& h, std::vector<uint8_t>&& d) : encoding(enc), hrp(std::move(h)), data(std::move(d)) {}
55 };
56 57 /** Decode a Bech32 or Bech32m string. */
58 DecodeResult Decode(const std::string& str, CharLimit limit = CharLimit::BECH32);
59 60 /** Return the positions of errors in a Bech32 string. */
61 std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str, CharLimit limit = CharLimit::BECH32);
62 63 // The internal namespace is used for things shared between bech32(m) and codex32.
64 // These functions should not be used except by other hrpstring-encoded codes.
65 namespace internal {
66 typedef std::vector<uint8_t> data;
67 68 extern const char* CHARSET;
69 extern const int8_t CHARSET_REV[128];
70 71 std::vector<unsigned char> PreparePolynomialCoefficients(const std::string& hrp, const data& values);
72 73 /** Encode a hrpstring without concerning ourselves with checksum validity */
74 std::string Encode(const std::string& hrp, const data& values, const data& checksum);
75 76 /** Decode a hrpstring without concerning ourselves with checksum validity */
77 std::pair<std::string, data> Decode(const std::string& str, CharLimit limit, size_t checksum_length);
78 79 } // namespace internal
80 81 } // namespace bech32
82 83 #endif // LIMENKA_BECH32_H
84