key.h raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-2022 The Limenka 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 LIMENKA_KEY_H
   8  #define LIMENKA_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  class KeyPair;
  32  
  33  /** An encapsulated private key. */
  34  class CKey
  35  {
  36  public:
  37      /**
  38       * secp256k1:
  39       */
  40      static const unsigned int SIZE            = 279;
  41      static const unsigned int COMPRESSED_SIZE = 214;
  42      /**
  43       * see www.keylength.com
  44       * script supports up to 75 for single byte push
  45       */
  46      static_assert(
  47          SIZE >= COMPRESSED_SIZE,
  48          "COMPRESSED_SIZE is larger than SIZE");
  49  
  50  private:
  51      /** Internal data container for private key material. */
  52      using KeyType = std::array<unsigned char, 32>;
  53  
  54      //! Whether the public key corresponding to this private key is (to be) compressed.
  55      bool fCompressed{false};
  56  
  57      //! The actual byte data. nullptr for invalid keys.
  58      secure_unique_ptr<KeyType> keydata;
  59  
  60      //! Check whether the 32-byte array pointed to by vch is valid keydata.
  61      bool static Check(const unsigned char* vch);
  62  
  63      void MakeKeyData()
  64      {
  65          if (!keydata) keydata = make_secure_unique<KeyType>();
  66      }
  67  
  68      void ClearKeyData()
  69      {
  70          keydata.reset();
  71      }
  72  
  73  public:
  74      CKey() noexcept = default;
  75      CKey(CKey&&) noexcept = default;
  76      CKey& operator=(CKey&&) noexcept = default;
  77  
  78      CKey& operator=(const CKey& other)
  79      {
  80          if (this != &other) {
  81              if (other.keydata) {
  82                  MakeKeyData();
  83                  *keydata = *other.keydata;
  84              } else {
  85                  ClearKeyData();
  86              }
  87              fCompressed = other.fCompressed;
  88          }
  89          return *this;
  90      }
  91  
  92      CKey(const CKey& other) { *this = other; }
  93  
  94      friend bool operator==(const CKey& a, const CKey& b)
  95      {
  96          return a.fCompressed == b.fCompressed &&
  97              a.size() == b.size() &&
  98              [&]() {
  99                  std::byte accumulator{};
 100                  auto ait = a.begin();
 101                  auto bit = b.begin();
 102                  for (; ait != a.end(); ++ait, ++bit) {
 103                      accumulator |= (*ait ^ *bit);
 104                  }
 105                  return accumulator == std::byte{};
 106              }();
 107      }
 108  
 109      //! Initialize using begin and end iterators to byte data.
 110      template <typename T>
 111      void Set(const T pbegin, const T pend, bool fCompressedIn)
 112      {
 113          if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) {
 114              ClearKeyData();
 115          } else if (Check(UCharCast(&pbegin[0]))) {
 116              MakeKeyData();
 117              memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size());
 118              fCompressed = fCompressedIn;
 119          } else {
 120              ClearKeyData();
 121          }
 122      }
 123  
 124      //! Simple read-only vector-like interface.
 125      unsigned int size() const { return keydata ? keydata->size() : 0; }
 126      const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; }
 127      const std::byte* begin() const { return data(); }
 128      const std::byte* end() const { return data() + size(); }
 129  
 130      //! Check whether this private key is valid.
 131      bool IsValid() const { return !!keydata; }
 132  
 133      //! Check whether the public key corresponding to this private key is (to be) compressed.
 134      bool IsCompressed() const { return fCompressed; }
 135  
 136      //! Generate a new private key using a cryptographic PRNG.
 137      void MakeNewKey(bool fCompressed);
 138  
 139      /**
 140       * Convert the private key to a CPrivKey (serialized OpenSSL private key data).
 141       * This is expensive.
 142       */
 143      CPrivKey GetPrivKey() const;
 144  
 145      /**
 146       * Compute the public key from a private key.
 147       * This is expensive.
 148       */
 149      CPubKey GetPubKey() const;
 150  
 151      /**
 152       * Create a DER-serialized signature.
 153       * The test_case parameter tweaks the deterministic nonce.
 154       */
 155      bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const;
 156  
 157      /**
 158       * Create a compact signature (65 bytes), which allows reconstructing the used public key.
 159       * The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
 160       * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
 161       *                  0x1D = second key with even y, 0x1E = second key with odd y,
 162       *                  add 0x04 for compressed keys.
 163       */
 164      bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
 165  
 166      /**
 167       * Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this,
 168       * optionally tweaked by *merkle_root. Additional nonce entropy is provided through
 169       * aux.
 170       *
 171       * merkle_root is used to optionally perform tweaking of the private key, as specified
 172       * in BIP341:
 173       * - If merkle_root == nullptr: no tweaking is done, sign with key directly (this is
 174       *                              used for signatures in BIP342 script).
 175       * - If merkle_root->IsNull():  sign with key + H_TapTweak(pubkey) (this is used for
 176       *                              key path spending when no scripts are present).
 177       * - Otherwise:                 sign with key + H_TapTweak(pubkey || *merkle_root)
 178       *                              (this is used for key path spending, with specific
 179       *                              Merkle root of the script tree).
 180       */
 181      bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const;
 182  
 183      //! Derive BIP32 child key.
 184      [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
 185  
 186      /**
 187       * Verify thoroughly whether a private key and a public key match.
 188       * This is done using a different mechanism than just regenerating it.
 189       */
 190      bool VerifyPubKey(const CPubKey& vchPubKey) const;
 191  
 192      //! Load private key and check that public key matches.
 193      bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck);
 194  
 195      /** Create an ellswift-encoded public key for this key, with specified entropy.
 196       *
 197       *  entropy must be a 32-byte span with additional entropy to use in the encoding. Every
 198       *  public key has ~2^256 different encodings, and this function will deterministically pick
 199       *  one of them, based on entropy. Note that even without truly random entropy, the
 200       *  resulting encoding will be indistinguishable from uniform to any adversary who does not
 201       *  know the private key (because the private key itself is always used as entropy as well).
 202       */
 203      EllSwiftPubKey EllSwiftCreate(Span<const std::byte> entropy) const;
 204  
 205      /** Compute a BIP324-style ECDH shared secret.
 206       *
 207       *  - their_ellswift: EllSwiftPubKey that was received from the other side.
 208       *  - our_ellswift: EllSwiftPubKey that was sent to the other side (must have been generated
 209       *                  from *this using EllSwiftCreate()).
 210       *  - initiating: whether we are the initiating party (true) or responding party (false).
 211       */
 212      ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift,
 213                                         const EllSwiftPubKey& our_ellswift,
 214                                         bool initiating) const;
 215      /** Compute a KeyPair
 216       *
 217       *  Wraps a `secp256k1_keypair` type.
 218       *
 219       *  `merkle_root` is used to optionally perform tweaking of
 220       *  the internal key, as specified in BIP341:
 221       *
 222       *  - If merkle_root == nullptr: no tweaking is done, use the internal key directly (this is
 223       *                               used for signatures in BIP342 script).
 224       *  - If merkle_root->IsNull():  tweak the internal key with H_TapTweak(pubkey) (this is used for
 225       *                               key path spending when no scripts are present).
 226       *  - Otherwise:                 tweak the internal key with H_TapTweak(pubkey || *merkle_root)
 227       *                               (this is used for key path spending with the
 228       *                               Merkle root of the script tree).
 229       */
 230      KeyPair ComputeKeyPair(const uint256* merkle_root) const;
 231  };
 232  
 233  CKey GenerateRandomKey(bool compressed = true) noexcept;
 234  
 235  struct CExtKey {
 236      unsigned char nDepth;
 237      unsigned char vchFingerprint[4];
 238      unsigned int nChild;
 239      ChainCode chaincode;
 240      CKey key;
 241  
 242      friend bool operator==(const CExtKey& a, const CExtKey& b)
 243      {
 244          return a.nDepth == b.nDepth &&
 245              memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
 246              a.nChild == b.nChild &&
 247              a.chaincode == b.chaincode &&
 248              a.key == b.key;
 249      }
 250  
 251      CExtKey() = default;
 252      CExtKey(const CExtPubKey& xpub, const CKey& key_in) : nDepth(xpub.nDepth), nChild(xpub.nChild), chaincode(xpub.chaincode), key(key_in)
 253      {
 254          std::copy(xpub.vchFingerprint, xpub.vchFingerprint + sizeof(xpub.vchFingerprint), vchFingerprint);
 255      }
 256  
 257      void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
 258      void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
 259      [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
 260      CExtPubKey Neuter() const;
 261      void SetSeed(Span<const std::byte> seed);
 262  };
 263  
 264  /** KeyPair
 265   *
 266   *  Wraps a `secp256k1_keypair` type, an opaque data structure for holding a secret and public key.
 267   *  This is intended for BIP340 keys and allows us to easily determine if the secret key needs to
 268   *  be negated by checking the parity of the public key. This class primarily intended for passing
 269   *  secret keys to libsecp256k1 functions expecting a `secp256k1_keypair`. For all other cases,
 270   *  CKey should be preferred.
 271   *
 272   *  A KeyPair can be created from a CKey with an optional merkle_root tweak (per BIP342). See
 273   *  CKey::ComputeKeyPair for more details.
 274   */
 275  class KeyPair
 276  {
 277  public:
 278      KeyPair() noexcept = default;
 279      KeyPair(KeyPair&&) noexcept = default;
 280      KeyPair& operator=(KeyPair&&) noexcept = default;
 281      KeyPair& operator=(const KeyPair& other)
 282      {
 283          if (this != &other) {
 284              if (other.m_keypair) {
 285                  MakeKeyPairData();
 286                  *m_keypair = *other.m_keypair;
 287              } else {
 288                  ClearKeyPairData();
 289              }
 290          }
 291          return *this;
 292      }
 293  
 294      KeyPair(const KeyPair& other) { *this = other; }
 295  
 296      friend KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const;
 297      [[nodiscard]] bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256& aux) const;
 298  
 299      //! Check whether this keypair is valid.
 300      bool IsValid() const { return !!m_keypair; }
 301  
 302  private:
 303      KeyPair(const CKey& key, const uint256* merkle_root);
 304  
 305      using KeyType = std::array<unsigned char, 96>;
 306      secure_unique_ptr<KeyType> m_keypair;
 307  
 308      void MakeKeyPairData()
 309      {
 310          if (!m_keypair) m_keypair = make_secure_unique<KeyType>();
 311      }
 312  
 313      void ClearKeyPairData()
 314      {
 315          m_keypair.reset();
 316      }
 317  };
 318  
 319  /** Check that required EC support is available at runtime. */
 320  bool ECC_InitSanityCheck();
 321  
 322  /**
 323   * RAII class initializing and deinitializing global state for elliptic curve support.
 324   * Only one instance may be initialized at a time.
 325   *
 326   * In the future global ECC state could be removed, and this class could contain
 327   * state and be passed as an argument to ECC key functions.
 328   */
 329  class ECC_Context
 330  {
 331  public:
 332      ECC_Context();
 333      ~ECC_Context();
 334  };
 335  
 336  #endif // LIMENKA_KEY_H
 337