LCOV - code coverage report
Current view: top level - src/sapling - crypter_sapling.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 42 45 93.3 %
Date: 2025-02-23 09:33:43 Functions: 5 5 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2016-2020 The ZCash developers
       2             : // Copyright (c) 2020-2021 The PIVX Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or https://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #include "crypter.h"
       7             : 
       8             : #include "script/script.h"
       9             : #include "script/standard.h"
      10             : #include "util/system.h"
      11             : #include "uint256.h"
      12             : 
      13         106 : bool CCryptoKeyStore::AddCryptedSaplingSpendingKey(
      14             :         const libzcash::SaplingExtendedFullViewingKey &extfvk,
      15             :         const std::vector<unsigned char> &vchCryptedSecret)
      16             : {
      17         212 :     LOCK(cs_KeyStore);
      18         106 :     if (!SetCrypted()) {
      19             :         return false;
      20             :     }
      21             : 
      22             :     // if extfvk is not in SaplingFullViewingKeyMap, add it
      23         106 :     if (!AddSaplingFullViewingKey(extfvk)) {
      24             :         return false;
      25             :     }
      26             : 
      27         106 :     mapCryptedSaplingSpendingKeys[extfvk] = vchCryptedSecret;
      28             :     return true;
      29             : }
      30             : 
      31         112 : static bool DecryptSaplingSpendingKey(const CKeyingMaterial& vMasterKey,
      32             :                                       const std::vector<unsigned char>& vchCryptedSecret,
      33             :                                       const libzcash::SaplingExtendedFullViewingKey& extfvk,
      34             :                                       libzcash::SaplingExtendedSpendingKey& sk)
      35             : {
      36         224 :     CKeyingMaterial vchSecret;
      37         112 :     if (!DecryptSecret(vMasterKey, vchCryptedSecret, extfvk.fvk.GetFingerprint(), vchSecret))
      38             :         return false;
      39             : 
      40         111 :     if (vchSecret.size() != ZIP32_XSK_SIZE)
      41             :         return false;
      42             : 
      43         223 :     CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION);
      44         111 :     ss >> sk;
      45         111 :     return sk.expsk.full_viewing_key() == extfvk.fvk;
      46             : }
      47             : 
      48        1148 : bool CCryptoKeyStore::GetSaplingSpendingKey(
      49             :         const libzcash::SaplingExtendedFullViewingKey& extfvk,
      50             :         libzcash::SaplingExtendedSpendingKey& skOut) const
      51             : {
      52        2296 :     LOCK(cs_KeyStore);
      53        1148 :     if (!IsCrypted()) {
      54        1143 :         return CBasicKeyStore::GetSaplingSpendingKey(extfvk, skOut);
      55             :     }
      56             : 
      57           5 :     auto it = mapCryptedSaplingSpendingKeys.find(extfvk);
      58           5 :     if (it == mapCryptedSaplingSpendingKeys.end()) return false;
      59           5 :     const std::vector<unsigned char>& vchCryptedSecret = it->second;
      60           5 :     return DecryptSaplingSpendingKey(vMasterKey, vchCryptedSecret, it->first, skOut);
      61             : }
      62             : 
      63        8200 : bool CCryptoKeyStore::HaveSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey& extfvk) const
      64             : {
      65       16400 :     LOCK(cs_KeyStore);
      66        8200 :     if (!IsCrypted()) {
      67        7989 :         return CBasicKeyStore::HaveSaplingSpendingKey(extfvk);
      68             :     }
      69         422 :     return mapCryptedSaplingSpendingKeys.count(extfvk) > 0;
      70             : }
      71             : 
      72          24 : bool CCryptoKeyStore::UnlockSaplingKeys(const CKeyingMaterial& vMasterKeyIn, bool fDecryptionThoroughlyChecked)
      73             : {
      74          24 :     if (mapCryptedSaplingSpendingKeys.empty()) {
      75          17 :         LogPrintf("%s: mapCryptedSaplingSpendingKeys empty. No need to unlock anything.\n", __func__);
      76          17 :         return true;
      77             :     }
      78             : 
      79           7 :     bool keyFail = false;
      80           7 :     bool keyPass = false;
      81           7 :     CryptedSaplingSpendingKeyMap::const_iterator miSapling = mapCryptedSaplingSpendingKeys.begin();
      82         111 :     for (; miSapling != mapCryptedSaplingSpendingKeys.end(); ++miSapling) {
      83         107 :         const libzcash::SaplingExtendedFullViewingKey &extfvk = (*miSapling).first;
      84         107 :         const std::vector<unsigned char> &vchCryptedSecret = (*miSapling).second;
      85         107 :         libzcash::SaplingExtendedSpendingKey sk;
      86         107 :         if (!DecryptSaplingSpendingKey(vMasterKeyIn, vchCryptedSecret, extfvk, sk)) {
      87             :             keyFail = true;
      88           3 :             break;
      89             :         }
      90         107 :         keyPass = true;
      91         107 :         if (fDecryptionThoroughlyChecked)
      92             :             break;
      93             :     }
      94             : 
      95           7 :     if (keyPass && keyFail) {
      96           0 :         LogPrintf("Sapling wallet is probably corrupted: Some keys decrypt but not all.\n");
      97           0 :         throw std::runtime_error("Error unlocking sapling wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
      98             :     }
      99           7 :     if (keyFail || !keyPass)
     100           0 :         return false;
     101             : 
     102             :     return true;
     103             : }

Generated by: LCOV version 1.14