Bitcoin ABC 0.30.7
P2P Digital Currency
pubkey.h
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Copyright (c) 2017 The Zcash developers
4// Distributed under the MIT software license, see the accompanying
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 <boost/range/adaptor/sliced.hpp>
15
16#include <stdexcept>
17#include <vector>
18
19const unsigned int BIP32_EXTKEY_SIZE = 74;
20
22class CKeyID : public uint160 {
23public:
24 CKeyID() : uint160() {}
25 explicit CKeyID(const uint160 &in) : uint160(in) {}
26};
27
29
31class CPubKey {
32public:
36 static constexpr unsigned int SIZE = 65;
37 static constexpr unsigned int COMPRESSED_SIZE = 33;
38 static constexpr unsigned int SCHNORR_SIZE = 64;
39 static constexpr unsigned int SIGNATURE_SIZE = 72;
40 static constexpr unsigned int COMPACT_SIGNATURE_SIZE = 65;
45 static_assert(SIZE >= COMPRESSED_SIZE,
46 "COMPRESSED_SIZE is larger than SIZE");
47
48private:
53 uint8_t vch[SIZE];
54
56 static unsigned int GetLen(uint8_t chHeader) {
57 if (chHeader == 2 || chHeader == 3) {
58 return COMPRESSED_SIZE;
59 }
60 if (chHeader == 4 || chHeader == 6 || chHeader == 7) {
61 return SIZE;
62 }
63 return 0;
64 }
65
67 void Invalidate() { vch[0] = 0xFF; }
68
69public:
70 bool static ValidSize(const std::vector<uint8_t> &vch) {
71 return vch.size() > 0 && GetLen(vch[0]) == vch.size();
72 }
73
76
78 template <typename T> void Set(const T pbegin, const T pend) {
79 int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
80 if (len && len == (pend - pbegin)) {
81 memcpy(vch, (uint8_t *)&pbegin[0], len);
82 } else {
83 Invalidate();
84 }
85 }
86
88 template <typename T> CPubKey(const T pbegin, const T pend) {
89 Set(pbegin, pend);
90 }
91
94 Set(_vch.begin(), _vch.end());
95 }
96
98 unsigned int size() const { return GetLen(vch[0]); }
99 const uint8_t *data() const { return vch; }
100 const uint8_t *begin() const { return vch; }
101 const uint8_t *end() const { return vch + size(); }
102 const uint8_t &operator[](unsigned int pos) const { return vch[pos]; }
103
105 friend bool operator==(const CPubKey &a, const CPubKey &b) {
106 return a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) == 0;
107 }
108 friend bool operator!=(const CPubKey &a, const CPubKey &b) {
109 return !(a == b);
110 }
111 friend bool operator<(const CPubKey &a, const CPubKey &b) {
112 return a.vch[0] < b.vch[0] ||
113 (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
114 }
115
117 template <typename Stream> void Serialize(Stream &s) const {
118 unsigned int len = size();
119 ::WriteCompactSize(s, len);
120 s.write(AsBytes(Span{vch, len}));
121 }
122 template <typename Stream> void Unserialize(Stream &s) {
123 const unsigned int len(::ReadCompactSize(s));
124 if (len <= SIZE) {
125 s.read(AsWritableBytes(Span{vch, len}));
126 if (len != size()) {
127 Invalidate();
128 }
129 } else {
130 // invalid pubkey, skip available data
131 s.ignore(len);
132 Invalidate();
133 }
134 }
135
137 CKeyID GetID() const { return CKeyID(Hash160(Span{vch}.first(size()))); }
138
140 uint256 GetHash() const { return Hash(Span{vch}.first(size())); }
141
142 /*
143 * Check syntactic correctness.
144 *
145 * Note that this is consensus critical as CheckSig() calls it!
146 */
147 bool IsValid() const { return size() > 0; }
148
151 bool IsFullyValid() const;
152
154 bool IsCompressed() const { return size() == COMPRESSED_SIZE; }
155
160 bool VerifyECDSA(const uint256 &hash,
161 const std::vector<uint8_t> &vchSig) const;
162
167 bool VerifySchnorr(const uint256 &hash,
168 const std::array<uint8_t, SCHNORR_SIZE> &sig) const;
169 bool VerifySchnorr(const uint256 &hash,
170 const std::vector<uint8_t> &vchSig) const;
171
175 static bool
176 CheckLowS(const boost::sliced_range<const std::vector<uint8_t>> &vchSig);
177 static bool CheckLowS(const std::vector<uint8_t> &vchSig) {
178 return CheckLowS(vchSig | boost::adaptors::sliced(0, vchSig.size()));
179 }
180
182 bool RecoverCompact(const uint256 &hash,
183 const std::vector<uint8_t> &vchSig);
184
186 bool Decompress();
187
189 bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild,
190 const ChainCode &cc) const;
191};
192
194 uint8_t nDepth;
195 uint8_t vchFingerprint[4];
196 unsigned int nChild;
199
200 friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) {
201 return a.nDepth == b.nDepth &&
202 memcmp(a.vchFingerprint, b.vchFingerprint,
203 sizeof(vchFingerprint)) == 0 &&
204 a.nChild == b.nChild && a.chaincode == b.chaincode &&
205 a.pubkey == b.pubkey;
206 }
207
208 friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b) {
209 return !(a == b);
210 }
211
212 void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const;
213 void Decode(const uint8_t code[BIP32_EXTKEY_SIZE]);
214 bool Derive(CExtPubKey &out, unsigned int nChild) const;
215
216 CExtPubKey() = default;
217};
218
224 static int refcount;
225
226public:
229};
230
231#endif // BITCOIN_PUBKEY_H
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:22
CKeyID()
Definition: pubkey.h:24
CKeyID(const uint160 &in)
Definition: pubkey.h:25
An encapsulated public key.
Definition: pubkey.h:31
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:154
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:137
static constexpr unsigned int SCHNORR_SIZE
Definition: pubkey.h:38
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:37
uint8_t vch[SIZE]
see www.keylength.com script supports up to 75 for single byte push
Definition: pubkey.h:53
bool VerifySchnorr(const uint256 &hash, const std::array< uint8_t, SCHNORR_SIZE > &sig) const
Verify a Schnorr signature (=64 bytes).
Definition: pubkey.cpp:199
const uint8_t * end() const
Definition: pubkey.h:101
static bool CheckLowS(const std::vector< uint8_t > &vchSig)
Definition: pubkey.h:177
CPubKey()
Construct an invalid public key.
Definition: pubkey.h:75
bool VerifyECDSA(const uint256 &hash, const std::vector< uint8_t > &vchSig) const
Verify a DER-serialized ECDSA signature (~72 bytes).
Definition: pubkey.cpp:172
bool IsValid() const
Definition: pubkey.h:147
bool Decompress()
Turn this public key into an uncompressed public key.
Definition: pubkey.cpp:267
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:36
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:256
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:98
friend bool operator==(const CPubKey &a, const CPubKey &b)
Comparator implementation.
Definition: pubkey.h:105
void Serialize(Stream &s) const
Implement serialization, as if this was a byte vector.
Definition: pubkey.h:117
static bool ValidSize(const std::vector< uint8_t > &vch)
Definition: pubkey.h:70
CPubKey(const T pbegin, const T pend)
Construct a public key using begin/end iterators to byte data.
Definition: pubkey.h:88
const uint8_t * data() const
Definition: pubkey.h:99
bool RecoverCompact(const uint256 &hash, const std::vector< uint8_t > &vchSig)
Recover a public key from a compact ECDSA signature.
Definition: pubkey.cpp:227
void Invalidate()
Set this key data to be invalid.
Definition: pubkey.h:67
CPubKey(Span< const uint8_t > _vch)
Construct a public key from a byte vector.
Definition: pubkey.h:93
void Unserialize(Stream &s)
Definition: pubkey.h:122
const uint8_t * begin() const
Definition: pubkey.h:100
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition: pubkey.h:140
static bool CheckLowS(const boost::sliced_range< const std::vector< uint8_t > > &vchSig)
Check whether a DER-serialized ECDSA signature is normalized (lower-S).
Definition: pubkey.cpp:341
bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child pubkey.
Definition: pubkey.cpp:286
const uint8_t & operator[](unsigned int pos) const
Definition: pubkey.h:102
static constexpr unsigned int SIGNATURE_SIZE
Definition: pubkey.h:39
static unsigned int GetLen(uint8_t chHeader)
Compute the length of a pubkey with a given first byte.
Definition: pubkey.h:56
static constexpr unsigned int COMPACT_SIGNATURE_SIZE
Definition: pubkey.h:40
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:78
friend bool operator!=(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:108
friend bool operator<(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:111
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:223
static int refcount
Definition: pubkey.h:224
constexpr C * begin() const noexcept
Definition: span.h:199
constexpr C * end() const noexcept
Definition: span.h:200
160-bit opaque blob.
Definition: uint256.h:117
256-bit opaque blob.
Definition: uint256.h:129
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:93
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:75
SchnorrSig sig
Definition: processor.cpp:498
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:19
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:413
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:1254
Span< std::byte > AsWritableBytes(Span< T > s) noexcept
Definition: span.h:297
Span< const std::byte > AsBytes(Span< T > s) noexcept
Definition: span.h:294
void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:313
friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:200
uint8_t nDepth
Definition: pubkey.h:194
ChainCode chaincode
Definition: pubkey.h:197
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:333
uint8_t vchFingerprint[4]
Definition: pubkey.h:195
void Decode(const uint8_t code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:325
friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:208
CPubKey pubkey
Definition: pubkey.h:198
unsigned int nChild
Definition: pubkey.h:196
CExtPubKey()=default