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