LCOV - code coverage report
Current view: top level - src/test - bip32_tests.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 98.1 % 264 259
Test Date: 2026-10-11 07:59:32 Functions: 100.0 % 25 25
Branches: 50.1 % 1838 921

             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                 :       10971 : 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         [ -  + ]:         636 :     explicit TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {}
      31                 :             : 
      32                 :        2703 :     TestVector& operator()(std::string pub, std::string prv, unsigned int nChild) {
      33                 :        2703 :         vDerive.emplace_back();
      34                 :        2703 :         TestDerivation &der = vDerive.back();
      35                 :        2703 :         der.pub = pub;
      36                 :        2703 :         der.prv = prv;
      37                 :        2703 :         der.nChild = nChild;
      38                 :        2703 :         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                 :             :         // Test serialization round trip
     133                 :          17 :         DataStream ss{};
     134         [ +  - ]:          17 :         ss << key;
     135         [ +  - ]:          17 :         ss << pubkey;
     136   [ +  -  -  +  :          17 :         BOOST_CHECK_EQUAL(ss.size(), 2 * BIP32_EXTKEY_SIZE);
                   +  - ]
     137         [ +  - ]:          17 :         CExtKey key_deser;
     138         [ +  - ]:          17 :         CExtPubKey pubkey_deser;
     139         [ +  - ]:          17 :         ss >> key_deser;
     140         [ +  - ]:          17 :         ss >> pubkey_deser;
     141   [ +  -  +  -  :          34 :         BOOST_CHECK(key_deser == key);
                   +  - ]
     142   [ +  -  +  -  :          34 :         BOOST_CHECK(pubkey_deser == pubkey);
                   +  - ]
     143                 :             : 
     144                 :             :         // Test private key
     145   [ +  -  +  -  :          34 :         BOOST_CHECK(EncodeExtKey(key) == derive.prv);
             +  -  +  - ]
     146   [ +  -  +  -  :          34 :         BOOST_CHECK(DecodeExtKey(derive.prv) == key); //ensure a base58 decoded key also matches
             +  -  +  - ]
     147                 :             : 
     148                 :             :         // Test public key
     149   [ +  -  +  -  :          34 :         BOOST_CHECK(EncodeExtPubKey(pubkey) == derive.pub);
             +  -  +  - ]
     150   [ +  -  +  -  :          34 :         BOOST_CHECK(DecodeExtPubKey(derive.pub) == pubkey); //ensure a base58 decoded pubkey also matches
             +  -  +  - ]
     151                 :             : 
     152                 :             :         // Derive new keys
     153         [ +  - ]:          17 :         CExtKey keyNew;
     154   [ +  -  +  -  :          34 :         BOOST_CHECK(key.Derive(keyNew, derive.nChild));
             +  -  +  - ]
     155         [ +  - ]:          17 :         CExtPubKey pubkeyNew = keyNew.Neuter();
     156         [ +  + ]:          17 :         if (!(derive.nChild & BIP32_HARDENED_FLAG)) {
     157                 :             :             // Compare with public derivation
     158         [ +  - ]:          10 :             CExtPubKey pubkeyNew2;
     159   [ +  -  +  -  :          20 :             BOOST_CHECK(pubkey.Derive(pubkeyNew2, derive.nChild));
             +  -  +  - ]
     160   [ +  -  +  - ]:          20 :             BOOST_CHECK(pubkeyNew == pubkeyNew2);
     161                 :          10 :         }
     162         [ +  - ]:          17 :         key = keyNew;
     163                 :          17 :         pubkey = pubkeyNew;
     164                 :          17 :     }
     165                 :           4 : }
     166                 :             : 
     167                 :             : }  // namespace
     168                 :             : 
     169                 :             : BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup)
     170                 :             : 
     171   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_test1) {
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     172                 :           1 :     RunTest(test1);
     173                 :           1 : }
     174                 :             : 
     175   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_test2) {
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     176                 :           1 :     RunTest(test2);
     177                 :           1 : }
     178                 :             : 
     179   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_test3) {
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     180                 :           1 :     RunTest(test3);
     181                 :           1 : }
     182                 :             : 
     183   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_test4) {
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     184                 :           1 :     RunTest(test4);
     185                 :           1 : }
     186                 :             : 
     187   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_test5) {
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     188         [ +  + ]:          17 :     for (const auto& str : TEST5) {
     189                 :          16 :         auto dec_extkey = DecodeExtKey(str);
     190         [ +  - ]:          16 :         auto dec_extpubkey = DecodeExtPubKey(str);
     191   [ +  -  +  -  :          48 :         BOOST_CHECK_MESSAGE(!dec_extkey.key.IsValid(), "Decoding '" + str + "' as xprv should fail");
                   +  - ]
     192   [ +  -  +  -  :          48 :         BOOST_CHECK_MESSAGE(!dec_extpubkey.pubkey.IsValid(), "Decoding '" + str + "' as xpub should fail");
                   +  - ]
     193                 :          16 :     }
     194                 :           1 : }
     195                 :             : 
     196   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_deserialize_invalid)
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     197                 :             : {
     198                 :             :     // A serialized extended key is exactly BIP32_EXTKEY_SIZE bytes. A shorter
     199                 :             :     // stream must throw rather than read past the end.
     200         [ +  + ]:          75 :     for (size_t len{0}; len < BIP32_EXTKEY_SIZE; ++len) {
     201         [ +  - ]:          74 :         CExtKey key;
     202         [ +  - ]:          74 :         CExtPubKey pubkey;
     203   [ +  -  +  -  :         222 :         DataStream ss_key{std::vector<unsigned char>(len)};
                   +  - ]
     204   [ +  -  +  -  :         222 :         DataStream ss_pubkey{std::vector<unsigned char>(len)};
                   +  - ]
     205   [ +  -  -  +  :         148 :         BOOST_CHECK_THROW(ss_key >> key, std::ios_base::failure);
          -  -  -  -  -  
             +  +  -  +  
                      - ]
     206   [ +  -  -  +  :         148 :         BOOST_CHECK_THROW(ss_pubkey >> pubkey, std::ios_base::failure);
          -  -  -  -  -  
             +  +  -  +  
                      - ]
     207                 :          74 :     }
     208                 :             : 
     209                 :             :     // Serialize a valid depth-0 xprv/xpub to mutate below.
     210                 :           1 :     const CExtKey master{DecodeExtKey(test1.vDerive[0].prv)};
     211         [ +  - ]:           1 :     const CExtPubKey master_pub{master.Neuter()};
     212   [ +  -  +  -  :           2 :     BOOST_REQUIRE(master.nDepth == 0);
                   +  - ]
     213                 :           1 :     std::vector<unsigned char> key_bytes, pubkey_bytes;
     214                 :           1 :     {
     215                 :           1 :         DataStream ss{};
     216         [ +  - ]:           1 :         ss << master;
     217                 :           1 :         const auto ss_span{MakeUCharSpan(ss)};
     218         [ +  - ]:           1 :         key_bytes.assign(ss_span.begin(), ss_span.end());
     219                 :           1 :         DataStream sp{};
     220         [ +  - ]:           1 :         sp << master_pub;
     221                 :           1 :         const auto sp_span{MakeUCharSpan(sp)};
     222         [ +  - ]:           1 :         pubkey_bytes.assign(sp_span.begin(), sp_span.end());
     223                 :           1 :     }
     224   [ +  -  -  +  :           1 :     BOOST_CHECK_EQUAL(key_bytes.size(), BIP32_EXTKEY_SIZE);
                   +  - ]
     225   [ +  -  -  +  :           1 :     BOOST_CHECK_EQUAL(pubkey_bytes.size(), BIP32_EXTKEY_SIZE);
                   +  - ]
     226                 :             : 
     227                 :             :     // A longer stream is not invalid: exactly BIP32_EXTKEY_SIZE bytes are consumed
     228                 :             :     // and the trailing byte is left unread.
     229                 :           1 :     {
     230         [ +  - ]:           1 :         std::vector<unsigned char> extra{key_bytes};
     231         [ +  - ]:           1 :         extra.push_back(0);
     232   [ -  +  +  - ]:           1 :         DataStream ss{extra};
     233         [ +  - ]:           1 :         CExtKey key;
     234         [ +  - ]:           1 :         ss >> key;
     235   [ +  -  +  -  :           2 :         BOOST_CHECK(key == master);
                   +  - ]
     236   [ +  -  -  +  :           1 :         BOOST_CHECK_EQUAL(ss.size(), 1);
                   +  - ]
     237                 :           1 :     }
     238                 :           1 :     {
     239         [ +  - ]:           1 :         std::vector<unsigned char> extra{pubkey_bytes};
     240         [ +  - ]:           1 :         extra.push_back(0);
     241   [ -  +  +  - ]:           1 :         DataStream ss{extra};
     242         [ +  - ]:           1 :         CExtPubKey pubkey;
     243         [ +  - ]:           1 :         ss >> pubkey;
     244   [ +  -  +  -  :           2 :         BOOST_CHECK(pubkey == master_pub);
                   +  - ]
     245   [ +  -  -  +  :           1 :         BOOST_CHECK_EQUAL(ss.size(), 1);
                   +  - ]
     246                 :           1 :     }
     247                 :             : 
     248                 :           4 :     const auto deser_extkey{[](std::vector<unsigned char> bytes) {
     249         [ -  + ]:           3 :         DataStream ss{bytes};
     250         [ +  - ]:           3 :         CExtKey key;
     251         [ +  - ]:           3 :         ss >> key;
     252                 :           3 :         return key;
     253                 :           3 :     }};
     254                 :           4 :     const auto deser_extpubkey{[](std::vector<unsigned char> bytes) {
     255         [ -  + ]:           3 :         DataStream ss{bytes};
     256         [ +  - ]:           3 :         CExtPubKey pubkey;
     257         [ +  - ]:           3 :         ss >> pubkey;
     258                 :           3 :         return pubkey;
     259                 :           3 :     }};
     260                 :             : 
     261                 :             :     // Non-zero private key prefix (offset 41) => invalid.
     262                 :           1 :     {
     263         [ +  - ]:           1 :         auto bytes{key_bytes};
     264         [ +  - ]:           1 :         bytes[41] = 1;
     265   [ +  -  +  -  :           2 :         BOOST_CHECK(!deser_extkey(bytes).key.IsValid());
             +  -  +  - ]
     266                 :           0 :     }
     267                 :             :     // Non-zero child index with nDepth == 0 (offset 8) => invalid.
     268                 :           1 :     {
     269         [ +  - ]:           1 :         auto bytes{key_bytes};
     270         [ +  - ]:           1 :         bytes[8] = 1;
     271   [ +  -  +  -  :           2 :         BOOST_CHECK(!deser_extkey(bytes).key.IsValid());
             +  -  +  - ]
     272                 :           0 :     }
     273                 :             :     // Non-zero parent fingerprint with nDepth == 0 (offset 1) => invalid.
     274                 :           1 :     {
     275         [ +  - ]:           1 :         auto bytes{key_bytes};
     276         [ +  - ]:           1 :         bytes[1] = 1;
     277   [ +  -  +  -  :           2 :         BOOST_CHECK(!deser_extkey(bytes).key.IsValid());
             +  -  +  - ]
     278                 :           0 :     }
     279                 :             :     // Invalid public key header (offset 41) => invalid.
     280                 :           1 :     {
     281         [ +  - ]:           1 :         auto bytes{pubkey_bytes};
     282         [ +  - ]:           1 :         bytes[41] = 0;
     283   [ +  -  +  -  :           2 :         BOOST_CHECK(!deser_extpubkey(bytes).pubkey.IsValid());
             +  -  +  - ]
     284                 :           0 :     }
     285                 :             :     // Non-zero child index with nDepth == 0 (offset 8) => invalid.
     286                 :           1 :     {
     287         [ +  - ]:           1 :         auto bytes{pubkey_bytes};
     288         [ +  - ]:           1 :         bytes[8] = 1;
     289   [ +  -  +  -  :           2 :         BOOST_CHECK(!deser_extpubkey(bytes).pubkey.IsValid());
             +  -  +  - ]
     290                 :           0 :     }
     291                 :             :     // Non-zero parent fingerprint with nDepth == 0 (offset 1) => invalid.
     292                 :           1 :     {
     293         [ +  - ]:           1 :         auto bytes{pubkey_bytes};
     294         [ +  - ]:           1 :         bytes[1] = 1;
     295   [ +  -  +  -  :           2 :         BOOST_CHECK(!deser_extpubkey(bytes).pubkey.IsValid());
             +  -  +  - ]
     296                 :           1 :     }
     297                 :           1 : }
     298                 :             : 
     299   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_derive_ext_key)
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     300                 :             : {
     301                 :           1 :     const CExtKey master{DecodeExtKey(test1.vDerive[0].prv)};
     302         [ +  - ]:           1 :     const std::vector<uint32_t> path{test1.vDerive[0].nChild, test1.vDerive[1].nChild};
     303         [ +  - ]:           1 :     const auto derived{DeriveExtKey(master, path)};
     304   [ +  -  +  -  :           2 :     BOOST_REQUIRE(derived);
                   +  - ]
     305   [ +  -  +  -  :           2 :     BOOST_CHECK(EncodeExtKey(derived->first) == test1.vDerive[2].prv);
             +  -  +  - ]
     306                 :             : 
     307         [ +  - ]:           1 :     KeyOriginInfo expected_origin;
     308         [ +  - ]:           1 :     expected_origin.fingerprint = master.id_key_fingerprint();
     309         [ +  - ]:           1 :     expected_origin.path = path;
     310   [ +  -  +  -  :           2 :     BOOST_CHECK(derived->second == expected_origin);
                   +  - ]
     311                 :             : 
     312         [ +  - ]:           1 :     const auto root{DeriveExtKey(master, {})};
     313   [ +  -  +  -  :           2 :     BOOST_REQUIRE(root);
                   +  - ]
     314   [ +  -  +  -  :           2 :     BOOST_CHECK(root->first == master);
                   +  - ]
     315         [ +  - ]:           1 :     expected_origin.path.clear();
     316   [ +  -  +  -  :           2 :     BOOST_CHECK(root->second == expected_origin);
                   +  - ]
     317                 :             : 
     318         [ +  - ]:           1 :     CExtKey max_depth{master};
     319         [ +  + ]:         256 :     for (auto i{0}; i++ < 255;) {
     320         [ +  - ]:         255 :         CExtKey next_key;
     321   [ +  -  +  -  :         510 :         BOOST_REQUIRE(max_depth.Derive(next_key, 0));
             +  -  +  - ]
     322         [ +  - ]:         255 :         max_depth = next_key;
     323                 :         255 :     }
     324   [ +  -  +  -  :           3 :     BOOST_CHECK(!DeriveExtKey(max_depth, {0}));
          +  -  +  -  -  
                      + ]
     325   [ +  -  +  - ]:           3 : }
     326                 :             : 
     327   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_has_hardened_derivation)
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     328                 :             : {
     329                 :           1 :     const std::vector<uint32_t> empty;
     330         [ +  - ]:           1 :     const std::vector<uint32_t> unhardened{0, 1, 2};
     331         [ +  - ]:           1 :     const std::vector<uint32_t> hardened{BIP32_HARDENED_FLAG};
     332         [ +  - ]:           1 :     const std::vector<uint32_t> mixed{0, BIP32_HARDENED_FLAG | 1, 2};
     333   [ +  -  -  +  :           2 :     BOOST_CHECK(!HasHardenedDerivation(empty));
          +  -  +  -  +  
                      - ]
     334   [ +  -  -  +  :           2 :     BOOST_CHECK(!HasHardenedDerivation(unhardened));
          +  -  +  -  +  
                      - ]
     335   [ +  -  -  +  :           2 :     BOOST_CHECK(HasHardenedDerivation(hardened));
          +  -  +  -  +  
                      - ]
     336   [ +  -  -  +  :           2 :     BOOST_CHECK(HasHardenedDerivation(mixed));
             +  -  +  - ]
     337                 :           1 : }
     338                 :             : 
     339   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(bip32_max_depth) {
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     340         [ +  - ]:           1 :     CExtKey key_parent{DecodeExtKey(test1.vDerive[0].prv)}, key_child;
     341         [ +  - ]:           1 :     CExtPubKey pubkey_parent{DecodeExtPubKey(test1.vDerive[0].pub)}, pubkey_child;
     342                 :             : 
     343                 :             :     // We can derive up to the 255th depth..
     344         [ +  + ]:         256 :     for (auto i = 0; i++ < 255;) {
     345   [ +  -  +  -  :         510 :         BOOST_CHECK(key_parent.Derive(key_child, 0));
                   +  - ]
     346                 :         255 :         std::swap(key_parent, key_child);
     347   [ +  -  +  -  :         510 :         BOOST_CHECK(pubkey_parent.Derive(pubkey_child, 0));
                   +  - ]
     348                 :         255 :         std::swap(pubkey_parent, pubkey_child);
     349                 :             :     }
     350                 :             : 
     351                 :             :     // But trying to derive a non-existent 256th depth will fail!
     352   [ +  -  +  -  :           2 :     BOOST_CHECK(key_parent.nDepth == 255);
                   +  - ]
     353   [ +  -  +  -  :           2 :     BOOST_CHECK(pubkey_parent.nDepth == 255);
                   +  - ]
     354   [ +  -  +  -  :           2 :     BOOST_CHECK(!key_parent.Derive(key_child, 0));
             +  -  +  - ]
     355   [ +  -  +  -  :           2 :     BOOST_CHECK(!pubkey_parent.Derive(pubkey_child, 0));
                   +  - ]
     356                 :           1 : }
     357                 :             : 
     358   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(parse_hd_keypath)
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
     359                 :             : {
     360                 :           1 :     std::vector<uint32_t> keypath;
     361                 :             : 
     362   [ +  -  +  -  :           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));
          +  -  +  -  +  
                      - ]
     363   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("///////////////////////////", keypath));
          +  -  +  -  +  
                      - ]
     364                 :             : 
     365   [ +  -  +  -  :           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));
          +  -  +  -  +  
                      - ]
     366   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("//////////////////////////'/", keypath));
          +  -  +  -  +  
                      - ]
     367                 :             : 
     368   [ +  -  +  -  :           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));
          +  -  +  -  +  
                      - ]
     369   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("1///////////////////////////", keypath));
          +  -  +  -  +  
                      - ]
     370                 :             : 
     371   [ +  -  +  -  :           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));
          +  -  +  -  +  
                      - ]
     372   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("1/'//////////////////////////", keypath));
          +  -  +  -  +  
                      - ]
     373                 :             : 
     374   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("", keypath));
          +  -  +  -  +  
                      - ]
     375   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath(" ", keypath));
          +  -  +  -  +  
                      - ]
     376                 :             : 
     377   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("0", keypath));
          +  -  +  -  +  
                      - ]
     378   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("O", keypath));
          +  -  +  -  +  
                      - ]
     379                 :             : 
     380   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("0000'/0000'/0000'", keypath));
          +  -  +  -  +  
                      - ]
     381   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("0000,/0000,/0000,", keypath));
          +  -  +  -  +  
                      - ]
     382                 :             : 
     383   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("01234", keypath));
          +  -  +  -  +  
                      - ]
     384   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("0x1234", keypath));
          +  -  +  -  +  
                      - ]
     385                 :             : 
     386   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("1", keypath));
          +  -  +  -  +  
                      - ]
     387   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath(" 1", keypath));
          +  -  +  -  +  
                      - ]
     388                 :             : 
     389   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("42", keypath));
          +  -  +  -  +  
                      - ]
     390   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m42", keypath));
          +  -  +  -  +  
                      - ]
     391                 :             : 
     392                 :             :     // A path element's numeric part is capped at 2^31-1; the top bit is
     393                 :             :     // reserved for the hardened marker (h or ').
     394   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("2147483647", keypath));  // 0x7fffffff, largest normal index
          +  -  +  -  +  
                      - ]
     395   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("2147483648", keypath)); // 0x80000000, would set the hardened bit
          +  -  +  -  +  
                      - ]
     396   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("4294967295", keypath)); // 0xffffffff
          +  -  +  -  +  
                      - ]
     397   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("4294967296", keypath)); // uint32_t max + 1
          +  -  +  -  +  
                      - ]
     398                 :             : 
     399   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m", keypath));
          +  -  +  -  +  
                      - ]
     400   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("n", keypath));
          +  -  +  -  +  
                      - ]
     401                 :             : 
     402   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/", keypath));
          +  -  +  -  +  
                      - ]
     403   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("n/", keypath));
          +  -  +  -  +  
                      - ]
     404                 :             : 
     405   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0", keypath));
          +  -  +  -  +  
                      - ]
     406   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("n/0", keypath));
          +  -  +  -  +  
                      - ]
     407                 :             : 
     408   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0'", keypath));
          +  -  +  -  +  
                      - ]
     409   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0''", keypath));
          +  -  +  -  +  
                      - ]
     410                 :             : 
     411   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0h", keypath));
          +  -  +  -  +  
                      - ]
     412   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0hh", keypath));
          +  -  +  -  +  
                      - ]
     413   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0x", keypath));
          +  -  +  -  +  
                      - ]
     414   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0a", keypath));
          +  -  +  -  +  
                      - ]
     415   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0G", keypath));
          +  -  +  -  +  
                      - ]
     416   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/h0", keypath));
          +  -  +  -  +  
                      - ]
     417                 :             : 
     418         [ +  - ]:           1 :     keypath.clear();
     419   [ +  -  +  -  :           2 :     BOOST_REQUIRE(ParseHDKeypath("m/0h/1h/2h", keypath));
          +  -  +  -  +  
                      - ]
     420   [ +  -  -  +  :           1 :     BOOST_REQUIRE_EQUAL(keypath.size(), 3);
                   +  - ]
     421   [ +  -  +  - ]:           1 :     BOOST_CHECK_EQUAL(keypath[0], BIP32_HARDENED_FLAG);
     422   [ +  -  +  - ]:           1 :     BOOST_CHECK_EQUAL(keypath[1], BIP32_HARDENED_FLAG | 1);
     423   [ +  -  +  - ]:           1 :     BOOST_CHECK_EQUAL(keypath[2], BIP32_HARDENED_FLAG | 2);
     424                 :             : 
     425   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0'/0'", keypath));
          +  -  +  -  +  
                      - ]
     426   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0h/0h", keypath));
          +  -  +  -  +  
                      - ]
     427   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0'/0h", keypath));
          +  -  +  -  +  
                      - ]
     428   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/'0/0'", keypath));
          +  -  +  -  +  
                      - ]
     429   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/h0/0'", keypath));
          +  -  +  -  +  
                      - ]
     430                 :             : 
     431   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0/0", keypath));
          +  -  +  -  +  
                      - ]
     432   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("n/0/0", keypath));
          +  -  +  -  +  
                      - ]
     433                 :             : 
     434   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0/0/00", keypath));
          +  -  +  -  +  
                      - ]
     435   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0/0/f00", keypath));
          +  -  +  -  +  
                      - ]
     436                 :             : 
     437   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0/0/000000000000000000000000000000000000000000000000000000000000000000000000000000000000", keypath));
          +  -  +  -  +  
                      - ]
     438   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/1/1/111111111111111111111111111111111111111111111111111111111111111111111111111111111111", keypath));
          +  -  +  -  +  
                      - ]
     439                 :             : 
     440   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0/00/0", keypath));
          +  -  +  -  +  
                      - ]
     441   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0'/00/'0", keypath));
          +  -  +  -  +  
                      - ]
     442                 :             : 
     443   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/1/", keypath));
          +  -  +  -  +  
                      - ]
     444   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/1//", keypath));
          +  -  +  -  +  
                      - ]
     445                 :             : 
     446                 :             :     // The cap applies to every element, wherever it sits in the path.
     447   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/2147483647", keypath));
          +  -  +  -  +  
                      - ]
     448   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/2147483648", keypath));
          +  -  +  -  +  
                      - ]
     449   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/4294967295", keypath));
          +  -  +  -  +  
                      - ]
     450   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/4294967296", keypath));
          +  -  +  -  +  
                      - ]
     451                 :             : 
     452   [ +  -  +  -  :           2 :     BOOST_CHECK(ParseHDKeypath("m/0/2147483647", keypath));
          +  -  +  -  +  
                      - ]
     453   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0/2147483648", keypath));
          +  -  +  -  +  
                      - ]
     454   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0/4294967295", keypath));
          +  -  +  -  +  
                      - ]
     455   [ +  -  +  -  :           2 :     BOOST_CHECK(!ParseHDKeypath("m/0/4294967296", keypath));
             +  -  +  - ]
     456                 :           1 : }
     457                 :             : 
     458                 :             : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1