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