Bitcoin Core 31.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-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#include <bech32.h>
7#include <util/strencodings.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 std::string(100, 'q'),
75 };
76 static const std::pair<std::string, std::vector<int>> ERRORS[] = {
77 {"Invalid character or mixed case", {0}},
78 {"Invalid character or mixed case", {0}},
79 {"Invalid character or mixed case", {0}},
80 {"Bech32 string too long", {90}},
81 {"Missing separator", {}},
82 {"Invalid separator position", {0}},
83 {"Invalid Base 32 character", {2}},
84 {"Invalid separator position", {2}},
85 {"Invalid character or mixed case", {8}},
86 {"Invalid checksum", {}}, // The checksum is calculated using the uppercase form so the entire string is invalid, not just a few characters
87 {"Invalid separator position", {0}},
88 {"Invalid separator position", {0}},
89 {"Invalid character or mixed case", {3, 4, 5, 7}},
90 {"Invalid character or mixed case", {3}},
91 {"Invalid Bech32 checksum", {11}},
92 {"Invalid Bech32 checksum", {9, 16}},
93 {"Bech32 string too long", {90}},
94 };
95 static_assert(std::size(CASES) == std::size(ERRORS), "Bech32 CASES and ERRORS should have the same length");
96
97 int i = 0;
98 for (const std::string& str : CASES) {
99 const auto& err = ERRORS[i];
100 const auto dec = bech32::Decode(str);
101 BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
102 auto [error, error_locations] = bech32::LocateErrors(str);
103 BOOST_CHECK_EQUAL(err.first, error);
104 BOOST_CHECK(err.second == error_locations);
105 i++;
106 }
107}
108
109BOOST_AUTO_TEST_CASE(bech32m_testvectors_invalid)
110{
111 static const std::string CASES[] = {
112 " 1xj0phk",
113 "\x7f""1g6xzxy",
114 "\x80""1vctc34",
115 "an84characterslonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11d6pts4",
116 "qyrz8wqd2c9m",
117 "1qyrz8wqd2c9m",
118 "y1b0jsk6g",
119 "lt1igcx5c0",
120 "in1muywd",
121 "mm1crxm3i",
122 "au1s5cgom",
123 "M1VUXWEZ",
124 "16plkw9",
125 "1p2gdwpf",
126 "abcdef1l7aum6echk45nj2s0wdvt2fg8x9yrzpqzd3ryx",
127 "test1zg69v7y60n00qy352euf40x77qcusag6",
128 };
129 static const std::pair<std::string, std::vector<int>> ERRORS[] = {
130 {"Invalid character or mixed case", {0}},
131 {"Invalid character or mixed case", {0}},
132 {"Invalid character or mixed case", {0}},
133 {"Bech32 string too long", {90}},
134 {"Missing separator", {}},
135 {"Invalid separator position", {0}},
136 {"Invalid Base 32 character", {2}},
137 {"Invalid Base 32 character", {3}},
138 {"Invalid separator position", {2}},
139 {"Invalid Base 32 character", {8}},
140 {"Invalid Base 32 character", {7}},
141 {"Invalid checksum", {}},
142 {"Invalid separator position", {0}},
143 {"Invalid separator position", {0}},
144 {"Invalid Bech32m checksum", {21}},
145 {"Invalid Bech32m checksum", {13, 32}},
146 };
147 static_assert(std::size(CASES) == std::size(ERRORS), "Bech32m CASES and ERRORS should have the same length");
148
149 int i = 0;
150 for (const std::string& str : CASES) {
151 const auto& err = ERRORS[i];
152 const auto dec = bech32::Decode(str);
153 BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
154 auto [error, error_locations] = bech32::LocateErrors(str);
155 BOOST_CHECK_EQUAL(err.first, error);
156 BOOST_CHECK(err.second == error_locations);
157 i++;
158 }
159}
160
BOOST_AUTO_TEST_CASE(bech32_testvectors_valid)
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
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:402
@ 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:373
std::string Encode(Encoding encoding, const std::string &hrp, const data &values)
Encode a Bech32 or Bech32m string.
Definition: bech32.cpp:357
#define BOOST_CHECK(expr)
Definition: object.cpp:16
bool CaseInsensitiveEqual(std::string_view s1, std::string_view s2)
Locale-independent, ASCII-only comparator.