]>
Commit | Line | Data |
---|---|---|
8bd66202 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
88216419 | 2 | // Copyright (c) 2009-2012 The Bitcoin developers |
8bd66202 | 3 | // Distributed under the MIT/X11 software license, see the accompanying |
3a25a2b9 | 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
223b6f1b WL |
5 | #ifndef BITCOIN_KEY_H |
6 | #define BITCOIN_KEY_H | |
8bd66202 | 7 | |
fcedd45c VN |
8 | #include <stdexcept> |
9 | #include <vector> | |
10 | ||
0a83c0fc | 11 | #include "allocators.h" |
fd61d6f5 | 12 | #include "serialize.h" |
fcedd45c | 13 | #include "uint256.h" |
0fb9073e | 14 | #include "hash.h" |
fcedd45c | 15 | |
096e06db GA |
16 | #include <openssl/ec.h> // for EC_KEY definition |
17 | ||
8bd66202 GA |
18 | // secp160k1 |
19 | // const unsigned int PRIVATE_KEY_SIZE = 192; | |
20 | // const unsigned int PUBLIC_KEY_SIZE = 41; | |
21 | // const unsigned int SIGNATURE_SIZE = 48; | |
22 | // | |
23 | // secp192k1 | |
24 | // const unsigned int PRIVATE_KEY_SIZE = 222; | |
25 | // const unsigned int PUBLIC_KEY_SIZE = 49; | |
26 | // const unsigned int SIGNATURE_SIZE = 57; | |
27 | // | |
28 | // secp224k1 | |
29 | // const unsigned int PRIVATE_KEY_SIZE = 250; | |
30 | // const unsigned int PUBLIC_KEY_SIZE = 57; | |
31 | // const unsigned int SIGNATURE_SIZE = 66; | |
32 | // | |
33 | // secp256k1: | |
34 | // const unsigned int PRIVATE_KEY_SIZE = 279; | |
35 | // const unsigned int PUBLIC_KEY_SIZE = 65; | |
36 | // const unsigned int SIGNATURE_SIZE = 72; | |
37 | // | |
38 | // see www.keylength.com | |
39 | // script supports up to 75 for single byte push | |
40 | ||
8bd66202 GA |
41 | class key_error : public std::runtime_error |
42 | { | |
43 | public: | |
44 | explicit key_error(const std::string& str) : std::runtime_error(str) {} | |
45 | }; | |
46 | ||
10254401 PW |
47 | /** A reference to a CKey: the Hash160 of its serialized public key */ |
48 | class CKeyID : public uint160 | |
49 | { | |
50 | public: | |
51 | CKeyID() : uint160(0) { } | |
52 | CKeyID(const uint160 &in) : uint160(in) { } | |
53 | }; | |
54 | ||
55 | /** A reference to a CScript: the Hash160 of its serialization (see script.h) */ | |
56 | class CScriptID : public uint160 | |
57 | { | |
58 | public: | |
59 | CScriptID() : uint160(0) { } | |
60 | CScriptID(const uint160 &in) : uint160(in) { } | |
61 | }; | |
62 | ||
63 | /** An encapsulated public key. */ | |
fd61d6f5 PW |
64 | class CPubKey { |
65 | private: | |
5d891489 PW |
66 | unsigned char vch[65]; |
67 | ||
68 | unsigned int static GetLen(unsigned char chHeader) { | |
69 | if (chHeader == 2 || chHeader == 3) | |
70 | return 33; | |
71 | if (chHeader == 4 || chHeader == 6 || chHeader == 7) | |
72 | return 65; | |
73 | return 0; | |
74 | } | |
75 | ||
76 | unsigned char *begin() { | |
77 | return vch; | |
78 | } | |
79 | ||
fd61d6f5 PW |
80 | friend class CKey; |
81 | ||
82 | public: | |
5d891489 PW |
83 | CPubKey() { vch[0] = 0xFF; } |
84 | ||
85 | CPubKey(const std::vector<unsigned char> &vchPubKeyIn) { | |
86 | int len = vchPubKeyIn.empty() ? 0 : GetLen(vchPubKeyIn[0]); | |
87 | if (len) { | |
88 | memcpy(vch, &vchPubKeyIn[0], len); | |
89 | } else { | |
90 | vch[0] = 0xFF; | |
91 | } | |
92 | } | |
93 | ||
94 | unsigned int size() const { | |
95 | return GetLen(vch[0]); | |
96 | } | |
97 | ||
98 | const unsigned char *begin() const { | |
99 | return vch; | |
100 | } | |
fd61d6f5 | 101 | |
5d891489 PW |
102 | const unsigned char *end() const { |
103 | return vch+size(); | |
104 | } | |
105 | ||
106 | friend bool operator==(const CPubKey &a, const CPubKey &b) { return memcmp(a.vch, b.vch, a.size()) == 0; } | |
107 | friend bool operator!=(const CPubKey &a, const CPubKey &b) { return memcmp(a.vch, b.vch, a.size()) != 0; } | |
108 | friend bool operator<(const CPubKey &a, const CPubKey &b) { | |
109 | return a.vch[0] < b.vch[0] || | |
110 | (a.vch[0] == b.vch[0] && memcmp(a.vch+1, b.vch+1, a.size() - 1) < 0); | |
111 | } | |
112 | ||
113 | unsigned int GetSerializeSize(int nType, int nVersion) const { | |
114 | return size() + 1; | |
115 | } | |
116 | ||
117 | template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const { | |
118 | unsigned int len = size(); | |
119 | ::Serialize(s, VARINT(len), nType, nVersion); | |
120 | s.write((char*)vch, len); | |
121 | } | |
122 | ||
123 | template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) { | |
124 | unsigned int len; | |
125 | ::Unserialize(s, VARINT(len), nType, nVersion); | |
126 | if (len <= 65) { | |
127 | s.read((char*)vch, len); | |
128 | } else { | |
129 | // invalid pubkey | |
130 | vch[0] = 0xFF; | |
131 | char dummy; | |
132 | while (len--) | |
133 | s.read(&dummy, 1); | |
134 | } | |
135 | } | |
fd61d6f5 | 136 | |
10254401 | 137 | CKeyID GetID() const { |
5d891489 | 138 | return CKeyID(Hash160(vch, vch+size())); |
fd61d6f5 PW |
139 | } |
140 | ||
141 | uint256 GetHash() const { | |
5d891489 | 142 | return Hash(vch, vch+size()); |
fd61d6f5 PW |
143 | } |
144 | ||
145 | bool IsValid() const { | |
5d891489 | 146 | return size() > 0; |
fd61d6f5 PW |
147 | } |
148 | ||
10254401 | 149 | bool IsCompressed() const { |
5d891489 | 150 | return size() == 33; |
10254401 PW |
151 | } |
152 | ||
fd61d6f5 | 153 | std::vector<unsigned char> Raw() const { |
5d891489 | 154 | return std::vector<unsigned char>(vch, vch+size()); |
fd61d6f5 PW |
155 | } |
156 | }; | |
157 | ||
8bd66202 | 158 | |
7fddf121 | 159 | // secure_allocator is defined in allocators.h |
d825e6a3 | 160 | // CPrivKey is a serialized private key, with all parameters included (279 bytes) |
223b6f1b | 161 | typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; |
d825e6a3 | 162 | // CSecret is a serialization of just the secret parameter (32 bytes) |
acd65016 | 163 | typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret; |
8bd66202 | 164 | |
6b8de05d | 165 | /** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */ |
8bd66202 GA |
166 | class CKey |
167 | { | |
168 | protected: | |
169 | EC_KEY* pkey; | |
170 | bool fSet; | |
11529c6e PW |
171 | bool fCompressedPubKey; |
172 | ||
8bd66202 | 173 | public: |
69fc8047 | 174 | void SetCompressedPubKey(bool fCompressed = true); |
11529c6e | 175 | |
096e06db | 176 | void Reset(); |
8bd66202 | 177 | |
096e06db GA |
178 | CKey(); |
179 | CKey(const CKey& b); | |
11529c6e | 180 | |
096e06db | 181 | CKey& operator=(const CKey& b); |
8bd66202 | 182 | |
096e06db | 183 | ~CKey(); |
8bd66202 | 184 | |
096e06db GA |
185 | bool IsNull() const; |
186 | bool IsCompressed() const; | |
acd65016 | 187 | |
096e06db GA |
188 | void MakeNewKey(bool fCompressed); |
189 | bool SetPrivKey(const CPrivKey& vchPrivKey); | |
190 | bool SetSecret(const CSecret& vchSecret, bool fCompressed = false); | |
191 | CSecret GetSecret(bool &fCompressed) const; | |
192 | CPrivKey GetPrivKey() const; | |
fd61d6f5 PW |
193 | bool SetPubKey(const CPubKey& vchPubKey); |
194 | CPubKey GetPubKey() const; | |
acd65016 | 195 | |
096e06db | 196 | bool Sign(uint256 hash, std::vector<unsigned char>& vchSig); |
8bd66202 | 197 | |
01cc5263 | 198 | // create a compact signature (65 bytes), which allows reconstructing the used public key |
d825e6a3 PW |
199 | // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. |
200 | // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, | |
201 | // 0x1D = second key with even y, 0x1E = second key with odd y | |
096e06db | 202 | bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig); |
01cc5263 PW |
203 | |
204 | // reconstruct public key from a compact signature | |
d825e6a3 PW |
205 | // This is only slightly more CPU intensive than just verifying it. |
206 | // If this function succeeds, the recovered public key is guaranteed to be valid | |
207 | // (the signature is a valid signature of the given data for that key) | |
096e06db | 208 | bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig); |
01cc5263 | 209 | |
096e06db | 210 | bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig); |
2ffba736 | 211 | |
d825e6a3 | 212 | // Verify a compact signature |
096e06db | 213 | bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig); |
91f43a33 | 214 | |
096e06db | 215 | bool IsValid(); |
8bd66202 | 216 | }; |
223b6f1b WL |
217 | |
218 | #endif |