From 55f2889396ed3fb3dd4b11a208f5e9de0b0fe6a9 Mon Sep 17 00:00:00 2001 From: Jay Graber Date: Thu, 12 Jul 2018 14:57:53 -0700 Subject: [PATCH] Add Sapling have/get sk crypter overrides --- src/wallet/crypter.cpp | 37 +++++++++++++++++++++++++++++++++++-- src/wallet/crypter.h | 12 ++++++++++++ src/zcash/Address.cpp | 10 ++++++++++ src/zcash/Address.hpp | 9 +++++++-- 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index a1e6b42f6..5d1a31e14 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -151,6 +151,23 @@ static bool DecryptSpendingKey(const CKeyingMaterial& vMasterKey, return sk.address() == address; } +static bool DecryptSaplingSpendingKey(const CKeyingMaterial& vMasterKey, + const std::vector& vchCryptedSecret, + const libzcash::SaplingFullViewingKey& fvk, + libzcash::SaplingSpendingKey& sk) +{ + CKeyingMaterial vchSecret; + if(!DecryptSecret(vMasterKey, vchCryptedSecret, fvk.GetFingerprint(), vchSecret)) + return false; + + if (vchSecret.size() != libzcash::SerializedSaplingSpendingKeySize) + return false; + + CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION); + ss >> sk; + return sk.full_viewing_key() == fvk; +} + bool CCryptoKeyStore::SetCrypted() { LOCK2(cs_KeyStore, cs_SpendingKeyStore); @@ -338,9 +355,8 @@ bool CCryptoKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey & CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << sk; CKeyingMaterial vchSecret(ss.begin(), ss.end()); - auto address = sk.default_address(); auto fvk = sk.full_viewing_key(); - if (!EncryptSecret(vMasterKey, vchSecret, address.GetHash(), vchCryptedSecret)) { + if (!EncryptSecret(vMasterKey, vchSecret, fvk.GetFingerprint(), vchCryptedSecret)) { return false; } @@ -398,6 +414,23 @@ bool CCryptoKeyStore::GetSpendingKey(const libzcash::SproutPaymentAddress &addre return false; } +bool CCryptoKeyStore::GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey &skOut) const +{ + { + LOCK(cs_SpendingKeyStore); + 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); + } + } + return false; +} + bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) { { diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index dba4c4c12..d42a8f556 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -236,6 +236,18 @@ public: virtual bool AddCryptedSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, const std::vector &vchCryptedSecret); bool AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk); + bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const + { + { + LOCK(cs_SpendingKeyStore); + if (!IsCrypted()) + return CBasicKeyStore::HaveSaplingSpendingKey(fvk); + return mapCryptedSaplingSpendingKeys.count(fvk) > 0; + } + return false; + } + bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey &skOut) const; + /** * Wallet status (encrypted, locked) changed. diff --git a/src/zcash/Address.cpp b/src/zcash/Address.cpp index d12e82cdc..3b810806f 100644 --- a/src/zcash/Address.cpp +++ b/src/zcash/Address.cpp @@ -6,6 +6,9 @@ #include +const unsigned char ZCASH_SAPLING_FVFP_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] = + {'Z', 'c', 'a', 's', 'h', 'S', 'a', 'p', 'l', 'i', 'n', 'g', 'F', 'V', 'F', 'P'}; + namespace libzcash { uint256 SproutPaymentAddress::GetHash() const { @@ -73,6 +76,13 @@ bool SaplingFullViewingKey::is_valid() const { return !ivk.IsNull(); } +uint256 SaplingFullViewingKey::GetFingerprint() const { + CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SAPLING_FVFP_PERSONALIZATION); + ss << *this; + return ss.GetHash(); +} + + SaplingSpendingKey SaplingSpendingKey::random() { while (true) { auto sk = SaplingSpendingKey(random_uint256()); diff --git a/src/zcash/Address.hpp b/src/zcash/Address.hpp index 34e56a592..3e960f847 100644 --- a/src/zcash/Address.hpp +++ b/src/zcash/Address.hpp @@ -19,6 +19,8 @@ const size_t SerializedPaymentAddressSize = 64; const size_t SerializedViewingKeySize = 64; const size_t SerializedSpendingKeySize = 32; +const size_t SerializedSaplingSpendingKeySize = 32; + typedef std::array diversifier_t; class SproutPaymentAddress { @@ -146,12 +148,15 @@ public: ADD_SERIALIZE_METHODS; template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(ak); READWRITE(nk); READWRITE(ovk); } + //! Get the fingerprint of this full viewing key (as defined in ZIP 32). + uint256 GetFingerprint() const; + SaplingIncomingViewingKey in_viewing_key() const; bool is_valid() const; @@ -178,7 +183,7 @@ public: ADD_SERIALIZE_METHODS; template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(ask); READWRITE(nsk); READWRITE(ovk);