]>
Commit | Line | Data |
---|---|---|
8bd66202 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
877964c8 | 3 | // Copyright (c) 2017 The Zcash developers |
ffd8edda | 4 | // Distributed under the MIT software license, see the accompanying |
bc909a7a | 5 | // file COPYING or https://www.opensource.org/licenses/mit-license.php . |
51ed9ec9 | 6 | |
223b6f1b WL |
7 | #ifndef BITCOIN_KEY_H |
8 | #define BITCOIN_KEY_H | |
8bd66202 | 9 | |
8cf1485f | 10 | #include "pubkey.h" |
fd61d6f5 | 11 | #include "serialize.h" |
d7d187e8 | 12 | #include "support/allocators/secure.h" |
fcedd45c | 13 | #include "uint256.h" |
51ed9ec9 BD |
14 | |
15 | #include <stdexcept> | |
16 | #include <vector> | |
fcedd45c | 17 | |
a01fa303 | 18 | |
ffd8edda MF |
19 | /** |
20 | * secure_allocator is defined in allocators.h | |
877964c8 JG |
21 | * CPrivKey is a serialized private key, with all parameters included |
22 | * (PRIVATE_KEY_SIZE bytes) | |
ffd8edda | 23 | */ |
223b6f1b | 24 | typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; |
8bd66202 | 25 | |
dfa23b94 | 26 | /** An encapsulated private key. */ |
20e01b1a PW |
27 | class CKey |
28 | { | |
c4c7c663 JG |
29 | public: |
30 | /** | |
31 | * secp256k1: | |
32 | */ | |
33 | static const unsigned int PRIVATE_KEY_SIZE = 279; | |
34 | static const unsigned int COMPRESSED_PRIVATE_KEY_SIZE = 214; | |
35 | /** | |
36 | * see www.keylength.com | |
37 | * script supports up to 75 for single byte push | |
38 | */ | |
39 | static_assert( | |
40 | PRIVATE_KEY_SIZE >= COMPRESSED_PRIVATE_KEY_SIZE, | |
41 | "COMPRESSED_PRIVATE_KEY_SIZE is larger than PRIVATE_KEY_SIZE"); | |
42 | ||
dfa23b94 | 43 | private: |
ffd8edda MF |
44 | //! Whether this private key is valid. We check for correctness when modifying the key |
45 | //! data, so fValid should always correspond to the actual state. | |
dfa23b94 | 46 | bool fValid; |
11529c6e | 47 | |
ffd8edda | 48 | //! Whether the public key corresponding to this private key is (to be) compressed. |
dfa23b94 PW |
49 | bool fCompressed; |
50 | ||
ffd8edda | 51 | //! The actual byte data |
dfa23b94 PW |
52 | unsigned char vch[32]; |
53 | ||
ffd8edda | 54 | //! Check whether the 32-byte array pointed to be vch is valid keydata. |
20e01b1a | 55 | bool static Check(const unsigned char* vch); |
11529c6e | 56 | |
20e01b1a | 57 | public: |
ffd8edda | 58 | //! Construct an invalid private key. |
20e01b1a PW |
59 | CKey() : fValid(false), fCompressed(false) |
60 | { | |
dfa23b94 PW |
61 | LockObject(vch); |
62 | } | |
8bd66202 | 63 | |
ffd8edda | 64 | //! Copy constructor. This is necessary because of memlocking. |
20e01b1a PW |
65 | CKey(const CKey& secret) : fValid(secret.fValid), fCompressed(secret.fCompressed) |
66 | { | |
dfa23b94 PW |
67 | LockObject(vch); |
68 | memcpy(vch, secret.vch, sizeof(vch)); | |
69 | } | |
11529c6e | 70 | |
ffd8edda | 71 | //! Destructor (again necessary because of memlocking). |
20e01b1a PW |
72 | ~CKey() |
73 | { | |
dfa23b94 PW |
74 | UnlockObject(vch); |
75 | } | |
8bd66202 | 76 | |
20e01b1a PW |
77 | friend bool operator==(const CKey& a, const CKey& b) |
78 | { | |
a3996740 PK |
79 | return a.fCompressed == b.fCompressed && a.size() == b.size() && |
80 | memcmp(&a.vch[0], &b.vch[0], a.size()) == 0; | |
eb2c9990 PW |
81 | } |
82 | ||
ffd8edda | 83 | //! Initialize using begin and end iterators to byte data. |
20e01b1a PW |
84 | template <typename T> |
85 | void Set(const T pbegin, const T pend, bool fCompressedIn) | |
86 | { | |
dfa23b94 PW |
87 | if (pend - pbegin != 32) { |
88 | fValid = false; | |
89 | return; | |
90 | } | |
91 | if (Check(&pbegin[0])) { | |
92 | memcpy(vch, (unsigned char*)&pbegin[0], 32); | |
93 | fValid = true; | |
94 | fCompressed = fCompressedIn; | |
95 | } else { | |
96 | fValid = false; | |
97 | } | |
98 | } | |
99 | ||
ffd8edda | 100 | //! Simple read-only vector-like interface. |
dfa23b94 | 101 | unsigned int size() const { return (fValid ? 32 : 0); } |
20e01b1a PW |
102 | const unsigned char* begin() const { return vch; } |
103 | const unsigned char* end() const { return vch + size(); } | |
dfa23b94 | 104 | |
ffd8edda | 105 | //! Check whether this private key is valid. |
dfa23b94 | 106 | bool IsValid() const { return fValid; } |
8bd66202 | 107 | |
ffd8edda | 108 | //! Check whether the public key corresponding to this private key is (to be) compressed. |
dfa23b94 | 109 | bool IsCompressed() const { return fCompressed; } |
acd65016 | 110 | |
ffd8edda | 111 | //! Initialize from a CPrivKey (serialized OpenSSL private key data). |
20e01b1a | 112 | bool SetPrivKey(const CPrivKey& vchPrivKey, bool fCompressed); |
dfa23b94 | 113 | |
ffd8edda | 114 | //! Generate a new private key using a cryptographic PRNG. |
096e06db | 115 | void MakeNewKey(bool fCompressed); |
dfa23b94 | 116 | |
ffd8edda MF |
117 | /** |
118 | * Convert the private key to a CPrivKey (serialized OpenSSL private key data). | |
119 | * This is expensive. | |
120 | */ | |
096e06db | 121 | CPrivKey GetPrivKey() const; |
dfa23b94 | 122 | |
ffd8edda MF |
123 | /** |
124 | * Compute the public key from a private key. | |
125 | * This is expensive. | |
126 | */ | |
fd61d6f5 | 127 | CPubKey GetPubKey() const; |
acd65016 | 128 | |
a53fd414 PW |
129 | /** |
130 | * Create a DER-serialized signature. | |
437ada3e | 131 | * The test_case parameter tweaks the deterministic nonce. |
a53fd414 PW |
132 | */ |
133 | bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, uint32_t test_case = 0) const; | |
8bd66202 | 134 | |
ffd8edda MF |
135 | /** |
136 | * Create a compact signature (65 bytes), which allows reconstructing the used public key. | |
137 | * The format is one header byte, followed by two times 32 bytes for the serialized r and s values. | |
138 | * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, | |
139 | * 0x1D = second key with even y, 0x1E = second key with odd y, | |
140 | * add 0x04 for compressed keys. | |
141 | */ | |
20e01b1a | 142 | bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const; |
eb2c9990 | 143 | |
ffd8edda | 144 | //! Derive BIP32 child key. |
a5748996 | 145 | bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; |
a3996740 | 146 | |
d0c41a73 PW |
147 | /** |
148 | * Verify thoroughly whether a private key and a public key match. | |
149 | * This is done using a different mechanism than just regenerating it. | |
150 | */ | |
151 | bool VerifyPubKey(const CPubKey& vchPubKey) const; | |
152 | ||
ffd8edda | 153 | //! Load private key and check that public key matches. |
20e01b1a | 154 | bool Load(CPrivKey& privkey, CPubKey& vchPubKey, bool fSkipCheck); |
6fd7ef2b | 155 | |
ffd8edda | 156 | //! Check whether an element of a signature (r or s) is valid. |
20e01b1a | 157 | static bool CheckSignatureElement(const unsigned char* vch, int len, bool half); |
eb2c9990 PW |
158 | }; |
159 | ||
eb2c9990 PW |
160 | struct CExtKey { |
161 | unsigned char nDepth; | |
162 | unsigned char vchFingerprint[4]; | |
163 | unsigned int nChild; | |
a5748996 | 164 | ChainCode chaincode; |
eb2c9990 PW |
165 | CKey key; |
166 | ||
20e01b1a PW |
167 | friend bool operator==(const CExtKey& a, const CExtKey& b) |
168 | { | |
eb2c9990 | 169 | return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild && |
a5748996 | 170 | a.chaincode == b.chaincode && a.key == b.key; |
eb2c9990 PW |
171 | } |
172 | ||
6cbe2c48 JS |
173 | void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const; |
174 | void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]); | |
20e01b1a | 175 | bool Derive(CExtKey& out, unsigned int nChild) const; |
eb2c9990 | 176 | CExtPubKey Neuter() const; |
20e01b1a | 177 | void SetMaster(const unsigned char* seed, unsigned int nSeedLen); |
6cbe2c48 | 178 | template <typename Stream> |
242f1421 | 179 | void Serialize(Stream& s) const |
6cbe2c48 JS |
180 | { |
181 | unsigned int len = BIP32_EXTKEY_SIZE; | |
182 | ::WriteCompactSize(s, len); | |
183 | unsigned char code[BIP32_EXTKEY_SIZE]; | |
184 | Encode(code); | |
185 | s.write((const char *)&code[0], len); | |
186 | } | |
187 | template <typename Stream> | |
242f1421 | 188 | void Unserialize(Stream& s) |
6cbe2c48 JS |
189 | { |
190 | unsigned int len = ::ReadCompactSize(s); | |
191 | unsigned char code[BIP32_EXTKEY_SIZE]; | |
192 | s.read((char *)&code[0], len); | |
193 | Decode(code); | |
194 | } | |
8bd66202 | 195 | }; |
223b6f1b | 196 | |
a56054be PW |
197 | /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ |
198 | void ECC_Start(void); | |
199 | ||
200 | /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ | |
201 | void ECC_Stop(void); | |
202 | ||
203 | /** Check that required EC support is available at runtime. */ | |
4a09e1df AP |
204 | bool ECC_InitSanityCheck(void); |
205 | ||
093303a8 | 206 | #endif // BITCOIN_KEY_H |