/Users/brunogarcia/projects/bitcoin-core-dev/src/key.cpp
Line | Count | Source |
1 | | // Copyright (c) 2009-present The Bitcoin Core developers |
2 | | // Copyright (c) 2017 The Zcash 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 | | #include <key.h> |
7 | | |
8 | | #include <crypto/common.h> |
9 | | #include <crypto/hmac_sha512.h> |
10 | | #include <hash.h> |
11 | | #include <random.h> |
12 | | |
13 | | #include <secp256k1.h> |
14 | | #include <secp256k1_ellswift.h> |
15 | | #include <secp256k1_extrakeys.h> |
16 | | #include <secp256k1_musig.h> |
17 | | #include <secp256k1_recovery.h> |
18 | | #include <secp256k1_schnorrsig.h> |
19 | | |
20 | | static secp256k1_context* secp256k1_context_sign = nullptr; |
21 | | |
22 | | /** These functions are taken from the libsecp256k1 distribution and are very ugly. */ |
23 | | |
24 | | /** |
25 | | * This parses a format loosely based on a DER encoding of the ECPrivateKey type from |
26 | | * section C.4 of SEC 1 <https://www.secg.org/sec1-v2.pdf>, with the following caveats: |
27 | | * |
28 | | * * The octet-length of the SEQUENCE must be encoded as 1 or 2 octets. It is not |
29 | | * required to be encoded as one octet if it is less than 256, as DER would require. |
30 | | * * The octet-length of the SEQUENCE must not be greater than the remaining |
31 | | * length of the key encoding, but need not match it (i.e. the encoding may contain |
32 | | * junk after the encoded SEQUENCE). |
33 | | * * The privateKey OCTET STRING is zero-filled on the left to 32 octets. |
34 | | * * Anything after the encoding of the privateKey OCTET STRING is ignored, whether |
35 | | * or not it is validly encoded DER. |
36 | | * |
37 | | * out32 must point to an output buffer of length at least 32 bytes. |
38 | | */ |
39 | 0 | int ec_seckey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *seckey, size_t seckeylen) { |
40 | 0 | const unsigned char *end = seckey + seckeylen; |
41 | 0 | memset(out32, 0, 32); |
42 | | /* sequence header */ |
43 | 0 | if (end - seckey < 1 || *seckey != 0x30u) { |
44 | 0 | return 0; |
45 | 0 | } |
46 | 0 | seckey++; |
47 | | /* sequence length constructor */ |
48 | 0 | if (end - seckey < 1 || !(*seckey & 0x80u)) { |
49 | 0 | return 0; |
50 | 0 | } |
51 | 0 | ptrdiff_t lenb = *seckey & ~0x80u; seckey++; |
52 | 0 | if (lenb < 1 || lenb > 2) { |
53 | 0 | return 0; |
54 | 0 | } |
55 | 0 | if (end - seckey < lenb) { |
56 | 0 | return 0; |
57 | 0 | } |
58 | | /* sequence length */ |
59 | 0 | ptrdiff_t len = seckey[lenb-1] | (lenb > 1 ? seckey[lenb-2] << 8 : 0u); |
60 | 0 | seckey += lenb; |
61 | 0 | if (end - seckey < len) { |
62 | 0 | return 0; |
63 | 0 | } |
64 | | /* sequence element 0: version number (=1) */ |
65 | 0 | if (end - seckey < 3 || seckey[0] != 0x02u || seckey[1] != 0x01u || seckey[2] != 0x01u) { |
66 | 0 | return 0; |
67 | 0 | } |
68 | 0 | seckey += 3; |
69 | | /* sequence element 1: octet string, up to 32 bytes */ |
70 | 0 | if (end - seckey < 2 || seckey[0] != 0x04u) { |
71 | 0 | return 0; |
72 | 0 | } |
73 | 0 | ptrdiff_t oslen = seckey[1]; |
74 | 0 | seckey += 2; |
75 | 0 | if (oslen > 32 || end - seckey < oslen) { |
76 | 0 | return 0; |
77 | 0 | } |
78 | 0 | memcpy(out32 + (32 - oslen), seckey, oslen); |
79 | 0 | if (!secp256k1_ec_seckey_verify(ctx, out32)) { |
80 | 0 | memset(out32, 0, 32); |
81 | 0 | return 0; |
82 | 0 | } |
83 | 0 | return 1; |
84 | 0 | } |
85 | | |
86 | | /** |
87 | | * This serializes to a DER encoding of the ECPrivateKey type from section C.4 of SEC 1 |
88 | | * <https://www.secg.org/sec1-v2.pdf>. The optional parameters and publicKey fields are |
89 | | * included. |
90 | | * |
91 | | * seckey must point to an output buffer of length at least CKey::SIZE bytes. |
92 | | * seckeylen must initially be set to the size of the seckey buffer. Upon return it |
93 | | * will be set to the number of bytes used in the buffer. |
94 | | * key32 must point to a 32-byte raw private key. |
95 | | */ |
96 | 79.3k | int ec_seckey_export_der(const secp256k1_context *ctx, unsigned char *seckey, size_t *seckeylen, const unsigned char *key32, bool compressed) { |
97 | 79.3k | assert(*seckeylen >= CKey::SIZE); |
98 | 79.3k | secp256k1_pubkey pubkey; |
99 | 79.3k | size_t pubkeylen = 0; |
100 | 79.3k | if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { |
101 | 0 | *seckeylen = 0; |
102 | 0 | return 0; |
103 | 0 | } |
104 | 79.3k | if (compressed) { |
105 | 79.3k | static const unsigned char begin[] = { |
106 | 79.3k | 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20 |
107 | 79.3k | }; |
108 | 79.3k | static const unsigned char middle[] = { |
109 | 79.3k | 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, |
110 | 79.3k | 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
111 | 79.3k | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
112 | 79.3k | 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, |
113 | 79.3k | 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, |
114 | 79.3k | 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, |
115 | 79.3k | 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
116 | 79.3k | 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, |
117 | 79.3k | 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00 |
118 | 79.3k | }; |
119 | 79.3k | unsigned char *ptr = seckey; |
120 | 79.3k | memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); |
121 | 79.3k | memcpy(ptr, key32, 32); ptr += 32; |
122 | 79.3k | memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); |
123 | 79.3k | pubkeylen = CPubKey::COMPRESSED_SIZE; |
124 | 79.3k | secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); Line | Count | Source | 224 | 79.3k | #define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) Line | Count | Source | 205 | 79.3k | #define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) |
| #define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) Line | Count | Source | 210 | 79.3k | #define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) |
|
|
125 | 79.3k | ptr += pubkeylen; |
126 | 79.3k | *seckeylen = ptr - seckey; |
127 | 79.3k | assert(*seckeylen == CKey::COMPRESSED_SIZE); |
128 | 79.3k | } else { |
129 | 0 | static const unsigned char begin[] = { |
130 | 0 | 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 |
131 | 0 | }; |
132 | 0 | static const unsigned char middle[] = { |
133 | 0 | 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, |
134 | 0 | 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
135 | 0 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
136 | 0 | 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, |
137 | 0 | 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, |
138 | 0 | 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, |
139 | 0 | 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11, |
140 | 0 | 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10, |
141 | 0 | 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
142 | 0 | 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, |
143 | 0 | 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00 |
144 | 0 | }; |
145 | 0 | unsigned char *ptr = seckey; |
146 | 0 | memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); |
147 | 0 | memcpy(ptr, key32, 32); ptr += 32; |
148 | 0 | memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); |
149 | 0 | pubkeylen = CPubKey::SIZE; |
150 | 0 | secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); Line | Count | Source | 225 | 0 | #define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION) Line | Count | Source | 205 | 0 | #define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) |
|
|
151 | 0 | ptr += pubkeylen; |
152 | 0 | *seckeylen = ptr - seckey; |
153 | 0 | assert(*seckeylen == CKey::SIZE); |
154 | 0 | } |
155 | 79.3k | return 1; |
156 | 79.3k | } |
157 | | |
158 | 79.3k | bool CKey::Check(const unsigned char *vch) { |
159 | 79.3k | return secp256k1_ec_seckey_verify(secp256k1_context_static, vch); |
160 | 79.3k | } |
161 | | |
162 | 0 | void CKey::MakeNewKey(bool fCompressedIn) { |
163 | 0 | MakeKeyData(); |
164 | 0 | do { |
165 | 0 | GetStrongRandBytes(*keydata); |
166 | 0 | } while (!Check(keydata->data())); |
167 | 0 | fCompressed = fCompressedIn; |
168 | 0 | } |
169 | | |
170 | 79.3k | CPrivKey CKey::GetPrivKey() const { |
171 | 79.3k | assert(keydata); |
172 | 79.3k | CPrivKey seckey; |
173 | 79.3k | int ret; |
174 | 79.3k | size_t seckeylen; |
175 | 79.3k | seckey.resize(SIZE); |
176 | 79.3k | seckeylen = SIZE; |
177 | 79.3k | ret = ec_seckey_export_der(secp256k1_context_sign, seckey.data(), &seckeylen, UCharCast(begin()), fCompressed); |
178 | 79.3k | assert(ret); |
179 | 79.3k | seckey.resize(seckeylen); |
180 | 79.3k | return seckey; |
181 | 79.3k | } |
182 | | |
183 | 158k | CPubKey CKey::GetPubKey() const { |
184 | 158k | assert(keydata); |
185 | 158k | secp256k1_pubkey pubkey; |
186 | 158k | size_t clen = CPubKey::SIZE; |
187 | 158k | CPubKey result; |
188 | 158k | int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, UCharCast(begin())); |
189 | 158k | assert(ret); |
190 | 158k | secp256k1_ec_pubkey_serialize(secp256k1_context_static, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED0 ); Line | Count | Source | 224 | 158k | #define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) Line | Count | Source | 205 | 158k | #define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) |
| #define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) Line | Count | Source | 210 | 158k | #define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) |
|
| secp256k1_ec_pubkey_serialize(secp256k1_context_static, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED0 ); Line | Count | Source | 225 | 158k | #define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION0 ) Line | Count | Source | 205 | 0 | #define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) |
|
|
191 | 158k | assert(result.size() == clen); |
192 | 158k | assert(result.IsValid()); |
193 | 158k | return result; |
194 | 158k | } |
195 | | |
196 | | // Check that the sig has a low R value and will be less than 71 bytes |
197 | | bool SigHasLowR(const secp256k1_ecdsa_signature* sig) |
198 | 0 | { |
199 | 0 | unsigned char compact_sig[64]; |
200 | 0 | secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_static, compact_sig, sig); |
201 | | |
202 | | // In DER serialization, all values are interpreted as big-endian, signed integers. The highest bit in the integer indicates |
203 | | // its signed-ness; 0 is positive, 1 is negative. When the value is interpreted as a negative integer, it must be converted |
204 | | // to a positive value by prepending a 0x00 byte so that the highest bit is 0. We can avoid this prepending by ensuring that |
205 | | // our highest bit is always 0, and thus we must check that the first byte is less than 0x80. |
206 | 0 | return compact_sig[0] < 0x80; |
207 | 0 | } |
208 | | |
209 | 0 | bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool grind, uint32_t test_case) const { |
210 | 0 | if (!keydata) |
211 | 0 | return false; |
212 | 0 | vchSig.resize(CPubKey::SIGNATURE_SIZE); |
213 | 0 | size_t nSigLen = CPubKey::SIGNATURE_SIZE; |
214 | 0 | unsigned char extra_entropy[32] = {0}; |
215 | 0 | WriteLE32(extra_entropy, test_case); |
216 | 0 | secp256k1_ecdsa_signature sig; |
217 | 0 | uint32_t counter = 0; |
218 | 0 | int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, (!grind && test_case) ? extra_entropy : nullptr); |
219 | | |
220 | | // Grind for low R |
221 | 0 | while (ret && !SigHasLowR(&sig) && grind) { |
222 | 0 | WriteLE32(extra_entropy, ++counter); |
223 | 0 | ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, extra_entropy); |
224 | 0 | } |
225 | 0 | assert(ret); |
226 | 0 | secp256k1_ecdsa_signature_serialize_der(secp256k1_context_static, vchSig.data(), &nSigLen, &sig); |
227 | 0 | vchSig.resize(nSigLen); |
228 | | // Additional verification step to prevent using a potentially corrupted signature |
229 | 0 | secp256k1_pubkey pk; |
230 | 0 | ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pk, UCharCast(begin())); |
231 | 0 | assert(ret); |
232 | 0 | ret = secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pk); |
233 | 0 | assert(ret); |
234 | 0 | return true; |
235 | 0 | } |
236 | | |
237 | 0 | bool CKey::VerifyPubKey(const CPubKey& pubkey) const { |
238 | 0 | if (pubkey.IsCompressed() != fCompressed) { |
239 | 0 | return false; |
240 | 0 | } |
241 | 0 | unsigned char rnd[8]; |
242 | 0 | std::string str = "Bitcoin key verification\n"; |
243 | 0 | GetRandBytes(rnd); |
244 | 0 | uint256 hash{Hash(str, rnd)}; |
245 | 0 | std::vector<unsigned char> vchSig; |
246 | 0 | Sign(hash, vchSig); |
247 | 0 | return pubkey.Verify(hash, vchSig); |
248 | 0 | } |
249 | | |
250 | 0 | bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const { |
251 | 0 | if (!keydata) |
252 | 0 | return false; |
253 | 0 | vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE); |
254 | 0 | int rec = -1; |
255 | 0 | secp256k1_ecdsa_recoverable_signature rsig; |
256 | 0 | int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &rsig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, nullptr); |
257 | 0 | assert(ret); |
258 | 0 | ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_static, &vchSig[1], &rec, &rsig); |
259 | 0 | assert(ret); |
260 | 0 | assert(rec != -1); |
261 | 0 | vchSig[0] = 27 + rec + (fCompressed ? 4 : 0); |
262 | | // Additional verification step to prevent using a potentially corrupted signature |
263 | 0 | secp256k1_pubkey epk, rpk; |
264 | 0 | ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &epk, UCharCast(begin())); |
265 | 0 | assert(ret); |
266 | 0 | ret = secp256k1_ecdsa_recover(secp256k1_context_static, &rpk, &rsig, hash.begin()); |
267 | 0 | assert(ret); |
268 | 0 | ret = secp256k1_ec_pubkey_cmp(secp256k1_context_static, &epk, &rpk); |
269 | 0 | assert(ret == 0); |
270 | 0 | return true; |
271 | 0 | } |
272 | | |
273 | | bool CKey::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const |
274 | 0 | { |
275 | 0 | KeyPair kp = ComputeKeyPair(merkle_root); |
276 | 0 | return kp.SignSchnorr(hash, sig, aux); |
277 | 0 | } |
278 | | |
279 | 0 | bool CKey::Load(const CPrivKey &seckey, const CPubKey &vchPubKey, bool fSkipCheck=false) { |
280 | 0 | MakeKeyData(); |
281 | 0 | if (!ec_seckey_import_der(secp256k1_context_static, (unsigned char*)begin(), seckey.data(), seckey.size())) { |
282 | 0 | ClearKeyData(); |
283 | 0 | return false; |
284 | 0 | } |
285 | 0 | fCompressed = vchPubKey.IsCompressed(); |
286 | |
|
287 | 0 | if (fSkipCheck) |
288 | 0 | return true; |
289 | | |
290 | 0 | return VerifyPubKey(vchPubKey); |
291 | 0 | } |
292 | | |
293 | 0 | bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const { |
294 | 0 | assert(IsValid()); |
295 | 0 | assert(IsCompressed()); |
296 | 0 | std::vector<unsigned char, secure_allocator<unsigned char>> vout(64); |
297 | 0 | if ((nChild >> 31) == 0) { |
298 | 0 | CPubKey pubkey = GetPubKey(); |
299 | 0 | assert(pubkey.size() == CPubKey::COMPRESSED_SIZE); |
300 | 0 | BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin()+1, vout.data()); |
301 | 0 | } else { |
302 | 0 | assert(size() == 32); |
303 | 0 | BIP32Hash(cc, nChild, 0, UCharCast(begin()), vout.data()); |
304 | 0 | } |
305 | 0 | memcpy(ccChild.begin(), vout.data()+32, 32); |
306 | 0 | keyChild.Set(begin(), begin() + 32, true); |
307 | 0 | bool ret = secp256k1_ec_seckey_tweak_add(secp256k1_context_static, (unsigned char*)keyChild.begin(), vout.data()); |
308 | 0 | if (!ret) keyChild.ClearKeyData(); |
309 | 0 | return ret; |
310 | 0 | } |
311 | | |
312 | | EllSwiftPubKey CKey::EllSwiftCreate(std::span<const std::byte> ent32) const |
313 | 0 | { |
314 | 0 | assert(keydata); |
315 | 0 | assert(ent32.size() == 32); |
316 | 0 | std::array<std::byte, EllSwiftPubKey::size()> encoded_pubkey; |
317 | |
|
318 | 0 | auto success = secp256k1_ellswift_create(secp256k1_context_sign, |
319 | 0 | UCharCast(encoded_pubkey.data()), |
320 | 0 | keydata->data(), |
321 | 0 | UCharCast(ent32.data())); |
322 | | |
323 | | // Should always succeed for valid keys (asserted above). |
324 | 0 | assert(success); |
325 | 0 | return {encoded_pubkey}; |
326 | 0 | } |
327 | | |
328 | | ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, const EllSwiftPubKey& our_ellswift, bool initiating) const |
329 | 0 | { |
330 | 0 | assert(keydata); |
331 | | |
332 | 0 | ECDHSecret output; |
333 | | // BIP324 uses the initiator as party A, and the responder as party B. Remap the inputs |
334 | | // accordingly: |
335 | 0 | bool success = secp256k1_ellswift_xdh(secp256k1_context_static, |
336 | 0 | UCharCast(output.data()), |
337 | 0 | UCharCast(initiating ? our_ellswift.data() : their_ellswift.data()), |
338 | 0 | UCharCast(initiating ? their_ellswift.data() : our_ellswift.data()), |
339 | 0 | keydata->data(), |
340 | 0 | initiating ? 0 : 1, |
341 | 0 | secp256k1_ellswift_xdh_hash_function_bip324, |
342 | 0 | nullptr); |
343 | | // Should always succeed for valid keys (assert above). |
344 | 0 | assert(success); |
345 | 0 | return output; |
346 | 0 | } |
347 | | |
348 | | KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const |
349 | 0 | { |
350 | 0 | return KeyPair(*this, merkle_root); |
351 | 0 | } |
352 | | |
353 | | std::vector<uint8_t> CKey::CreateMuSig2Nonce(MuSig2SecNonce& secnonce, const uint256& sighash, const CPubKey& aggregate_pubkey, const std::vector<CPubKey>& pubkeys) |
354 | 0 | { |
355 | | // Get the keyagg cache and aggregate pubkey |
356 | 0 | secp256k1_musig_keyagg_cache keyagg_cache; |
357 | 0 | if (!MuSig2AggregatePubkeys(pubkeys, keyagg_cache, aggregate_pubkey)) return {}; |
358 | | |
359 | | // Parse participant pubkey |
360 | 0 | CPubKey our_pubkey = GetPubKey(); |
361 | 0 | secp256k1_pubkey pubkey; |
362 | 0 | if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, our_pubkey.data(), our_pubkey.size())) { |
363 | 0 | return {}; |
364 | 0 | } |
365 | | |
366 | | // Generate randomness for nonce |
367 | 0 | uint256 rand; |
368 | 0 | GetStrongRandBytes(rand); |
369 | | |
370 | | // Generate nonce |
371 | 0 | secp256k1_musig_pubnonce pubnonce; |
372 | 0 | if (!secp256k1_musig_nonce_gen(secp256k1_context_sign, secnonce.Get(), &pubnonce, rand.data(), UCharCast(begin()), &pubkey, sighash.data(), &keyagg_cache, nullptr)) { |
373 | 0 | return {}; |
374 | 0 | } |
375 | | |
376 | | // Serialize pubnonce |
377 | 0 | std::vector<uint8_t> out; |
378 | 0 | out.resize(MUSIG2_PUBNONCE_SIZE); |
379 | 0 | if (!secp256k1_musig_pubnonce_serialize(secp256k1_context_static, out.data(), &pubnonce)) { |
380 | 0 | return {}; |
381 | 0 | } |
382 | | |
383 | 0 | return out; |
384 | 0 | } |
385 | | |
386 | | std::optional<uint256> CKey::CreateMuSig2PartialSig(const uint256& sighash, const CPubKey& aggregate_pubkey, const std::vector<CPubKey>& pubkeys, const std::map<CPubKey, std::vector<uint8_t>>& pubnonces, MuSig2SecNonce& secnonce, const std::vector<std::pair<uint256, bool>>& tweaks) |
387 | 0 | { |
388 | 0 | secp256k1_keypair keypair; |
389 | 0 | if (!secp256k1_keypair_create(secp256k1_context_sign, &keypair, UCharCast(begin()))) return std::nullopt; |
390 | | |
391 | | // Get the keyagg cache and aggregate pubkey |
392 | 0 | secp256k1_musig_keyagg_cache keyagg_cache; |
393 | 0 | if (!MuSig2AggregatePubkeys(pubkeys, keyagg_cache, aggregate_pubkey)) return std::nullopt; |
394 | | |
395 | | // Check that there are enough pubnonces |
396 | 0 | if (pubnonces.size() != pubkeys.size()) return std::nullopt; |
397 | | |
398 | | // Parse the pubnonces |
399 | 0 | std::vector<std::pair<secp256k1_pubkey, secp256k1_musig_pubnonce>> signers_data; |
400 | 0 | std::vector<const secp256k1_musig_pubnonce*> pubnonce_ptrs; |
401 | 0 | std::optional<size_t> our_pubkey_idx; |
402 | 0 | CPubKey our_pubkey = GetPubKey(); |
403 | 0 | for (const CPubKey& part_pk : pubkeys) { |
404 | 0 | const auto& pn_it = pubnonces.find(part_pk); |
405 | 0 | if (pn_it == pubnonces.end()) return std::nullopt; |
406 | 0 | const std::vector<uint8_t> pubnonce = pn_it->second; |
407 | 0 | if (pubnonce.size() != MUSIG2_PUBNONCE_SIZE) return std::nullopt; |
408 | 0 | if (part_pk == our_pubkey) { |
409 | 0 | our_pubkey_idx = signers_data.size(); |
410 | 0 | } |
411 | |
|
412 | 0 | auto& [secp_pk, secp_pn] = signers_data.emplace_back(); |
413 | |
|
414 | 0 | if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &secp_pk, part_pk.data(), part_pk.size())) { |
415 | 0 | return std::nullopt; |
416 | 0 | } |
417 | | |
418 | 0 | if (!secp256k1_musig_pubnonce_parse(secp256k1_context_static, &secp_pn, pubnonce.data())) { |
419 | 0 | return std::nullopt; |
420 | 0 | } |
421 | 0 | } |
422 | 0 | if (our_pubkey_idx == std::nullopt) { |
423 | 0 | return std::nullopt; |
424 | 0 | } |
425 | 0 | pubnonce_ptrs.reserve(signers_data.size()); |
426 | 0 | for (auto& [_, pn] : signers_data) { |
427 | 0 | pubnonce_ptrs.push_back(&pn); |
428 | 0 | } |
429 | | |
430 | | // Aggregate nonces |
431 | 0 | secp256k1_musig_aggnonce aggnonce; |
432 | 0 | if (!secp256k1_musig_nonce_agg(secp256k1_context_static, &aggnonce, pubnonce_ptrs.data(), pubnonce_ptrs.size())) { |
433 | 0 | return std::nullopt; |
434 | 0 | } |
435 | | |
436 | | // Apply tweaks |
437 | 0 | for (const auto& [tweak, xonly] : tweaks) { |
438 | 0 | if (xonly) { |
439 | 0 | if (!secp256k1_musig_pubkey_xonly_tweak_add(secp256k1_context_static, nullptr, &keyagg_cache, tweak.data())) { |
440 | 0 | return std::nullopt; |
441 | 0 | } |
442 | 0 | } else if (!secp256k1_musig_pubkey_ec_tweak_add(secp256k1_context_static, nullptr, &keyagg_cache, tweak.data())) { |
443 | 0 | return std::nullopt; |
444 | 0 | } |
445 | 0 | } |
446 | | |
447 | | // Create musig_session |
448 | 0 | secp256k1_musig_session session; |
449 | 0 | if (!secp256k1_musig_nonce_process(secp256k1_context_static, &session, &aggnonce, sighash.data(), &keyagg_cache)) { |
450 | 0 | return std::nullopt; |
451 | 0 | } |
452 | | |
453 | | // Create partial signature |
454 | 0 | secp256k1_musig_partial_sig psig; |
455 | 0 | if (!secp256k1_musig_partial_sign(secp256k1_context_static, &psig, secnonce.Get(), &keypair, &keyagg_cache, &session)) { |
456 | 0 | return std::nullopt; |
457 | 0 | } |
458 | | // The secnonce must be deleted after signing to prevent nonce reuse. |
459 | 0 | secnonce.Invalidate(); |
460 | | |
461 | | // Verify partial signature |
462 | 0 | if (!secp256k1_musig_partial_sig_verify(secp256k1_context_static, &psig, &(signers_data.at(*our_pubkey_idx).second), &(signers_data.at(*our_pubkey_idx).first), &keyagg_cache, &session)) { |
463 | 0 | return std::nullopt; |
464 | 0 | } |
465 | | |
466 | | // Serialize |
467 | 0 | uint256 sig; |
468 | 0 | if (!secp256k1_musig_partial_sig_serialize(secp256k1_context_static, sig.data(), &psig)) { |
469 | 0 | return std::nullopt; |
470 | 0 | } |
471 | | |
472 | 0 | return sig; |
473 | 0 | } |
474 | | |
475 | | CKey GenerateRandomKey(bool compressed) noexcept |
476 | 0 | { |
477 | 0 | CKey key; |
478 | 0 | key.MakeNewKey(/*fCompressed=*/compressed); |
479 | 0 | return key; |
480 | 0 | } |
481 | | |
482 | 0 | bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const { |
483 | 0 | if (nDepth == std::numeric_limits<unsigned char>::max()) return false; |
484 | 0 | out.nDepth = nDepth + 1; |
485 | 0 | CKeyID id = key.GetPubKey().GetID(); |
486 | 0 | memcpy(out.vchFingerprint, &id, 4); |
487 | 0 | out.nChild = _nChild; |
488 | 0 | return key.Derive(out.key, out.chaincode, _nChild, chaincode); |
489 | 0 | } |
490 | | |
491 | | void CExtKey::SetSeed(std::span<const std::byte> seed) |
492 | 0 | { |
493 | 0 | static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'}; |
494 | 0 | std::vector<unsigned char, secure_allocator<unsigned char>> vout(64); |
495 | 0 | CHMAC_SHA512{hashkey, sizeof(hashkey)}.Write(UCharCast(seed.data()), seed.size()).Finalize(vout.data()); |
496 | 0 | key.Set(vout.data(), vout.data() + 32, true); |
497 | 0 | memcpy(chaincode.begin(), vout.data() + 32, 32); |
498 | 0 | nDepth = 0; |
499 | 0 | nChild = 0; |
500 | 0 | memset(vchFingerprint, 0, sizeof(vchFingerprint)); |
501 | 0 | } |
502 | | |
503 | 79.3k | CExtPubKey CExtKey::Neuter() const { |
504 | 79.3k | CExtPubKey ret; |
505 | 79.3k | ret.nDepth = nDepth; |
506 | 79.3k | memcpy(ret.vchFingerprint, vchFingerprint, 4); |
507 | 79.3k | ret.nChild = nChild; |
508 | 79.3k | ret.pubkey = key.GetPubKey(); |
509 | 79.3k | ret.chaincode = chaincode; |
510 | 79.3k | return ret; |
511 | 79.3k | } |
512 | | |
513 | 0 | void CExtKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const { |
514 | 0 | code[0] = nDepth; |
515 | 0 | memcpy(code+1, vchFingerprint, 4); |
516 | 0 | WriteBE32(code+5, nChild); |
517 | 0 | memcpy(code+9, chaincode.begin(), 32); |
518 | 0 | code[41] = 0; |
519 | 0 | assert(key.size() == 32); |
520 | 0 | memcpy(code+42, key.begin(), 32); |
521 | 0 | } |
522 | | |
523 | 79.3k | void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) { |
524 | 79.3k | nDepth = code[0]; |
525 | 79.3k | memcpy(vchFingerprint, code+1, 4); |
526 | 79.3k | nChild = ReadBE32(code+5); |
527 | 79.3k | memcpy(chaincode.begin(), code+9, 32); |
528 | 79.3k | key.Set(code+42, code+BIP32_EXTKEY_SIZE, true); |
529 | 79.3k | if ((nDepth == 0 && (nChild != 0 || ReadLE32(vchFingerprint) != 0)) || code[41] != 0) key = CKey()0 ; |
530 | 79.3k | } |
531 | | |
532 | | KeyPair::KeyPair(const CKey& key, const uint256* merkle_root) |
533 | 0 | { |
534 | 0 | static_assert(std::tuple_size<KeyType>() == sizeof(secp256k1_keypair)); |
535 | 0 | MakeKeyPairData(); |
536 | 0 | auto keypair = reinterpret_cast<secp256k1_keypair*>(m_keypair->data()); |
537 | 0 | bool success = secp256k1_keypair_create(secp256k1_context_sign, keypair, UCharCast(key.data())); |
538 | 0 | if (success && merkle_root) { |
539 | 0 | secp256k1_xonly_pubkey pubkey; |
540 | 0 | unsigned char pubkey_bytes[32]; |
541 | 0 | assert(secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey, nullptr, keypair)); |
542 | 0 | assert(secp256k1_xonly_pubkey_serialize(secp256k1_context_static, pubkey_bytes, &pubkey)); |
543 | 0 | uint256 tweak = XOnlyPubKey(pubkey_bytes).ComputeTapTweakHash(merkle_root->IsNull() ? nullptr : merkle_root); |
544 | 0 | success = secp256k1_keypair_xonly_tweak_add(secp256k1_context_static, keypair, tweak.data()); |
545 | 0 | } |
546 | 0 | if (!success) ClearKeyPairData(); |
547 | 0 | } |
548 | | |
549 | | bool KeyPair::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256& aux) const |
550 | 0 | { |
551 | 0 | assert(sig.size() == 64); |
552 | 0 | if (!IsValid()) return false; |
553 | 0 | auto keypair = reinterpret_cast<const secp256k1_keypair*>(m_keypair->data()); |
554 | 0 | bool ret = secp256k1_schnorrsig_sign32(secp256k1_context_sign, sig.data(), hash.data(), keypair, aux.data()); |
555 | 0 | if (ret) { |
556 | | // Additional verification step to prevent using a potentially corrupted signature |
557 | 0 | secp256k1_xonly_pubkey pubkey_verify; |
558 | 0 | ret = secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey_verify, nullptr, keypair); |
559 | 0 | ret &= secp256k1_schnorrsig_verify(secp256k1_context_static, sig.data(), hash.begin(), 32, &pubkey_verify); |
560 | 0 | } |
561 | 0 | if (!ret) memory_cleanse(sig.data(), sig.size()); |
562 | 0 | return ret; |
563 | 0 | } |
564 | | |
565 | 0 | bool ECC_InitSanityCheck() { |
566 | 0 | CKey key = GenerateRandomKey(); |
567 | 0 | CPubKey pubkey = key.GetPubKey(); |
568 | 0 | return key.VerifyPubKey(pubkey); |
569 | 0 | } |
570 | | |
571 | | /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ |
572 | 0 | static void ECC_Start() { |
573 | 0 | assert(secp256k1_context_sign == nullptr); |
574 | | |
575 | 0 | secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); Line | Count | Source | 214 | 0 | #define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT) Line | Count | Source | 204 | 0 | #define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0) |
|
|
576 | 0 | assert(ctx != nullptr); |
577 | | |
578 | 0 | { |
579 | | // Pass in a random blinding seed to the secp256k1 context. |
580 | 0 | std::vector<unsigned char, secure_allocator<unsigned char>> vseed(32); |
581 | 0 | GetRandBytes(vseed); |
582 | 0 | bool ret = secp256k1_context_randomize(ctx, vseed.data()); |
583 | 0 | assert(ret); |
584 | 0 | } |
585 | | |
586 | 0 | secp256k1_context_sign = ctx; |
587 | 0 | } |
588 | | |
589 | | /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ |
590 | 1 | static void ECC_Stop() { |
591 | 1 | secp256k1_context *ctx = secp256k1_context_sign; |
592 | 1 | secp256k1_context_sign = nullptr; |
593 | | |
594 | 1 | if (ctx) { |
595 | 1 | secp256k1_context_destroy(ctx); |
596 | 1 | } |
597 | 1 | } |
598 | | |
599 | | ECC_Context::ECC_Context() |
600 | 0 | { |
601 | 0 | ECC_Start(); |
602 | 0 | } |
603 | | |
604 | | ECC_Context::~ECC_Context() |
605 | 1 | { |
606 | 1 | ECC_Stop(); |
607 | 1 | } |