diff --git a/src/keystore.h b/src/keystore.h index b369dec78..6ff34b20d 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -311,6 +311,6 @@ typedef std::map > > Crypt typedef std::map > CryptedSproutSpendingKeyMap; //! Sapling -typedef std::map > CryptedSaplingSpendingKeyMap; +typedef std::map > CryptedSaplingSpendingKeyMap; #endif // BITCOIN_KEYSTORE_H diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 25d69cc3d..cf87c01d4 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -170,11 +170,11 @@ static bool DecryptSproutSpendingKey(const CKeyingMaterial& vMasterKey, static bool DecryptSaplingSpendingKey(const CKeyingMaterial& vMasterKey, const std::vector& vchCryptedSecret, - const libzcash::SaplingFullViewingKey& fvk, + const libzcash::SaplingExtendedFullViewingKey& extfvk, libzcash::SaplingExtendedSpendingKey& sk) { CKeyingMaterial vchSecret; - if (!DecryptSecret(vMasterKey, vchCryptedSecret, fvk.GetFingerprint(), vchSecret)) + if (!DecryptSecret(vMasterKey, vchCryptedSecret, extfvk.fvk.GetFingerprint(), vchSecret)) return false; if (vchSecret.size() != ZIP32_XSK_SIZE) @@ -182,7 +182,7 @@ static bool DecryptSaplingSpendingKey(const CKeyingMaterial& vMasterKey, CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION); ss >> sk; - return sk.expsk.full_viewing_key() == fvk; + return sk.expsk.full_viewing_key() == extfvk.fvk; } bool CCryptoKeyStore::SetCrypted() @@ -261,10 +261,10 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) CryptedSaplingSpendingKeyMap::const_iterator miSapling = mapCryptedSaplingSpendingKeys.begin(); for (; miSapling != mapCryptedSaplingSpendingKeys.end(); ++miSapling) { - const libzcash::SaplingFullViewingKey &fvk = (*miSapling).first; + const libzcash::SaplingExtendedFullViewingKey &extfvk = (*miSapling).first; const std::vector &vchCryptedSecret = (*miSapling).second; libzcash::SaplingExtendedSpendingKey sk; - if (!DecryptSaplingSpendingKey(vMasterKeyIn, vchCryptedSecret, fvk, sk)) + if (!DecryptSaplingSpendingKey(vMasterKeyIn, vchCryptedSecret, extfvk, sk)) { keyFail = true; break; @@ -465,12 +465,12 @@ bool CCryptoKeyStore::AddSaplingSpendingKey( CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << sk; CKeyingMaterial vchSecret(ss.begin(), ss.end()); - auto fvk = sk.expsk.full_viewing_key(); - if (!EncryptSecret(vMasterKey, vchSecret, fvk.GetFingerprint(), vchCryptedSecret)) { + auto extfvk = sk.ToXFVK(); + if (!EncryptSecret(vMasterKey, vchSecret, extfvk.fvk.GetFingerprint(), vchCryptedSecret)) { return false; } - if (!AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret, defaultAddr)) { + if (!AddCryptedSaplingSpendingKey(extfvk, vchCryptedSecret, defaultAddr)) { return false; } } @@ -494,7 +494,7 @@ bool CCryptoKeyStore::AddCryptedSproutSpendingKey( } bool CCryptoKeyStore::AddCryptedSaplingSpendingKey( - const libzcash::SaplingFullViewingKey &fvk, + const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector &vchCryptedSecret, const libzcash::SaplingPaymentAddress &defaultAddr) { @@ -505,11 +505,11 @@ bool CCryptoKeyStore::AddCryptedSaplingSpendingKey( } // if SaplingFullViewingKey is not in SaplingFullViewingKeyMap, add it - if (!AddSaplingFullViewingKey(fvk, defaultAddr)) { + if (!AddSaplingFullViewingKey(extfvk.fvk, defaultAddr)) { return false; } - mapCryptedSaplingSpendingKeys[fvk] = vchCryptedSecret; + mapCryptedSaplingSpendingKeys[extfvk] = vchCryptedSecret; } return true; } @@ -538,11 +538,11 @@ bool CCryptoKeyStore::GetSaplingSpendingKey(const libzcash::SaplingFullViewingKe if (!IsCrypted()) return CBasicKeyStore::GetSaplingSpendingKey(fvk, skOut); - CryptedSaplingSpendingKeyMap::const_iterator mi = mapCryptedSaplingSpendingKeys.find(fvk); - if (mi != mapCryptedSaplingSpendingKeys.end()) - { - const std::vector &vchCryptedSecret = (*mi).second; - return DecryptSaplingSpendingKey(vMasterKey, vchCryptedSecret, fvk, skOut); + for (auto entry : mapCryptedSaplingSpendingKeys) { + if (entry.first.fvk == fvk) { + const std::vector &vchCryptedSecret = entry.second; + return DecryptSaplingSpendingKey(vMasterKey, vchCryptedSecret, entry.first, skOut); + } } } return false; @@ -609,12 +609,12 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << sk; CKeyingMaterial vchSecret(ss.begin(), ss.end()); - libzcash::SaplingFullViewingKey fvk = sk.expsk.full_viewing_key(); + auto extfvk = sk.ToXFVK(); std::vector vchCryptedSecret; - if (!EncryptSecret(vMasterKeyIn, vchSecret, fvk.GetFingerprint(), vchCryptedSecret)) { + if (!EncryptSecret(vMasterKeyIn, vchSecret, extfvk.fvk.GetFingerprint(), vchCryptedSecret)) { return false; } - if (!AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret, sk.DefaultAddress())) { + if (!AddCryptedSaplingSpendingKey(extfvk, vchCryptedSecret, sk.DefaultAddress())) { return false; } } diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index b751ce300..1cfefe886 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -241,7 +241,7 @@ public: } //! Sapling virtual bool AddCryptedSaplingSpendingKey( - const libzcash::SaplingFullViewingKey &fvk, + const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector &vchCryptedSecret, const libzcash::SaplingPaymentAddress &defaultAddr); bool AddSaplingSpendingKey( @@ -253,7 +253,11 @@ public: LOCK(cs_SpendingKeyStore); if (!IsCrypted()) return CBasicKeyStore::HaveSaplingSpendingKey(fvk); - return mapCryptedSaplingSpendingKeys.count(fvk) > 0; + for (auto entry : mapCryptedSaplingSpendingKeys) { + if (entry.first.fvk == fvk) { + return true; + } + } } return false; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b53691fbb..09a9d15d5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -293,11 +293,11 @@ bool CWallet::AddCryptedSproutSpendingKey( return false; } -bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, +bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector &vchCryptedSecret, const libzcash::SaplingPaymentAddress &defaultAddr) { - if (!CCryptoKeyStore::AddCryptedSaplingSpendingKey(fvk, vchCryptedSecret, defaultAddr)) + if (!CCryptoKeyStore::AddCryptedSaplingSpendingKey(extfvk, vchCryptedSecret, defaultAddr)) return false; if (!fFileBacked) return true; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index a08a8c782..95cd7b63e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1060,7 +1060,7 @@ public: const libzcash::SaplingExtendedSpendingKey &key, const libzcash::SaplingPaymentAddress &defaultAddr); bool AddCryptedSaplingSpendingKey( - const libzcash::SaplingFullViewingKey &fvk, + const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector &vchCryptedSecret, const libzcash::SaplingPaymentAddress &defaultAddr); diff --git a/src/zcash/zip32.h b/src/zcash/zip32.h index 0fc5785bd..44bc58598 100644 --- a/src/zcash/zip32.h +++ b/src/zcash/zip32.h @@ -78,6 +78,21 @@ struct SaplingExtendedFullViewingKey { Address(diversifier_index_t j) const; libzcash::SaplingPaymentAddress DefaultAddress() const; + + friend inline bool operator==(const SaplingExtendedFullViewingKey& a, const SaplingExtendedFullViewingKey& b) { + return ( + a.depth == b.depth && + a.parentFVKTag == b.parentFVKTag && + a.childIndex == b.childIndex && + a.chaincode == b.chaincode && + a.fvk == b.fvk && + a.dk == b.dk); + } + friend inline bool operator<(const SaplingExtendedFullViewingKey& a, const SaplingExtendedFullViewingKey& b) { + return (a.depth < b.depth || + (a.depth == b.depth && a.childIndex < b.childIndex) || + (a.depth == b.depth && a.childIndex == b.childIndex && a.fvk < b.fvk)); + } }; struct SaplingExtendedSpendingKey {