Make CPubKey statically allocated
This commit is contained in:
parent
ec0004aca0
commit
5d891489ab
7 changed files with 98 additions and 28 deletions
11
src/hash.h
11
src/hash.h
|
@ -105,15 +105,22 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
|
||||||
return ss.GetHash();
|
return ss.GetHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint160 Hash160(const std::vector<unsigned char>& vch)
|
template<typename T1>
|
||||||
|
inline uint160 Hash160(const T1 pbegin, const T1 pend)
|
||||||
{
|
{
|
||||||
|
static unsigned char pblank[1];
|
||||||
uint256 hash1;
|
uint256 hash1;
|
||||||
SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
|
SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
|
||||||
uint160 hash2;
|
uint160 hash2;
|
||||||
RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||||
return hash2;
|
return hash2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint160 Hash160(const std::vector<unsigned char>& vch)
|
||||||
|
{
|
||||||
|
return Hash160(vch.begin(), vch.end());
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
|
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
14
src/key.cpp
14
src/key.cpp
|
@ -258,11 +258,11 @@ CPrivKey CKey::GetPrivKey() const
|
||||||
|
|
||||||
bool CKey::SetPubKey(const CPubKey& vchPubKey)
|
bool CKey::SetPubKey(const CPubKey& vchPubKey)
|
||||||
{
|
{
|
||||||
const unsigned char* pbegin = &vchPubKey.vchPubKey[0];
|
const unsigned char* pbegin = vchPubKey.begin();
|
||||||
if (o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.vchPubKey.size()))
|
if (o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
|
||||||
{
|
{
|
||||||
fSet = true;
|
fSet = true;
|
||||||
if (vchPubKey.vchPubKey.size() == 33)
|
if (vchPubKey.size() == 33)
|
||||||
SetCompressedPubKey();
|
SetCompressedPubKey();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -276,11 +276,13 @@ CPubKey CKey::GetPubKey() const
|
||||||
int nSize = i2o_ECPublicKey(pkey, NULL);
|
int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||||
if (!nSize)
|
if (!nSize)
|
||||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||||
std::vector<unsigned char> vchPubKey(nSize, 0);
|
assert(nSize <= 65);
|
||||||
unsigned char* pbegin = &vchPubKey[0];
|
CPubKey ret;
|
||||||
|
unsigned char *pbegin = ret.begin();
|
||||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||||
return CPubKey(vchPubKey);
|
assert((int)ret.size() == nSize);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)
|
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||||
|
|
85
src/key.h
85
src/key.h
|
@ -63,38 +63,95 @@ public:
|
||||||
/** An encapsulated public key. */
|
/** An encapsulated public key. */
|
||||||
class CPubKey {
|
class CPubKey {
|
||||||
private:
|
private:
|
||||||
std::vector<unsigned char> vchPubKey;
|
unsigned char vch[65];
|
||||||
|
|
||||||
|
unsigned int static GetLen(unsigned char chHeader) {
|
||||||
|
if (chHeader == 2 || chHeader == 3)
|
||||||
|
return 33;
|
||||||
|
if (chHeader == 4 || chHeader == 6 || chHeader == 7)
|
||||||
|
return 65;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *begin() {
|
||||||
|
return vch;
|
||||||
|
}
|
||||||
|
|
||||||
friend class CKey;
|
friend class CKey;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPubKey() { }
|
CPubKey() { vch[0] = 0xFF; }
|
||||||
CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
|
|
||||||
friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; }
|
|
||||||
friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; }
|
|
||||||
friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
|
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE(
|
CPubKey(const std::vector<unsigned char> &vchPubKeyIn) {
|
||||||
READWRITE(vchPubKey);
|
int len = vchPubKeyIn.empty() ? 0 : GetLen(vchPubKeyIn[0]);
|
||||||
)
|
if (len) {
|
||||||
|
memcpy(vch, &vchPubKeyIn[0], len);
|
||||||
|
} else {
|
||||||
|
vch[0] = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int size() const {
|
||||||
|
return GetLen(vch[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char *begin() const {
|
||||||
|
return vch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char *end() const {
|
||||||
|
return vch+size();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const CPubKey &a, const CPubKey &b) { return memcmp(a.vch, b.vch, a.size()) == 0; }
|
||||||
|
friend bool operator!=(const CPubKey &a, const CPubKey &b) { return memcmp(a.vch, b.vch, a.size()) != 0; }
|
||||||
|
friend bool operator<(const CPubKey &a, const CPubKey &b) {
|
||||||
|
return a.vch[0] < b.vch[0] ||
|
||||||
|
(a.vch[0] == b.vch[0] && memcmp(a.vch+1, b.vch+1, a.size() - 1) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int GetSerializeSize(int nType, int nVersion) const {
|
||||||
|
return size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const {
|
||||||
|
unsigned int len = size();
|
||||||
|
::Serialize(s, VARINT(len), nType, nVersion);
|
||||||
|
s.write((char*)vch, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) {
|
||||||
|
unsigned int len;
|
||||||
|
::Unserialize(s, VARINT(len), nType, nVersion);
|
||||||
|
if (len <= 65) {
|
||||||
|
s.read((char*)vch, len);
|
||||||
|
} else {
|
||||||
|
// invalid pubkey
|
||||||
|
vch[0] = 0xFF;
|
||||||
|
char dummy;
|
||||||
|
while (len--)
|
||||||
|
s.read(&dummy, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CKeyID GetID() const {
|
CKeyID GetID() const {
|
||||||
return CKeyID(Hash160(vchPubKey));
|
return CKeyID(Hash160(vch, vch+size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 GetHash() const {
|
uint256 GetHash() const {
|
||||||
return Hash(vchPubKey.begin(), vchPubKey.end());
|
return Hash(vch, vch+size());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValid() const {
|
bool IsValid() const {
|
||||||
return vchPubKey.size() == 33 || vchPubKey.size() == 65;
|
return size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCompressed() const {
|
bool IsCompressed() const {
|
||||||
return vchPubKey.size() == 33;
|
return size() == 33;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> Raw() const {
|
std::vector<unsigned char> Raw() const {
|
||||||
return vchPubKey;
|
return std::vector<unsigned char>(vch, vch+size());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1445,7 +1445,7 @@ public:
|
||||||
CPubKey vchPubKey;
|
CPubKey vchPubKey;
|
||||||
pwalletMain->GetPubKey(keyID, vchPubKey);
|
pwalletMain->GetPubKey(keyID, vchPubKey);
|
||||||
obj.push_back(Pair("isscript", false));
|
obj.push_back(Pair("isscript", false));
|
||||||
obj.push_back(Pair("pubkey", HexStr(vchPubKey.Raw())));
|
obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
|
||||||
obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
|
obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1895,10 +1895,11 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector<unsigne
|
||||||
if (!key.SetPubKey(CPubKey(vch)))
|
if (!key.SetPubKey(CPubKey(vch)))
|
||||||
return false;
|
return false;
|
||||||
key.SetCompressedPubKey(false); // Decompress public key
|
key.SetCompressedPubKey(false); // Decompress public key
|
||||||
CPubKey pubkey = key.GetPubKey();
|
const CPubKey pubkey = key.GetPubKey();
|
||||||
|
assert(pubkey.size() == 65);
|
||||||
script.resize(67);
|
script.resize(67);
|
||||||
script[0] = 65;
|
script[0] = 65;
|
||||||
memcpy(&script[1], &pubkey.Raw()[0], 65);
|
memcpy(&script[1], pubkey.begin(), 65);
|
||||||
script[66] = OP_CHECKSIG;
|
script[66] = OP_CHECKSIG;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,8 +348,10 @@ public:
|
||||||
|
|
||||||
CScript& operator<<(const CPubKey& key)
|
CScript& operator<<(const CPubKey& key)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> vchKey = key.Raw();
|
assert(key.size() < OP_PUSHDATA1);
|
||||||
return (*this) << vchKey;
|
insert(end(), (unsigned char)key.size());
|
||||||
|
insert(end(), key.begin(), key.end());
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScript& operator<<(const CBigNum& b)
|
CScript& operator<<(const CBigNum& b)
|
||||||
|
|
|
@ -300,7 +300,8 @@ std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)
|
template<typename T>
|
||||||
|
inline std::string HexStr(const T& vch, bool fSpaces=false)
|
||||||
{
|
{
|
||||||
return HexStr(vch.begin(), vch.end(), fSpaces);
|
return HexStr(vch.begin(), vch.end(), fSpaces);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue