// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Copyright (c) 2016-2024 The Hush developers // Distributed under the GPLv3 software license, see the accompanying // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * SuperNET software, including this file may be copied, modified, propagated * * or distributed except according to the terms contained in the LICENSE file * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ #ifndef HUSH_KEYSTORE_H #define HUSH_KEYSTORE_H #include "key.h" #include "pubkey.h" #include "script/script.h" #include "script/standard.h" #include "sync.h" #include "zcash/Address.hpp" #include "zcash/NoteEncryption.hpp" #include "zcash/zip32.h" #include #include /** A virtual base class for key stores */ class CKeyStore { protected: mutable CCriticalSection cs_KeyStore; mutable CCriticalSection cs_SpendingKeyStore; public: virtual ~CKeyStore() {} //! Set the HD seed for this keystore virtual bool SetHDSeed(const HDSeed& seed) =0; virtual bool HaveHDSeed() const =0; //! Get the HD seed for this keystore virtual bool GetHDSeed(HDSeed& seedOut) const =0; //! Add a key to the store. virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) =0; virtual bool AddKey(const CKey &key); //! Check whether a key corresponding to a given address is present in the store. virtual bool HaveKey(const CKeyID &address) const =0; virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; virtual void GetKeys(std::set &setAddress) const =0; virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki virtual bool AddCScript(const CScript& redeemScript) =0; virtual bool HaveCScript(const CScriptID &hash) const =0; virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0; //! Support for Watch-only addresses virtual bool AddWatchOnly(const CScript &dest) =0; virtual bool RemoveWatchOnly(const CScript &dest) =0; virtual bool HaveWatchOnly(const CScript &dest) const =0; virtual bool HaveWatchOnly() const =0; //! Add a Sapling spending key to the store. virtual bool AddSaplingSpendingKey( const libzcash::SaplingExtendedSpendingKey &sk, const libzcash::SaplingPaymentAddress &defaultAddr) =0; //! Check whether a Sapling spending key corresponding to a given Sapling viewing key is present in the store. virtual bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const =0; virtual bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingExtendedSpendingKey& skOut) const =0; //! Support for Sapling full viewing keys virtual bool AddSaplingFullViewingKey( const libzcash::SaplingFullViewingKey &fvk, const libzcash::SaplingPaymentAddress &defaultAddr) =0; virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const =0; virtual bool GetSaplingFullViewingKey( const libzcash::SaplingIncomingViewingKey &ivk, libzcash::SaplingFullViewingKey& fvkOut) const =0; //! Sapling incoming viewing keys virtual bool AddSaplingIncomingViewingKey( const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingPaymentAddress &addr) =0; virtual bool HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr) const =0; virtual bool GetSaplingIncomingViewingKey( const libzcash::SaplingPaymentAddress &addr, libzcash::SaplingIncomingViewingKey& ivkOut) const =0; virtual void GetSaplingPaymentAddresses(std::set &setAddress) const =0; }; typedef std::map KeyMap; typedef std::map ScriptMap; typedef std::set WatchOnlySet; // Full viewing key has equivalent functionality to a transparent address // When encrypting wallet, encrypt SaplingSpendingKeyMap, while leaving SaplingFullViewingKeyMap unencrypted typedef std::map SaplingSpendingKeyMap; typedef std::map SaplingFullViewingKeyMap; // Only maps from default addresses to ivk, may need to be reworked when adding diversified addresses. typedef std::map SaplingIncomingViewingKeyMap; /** Basic key store, that keeps keys in an address->secret map */ class CBasicKeyStore : public CKeyStore { protected: HDSeed hdSeed; KeyMap mapKeys; ScriptMap mapScripts; WatchOnlySet setWatchOnly; SaplingSpendingKeyMap mapSaplingSpendingKeys; SaplingFullViewingKeyMap mapSaplingFullViewingKeys; SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys; public: bool SetHDSeed(const HDSeed& seed); bool HaveHDSeed() const; bool GetHDSeed(HDSeed& seedOut) const; bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); bool HaveKey(const CKeyID &address) const { bool result; { LOCK(cs_KeyStore); result = (mapKeys.count(address) > 0); } return result; } void GetKeys(std::set &setAddress) const { setAddress.clear(); { LOCK(cs_KeyStore); KeyMap::const_iterator mi = mapKeys.begin(); while (mi != mapKeys.end()) { setAddress.insert((*mi).first); mi++; } } } bool GetKey(const CKeyID &address, CKey &keyOut) const { { LOCK(cs_KeyStore); KeyMap::const_iterator mi = mapKeys.find(address); if (mi != mapKeys.end()) { keyOut = mi->second; return true; } } return false; } virtual bool AddCScript(const CScript& redeemScript); virtual bool HaveCScript(const CScriptID &hash) const; virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const; virtual bool AddWatchOnly(const CScript &dest); virtual bool RemoveWatchOnly(const CScript &dest); virtual bool HaveWatchOnly(const CScript &dest) const; virtual bool HaveWatchOnly() const; //! Sapling bool AddSaplingSpendingKey( const libzcash::SaplingExtendedSpendingKey &sk, const libzcash::SaplingPaymentAddress &defaultAddr); bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const { bool result; { LOCK(cs_SpendingKeyStore); result = (mapSaplingSpendingKeys.count(fvk) > 0); } return result; } bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingExtendedSpendingKey &skOut) const { { LOCK(cs_SpendingKeyStore); SaplingSpendingKeyMap::const_iterator mi = mapSaplingSpendingKeys.find(fvk); if (mi != mapSaplingSpendingKeys.end()) { skOut = mi->second; return true; } } return false; } virtual bool AddSaplingFullViewingKey( const libzcash::SaplingFullViewingKey &fvk, const libzcash::SaplingPaymentAddress &defaultAddr); virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const; virtual bool GetSaplingFullViewingKey( const libzcash::SaplingIncomingViewingKey &ivk, libzcash::SaplingFullViewingKey& fvkOut) const; virtual bool AddSaplingIncomingViewingKey( const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingPaymentAddress &addr); virtual bool HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr) const; virtual bool GetSaplingIncomingViewingKey( const libzcash::SaplingPaymentAddress &addr, libzcash::SaplingIncomingViewingKey& ivkOut) const; bool GetSaplingExtendedSpendingKey( const libzcash::SaplingPaymentAddress &addr, libzcash::SaplingExtendedSpendingKey &extskOut) const; void GetSaplingPaymentAddresses(std::set &setAddress) const { setAddress.clear(); { LOCK(cs_SpendingKeyStore); auto mi = mapSaplingIncomingViewingKeys.begin(); while (mi != mapSaplingIncomingViewingKeys.end()) { setAddress.insert((*mi).first); mi++; } } } }; typedef std::vector > CKeyingMaterial; typedef std::map > > CryptedKeyMap; //! Sapling typedef std::map > CryptedSaplingSpendingKeyMap; #endif // HUSH_KEYSTORE_H