PageRenderTime 125ms CodeModel.GetById 5ms RepoModel.GetById 1ms app.codeStats 0ms

/src/test/bech32_tests.cpp

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