/ src / key.h
key.h
  1  // Copyright (c) 2009-2010 Satoshi Nakamoto
  2  // Copyright (c) 2009-2022 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_KEY_H
  8  #define BITCOIN_KEY_H
  9  
 10  #include <pubkey.h>
 11  #include <serialize.h>
 12  #include <support/allocators/secure.h>
 13  #include <uint256.h>
 14  
 15  #include <stdexcept>
 16  #include <vector>
 17  
 18  
 19  /**
 20   * CPrivKey is a serialized private key, with all parameters included
 21   * (SIZE bytes)
 22   */
 23  typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
 24  
 25  /** Size of ECDH shared secrets. */
 26  constexpr static size_t ECDH_SECRET_SIZE = CSHA256::OUTPUT_SIZE;
 27  
 28  // Used to represent ECDH shared secret (ECDH_SECRET_SIZE bytes)
 29  using ECDHSecret = std::array<std::byte, ECDH_SECRET_SIZE>;
 30  
 31  /** An encapsulated private key. */
 32  class CKey
 33  {
 34  public:
 35      /**
 36       * secp256k1:
 37       */
 38      static const unsigned int SIZE            = 279;
 39      static const unsigned int COMPRESSED_SIZE = 214;
 40      /**
 41       * see www.keylength.com
 42       * script supports up to 75 for single byte push
 43       */
 44      static_assert(
 45          SIZE >= COMPRESSED_SIZE,
 46          "COMPRESSED_SIZE is larger than SIZE");
 47  
 48  private:
 49      /** Internal data container for private key material. */
 50      using KeyType = std::array<unsigned char, 32>;
 51  
 52      //! Whether the public key corresponding to this private key is (to be) compressed.
 53      bool fCompressed{false};
 54  
 55      //! The actual byte data. nullptr for invalid keys.
 56      secure_unique_ptr<KeyType> keydata;
 57  
 58      //! Check whether the 32-byte array pointed to by vch is valid keydata.
 59      bool static Check(const unsigned char* vch);
 60  
 61      void MakeKeyData()
 62      {
 63          if (!keydata) keydata = make_secure_unique<KeyType>();
 64      }
 65  
 66      void ClearKeyData()
 67      {
 68          keydata.reset();
 69      }
 70  
 71  public:
 72      CKey() noexcept = default;
 73      CKey(CKey&&) noexcept = default;
 74      CKey& operator=(CKey&&) noexcept = default;
 75  
 76      CKey& operator=(const CKey& other)
 77      {
 78          if (other.keydata) {
 79              MakeKeyData();
 80              *keydata = *other.keydata;
 81          } else {
 82              ClearKeyData();
 83          }
 84          fCompressed = other.fCompressed;
 85          return *this;
 86      }
 87  
 88      CKey(const CKey& other) { *this = other; }
 89  
 90      friend bool operator==(const CKey& a, const CKey& b)
 91      {
 92          return a.fCompressed == b.fCompressed &&
 93              a.size() == b.size() &&
 94              memcmp(a.data(), b.data(), a.size()) == 0;
 95      }
 96  
 97      //! Initialize using begin and end iterators to byte data.
 98      template <typename T>
 99      void Set(const T pbegin, const T pend, bool fCompressedIn)
100      {
101          if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) {
102              ClearKeyData();
103          } else if (Check(UCharCast(&pbegin[0]))) {
104              MakeKeyData();
105              memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size());
106              fCompressed = fCompressedIn;
107          } else {
108              ClearKeyData();
109          }
110      }
111  
112      //! Simple read-only vector-like interface.
113      unsigned int size() const { return keydata ? keydata->size() : 0; }
114      const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; }
115      const std::byte* begin() const { return data(); }
116      const std::byte* end() const { return data() + size(); }
117  
118      //! Check whether this private key is valid.
119      bool IsValid() const { return !!keydata; }
120  
121      //! Check whether the public key corresponding to this private key is (to be) compressed.
122      bool IsCompressed() const { return fCompressed; }
123  
124      //! Generate a new private key using a cryptographic PRNG.
125      void MakeNewKey(bool fCompressed);
126  
127      //! Negate private key
128      bool Negate();
129  
130      /**
131       * Convert the private key to a CPrivKey (serialized OpenSSL private key data).
132       * This is expensive.
133       */
134      CPrivKey GetPrivKey() const;
135  
136      /**
137       * Compute the public key from a private key.
138       * This is expensive.
139       */
140      CPubKey GetPubKey() const;
141  
142      /**
143       * Create a DER-serialized signature.
144       * The test_case parameter tweaks the deterministic nonce.
145       */
146      bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const;
147  
148      /**
149       * Create a compact signature (65 bytes), which allows reconstructing the used public key.
150       * The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
151       * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
152       *                  0x1D = second key with even y, 0x1E = second key with odd y,
153       *                  add 0x04 for compressed keys.
154       */
155      bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
156  
157      /**
158       * Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this,
159       * optionally tweaked by *merkle_root. Additional nonce entropy is provided through
160       * aux.
161       *
162       * merkle_root is used to optionally perform tweaking of the private key, as specified
163       * in BIP341:
164       * - If merkle_root == nullptr: no tweaking is done, sign with key directly (this is
165       *                              used for signatures in BIP342 script).
166       * - If merkle_root->IsNull():  sign with key + H_TapTweak(pubkey) (this is used for
167       *                              key path spending when no scripts are present).
168       * - Otherwise:                 sign with key + H_TapTweak(pubkey || *merkle_root)
169       *                              (this is used for key path spending, with specific
170       *                              Merkle root of the script tree).
171       */
172      bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const;
173  
174      //! Derive BIP32 child key.
175      [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
176  
177      /**
178       * Verify thoroughly whether a private key and a public key match.
179       * This is done using a different mechanism than just regenerating it.
180       */
181      bool VerifyPubKey(const CPubKey& vchPubKey) const;
182  
183      //! Load private key and check that public key matches.
184      bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck);
185  
186      /** Create an ellswift-encoded public key for this key, with specified entropy.
187       *
188       *  entropy must be a 32-byte span with additional entropy to use in the encoding. Every
189       *  public key has ~2^256 different encodings, and this function will deterministically pick
190       *  one of them, based on entropy. Note that even without truly random entropy, the
191       *  resulting encoding will be indistinguishable from uniform to any adversary who does not
192       *  know the private key (because the private key itself is always used as entropy as well).
193       */
194      EllSwiftPubKey EllSwiftCreate(Span<const std::byte> entropy) const;
195  
196      /** Compute a BIP324-style ECDH shared secret.
197       *
198       *  - their_ellswift: EllSwiftPubKey that was received from the other side.
199       *  - our_ellswift: EllSwiftPubKey that was sent to the other side (must have been generated
200       *                  from *this using EllSwiftCreate()).
201       *  - initiating: whether we are the initiating party (true) or responding party (false).
202       */
203      ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift,
204                                         const EllSwiftPubKey& our_ellswift,
205                                         bool initiating) const;
206  };
207  
208  CKey GenerateRandomKey(bool compressed = true) noexcept;
209  
210  struct CExtKey {
211      unsigned char nDepth;
212      unsigned char vchFingerprint[4];
213      unsigned int nChild;
214      ChainCode chaincode;
215      CKey key;
216  
217      friend bool operator==(const CExtKey& a, const CExtKey& b)
218      {
219          return a.nDepth == b.nDepth &&
220              memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
221              a.nChild == b.nChild &&
222              a.chaincode == b.chaincode &&
223              a.key == b.key;
224      }
225  
226      void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
227      void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
228      [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
229      CExtPubKey Neuter() const;
230      void SetSeed(Span<const std::byte> seed);
231  };
232  
233  /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */
234  void ECC_Start();
235  
236  /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */
237  void ECC_Stop();
238  
239  /** Check that required EC support is available at runtime. */
240  bool ECC_InitSanityCheck();
241  
242  #endif // BITCOIN_KEY_H