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