Browse Source

Merge pull request #6034

a574899 chaincodes: abstract away more chaincode behavior [squashme] replace struct CCainCode with a typedef uint256 ChainCode (Cory Fields)
8cf1485 Abstract chaincodes into CChainCode (Pieter Wuille)
0.13
Wladimir J. van der Laan 10 years ago
parent
commit
6a877e870e
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 8
      src/hash.cpp
  2. 4
      src/hash.h
  3. 14
      src/key.cpp
  4. 10
      src/key.h
  5. 10
      src/pubkey.cpp
  6. 10
      src/pubkey.h

8
src/hash.cpp

@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
#include "hash.h"
#include "crypto/common.h"
#include "crypto/hmac_sha512.h"
#include "pubkey.h"
inline uint32_t ROTL32(uint32_t x, int8_t r)
@ -71,15 +72,12 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char @@ -71,15 +72,12 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
return h1;
}
void BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
{
unsigned char num[4];
num[0] = (nChild >> 24) & 0xFF;
num[1] = (nChild >> 16) & 0xFF;
num[2] = (nChild >> 8) & 0xFF;
num[3] = (nChild >> 0) & 0xFF;
CHMAC_SHA512(chainCode, 32).Write(&header, 1)
.Write(data, 32)
.Write(num, 4)
.Finalize(output);
CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
}

4
src/hash.h

