You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pubkey.h 6.8KB

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