Compressed pubkeys

This patch enabled compressed pubkeys when -compressedpubkeys is passed.
These are 33 bytes instead of 65, and require only marginally more CPU
power when verifying. Compressed pubkeys have a different corresponding
address, so it is determined at generation. When -compressedpubkeys is
given, all newly generated addresses will use a compressed key, while
older/other addresses keep using normal keys. Unpatched clients will
relay and verify these transactions.
This commit is contained in:
Pieter Wuille
2011-11-21 02:46:28 +01:00
parent 1684f98b27
commit 11529c6e4f
7 changed files with 79 additions and 50 deletions

View File

@@ -29,8 +29,10 @@ bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned c
bool CBasicKeyStore::AddKey(const CKey& key)
{
bool fCompressed = false;
CSecret secret = key.GetSecret(fCompressed);
CRITICAL_BLOCK(cs_KeyStore)
mapKeys[CBitcoinAddress(key.GetPubKey())] = key.GetSecret();
mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
return true;
}
@@ -77,16 +79,6 @@ bool CCryptoKeyStore::SetCrypted()
return true;
}
std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey()
{
RandAddSeedPerfmon();
CKey key;
key.MakeNewKey();
if (!AddKey(key))
throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed");
return key.GetPubKey();
}
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
{
CRITICAL_BLOCK(cs_KeyStore)
@@ -103,6 +95,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
return false;
CKey key;
key.SetPubKey(vchPubKey);
key.SetSecret(vchSecret);
if (key.GetPubKey() == vchPubKey)
break;
@@ -125,7 +118,8 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
std::vector<unsigned char> vchCryptedSecret;
std::vector<unsigned char> vchPubKey = key.GetPubKey();
if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
bool fCompressed;
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
return false;
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
@@ -147,19 +141,24 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey,
return true;
}
bool CCryptoKeyStore::GetSecret(const CBitcoinAddress &address, CSecret& vchSecretOut) const
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
{
CRITICAL_BLOCK(cs_KeyStore)
{
if (!IsCrypted())
return CBasicKeyStore::GetSecret(address, vchSecretOut);
return CBasicKeyStore::GetKey(address, keyOut);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end())
{
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
return DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecretOut);
CSecret vchSecret;
if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
return false;
keyOut.SetPubKey(vchPubKey);
keyOut.SetSecret(vchSecret);
return true;
}
}
return false;
@@ -190,14 +189,15 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
return false;
fUseCrypto = true;
CKey key;
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
{
if (!key.SetSecret(mKey.second))
CKey key;
if (!key.SetSecret(mKey.second.first, false))
return false;
const std::vector<unsigned char> vchPubKey = key.GetPubKey();
std::vector<unsigned char> vchCryptedSecret;
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
bool fCompressed;
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
return false;
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
return false;