Coverage Report

Created: 2024-08-21 05:08

/workdir/bitcoin/src/pubkey.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2009-2022 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 <pubkey.h>
7
8
#include <hash.h>
9
#include <secp256k1.h>
10
#include <secp256k1_ellswift.h>
11
#include <secp256k1_extrakeys.h>
12
#include <secp256k1_recovery.h>
13
#include <secp256k1_schnorrsig.h>
14
#include <span.h>
15
#include <uint256.h>
16
#include <util/strencodings.h>
17
18
#include <algorithm>
19
#include <cassert>
20
21
namespace {
22
23
struct Secp256k1SelfTester
24
{
25
0
    Secp256k1SelfTester() {
26
        /* Run libsecp256k1 self-test before using the secp256k1_context_static. */
27
0
        secp256k1_selftest();
28
0
    }
29
} SECP256K1_SELFTESTER;
30
31
} // namespace
32
33
/** This function is taken from the libsecp256k1 distribution and implements
34
 *  DER parsing for ECDSA signatures, while supporting an arbitrary subset of
35
 *  format violations.
36
 *
37
 *  Supported violations include negative integers, excessive padding, garbage
38
 *  at the end, and overly long length descriptors. This is safe to use in
39
 *  Bitcoin because since the activation of BIP66, signatures are verified to be
40
 *  strict DER before being passed to this module, and we know it supports all
41
 *  violations present in the blockchain before that point.
42
 */
43
0
int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
44
0
    size_t rpos, rlen, spos, slen;
45
0
    size_t pos = 0;
46
0
    size_t lenbyte;
47
0
    unsigned char tmpsig[64] = {0};
48
0
    int overflow = 0;
49
50
    /* Hack to initialize sig with a correctly-parsed but invalid signature. */
51
0
    secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
52
53
    /* Sequence tag byte */
54
0
    if (pos == inputlen || input[pos] != 0x30) {
  Branch (54:9): [True: 0, False: 0]
  Branch (54:28): [True: 0, False: 0]
55
0
        return 0;
56
0
    }
57
0
    pos++;
58
59
    /* Sequence length bytes */
60
0
    if (pos == inputlen) {
  Branch (60:9): [True: 0, False: 0]
61
0
        return 0;
62
0
    }
63
0
    lenbyte = input[pos++];
64
0
    if (lenbyte & 0x80) {
  Branch (64:9): [True: 0, False: 0]
65
0
        lenbyte -= 0x80;
66
0
        if (lenbyte > inputlen - pos) {
  Branch (66:13): [True: 0, False: 0]
67
0
            return 0;
68
0
        }
69
0
        pos += lenbyte;
70
0
    }
71
72
    /* Integer tag byte for R */
73
0
    if (pos == inputlen || input[pos] != 0x02) {
  Branch (73:9): [True: 0, False: 0]
  Branch (73:28): [True: 0, False: 0]
74
0
        return 0;
75
0
    }
76
0
    pos++;
77
78
    /* Integer length for R */
79
0
    if (pos == inputlen) {
  Branch (79:9): [True: 0, False: 0]
80
0
        return 0;
81
0
    }
82
0
    lenbyte = input[pos++];
83
0
    if (lenbyte & 0x80) {
  Branch (83:9): [True: 0, False: 0]
84
0
        lenbyte -= 0x80;
85
0
        if (lenbyte > inputlen - pos) {
  Branch (85:13): [True: 0, False: 0]
86
0
            return 0;
87
0
        }
88
0
        while (lenbyte > 0 && input[pos] == 0) {
  Branch (88:16): [True: 0, False: 0]
  Branch (88:31): [True: 0, False: 0]
89
0
            pos++;
90
0
            lenbyte--;
91
0
        }
92
0
        static_assert(sizeof(size_t) >= 4, "size_t too small");
93
0
        if (lenbyte >= 4) {
  Branch (93:13): [True: 0, False: 0]
94
0
            return 0;
95
0
        }
96
0
        rlen = 0;
97
0
        while (lenbyte > 0) {
  Branch (97:16): [True: 0, False: 0]
98
0
            rlen = (rlen << 8) + input[pos];
99
0
            pos++;
100
0
            lenbyte--;
101
0
        }
102
0
    } else {
103
0
        rlen = lenbyte;
104
0
    }
