LCOV - code coverage report
Current view: top level - src/test/fuzz - key.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 98.4 % 243 239
Test Date: 2024-09-01 05:20:30 Functions: 87.5 % 8 7
Branches: 50.8 % 654 332

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2020-2022 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 <chainparams.h>
       6                 :             : #include <key.h>
       7                 :             : #include <key_io.h>
       8                 :             : #include <outputtype.h>
       9                 :             : #include <policy/policy.h>
      10                 :             : #include <pubkey.h>
      11                 :             : #include <rpc/util.h>
      12                 :             : #include <script/keyorigin.h>
      13                 :             : #include <script/script.h>
      14                 :             : #include <script/sign.h>
      15                 :             : #include <script/signingprovider.h>
      16                 :             : #include <script/solver.h>
      17                 :             : #include <streams.h>
      18                 :             : #include <test/fuzz/FuzzedDataProvider.h>
      19                 :             : #include <test/fuzz/fuzz.h>
      20                 :             : #include <test/fuzz/util.h>
      21                 :             : #include <util/chaintype.h>
      22                 :             : #include <util/strencodings.h>
      23                 :             : 
      24                 :             : #include <array>
      25                 :             : #include <cassert>
      26                 :             : #include <cstddef>
      27                 :             : #include <cstdint>
      28                 :             : #include <numeric>
      29                 :             : #include <optional>
      30                 :             : #include <string>
      31                 :             : #include <vector>
      32                 :             : 
      33                 :           0 : void initialize_key()
      34                 :             : {
      35   [ #  #  #  #  :           0 :     static ECC_Context ecc_context{};
                   #  # ]
      36                 :           0 :     SelectParams(ChainType::REGTEST);
      37                 :           0 : }
      38                 :             : 
      39         [ +  - ]:         543 : FUZZ_TARGET(key, .init = initialize_key)
      40                 :             : {
      41                 :        1082 :     const CKey key = [&] {
      42                 :         541 :         CKey k;
      43         [ +  - ]:         541 :         k.Set(buffer.begin(), buffer.end(), true);
      44                 :         541 :         return k;
      45         [ +  - ]:         541 :     }();
      46   [ +  -  +  + ]:         541 :     if (!key.IsValid()) {
      47                 :           7 :         return;
      48                 :             :     }
      49                 :             : 
      50                 :             :     {
      51   [ +  -  +  -  :         534 :         assert(key.begin() + key.size() == key.end());
             +  -  +  - ]
      52   [ +  -  +  - ]:         534 :         assert(key.IsCompressed());
      53   [ +  -  +  - ]:         534 :         assert(key.size() == 32);
      54   [ +  -  +  -  :         534 :         assert(DecodeSecret(EncodeSecret(key)) == key);
             +  -  +  - ]
      55                 :             :     }
      56                 :             : 
      57                 :             :     {
      58                 :         534 :         CKey invalid_key;
      59   [ +  -  +  - ]:         534 :         assert(!(invalid_key == key));
      60   [ +  -  +  - ]:         534 :         assert(!invalid_key.IsCompressed());
      61   [ +  -  +  - ]:         534 :         assert(!invalid_key.IsValid());
      62   [ +  -  +  - ]:         534 :         assert(invalid_key.size() == 0);
      63                 :         534 :     }
      64                 :             : 
      65                 :             :     {
      66                 :         534 :         CKey uncompressed_key;
      67         [ +  - ]:         534 :         uncompressed_key.Set(buffer.begin(), buffer.end(), false);
      68   [ +  -  +  - ]:         534 :         assert(!(uncompressed_key == key));
      69   [ +  -  +  - ]:         534 :         assert(!uncompressed_key.IsCompressed());
      70   [ +  -  +  - ]:         534 :         assert(key.size() == 32);
      71   [ +  -  +  -  :         534 :         assert(uncompressed_key.begin() + uncompressed_key.size() == uncompressed_key.end());
             +  -  +  - ]
      72   [ +  -  +  - ]:         534 :         assert(uncompressed_key.IsValid());
      73                 :         534 :     }
      74                 :             : 
      75                 :             :     {
      76                 :         534 :         CKey copied_key;
      77   [ +  -  +  -  :         534 :         copied_key.Set(key.begin(), key.end(), key.IsCompressed());
             +  -  +  - ]
      78   [ +  -  +  - ]:         534 :         assert(copied_key == key);
      79                 :         534 :     }
      80                 :             : 
      81         [ +  - ]:         534 :     const uint256 random_uint256 = Hash(buffer);
      82                 :             : 
      83                 :             :     {
      84                 :         534 :         CKey child_key;
      85         [ +  - ]:         534 :         ChainCode child_chaincode;
      86         [ +  - ]:         534 :         const bool ok = key.Derive(child_key, child_chaincode, 0, random_uint256);
      87         [ +  - ]:         534 :         assert(ok);
      88   [ +  -  +  - ]:         534 :         assert(child_key.IsValid());
      89   [ +  -  +  - ]:         534 :         assert(!(child_key == key));
      90   [ +  -  +  - ]:         534 :         assert(child_chaincode != random_uint256);
      91                 :         534 :     }
      92                 :             : 
      93         [ +  - ]:         534 :     const CPubKey pubkey = key.GetPubKey();
      94                 :             : 
      95                 :             :     {
      96   [ +  -  +  - ]:         534 :         assert(pubkey.size() == 33);
      97   [ +  -  +  - ]:         534 :         assert(key.VerifyPubKey(pubkey));
      98   [ +  -  +  -  :         534 :         assert(pubkey.GetHash() != random_uint256);
                   +  - ]
      99   [ +  -  +  -  :         534 :         assert(pubkey.begin() + pubkey.size() == pubkey.end());
             +  -  +  - ]
     100   [ +  -  +  -  :         534 :         assert(pubkey.data() == pubkey.begin());
                   +  - ]
     101   [ +  -  +  - ]:         534 :         assert(pubkey.IsCompressed());
     102   [ +  -  +  - ]:         534 :         assert(pubkey.IsValid());
     103   [ +  -  +  - ]:         534 :         assert(pubkey.IsFullyValid());
     104   [ +  -  +  -  :         534 :         assert(HexToPubKey(HexStr(pubkey)) == pubkey);
          +  -  +  -  +  
                      - ]
     105   [ +  -  +  - ]:         534 :         assert(GetAllDestinationsForKey(pubkey).size() == 3);
     106                 :             :     }
     107                 :             : 
     108                 :             :     {
     109                 :         534 :         DataStream data_stream{};
     110         [ +  - ]:         534 :         pubkey.Serialize(data_stream);
     111                 :             : 
     112         [ +  - ]:         534 :         CPubKey pubkey_deserialized;
     113         [ +  - ]:         534 :         pubkey_deserialized.Unserialize(data_stream);
     114   [ +  -  +  - ]:         534 :         assert(pubkey_deserialized == pubkey);
     115                 :         534 :     }
     116                 :             : 
     117                 :             :     {
     118         [ +  - ]:         534 :         const CScript tx_pubkey_script = GetScriptForRawPubKey(pubkey);
     119   [ +  -  +  - ]:         534 :         assert(!tx_pubkey_script.IsPayToScriptHash());
     120   [ +  -  +  - ]:         534 :         assert(!tx_pubkey_script.IsPayToWitnessScriptHash());
     121   [ +  -  +  - ]:         534 :         assert(!tx_pubkey_script.IsPushOnly());
     122   [ +  -  +  - ]:         534 :         assert(!tx_pubkey_script.IsUnspendable());
     123   [ +  -  +  - ]:         534 :         assert(tx_pubkey_script.HasValidOps());
     124   [ +  -  +  - ]:         534 :         assert(tx_pubkey_script.size() == 35);
     125                 :             : 
     126   [ +  -  +  - ]:         534 :         const CScript tx_multisig_script = GetScriptForMultisig(1, {pubkey});
     127   [ +  -  +  - ]:         534 :         assert(!tx_multisig_script.IsPayToScriptHash());
     128   [ +  -  +  - ]:         534 :         assert(!tx_multisig_script.IsPayToWitnessScriptHash());
     129   [ +  -  +  - ]:         534 :         assert(!tx_multisig_script.IsPushOnly());
     130   [ +  -  +  - ]:         534 :         assert(!tx_multisig_script.IsUnspendable());
     131   [ +  -  +  - ]:         534 :         assert(tx_multisig_script.HasValidOps());
     132   [ +  -  +  - ]:         534 :         assert(tx_multisig_script.size() == 37);
     133                 :             : 
     134                 :         534 :         FillableSigningProvider fillable_signing_provider;
     135   [ +  -  +  - ]:         534 :         assert(!IsSegWitOutput(fillable_signing_provider, tx_pubkey_script));
     136   [ +  -  +  - ]:         534 :         assert(!IsSegWitOutput(fillable_signing_provider, tx_multisig_script));
     137   [ +  -  +  - ]:         534 :         assert(fillable_signing_provider.GetKeys().size() == 0);
     138   [ +  -  +  -  :         534 :         assert(!fillable_signing_provider.HaveKey(pubkey.GetID()));
                   +  - ]
     139                 :             : 
     140         [ +  - ]:         534 :         const bool ok_add_key = fillable_signing_provider.AddKey(key);
     141         [ +  - ]:         534 :         assert(ok_add_key);
     142   [ +  -  +  -  :         534 :         assert(fillable_signing_provider.HaveKey(pubkey.GetID()));
                   +  - ]
     143                 :             : 
     144                 :         534 :         FillableSigningProvider fillable_signing_provider_pub;
     145   [ +  -  +  -  :         534 :         assert(!fillable_signing_provider_pub.HaveKey(pubkey.GetID()));
                   +  - ]
     146                 :             : 
     147         [ +  - ]:         534 :         const bool ok_add_key_pubkey = fillable_signing_provider_pub.AddKeyPubKey(key, pubkey);
     148         [ +  - ]:         534 :         assert(ok_add_key_pubkey);
     149   [ +  -  +  -  :         534 :         assert(fillable_signing_provider_pub.HaveKey(pubkey.GetID()));
                   +  - ]
     150                 :             : 
     151                 :         534 :         TxoutType which_type_tx_pubkey;
     152         [ +  - ]:         534 :         const bool is_standard_tx_pubkey = IsStandard(tx_pubkey_script, std::nullopt, which_type_tx_pubkey);
     153         [ +  - ]:         534 :         assert(is_standard_tx_pubkey);
     154         [ +  - ]:         534 :         assert(which_type_tx_pubkey == TxoutType::PUBKEY);
     155                 :             : 
     156                 :         534 :         TxoutType which_type_tx_multisig;
     157         [ +  - ]:         534 :         const bool is_standard_tx_multisig = IsStandard(tx_multisig_script, std::nullopt, which_type_tx_multisig);
     158         [ +  - ]:         534 :         assert(is_standard_tx_multisig);
     159         [ +  - ]:         534 :         assert(which_type_tx_multisig == TxoutType::MULTISIG);
     160                 :             : 
     161                 :         534 :         std::vector<std::vector<unsigned char>> v_solutions_ret_tx_pubkey;
     162         [ +  - ]:         534 :         const TxoutType outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey);
     163         [ +  - ]:         534 :         assert(outtype_tx_pubkey == TxoutType::PUBKEY);
     164         [ +  - ]:         534 :         assert(v_solutions_ret_tx_pubkey.size() == 1);
     165         [ +  - ]:         534 :         assert(v_solutions_ret_tx_pubkey[0].size() == 33);
     166                 :             : 
     167                 :         534 :         std::vector<std::vector<unsigned char>> v_solutions_ret_tx_multisig;
     168         [ +  - ]:         534 :         const TxoutType outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig);
     169         [ +  - ]:         534 :         assert(outtype_tx_multisig == TxoutType::MULTISIG);
     170         [ +  - ]:         534 :         assert(v_solutions_ret_tx_multisig.size() == 3);
     171         [ +  - ]:         534 :         assert(v_solutions_ret_tx_multisig[0].size() == 1);
     172         [ +  - ]:         534 :         assert(v_solutions_ret_tx_multisig[1].size() == 33);
     173         [ +  - ]:         534 :         assert(v_solutions_ret_tx_multisig[2].size() == 1);
     174                 :             : 
     175                 :         534 :         OutputType output_type{};
     176         [ +  - ]:         534 :         const CTxDestination tx_destination = GetDestinationForKey(pubkey, output_type);
     177         [ +  - ]:         534 :         assert(output_type == OutputType::LEGACY);
     178   [ +  -  +  - ]:         534 :         assert(IsValidDestination(tx_destination));
     179   [ +  -  +  - ]:         534 :         assert(PKHash{pubkey} == *std::get_if<PKHash>(&tx_destination));
     180                 :             : 
     181         [ +  - ]:         534 :         const CScript script_for_destination = GetScriptForDestination(tx_destination);
     182   [ +  -  +  - ]:         534 :         assert(script_for_destination.size() == 25);
     183                 :             : 
     184         [ +  - ]:         534 :         const std::string destination_address = EncodeDestination(tx_destination);
     185   [ +  -  +  -  :         534 :         assert(DecodeDestination(destination_address) == tx_destination);
                   +  - ]
     186                 :             : 
     187         [ +  - ]:         534 :         const CPubKey pubkey_from_address_string = AddrToPubKey(fillable_signing_provider, destination_address);
     188   [ +  -  +  - ]:         534 :         assert(pubkey_from_address_string == pubkey);
     189                 :             : 
     190         [ +  - ]:         534 :         CKeyID key_id = pubkey.GetID();
     191   [ +  -  +  - ]:         534 :         assert(!key_id.IsNull());
     192   [ +  -  +  - ]:         534 :         assert(key_id == CKeyID{key_id});
     193   [ +  -  +  -  :         534 :         assert(key_id == GetKeyForDestination(fillable_signing_provider, tx_destination));
                   +  - ]
     194                 :             : 
     195         [ +  - ]:         534 :         CPubKey pubkey_out;
     196         [ +  - ]:         534 :         const bool ok_get_pubkey = fillable_signing_provider.GetPubKey(key_id, pubkey_out);
     197         [ +  - ]:         534 :         assert(ok_get_pubkey);
     198                 :             : 
     199                 :         534 :         CKey key_out;
     200         [ +  - ]:         534 :         const bool ok_get_key = fillable_signing_provider.GetKey(key_id, key_out);
     201         [ +  - ]:         534 :         assert(ok_get_key);
     202   [ +  -  +  - ]:         534 :         assert(fillable_signing_provider.GetKeys().size() == 1);
     203   [ +  -  +  - ]:         534 :         assert(fillable_signing_provider.HaveKey(key_id));
     204                 :             : 
     205                 :         534 :         KeyOriginInfo key_origin_info;
     206         [ +  - ]:         534 :         const bool ok_get_key_origin = fillable_signing_provider.GetKeyOrigin(key_id, key_origin_info);
     207         [ +  - ]:         534 :         assert(!ok_get_key_origin);
     208                 :         534 :     }
     209                 :             : 
     210                 :             :     {
     211   [ +  -  +  -  :         534 :         const std::vector<unsigned char> vch_pubkey{pubkey.begin(), pubkey.end()};
                   +  - ]
     212   [ +  -  +  - ]:         534 :         assert(CPubKey::ValidSize(vch_pubkey));
     213   [ +  -  +  -  :         534 :         assert(!CPubKey::ValidSize({pubkey.begin(), pubkey.begin() + pubkey.size() - 1}));
          +  -  +  -  +  
                -  +  - ]
     214                 :             : 
     215   [ +  -  +  - ]:         534 :         const CPubKey pubkey_ctor_1{vch_pubkey};
     216   [ +  -  +  - ]:         534 :         assert(pubkey == pubkey_ctor_1);
     217                 :             : 
     218         [ +  - ]:         534 :         const CPubKey pubkey_ctor_2{vch_pubkey.begin(), vch_pubkey.end()};
     219   [ +  -  +  - ]:         534 :         assert(pubkey == pubkey_ctor_2);
     220                 :             : 
     221         [ +  - ]:         534 :         CPubKey pubkey_set;
     222         [ +  - ]:         534 :         pubkey_set.Set(vch_pubkey.begin(), vch_pubkey.end());
     223   [ +  -  +  - ]:         534 :         assert(pubkey == pubkey_set);
     224                 :         534 :     }
     225                 :             : 
     226                 :             :     {
     227         [ +  - ]:         534 :         const CPubKey invalid_pubkey{};
     228   [ +  -  +  - ]:         534 :         assert(!invalid_pubkey.IsValid());
     229   [ +  -  +  - ]:         534 :         assert(!invalid_pubkey.IsFullyValid());
     230   [ +  -  +  - ]:         534 :         assert(!(pubkey == invalid_pubkey));
     231   [ +  -  +  - ]:         534 :         assert(pubkey != invalid_pubkey);
     232   [ +  -  +  - ]:         534 :         assert(pubkey < invalid_pubkey);
     233                 :         534 :     }
     234                 :             : 
     235                 :             :     {
     236                 :             :         // Cover CPubKey's operator[](unsigned int pos)
     237                 :         534 :         unsigned int sum = 0;
     238   [ +  -  +  + ]:       18156 :         for (size_t i = 0; i < pubkey.size(); ++i) {
     239         [ +  - ]:       17622 :             sum += pubkey[i];
     240                 :       17622 :         }
     241   [ +  -  +  -  :         534 :         assert(std::accumulate(pubkey.begin(), pubkey.end(), 0U) == sum);
             +  -  +  - ]
     242                 :         534 :     }
     243                 :             : 
     244                 :             :     {
     245                 :         534 :         CPubKey decompressed_pubkey = pubkey;
     246   [ +  -  +  - ]:         534 :         assert(decompressed_pubkey.IsCompressed());
     247                 :             : 
     248         [ +  - ]:         534 :         const bool ok = decompressed_pubkey.Decompress();
     249         [ +  - ]:         534 :         assert(ok);
     250   [ +  -  +  - ]:         534 :         assert(!decompressed_pubkey.IsCompressed());
     251   [ +  -  +  - ]:         534 :         assert(decompressed_pubkey.size() == 65);
     252                 :         534 :     }
     253                 :             : 
     254                 :             :     {
     255                 :         534 :         std::vector<unsigned char> vch_sig;
     256         [ +  - ]:         534 :         const bool ok = key.Sign(random_uint256, vch_sig, false);
     257         [ +  - ]:         534 :         assert(ok);
     258   [ +  -  +  - ]:         534 :         assert(pubkey.Verify(random_uint256, vch_sig));
     259   [ +  -  +  - ]:         534 :         assert(CPubKey::CheckLowS(vch_sig));
     260                 :             : 
     261         [ +  - ]:         534 :         const std::vector<unsigned char> vch_invalid_sig{vch_sig.begin(), vch_sig.begin() + vch_sig.size() - 1};
     262   [ +  -  +  - ]:         534 :         assert(!pubkey.Verify(random_uint256, vch_invalid_sig));
     263   [ +  -  +  - ]:         534 :         assert(!CPubKey::CheckLowS(vch_invalid_sig));
     264                 :         534 :     }
     265                 :             : 
     266                 :             :     {
     267                 :         534 :         std::vector<unsigned char> vch_compact_sig;
     268         [ +  - ]:         534 :         const bool ok_sign_compact = key.SignCompact(random_uint256, vch_compact_sig);
     269         [ +  - ]:         534 :         assert(ok_sign_compact);
     270                 :             : 
     271         [ +  - ]:         534 :         CPubKey recover_pubkey;
     272         [ +  - ]:         534 :         const bool ok_recover_compact = recover_pubkey.RecoverCompact(random_uint256, vch_compact_sig);
     273         [ +  - ]:         534 :         assert(ok_recover_compact);
     274   [ +  -  +  - ]:         534 :         assert(recover_pubkey == pubkey);
     275                 :         534 :     }
     276                 :             : 
     277                 :             :     {
     278         [ +  - ]:         534 :         CPubKey child_pubkey;
     279         [ +  - ]:         534 :         ChainCode child_chaincode;
     280         [ +  - ]:         534 :         const bool ok = pubkey.Derive(child_pubkey, child_chaincode, 0, random_uint256);
     281         [ +  - ]:         534 :         assert(ok);
     282   [ +  -  +  - ]:         534 :         assert(child_pubkey != pubkey);
     283   [ +  -  +  - ]:         534 :         assert(child_pubkey.IsCompressed());
     284   [ +  -  +  - ]:         534 :         assert(child_pubkey.IsFullyValid());
     285   [ +  -  +  - ]:         534 :         assert(child_pubkey.IsValid());
     286   [ +  -  +  - ]:         534 :         assert(child_pubkey.size() == 33);
     287   [ +  -  +  - ]:         534 :         assert(child_chaincode != random_uint256);
     288                 :         534 :     }
     289                 :             : 
     290         [ +  - ]:         534 :     const CPrivKey priv_key = key.GetPrivKey();
     291                 :             : 
     292                 :             :     {
     293         [ +  + ]:        1602 :         for (const bool skip_check : {true, false}) {
     294                 :        1068 :             CKey loaded_key;
     295         [ +  - ]:        1068 :             const bool ok = loaded_key.Load(priv_key, pubkey, skip_check);
     296         [ -  + ]:        1068 :             assert(ok);
     297   [ +  -  -  + ]:        1068 :             assert(key == loaded_key);
     298                 :        1068 :         }
     299                 :             :     }
     300         [ -  + ]:         541 : }
     301                 :             : 
     302         [ +  - ]:         406 : FUZZ_TARGET(ellswift_roundtrip, .init = initialize_key)
     303                 :             : {
     304                 :         404 :     FuzzedDataProvider fdp{buffer.data(), buffer.size()};
     305                 :             : 
     306                 :         404 :     CKey key = ConsumePrivateKey(fdp, /*compressed=*/true);
     307   [ +  -  +  + ]:         404 :     if (!key.IsValid()) return;
     308                 :             : 
     309         [ +  - ]:         400 :     auto ent32 = fdp.ConsumeBytes<std::byte>(32);
     310         [ +  - ]:         400 :     ent32.resize(32);
     311                 :             : 
     312   [ +  -  +  - ]:         400 :     auto encoded_ellswift = key.EllSwiftCreate(ent32);
     313         [ +  - ]:         400 :     auto decoded_pubkey = encoded_ellswift.Decode();
     314                 :             : 
     315                 :         400 :     uint256 hash{ConsumeUInt256(fdp)};
     316                 :         400 :     std::vector<unsigned char> sig;
     317         [ +  - ]:         400 :     key.Sign(hash, sig);
     318   [ +  -  +  - ]:         400 :     assert(decoded_pubkey.Verify(hash, sig));
     319         [ -  + ]:         404 : }
     320                 :             : 
     321         [ +  - ]:         290 : FUZZ_TARGET(bip324_ecdh, .init = initialize_key)
     322                 :             : {
     323                 :         288 :     FuzzedDataProvider fdp{buffer.data(), buffer.size()};
     324                 :             : 
     325                 :             :     // We generate private key, k1.
     326                 :         288 :     CKey k1 = ConsumePrivateKey(fdp, /*compressed=*/true);
     327   [ +  -  +  + ]:         288 :     if (!k1.IsValid()) return;
     328                 :             : 
     329                 :             :     // They generate private key, k2.
     330                 :         286 :     CKey k2 = ConsumePrivateKey(fdp, /*compressed=*/true);
     331   [ +  -  +  + ]:         286 :     if (!k2.IsValid()) return;
     332                 :             : 
     333                 :             :     // We construct an ellswift encoding for our key, k1_ellswift.
     334         [ +  - ]:         283 :     auto ent32_1 = fdp.ConsumeBytes<std::byte>(32);
     335         [ +  - ]:         283 :     ent32_1.resize(32);
     336   [ +  -  +  - ]:         283 :     auto k1_ellswift = k1.EllSwiftCreate(ent32_1);
     337                 :             : 
     338                 :             :     // They construct an ellswift encoding for their key, k2_ellswift.
     339         [ +  - ]:         283 :     auto ent32_2 = fdp.ConsumeBytes<std::byte>(32);
     340         [ +  - ]:         283 :     ent32_2.resize(32);
     341   [ +  -  +  - ]:         283 :     auto k2_ellswift = k2.EllSwiftCreate(ent32_2);
     342                 :             : 
     343                 :             :     // They construct another (possibly distinct) ellswift encoding for their key, k2_ellswift_bad.
     344         [ +  - ]:         283 :     auto ent32_2_bad = fdp.ConsumeBytes<std::byte>(32);
     345         [ +  - ]:         283 :     ent32_2_bad.resize(32);
     346   [ +  -  +  - ]:         283 :     auto k2_ellswift_bad = k2.EllSwiftCreate(ent32_2_bad);
     347   [ +  -  +  -  :         283 :     assert((ent32_2_bad == ent32_2) == (k2_ellswift_bad == k2_ellswift));
                   +  - ]
     348                 :             : 
     349                 :             :     // Determine who is who.
     350         [ +  - ]:         283 :     bool initiating = fdp.ConsumeBool();
     351                 :             : 
     352                 :             :     // We compute our shared secret using our key and their public key.
     353         [ +  - ]:         283 :     auto ecdh_secret_1 = k1.ComputeBIP324ECDHSecret(k2_ellswift, k1_ellswift, initiating);
     354                 :             :     // They compute their shared secret using their key and our public key.
     355         [ +  - ]:         283 :     auto ecdh_secret_2 = k2.ComputeBIP324ECDHSecret(k1_ellswift, k2_ellswift, !initiating);
     356                 :             :     // Those must match, as everyone is behaving correctly.
     357   [ +  -  +  - ]:         283 :     assert(ecdh_secret_1 == ecdh_secret_2);
     358                 :             : 
     359   [ +  -  +  + ]:         283 :     if (k1_ellswift != k2_ellswift) {
     360                 :             :         // Unless the two keys are exactly identical, acting as the wrong party breaks things.
     361         [ +  - ]:         275 :         auto ecdh_secret_bad = k1.ComputeBIP324ECDHSecret(k2_ellswift, k1_ellswift, !initiating);
     362   [ +  -  +  - ]:         275 :         assert(ecdh_secret_bad != ecdh_secret_1);
     363                 :         275 :     }
     364                 :             : 
     365   [ +  -  +  + ]:         283 :     if (k2_ellswift_bad != k2_ellswift) {
     366                 :             :         // Unless both encodings created by them are identical, using the second one breaks things.
     367         [ +  - ]:          78 :         auto ecdh_secret_bad = k1.ComputeBIP324ECDHSecret(k2_ellswift_bad, k1_ellswift, initiating);
     368   [ +  -  +  - ]:          78 :         assert(ecdh_secret_bad != ecdh_secret_1);
     369                 :          78 :     }
     370         [ -  + ]:         288 : }
        

Generated by: LCOV version 2.0-1