Skip to content

Commit 92f1f8b

Browse files
committed
Split off key_io_tests from base58_tests
1 parent 119b0f8 commit 92f1f8b

File tree

5 files changed

+156
-142
lines changed

5 files changed

+156
-142
lines changed

src/Makefile.test.include

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ TEST_SRCDIR = test
99
TEST_BINARY=test/test_bitcoin$(EXEEXT)
1010

1111
JSON_TEST_FILES = \
12-
test/data/script_tests.json \
13-
test/data/base58_keys_valid.json \
1412
test/data/base58_encode_decode.json \
15-
test/data/base58_keys_invalid.json \
13+
test/data/key_io_valid.json \
14+
test/data/key_io_invalid.json \
15+
test/data/script_tests.json \
16+
test/data/sighash.json \
1617
test/data/tx_invalid.json \
17-
test/data/tx_valid.json \
18-
test/data/sighash.json
18+
test/data/tx_valid.json
1919

2020
RAW_TEST_FILES =
2121

@@ -45,6 +45,7 @@ BITCOIN_TESTS =\
4545
test/DoS_tests.cpp \
4646
test/getarg_tests.cpp \
4747
test/hash_tests.cpp \
48+
test/key_io_tests.cpp \
4849
test/key_tests.cpp \
4950
test/limitedmap_tests.cpp \
5051
test/dbwrapper_tests.cpp \

src/test/base58_tests.cpp

Lines changed: 1 addition & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,10 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5-
#include <base58.h>
6-
75
#include <test/data/base58_encode_decode.json.h>
8-
#include <test/data/base58_keys_invalid.json.h>
9-
#include <test/data/base58_keys_valid.json.h>
106

11-
#include <key.h>
12-
#include <key_io.h>
13-
#include <script/script.h>
7+
#include <base58.h>
148
#include <test/test_bitcoin.h>
15-
#include <uint256.h>
16-
#include <util.h>
179
#include <utilstrencodings.h>
1810

1911
#include <univalue.h>
@@ -74,132 +66,4 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
7466
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
7567
}
7668

