Skip to content

Commit 551483e

Browse files
committed
Merge #595: Add unit test for the PolyMod method in b(l)ech32
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
2 parents 2412d38 + 4a218cd commit 551483e

7 files changed

+77
-14
lines changed

src/Makefile.test.include

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ BITCOIN_TESTS =\
3939
test/base58_tests.cpp \
4040
test/base64_tests.cpp \
4141
test/bech32_tests.cpp \
42+
test/blech32_tests.cpp \
4243
test/bip32_tests.cpp \
4344
test/blockchain_tests.cpp \
4445
test/blockencodings_tests.cpp \

src/bech32.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#include <bech32.h>
66

7-
namespace
7+
namespace bech32
88
{
99

1010
typedef std::vector<uint8_t> data;
@@ -138,11 +138,6 @@ data CreateChecksum(const std::string& hrp, const data& values)
138138
return ret;
139139
}
140140

141-
} // namespace
142-
143-
namespace bech32
144-
{
145-
146141
/** Encode a Bech32 string. */
147142
std::string Encode(const std::string& hrp, const data& values) {
148143
data checksum = CreateChecksum(hrp, values);

src/bech32.h

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ std::string Encode(const std::string& hrp, const std::vector<uint8_t>& values);
2525
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
2626
std::pair<std::string, std::vector<uint8_t>> Decode(const std::string& str);
2727

28+
/// Exported for testing.
29+
uint32_t PolyMod(const std::vector<uint8_t>& v);
30+
2831
} // namespace bech32
2932

3033
#endif // BITCOIN_BECH32_H

src/blech32.cpp

+3-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* TODO: Update comments
1212
*/
1313

14-
namespace
14+
namespace blech32
1515
{
1616

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

148-
} // namespace
149-
150-
namespace blech32
151-
{
152-
153148
/** Encode a Blech32 string. */
154149
std::string Encode(const std::string& hrp, const data& values) {
155150
data checksum = CreateChecksum(hrp, values);

src/blech32.h

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ std::string Encode(const std::string& hrp, const std::vector<uint8_t>& values);
2525
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
2626
std::pair<std::string, std::vector<uint8_t>> Decode(const std::string& str);
2727

28+
/// Exported for testing.
29+
uint64_t PolyMod(const std::vector<uint8_t>& v);
30+
/// Exported for testing.
31+
std::vector<uint8_t> CreateChecksum(const std::string& hrp, const std::vector<uint8_t>& values);
32+
2833
} // namespace blech32
2934

3035
#endif // BITCOIN_BLECH32_H

src/test/bech32_tests.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,22 @@ BOOST_AUTO_TEST_CASE(bip173_testvectors_invalid)
6666
}
6767
}
6868

69+
BOOST_AUTO_TEST_CASE(bech32_polymod_sanity)
70+
{
71+
std::vector<unsigned char> data(40);
72+
GetRandBytes(data.data(), data.size());
73+
74+
std::vector<unsigned char> base32;
75+
ConvertBits<8, 5, true>([&](unsigned char c) { base32.push_back(c); }, data.begin(), data.end());
76+
uint64_t plm1 = bech32::PolyMod(base32);
77+
78+
// Now add 1023 zeros.
79+
for (auto i = 0; i < 1023; i++) {
80+
base32.push_back(0);
81+
}
82+
uint64_t plm2 = bech32::PolyMod(base32);
83+
84+
BOOST_CHECK_EQUAL(plm1, plm2);
85+
}
86+
6987
BOOST_AUTO_TEST_SUITE_END()

src/test/blech32_tests.cpp

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) 2017 Pieter Wuille
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <blech32.h>
6+
#include <random.h>
7+
#include <utilstrencodings.h>
8+
#include <test/test_bitcoin.h>
9+
10+
#include <boost/test/unit_test.hpp>
11+
12+
BOOST_FIXTURE_TEST_SUITE(blech32_tests, BasicTestingSetup)
13+
14+
BOOST_AUTO_TEST_CASE(blech32_polymod_sanity)
15+
{
16+
std::vector<unsigned char> data(40);
17+
GetRandBytes(data.data(), data.size());
18+
19+
std::vector<unsigned char> base32;
20+
ConvertBits<8, 5, true>([&](unsigned char c) { base32.push_back(c); }, data.begin(), data.end());
21+
uint64_t plm1 = blech32::PolyMod(base32);
22+
23+
// Now add 1023 zeros.
24+
for (auto i = 0; i < 1023; i++) {
25+
base32.push_back(0);
26+
}
27+
uint64_t plm2 = blech32::PolyMod(base32);
28+
29+
BOOST_CHECK_EQUAL(plm1, plm2);
30+
}
31+
32+
BOOST_AUTO_TEST_CASE(blech32_checksum)
33+
{
34+
std::vector<unsigned char> vector{7,2,3,4,5,6,7,8,9,234,123,213,16};
35+
std::vector<unsigned char> b32;
36+
ConvertBits<8, 5, true>([&](unsigned char c) { b32.push_back(c); }, vector.begin(), vector.end());
37+
std::vector<unsigned char> cs = blech32::CreateChecksum("lq", b32);
38+
39+
std::vector<unsigned char> expected_cs{22,13,13,5,4,4,23,7,28,21,30,12};
40+
for (size_t i = 0; i < expected_cs.size(); i++) {
41+
BOOST_CHECK_EQUAL(expected_cs[i], cs[i]);
42+
}
43+
}
44+
45+
BOOST_AUTO_TEST_SUITE_END()
46+

0 commit comments

Comments
 (0)