105
0
    if (rlen > inputlen - pos) {
  Branch (105:9): [True: 0, False: 0]
106
0
        return 0;
107
0
    }
108
0
    rpos = pos;
109
0
    pos += rlen;
110
111
    /* Integer tag byte for S */
112
0
    if (pos == inputlen || input[pos] != 0x02) {
  Branch (112:9): [True: 0, False: 0]
  Branch (112:28): [True: 0, False: 0]
113
0
        return 0;
114
0
    }
115
0
    pos++;
116
117
    /* Integer length for S */
118
0
    if (pos == inputlen) {
  Branch (118:9): [True: 0, False: 0]
119
0
        return 0;
120
0
    }
121
0
    lenbyte = input[pos++];
122
0
    if (lenbyte & 0x80) {
  Branch (122:9): [True: 0, False: 0]
123
0
        lenbyte -= 0x80;
124
0
        if (lenbyte > inputlen - pos) {
  Branch (124:13): [True: 0, False: 0]
125
0
            return 0;
126
0
        }
127
0
        while (lenbyte > 0 && input[pos] == 0) {
  Branch (127:16): [True: 0, False: 0]
  Branch (127:31): [True: 0, False: 0]
128
0
            pos++;
129
0
            lenbyte--;
130
0
        }
131
0
        static_assert(sizeof(size_t) >= 4, "size_t too small");
132
0
        if (lenbyte >= 4) {
  Branch (132:13): [True: 0, False: 0]
133
0
            return 0;
134
0
        }
135
0
        slen = 0;
136
0
        while (lenbyte > 0) {
  Branch (136:16): [True: 0, False: 0]
137
0
            slen = (slen << 8) + input[pos];
138
0
            pos++;
139
0
            lenbyte--;
140
0
        }
141
0
    } else {
142
0
        slen = lenbyte;
143
0
    }
144
0
    if (slen > inputlen - pos) {
  Branch (144:9): [True: 0, False: 0]
145
0
        return 0;
146
0
    }
147
0
    spos = pos;
148
149
    /* Ignore leading zeroes in R */
150
0
    while (rlen > 0 && input[rpos] == 0) {
  Branch (150:12): [True: 0, False: 0]
  Branch (150:24): [True: 0, False: 0]
151
0
        rlen--;
152
0
        rpos++;
153
0
    }
154
    /* Copy R value */
155
0
    if (rlen > 32) {
  Branch (155:9): [True: 0, False: 0]
156
0
        overflow = 1;
157
0
    } else {
158
0
        memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
159
0
    }
160
161
    /* Ignore leading zeroes in S */
162
0
    while (slen > 0 && input[spos] == 0) {
  Branch (162:12): [True: 0, False: 0]
  Branch (162:24): [True: 0, False: 0]
163
0
        slen--;
164
0
        spos++;
165
0
    }
166
    /* Copy S value */
167
0
    if (slen > 32) {
  Branch (167:9): [True: 0, False: 0]
168
0
        overflow = 1;
169
0
    } else {
170
0
        memcpy(tmpsig + 64 - slen, input + spos, slen);
171
0
    }
172
173
0
    if (!overflow) {
  Branch (173:9): [True: 0, False: 0]
174
0
        overflow = !secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
175
0
    }
176
0
    if (overflow) {
  Branch (176:9): [True: 0, False: 0]
177
        /* Overwrite the result again with a correctly-parsed but invalid
178
           signature if parsing failed. */
179
0
        memset(tmpsig, 0, 64);
180
0
        secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
181
0
    }
182
0
    return 1;