77-
// Goal: check that parsed keys match test payload
78-
BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
79-
{
80-
UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
81-
CKey privkey;
82-
CTxDestination destination;
83-
SelectParams(CBaseChainParams::MAIN);
84-
85-
for (unsigned int idx = 0; idx < tests.size(); idx++) {
86-
UniValue test = tests[idx];
87-
std::string strTest = test.write();
88-
if (test.size() < 3) { // Allow for extra stuff (useful for comments)
89-
BOOST_ERROR("Bad test: " << strTest);
90-
continue;
91-
}
92-
std::string exp_base58string = test[0].get_str();
93-
std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
94-
const UniValue &metadata = test[2].get_obj();
95-
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
96-
SelectParams(find_value(metadata, "chain").get_str());
97-
bool try_case_flip = find_value(metadata, "tryCaseFlip").isNull() ? false : find_value(metadata, "tryCaseFlip").get_bool();
98-
if (isPrivkey) {
99-
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
100-
// Must be valid private key
101-
privkey = DecodeSecret(exp_base58string);
102-
BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest);
103-
BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest);
104-
BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() && std::equal(privkey.begin(), privkey.end(), exp_payload.begin()), "key mismatch:" + strTest);
105-
106-
// Private key must be invalid public key
107-
destination = DecodeDestination(exp_base58string);
108-
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid privkey as pubkey:" + strTest);
109-
} else {
110-
// Must be valid public key
111-
destination = DecodeDestination(exp_base58string);
112-
CScript script = GetScriptForDestination(destination);
113-
BOOST_CHECK_MESSAGE(IsValidDestination(destination), "!IsValid:" + strTest);
114-
BOOST_CHECK_EQUAL(HexStr(script), HexStr(exp_payload));
115-
116-
// Try flipped case version
117-
for (char& c : exp_base58string) {
118-
if (c >= 'a' && c <= 'z') {
119-
c = (c - 'a') + 'A';
120-
} else if (c >= 'A' && c <= 'Z') {
121-
c = (c - 'A') + 'a';
122-
}
123-
}
124-
destination = DecodeDestination(exp_base58string);
125-
BOOST_CHECK_MESSAGE(IsValidDestination(destination) == try_case_flip, "!IsValid case flipped:" + strTest);
126-
if (IsValidDestination(destination)) {
127-
script = GetScriptForDestination(destination);
128-
BOOST_CHECK_EQUAL(HexStr(script), HexStr(exp_payload));
129-
}
130-
131-
// Public key must be invalid private key
132-
privkey = DecodeSecret(exp_base58string);
133-
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid pubkey as privkey:" + strTest);
134-
}
135-
}
136-
}
137-
138-
// Goal: check that generated keys match test vectors
139-
BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
140-
{
141-
UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
142-
143-
for (unsigned int idx = 0; idx < tests.size(); idx++) {
144-
UniValue test = tests[idx];
145-
std::string strTest = test.write();
146-
if (test.size() < 3) // Allow for extra stuff (useful for comments)
147-
{
148-
BOOST_ERROR("Bad test: " << strTest);
149-
continue;
150-
}
151-
std::string exp_base58string = test[0].get_str();
152-
std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
153-
const UniValue &metadata = test[2].get_obj();
154-
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
155-
SelectParams(find_value(metadata, "chain").get_str());
156-
if (isPrivkey) {
157-
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
158-
CKey key;
159-
key.Set(exp_payload.begin(), exp_payload.end(), isCompressed);
160-
assert(key.IsValid());
161-
BOOST_CHECK_MESSAGE(EncodeSecret(key) == exp_base58string, "result mismatch: " + strTest);
162-
} else {
163-
CTxDestination dest;
164-
CScript exp_script(exp_payload.begin(), exp_payload.end());
165-
ExtractDestination(exp_script, dest);
166-
std::string address = EncodeDestination(dest);
167-
168-
BOOST_CHECK_EQUAL(address, exp_base58string);
169-
}
170-
}
171-
172-
SelectParams(CBaseChainParams::MAIN);
173-
}
174-
175-
176-
// Goal: check that base58 parsing code is robust against a variety of corrupted data
177-
BOOST_AUTO_TEST_CASE(base58_keys_invalid)
178-
{
179-
UniValue tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases
180-
CKey privkey;
181-
CTxDestination destination;
182-
183-
for (unsigned int idx = 0; idx < tests.size(); idx++) {
184-
UniValue test = tests[idx];
185-
std::string strTest = test.write();
186-
if (test.size() < 1) // Allow for extra stuff (useful for comments)
187-
{
188-
BOOST_ERROR("Bad test: " << strTest);
189-
continue;
190-
}
191-
std::string exp_base58string = test[0].get_str();
192-
193-
// must be invalid as public and as private key
194-
for (auto chain : { CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::REGTEST }) {
195-
SelectParams(chain);
196-
destination = DecodeDestination(exp_base58string);
197-
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid pubkey in mainnet:" + strTest);
198-
privkey = DecodeSecret(exp_base58string);
199-
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid privkey in mainnet:" + strTest);
200-
}
201-
}
202-
}
203-
204-
20569
BOOST_AUTO_TEST_SUITE_END()

