Browse Source

Add support for spending keys to the basic key store

pull/4/head
Jack Grigg 8 years ago
parent
commit
7c929cf5bc
  1. 1
      src/Makefile.gtest.include
  2. 26
      src/gtest/test_keystore.cpp
  3. 11
      src/keystore.cpp
  4. 49
      src/keystore.h
  5. 2
      src/uint252.h
  6. 6
      src/zcash/Address.cpp
  7. 6
      src/zcash/Address.hpp

1
src/Makefile.gtest.include

@ -8,6 +8,7 @@ zcash_gtest_SOURCES = \
gtest/test_checktransaction.cpp \
gtest/test_equihash.cpp \
gtest/test_joinsplit.cpp \
gtest/test_keystore.cpp \
gtest/test_noteencryption.cpp \
gtest/test_merkletree.cpp \
gtest/test_circuit.cpp \

26
src/gtest/test_keystore.cpp

@ -0,0 +1,26 @@
#include <gtest/gtest.h>
#include "keystore.h"
#include "zcash/Address.hpp"
TEST(keystore_tests, store_and_retrieve_spending_key) {
CBasicKeyStore keyStore;
std::set<libzcash::PaymentAddress> addrs;
keyStore.GetPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size());
auto sk = libzcash::SpendingKey::random();
keyStore.AddSpendingKey(sk);
auto addr = sk.address();
ASSERT_TRUE(keyStore.HaveSpendingKey(addr));
libzcash::SpendingKey keyOut;
keyStore.GetSpendingKey(addr, keyOut);
ASSERT_EQ(sk, keyOut);
keyStore.GetPaymentAddresses(addrs);
ASSERT_EQ(1, addrs.size());
ASSERT_EQ(1, addrs.count(addr));
}

11
src/keystore.cpp

@ -23,6 +23,10 @@ bool CKeyStore::AddKey(const CKey &key) {
return AddKeyPubKey(key, key.GetPubKey());
}
bool CKeyStore::AddSpendingKey(const libzcash::SpendingKey &key) {
return AddSpendingKeyPaymentAddress(key, key.address());
}
bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
{
LOCK(cs_KeyStore);
@ -83,3 +87,10 @@ bool CBasicKeyStore::HaveWatchOnly() const
LOCK(cs_KeyStore);
return (!setWatchOnly.empty());
}
bool CBasicKeyStore::AddSpendingKeyPaymentAddress(const libzcash::SpendingKey& key, const libzcash::PaymentAddress &address)
{
LOCK(cs_KeyStore);
mapSpendingKeys[address] = key;
return true;
}

49
src/keystore.h

@ -11,6 +11,7 @@
#include "script/script.h"
#include "script/standard.h"
#include "sync.h"
#include "zcash/Address.hpp"
#include <boost/signals2/signal.hpp>
#include <boost/variant.hpp>
@ -44,11 +45,21 @@ public:
virtual bool RemoveWatchOnly(const CScript &dest) =0;
virtual bool HaveWatchOnly(const CScript &dest) const =0;
virtual bool HaveWatchOnly() const =0;
//! Add a spending key to the store.
virtual bool AddSpendingKeyPaymentAddress(const libzcash::SpendingKey &key, const libzcash::PaymentAddress &address) =0;
virtual bool AddSpendingKey(const libzcash::SpendingKey &key);
//! Check whether a spending key corresponding to a given payment address is present in the store.
virtual bool HaveSpendingKey(const libzcash::PaymentAddress &address) const =0;
virtual bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey& keyOut) const =0;
virtual void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const =0;
};
typedef std::map<CKeyID, CKey> KeyMap;
typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet;
typedef std::map<libzcash::PaymentAddress, libzcash::SpendingKey> SpendingKeyMap;
/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
@ -57,6 +68,7 @@ protected:
KeyMap mapKeys;
ScriptMap mapScripts;
WatchOnlySet setWatchOnly;
SpendingKeyMap mapSpendingKeys;
public:
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
@ -103,6 +115,43 @@ public:
virtual bool RemoveWatchOnly(const CScript &dest);
virtual bool HaveWatchOnly(const CScript &dest) const;
virtual bool HaveWatchOnly() const;
bool AddSpendingKeyPaymentAddress(const libzcash::SpendingKey &key, const libzcash::PaymentAddress &address);
bool HaveSpendingKey(const libzcash::PaymentAddress &address) const
{
bool result;
{
LOCK(cs_KeyStore);
result = (mapSpendingKeys.count(address) > 0);
}
return result;
}
bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &keyOut) const
{
{
LOCK(cs_KeyStore);
SpendingKeyMap::const_iterator mi = mapSpendingKeys.find(address);
if (mi != mapSpendingKeys.end())
{
keyOut = mi->second;
return true;
}
}
return false;
}
void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const
{
setAddress.clear();
{
LOCK(cs_KeyStore);
SpendingKeyMap::const_iterator mi = mapSpendingKeys.begin();
while (mi != mapSpendingKeys.end())
{
setAddress.insert((*mi).first);
mi++;
}
}
}
};
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;

2
src/uint252.h

@ -43,6 +43,8 @@ public:
uint256 inner() const {
return contents;
}
friend inline bool operator==(const uint252& a, const uint252& b) { return a.contents == b.contents; }
};
#endif

6
src/zcash/Address.cpp

@ -8,7 +8,7 @@ uint256 ViewingKey::pk_enc() {
return ZCNoteEncryption::generate_pubkey(*this);
}
ViewingKey SpendingKey::viewing_key() {
ViewingKey SpendingKey::viewing_key() const {
return ViewingKey(ZCNoteEncryption::generate_privkey(*this));
}
@ -16,8 +16,8 @@ SpendingKey SpendingKey::random() {
return SpendingKey(random_uint252());
}
PaymentAddress SpendingKey::address() {
PaymentAddress SpendingKey::address() const {
return PaymentAddress(PRF_addr_a_pk(*this), viewing_key().pk_enc());
}
}
}

6
src/zcash/Address.hpp

@ -22,6 +22,8 @@ public:
READWRITE(a_pk);
READWRITE(pk_enc);
}
friend inline bool operator<(const PaymentAddress& a, const PaymentAddress& b) { return a.a_pk < b.a_pk; }
};
class ViewingKey : public uint256 {
@ -38,8 +40,8 @@ public:
static SpendingKey random();
ViewingKey viewing_key();
PaymentAddress address();
ViewingKey viewing_key() const;
PaymentAddress address() const;
};
}

Loading…
Cancel
Save