Bitcoin Core 28.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
13BOOST_AUTO_TEST_SUITE(bech32_tests)
14
15BOOST_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);
29 std::string recode = bech32::Encode(bech32::Encoding::BECH32, dec.hrp, dec.data);
30 BOOST_CHECK(!recode.empty());
32 }
33}
34
35BOOST_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);
49 std::string recode = bech32::Encode(bech32::Encoding::BECH32M, dec.hrp, dec.data);
50 BOOST_CHECK(!recode.empty());
52 }
53}
54
55BOOST_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);
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
107BOOST_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
BOOST_AUTO_TEST_CASE(bech32_testvectors_valid)
BOOST_AUTO_TEST_SUITE_END()
std::pair< std::string, std::vector< int > > LocateErrors(const std::string &str, CharLimit limit)
Find index of an incorrect character in a Bech32 string.
Definition: bech32.cpp:403
@ INVALID
Failed decoding.
@ BECH32
Bech32 encoding as defined in BIP173.
@ BECH32M
Bech32m encoding as defined in BIP350.
DecodeResult Decode(const std::string &str, CharLimit limit)
Decode a Bech32 or Bech32m string.
Definition: bech32.cpp:374
std::string Encode(Encoding encoding, const std::string &hrp, const data &values)
Encode a Bech32 or Bech32m string.
Definition: bech32.cpp:358
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
bool CaseInsensitiveEqual(const std::string &s1, const std::string &s2)
Definition: str.cpp:10