diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 4617beecd999e..b559b7fdcb937 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include using namespace std::literals; @@ -29,9 +31,45 @@ BOOST_AUTO_TEST_CASE(base32_testvectors) // Decoding strings with embedded NUL characters should fail BOOST_CHECK(!DecodeBase32("invalid\0"s)); // correct size, invalid due to \0 - BOOST_CHECK(DecodeBase32("AWSX3VPP"s)); // valid + BOOST_CHECK( DecodeBase32("AWSX3VPP"s)); // valid BOOST_CHECK(!DecodeBase32("AWSX3VPP\0invalid"s)); // correct size, invalid due to \0 BOOST_CHECK(!DecodeBase32("AWSX3VPPinvalid"s)); // invalid size } +BOOST_AUTO_TEST_CASE(base32_padding) +{ + // Is valid without padding + { + const std::vector in{'f', 'o', 'o', 'b', 'a'}; + const std::string out{"mzxw6ytb"}; + BOOST_CHECK_EQUAL(EncodeBase32(in), out); + } + + // Valid size + BOOST_CHECK(!DecodeBase32("========"s)); + BOOST_CHECK(!DecodeBase32("a======="s)); + BOOST_CHECK( DecodeBase32("aa======"s)); + BOOST_CHECK(!DecodeBase32("aaa====="s)); + BOOST_CHECK( DecodeBase32("aaaa===="s)); + BOOST_CHECK( DecodeBase32("aaaaa==="s)); + BOOST_CHECK(!DecodeBase32("aaaaaa=="s)); + BOOST_CHECK( DecodeBase32("aaaaaaa="s)); +} + +BOOST_AUTO_TEST_CASE(base32_roundtrip) { + FastRandomContext rng; + for (int i = 0; i < 100; ++i) { + auto chars = rng.randbytes(rng.randrange(32)); + std::string randomStr(chars.begin(), chars.end()); + auto encoded = EncodeBase32(randomStr); + + auto decodedOpt = DecodeBase32(encoded); + BOOST_REQUIRE_MESSAGE(decodedOpt, "Decoding failed for " + encoded); + auto decoded = *decodedOpt; + + std::string decodedStr(decoded.begin(), decoded.end()); + BOOST_CHECK_MESSAGE(randomStr == decodedStr, "Roundtrip mismatch: original=" + randomStr + ", roundtrip=" + decodedStr); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index 6462aa82fb66c..c3d58a86bb3cb 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include using namespace std::literals; @@ -35,10 +37,42 @@ BOOST_AUTO_TEST_CASE(base64_testvectors) } // Decoding strings with embedded NUL characters should fail - BOOST_CHECK(!DecodeBase64("invalid\0"s)); - BOOST_CHECK(DecodeBase64("nQB/pZw="s)); - BOOST_CHECK(!DecodeBase64("nQB/pZw=\0invalid"s)); - BOOST_CHECK(!DecodeBase64("nQB/pZw=invalid\0"s)); + BOOST_CHECK(!DecodeBase64("invalid\0"s)); // correct size, invalid due to \0 + BOOST_CHECK( DecodeBase64("nQB/pZw="s)); // valid + BOOST_CHECK(!DecodeBase64("nQB/pZw=\0invalid"s)); // correct size, invalid due to \0 + BOOST_CHECK(!DecodeBase64("nQB/pZw=invalid\0"s)); // invalid size +} + +BOOST_AUTO_TEST_CASE(base64_padding) +{ + // Is valid without padding + { + const std::vector in{'f', 'o', 'o', 'b', 'a', 'r'}; + const std::string out{"Zm9vYmFy"}; + BOOST_CHECK_EQUAL(EncodeBase64(in), out); + } + + // Valid size + BOOST_CHECK(!DecodeBase64("===="s)); + BOOST_CHECK(!DecodeBase64("a==="s)); + BOOST_CHECK( DecodeBase64("YQ=="s)); + BOOST_CHECK( DecodeBase64("YWE="s)); +} + +BOOST_AUTO_TEST_CASE(base64_roundtrip) { + FastRandomContext rng; + for (int i = 0; i < 100; ++i) { + auto chars = rng.randbytes(rng.randrange(64)); + std::string randomStr(chars.begin(), chars.end()); + auto encoded = EncodeBase64(randomStr); + + auto decodedOpt = DecodeBase64(encoded); + BOOST_REQUIRE_MESSAGE(decodedOpt, "Decoding failed for " + encoded); + auto decoded = *decodedOpt; + + std::string decodedStr(decoded.begin(), decoded.end()); + BOOST_CHECK_MESSAGE(randomStr == decodedStr, "Roundtrip mismatch: original=" + randomStr + ", roundtrip=" + decodedStr); + } } BOOST_AUTO_TEST_SUITE_END()