signmessage.h raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-2022 The Limenka developers
   3  // Distributed under the MIT software license, see the accompanying
   4  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  
   6  #ifndef LIMENKA_COMMON_SIGNMESSAGE_H
   7  #define LIMENKA_COMMON_SIGNMESSAGE_H
   8  
   9  #include <addresstype.h>
  10  #include <primitives/transaction.h>
  11  #include <uint256.h>
  12  
  13  #include <optional>
  14  #include <string>
  15  #include <vector>
  16  
  17  class CKey;
  18  
  19  extern const std::string MESSAGE_MAGIC;
  20  
  21  enum class MessageSignatureFormat {
  22      //! Legacy format, which only works on legacy addresses
  23      LEGACY,
  24  
  25      //! Simple BIP-322 format, i.e. the script witness stack only
  26      SIMPLE,
  27  
  28      //! Full BIP-322 format, i.e. the serialized to_sign transaction in full
  29      FULL,
  30  };
  31  
  32  /** The result of a signed message verification.
  33   * Message verification takes as an input:
  34   * - address (with whose private key the message is supposed to have been signed)
  35   * - signature
  36   * - message
  37   */
  38  enum class MessageVerificationResult {
  39      //! The provided address is invalid.
  40      ERR_INVALID_ADDRESS,
  41  
  42      //! The provided address is valid but does not refer to a public key.
  43      ERR_ADDRESS_NO_KEY,
  44  
  45      //! The provided signature couldn't be parsed (maybe invalid base64).
  46      ERR_MALFORMED_SIGNATURE,
  47  
  48      //! A public key could not be recovered from the provided signature and message.
  49      ERR_PUBKEY_NOT_RECOVERED,
  50  
  51      //! The message was not signed with the private key of the provided address.
  52      ERR_NOT_SIGNED,
  53  
  54      //! The message verification was successful.
  55      OK,
  56  
  57      //
  58      // BIP-322 extensions
  59      //
  60  
  61      //! The validator was unable to check the scripts (BIP-322)
  62      INCONCLUSIVE,
  63  
  64      //! Some check failed (BIP-322)
  65      ERR_INVALID,
  66  
  67      //! Proof of funds require the wallet-enabled verifier (BIP-322)
  68      ERR_POF,
  69  };
  70  
  71  enum class SigningResult {
  72      OK, //!< No error
  73      PRIVATE_KEY_NOT_AVAILABLE,
  74      SIGNING_FAILED,
  75  };
  76  
  77  /** Verify a signed message.
  78   * @param[in] address Signer's limenka address.
  79   * @param[in] signature The signature in base64 format.
  80   * @param[in] message The message that was signed.
  81   * @return result code */
  82  MessageVerificationResult MessageVerify(
  83      const std::string& address,
  84      const std::string& signature,
  85      const std::string& message);
  86  
  87  /** Sign a message using legacy format.
  88   * @param[in] privkey Private key to sign with.
  89   * @param[in] message The message to sign.
  90   * @param[out] signature Signature, base64 encoded, only set if true is returned.
  91   * @return true if signing was successful. */
  92  bool MessageSign(
  93      const CKey& privkey,
  94      const std::string& message,
  95      std::string& signature);
  96  
  97  /**
  98   * Hashes a message for signing and verification in a manner that prevents
  99   * inadvertently signing a transaction.
 100   */
 101  uint256 MessageHash(const std::string& message, MessageSignatureFormat format);
 102  
 103  std::string SigningResultString(const SigningResult res);
 104  
 105  /**
 106   * Generate the BIP-322 tx corresponding to the given challenge
 107   */
 108  class BIP322Txs {
 109  private:
 110      template<class T1, class T2>
 111      BIP322Txs(const T1& to_spend, const T2& to_sign) : m_to_spend{to_spend}, m_to_sign{to_sign} { }
 112  
 113  public:
 114      static std::optional<BIP322Txs> Create(const CTxDestination& destination, const std::string& message, MessageVerificationResult& result, std::optional<const std::vector<unsigned char>> = std::nullopt);
 115  
 116      const CTransaction m_to_spend;
 117      const CTransaction m_to_sign;
 118  };
 119  
 120  #endif // LIMENKA_COMMON_SIGNMESSAGE_H
 121