-
Notifications
You must be signed in to change notification settings - Fork 94
/
hdkeys.h
142 lines (111 loc) · 4.09 KB
/
hdkeys.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
////////////////////////////////////////////////////////////////////////////////
//
// hdkeys.h
//
// Copyright (c) 2013-2014 Eric Lombrozo
// Copyright (c) 2011-2016 Ciphrex Corp.
//
// Distributed under the MIT software license, see the accompanying
// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
//
#ifndef COIN_HDKEYS_H
#define COIN_HDKEYS_H
#include "hash.h"
#include "typedefs.h"
#include <stdexcept>
namespace Coin {
const uchar_vector BITCOIN_SEED("426974636f696e2073656564"); // key = "Bitcoin seed"
class HDSeed
{
public:
HDSeed(const bytes_t& seed, const bytes_t& coin_seed = BITCOIN_SEED)
{
bytes_t hmac = hmac_sha512(coin_seed, seed);
master_key_.assign(hmac.begin(), hmac.begin() + 32);
master_chain_code_.assign(hmac.begin() + 32, hmac.end());
}
const bytes_t& getSeed() const { return seed_; }
const bytes_t& getMasterKey() const { return master_key_; }
const bytes_t& getMasterChainCode() const { return master_chain_code_; }
bytes_t getExtendedKey(bool bPrivate = false) const;
private:
bytes_t seed_;
bytes_t master_key_;
bytes_t master_chain_code_;
};
class InvalidHDKeychainException : public std::runtime_error
{
public:
InvalidHDKeychainException()
: std::runtime_error("Keychain is invalid.") { }
};
class InvalidHDKeychainPathException : public std::runtime_error
{
public:
InvalidHDKeychainPathException()
: std::runtime_error("Keychain path is invalid.") { }
};
class HDKeychain
{
public:
HDKeychain() { }
HDKeychain(const bytes_t& key, const bytes_t& chain_code, uint32_t child_num = 0, uint32_t parent_fp = 0, uint32_t depth = 0);
HDKeychain(const bytes_t& extkey);
HDKeychain(const HDKeychain& source);
HDKeychain& operator=(const HDKeychain& rhs);
explicit operator bool() const { return valid_; }
bool operator==(const HDKeychain& rhs) const;
bool operator!=(const HDKeychain& rhs) const;
// Serialization
bytes_t extkey() const;
// Accessor Methods
uint32_t version() const { return version_; }
int depth() const { return depth_; }
uint32_t parent_fp() const { return parent_fp_; }
uint32_t child_num() const { return child_num_; }
const bytes_t& chain_code() const { return chain_code_; }
const bytes_t& key() const { return key_; }
bytes_t privkey() const;
const bytes_t& pubkey() const { return pubkey_; }
bytes_t uncompressed_pubkey() const;
bool isPrivate() const { return (key_.size() == 33 && key_[0] == 0x00); }
bytes_t hash() const; // hash is ripemd160(sha256(pubkey))
uint32_t fp() const; // fingerprint is first 32 bits of hash
bytes_t full_hash() const; // full_hash is ripemd160(sha256(pubkey + chain_code))
HDKeychain getPublic() const;
HDKeychain getChild(uint32_t i) const;
HDKeychain getChild(const std::string& path) const;
HDKeychain getChildNode(uint32_t i, bool private_derivation = false) const
{
uint32_t mask = private_derivation ? 0x80000000ull : 0x00000000ull;
return getChild(mask).getChild(i);
}
// Precondition: i >= 1
bytes_t getPrivateSigningKey(uint32_t i) const
{
// if (i == 0) throw std::runtime_error("Signing key index cannot be zero.");
return getChild(i).privkey();
}
// Precondition: i >= 1
bytes_t getPublicSigningKey(uint32_t i, bool bCompressed = true) const
{
// if (i == 0) throw std::runtime_error("Signing key index cannot be zero.");
return bCompressed ? getChild(i).pubkey() : getChild(i).uncompressed_pubkey();
}
static void setVersions(uint32_t priv_version, uint32_t pub_version) { priv_version_ = priv_version; pub_version_ = pub_version; }
std::string toString() const;
private:
static uint32_t priv_version_;
static uint32_t pub_version_;
uint32_t version_;
unsigned char depth_;
uint32_t parent_fp_;
uint32_t child_num_;
bytes_t chain_code_; // 32 bytes
bytes_t key_; // 33 bytes, first byte is 0x00 for private key
bytes_t pubkey_;
bool valid_;
void updatePubkey();
};
}
#endif // COIN_HDKEYS_H