Browse Source

add bip32 pubkey serialization

CExtPubKey should be serializable like CPubKey
0.13
Jonas Schnelli 10 years ago committed by Jonas Schnelli
parent
commit
90604f16af
No known key found for this signature in database
GPG Key ID: 29D4BCB6416F53EC
  1. 4
      src/base58.h
  2. 6
      src/key.cpp
  3. 21
      src/key.h
  4. 6
      src/pubkey.cpp
  5. 30
      src/pubkey.h
  6. 16
      src/test/bip32_tests.cpp

4
src/base58.h

@ -164,7 +164,7 @@ public: @@ -164,7 +164,7 @@ public:
CBitcoinExtKeyBase() {}
};
typedef CBitcoinExtKeyBase<CExtKey, 74, CChainParams::EXT_SECRET_KEY> CBitcoinExtKey;
typedef CBitcoinExtKeyBase<CExtPubKey, 74, CChainParams::EXT_PUBLIC_KEY> CBitcoinExtPubKey;
typedef CBitcoinExtKeyBase<CExtKey, BIP32_EXTKEY_SIZE, CChainParams::EXT_SECRET_KEY> CBitcoinExtKey;
typedef CBitcoinExtKeyBase<CExtPubKey, BIP32_EXTKEY_SIZE, CChainParams::EXT_PUBLIC_KEY> CBitcoinExtPubKey;
#endif // BITCOIN_BASE58_H

6
src/key.cpp

@ -275,7 +275,7 @@ CExtPubKey CExtKey::Neuter() const { @@ -275,7 +275,7 @@ CExtPubKey CExtKey::Neuter() const {
return ret;
}
void CExtKey::Encode(unsigned char code[74]) const {
void CExtKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
code[0] = nDepth;
memcpy(code+1, vchFingerprint, 4);
code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
@ -286,12 +286,12 @@ void CExtKey::Encode(unsigned char code[74]) const { @@ -286,12 +286,12 @@ void CExtKey::Encode(unsigned char code[74]) const {
memcpy(code+42, key.begin(), 32);
}
void CExtKey::Decode(const unsigned char code[74]) {
void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
nDepth = code[0];
memcpy(vchFingerprint, code+1, 4);
nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
memcpy(chaincode.begin(), code+9, 32);
key.Set(code+42, code+74, true);
key.Set(code+42, code+BIP32_EXTKEY_SIZE, true);
}
bool ECC_InitSanityCheck() {

21
src/key.h

@ -164,11 +164,28 @@ struct CExtKey { @@ -164,11 +164,28 @@ struct CExtKey {
a.chaincode == b.chaincode && a.key == b.key;
}
void Encode(unsigned char code[74]) const;
void Decode(const unsigned char code[74]);
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
bool Derive(CExtKey& out, unsigned int nChild) const;
CExtPubKey Neuter() const;
void SetMaster(const unsigned char* seed, unsigned int nSeedLen);
template <typename Stream>
void Serialize(Stream& s, int nType, int nVersion) const
{
unsigned int len = BIP32_EXTKEY_SIZE;
::WriteCompactSize(s, len);
unsigned char code[BIP32_EXTKEY_SIZE];
Encode(code);
s.write((const char *)&code[0], len);
}
template <typename Stream>
void Unserialize(Stream& s, int nType, int nVersion)
{
unsigned int len = ::ReadCompactSize(s);
unsigned char code[BIP32_EXTKEY_SIZE];
s.read((char *)&code[0], len);
Decode(code);
}
};
/** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */

6
src/pubkey.cpp

@ -246,7 +246,7 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi @@ -246,7 +246,7 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi
return true;
}
void CExtPubKey::Encode(unsigned char code[74]) const {
void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
code[0] = nDepth;
memcpy(code+1, vchFingerprint, 4);
code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
@ -256,12 +256,12 @@ void CExtPubKey::Encode(unsigned char code[74]) const { @@ -256,12 +256,12 @@ void CExtPubKey::Encode(unsigned char code[74]) const {
memcpy(code+41, pubkey.begin(), 33);
}
void CExtPubKey::Decode(const unsigned char code[74]) {
void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
nDepth = code[0];
memcpy(vchFingerprint, code+1, 4);
nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
memcpy(chaincode.begin(), code+9, 32);
pubkey.Set(code+41, code+74);
pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
}
bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const {

30
src/pubkey.h

@ -23,6 +23,8 @@ @@ -23,6 +23,8 @@
* script supports up to 75 for single byte push
*/
const unsigned int BIP32_EXTKEY_SIZE = 74;
/** A reference to a CKey: the Hash160 of its serialized public key */
class CKeyID : public uint160
{
@ -205,9 +207,33 @@ struct CExtPubKey { @@ -205,9 +207,33 @@ struct CExtPubKey {
a.chaincode == b.chaincode && a.pubkey == b.pubkey;
}
void Encode(unsigned char code[74]) const;
void Decode(const unsigned char code[74]);
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
bool Derive(CExtPubKey& out, unsigned int nChild) const;
unsigned int GetSerializeSize(int nType, int nVersion) const
{
return BIP32_EXTKEY_SIZE+1; //add one byte for the size (compact int)
}
template <typename Stream>
void Serialize(Stream& s, int nType, int nVersion) const
{
unsigned int len = BIP32_EXTKEY_SIZE;
::WriteCompactSize(s, len);
unsigned char code[BIP32_EXTKEY_SIZE];
Encode(code);
s.write((const char *)&code[0], len);
}
template <typename Stream>
void Unserialize(Stream& s, int nType, int nVersion)
{
unsigned int len = ::ReadCompactSize(s);
unsigned char code[BIP32_EXTKEY_SIZE];
if (len != BIP32_EXTKEY_SIZE)
throw std::runtime_error("Invalid extended key size\n");
s.read((char *)&code[0], len);
Decode(code);
}
};
/** Users of this module must hold an ECCVerifyHandle. The constructor and

16
src/test/bip32_tests.cpp

@ -117,6 +117,22 @@ void RunTest(const TestVector &test) { @@ -117,6 +117,22 @@ void RunTest(const TestVector &test) {
}
key = keyNew;
pubkey = pubkeyNew;
CDataStream ssPub(SER_DISK, CLIENT_VERSION);
ssPub << pubkeyNew;
BOOST_CHECK(ssPub.size() == 75);
CDataStream ssPriv(SER_DISK, CLIENT_VERSION);
ssPriv << keyNew;
BOOST_CHECK(ssPriv.size() == 75);
CExtPubKey pubCheck;
CExtKey privCheck;
ssPub >> pubCheck;
ssPriv >> privCheck;
BOOST_CHECK(pubCheck == pubkeyNew);
BOOST_CHECK(privCheck == keyNew);
}
}

Loading…
Cancel
Save