Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #ifndef BITCOIN_KEY_H
7 : #define BITCOIN_KEY_H
8 :
9 : #include "pubkey.h"
10 : #include "serialize.h"
11 : #include "support/allocators/secure.h"
12 : #include "uint256.h"
13 :
14 : #include <stdexcept>
15 : #include <vector>
16 :
17 :
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 : */
27 :
28 : /**
29 : * secure_allocator is defined in allocators.h
30 : * CPrivKey is a serialized private key, with all parameters included (279 bytes)
31 : */
32 : typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
33 :
34 : /** An encapsulated private key. */
35 : class CKey
36 : {
37 : private:
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.
40 : bool fValid;
41 :
42 : //! Whether the public key corresponding to this private key is (to be) compressed.
43 : bool fCompressed;
44 :
45 : //! The actual byte data
46 : unsigned char vch[32];
47 :
48 : //! Check whether the 32-byte array pointed to be vch is valid keydata.
49 : bool static Check(const unsigned char* vch);
50 :
51 : public:
52 : //! Construct an invalid private key.
53 9702 : CKey() : fValid(false), fCompressed(false)
54 : {
55 9702 : LockObject(vch);
56 0 : }
57 :
58 : //! Copy constructor. This is necessary because of memlocking.
59 8090 : CKey(const CKey& secret) : fValid(secret.fValid), fCompressed(secret.fCompressed)
60 : {
61 8090 : LockObject(vch);
62 8090 : memcpy(vch, secret.vch, sizeof(vch));
63 8090 : }
64 :
65 : //! Destructor (again necessary because of memlocking).
66 0 : ~CKey()
67 : {
68 17792 : UnlockObject(vch);
69 17792 : }
70 :
71 12 : friend bool operator==(const CKey& a, const CKey& b)
72 : {
73 48 : return a.fCompressed == b.fCompressed && a.size() == b.size() &&
74 36 : memcmp(&a.vch[0], &b.vch[0], a.size()) == 0;
75 : }
76 :
77 : //! Initialize using begin and end iterators to byte data.
78 : template <typename T>
79 608 : void Set(const T pbegin, const T pend, bool fCompressedIn)
80 : {
81 608 : if (pend - pbegin != 32) {
82 0 : fValid = false;
83 608 : return;
84 : }
85 608 : if (Check(&pbegin[0])) {
86 608 : memcpy(vch, (unsigned char*)&pbegin[0], 32);
87 608 : fValid = true;
88 608 : fCompressed = fCompressedIn;
89 : } else {
90 0 : fValid = false;
91 : }
92 : }
93 :
94 : //! Simple read-only vector-like interface.
95 538 : unsigned int size() const { return (fValid ? 32 : 0); }
96 10456 : const unsigned char* begin() const { return vch; }
97 186 : const unsigned char* end() const { return vch + size(); }
98 :
99 : //! Check whether this private key is valid.
100 0 : bool IsValid() const { return fValid; }
101 :
102 : //! Check whether the public key corresponding to this private key is (to be) compressed.
103 0 : bool IsCompressed() const { return fCompressed; }
104 :
105 : //! Initialize from a CPrivKey (serialized OpenSSL private key data).
106 : bool SetPrivKey(const CPrivKey& vchPrivKey, bool fCompressed);
107 :
108 : //! Generate a new private key using a cryptographic PRNG.
109 : void MakeNewKey(bool fCompressed);
110 :
111 : /**
112 : * Convert the private key to a CPrivKey (serialized OpenSSL private key data).
113 : * This is expensive.
114 : */
115 : CPrivKey GetPrivKey() const;
116 :
117 : /**
118 : * Compute the public key from a private key.
119 : * This is expensive.
120 : */
121 : CPubKey GetPubKey() const;
122 :
123 : /**
124 : * Create a DER-serialized signature.
125 : * The test_case parameter tweaks the deterministic nonce.
126 : */
127 : bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, uint32_t test_case = 0) const;
128 :
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 : */
136 : bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
137 :
138 : //! Derive BIP32 child key.
139 : bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
140 :
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 :
147 : //! Load private key and check that public key matches.
148 : bool Load(CPrivKey& privkey, CPubKey& vchPubKey, bool fSkipCheck);
149 :
150 : //! Check whether an element of a signature (r or s) is valid.
151 : static bool CheckSignatureElement(const unsigned char* vch, int len, bool half);
152 : };
153 :
154 130 : struct CExtKey {
155 : unsigned char nDepth;
156 : unsigned char vchFingerprint[4];
157 : unsigned int nChild;
158 : ChainCode chaincode;
159 : CKey key;
160 :
161 12 : friend bool operator==(const CExtKey& a, const CExtKey& b)
162 : {
163 36 : return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
164 36 : a.chaincode == b.chaincode && a.key == b.key;
165 : }
166 :
167 : void Encode(unsigned char code[74]) const;
168 : void Decode(const unsigned char code[74]);
169 : bool Derive(CExtKey& out, unsigned int nChild) const;
170 : CExtPubKey Neuter() const;
171 : void SetMaster(const unsigned char* seed, unsigned int nSeedLen);
172 : };
173 :
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. */
181 : bool ECC_InitSanityCheck(void);
182 :
183 : #endif // BITCOIN_KEY_H
|