183
0
}
184
185
/** Nothing Up My Sleeve (NUMS) point
186
 *
187
 *  NUMS_H is a point with an unknown discrete logarithm, constructed by taking the sha256 of 'g'
188
 *  (uncompressed encoding), which happens to be a point on the curve.
189
 *
190
 *  For an example script for calculating H, refer to the unit tests in
191
 *  ./test/functional/test_framework/crypto/secp256k1.py
192
 */
193
static const std::vector<unsigned char> NUMS_H_DATA{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")};
194
const XOnlyPubKey XOnlyPubKey::NUMS_H{NUMS_H_DATA};
195
196
XOnlyPubKey::XOnlyPubKey(Span<const unsigned char> bytes)
197
0
{
198
0
    assert(bytes.size() == 32);
199
0
    std::copy(bytes.begin(), bytes.end(), m_keydata.begin());
200
0
}
201
202
std::vector<CKeyID> XOnlyPubKey::GetKeyIDs() const
203
0
{
204
0
    std::vector<CKeyID> out;
205
    // For now, use the old full pubkey-based key derivation logic. As it is indexed by
206
    // Hash160(full pubkey), we need to return both a version prefixed with 0x02, and one
207
    // with 0x03.
208
0
    unsigned char b[33] = {0x02};
209
0
    std::copy(m_keydata.begin(), m_keydata.end(), b + 1);
210
0
    CPubKey fullpubkey;
211
0
    fullpubkey.Set(b, b + 33);
212
0
    out.push_back(fullpubkey.GetID());
213
0
    b[0] = 0x03;
214
0
    fullpubkey.Set(b, b + 33);
215
0
    out.push_back(fullpubkey.GetID());
216
0
    return out;
217
0
}
218
219
CPubKey XOnlyPubKey::GetEvenCorrespondingCPubKey() const
220
0
{
221
0
    unsigned char full_key[CPubKey::COMPRESSED_SIZE] = {0x02};
222
0
    std::copy(begin(), end(), full_key + 1);
223
0
    return CPubKey{full_key};
224
0
}
225
226
bool XOnlyPubKey::IsFullyValid() const
227
0
{
228
0
    secp256k1_xonly_pubkey pubkey;
229
0
    return secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data());
230
0
}
231
232
bool XOnlyPubKey::VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const
233
0
{
234
0
    assert(sigbytes.size() == 64);
235
0
    secp256k1_xonly_pubkey pubkey;
236
0
    if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data())) return false;
  Branch (236:9): [True: 0, False: 0]
237
0
    return secp256k1_schnorrsig_verify(secp256k1_context_static, sigbytes.data(), msg.begin(), 32, &pubkey);
238
0
}
239
240
static const HashWriter HASHER_TAPTWEAK{TaggedHash("TapTweak")};
241
242
uint256 XOnlyPubKey::ComputeTapTweakHash(const uint256* merkle_root) const
243
0
{
244
0
    if (merkle_root == nullptr) {
  Branch (244:9): [True: 0, False: 0]
245
        // We have no scripts. The actual tweak does not matter, but follow BIP341 here to
246
        // allow for reproducible tweaking.
247
0
        return (HashWriter{HASHER_TAPTWEAK} << m_keydata).GetSHA256();
248
0
    } else {
249
0
        return (HashWriter{HASHER_TAPTWEAK} << m_keydata << *merkle_root).GetSHA256();
250
0
    }
251
0
}
252
253
bool XOnlyPubKey::CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const
254
0
{
255
0
    secp256k1_xonly_pubkey internal_key;
256
0
    if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &internal_key, internal.data())) return false;
  Branch (256:9): [True: 0, False: 0]
257
0
    uint256 tweak = internal.ComputeTapTweakHash(&merkle_root);
258
0
    return secp256k1_xonly_pubkey_tweak_add_check(secp256k1_context_static, m_keydata.begin(), parity, &internal_key, tweak.begin());
