mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-01 00:34:01 +02:00
Merge bitcoin/bitcoin#23577: Follow-ups to Bech32 error detection
a4fe70171bMake Bech32 LocateErrors return error list rather than using out-arg (Samuel Dobson)2fa4fd1961Use std::iota instead of manually pushing range (Samuel Dobson)405c96fc9fUse bounds-checked array lookups in Bech32 error detection code (Samuel Dobson)28d9c2857fSimplify encoding of e in GF(1024) tables to (1,0) (Samuel Dobson)14358a029dReplace GF1024 tables and syndrome constants with compile-time generated constexprs. (Samuel Dobson)63f7b69779Update release note for bech32 error detection (Samuel Dobson)c8b9a224e7Report encoding type in bech32 error message (Samuel Dobson)92f0cafdcaImprove Bech32 boost tests (Samuel Dobson)bb4d3e9b97Address review comments for Bech32 error validation (Samuel Dobson) Pull request description: A number of follow-ups and improvements to the bech32 error location code, introduced in #16807. Notably, this removes the hardcoded GF1024 tables in favour of constexpr table generation. ACKs for top commit: laanwj: Re-ACKa4fe70171bTree-SHA512: 6312373c20ebd6636f5797304876fa0d70fa777de2f6c507245f51a652b3d1224ebc55b236c9e11e6956c1e88e65faadab51d53587078efccb451455aa2e2276
This commit is contained in:
@@ -70,34 +70,36 @@ BOOST_AUTO_TEST_CASE(bech32_testvectors_invalid)
|
||||
"a12UEL5L",
|
||||
"A12uEL5L",
|
||||
"abcdef1qpzrz9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
|
||||
"test1zg69w7y6hn0aqy352euf40x77qddq3dc",
|
||||
};
|
||||
static const std::pair<std::string, int> ERRORS[] = {
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Bech32 string too long", 90},
|
||||
{"Missing separator", -1},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid Base 32 character", 2},
|
||||
{"Invalid separator position", 2},
|
||||
{"Invalid character or mixed case", 8},
|
||||
{"Invalid checksum", -1}, // The checksum is calculated using the uppercase form so the entire string is invalid, not just a few characters
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid character or mixed case", 3},
|
||||
{"Invalid character or mixed case", 3},
|
||||
{"Invalid checksum", 11}
|
||||
static const std::pair<std::string, std::vector<int>> ERRORS[] = {
|
||||
{"Invalid character or mixed case", {0}},
|
||||
{"Invalid character or mixed case", {0}},
|
||||
{"Invalid character or mixed case", {0}},
|
||||
{"Bech32 string too long", {90}},
|
||||
{"Missing separator", {}},
|
||||
{"Invalid separator position", {0}},
|
||||
{"Invalid Base 32 character", {2}},
|
||||
{"Invalid separator position", {2}},
|
||||
{"Invalid character or mixed case", {8}},
|
||||
{"Invalid checksum", {}}, // The checksum is calculated using the uppercase form so the entire string is invalid, not just a few characters
|
||||
{"Invalid separator position", {0}},
|
||||
{"Invalid separator position", {0}},
|
||||
{"Invalid character or mixed case", {3, 4, 5, 7}},
|
||||
{"Invalid character or mixed case", {3}},
|
||||
{"Invalid Bech32 checksum", {11}},
|
||||
{"Invalid Bech32 checksum", {9, 16}},
|
||||
};
|
||||
static_assert(std::size(CASES) == std::size(ERRORS), "Bech32 CASES and ERRORS should have the same length");
|
||||
|
||||
int i = 0;
|
||||
for (const std::string& str : CASES) {
|
||||
const auto& err = ERRORS[i];
|
||||
const auto dec = bech32::Decode(str);
|
||||
BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
|
||||
std::vector<int> error_locations;
|
||||
std::string error = bech32::LocateErrors(str, error_locations);
|
||||
auto [error, error_locations] = bech32::LocateErrors(str);
|
||||
BOOST_CHECK_EQUAL(err.first, error);
|
||||
if (err.second == -1) BOOST_CHECK(error_locations.empty());
|
||||
else BOOST_CHECK_EQUAL(err.second, error_locations[0]);
|
||||
BOOST_CHECK(err.second == error_locations);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -120,34 +122,36 @@ BOOST_AUTO_TEST_CASE(bech32m_testvectors_invalid)
|
||||
"16plkw9",
|
||||
"1p2gdwpf",
|
||||
"abcdef1l7aum6echk45nj2s0wdvt2fg8x9yrzpqzd3ryx",
|
||||
"test1zg69v7y60n00qy352euf40x77qcusag6",
|
||||
};
|
||||
static const std::pair<std::string, int> ERRORS[] = {
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Bech32 string too long", 90},
|
||||
{"Missing separator", -1},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid Base 32 character", 2},
|
||||
{"Invalid Base 32 character", 3},
|
||||
{"Invalid separator position", 2},
|
||||
{"Invalid Base 32 character", 8},
|
||||
{"Invalid Base 32 character", 7},
|
||||
{"Invalid checksum", -1},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid checksum", 21},
|
||||
static const std::pair<std::string, std::vector<int>> ERRORS[] = {
|
||||
{"Invalid character or mixed case", {0}},
|
||||
{"Invalid character or mixed case", {0}},
|
||||
{"Invalid character or mixed case", {0}},
|
||||
{"Bech32 string too long", {90}},
|
||||
{"Missing separator", {}},
|
||||
{"Invalid separator position", {0}},
|
||||
{"Invalid Base 32 character", {2}},
|
||||
{"Invalid Base 32 character", {3}},
|
||||
{"Invalid separator position", {2}},
|
||||
{"Invalid Base 32 character", {8}},
|
||||
{"Invalid Base 32 character", {7}},
|
||||
{"Invalid checksum", {}},
|
||||
{"Invalid separator position", {0}},
|
||||
{"Invalid separator position", {0}},
|
||||
{"Invalid Bech32m checksum", {21}},
|
||||
{"Invalid Bech32m checksum", {13, 32}},
|
||||
};
|
||||
static_assert(std::size(CASES) == std::size(ERRORS), "Bech32m CASES and ERRORS should have the same length");
|
||||
|
||||
int i = 0;
|
||||
for (const std::string& str : CASES) {
|
||||
const auto& err = ERRORS[i];
|
||||
const auto dec = bech32::Decode(str);
|
||||
BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
|
||||
std::vector<int> error_locations;
|
||||
std::string error = bech32::LocateErrors(str, error_locations);
|
||||
auto [error, error_locations] = bech32::LocateErrors(str);
|
||||
BOOST_CHECK_EQUAL(err.first, error);
|
||||
if (err.second == -1) BOOST_CHECK(error_locations.empty());
|
||||
else BOOST_CHECK_EQUAL(err.second, error_locations[0]);
|
||||
BOOST_CHECK(err.second == error_locations);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user