Line data Source code
1 : // Copyright (c) 2014 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 "random.h"
6 : #include "utilstrencodings.h"
7 : #include "test/test_pivx.h"
8 : #include "crypter.h"
9 :
10 : #include <vector>
11 :
12 : #include <boost/test/unit_test.hpp>
13 :
14 : BOOST_FIXTURE_TEST_SUITE(wallet_crypto, BasicTestingSetup)
15 :
16 : class TestCrypter
17 : {
18 : public:
19 70 : static void TestPassphraseSingle(const std::vector<unsigned char>& vchSalt, const SecureString& passphrase, uint32_t rounds,
20 : const std::vector<unsigned char>& correctKey = std::vector<unsigned char>(),
21 : const std::vector<unsigned char>& correctIV=std::vector<unsigned char>())
22 : {
23 140 : CCrypter crypt;
24 70 : crypt.SetKeyFromPassphrase(passphrase, vchSalt, rounds, 0);
25 :
26 70 : if(!correctKey.empty())
27 4 : BOOST_CHECK_MESSAGE(memcmp(crypt.vchKey.data(), correctKey.data(), crypt.vchKey.size()) == 0,
28 : HexStr(crypt.vchKey) + std::string(" != ") + HexStr(correctKey));
29 70 : if(!correctIV.empty())
30 4 : BOOST_CHECK_MESSAGE(memcmp(crypt.vchIV.data(), correctIV.data(), crypt.vchIV.size()) == 0,
31 : HexStr(crypt.vchIV) + std::string(" != ") + HexStr(correctIV));
32 :
33 70 : }
34 :
35 2 : static void TestPassphrase(const std::vector<unsigned char>& vchSalt, const SecureString& passphrase, uint32_t rounds,
36 : const std::vector<unsigned char>& correctKey = std::vector<unsigned char>(),
37 : const std::vector<unsigned char>& correctIV=std::vector<unsigned char>())
38 : {
39 2 : TestPassphraseSingle(vchSalt, passphrase, rounds, correctKey, correctIV);
40 70 : for(SecureString::const_iterator i(passphrase.begin()); i != passphrase.end(); ++i)
41 136 : TestPassphraseSingle(vchSalt, SecureString(i, passphrase.end()), rounds);
42 2 : }
43 :
44 :
45 3439 : static void TestDecrypt(const CCrypter& crypt, const std::vector<unsigned char>& vchCiphertext,
46 : const std::vector<unsigned char>& vchPlaintext = std::vector<unsigned char>())
47 : {
48 3439 : CKeyingMaterial vchDecrypted;
49 3439 : crypt.Decrypt(vchCiphertext, vchDecrypted);
50 3439 : if (vchPlaintext.size())
51 9999 : BOOST_CHECK(CKeyingMaterial(vchPlaintext.begin(), vchPlaintext.end()) == vchDecrypted);
52 3439 : }
53 :
54 3333 : static void TestEncryptSingle(const CCrypter& crypt, const CKeyingMaterial& vchPlaintext,
55 : const std::vector<unsigned char>& vchCiphertextCorrect = std::vector<unsigned char>())
56 : {
57 3333 : std::vector<unsigned char> vchCiphertext;
58 3333 : crypt.Encrypt(vchPlaintext, vchCiphertext);
59 :
60 3333 : if (!vchCiphertextCorrect.empty())
61 0 : BOOST_CHECK(vchCiphertext == vchCiphertextCorrect);
62 :
63 6666 : const std::vector<unsigned char> vchPlaintext2(vchPlaintext.begin(), vchPlaintext.end());
64 :
65 3333 : TestDecrypt(crypt, vchCiphertext, vchPlaintext2);
66 3333 : }
67 :
68 101 : static void TestEncrypt(const CCrypter& crypt, const std::vector<unsigned char>& vchPlaintextIn, \
69 : const std::vector<unsigned char>& vchCiphertextCorrect = std::vector<unsigned char>())
70 : {
71 101 : TestEncryptSingle(crypt, CKeyingMaterial(vchPlaintextIn.begin(), vchPlaintextIn.end()), vchCiphertextCorrect);
72 3333 : for(std::vector<unsigned char>::const_iterator i(vchPlaintextIn.begin()); i != vchPlaintextIn.end(); ++i)
73 6464 : TestEncryptSingle(crypt, CKeyingMaterial(i, vchPlaintextIn.end()));
74 101 : }
75 :
76 : };
77 :
78 2 : BOOST_AUTO_TEST_CASE(passphrase) {
79 : // These are expensive.
80 :
81 2 : TestCrypter::TestPassphrase(ParseHex("0000deadbeef0000"), "test", 25000, \
82 2 : ParseHex("fc7aba077ad5f4c3a0988d8daa4810d0d4a0e3bcb53af662998898f33df0556a"), \
83 1 : ParseHex("cf2f2691526dd1aa220896fb8bf7c369"));
84 :
85 1 : std::string hash(GetRandHash().ToString());
86 2 : std::vector<unsigned char> vchSalt(8);
87 1 : GetRandBytes(vchSalt.data(), vchSalt.size());
88 1 : uint32_t rounds = GetRandInt(30000);
89 1 : if (rounds > 30000)
90 0 : rounds = 30000;
91 2 : TestCrypter::TestPassphrase(vchSalt, SecureString(hash.begin(), hash.end()), rounds);
92 1 : }
93 :
94 2 : BOOST_AUTO_TEST_CASE(encrypt) {
95 1 : std::vector<unsigned char> vchSalt = ParseHex("0000deadbeef0000");
96 2 : BOOST_CHECK(vchSalt.size() == WALLET_CRYPTO_SALT_SIZE);
97 2 : CCrypter crypt;
98 1 : crypt.SetKeyFromPassphrase("passphrase", vchSalt, 25000, 0);
99 2 : TestCrypter::TestEncrypt(crypt, ParseHex("22bcade09ac03ff6386914359cfe885cfeb5f77ff0d670f102f619687453b29d"));
100 :
101 101 : for (int i = 0; i != 100; i++)
102 : {
103 100 : uint256 hash(GetRandHash());
104 200 : TestCrypter::TestEncrypt(crypt, std::vector<unsigned char>(hash.begin(), hash.end()));
105 : }
106 :
107 1 : }
108 :
109 2 : BOOST_AUTO_TEST_CASE(decrypt) {
110 1 : std::vector<unsigned char> vchSalt = ParseHex("0000deadbeef0000");
111 2 : BOOST_CHECK(vchSalt.size() == WALLET_CRYPTO_SALT_SIZE);
112 2 : CCrypter crypt;
113 1 : crypt.SetKeyFromPassphrase("passphrase", vchSalt, 25000, 0);
114 :
115 : // Some corner cases the came up while testing
116 2 : TestCrypter::TestDecrypt(crypt,ParseHex("795643ce39d736088367822cdc50535ec6f103715e3e48f4f3b1a60a08ef59ca"));
117 2 : TestCrypter::TestDecrypt(crypt,ParseHex("de096f4a8f9bd97db012aa9d90d74de8cdea779c3ee8bc7633d8b5d6da703486"));
118 2 : TestCrypter::TestDecrypt(crypt,ParseHex("32d0a8974e3afd9c6c3ebf4d66aa4e6419f8c173de25947f98cf8b7ace49449c"));
119 2 : TestCrypter::TestDecrypt(crypt,ParseHex("e7c055cca2faa78cb9ac22c9357a90b4778ded9b2cc220a14cea49f931e596ea"));
120 2 : TestCrypter::TestDecrypt(crypt,ParseHex("b88efddd668a6801d19516d6830da4ae9811988ccbaf40df8fbb72f3f4d335fd"));
121 2 : TestCrypter::TestDecrypt(crypt,ParseHex("8cae76aa6a43694e961ebcb28c8ca8f8540b84153d72865e8561ddd93fa7bfa9"));
122 :
123 101 : for (int i = 0; i != 100; i++)
124 : {
125 100 : uint256 hash(GetRandHash());
126 200 : TestCrypter::TestDecrypt(crypt, std::vector<unsigned char>(hash.begin(), hash.end()));
127 : }
128 1 : }
129 :
130 : BOOST_AUTO_TEST_SUITE_END()
|