/root/bitcoin/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_recovery.h> |
17 | | #include <secp256k1_schnorrsig.h> |
18 | | |
19 | | #include <algorithm> |
20 | | |
21 | | static secp256k1_context* secp256k1_context_sign = nullptr; |
22 | | |
23 | | /** These functions are taken from the libsecp256k1 distribution and are very ugly. */ |
24 | | |
25 | | /** |
26 | | * This parses a format loosely based on a DER encoding of the ECPrivateKey type from |
27 | | * section C.4 of SEC 1 <https://www.secg.org/sec1-v2.pdf>, with the following caveats: |
28 | | * |
29 | | * * The octet-length of the SEQUENCE must be encoded as 1 or 2 octets. It is not |
30 | | * required to be encoded as one octet if it is less than 256, as DER would require. |
31 | | * * The octet-length of the SEQUENCE must not be greater than the remaining |
32 | | * length of the key encoding, but need not match it (i.e. the encoding may contain |
33 | | * junk after the encoded SEQUENCE). |
34 | | * * The privateKey OCTET STRING is zero-filled on the left to 32 octets. |
35 | | * * Anything after the encoding of the privateKey OCTET STRING is ignored, whether |
36 | | * or not it is validly encoded DER. |
37 | | * |
38 | | * out32 must point to an output buffer of length at least 32 bytes. |
39 | | */ |
40 | 2.35k | int ec_seckey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *seckey, size_t seckeylen) { |
41 | 2.35k | const unsigned char *end = seckey + seckeylen; |
42 | 2.35k | memset(out32, 0, 32); |
43 | | /* sequence header */ |
44 | 2.35k | if (end - seckey < 1 || *seckey != 0x30u) { Branch (44:9): [True: 0, False: 2.35k]
Branch (44:29): [True: 7, False: 2.35k]
|
45 | 7 | return 0; |
46 | 7 | } |
47 | 2.35k | seckey++; |
48 | | /* sequence length constructor */ |
49 | 2.35k | if (end - seckey < 1 || !(*seckey & 0x80u)) { Branch (49:9): [True: 0, False: 2.35k]
Branch (49:29): [True: 3, False: 2.34k]
|
50 | 3 | return 0; |
51 | 3 | } |
52 | 2.34k | ptrdiff_t lenb = *seckey & ~0x80u; seckey++; |
53 | 2.34k | if (lenb < 1 || lenb > 2) { Branch (53:9): [True: 2, False: 2.34k]
Branch (53:21): [True: 12, False: 2.33k]
|
54 | 14 | return 0; |
55 | 14 | } |
56 | 2.33k | if (end - seckey < lenb) { Branch (56:9): [True: 0, False: 2.33k]
|
57 | 0 | return 0; |
58 | 0 | } |
59 | | /* sequence length */ |
60 | 2.33k | ptrdiff_t len = seckey[lenb-1] | (lenb > 1 ? seckey[lenb-2] << 8 : 0u); Branch (60:39): [True: 64, False: 2.27k]
|
61 | 2.33k | seckey += lenb; |
62 | 2.33k | if (end - seckey < len) { Branch (62:9): [True: 16, False: 2.31k]
|
63 | 16 | return 0; |
64 | 16 | } |
65 | | /* sequence element 0: version number (=1) */ |
66 | 2.31k | if (end - seckey < 3 || seckey[0] != 0x02u || seckey[1] != 0x01u || seckey[2] != 0x01u) { Branch (66:9): [True: 0, False: 2.31k]
Branch (66:29): [True: 7, False: 2.31k]
Branch (66:51): [True: 5, False: 2.30k]
Branch (66:73): [True: 5, False: 2.30k]
|
67 | 17 | return 0; |
68 | 17 | } |
69 | 2.30k | seckey += 3; |
70 | | /* sequence element 1: octet string, up to 32 bytes */ |
71 | 2.30k | if (end - seckey < 2 || seckey[0] != 0x04u) { Branch (71:9): [True: 0, False: 2.30k]
Branch (71:29): [True: 3, False: 2.29k]
|
72 | 3 | return 0; |
73 | 3 | } |
74 | 2.29k | ptrdiff_t oslen = seckey[1]; |
75 | 2.29k | seckey += 2; |
76 | 2.29k | if (oslen > 32 || end - seckey < oslen) { Branch (76:9): [True: 6, False: 2.29k]
Branch (76:23): [True: 0, False: 2.29k]
|
77 | 6 | return 0; |
78 | 6 | } |
79 | 2.29k | memcpy(out32 + (32 - oslen), seckey, oslen); |
80 | 2.29k | if (!secp256k1_ec_seckey_verify(ctx, out32)) { Branch (80:9): [True: 7, False: 2.28k]
|
81 | 7 | memset(out32, 0, 32); |
82 | 7 | return 0; |
83 | 7 | } |
84 | 2.28k | return 1; |
85 | 2.29k | } |
86 | | |
87 | | /** |
88 | | * This serializes to a DER encoding of the ECPrivateKey type from section C.4 of SEC 1 |
89 | | * <https://www.secg.org/sec1-v2.pdf>. The optional parameters and publicKey fields are |
90 | | * included. |
91 | | * |
92 | | * seckey must point to an output buffer of length at least CKey::SIZE bytes. |
93 | | * seckeylen must initially be set to the size of the seckey buffer. Upon return it |
94 | | * will be set to the number of bytes used in the buffer. |
95 | | * key32 must point to a 32-byte raw private key. |
96 | | */ |
97 | 51.6k | int ec_seckey_export_der(const secp256k1_context *ctx, unsigned char *seckey, size_t *seckeylen, const unsigned char *key32, bool compressed) { |
98 | 51.6k | assert(*seckeylen >= CKey::SIZE); Branch (98:5): [True: 51.6k, False: 0]
|
99 | 51.6k | secp256k1_pubkey pubkey; |
100 | 51.6k | size_t pubkeylen = 0; |
101 | 51.6k | if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { Branch (101:9): [True: 24, False: 51.6k]
|
102 | 24 | *seckeylen = 0; |
103 | 24 | return 0; |
104 | 24 | } |
105 | 51.6k | if (compressed) { Branch (105:9): [True: 50.5k, False: 1.11k]
|
106 | 50.5k | static const unsigned char begin[] = { |
107 | 50.5k | 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20 |
108 | 50.5k | }; |
109 | 50.5k | static const unsigned char middle[] = { |
110 | 50.5k | 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, |
111 | 50.5k | 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
112 | 50.5k | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
113 | 50.5k | 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, |
114 | 50.5k | 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, |
115 | 50.5k | 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, |
116 | 50.5k | 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
117 | 50.5k | 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, |
118 | 50.5k | 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00 |
119 | 50.5k | }; |
120 | 50.5k | unsigned char *ptr = seckey; |
121 | 50.5k | memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); |
122 | 50.5k | memcpy(ptr, key32, 32); ptr += 32; |
123 | 50.5k | memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); |
124 | 50.5k | pubkeylen = CPubKey::COMPRESSED_SIZE; |
125 | 50.5k | secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); |
126 | 50.5k | ptr += pubkeylen; |
127 | 50.5k | *seckeylen = ptr - seckey; |
128 | 50.5k | assert(*seckeylen == CKey::COMPRESSED_SIZE); Branch (128:9): [True: 50.5k, False: 0]
|
129 | 50.5k | } else { |
130 | 1.11k | static const unsigned char begin[] = { |
131 | 1.11k | 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 |
132 | 1.11k | }; |
133 | 1.11k | static const unsigned char middle[] = { |
134 | 1.11k | 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, |
135 | 1.11k | 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
136 | 1.11k | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
137 | 1.11k | 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, |
138 | 1.11k | 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, |
139 | 1.11k | 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, |
140 | 1.11k | 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11, |
141 | 1.11k | 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10, |
142 | 1.11k | 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
143 | 1.11k | 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, |
144 | 1.11k | 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00 |
145 | 1.11k | }; |
146 | 1.11k | unsigned char *ptr = seckey; |
147 | 1.11k | memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); |
148 | 1.11k | memcpy(ptr, key32, 32); ptr += 32; |
149 | 1.11k | memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); |
150 | 1.11k | pubkeylen = CPubKey::SIZE; |
151 | 1.11k | secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); |
152 | 1.11k | ptr += pubkeylen; |
153 | 1.11k | *seckeylen = ptr - seckey; |
154 | 1.11k | assert(*seckeylen == CKey::SIZE); Branch (154:9): [True: 1.11k, False: 0]
|
155 | 1.11k | } |
156 | 51.6k | return 1; |
157 | 51.6k | } |
158 | | |
159 | 3.03M | bool CKey::Check(const unsigned char *vch) { |
160 | 3.03M | return secp256k1_ec_seckey_verify(secp256k1_context_static, vch); |
161 | 3.03M | } |
162 | | |
163 | 52.3k | void CKey::MakeNewKey(bool fCompressedIn) { |
164 | 52.3k | MakeKeyData(); |
165 | 52.3k | do { |
166 | 52.3k | GetStrongRandBytes(*keydata); |
167 | 52.3k | } while (!Check(keydata->data())); Branch (167:14): [True: 0, False: 52.3k]
|
168 | 52.3k | fCompressed = fCompressedIn; |
169 | 52.3k | } |
170 | | |
171 | 51.5k | CPrivKey CKey::GetPrivKey() const { |
172 | 51.5k | assert(keydata); Branch (172:5): [True: 51.5k, False: 0]
|
173 | 51.5k | CPrivKey seckey; |
174 | 51.5k | int ret; |
175 | 51.5k | size_t seckeylen; |
176 | 51.5k | seckey.resize(SIZE); |
177 | 51.5k | seckeylen = SIZE; |
178 | 51.5k | ret = ec_seckey_export_der(secp256k1_context_sign, seckey.data(), &seckeylen, UCharCast(begin()), fCompressed); |
179 | 51.5k | assert(ret); Branch (179:5): [True: 51.5k, False: 0]
|
180 | 51.5k | seckey.resize(seckeylen); |
181 | 51.5k | return seckey; |
182 | 51.5k | } |
183 | | |
184 | 7.80M | CPubKey CKey::GetPubKey() const { |
185 | 7.80M | assert(keydata); Branch (185:5): [True: 7.80M, False: 0]
|
186 | 7.80M | secp256k1_pubkey pubkey; |
187 | 7.80M | size_t clen = CPubKey::SIZE; |
188 | 7.80M | CPubKey result; |
189 | 7.80M | int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, UCharCast(begin())); |
190 | 7.80M | assert(ret); Branch (190:5): [True: 7.80M, False: 0]
|
191 | 7.80M | secp256k1_ec_pubkey_serialize(secp256k1_context_static, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); Branch (191:109): [True: 7.75M, False: 51.2k]
|
192 | 7.80M | assert(result.size() == clen); Branch (192:5): [True: 7.80M, False: 0]
|
193 | 7.80M | assert(result.IsValid()); Branch (193:5): [True: 7.80M, False: 0]
|
194 | 7.80M | return result; |
195 | 7.80M | } |
196 | | |
197 | | // Check that the sig has a low R value and will be less than 71 bytes |
198 | | bool SigHasLowR(const secp256k1_ecdsa_signature* sig) |
199 | 299k | { |
200 | 299k | unsigned char compact_sig[64]; |
201 | 299k | secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_static, compact_sig, sig); |
202 | | |
203 | | // In DER serialization, all values are interpreted as big-endian, signed integers. The highest bit in the integer indicates |
204 | | // its signed-ness; 0 is positive, 1 is negative. When the value is interpreted as a negative integer, it must be converted |
205 | | // to a positive value by prepending a 0x00 byte so that the highest bit is 0. We can avoid this prepending by ensuring that |
206 | | // our highest bit is always 0, and thus we must check that the first byte is less than 0x80. |
207 | 299k | return compact_sig[0] < 0x80; |
208 | 299k | } |
209 | | |
210 | 136k | bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool grind, uint32_t test_case) const { |
211 | 136k | if (!keydata) Branch (211:9): [True: 354, False: 135k]
|
212 | 354 | return false; |
213 | 135k | vchSig.resize(CPubKey::SIGNATURE_SIZE); |
214 | 135k | size_t nSigLen = CPubKey::SIGNATURE_SIZE; |
215 | 135k | unsigned char extra_entropy[32] = {0}; |
216 | 135k | WriteLE32(extra_entropy, test_case); |
217 | 135k | secp256k1_ecdsa_signature sig; |
218 | 135k | uint32_t counter = 0; |
219 | 135k | int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, (!grind && test_case) ? extra_entropy : nullptr); Branch (219:135): [True: 1.10k, False: 134k]
Branch (219:145): [True: 0, False: 1.10k]
|
220 | | |
221 | | // Grind for low R |
222 | 299k | while (ret && !SigHasLowR(&sig) && grind) { Branch (222:12): [True: 299k, False: 0]
Branch (222:19): [True: 163k, False: 135k]
Branch (222:40): [True: 163k, False: 580]
|
223 | 163k | WriteLE32(extra_entropy, ++counter); |
224 | 163k | ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, extra_entropy); |
225 | 163k | } |
226 | 135k | assert(ret); Branch (226:5): [True: 135k, False: 0]
|
227 | 135k | secp256k1_ecdsa_signature_serialize_der(secp256k1_context_static, vchSig.data(), &nSigLen, &sig); |
228 | 135k | vchSig.resize(nSigLen); |
229 | | // Additional verification step to prevent using a potentially corrupted signature |
230 | 135k | secp256k1_pubkey pk; |
231 | 135k | ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pk, UCharCast(begin())); |
232 | 135k | assert(ret); Branch (232:5): [True: 135k, False: 0]
|
233 | 135k | ret = secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pk); |
234 | 135k | assert(ret); Branch (234:5): [True: 135k, False: 0]
|
235 | 135k | return true; |
236 | 135k | } |
237 | | |
238 | 27.7k | bool CKey::VerifyPubKey(const CPubKey& pubkey) const { |
239 | 27.7k | if (pubkey.IsCompressed() != fCompressed) { Branch (239:9): [True: 206, False: 27.5k]
|
240 | 206 | return false; |
241 | 206 | } |
242 | 27.5k | unsigned char rnd[8]; |
243 | 27.5k | std::string str = "Bitcoin key verification\n"; |
244 | 27.5k | GetRandBytes(rnd); |
245 | 27.5k | uint256 hash{Hash(str, rnd)}; |
246 | 27.5k | std::vector<unsigned char> vchSig; |
247 | 27.5k | Sign(hash, vchSig); |
248 | 27.5k | return pubkey.Verify(hash, vchSig); |
249 | 27.7k | } |
250 | | |
251 | 9.61k | bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const { |
252 | 9.61k | if (!keydata) Branch (252:9): [True: 154, False: 9.46k]
|
253 | 154 | return false; |
254 | 9.46k | vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE); |
255 | 9.46k | int rec = -1; |
256 | 9.46k | secp256k1_ecdsa_recoverable_signature rsig; |
257 | 9.46k | int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &rsig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, nullptr); |
258 | 9.46k | assert(ret); Branch (258:5): [True: 9.46k, False: 0]
|
259 | 9.46k | ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_static, &vchSig[1], &rec, &rsig); |
260 | 9.46k | assert(ret); Branch (260:5): [True: 9.46k, False: 0]
|
261 | 9.46k | assert(rec != -1); Branch (261:5): [True: 9.46k, False: 0]
|
262 | 9.46k | vchSig[0] = 27 + rec + (fCompressed ? 4 : 0); Branch (262:29): [True: 7.56k, False: 1.89k]
|
263 | | // Additional verification step to prevent using a potentially corrupted signature |
264 | 9.46k | secp256k1_pubkey epk, rpk; |
265 | 9.46k | ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &epk, UCharCast(begin())); |
266 | 9.46k | assert(ret); Branch (266:5): [True: 9.46k, False: 0]
|
267 | 9.46k | ret = secp256k1_ecdsa_recover(secp256k1_context_static, &rpk, &rsig, hash.begin()); |
268 | 9.46k | assert(ret); Branch (268:5): [True: 9.46k, False: 0]
|
269 | 9.46k | ret = secp256k1_ec_pubkey_cmp(secp256k1_context_static, &epk, &rpk); |
270 | 9.46k | assert(ret == 0); Branch (270:5): [True: 9.46k, False: 0]
|
271 | 9.46k | return true; |
272 | 9.46k | } |
273 | | |
274 | | bool CKey::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const |
275 | 20.4k | { |
276 | 20.4k | KeyPair kp = ComputeKeyPair(merkle_root); |
277 | 20.4k | return kp.SignSchnorr(hash, sig, aux); |
278 | 20.4k | } |
279 | | |
280 | 2.20k | bool CKey::Load(const CPrivKey &seckey, const CPubKey &vchPubKey, bool fSkipCheck=false) { |
281 | 2.20k | MakeKeyData(); |
282 | 2.20k | if (!ec_seckey_import_der(secp256k1_context_static, (unsigned char*)begin(), seckey.data(), seckey.size())) { Branch (282:9): [True: 0, False: 2.20k]
|
283 | 0 | ClearKeyData(); |
284 | 0 | return false; |
285 | 0 | } |
286 | 2.20k | fCompressed = vchPubKey.IsCompressed(); |
287 | | |
288 | 2.20k | if (fSkipCheck) Branch (288:9): [True: 1.10k, False: 1.10k]
|
289 | 1.10k | return true; |
290 | | |
291 | 1.10k | return VerifyPubKey(vchPubKey); |
292 | 2.20k | } |
293 | | |
294 | 2.60M | bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const { |
295 | 2.60M | assert(IsValid()); Branch (295:5): [True: 2.60M, False: 0]
|
296 | 2.60M | assert(IsCompressed()); Branch (296:5): [True: 2.60M, False: 0]
|
297 | 2.60M | std::vector<unsigned char, secure_allocator<unsigned char>> vout(64); |
298 | 2.60M | if ((nChild >> 31) == 0) { Branch (298:9): [True: 1.25M, False: 1.35M]
|
299 | 1.25M | CPubKey pubkey = GetPubKey(); |
300 | 1.25M | assert(pubkey.size() == CPubKey::COMPRESSED_SIZE); Branch (300:9): [True: 1.25M, False: 0]
|
301 | 1.25M | BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin()+1, vout.data()); |
302 | 1.35M | } else { |
303 | 1.35M | assert(size() == 32); Branch (303:9): [True: 1.35M, False: 0]
|
304 | 1.35M | BIP32Hash(cc, nChild, 0, UCharCast(begin()), vout.data()); |
305 | 1.35M | } |
306 | 2.60M | memcpy(ccChild.begin(), vout.data()+32, 32); |
307 | 2.60M | keyChild.Set(begin(), begin() + 32, true); |
308 | 2.60M | bool ret = secp256k1_ec_seckey_tweak_add(secp256k1_context_static, (unsigned char*)keyChild.begin(), vout.data()); |
309 | 2.60M | if (!ret) keyChild.ClearKeyData(); Branch (309:9): [True: 0, False: 2.60M]
|
310 | 2.60M | return ret; |
311 | 2.60M | } |
312 | | |
313 | | EllSwiftPubKey CKey::EllSwiftCreate(std::span<const std::byte> ent32) const |
314 | 66.2k | { |
315 | 66.2k | assert(keydata); Branch (315:5): [True: 66.2k, False: 0]
|
316 | 66.2k | assert(ent32.size() == 32); Branch (316:5): [True: 66.2k, False: 0]
|
317 | 66.2k | std::array<std::byte, EllSwiftPubKey::size()> encoded_pubkey; |
318 | | |
319 | 66.2k | auto success = secp256k1_ellswift_create(secp256k1_context_sign, |
320 | 66.2k | UCharCast(encoded_pubkey.data()), |
321 | 66.2k | keydata->data(), |
322 | 66.2k | UCharCast(ent32.data())); |
323 | | |
324 | | // Should always succeed for valid keys (asserted above). |
325 | 66.2k | assert(success); Branch (325:5): [True: 66.2k, False: 0]
|
326 | 66.2k | return {encoded_pubkey}; |
327 | 66.2k | } |
328 | | |
329 | | ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, const EllSwiftPubKey& our_ellswift, bool initiating) const |
330 | 22.2k | { |
331 | 22.2k | assert(keydata); Branch (331:5): [True: 22.2k, False: 0]
|
332 | | |
333 | 22.2k | ECDHSecret output; |
334 | | // BIP324 uses the initiator as party A, and the responder as party B. Remap the inputs |
335 | | // accordingly: |
336 | 22.2k | bool success = secp256k1_ellswift_xdh(secp256k1_context_static, |
337 | 22.2k | UCharCast(output.data()), |
338 | 22.2k | UCharCast(initiating ? our_ellswift.data() : their_ellswift.data()), Branch (338:53): [True: 6.21k, False: 16.0k]
|
339 | 22.2k | UCharCast(initiating ? their_ellswift.data() : our_ellswift.data()), Branch (339:53): [True: 6.21k, False: 16.0k]
|
340 | 22.2k | keydata->data(), |
341 | 22.2k | initiating ? 0 : 1, Branch (341:43): [True: 6.21k, False: 16.0k]
|
342 | 22.2k | secp256k1_ellswift_xdh_hash_function_bip324, |
343 | 22.2k | nullptr); |
344 | | // Should always succeed for valid keys (assert above). |
345 | 22.2k | assert(success); Branch (345:5): [True: 22.2k, False: 0]
|
346 | 22.2k | return output; |
347 | 22.2k | } |
348 | | |
349 | | KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const |
350 | 20.4k | { |
351 | 20.4k | return KeyPair(*this, merkle_root); |
352 | 20.4k | } |
353 | | |
354 | | CKey GenerateRandomKey(bool compressed) noexcept |
355 | 52.3k | { |
356 | 52.3k | CKey key; |
357 | 52.3k | key.MakeNewKey(/*fCompressed=*/compressed); |
358 | 52.3k | return key; |
359 | 52.3k | } |
360 | | |
361 | 2.60M | bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const { |
362 | 2.60M | if (nDepth == std::numeric_limits<unsigned char>::max()) return false; Branch (362:9): [True: 0, False: 2.60M]
|
363 | 2.60M | out.nDepth = nDepth + 1; |
364 | 2.60M | out.fingerprint = id_key_fingerprint(); |
365 | 2.60M | out.nChild = _nChild; |
366 | 2.60M | return key.Derive(out.key, out.chaincode, _nChild, chaincode); |
367 | 2.60M | } |
368 | | |
369 | | std::optional<std::pair<CExtKey, KeyOriginInfo>> DeriveExtKey(const CExtKey& ext_key, const std::vector<uint32_t>& path) |
370 | 0 | { |
371 | 0 | CExtKey descendant = ext_key; |
372 | 0 | KeyOriginInfo origin; |
373 | 0 | origin.fingerprint = ext_key.id_key_fingerprint(); |
374 | 0 | origin.path = path; |
375 | 0 | for (uint32_t i : path) { Branch (375:21): [True: 0, False: 0]
|
376 | 0 | if (!descendant.Derive(descendant, i)) return std::nullopt; Branch (376:13): [True: 0, False: 0]
|
377 | 0 | } |
378 | 0 | return std::make_pair(descendant, origin); |
379 | 0 | } |
380 | | |
381 | | void CExtKey::SetSeed(std::span<const std::byte> seed) |
382 | 1.76k | { |
383 | 1.76k | Assert(16 <= seed.size() && seed.size() <= 64); |
384 | 1.76k | static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'}; |
385 | 1.76k | std::vector<unsigned char, secure_allocator<unsigned char>> vout(64); |
386 | 1.76k | CHMAC_SHA512{hashkey, sizeof(hashkey)}.Write(UCharCast(seed.data()), seed.size()).Finalize(vout.data()); |
387 | 1.76k | key.Set(vout.data(), vout.data() + 32, true); |
388 | 1.76k | memcpy(chaincode.begin(), vout.data() + 32, 32); |
389 | 1.76k | nDepth = 0; |
390 | 1.76k | nChild = 0; |
391 | 1.76k | fingerprint.fill(0); |
392 | 1.76k | } |
393 | | |
394 | 2.41M | CExtPubKey CExtKey::Neuter() const { |
395 | 2.41M | CExtPubKey ret; |
396 | 2.41M | ret.nDepth = nDepth; |
397 | 2.41M | ret.fingerprint = fingerprint; |
398 | 2.41M | ret.nChild = nChild; |
399 | 2.41M | ret.pubkey = key.GetPubKey(); |
400 | 2.41M | ret.chaincode = chaincode; |
401 | 2.41M | return ret; |
402 | 2.41M | } |
403 | | |
404 | 844k | void CExtKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const { |
405 | 844k | code[0] = nDepth; |
406 | 844k | std::ranges::copy(fingerprint, code+1); |
407 | 844k | WriteBE32(code+5, nChild); |
408 | 844k | memcpy(code+9, chaincode.begin(), 32); |
409 | 844k | code[41] = 0; |
410 | 844k | assert(key.size() == 32); Branch (410:5): [True: 844k, False: 0]
|
411 | 844k | memcpy(code+42, key.begin(), 32); |
412 | 844k | } |
413 | | |
414 | 188k | void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) { |
415 | 188k | nDepth = code[0]; |
416 | 188k | std::copy_n(code + 1, fingerprint.size(), fingerprint.begin()); |
417 | 188k | nChild = ReadBE32(code+5); |
418 | 188k | memcpy(chaincode.begin(), code+9, 32); |
419 | 188k | key.Set(code+42, code+BIP32_EXTKEY_SIZE, true); |
420 | 188k | if ((nDepth == 0 && (nChild != 0 || ReadLE32(fingerprint.data()) != 0)) || code[41] != 0) key = CKey(); Branch (420:10): [True: 165k, False: 23.5k]
Branch (420:26): [True: 0, False: 165k]
Branch (420:41): [True: 0, False: 165k]
Branch (420:80): [True: 0, False: 188k]
|
421 | 188k | } |
422 | | |
423 | | KeyPair::KeyPair(const CKey& key, const uint256* merkle_root) |
424 | 20.4k | { |
425 | 20.4k | static_assert(std::tuple_size<KeyType>() == sizeof(secp256k1_keypair)); |
426 | 20.4k | MakeKeyPairData(); |
427 | 20.4k | auto keypair = reinterpret_cast<secp256k1_keypair*>(m_keypair->data()); |
428 | 20.4k | bool success = secp256k1_keypair_create(secp256k1_context_sign, keypair, UCharCast(key.data())); |
429 | 20.4k | if (success && merkle_root) { Branch (429:9): [True: 20.4k, False: 0]
Branch (429:20): [True: 20.4k, False: 0]
|
430 | 20.4k | secp256k1_xonly_pubkey pubkey; |
431 | 20.4k | unsigned char pubkey_bytes[32]; |
432 | 20.4k | assert(secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey, nullptr, keypair)); Branch (432:9): [True: 20.4k, False: 0]
|
433 | 20.4k | assert(secp256k1_xonly_pubkey_serialize(secp256k1_context_static, pubkey_bytes, &pubkey)); Branch (433:9): [True: 20.4k, False: 0]
|
434 | 20.4k | uint256 tweak = XOnlyPubKey(pubkey_bytes).ComputeTapTweakHash(merkle_root->IsNull() ? nullptr : merkle_root); Branch (434:71): [True: 20.4k, False: 0]
|
435 | 20.4k | success = secp256k1_keypair_xonly_tweak_add(secp256k1_context_static, keypair, tweak.data()); |
436 | 20.4k | } |
437 | 20.4k | if (!success) ClearKeyPairData(); Branch (437:9): [True: 0, False: 20.4k]
|
438 | 20.4k | } |
439 | | |
440 | | bool KeyPair::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256& aux) const |
441 | 20.4k | { |
442 | 20.4k | assert(sig.size() == 64); Branch (442:5): [True: 20.4k, False: 0]
|
443 | 20.4k | if (!IsValid()) return false; Branch (443:9): [True: 0, False: 20.4k]
|
444 | 20.4k | auto keypair = reinterpret_cast<const secp256k1_keypair*>(m_keypair->data()); |
445 | 20.4k | bool ret = secp256k1_schnorrsig_sign32(secp256k1_context_sign, sig.data(), hash.data(), keypair, aux.data()); |
446 | 20.4k | if (ret) { Branch (446:9): [True: 20.4k, False: 0]
|
447 | | // Additional verification step to prevent using a potentially corrupted signature |
448 | 20.4k | secp256k1_xonly_pubkey pubkey_verify; |
449 | 20.4k | ret = secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey_verify, nullptr, keypair); |
450 | 20.4k | ret &= secp256k1_schnorrsig_verify(secp256k1_context_static, sig.data(), hash.begin(), 32, &pubkey_verify); |
451 | 20.4k | } |
452 | 20.4k | if (!ret) memory_cleanse(sig.data(), sig.size()); Branch (452:9): [True: 0, False: 20.4k]
|
453 | 20.4k | return ret; |
454 | 20.4k | } |
455 | | |
456 | 0 | bool ECC_InitSanityCheck() { |
457 | 0 | CKey key = GenerateRandomKey(); |
458 | 0 | CPubKey pubkey = key.GetPubKey(); |
459 | 0 | return key.VerifyPubKey(pubkey); |
460 | 0 | } |
461 | | |
462 | | secp256k1_context* GetSecp256k1SignContext() |
463 | 0 | { |
464 | 0 | return secp256k1_context_sign; |
465 | 0 | } |
466 | | |
467 | | /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */ |
468 | 2.09k | static void ECC_Start() { |
469 | 2.09k | assert(secp256k1_context_sign == nullptr); Branch (469:5): [True: 2.09k, False: 0]
|
470 | | |
471 | 2.09k | secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); |
472 | 2.09k | assert(ctx != nullptr); Branch (472:5): [True: 2.09k, False: 0]
|
473 | | |
474 | 2.09k | { |
475 | | // Pass in a random blinding seed to the secp256k1 context. |
476 | 2.09k | std::vector<unsigned char, secure_allocator<unsigned char>> vseed(32); |
477 | 2.09k | GetRandBytes(vseed); |
478 | 2.09k | bool ret = secp256k1_context_randomize(ctx, vseed.data()); |
479 | 2.09k | assert(ret); Branch (479:9): [True: 2.09k, False: 0]
|
480 | 2.09k | } |
481 | | |
482 | 2.09k | secp256k1_context_sign = ctx; |
483 | 2.09k | } |
484 | | |
485 | | /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */ |
486 | 2.21k | static void ECC_Stop() { |
487 | 2.21k | secp256k1_context *ctx = secp256k1_context_sign; |
488 | 2.21k | secp256k1_context_sign = nullptr; |
489 | | |
490 | 2.21k | if (ctx) { Branch (490:9): [True: 2.21k, False: 0]
|
491 | 2.21k | secp256k1_context_destroy(ctx); |
492 | 2.21k | } |
493 | 2.21k | } |
494 | | |
495 | | ECC_Context::ECC_Context() |
496 | 2.09k | { |
497 | 2.09k | ECC_Start(); |
498 | 2.09k | } |
499 | | |
500 | | ECC_Context::~ECC_Context() |
501 | 2.21k | { |
502 | 2.21k | ECC_Stop(); |
503 | 2.21k | } |