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