259
0
}
260
261
std::optional<std::pair<XOnlyPubKey, bool>> XOnlyPubKey::CreateTapTweak(const uint256* merkle_root) const
262
0
{
263
0
    secp256k1_xonly_pubkey base_point;
264
0
    if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &base_point, data())) return std::nullopt;
  Branch (264:9): [True: 0, False: 0]
265
0
    secp256k1_pubkey out;
266
0
    uint256 tweak = ComputeTapTweakHash(merkle_root);
267
0
    if (!secp256k1_xonly_pubkey_tweak_add(secp256k1_context_static, &out, &base_point, tweak.data())) return std::nullopt;
  Branch (267:9): [True: 0, False: 0]
268
0
    int parity = -1;
269
0
    std::pair<XOnlyPubKey, bool> ret;
270
0
    secp256k1_xonly_pubkey out_xonly;
271
0
    if (!secp256k1_xonly_pubkey_from_pubkey(secp256k1_context_static, &out_xonly, &parity, &out)) return std::nullopt;
  Branch (271:9): [True: 0, False: 0]
272
0
    secp256k1_xonly_pubkey_serialize(secp256k1_context_static, ret.first.begin(), &out_xonly);
273
0
    assert(parity == 0 || parity == 1);
274
0
    ret.second = parity;
275
0
    return ret;
276
0
}
277
278
279
0
bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
280
0
    if (!IsValid())
  Branch (280:9): [True: 0, False: 0]
281
0
        return false;
282
0
    secp256k1_pubkey pubkey;
283
0
    secp256k1_ecdsa_signature sig;
284
0
    if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
  Branch (284:9): [True: 0, False: 0]
285
0
        return false;
286
0
    }
287
0
    if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) {
  Branch (287:9): [True: 0, False: 0]
288
0
        return false;
289
0
    }
290
    /* libsecp256k1's ECDSA verification requires lower-S signatures, which have
291
     * not historically been enforced in Bitcoin, so normalize them first. */
292
0
    secp256k1_ecdsa_signature_normalize(secp256k1_context_static, &sig, &sig);
293
0
    return secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey);
294
0
}
295
296
0
bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
297
0
    if (vchSig.size() != COMPACT_SIGNATURE_SIZE)
  Branch (297:9): [True: 0, False: 0]
298
0
        return false;
299
0
    int recid = (vchSig[0] - 27) & 3;
300
0
    bool fComp = ((vchSig[0] - 27) & 4) != 0;
301
0
    secp256k1_pubkey pubkey;
302
0
    secp256k1_ecdsa_recoverable_signature sig;
303
0
    if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_static, &sig, &vchSig[1], recid)) {
  Branch (303:9): [True: 0, False: 0]
304
0
        return false;
305
0
    }
306
0
    if (!secp256k1_ecdsa_recover(secp256k1_context_static, &pubkey, &sig, hash.begin())) {
  Branch (306:9): [True: 0, False: 0]
307
0
        return false;
308
0
    }
309
0
    unsigned char pub[SIZE];
310
0
    size_t publen = SIZE;
311
0
    secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
  Branch (311:84): [True: 0, False: 0]
312
0
    Set(pub, pub + publen);
313
0
    return true;
314
0
}
315
316
0
bool CPubKey::IsFullyValid() const {
317
0
    if (!IsValid())
  Branch (317:9): [True: 0, False: 0]
318
0
        return false;
319
0
    secp256k1_pubkey pubkey;
320
0
    return secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size());
321
0
}
322
323
0
bool CPubKey::Decompress() {
324
0
    if (!IsValid())
  Branch (324:9): [True: 0, False: 0]
325
0
        return false;
326
0
    secp256k1_pubkey pubkey;
327
0
    if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
  Branch (327:9): [True: 0, False: 0]
328
0
        return false;
329
0
    }
330
0
    unsigned char pub[SIZE];
331
0
    size_t publen = SIZE;
332
0
    secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
333
0
    Set(pub, pub + publen);
334
0
    return true;
335
0
}
336
337
0
bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
338
0
    assert(IsValid());
339
0
    assert((nChild >> 31) == 0);
