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