]> Git Repo - VerusCoin.git/blame - src/pubkey.h
Scope the ECDSA constant sizes to CPubKey / CKey classes
[VerusCoin.git] / src / pubkey.h
CommitLineData
d2e74c55 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
b4347f60 4// Distributed under the MIT software license, see the accompanying
d2e74c55
CF
5// file COPYING or http://www.opensource.org/licenses/mit-license.php.
6
7#ifndef BITCOIN_PUBKEY_H
8#define BITCOIN_PUBKEY_H
9
10#include "hash.h"
11#include "serialize.h"
12#include "uint256.h"
13
14#include <stdexcept>
15#include <vector>
16
d2e74c55
CF
17/** A reference to a CKey: the Hash160 of its serialized public key */
18class CKeyID : public uint160
19{
20public:
4f152496 21 CKeyID() : uint160() {}
d2e74c55
CF
22 CKeyID(const uint160& in) : uint160(in) {}
23};
24
a5748996 25typedef uint256 ChainCode;
8cf1485f 26
d2e74c55
CF
27/** An encapsulated public key. */
28class CPubKey
29{
c4c7c663
JG
30public:
31 /**
32 * secp256k1:
33 */
34 static const unsigned int PUBLIC_KEY_SIZE = 65;
35 static const unsigned int COMPRESSED_PUBLIC_KEY_SIZE = 33;
36 static const unsigned int SIGNATURE_SIZE = 72;
37 static const unsigned int COMPACT_SIGNATURE_SIZE = 65;
38 /**
39 * see www.keylength.com
40 * script supports up to 75 for single byte push
41 */
42 static_assert(
43 PUBLIC_KEY_SIZE >= COMPRESSED_PUBLIC_KEY_SIZE,
44 "COMPRESSED_PUBLIC_KEY_SIZE is larger than PUBLIC_KEY_SIZE");
45
d2e74c55
CF
46private:
47
48 /**
49 * Just store the serialized data.
50 * Its length can very cheaply be computed from the first byte.
51 */
877964c8 52 unsigned char vch[PUBLIC_KEY_SIZE];
d2e74c55
CF
53
54 //! Compute the length of a pubkey with a given first byte.
55 unsigned int static GetLen(unsigned char chHeader)
56 {
57 if (chHeader == 2 || chHeader == 3)
877964c8 58 return COMPRESSED_PUBLIC_KEY_SIZE;
d2e74c55 59 if (chHeader == 4 || chHeader == 6 || chHeader == 7)
877964c8 60 return PUBLIC_KEY_SIZE;
d2e74c55
CF
61 return 0;
62 }
63
64 //! Set this key data to be invalid
65 void Invalidate()
66 {
67 vch[0] = 0xFF;
68 }
69
70public:
71 //! Construct an invalid public key.
72 CPubKey()
73 {
74 Invalidate();
75 }
76
77 //! Initialize a public key using begin/end iterators to byte data.
78 template <typename T>
79 void Set(const T pbegin, const T pend)
80 {
81 int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
82 if (len && len == (pend - pbegin))
83 memcpy(vch, (unsigned char*)&pbegin[0], len);
84 else
85 Invalidate();
86 }
87
88 //! Construct a public key using begin/end iterators to byte data.
89 template <typename T>
90 CPubKey(const T pbegin, const T pend)
91 {
92 Set(pbegin, pend);
93 }
94
95 //! Construct a public key from a byte vector.
96 CPubKey(const std::vector<unsigned char>& vch)
97 {
98 Set(vch.begin(), vch.end());
99 }
100
101 //! Simple read-only vector-like interface to the pubkey data.
102 unsigned int size() const { return GetLen(vch[0]); }
103 const unsigned char* begin() const { return vch; }
104 const unsigned char* end() const { return vch + size(); }
105 const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
106
107 //! Comparator implementation.
108 friend bool operator==(const CPubKey& a, const CPubKey& b)
109 {
110 return a.vch[0] == b.vch[0] &&
111 memcmp(a.vch, b.vch, a.size()) == 0;
112 }
113 friend bool operator!=(const CPubKey& a, const CPubKey& b)
114 {
115 return !(a == b);
116 }
117 friend bool operator<(const CPubKey& a, const CPubKey& b)
118 {
119 return a.vch[0] < b.vch[0] ||
120 (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
121 }
122
123 //! Implement serialization, as if this was a byte vector.
124 unsigned int GetSerializeSize(int nType, int nVersion) const
125 {
126 return size() + 1;
127 }
128 template <typename Stream>
129 void Serialize(Stream& s, int nType, int nVersion) const
130 {
131 unsigned int len = size();
132 ::WriteCompactSize(s, len);
133 s.write((char*)vch, len);
134 }
135 template <typename Stream>
136 void Unserialize(Stream& s, int nType, int nVersion)
137 {
138 unsigned int len = ::ReadCompactSize(s);
877964c8 139 if (len <= PUBLIC_KEY_SIZE) {
d2e74c55
CF
140 s.read((char*)vch, len);
141 } else {
142 // invalid pubkey, skip available data
143 char dummy;
144 while (len--)
145 s.read(&dummy, 1);
146 Invalidate();
147 }
148 }
149
150 //! Get the KeyID of this public key (hash of its serialization)
151 CKeyID GetID() const
152 {
153 return CKeyID(Hash160(vch, vch + size()));
154 }
155
156 //! Get the 256-bit hash of this public key.
157 uint256 GetHash() const
158 {
159 return Hash(vch, vch + size());
160 }
161
162 /*
163 * Check syntactic correctness.
164 *
165 * Note that this is consensus critical as CheckSig() calls it!
166 */
167 bool IsValid() const
168 {
169 return size() > 0;
170 }
171
172 //! fully validate whether this is a valid public key (more expensive than IsValid())
173 bool IsFullyValid() const;
174
175 //! Check whether this is a compressed public key.
176 bool IsCompressed() const
177 {
877964c8 178 return size() == COMPRESSED_PUBLIC_KEY_SIZE;
d2e74c55
CF
179 }
180
181 /**
182 * Verify a DER signature (~72 bytes).
183 * If this public key is not fully valid, the return value will be false.
184 */
185 bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
186
3d02d0f6
PW
187 /**
188 * Check whether a signature is normalized (lower-S).
189 */
190 static bool CheckLowS(const std::vector<unsigned char>& vchSig);
191
d2e74c55
CF
192 //! Recover a public key from a compact signature.
193 bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
194
195 //! Turn this public key into an uncompressed public key.
196 bool Decompress();
197
198 //! Derive BIP32 child pubkey.
a5748996 199 bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
d2e74c55
CF
200};
201
202struct CExtPubKey {
203 unsigned char nDepth;
204 unsigned char vchFingerprint[4];
205 unsigned int nChild;
a5748996 206 ChainCode chaincode;
d2e74c55
CF
207 CPubKey pubkey;
208
8cf1485f 209 friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
d2e74c55
CF
210 {
211 return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
a5748996 212 a.chaincode == b.chaincode && a.pubkey == b.pubkey;
d2e74c55
CF
213 }
214
215 void Encode(unsigned char code[74]) const;
216 void Decode(const unsigned char code[74]);
217 bool Derive(CExtPubKey& out, unsigned int nChild) const;
218};
219
3d02d0f6
PW
220/** Users of this module must hold an ECCVerifyHandle. The constructor and
221 * destructor of these are not allowed to run in parallel, though. */
222class ECCVerifyHandle
223{
224 static int refcount;
225
226public:
227 ECCVerifyHandle();
228 ~ECCVerifyHandle();
229};
230
d2e74c55 231#endif // BITCOIN_PUBKEY_H
This page took 0.139588 seconds and 4 git commands to generate.