340
0
    assert(size() == COMPRESSED_SIZE);
341
0
    unsigned char out[64];
342
0
    BIP32Hash(cc, nChild, *begin(), begin()+1, out);
343
0
    memcpy(ccChild.begin(), out+32, 32);
344
0
    secp256k1_pubkey pubkey;
345
0
    if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
  Branch (345:9): [True: 0, False: 0]
346
0
        return false;
347
0
    }
348
0
    if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_static, &pubkey, out)) {
  Branch (348:9): [True: 0, False: 0]
349
0
        return false;
350
0
    }
351
0
    unsigned char pub[COMPRESSED_SIZE];
352
0
    size_t publen = COMPRESSED_SIZE;
353
0
    secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
354
0
    pubkeyChild.Set(pub, pub + publen);
355
0
    return true;
356
0
}
357
358
EllSwiftPubKey::EllSwiftPubKey(Span<const std::byte> ellswift) noexcept
359
0
{
360
0
    assert(ellswift.size() == SIZE);
361
0
    std::copy(ellswift.begin(), ellswift.end(), m_pubkey.begin());
362
0
}
363
364
CPubKey EllSwiftPubKey::Decode() const
365
0
{
366
0
    secp256k1_pubkey pubkey;
367
0
    secp256k1_ellswift_decode(secp256k1_context_static, &pubkey, UCharCast(m_pubkey.data()));
368
369
0
    size_t sz = CPubKey::COMPRESSED_SIZE;
370
0
    std::array<uint8_t, CPubKey::COMPRESSED_SIZE> vch_bytes;
371
372
0
    secp256k1_ec_pubkey_serialize(secp256k1_context_static, vch_bytes.data(), &sz, &pubkey, SECP256K1_EC_COMPRESSED);
373
0
    assert(sz == vch_bytes.size());
374
375
0
    return CPubKey{vch_bytes.begin(), vch_bytes.end()};
376
0
}
377
378
0
void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
379
0
    code[0] = nDepth;
380
0
    memcpy(code+1, vchFingerprint, 4);
381
0
    WriteBE32(code+5, nChild);
382
0
    memcpy(code+9, chaincode.begin(), 32);
383
0
    assert(pubkey.size() == CPubKey::COMPRESSED_SIZE);
384
0
    memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_SIZE);
385
0
}
386
387
0
void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
388
0
    nDepth = code[0];
389
0
    memcpy(vchFingerprint, code+1, 4);
390
0
    nChild = ReadBE32(code+5);
391
0
    memcpy(chaincode.begin(), code+9, 32);
392
0
    pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
393
0
    if ((nDepth == 0 && (nChild != 0 || ReadLE32(vchFingerprint) != 0)) || !pubkey.IsFullyValid()) pubkey = CPubKey();
  Branch (393:10): [True: 0, False: 0]
  Branch (393:26): [True: 0, False: 0]
  Branch (393:41): [True: 0, False: 0]
  Branch (393:76): [True: 0, False: 0]
394
0
}
395
396
void CExtPubKey::EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const
397
0
{
398
0
    memcpy(code, version, 4);
399
0
    Encode(&code[4]);
400
0
}
401
402
void CExtPubKey::DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE])
403
0
{
404
0
    memcpy(version, code, 4);
405
0
    Decode(&code[4]);
406
0
}
407
408
0
bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
409
0
    if (nDepth == std::numeric_limits<unsigned char>::max()) return false;
  Branch (409:9): [True: 0, False: 0]
410
0
    out.nDepth = nDepth + 1;
411
0
    CKeyID id = pubkey.GetID();
412
0
    memcpy(out.vchFingerprint, &id, 4);
413
0
    out.nChild = _nChild;
414
0
    return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
415
0
}
416
417
0
/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
418
0
    secp256k1_ecdsa_signature sig;
419
0
    if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) {
  Branch (419:9): [True: 0, False: 0]
420
0
        return false;
421
0
    }
422
0
    return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_static, nullptr, &sig));
423
0
}