src/test/key_io_tests.cpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright (c) 2011-2016 The Bitcoin Core developers
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 <test/data/key_io_invalid.json.h>
6+
#include <test/data/key_io_valid.json.h>
7+
8+
#include <key.h>
9+
#include <key_io.h>
10+
#include <script/script.h>
11+
#include <utilstrencodings.h>
12+
#include <test/test_bitcoin.h>
13+
14+
#include <boost/test/unit_test.hpp>
15+
16+
#include <univalue.h>
17+
18+
extern UniValue read_json(const std::string& jsondata);
19+
20+
BOOST_FIXTURE_TEST_SUITE(key_io_tests, BasicTestingSetup)
21+
22+
// Goal: check that parsed keys match test payload
23+
BOOST_AUTO_TEST_CASE(key_io_valid_parse)
24+
{
25+
UniValue tests = read_json(std::string(json_tests::key_io_valid, json_tests::key_io_valid + sizeof(json_tests::key_io_valid)));
26+
CKey privkey;
27+
CTxDestination destination;
28+
SelectParams(CBaseChainParams::MAIN);
29+
30+
for (unsigned int idx = 0; idx < tests.size(); idx++) {
31+
UniValue test = tests[idx];
32+
std::string strTest = test.write();
33+
if (test.size() < 3) { // Allow for extra stuff (useful for comments)
34+
BOOST_ERROR("Bad test: " << strTest);
35+
continue;
36+
}
37+
std::string exp_base58string = test[0].get_str();
38+
std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
39+
const UniValue &metadata = test[2].get_obj();
40+
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
41+
SelectParams(find_value(metadata, "chain").get_str());
42+
bool try_case_flip = find_value(metadata, "tryCaseFlip").isNull() ? false : find_value(metadata, "tryCaseFlip").get_bool();
43+
if (isPrivkey) {
44+
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
45+
// Must be valid private key
46+
privkey = DecodeSecret(exp_base58string);
47+
BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest);
48+
BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest);
49+
BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() && std::equal(privkey.begin(), privkey.end(), exp_payload.begin()), "key mismatch:" + strTest);
50+
51+
// Private key must be invalid public key
52+
destination = DecodeDestination(exp_base58string);
53+
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid privkey as pubkey:" + strTest);
54+
} else {
55+
// Must be valid public key
56+
destination = DecodeDestination(exp_base58string);
57+
CScript script = GetScriptForDestination(destination);
58+
BOOST_CHECK_MESSAGE(IsValidDestination(destination), "!IsValid:" + strTest);
59+
BOOST_CHECK_EQUAL(HexStr(script), HexStr(exp_payload));
60+
61+
// Try flipped case version
62+
for (char& c : exp_base58string) {
63+
if (c >= 'a' && c <= 'z') {
64+
c = (c - 'a') + 'A';
65+
} else if (c >= 'A' && c <= 'Z') {
66+
c = (c - 'A') + 'a';
67+
}
68+
}
69+
destination = DecodeDestination(exp_base58string);
70+
BOOST_CHECK_MESSAGE(IsValidDestination(destination) == try_case_flip, "!IsValid case flipped:" + strTest);
71+
if (IsValidDestination(destination)) {
72+
script = GetScriptForDestination(destination);
73+
BOOST_CHECK_EQUAL(HexStr(script), HexStr(exp_payload));
74+
}
75+
76+
// Public key must be invalid private key
77+
privkey = DecodeSecret(exp_base58string);
78+
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid pubkey as privkey:" + strTest);
79+
}
80+
}
81+
}
82+
83+
// Goal: check that generated keys match test vectors
84+
BOOST_AUTO_TEST_CASE(key_io_valid_gen)
85+
{
86+
UniValue tests = read_json(std::string(json_tests::key_io_valid, json_tests::key_io_valid + sizeof(json_tests::key_io_valid)));
87+
88+
for (unsigned int idx = 0; idx < tests.size(); idx++) {
89+
UniValue test = tests[idx];
90+
std::string strTest = test.write();
91+
if (test.size() < 3) // Allow for extra stuff (useful for comments)
92+
{
93+
BOOST_ERROR("Bad test: " << strTest);
94+
continue;
95+
}
96+
std::string exp_base58string = test[0].get_str();
97+
std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
98+
const UniValue &metadata = test[2].get_obj();
99+
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
100+
SelectParams(find_value(metadata, "chain").get_str());
101+
if (isPrivkey) {
102+
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
103+
CKey key;
104+
key.Set(exp_payload.begin(), exp_payload.end(), isCompressed);
105+
assert(key.IsValid());
106+
BOOST_CHECK_MESSAGE(EncodeSecret(key) == exp_base58string, "result mismatch: " + strTest);
107+
} else {
108+
CTxDestination dest;
109+
CScript exp_script(exp_payload.begin(), exp_payload.end());
110+
ExtractDestination(exp_script, dest);
111+
std::string address = EncodeDestination(dest);
112+
113+
BOOST_CHECK_EQUAL(address, exp_base58string);
114+
}
115+
}
116+
117+
SelectParams(CBaseChainParams::MAIN);
118+
}
119+
120+
121+
// Goal: check that base58 parsing code is robust against a variety of corrupted data
122+
BOOST_AUTO_TEST_CASE(key_io_invalid)
123+
{
124+
UniValue tests = read_json(std::string(json_tests::key_io_invalid, json_tests::key_io_invalid + sizeof(json_tests::key_io_invalid))); // Negative testcases
125+
CKey privkey;
126+
CTxDestination destination;
127+
128+
for (unsigned int idx = 0; idx < tests.size(); idx++) {
129+
UniValue test = tests[idx];
130+
std::string strTest = test.write();
131+
if (test.size() < 1) // Allow for extra stuff (useful for comments)
132+
{
133+
BOOST_ERROR("Bad test: " << strTest);
134+
continue;
135+
}
136+
std::string exp_base58string = test[0].get_str();
137+
138+
// must be invalid as public and as private key
139+
for (auto chain : { CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::REGTEST }) {
140+
SelectParams(chain);
141+
destination = DecodeDestination(exp_base58string);
142+
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid pubkey in mainnet:" + strTest);
143+
privkey = DecodeSecret(exp_base58string);
144+
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid privkey in mainnet:" + strTest);
145+
}
146+
}
147+
}
148+
149+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)