mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 21:12:48 +01:00
commit
afcf6f974f
21
src/base58.h
21
src/base58.h
@ -359,22 +359,25 @@ public:
|
|||||||
class CBitcoinSecret : public CBase58Data
|
class CBitcoinSecret : public CBase58Data
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void SetSecret(const CSecret& vchSecret)
|
void SetSecret(const CSecret& vchSecret, bool fCompressed)
|
||||||
{
|
{
|
||||||
|
assert(vchSecret.size() == 32);
|
||||||
SetData(fTestNet ? 239 : 128, &vchSecret[0], vchSecret.size());
|
SetData(fTestNet ? 239 : 128, &vchSecret[0], vchSecret.size());
|
||||||
|
if (fCompressed)
|
||||||
|
vchData.push_back(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSecret GetSecret()
|
CSecret GetSecret(bool &fCompressedOut)
|
||||||
{
|
{
|
||||||
CSecret vchSecret;
|
CSecret vchSecret;
|
||||||
vchSecret.resize(vchData.size());
|
vchSecret.resize(32);
|
||||||
memcpy(&vchSecret[0], &vchData[0], vchData.size());
|
memcpy(&vchSecret[0], &vchData[0], 32);
|
||||||
|
fCompressedOut = vchData.size() == 33;
|
||||||
return vchSecret;
|
return vchSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValid() const
|
bool IsValid() const
|
||||||
{
|
{
|
||||||
int nExpectedSize = 32;
|
|
||||||
bool fExpectTestNet = false;
|
bool fExpectTestNet = false;
|
||||||
switch(nVersion)
|
switch(nVersion)
|
||||||
{
|
{
|
||||||
@ -388,12 +391,12 @@ public:
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
|
return fExpectTestNet == fTestNet && (vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
CBitcoinSecret(const CSecret& vchSecret)
|
CBitcoinSecret(const CSecret& vchSecret, bool fCompressed)
|
||||||
{
|
{
|
||||||
SetSecret(vchSecret);
|
SetSecret(vchSecret, fCompressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
CBitcoinSecret()
|
CBitcoinSecret()
|
||||||
|
@ -1701,6 +1701,9 @@ Value validateaddress(const Array& params, bool fHelp)
|
|||||||
ret.push_back(Pair("pubkey", HexStr(vchPubKey)));
|
ret.push_back(Pair("pubkey", HexStr(vchPubKey)));
|
||||||
std::string strPubKey(vchPubKey.begin(), vchPubKey.end());
|
std::string strPubKey(vchPubKey.begin(), vchPubKey.end());
|
||||||
ret.push_back(Pair("pubkey58", EncodeBase58(vchPubKey)));
|
ret.push_back(Pair("pubkey58", EncodeBase58(vchPubKey)));
|
||||||
|
CKey key;
|
||||||
|
key.SetPubKey(vchPubKey);
|
||||||
|
ret.push_back(Pair("iscompressed", key.IsCompressed()));
|
||||||
}
|
}
|
||||||
else if (pwalletMain->HaveCScript(address.GetHash160()))
|
else if (pwalletMain->HaveCScript(address.GetHash160()))
|
||||||
{
|
{
|
||||||
|
@ -860,12 +860,14 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
|
|||||||
{
|
{
|
||||||
CPrivKey pkey;
|
CPrivKey pkey;
|
||||||
ssValue >> pkey;
|
ssValue >> pkey;
|
||||||
|
key.SetPubKey(vchPubKey);
|
||||||
key.SetPrivKey(pkey);
|
key.SetPrivKey(pkey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CWalletKey wkey;
|
CWalletKey wkey;
|
||||||
ssValue >> wkey;
|
ssValue >> wkey;
|
||||||
|
key.SetPubKey(vchPubKey);
|
||||||
key.SetPrivKey(wkey.vchPrivKey);
|
key.SetPrivKey(wkey.vchPrivKey);
|
||||||
}
|
}
|
||||||
if (!pwallet->LoadKey(key))
|
if (!pwallet->LoadKey(key))
|
||||||
|
48
src/key.h
48
src/key.h
@ -59,16 +59,30 @@ class CKey
|
|||||||
protected:
|
protected:
|
||||||
EC_KEY* pkey;
|
EC_KEY* pkey;
|
||||||
bool fSet;
|
bool fSet;
|
||||||
|
bool fCompressedPubKey;
|
||||||
|
|
||||||
|
void SetCompressedPubKey()
|
||||||
|
{
|
||||||
|
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||||
|
fCompressedPubKey = true;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CKey()
|
|
||||||
|
void Reset()
|
||||||
{
|
{
|
||||||
|
fCompressedPubKey = false;
|
||||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||||
if (pkey == NULL)
|
if (pkey == NULL)
|
||||||
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
||||||
fSet = false;
|
fSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CKey()
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
CKey(const CKey& b)
|
CKey(const CKey& b)
|
||||||
{
|
{
|
||||||
pkey = EC_KEY_dup(b.pkey);
|
pkey = EC_KEY_dup(b.pkey);
|
||||||
@ -95,10 +109,17 @@ public:
|
|||||||
return !fSet;
|
return !fSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeNewKey()
|
bool IsCompressed() const
|
||||||
|
{
|
||||||
|
return fCompressedPubKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeNewKey(bool fCompressed = true)
|
||||||
{
|
{
|
||||||
if (!EC_KEY_generate_key(pkey))
|
if (!EC_KEY_generate_key(pkey))
|
||||||
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
||||||
|
if (fCompressed)
|
||||||
|
SetCompressedPubKey();
|
||||||
fSet = true;
|
fSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +132,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetSecret(const CSecret& vchSecret)
|
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false)
|
||||||
{
|
{
|
||||||
EC_KEY_free(pkey);
|
EC_KEY_free(pkey);
|
||||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||||
@ -126,10 +147,12 @@ public:
|
|||||||
throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
|
throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
|
||||||
BN_clear_free(bn);
|
BN_clear_free(bn);
|
||||||
fSet = true;
|
fSet = true;
|
||||||
|
if (fCompressed || fCompressedPubKey)
|
||||||
|
SetCompressedPubKey();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSecret GetSecret() const
|
CSecret GetSecret(bool &fCompressed) const
|
||||||
{
|
{
|
||||||
CSecret vchRet;
|
CSecret vchRet;
|
||||||
vchRet.resize(32);
|
vchRet.resize(32);
|
||||||
@ -140,6 +163,7 @@ public:
|
|||||||
int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
|
int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
|
||||||
if (n != nBytes)
|
if (n != nBytes)
|
||||||
throw key_error("CKey::GetSecret(): BN_bn2bin failed");
|
throw key_error("CKey::GetSecret(): BN_bn2bin failed");
|
||||||
|
fCompressed = fCompressedPubKey;
|
||||||
return vchRet;
|
return vchRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +185,8 @@ public:
|
|||||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
|
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
|
||||||
return false;
|
return false;
|
||||||
fSet = true;
|
fSet = true;
|
||||||
|
if (vchPubKey.size() == 33)
|
||||||
|
SetCompressedPubKey();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,6 +236,8 @@ public:
|
|||||||
{
|
{
|
||||||
CKey keyRec;
|
CKey keyRec;
|
||||||
keyRec.fSet = true;
|
keyRec.fSet = true;
|
||||||
|
if (fCompressedPubKey)
|
||||||
|
keyRec.SetCompressedPubKey();
|
||||||
if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1)
|
if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1)
|
||||||
if (keyRec.GetPubKey() == this->GetPubKey())
|
if (keyRec.GetPubKey() == this->GetPubKey())
|
||||||
{
|
{
|
||||||
@ -221,7 +249,7 @@ public:
|
|||||||
if (nRecId == -1)
|
if (nRecId == -1)
|
||||||
throw key_error("CKey::SignCompact() : unable to construct recoverable key");
|
throw key_error("CKey::SignCompact() : unable to construct recoverable key");
|
||||||
|
|
||||||
vchSig[0] = nRecId+27;
|
vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0);
|
||||||
BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]);
|
BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]);
|
||||||
BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]);
|
BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]);
|
||||||
fOk = true;
|
fOk = true;
|
||||||
@ -238,7 +266,8 @@ public:
|
|||||||
{
|
{
|
||||||
if (vchSig.size() != 65)
|
if (vchSig.size() != 65)
|
||||||
return false;
|
return false;
|
||||||
if (vchSig[0]<27 || vchSig[0]>=31)
|
int nV = vchSig[0];
|
||||||
|
if (nV<27 || nV>=35)
|
||||||
return false;
|
return false;
|
||||||
ECDSA_SIG *sig = ECDSA_SIG_new();
|
ECDSA_SIG *sig = ECDSA_SIG_new();
|
||||||
BN_bin2bn(&vchSig[1],32,sig->r);
|
BN_bin2bn(&vchSig[1],32,sig->r);
|
||||||
@ -246,7 +275,12 @@ public:
|
|||||||
|
|
||||||
EC_KEY_free(pkey);
|
EC_KEY_free(pkey);
|
||||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||||
if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), vchSig[0] - 27, 0) == 1)
|
if (nV >= 31)
|
||||||
|
{
|
||||||
|
SetCompressedPubKey();
|
||||||
|
nV -= 4;
|
||||||
|
}
|
||||||
|
if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1)
|
||||||
{
|
{
|
||||||
fSet = true;
|
fSet = true;
|
||||||
ECDSA_SIG_free(sig);
|
ECDSA_SIG_free(sig);
|
||||||
|
@ -29,8 +29,10 @@ bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned c
|
|||||||
|
|
||||||
bool CBasicKeyStore::AddKey(const CKey& key)
|
bool CBasicKeyStore::AddKey(const CKey& key)
|
||||||
{
|
{
|
||||||
|
bool fCompressed = false;
|
||||||
|
CSecret secret = key.GetSecret(fCompressed);
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
CRITICAL_BLOCK(cs_KeyStore)
|
||||||
mapKeys[CBitcoinAddress(key.GetPubKey())] = key.GetSecret();
|
mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,16 +79,6 @@ bool CCryptoKeyStore::SetCrypted()
|
|||||||
return true;
|
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)
|
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
CRITICAL_BLOCK(cs_KeyStore)
|
||||||
@ -103,6 +95,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
|||||||
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
|
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
|
||||||
return false;
|
return false;
|
||||||
CKey key;
|
CKey key;
|
||||||
|
key.SetPubKey(vchPubKey);
|
||||||
key.SetSecret(vchSecret);
|
key.SetSecret(vchSecret);
|
||||||
if (key.GetPubKey() == vchPubKey)
|
if (key.GetPubKey() == vchPubKey)
|
||||||
break;
|
break;
|
||||||
@ -125,7 +118,8 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
|
|||||||
|
|
||||||
std::vector<unsigned char> vchCryptedSecret;
|
std::vector<unsigned char> vchCryptedSecret;
|
||||||
std::vector<unsigned char> vchPubKey = key.GetPubKey();
|
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;
|
return false;
|
||||||
|
|
||||||
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
|
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
|
||||||
@ -147,19 +141,24 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetSecret(const CBitcoinAddress &address, CSecret& vchSecretOut) const
|
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
CRITICAL_BLOCK(cs_KeyStore)
|
||||||
{
|
{
|
||||||
if (!IsCrypted())
|
if (!IsCrypted())
|
||||||
return CBasicKeyStore::GetSecret(address, vchSecretOut);
|
return CBasicKeyStore::GetKey(address, keyOut);
|
||||||
|
|
||||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||||
if (mi != mapCryptedKeys.end())
|
if (mi != mapCryptedKeys.end())
|
||||||
{
|
{
|
||||||
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
|
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
|
||||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
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;
|
return false;
|
||||||
@ -190,14 +189,15 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
fUseCrypto = true;
|
fUseCrypto = true;
|
||||||
CKey key;
|
|
||||||
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
|
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
|
||||||
{
|
{
|
||||||
if (!key.SetSecret(mKey.second))
|
CKey key;
|
||||||
|
if (!key.SetSecret(mKey.second.first, false))
|
||||||
return false;
|
return false;
|
||||||
const std::vector<unsigned char> vchPubKey = key.GetPubKey();
|
const std::vector<unsigned char> vchPubKey = key.GetPubKey();
|
||||||
std::vector<unsigned char> vchCryptedSecret;
|
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;
|
return false;
|
||||||
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
|
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
|
||||||
return false;
|
return false;
|
||||||
|
@ -20,15 +20,7 @@ public:
|
|||||||
|
|
||||||
// Check whether a key corresponding to a given address is present in the store.
|
// Check whether a key corresponding to a given address is present in the store.
|
||||||
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
|
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
|
||||||
virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
|
||||||
{
|
|
||||||
CSecret vchSecret;
|
|
||||||
if (!GetSecret(address, vchSecret))
|
|
||||||
return false;
|
|
||||||
if (!keyOut.SetSecret(vchSecret))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
|
virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
|
||||||
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
|
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
|
||||||
|
|
||||||
@ -39,17 +31,17 @@ public:
|
|||||||
|
|
||||||
// Generate a new key, and add it to the store
|
// Generate a new key, and add it to the store
|
||||||
virtual std::vector<unsigned char> GenerateNewKey();
|
virtual std::vector<unsigned char> GenerateNewKey();
|
||||||
virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret) const
|
virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret, bool &fCompressed) const
|
||||||
{
|
{
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!GetKey(address, key))
|
if (!GetKey(address, key))
|
||||||
return false;
|
return false;
|
||||||
vchSecret = key.GetSecret();
|
vchSecret = key.GetSecret(fCompressed);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<CBitcoinAddress, CSecret> KeyMap;
|
typedef std::map<CBitcoinAddress, std::pair<CSecret, bool> > KeyMap;
|
||||||
typedef std::map<uint160, CScript > ScriptMap;
|
typedef std::map<uint160, CScript > ScriptMap;
|
||||||
|
|
||||||
// Basic key store, that keeps keys in an address->secret map
|
// Basic key store, that keeps keys in an address->secret map
|
||||||
@ -81,14 +73,15 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool GetSecret(const CBitcoinAddress &address, CSecret &vchSecret) const
|
bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
CRITICAL_BLOCK(cs_KeyStore)
|
||||||
{
|
{
|
||||||
KeyMap::const_iterator mi = mapKeys.find(address);
|
KeyMap::const_iterator mi = mapKeys.find(address);
|
||||||
if (mi != mapKeys.end())
|
if (mi != mapKeys.end())
|
||||||
{
|
{
|
||||||
vchSecret = (*mi).second;
|
keyOut.Reset();
|
||||||
|
keyOut.SetSecret((*mi).second.first, (*mi).second.second);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +147,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
std::vector<unsigned char> GenerateNewKey();
|
|
||||||
bool AddKey(const CKey& key);
|
bool AddKey(const CKey& key);
|
||||||
bool HaveKey(const CBitcoinAddress &address) const
|
bool HaveKey(const CBitcoinAddress &address) const
|
||||||
{
|
{
|
||||||
@ -166,7 +158,7 @@ public:
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret) const;
|
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
|
||||||
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
|
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
|
||||||
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
||||||
{
|
{
|
||||||
|
@ -62,7 +62,9 @@ Value importprivkey(const Array& params, bool fHelp)
|
|||||||
if (!fGood) throw JSONRPCError(-5,"Invalid private key");
|
if (!fGood) throw JSONRPCError(-5,"Invalid private key");
|
||||||
|
|
||||||
CKey key;
|
CKey key;
|
||||||
key.SetSecret(vchSecret.GetSecret());
|
bool fCompressed;
|
||||||
|
CSecret secret = vchSecret.GetSecret(fCompressed);
|
||||||
|
key.SetSecret(secret, fCompressed);
|
||||||
CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey());
|
CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey());
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
CRITICAL_BLOCK(cs_main)
|
||||||
@ -95,7 +97,8 @@ Value dumpprivkey(const Array& params, bool fHelp)
|
|||||||
if (!address.SetString(strAddress))
|
if (!address.SetString(strAddress))
|
||||||
throw JSONRPCError(-5, "Invalid bitcoin address");
|
throw JSONRPCError(-5, "Invalid bitcoin address");
|
||||||
CSecret vchSecret;
|
CSecret vchSecret;
|
||||||
if (!pwalletMain->GetSecret(address, vchSecret))
|
bool fCompressed;
|
||||||
|
if (!pwalletMain->GetSecret(address, vchSecret, fCompressed))
|
||||||
throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known");
|
throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known");
|
||||||
return CBitcoinSecret(vchSecret).ToString();
|
return CBitcoinSecret(vchSecret, fCompressed).ToString();
|
||||||
}
|
}
|
||||||
|
138
src/test/key_tests.cpp
Normal file
138
src/test/key_tests.cpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "key.h"
|
||||||
|
#include "base58.h"
|
||||||
|
#include "uint256.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj");
|
||||||
|
static const string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3");
|
||||||
|
static const string strSecret1C("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw");
|
||||||
|
static const string strSecret2C("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g");
|
||||||
|
|
||||||
|
#ifdef KEY_TESTS_DUMPINFO
|
||||||
|
void dumpKeyInfo(uint256 privkey)
|
||||||
|
{
|
||||||
|
CSecret secret;
|
||||||
|
secret.resize(32);
|
||||||
|
memcpy(&secret[0], &privkey, 32);
|
||||||
|
vector<unsigned char> sec;
|
||||||
|
sec.resize(32);
|
||||||
|
memcpy(&sec[0], &secret[0], 32);
|
||||||
|
printf(" * secret (hex): %s\n", HexStr(sec).c_str());
|
||||||
|
|
||||||
|
for (int nCompressed=0; nCompressed<2; nCompressed++)
|
||||||
|
{
|
||||||
|
bool fCompressed = nCompressed == 1;
|
||||||
|
printf(" * %s:\n", fCompressed ? "compressed" : "uncompressed");
|
||||||
|
CBitcoinSecret bsecret;
|
||||||
|
bsecret.SetSecret(secret, fCompressed);
|
||||||
|
printf(" * secret (base58): %s\n", bsecret.ToString().c_str());
|
||||||
|
CKey key;
|
||||||
|
key.SetSecret(secret, fCompressed);
|
||||||
|
vector<unsigned char> vchPubKey = key.GetPubKey();
|
||||||
|
printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str());
|
||||||
|
printf(" * address (base58): %s\n", CBitcoinAddress(vchPubKey).ToString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(key_tests)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(key_test1)
|
||||||
|
{
|
||||||
|
CBitcoinSecret bsecret1, bsecret2, bsecret1C, bsecret2C;
|
||||||
|
bsecret1.SetString (strSecret1);
|
||||||
|
bsecret2.SetString (strSecret2);
|
||||||
|
bsecret1C.SetString(strSecret1C);
|
||||||
|
bsecret2C.SetString(strSecret2C);
|
||||||
|
|
||||||
|
bool fCompressed;
|
||||||
|
CSecret secret1 = bsecret1.GetSecret (fCompressed);
|
||||||
|
BOOST_CHECK(fCompressed == false);
|
||||||
|
CSecret secret2 = bsecret2.GetSecret (fCompressed);
|
||||||
|
BOOST_CHECK(fCompressed == false);
|
||||||
|
CSecret secret1C = bsecret1C.GetSecret(fCompressed);
|
||||||
|
BOOST_CHECK(fCompressed == true);
|
||||||
|
CSecret secret2C = bsecret2C.GetSecret(fCompressed);
|
||||||
|
BOOST_CHECK(fCompressed == true);
|
||||||
|
|
||||||
|
BOOST_CHECK(secret1 == secret1C);
|
||||||
|
BOOST_CHECK(secret2 == secret2C);
|
||||||
|
|
||||||
|
CKey key1, key2, key1C, key2C;
|
||||||
|
key1.SetSecret(secret1, false);
|
||||||
|
key2.SetSecret(secret2, false);
|
||||||
|
key1C.SetSecret(secret1, true);
|
||||||
|
key2C.SetSecret(secret2, true);
|
||||||
|
|
||||||
|
BOOST_CHECK(CBitcoinAddress(key1.GetPubKey ()).ToString() == "1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ");
|
||||||
|
BOOST_CHECK(CBitcoinAddress(key2.GetPubKey ()).ToString() == "1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ");
|
||||||
|
BOOST_CHECK(CBitcoinAddress(key1C.GetPubKey()).ToString() == "1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs");
|
||||||
|
BOOST_CHECK(CBitcoinAddress(key2C.GetPubKey()).ToString() == "1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs");
|
||||||
|
|
||||||
|
for (int n=0; n<16; n++)
|
||||||
|
{
|
||||||
|
string strMsg = strprintf("Very secret message %i: 11", n);
|
||||||
|
uint256 hashMsg = Hash(strMsg.begin(), strMsg.end());
|
||||||
|
|
||||||
|
// normal signatures
|
||||||
|
|
||||||
|
vector<unsigned char> sign1, sign2, sign1C, sign2C;
|
||||||
|
|
||||||
|
BOOST_CHECK(key1.Sign (hashMsg, sign1));
|
||||||
|
BOOST_CHECK(key2.Sign (hashMsg, sign2));
|
||||||
|
BOOST_CHECK(key1C.Sign(hashMsg, sign1C));
|
||||||
|
BOOST_CHECK(key2C.Sign(hashMsg, sign2C));
|
||||||
|
|
||||||
|
BOOST_CHECK( key1.Verify(hashMsg, sign1));
|
||||||
|
BOOST_CHECK(!key1.Verify(hashMsg, sign2));
|
||||||
|
BOOST_CHECK( key1.Verify(hashMsg, sign1C));
|
||||||
|
BOOST_CHECK(!key1.Verify(hashMsg, sign2C));
|
||||||
|
|
||||||
|
BOOST_CHECK(!key2.Verify(hashMsg, sign1));
|
||||||
|
BOOST_CHECK( key2.Verify(hashMsg, sign2));
|
||||||
|
BOOST_CHECK(!key2.Verify(hashMsg, sign1C));
|
||||||
|
BOOST_CHECK( key2.Verify(hashMsg, sign2C));
|
||||||
|
|
||||||
|
BOOST_CHECK( key1C.Verify(hashMsg, sign1));
|
||||||
|
BOOST_CHECK(!key1C.Verify(hashMsg, sign2));
|
||||||
|
BOOST_CHECK( key1C.Verify(hashMsg, sign1C));
|
||||||
|
BOOST_CHECK(!key1C.Verify(hashMsg, sign2C));
|
||||||
|
|
||||||
|
BOOST_CHECK(!key2C.Verify(hashMsg, sign1));
|
||||||
|
BOOST_CHECK( key2C.Verify(hashMsg, sign2));
|
||||||
|
BOOST_CHECK(!key2C.Verify(hashMsg, sign1C));
|
||||||
|
BOOST_CHECK( key2C.Verify(hashMsg, sign2C));
|
||||||
|
|
||||||
|
// compact signatures (with key recovery)
|
||||||
|
|
||||||
|
vector<unsigned char> csign1, csign2, csign1C, csign2C;
|
||||||
|
|
||||||
|
BOOST_CHECK(key1.SignCompact (hashMsg, csign1));
|
||||||
|
BOOST_CHECK(key2.SignCompact (hashMsg, csign2));
|
||||||
|
BOOST_CHECK(key1C.SignCompact(hashMsg, csign1C));
|
||||||
|
BOOST_CHECK(key2C.SignCompact(hashMsg, csign2C));
|
||||||
|
|
||||||
|
CKey rkey1, rkey2, rkey1C, rkey2C;
|
||||||
|
|
||||||
|
BOOST_CHECK(rkey1.SetCompactSignature (hashMsg, csign1));
|
||||||
|
BOOST_CHECK(rkey2.SetCompactSignature (hashMsg, csign2));
|
||||||
|
BOOST_CHECK(rkey1C.SetCompactSignature(hashMsg, csign1C));
|
||||||
|
BOOST_CHECK(rkey2C.SetCompactSignature(hashMsg, csign2C));
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_CHECK(rkey1.GetPubKey() == key1.GetPubKey());
|
||||||
|
BOOST_CHECK(rkey2.GetPubKey() == key2.GetPubKey());
|
||||||
|
BOOST_CHECK(rkey1C.GetPubKey() == key1C.GetPubKey());
|
||||||
|
BOOST_CHECK(rkey2C.GetPubKey() == key2C.GetPubKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue
Block a user