Skip to content

Commit

Permalink
Merge #595: Add unit test for the PolyMod method in b(l)ech32
Browse files Browse the repository at this point in the history
4a218cd Fix linter by exporting b(l)ech32 internals (Steven Roose)
99b047c Add additional blech32 unit test (Steven Roose)
6412970 Fix bug in blech32 (Steven Roose)
0de2b05 Add unit test for the PolyMod method in b(l)ech32 (Steven Roose)

Pull request description:

Tree-SHA512: 9d574376b6471742283d0d145359d8d674b7e95fd40f52396c6fc5f671dc262526624d1d15cb8ab7b4517a8b2501405dd0f680f69dfc41dabb0eb11d7bbbfe88
  • Loading branch information
instagibbs committed Apr 23, 2019
2 parents 2412d38 + 4a218cd commit 551483e
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ BITCOIN_TESTS =\
test/base58_tests.cpp \
test/base64_tests.cpp \
test/bech32_tests.cpp \
test/blech32_tests.cpp \
test/bip32_tests.cpp \
test/blockchain_tests.cpp \
test/blockencodings_tests.cpp \
Expand Down
7 changes: 1 addition & 6 deletions src/bech32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include <bech32.h>

namespace
namespace bech32
{

typedef std::vector<uint8_t> data;
Expand Down Expand Up @@ -138,11 +138,6 @@ data CreateChecksum(const std::string& hrp, const data& values)
return ret;
}

} // namespace

namespace bech32
{

/** Encode a Bech32 string. */
std::string Encode(const std::string& hrp, const data& values) {
data checksum = CreateChecksum(hrp, values);
Expand Down
3 changes: 3 additions & 0 deletions src/bech32.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ std::string Encode(const std::string& hrp, const std::vector<uint8_t>& values);
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
std::pair<std::string, std::vector<uint8_t>> Decode(const std::string& str);

/// Exported for testing.
uint32_t PolyMod(const std::vector<uint8_t>& v);

} // namespace bech32

#endif // BITCOIN_BECH32_H
11 changes: 3 additions & 8 deletions src/blech32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* TODO: Update comments
*/

namespace
namespace blech32
{

typedef std::vector<uint8_t> data;
Expand Down Expand Up @@ -41,7 +41,7 @@ data Cat(data x, const data& y)
/** This function will compute what 6 5-bit values to XOR into the last 6 input values, in order to
* make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher
* bits correspond to earlier values. */
uint32_t PolyMod(const data& v)
uint64_t PolyMod(const data& v)
{
// The input is interpreted as a list of coefficients of a polynomial over F = GF(32), with an
// implicit 1 in front. If the input is [v0,v1,v2,v3,v4], that polynomial is v(x) =
Expand Down Expand Up @@ -136,7 +136,7 @@ data CreateChecksum(const std::string& hrp, const data& values)
{
data enc = Cat(ExpandHRP(hrp), values);
enc.resize(enc.size() + 12); // ELEMENTS: Append 6->12 zeroes
uint32_t mod = PolyMod(enc) ^ 1; // Determine what to XOR into those 6 zeroes.
uint64_t mod = PolyMod(enc) ^ 1; // Determine what to XOR into those 6 zeroes.
data ret(12); // ELEMENTS: 6->12
for (size_t i = 0; i < 12; ++i) { // ELEMENTS: 6->12
// Convert the 5-bit groups in mod to checksum values.
Expand All @@ -145,11 +145,6 @@ data CreateChecksum(const std::string& hrp, const data& values)
return ret;
}

} // namespace

namespace blech32
{

/** Encode a Blech32 string. */
std::string Encode(const std::string& hrp, const data& values) {
data checksum = CreateChecksum(hrp, values);
Expand Down
5 changes: 5 additions & 0 deletions src/blech32.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ std::string Encode(const std::string& hrp, const std::vector<uint8_t>& values);
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
std::pair<std::string, std::vector<uint8_t>> Decode(const std::string& str);

/// Exported for testing.
uint64_t PolyMod(const std::vector<uint8_t>& v);
/// Exported for testing.
std::vector<uint8_t> CreateChecksum(const std::string& hrp, const std::vector<uint8_t>& values);

} // namespace blech32

#endif // BITCOIN_BLECH32_H
18 changes: 18 additions & 0 deletions src/test/bech32_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,22 @@ BOOST_AUTO_TEST_CASE(bip173_testvectors_invalid)
}
}

BOOST_AUTO_TEST_CASE(bech32_polymod_sanity)
{
std::vector<unsigned char> data(40);
GetRandBytes(data.data(), data.size());

std::vector<unsigned char> base32;
ConvertBits<8, 5, true>([&](unsigned char c) { base32.push_back(c); }, data.begin(), data.end());
uint64_t plm1 = bech32::PolyMod(base32);

// Now add 1023 zeros.
for (auto i = 0; i < 1023; i++) {
base32.push_back(0);
}
uint64_t plm2 = bech32::PolyMod(base32);

BOOST_CHECK_EQUAL(plm1, plm2);
}

BOOST_AUTO_TEST_SUITE_END()
46 changes: 46 additions & 0 deletions src/test/blech32_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2017 Pieter Wuille
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <blech32.h>
#include <random.h>
#include <utilstrencodings.h>
#include <test/test_bitcoin.h>

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(blech32_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(blech32_polymod_sanity)
{
std::vector<unsigned char> data(40);
GetRandBytes(data.data(), data.size());

std::vector<unsigned char> base32;
ConvertBits<8, 5, true>([&](unsigned char c) { base32.push_back(c); }, data.begin(), data.end());
uint64_t plm1 = blech32::PolyMod(base32);

// Now add 1023 zeros.
for (auto i = 0; i < 1023; i++) {
base32.push_back(0);
}
uint64_t plm2 = blech32::PolyMod(base32);

BOOST_CHECK_EQUAL(plm1, plm2);
}

BOOST_AUTO_TEST_CASE(blech32_checksum)
{
std::vector<unsigned char> vector{7,2,3,4,5,6,7,8,9,234,123,213,16};
std::vector<unsigned char> b32;
ConvertBits<8, 5, true>([&](unsigned char c) { b32.push_back(c); }, vector.begin(), vector.end());
std::vector<unsigned char> cs = blech32::CreateChecksum("lq", b32);

std::vector<unsigned char> expected_cs{22,13,13,5,4,4,23,7,28,21,30,12};
for (size_t i = 0; i < expected_cs.size(); i++) {
BOOST_CHECK_EQUAL(expected_cs[i], cs[i]);
}
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 551483e

Please sign in to comment.