Bitcoin Core  22.99.0
P2P Digital Currency
bech32_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 Pieter Wuille
2 // Copyright (c) 2021 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 #include <bech32.h>
7 #include <test/util/str.h>
8 
9 #include <boost/test/unit_test.hpp>
10 
11 #include <string>
12 
13 BOOST_AUTO_TEST_SUITE(bech32_tests)
14 
15 BOOST_AUTO_TEST_CASE(bech32_testvectors_valid)
16 {
17  static const std::string CASES[] = {
18  "A12UEL5L",
19  "a12uel5l",
20  "an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",
21  "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
22  "11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
23  "split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w",
24  "?1ezyfcl",
25  };
26  for (const std::string& str : CASES) {
27  const auto dec = bech32::Decode(str);
28  BOOST_CHECK(dec.encoding == bech32::Encoding::BECH32);
29  std::string recode = bech32::Encode(bech32::Encoding::BECH32, dec.hrp, dec.data);
30  BOOST_CHECK(!recode.empty());
31  BOOST_CHECK(CaseInsensitiveEqual(str, recode));
32  }
33 }
34 
35 BOOST_AUTO_TEST_CASE(bech32m_testvectors_valid)
36 {
37  static const std::string CASES[] = {
38  "A1LQFN3A",
39  "a1lqfn3a",
40  "an83characterlonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11sg7hg6",
41  "abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx",
42  "11llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllludsr8",
43  "split1checkupstagehandshakeupstreamerranterredcaperredlc445v",
44  "?1v759aa"
45  };
46  for (const std::string& str : CASES) {
47  const auto dec = bech32::Decode(str);
48  BOOST_CHECK(dec.encoding == bech32::Encoding::BECH32M);
49  std::string recode = bech32::Encode(bech32::Encoding::BECH32M, dec.hrp, dec.data);
50  BOOST_CHECK(!recode.empty());
51  BOOST_CHECK(CaseInsensitiveEqual(str, recode));
52  }
53 }
54 
55 BOOST_AUTO_TEST_CASE(bech32_testvectors_invalid)
56 {
57  static const std::string CASES[] = {
58  " 1nwldj5",
59  "\x7f""1axkwrx",
60  "\x80""1eym55h",
61  "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",
62  "pzry9x0s0muk",
63  "1pzry9x0s0muk",
64  "x1b4n0q5v",
65  "li1dgmt3",
66  "de1lg7wt\xff",
67  "A1G7SGD8",
68  "10a06t8",
69  "1qzzfhee",
70  "a12UEL5L",
71  "A12uEL5L",
72  "abcdef1qpzrz9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
73  "test1zg69w7y6hn0aqy352euf40x77qddq3dc",
74  };
75  static const std::pair<std::string, std::vector<int>> ERRORS[] = {
76  {"Invalid character or mixed case", {0}},
77  {"Invalid character or mixed case", {0}},
78  {"Invalid character or mixed case", {0}},
79  {"Bech32 string too long", {90}},
80  {"Missing separator", {}},
81  {"Invalid separator position", {0}},
82  {"Invalid Base 32 character", {2}},
83  {"Invalid separator position", {2}},
84  {"Invalid character or mixed case", {8}},
85  {"Invalid checksum", {}}, // The checksum is calculated using the uppercase form so the entire string is invalid, not just a few characters
86  {"Invalid separator position", {0}},
87  {"Invalid separator position", {0}},
88  {"Invalid character or mixed case", {3, 4, 5, 7}},
89  {"Invalid character or mixed case", {3}},
90  {"Invalid Bech32 checksum", {11}},
91  {"Invalid Bech32 checksum", {9, 16}},
92  };
93  static_assert(std::size(CASES) == std::size(ERRORS), "Bech32 CASES and ERRORS should have the same length");
94 
95  int i = 0;
96  for (const std::string& str : CASES) {
97  const auto& err = ERRORS[i];
98  const auto dec = bech32::Decode(str);
99  BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
100  auto [error, error_locations] = bech32::LocateErrors(str);
101  BOOST_CHECK_EQUAL(err.first, error);
102  BOOST_CHECK(err.second == error_locations);
103  i++;
104  }
105 }
106 
107 BOOST_AUTO_TEST_CASE(bech32m_testvectors_invalid)
108 {
109  static const std::string CASES[] = {
110  " 1xj0phk",
111  "\x7f""1g6xzxy",
112  "\x80""1vctc34",
113  "an84characterslonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11d6pts4",
114  "qyrz8wqd2c9m",
115  "1qyrz8wqd2c9m",
116  "y1b0jsk6g",
117  "lt1igcx5c0",
118  "in1muywd",
119  "mm1crxm3i",
120  "au1s5cgom",
121  "M1VUXWEZ",
122  "16plkw9",
123  "1p2gdwpf",
124  "abcdef1l7aum6echk45nj2s0wdvt2fg8x9yrzpqzd3ryx",
125  "test1zg69v7y60n00qy352euf40x77qcusag6",
126  };
127  static const std::pair<std::string, std::vector<int>> ERRORS[] = {
128  {"Invalid character or mixed case", {0}},
129  {"Invalid character or mixed case", {0}},
130  {"Invalid character or mixed case", {0}},
131  {"Bech32 string too long", {90}},
132  {"Missing separator", {}},
133  {"Invalid separator position", {0}},
134  {"Invalid Base 32 character", {2}},
135  {"Invalid Base 32 character", {3}},
136  {"Invalid separator position", {2}},
137  {"Invalid Base 32 character", {8}},
138  {"Invalid Base 32 character", {7}},
139  {"Invalid checksum", {}},
140  {"Invalid separator position", {0}},
141  {"Invalid separator position", {0}},
142  {"Invalid Bech32m checksum", {21}},
143  {"Invalid Bech32m checksum", {13, 32}},
144  };
145  static_assert(std::size(CASES) == std::size(ERRORS), "Bech32m CASES and ERRORS should have the same length");
146 
147  int i = 0;
148  for (const std::string& str : CASES) {
149  const auto& err = ERRORS[i];
150  const auto dec = bech32::Decode(str);
151  BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
152  auto [error, error_locations] = bech32::LocateErrors(str);
153  BOOST_CHECK_EQUAL(err.first, error);
154  BOOST_CHECK(err.second == error_locations);
155  i++;
156  }
157 }
158 
str.h
BOOST_AUTO_TEST_SUITE
BOOST_AUTO_TEST_SUITE(cuckoocache_tests)
Test Suite for CuckooCache.
bech32::Decode
DecodeResult Decode(const std::string &str)
Decode a Bech32 or Bech32m string.
Definition: bech32.cpp:372
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(bech32_testvectors_valid)
Definition: bech32_tests.cpp:15
bech32::Encoding::BECH32
@ BECH32
Bech32 encoding as defined in BIP173.
bech32::Encoding::INVALID
@ INVALID
Failed decoding.
CaseInsensitiveEqual
bool CaseInsensitiveEqual(const std::string &s1, const std::string &s2)
Definition: str.cpp:10
bech32::LocateErrors
std::pair< std::string, std::vector< int > > LocateErrors(const std::string &str)
Find index of an incorrect character in a Bech32 string.
Definition: bech32.cpp:399
bech32::Encoding::BECH32M
@ BECH32M
Bech32m encoding as defined in BIP350.
bech32.h
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
bech32::Encode
std::string Encode(Encoding encoding, const std::string &hrp, const data &values)
Encode a Bech32 or Bech32m string.
Definition: bech32.cpp:356
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition: object.cpp:17
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18