Branch data Line data Source code
1 : : // Copyright (c) 2013-present 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 <boost/test/unit_test.hpp>
6 : :
7 : : #include <clientversion.h>
8 : : #include <key.h>
9 : : #include <key_io.h>
10 : : #include <streams.h>
11 : : #include <test/util/setup_common.h>
12 : : #include <util/bip32.h>
13 : : #include <util/strencodings.h>
14 : :
15 : : #include <string>
16 : : #include <vector>
17 : :
18 : : namespace {
19 : :
20 : 10695 : struct TestDerivation {
21 : : std::string pub;
22 : : std::string prv;
23 : : unsigned int nChild;
24 : : };
25 : :
26 : : struct TestVector {
27 : : std::string strHexMaster;
28 : : std::vector<TestDerivation> vDerive;
29 : :
30 [ - + ]: 620 : explicit TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {}
31 : :
32 : 2635 : TestVector& operator()(std::string pub, std::string prv, unsigned int nChild) {
33 : 2635 : vDerive.emplace_back();
34 : 2635 : TestDerivation &der = vDerive.back();
35 : 2635 : der.pub = pub;
36 : 2635 : der.prv = prv;
37 : 2635 : der.nChild = nChild;
38 : 2635 : return *this;
39 : : }
40 : : };
41 : :
42 : : TestVector test1 =
43 : : TestVector("000102030405060708090a0b0c0d0e0f")
44 : : ("xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
45 : : "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
46 : : BIP32_HARDENED_FLAG)
47 : : ("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
48 : : "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
49 : : 1)
50 : : ("xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
51 : : "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
52 : : BIP32_HARDENED_FLAG | 2)
53 : : ("xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5",
54 : : "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
55 : : 2)
56 : : ("xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV",
57 : : "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
58 : : 1000000000)
59 : : ("xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy",
60 : : "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
61 : : 0);
62 : :
63 : : TestVector test2 =
64 : : TestVector("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542")
65 : : ("xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
66 : : "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
67 : : 0)
68 : : ("xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
69 : : "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
70 : : 0xFFFFFFFF)
71 : : ("xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a",
72 : : "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
73 : : 1)
74 : : ("xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon",
75 : : "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
76 : : 0xFFFFFFFE)
77 : : ("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL",
78 : : "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
79 : : 2)
80 : : ("xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt",
81 : : "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
82 : : 0);
83 : :
84 : : TestVector test3 =
85 : : TestVector("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be")
86 : : ("xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13",
87 : : "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6",
88 : : BIP32_HARDENED_FLAG)
89 : : ("xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y",
90 : : "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L",
91 : : 0);
92 : :
93 : : TestVector test4 =
94 : : TestVector("3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678")
95 : : ("xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa",
96 : : "xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv",
97 : : BIP32_HARDENED_FLAG)
98 : : ("xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m",
99 : : "xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G",
100 : : BIP32_HARDENED_FLAG | 1)
101 : : ("xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt",
102 : : "xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1",
103 : : 0);
104 : :
105 : : const std::vector<std::string> TEST5 = {
106 : : "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm",
107 : : "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGTQQD3dC4H2D5GBj7vWvSQaaBv5cxi9gafk7NF3pnBju6dwKvH",
108 : : "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Txnt3siSujt9RCVYsx4qHZGc62TG4McvMGcAUjeuwZdduYEvFn",
109 : : "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGpWnsj83BHtEy5Zt8CcDr1UiRXuWCmTQLxEK9vbz5gPstX92JQ",
110 : : "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6N8ZMMXctdiCjxTNq964yKkwrkBJJwpzZS4HS2fxvyYUA4q2Xe4",
111 : : "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fEQ3Qen6J",
112 : : "xprv9s2SPatNQ9Vc6GTbVMFPFo7jsaZySyzk7L8n2uqKXJen3KUmvQNTuLh3fhZMBoG3G4ZW1N2kZuHEPY53qmbZzCHshoQnNf4GvELZfqTUrcv",
113 : : "xpub661no6RGEX3uJkY4bNnPcw4URcQTrSibUZ4NqJEw5eBkv7ovTwgiT91XX27VbEXGENhYRCf7hyEbWrR3FewATdCEebj6znwMfQkhRYHRLpJ",
114 : : "xprv9s21ZrQH4r4TsiLvyLXqM9P7k1K3EYhA1kkD6xuquB5i39AU8KF42acDyL3qsDbU9NmZn6MsGSUYZEsuoePmjzsB3eFKSUEh3Gu1N3cqVUN",
115 : : "xpub661MyMwAuDcm6CRQ5N4qiHKrJ39Xe1R1NyfouMKTTWcguwVcfrZJaNvhpebzGerh7gucBvzEQWRugZDuDXjNDRmXzSZe4c7mnTK97pTvGS8",
116 : : "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHGMQzT7ayAmfo4z3gY5KfbrZWZ6St24UVf2Qgo6oujFktLHdHY4",
117 : : "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHPmHJiEDXkTiJTVV9rHEBUem2mwVbbNfvT2MTcAqj3nesx8uBf9",
118 : : "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx",
119 : : "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD5SDKr24z3aiUvKr9bJpdrcLg1y3G",
120 : : "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Q5JXayek4PRsn35jii4veMimro1xefsM58PgBMrvdYre8QyULY",
121 : : "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHL"
122 : : };
123 : :
124 : 4 : void RunTest(const TestVector& test)
125 : : {
126 [ - + ]: 4 : std::vector<std::byte> seed{ParseHex<std::byte>(test.strHexMaster)};
127 [ - + ]: 4 : CExtKey key;
128 [ - + ]: 4 : CExtPubKey pubkey;
129 [ - + + - ]: 4 : key.SetSeed(seed);
130 [ + - ]: 4 : pubkey = key.Neuter();
131 [ + + ]: 21 : for (const TestDerivation &derive : test.vDerive) {
132 : 17 : unsigned char data[74];
133 [ + - ]: 17 : key.Encode(data);
134 [ + - ]: 17 : pubkey.Encode(data);
135 : :
136 : : // Test private key
137 [ + - + - : 34 : BOOST_CHECK(EncodeExtKey(key) == derive.prv);
+ - + - ]
138 [ + - + - : 34 : BOOST_CHECK(DecodeExtKey(derive.prv) == key); //ensure a base58 decoded key also matches
+ - + - ]
139 : :
140 : : // Test public key
141 [ + - + - : 34 : BOOST_CHECK(EncodeExtPubKey(pubkey) == derive.pub);
+ - + - ]
142 [ + - + - : 34 : BOOST_CHECK(DecodeExtPubKey(derive.pub) == pubkey); //ensure a base58 decoded pubkey also matches
+ - + - ]
143 : :
144 : : // Derive new keys
145 [ + - ]: 17 : CExtKey keyNew;
146 [ + - + - : 34 : BOOST_CHECK(key.Derive(keyNew, derive.nChild));
+ - + - ]
147 [ + - ]: 17 : CExtPubKey pubkeyNew = keyNew.Neuter();
148 [ + + ]: 17 : if (!(derive.nChild & BIP32_HARDENED_FLAG)) {
149 : : // Compare with public derivation
150 [ + - ]: 10 : CExtPubKey pubkeyNew2;
151 [ + - + - : 20 : BOOST_CHECK(pubkey.Derive(pubkeyNew2, derive.nChild));
+ - + - ]
152 [ + - + - ]: 20 : BOOST_CHECK(pubkeyNew == pubkeyNew2);
153 : 10 : }
154 [ + - ]: 17 : key = keyNew;
155 : 17 : pubkey = pubkeyNew;
156 : 17 : }
157 : 4 : }
158 : :
159 : : } // namespace
160 : :
161 : : BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup)
162 : :
163 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(bip32_test1) {
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
164 : 1 : RunTest(test1);
165 : 1 : }
166 : :
167 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(bip32_test2) {
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
168 : 1 : RunTest(test2);
169 : 1 : }
170 : :
171 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(bip32_test3) {
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
172 : 1 : RunTest(test3);
173 : 1 : }
174 : :
175 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(bip32_test4) {
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
176 : 1 : RunTest(test4);
177 : 1 : }
178 : :
179 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(bip32_test5) {
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
180 [ + + ]: 17 : for (const auto& str : TEST5) {
181 : 16 : auto dec_extkey = DecodeExtKey(str);
182 [ + - ]: 16 : auto dec_extpubkey = DecodeExtPubKey(str);
183 [ + - + - : 48 : BOOST_CHECK_MESSAGE(!dec_extkey.key.IsValid(), "Decoding '" + str + "' as xprv should fail");
+ - ]
184 [ + - + - : 48 : BOOST_CHECK_MESSAGE(!dec_extpubkey.pubkey.IsValid(), "Decoding '" + str + "' as xpub should fail");
+ - ]
185 : 16 : }
186 : 1 : }
187 : :
188 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(bip32_derive_ext_key)
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
189 : : {
190 : 1 : const CExtKey master{DecodeExtKey(test1.vDerive[0].prv)};
191 [ + - ]: 1 : const std::vector<uint32_t> path{test1.vDerive[0].nChild, test1.vDerive[1].nChild};
192 [ + - ]: 1 : const auto derived{DeriveExtKey(master, path)};
193 [ + - + - : 2 : BOOST_REQUIRE(derived);
+ - ]
194 [ + - + - : 2 : BOOST_CHECK(EncodeExtKey(derived->first) == test1.vDerive[2].prv);
+ - + - ]
195 : :
196 [ + - ]: 1 : KeyOriginInfo expected_origin;
197 [ + - ]: 1 : expected_origin.fingerprint = master.id_key_fingerprint();
198 [ + - ]: 1 : expected_origin.path = path;
199 [ + - + - : 2 : BOOST_CHECK(derived->second == expected_origin);
+ - ]
200 : :
201 [ + - ]: 1 : const auto root{DeriveExtKey(master, {})};
202 [ + - + - : 2 : BOOST_REQUIRE(root);
+ - ]
203 [ + - + - : 2 : BOOST_CHECK(root->first == master);
+ - ]
204 [ + - ]: 1 : expected_origin.path.clear();
205 [ + - + - : 2 : BOOST_CHECK(root->second == expected_origin);
+ - ]
206 : :
207 [ + - ]: 1 : CExtKey max_depth{master};
208 [ + + ]: 256 : for (auto i{0}; i++ < 255;) {
209 [ + - ]: 255 : CExtKey next_key;
210 [ + - + - : 510 : BOOST_REQUIRE(max_depth.Derive(next_key, 0));
+ - + - ]
211 [ + - ]: 255 : max_depth = next_key;
212 : 255 : }
213 [ + - + - : 3 : BOOST_CHECK(!DeriveExtKey(max_depth, {0}));
+ - + - -
+ ]
214 [ + - + - ]: 3 : }
215 : :
216 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(bip32_has_hardened_derivation)
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
217 : : {
218 : 1 : const std::vector<uint32_t> empty;
219 [ + - ]: 1 : const std::vector<uint32_t> unhardened{0, 1, 2};
220 [ + - ]: 1 : const std::vector<uint32_t> hardened{BIP32_HARDENED_FLAG};
221 [ + - ]: 1 : const std::vector<uint32_t> mixed{0, BIP32_HARDENED_FLAG | 1, 2};
222 [ + - - + : 2 : BOOST_CHECK(!HasHardenedDerivation(empty));
+ - + - +
- ]
223 [ + - - + : 2 : BOOST_CHECK(!HasHardenedDerivation(unhardened));
+ - + - +
- ]
224 [ + - - + : 2 : BOOST_CHECK(HasHardenedDerivation(hardened));
+ - + - +
- ]
225 [ + - - + : 2 : BOOST_CHECK(HasHardenedDerivation(mixed));
+ - + - ]
226 : 1 : }
227 : :
228 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(bip32_max_depth) {
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
229 [ + - ]: 1 : CExtKey key_parent{DecodeExtKey(test1.vDerive[0].prv)}, key_child;
230 [ + - ]: 1 : CExtPubKey pubkey_parent{DecodeExtPubKey(test1.vDerive[0].pub)}, pubkey_child;
231 : :
232 : : // We can derive up to the 255th depth..
233 [ + + ]: 256 : for (auto i = 0; i++ < 255;) {
234 [ + - + - : 510 : BOOST_CHECK(key_parent.Derive(key_child, 0));
+ - ]
235 : 255 : std::swap(key_parent, key_child);
236 [ + - + - : 510 : BOOST_CHECK(pubkey_parent.Derive(pubkey_child, 0));
+ - ]
237 : 255 : std::swap(pubkey_parent, pubkey_child);
238 : : }
239 : :
240 : : // But trying to derive a non-existent 256th depth will fail!
241 [ + - + - : 2 : BOOST_CHECK(key_parent.nDepth == 255);
+ - ]
242 [ + - + - : 2 : BOOST_CHECK(pubkey_parent.nDepth == 255);
+ - ]
243 [ + - + - : 2 : BOOST_CHECK(!key_parent.Derive(key_child, 0));
+ - + - ]
244 [ + - + - : 2 : BOOST_CHECK(!pubkey_parent.Derive(pubkey_child, 0));
+ - ]
245 : 1 : }
246 : :
247 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(parse_hd_keypath)
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
248 : : {
249 : 1 : std::vector<uint32_t> keypath;
250 : :
251 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1", keypath));
+ - + - +
- ]
252 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("///////////////////////////", keypath));
+ - + - +
- ]
253 : :
254 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1'/1", keypath));
+ - + - +
- ]
255 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("//////////////////////////'/", keypath));
+ - + - +
- ]
256 : :
257 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/", keypath));
+ - + - +
- ]
258 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("1///////////////////////////", keypath));
+ - + - +
- ]
259 : :
260 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1'/", keypath));
+ - + - +
- ]
261 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("1/'//////////////////////////", keypath));
+ - + - +
- ]
262 : :
263 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("", keypath));
+ - + - +
- ]
264 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath(" ", keypath));
+ - + - +
- ]
265 : :
266 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("0", keypath));
+ - + - +
- ]
267 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("O", keypath));
+ - + - +
- ]
268 : :
269 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("0000'/0000'/0000'", keypath));
+ - + - +
- ]
270 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("0000,/0000,/0000,", keypath));
+ - + - +
- ]
271 : :
272 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("01234", keypath));
+ - + - +
- ]
273 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("0x1234", keypath));
+ - + - +
- ]
274 : :
275 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("1", keypath));
+ - + - +
- ]
276 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath(" 1", keypath));
+ - + - +
- ]
277 : :
278 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("42", keypath));
+ - + - +
- ]
279 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m42", keypath));
+ - + - +
- ]
280 : :
281 : : // A path element's numeric part is capped at 2^31-1; the top bit is
282 : : // reserved for the hardened marker (h or ').
283 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("2147483647", keypath)); // 0x7fffffff, largest normal index
+ - + - +
- ]
284 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("2147483648", keypath)); // 0x80000000, would set the hardened bit
+ - + - +
- ]
285 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("4294967295", keypath)); // 0xffffffff
+ - + - +
- ]
286 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("4294967296", keypath)); // uint32_t max + 1
+ - + - +
- ]
287 : :
288 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m", keypath));
+ - + - +
- ]
289 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("n", keypath));
+ - + - +
- ]
290 : :
291 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/", keypath));
+ - + - +
- ]
292 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("n/", keypath));
+ - + - +
- ]
293 : :
294 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0", keypath));
+ - + - +
- ]
295 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("n/0", keypath));
+ - + - +
- ]
296 : :
297 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0'", keypath));
+ - + - +
- ]
298 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0''", keypath));
+ - + - +
- ]
299 : :
300 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0h", keypath));
+ - + - +
- ]
301 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0hh", keypath));
+ - + - +
- ]
302 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0x", keypath));
+ - + - +
- ]
303 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0a", keypath));
+ - + - +
- ]
304 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0G", keypath));
+ - + - +
- ]
305 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/h0", keypath));
+ - + - +
- ]
306 : :
307 [ + - ]: 1 : keypath.clear();
308 [ + - + - : 2 : BOOST_REQUIRE(ParseHDKeypath("m/0h/1h/2h", keypath));
+ - + - +
- ]
309 [ + - - + : 1 : BOOST_REQUIRE_EQUAL(keypath.size(), 3);
+ - ]
310 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(keypath[0], BIP32_HARDENED_FLAG);
311 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(keypath[1], BIP32_HARDENED_FLAG | 1);
312 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(keypath[2], BIP32_HARDENED_FLAG | 2);
313 : :
314 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0'/0'", keypath));
+ - + - +
- ]
315 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0h/0h", keypath));
+ - + - +
- ]
316 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0'/0h", keypath));
+ - + - +
- ]
317 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/'0/0'", keypath));
+ - + - +
- ]
318 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/h0/0'", keypath));
+ - + - +
- ]
319 : :
320 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0/0", keypath));
+ - + - +
- ]
321 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("n/0/0", keypath));
+ - + - +
- ]
322 : :
323 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0/0/00", keypath));
+ - + - +
- ]
324 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0/0/f00", keypath));
+ - + - +
- ]
325 : :
326 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0/0/000000000000000000000000000000000000000000000000000000000000000000000000000000000000", keypath));
+ - + - +
- ]
327 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/1/1/111111111111111111111111111111111111111111111111111111111111111111111111111111111111", keypath));
+ - + - +
- ]
328 : :
329 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0/00/0", keypath));
+ - + - +
- ]
330 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0'/00/'0", keypath));
+ - + - +
- ]
331 : :
332 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/1/", keypath));
+ - + - +
- ]
333 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/1//", keypath));
+ - + - +
- ]
334 : :
335 : : // The cap applies to every element, wherever it sits in the path.
336 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/2147483647", keypath));
+ - + - +
- ]
337 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/2147483648", keypath));
+ - + - +
- ]
338 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/4294967295", keypath));
+ - + - +
- ]
339 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/4294967296", keypath));
+ - + - +
- ]
340 : :
341 [ + - + - : 2 : BOOST_CHECK(ParseHDKeypath("m/0/2147483647", keypath));
+ - + - +
- ]
342 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0/2147483648", keypath));
+ - + - +
- ]
343 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0/4294967295", keypath));
+ - + - +
- ]
344 [ + - + - : 2 : BOOST_CHECK(!ParseHDKeypath("m/0/4294967296", keypath));
+ - + - ]
345 : 1 : }
346 : :
347 : : BOOST_AUTO_TEST_SUITE_END()
|