@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
#include <vector>
typedef uint256 ChainCode;
/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
class CHash256 {
private:
@ -159,6 +161,6 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL @@ -159,6 +161,6 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
void BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
#endif // BITCOIN_HASH_H

14
src/key.cpp

@ -111,7 +111,7 @@ bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { @@ -111,7 +111,7 @@ bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) {
return VerifyPubKey(vchPubKey);
}
bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
assert(IsValid());
assert(IsCompressed());
unsigned char out[64];
@ -124,7 +124,7 @@ bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild @@ -124,7 +124,7 @@ bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild
assert(begin() + 32 == end());
BIP32Hash(cc, nChild, 0, begin(), out);
}
memcpy(ccChild, out+32, 32);
memcpy(ccChild.begin(), out+32, 32);
memcpy((unsigned char*)keyChild.begin(), begin(), 32);
bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context, (unsigned char*)keyChild.begin(), out);
UnlockObject(out);
@ -138,7 +138,7 @@ bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const { @@ -138,7 +138,7 @@ bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const {
CKeyID id = key.GetPubKey().GetID();
memcpy(&out.vchFingerprint[0], &id, 4);
out.nChild = nChild;
return key.Derive(out.key, out.vchChainCode, nChild, vchChainCode);
return key.Derive(out.key, out.chaincode, nChild, chaincode);
}
void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
@ -147,7 +147,7 @@ void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) { @@ -147,7 +147,7 @@ void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
LockObject(out);
CHMAC_SHA512(hashkey, sizeof(hashkey)).Write(seed, nSeedLen).Finalize(out);
key.Set(&out[0], &out[32], true);
memcpy(vchChainCode, &out[32], 32);
memcpy(chaincode.begin(), &out[32], 32);
UnlockObject(out);
nDepth = 0;
nChild = 0;
@ -160,7 +160,7 @@ CExtPubKey CExtKey::Neuter() const { @@ -160,7 +160,7 @@ CExtPubKey CExtKey::Neuter() const {
memcpy(&ret.vchFingerprint[0], &vchFingerprint[0], 4);
ret.nChild = nChild;
ret.pubkey = key.GetPubKey();
memcpy(&ret.vchChainCode[0], &vchChainCode[0], 32);
ret.chaincode = chaincode;
return ret;
}
@ -169,7 +169,7 @@ void CExtKey::Encode(unsigned char code[74]) const { @@ -169,7 +169,7 @@ void CExtKey::Encode(unsigned char code[74]) const {
memcpy(code+1, vchFingerprint, 4);
code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
memcpy(code+9, vchChainCode, 32);
memcpy(code+9, chaincode.begin(), 32);
code[41] = 0;
assert(key.size() == 32);
memcpy(code+42, key.begin(), 32);
@ -179,7 +179,7 @@ void CExtKey::Decode(const unsigned char code[74]) { @@ -179,7 +179,7 @@ void CExtKey::Decode(const unsigned char code[74]) {
nDepth = code[0];
memcpy(vchFingerprint, code+1, 4);
nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
memcpy(vchChainCode, code+9, 32);
memcpy(chaincode.begin(), code+9, 32);
key.Set(code+42, code+74, true);
}

10
src/key.h

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
#ifndef BITCOIN_KEY_H
#define BITCOIN_KEY_H
#include "pubkey.h"
#include "serialize.h"
#include "support/allocators/secure.h"
#include "uint256.h"
@ -13,9 +14,6 @@ @@ -13,9 +14,6 @@
#include <stdexcept>
#include <vector>
class CPubKey;
struct CExtPubKey;
/**
* secp256k1:
@ -138,7 +136,7 @@ public: @@ -138,7 +136,7 @@ public:
bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
//! Derive BIP32 child key.
bool Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const;
bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
/**
* Verify thoroughly whether a private key and a public key match.
@ -157,13 +155,13 @@ struct CExtKey { @@ -157,13 +155,13 @@ struct CExtKey {
unsigned char nDepth;
unsigned char vchFingerprint[4];
unsigned int nChild;
unsigned char vchChainCode[32];
ChainCode chaincode;
CKey key;
friend bool operator==(const CExtKey& a, const CExtKey& b)
{
return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.key == b.key;
a.chaincode == b.chaincode && a.key == b.key;
}
void Encode(unsigned char code[74]) const;

10
src/pubkey.cpp

@ -54,13 +54,13 @@ bool CPubKey::Decompress() { @@ -54,13 +54,13 @@ bool CPubKey::Decompress() {
return true;
}
bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
assert(IsValid());
assert((nChild >> 31) == 0);
assert(begin() + 33 == end());
unsigned char out[64];
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
memcpy(ccChild, out+32, 32);
memcpy(ccChild.begin(), out+32, 32);
CECKey key;
bool ret = key.SetPubKey(begin(), size());
ret &= key.TweakPublic(out);
@ -75,7 +75,7 @@ void CExtPubKey::Encode(unsigned char code[74]) const { @@ -75,7 +75,7 @@ void CExtPubKey::Encode(unsigned char code[74]) const {
memcpy(code+1, vchFingerprint, 4);
code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
memcpy(code+9, vchChainCode, 32);
memcpy(code+9, chaincode.begin(), 32);
assert(pubkey.size() == 33);
memcpy(code+41, pubkey.begin(), 33);
}
@ -84,7 +84,7 @@ void CExtPubKey::Decode(const unsigned char code[74]) { @@ -84,7 +84,7 @@ void CExtPubKey::Decode(const unsigned char code[74]) {
nDepth = code[0];
memcpy(vchFingerprint, code+1, 4);
nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
memcpy(vchChainCode, code+9, 32);
memcpy(chaincode.begin(), code+9, 32);
pubkey.Set(code+41, code+74);
}
@ -93,5 +93,5 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const { @@ -93,5 +93,5 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const {
CKeyID id = pubkey.GetID();
memcpy(&out.vchFingerprint[0], &id, 4);
out.nChild = nChild;
return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode);
return pubkey.Derive(out.pubkey, out.chaincode, nChild, chaincode);
}

10
src/pubkey.h

@ -31,6 +31,8 @@ public: @@ -31,6 +31,8 @@ public:
CKeyID(const uint160& in) : uint160(in) {}
};
typedef uint256 ChainCode;
/** An encapsulated public key. */
class CPubKey
{
@ -182,20 +184,20 @@ public: @@ -182,20 +184,20 @@ public:
bool Decompress();
//! Derive BIP32 child pubkey.
bool Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const;
bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
};
struct CExtPubKey {
unsigned char nDepth;
unsigned char vchFingerprint[4];
unsigned int nChild;
unsigned char vchChainCode[32];
ChainCode chaincode;
CPubKey pubkey;
friend bool operator==(const CExtPubKey& a, const CExtPubKey& b)
friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
{
return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.pubkey == b.pubkey;
a.chaincode == b.chaincode && a.pubkey == b.pubkey;
}
void Encode(unsigned char code[74]) const;

Loading…
Cancel
Save