Bitcoin ABC  0.24.10
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 
19 const unsigned int BIP32_EXTKEY_SIZE = 74;
20 
22 class CKeyID : public uint160 {
23 public:
24  CKeyID() : uint160() {}
25  explicit CKeyID(const uint160 &in) : uint160(in) {}
26 };
27 
29 
31 class CPubKey {
32 public:
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 
48 private:
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 
69 public:
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 
93  explicit CPubKey(const std::vector<uint8_t> &_vch) {
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((char *)vch, len);
121  }
122  template <typename Stream> void Unserialize(Stream &s) {
123  unsigned int len = ::ReadCompactSize(s);
124  if (len <= SIZE) {
125  s.read((char *)vch, len);
126  if (len != size()) {
127  Invalidate();
128  }
129  } else {
130  // invalid pubkey, skip available data
131  char dummy;
132  while (len--) {
133  s.read(&dummy, 1);
134  }
135  Invalidate();
136  }
137  }
138 
140  CKeyID GetID() const {
141  return CKeyID(Hash160(MakeSpan(vch).first(size())));
142  }
143 
145  uint256 GetHash() const { return Hash(MakeSpan(vch).first(size())); }
146 
147  /*
148  * Check syntactic correctness.
149  *
150  * Note that this is consensus critical as CheckSig() calls it!
151  */
152  bool IsValid() const { return size() > 0; }
153 
156  bool IsFullyValid() const;
157 
159  bool IsCompressed() const { return size() == COMPRESSED_SIZE; }
160 
165  bool VerifyECDSA(const uint256 &hash,
166  const std::vector<uint8_t> &vchSig) const;
167 
172  bool VerifySchnorr(const uint256 &hash,
173  const std::array<uint8_t, SCHNORR_SIZE> &sig) const;
174  bool VerifySchnorr(const uint256 &hash,
175  const std::vector<uint8_t> &vchSig) const;
176 
180  static bool
181  CheckLowS(const boost::sliced_range<const std::vector<uint8_t>> &vchSig);
182  static bool CheckLowS(const std::vector<uint8_t> &vchSig) {
183  return CheckLowS(vchSig | boost::adaptors::sliced(0, vchSig.size()));
184  }
185 
187  bool RecoverCompact(const uint256 &hash,
188  const std::vector<uint8_t> &vchSig);
189 
191  bool Decompress();
192 
194  bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild,
195  const ChainCode &cc) const;
196 };
197 
198 struct CExtPubKey {
199  uint8_t nDepth;
200  uint8_t vchFingerprint[4];
201  unsigned int nChild;
204 
205  friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) {
206  return a.nDepth == b.nDepth &&
207  memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0],
208  sizeof(vchFingerprint)) == 0 &&
209  a.nChild == b.nChild && a.chaincode == b.chaincode &&
210  a.pubkey == b.pubkey;
211  }
212 
213  friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b) {
214  return !(a == b);
215  }
216 
217  void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const;
218  void Decode(const uint8_t code[BIP32_EXTKEY_SIZE]);
219  bool Derive(CExtPubKey &out, unsigned int nChild) const;
220 
221  CExtPubKey() = default;
222 };
223 
229  static int refcount;
230 
231 public:
232  ECCVerifyHandle();
234 };
235 
236 #endif // BITCOIN_PUBKEY_H
BIP32_EXTKEY_SIZE
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:19
CPubKey::SIGNATURE_SIZE
static constexpr unsigned int SIGNATURE_SIZE
Definition: pubkey.h:39
CExtPubKey::CExtPubKey
CExtPubKey()=default
CPubKey::GetLen
static unsigned int GetLen(uint8_t chHeader)
Compute the length of a pubkey with a given first byte.
Definition: pubkey.h:56
CKeyID::CKeyID
CKeyID()
Definition: pubkey.h:24
CPubKey::end
const uint8_t * end() const
Definition: pubkey.h:101
CPubKey::CPubKey
CPubKey(const std::vector< uint8_t > &_vch)
Construct a public key from a byte vector.
Definition: pubkey.h:93
CPubKey::VerifySchnorr
bool VerifySchnorr(const uint256 &hash, const std::array< uint8_t, SCHNORR_SIZE > &sig) const
Verify a Schnorr signature (=64 bytes).
Definition: pubkey.cpp:200
CPubKey::Invalidate
void Invalidate()
Set this key data to be invalid.
Definition: pubkey.h:67
CPubKey::SIZE
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:36
uint256.h
CPubKey::Set
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:78
CExtPubKey::nDepth
uint8_t nDepth
Definition: pubkey.h:199
CPubKey::SCHNORR_SIZE
static constexpr unsigned int SCHNORR_SIZE
Definition: pubkey.h:38
CPubKey::Derive
bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child pubkey.
Definition: pubkey.cpp:287
ECCVerifyHandle::ECCVerifyHandle
ECCVerifyHandle()
Definition: pubkey.cpp:357
CPubKey::Decompress
bool Decompress()
Turn this public key into an uncompressed public key.
Definition: pubkey.cpp:268
CKeyID
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:22
CExtPubKey::operator!=
friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:213
ReadCompactSize
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:430
ECCVerifyHandle::refcount
static int refcount
Definition: pubkey.h:229
CExtPubKey::Derive
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:334
ECCVerifyHandle::~ECCVerifyHandle
~ECCVerifyHandle()
Definition: pubkey.cpp:367
CExtPubKey::Encode
void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:314
CExtPubKey::nChild
unsigned int nChild
Definition: pubkey.h:201
CPubKey::begin
const uint8_t * begin() const
Definition: pubkey.h:100
sig
SchnorrSig sig
Definition: processor.cpp:322
Hash
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:74
CExtPubKey::operator==
friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
Definition: pubkey.h:205
CPubKey::VerifyECDSA
bool VerifyECDSA(const uint256 &hash, const std::vector< uint8_t > &vchSig) const
Verify a DER-serialized ECDSA signature (~72 bytes).
Definition: pubkey.cpp:173
CPubKey::vch
uint8_t vch[SIZE]
see www.keylength.com script supports up to 75 for single byte push
Definition: pubkey.h:46
WriteCompactSize
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:1178
CPubKey::GetHash
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition: pubkey.h:145
CPubKey::Unserialize
void Unserialize(Stream &s)
Definition: pubkey.h:122
CPubKey::Serialize
void Serialize(Stream &s) const
Implement serialization, as if this was a byte vector.
Definition: pubkey.h:117
CPubKey::CPubKey
CPubKey()
Construct an invalid public key.
Definition: pubkey.h:75
CPubKey::CheckLowS
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:342
CPubKey::size
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:98
CPubKey::COMPRESSED_SIZE
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:37
uint256
256-bit opaque blob.
Definition: uint256.h:127
CPubKey::IsCompressed
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:159
CPubKey::operator==
friend bool operator==(const CPubKey &a, const CPubKey &b)
Comparator implementation.
Definition: pubkey.h:105
CPubKey::CheckLowS
static bool CheckLowS(const std::vector< uint8_t > &vchSig)
Definition: pubkey.h:182
uint160
160-bit opaque blob.
Definition: uint256.h:115
CPubKey
An encapsulated public key.
Definition: pubkey.h:31
ECCVerifyHandle
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:228
CPubKey::data
const uint8_t * data() const
Definition: pubkey.h:99
CExtPubKey::chaincode
ChainCode chaincode
Definition: pubkey.h:202
Hash160
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
CPubKey::COMPACT_SIGNATURE_SIZE
static constexpr unsigned int COMPACT_SIGNATURE_SIZE
Definition: pubkey.h:40
CPubKey::operator<
friend bool operator<(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:111
CExtPubKey::vchFingerprint
uint8_t vchFingerprint[4]
Definition: pubkey.h:200
CPubKey::IsFullyValid
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:257
CPubKey::CPubKey
CPubKey(const T pbegin, const T pend)
Construct a public key using begin/end iterators to byte data.
Definition: pubkey.h:88
hash.h
serialize.h
CPubKey::RecoverCompact
bool RecoverCompact(const uint256 &hash, const std::vector< uint8_t > &vchSig)
Recover a public key from a compact ECDSA signature.
Definition: pubkey.cpp:228
CKeyID::CKeyID
CKeyID(const uint160 &in)
Definition: pubkey.h:25
CPubKey::IsValid
bool IsValid() const
Definition: pubkey.h:152
CPubKey::ValidSize
static bool ValidSize(const std::vector< uint8_t > &vch)
Definition: pubkey.h:70
CExtPubKey::pubkey
CPubKey pubkey
Definition: pubkey.h:203
CPubKey::operator[]
const uint8_t & operator[](unsigned int pos) const
Definition: pubkey.h:102
MakeSpan
constexpr Span< A > MakeSpan(A(&a)[N])
MakeSpan for arrays:
Definition: span.h:229
CExtPubKey
Definition: pubkey.h:198
CPubKey::GetID
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:140
CExtPubKey::Decode
void Decode(const uint8_t code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:326
CPubKey::operator!=
friend bool operator!=(const CPubKey &a, const CPubKey &b)
Definition: pubkey.h:108