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