LCOV - code coverage report
Current view: top level - src - key.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 78.1 % 352 275
Test Date: 2025-10-25 04:38:23 Functions: 93.5 % 31 29
Branches: 39.6 % 356 141

             Branch data     Line data    Source code
       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                 :          18 : int ec_seckey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *seckey, size_t seckeylen) {
      40                 :          18 :     const unsigned char *end = seckey + seckeylen;
      41         [ +  - ]:          18 :     memset(out32, 0, 32);
      42                 :             :     /* sequence header */
      43   [ +  -  +  - ]:          18 :     if (end - seckey < 1 || *seckey != 0x30u) {
      44                 :             :         return 0;
      45                 :             :     }
      46                 :          18 :     seckey++;
      47                 :             :     /* sequence length constructor */
      48   [ +  -  +  - ]:          18 :     if (end - seckey < 1 || !(*seckey & 0x80u)) {
      49                 :             :         return 0;
      50                 :             :     }
      51                 :          18 :     ptrdiff_t lenb = *seckey & ~0x80u; seckey++;
      52         [ +  - ]:          18 :     if (lenb < 1 || lenb > 2) {
      53                 :             :         return 0;
      54                 :             :     }
      55         [ +  - ]:          18 :     if (end - seckey < lenb) {
      56                 :             :         return 0;
      57                 :             :     }
      58                 :             :     /* sequence length */
      59         [ -  + ]:          18 :     ptrdiff_t len = seckey[lenb-1] | (lenb > 1 ? seckey[lenb-2] << 8 : 0u);
      60                 :          18 :     seckey += lenb;
      61         [ +  - ]:          18 :     if (end - seckey < len) {
      62                 :             :         return 0;
      63                 :             :     }
      64                 :             :     /* sequence element 0: version number (=1) */
      65   [ +  -  +  -  :          18 :     if (end - seckey < 3 || seckey[0] != 0x02u || seckey[1] != 0x01u || seckey[2] != 0x01u) {
             +  -  +  - ]
      66                 :             :         return 0;
      67                 :             :     }
      68                 :          18 :     seckey += 3;
      69                 :             :     /* sequence element 1: octet string, up to 32 bytes */
      70   [ +  -  +  - ]:          18 :     if (end - seckey < 2 || seckey[0] != 0x04u) {
      71                 :             :         return 0;
      72                 :             :     }
      73                 :          18 :     ptrdiff_t oslen = seckey[1];
      74                 :          18 :     seckey += 2;
      75   [ +  -  +  - ]:          18 :     if (oslen > 32 || end - seckey < oslen) {
      76                 :             :         return 0;
      77                 :             :     }
      78                 :          18 :     memcpy(out32 + (32 - oslen), seckey, oslen);
      79         [ -  + ]:          18 :     if (!secp256k1_ec_seckey_verify(ctx, out32)) {
      80                 :           0 :         memset(out32, 0, 32);
      81                 :           0 :         return 0;
      82                 :             :     }
      83                 :             :     return 1;
      84                 :             : }
      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                 :         287 : int ec_seckey_export_der(const secp256k1_context *ctx, unsigned char *seckey, size_t *seckeylen, const unsigned char *key32, bool compressed) {
      97         [ -  + ]:         287 :     assert(*seckeylen >= CKey::SIZE);
      98                 :         287 :     secp256k1_pubkey pubkey;
      99                 :         287 :     size_t pubkeylen = 0;
     100         [ -  + ]:         287 :     if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) {
     101                 :           0 :         *seckeylen = 0;
     102                 :           0 :         return 0;
     103                 :             :     }
     104         [ +  + ]:         287 :     if (compressed) {
     105                 :         283 :         static const unsigned char begin[] = {
     106                 :             :             0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
     107                 :             :         };
     108                 :         283 :         static const unsigned char middle[] = {
     109                 :             :             0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
     110                 :             :             0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
     111                 :             :             0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
     112                 :             :             0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
     113                 :             :             0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
     114                 :             :             0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
     115                 :             :             0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
     116                 :             :             0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
     117                 :             :             0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00
     118                 :             :         };
     119                 :         283 :         unsigned char *ptr = seckey;
     120                 :         283 :         memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
     121                 :         283 :         memcpy(ptr, key32, 32); ptr += 32;
     122                 :         283 :         memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
     123                 :         283 :         pubkeylen = CPubKey::COMPRESSED_SIZE;
     124                 :         283 :         secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED);
     125                 :         283 :         ptr += pubkeylen;
     126                 :         283 :         *seckeylen = ptr - seckey;
     127         [ -  + ]:         283 :         assert(*seckeylen == CKey::COMPRESSED_SIZE);
     128                 :             :     } else {
     129                 :           4 :         static const unsigned char begin[] = {
     130                 :             :             0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20
     131                 :             :         };
     132                 :           4 :         static const unsigned char middle[] = {
     133                 :             :             0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
     134                 :             :             0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
     135                 :             :             0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
     136                 :             :             0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
     137                 :             :             0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
     138                 :             :             0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
     139                 :             :             0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11,
     140                 :             :             0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10,
     141                 :             :             0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
     142                 :             :             0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
     143                 :             :             0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00
     144                 :             :         };
     145                 :           4 :         unsigned char *ptr = seckey;
     146                 :           4 :         memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
     147                 :           4 :         memcpy(ptr, key32, 32); ptr += 32;
     148                 :           4 :         memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
     149                 :           4 :         pubkeylen = CPubKey::SIZE;
     150                 :           4 :         secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
     151                 :           4 :         ptr += pubkeylen;
     152                 :           4 :         *seckeylen = ptr - seckey;
     153         [ -  + ]:           4 :         assert(*seckeylen == CKey::SIZE);
     154                 :             :     }
     155                 :             :     return 1;
     156                 :             : }
     157                 :             : 
     158                 :        6833 : bool CKey::Check(const unsigned char *vch) {
     159                 :        6833 :     return secp256k1_ec_seckey_verify(secp256k1_context_static, vch);
     160                 :             : }
     161                 :             : 
     162                 :         221 : void CKey::MakeNewKey(bool fCompressedIn) {
     163                 :         221 :     MakeKeyData();
     164                 :         221 :     do {
     165                 :         221 :         GetStrongRandBytes(*keydata);
     166         [ -  + ]:         221 :     } while (!Check(keydata->data()));
     167                 :         221 :     fCompressed = fCompressedIn;
     168                 :         221 : }
     169                 :             : 
     170                 :         287 : CPrivKey CKey::GetPrivKey() const {
     171         [ -  + ]:         287 :     assert(keydata);
     172                 :         287 :     CPrivKey seckey;
     173                 :         287 :     int ret;
     174                 :         287 :     size_t seckeylen;
     175         [ +  - ]:         287 :     seckey.resize(SIZE);
     176                 :         287 :     seckeylen = SIZE;
     177   [ +  -  +  - ]:         574 :     ret = ec_seckey_export_der(secp256k1_context_sign, seckey.data(), &seckeylen, UCharCast(begin()), fCompressed);
     178         [ -  + ]:         287 :     assert(ret);
     179         [ +  - ]:         287 :     seckey.resize(seckeylen);
     180                 :         287 :     return seckey;
     181                 :           0 : }
     182                 :             : 
     183                 :       18517 : CPubKey CKey::GetPubKey() const {
     184         [ -  + ]:       18517 :     assert(keydata);
     185                 :       18517 :     secp256k1_pubkey pubkey;
     186                 :       18517 :     size_t clen = CPubKey::SIZE;
     187                 :       18517 :     CPubKey result;
     188                 :       18517 :     int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, UCharCast(begin()));
     189         [ -  + ]:       18517 :     assert(ret);
     190         [ +  + ]:       18593 :     secp256k1_ec_pubkey_serialize(secp256k1_context_static, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
     191         [ -  + ]:       18517 :     assert(result.size() == clen);
     192         [ -  + ]:       18517 :     assert(result.IsValid());
     193                 :       18517 :     return result;
     194                 :             : }
     195                 :             : 
     196                 :             : // Check that the sig has a low R value and will be less than 71 bytes
     197                 :       13819 : bool SigHasLowR(const secp256k1_ecdsa_signature* sig)
     198                 :             : {
     199                 :       13819 :     unsigned char compact_sig[64];
     200                 :       13819 :     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                 :       13819 :     return compact_sig[0] < 0x80;
     207                 :             : }
     208                 :             : 
     209                 :        7422 : bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool grind, uint32_t test_case) const {
     210         [ +  - ]:        7422 :     if (!keydata)
     211                 :             :         return false;
     212                 :        7422 :     vchSig.resize(CPubKey::SIGNATURE_SIZE);
     213                 :        7422 :     size_t nSigLen = CPubKey::SIGNATURE_SIZE;
     214                 :        7422 :     unsigned char extra_entropy[32] = {0};
     215                 :        7422 :     WriteLE32(extra_entropy, test_case);
     216                 :        7422 :     secp256k1_ecdsa_signature sig;
     217                 :        7422 :     uint32_t counter = 0;
     218   [ +  +  +  - ]:       21067 :     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   [ +  -  +  +  :       21241 :     while (ret && !SigHasLowR(&sig) && grind) {
                   +  + ]
     222                 :        6397 :         WriteLE32(extra_entropy, ++counter);
     223         [ +  - ]:       12794 :         ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, extra_entropy);
     224                 :             :     }
     225         [ -  + ]:        7422 :     assert(ret);
     226                 :        7422 :     secp256k1_ecdsa_signature_serialize_der(secp256k1_context_static, vchSig.data(), &nSigLen, &sig);
     227                 :        7422 :     vchSig.resize(nSigLen);
     228                 :             :     // Additional verification step to prevent using a potentially corrupted signature
     229                 :        7422 :     secp256k1_pubkey pk;
     230         [ +  - ]:       14844 :     ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pk, UCharCast(begin()));
     231         [ -  + ]:        7422 :     assert(ret);
     232                 :        7422 :     ret = secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pk);
     233         [ -  + ]:        7422 :     assert(ret);
     234                 :             :     return true;
     235                 :             : }
     236                 :             : 
     237                 :          49 : bool CKey::VerifyPubKey(const CPubKey& pubkey) const {
     238         [ +  + ]:          49 :     if (pubkey.IsCompressed() != fCompressed) {
     239                 :             :         return false;
     240                 :             :     }
     241                 :          41 :     unsigned char rnd[8];
     242                 :          41 :     std::string str = "Bitcoin key verification\n";
     243                 :          41 :     GetRandBytes(rnd);
     244         [ +  - ]:          41 :     uint256 hash{Hash(str, rnd)};
     245                 :          41 :     std::vector<unsigned char> vchSig;
     246         [ +  - ]:          41 :     Sign(hash, vchSig);
     247         [ +  - ]:          41 :     return pubkey.Verify(hash, vchSig);
     248                 :          41 : }
     249                 :             : 
     250                 :          70 : bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
     251         [ +  + ]:          70 :     if (!keydata)
     252                 :             :         return false;
     253                 :          69 :     vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE);
     254                 :          69 :     int rec = -1;
     255                 :          69 :     secp256k1_ecdsa_recoverable_signature rsig;
     256         [ +  - ]:         138 :     int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &rsig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, nullptr);
     257         [ -  + ]:          69 :     assert(ret);
     258                 :          69 :     ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_static, &vchSig[1], &rec, &rsig);
     259         [ -  + ]:          69 :     assert(ret);
     260         [ -  + ]:          69 :     assert(rec != -1);
     261   [ +  +  +  - ]:         103 :     vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
     262                 :             :     // Additional verification step to prevent using a potentially corrupted signature
     263                 :          69 :     secp256k1_pubkey epk, rpk;
     264         [ +  - ]:         138 :     ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &epk, UCharCast(begin()));
     265         [ -  + ]:          69 :     assert(ret);
     266                 :          69 :     ret = secp256k1_ecdsa_recover(secp256k1_context_static, &rpk, &rsig, hash.begin());
     267         [ -  + ]:          69 :     assert(ret);
     268                 :          69 :     ret = secp256k1_ec_pubkey_cmp(secp256k1_context_static, &epk, &rpk);
     269         [ -  + ]:          69 :     assert(ret == 0);
     270                 :             :     return true;
     271                 :             : }
     272                 :             : 
     273                 :         378 : bool CKey::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const
     274                 :             : {
     275                 :         378 :     KeyPair kp = ComputeKeyPair(merkle_root);
     276         [ +  - ]:         378 :     return kp.SignSchnorr(hash, sig, aux);
     277                 :         378 : }
     278                 :             : 
     279                 :          18 : bool CKey::Load(const CPrivKey &seckey, const CPubKey &vchPubKey, bool fSkipCheck=false) {
     280                 :          18 :     MakeKeyData();
     281   [ -  +  +  -  :          36 :     if (!ec_seckey_import_der(secp256k1_context_static, (unsigned char*)begin(), seckey.data(), seckey.size())) {
                   -  + ]
     282                 :           0 :         ClearKeyData();
     283                 :           0 :         return false;
     284                 :             :     }
     285         [ -  + ]:          18 :     fCompressed = vchPubKey.IsCompressed();
     286                 :             : 
     287         [ -  + ]:          18 :     if (fSkipCheck)
     288                 :             :         return true;
     289                 :             : 
     290                 :           0 :     return VerifyPubKey(vchPubKey);
     291                 :             : }
     292                 :             : 
     293                 :        5552 : bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
     294         [ -  + ]:        5552 :     assert(IsValid());
     295         [ -  + ]:        5552 :     assert(IsCompressed());
     296                 :        5552 :     std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
     297         [ +  + ]:        5552 :     if ((nChild >> 31) == 0) {
     298         [ +  - ]:        1501 :         CPubKey pubkey = GetPubKey();
     299         [ -  + ]:        1501 :         assert(pubkey.size() == CPubKey::COMPRESSED_SIZE);
     300         [ +  - ]:        1501 :         BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin()+1, vout.data());
     301                 :             :     } else {
     302         [ +  - ]:        4051 :         assert(size() == 32);
     303         [ +  - ]:        4051 :         BIP32Hash(cc, nChild, 0, UCharCast(begin()), vout.data());
     304                 :             :     }
     305         [ +  - ]:        5552 :     memcpy(ccChild.begin(), vout.data()+32, 32);
     306   [ +  -  +  - ]:       11104 :     keyChild.Set(begin(), begin() + 32, true);
     307   [ +  -  +  - ]:       11104 :     bool ret = secp256k1_ec_seckey_tweak_add(secp256k1_context_static, (unsigned char*)keyChild.begin(), vout.data());
     308         [ -  + ]:        5552 :     if (!ret) keyChild.ClearKeyData();
     309                 :        5552 :     return ret;
     310                 :        5552 : }
     311                 :             : 
     312                 :         154 : EllSwiftPubKey CKey::EllSwiftCreate(std::span<const std::byte> ent32) const
     313                 :             : {
     314         [ -  + ]:         154 :     assert(keydata);
     315         [ -  + ]:         154 :     assert(ent32.size() == 32);
     316                 :         154 :     std::array<std::byte, EllSwiftPubKey::size()> encoded_pubkey;
     317                 :             : 
     318                 :         154 :     auto success = secp256k1_ellswift_create(secp256k1_context_sign,
     319                 :             :                                              UCharCast(encoded_pubkey.data()),
     320                 :         154 :                                              keydata->data(),
     321                 :             :                                              UCharCast(ent32.data()));
     322                 :             : 
     323                 :             :     // Should always succeed for valid keys (asserted above).
     324         [ -  + ]:         154 :     assert(success);
     325                 :         154 :     return {encoded_pubkey};
     326                 :             : }
     327                 :             : 
     328                 :         244 : ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, const EllSwiftPubKey& our_ellswift, bool initiating) const
     329                 :             : {
     330         [ -  + ]:         244 :     assert(keydata);
     331                 :             : 
     332                 :         244 :     ECDHSecret output;
     333                 :             :     // BIP324 uses the initiator as party A, and the responder as party B. Remap the inputs
     334                 :             :     // accordingly:
     335         [ +  + ]:         488 :     bool success = secp256k1_ellswift_xdh(secp256k1_context_static,
     336                 :             :                                           UCharCast(output.data()),
     337                 :         244 :                                           UCharCast(initiating ? our_ellswift.data() : their_ellswift.data()),
     338                 :         244 :                                           UCharCast(initiating ? their_ellswift.data() : our_ellswift.data()),
     339                 :         244 :                                           keydata->data(),
     340                 :             :                                           initiating ? 0 : 1,
     341                 :             :                                           secp256k1_ellswift_xdh_hash_function_bip324,
     342                 :         244 :                                           nullptr);
     343                 :             :     // Should always succeed for valid keys (assert above).
     344         [ -  + ]:         244 :     assert(success);
     345                 :         244 :     return output;
     346                 :             : }
     347                 :             : 
     348                 :         422 : KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const
     349                 :             : {
     350                 :         422 :     return KeyPair(*this, merkle_root);
     351                 :             : }
     352                 :             : 
     353                 :           0 : std::vector<uint8_t> CKey::CreateMuSig2Nonce(MuSig2SecNonce& secnonce, const uint256& sighash, const CPubKey& aggregate_pubkey, const std::vector<CPubKey>& pubkeys)
     354                 :             : {
     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                 :             :     }
     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                 :             :     }
     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                 :             :     }
     382                 :             : 
     383                 :           0 :     return out;
     384                 :           0 : }
     385                 :             : 
     386                 :           0 : 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                 :             : {
     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                 :             :         }
     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                 :             :         }
     417                 :             : 
     418   [ #  #  #  # ]:           0 :         if (!secp256k1_musig_pubnonce_parse(secp256k1_context_static, &secp_pn, pubnonce.data())) {
     419                 :           0 :             return std::nullopt;
     420                 :             :         }
     421                 :           0 :     }
     422         [ #  # ]:           0 :     if (our_pubkey_idx == std::nullopt) {
     423                 :           0 :         return std::nullopt;
     424                 :             :     }
     425   [ #  #  #  # ]:           0 :     pubnonce_ptrs.reserve(signers_data.size());
     426   [ #  #  #  # ]:           0 :     for (auto& [_, pn] : signers_data) {
     427         [ #  # ]:           0 :         pubnonce_ptrs.push_back(&pn);
     428                 :             :     }
     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                 :             :     }
     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                 :             :             }
     442   [ #  #  #  # ]:           0 :         } else if (!secp256k1_musig_pubkey_ec_tweak_add(secp256k1_context_static, nullptr, &keyagg_cache, tweak.data())) {
     443                 :           0 :             return std::nullopt;
     444                 :             :         }
     445                 :             :     }
     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                 :             :     }
     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                 :             :     }
     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                 :             :     }
     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                 :             :     }
     471                 :             : 
     472                 :           0 :     return sig;
     473                 :           0 : }
     474                 :             : 
     475                 :         163 : CKey GenerateRandomKey(bool compressed) noexcept
     476                 :             : {
     477                 :         163 :     CKey key;
     478                 :         163 :     key.MakeNewKey(/*fCompressed=*/compressed);
     479                 :         163 :     return key;
     480                 :             : }
     481                 :             : 
     482                 :        5553 : bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const {
     483         [ +  + ]:        5553 :     if (nDepth == std::numeric_limits<unsigned char>::max()) return false;
     484                 :        5552 :     out.nDepth = nDepth + 1;
     485                 :        5552 :     CKeyID id = key.GetPubKey().GetID();
     486                 :        5552 :     memcpy(out.vchFingerprint, &id, 4);
     487                 :        5552 :     out.nChild = _nChild;
     488                 :        5552 :     return key.Derive(out.key, out.chaincode, _nChild, chaincode);
     489                 :             : }
     490                 :             : 
     491                 :          36 : void CExtKey::SetSeed(std::span<const std::byte> seed)
     492                 :             : {
     493                 :          36 :     static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
     494                 :          36 :     std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
     495   [ +  -  +  -  :          36 :     CHMAC_SHA512{hashkey, sizeof(hashkey)}.Write(UCharCast(seed.data()), seed.size()).Finalize(vout.data());
                   +  - ]
     496         [ +  - ]:          36 :     key.Set(vout.data(), vout.data() + 32, true);
     497                 :          36 :     memcpy(chaincode.begin(), vout.data() + 32, 32);
     498                 :          36 :     nDepth = 0;
     499                 :          36 :     nChild = 0;
     500                 :          36 :     memset(vchFingerprint, 0, sizeof(vchFingerprint));
     501                 :          36 : }
     502                 :             : 
     503                 :        4614 : CExtPubKey CExtKey::Neuter() const {
     504                 :        4614 :     CExtPubKey ret;
     505                 :        4614 :     ret.nDepth = nDepth;
     506                 :        4614 :     memcpy(ret.vchFingerprint, vchFingerprint, 4);
     507                 :        4614 :     ret.nChild = nChild;
     508                 :        4614 :     ret.pubkey = key.GetPubKey();
     509                 :        4614 :     ret.chaincode = chaincode;
     510                 :        4614 :     return ret;
     511                 :             : }
     512                 :             : 
     513                 :         366 : void CExtKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
     514                 :         366 :     code[0] = nDepth;
     515                 :         366 :     memcpy(code+1, vchFingerprint, 4);
     516                 :         366 :     WriteBE32(code+5, nChild);
     517         [ -  + ]:         366 :     memcpy(code+9, chaincode.begin(), 32);
     518                 :         366 :     code[41] = 0;
     519         [ -  + ]:         366 :     assert(key.size() == 32);
     520                 :         366 :     memcpy(code+42, key.begin(), 32);
     521                 :         366 : }
     522                 :             : 
     523                 :         210 : void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
     524                 :         210 :     nDepth = code[0];
     525                 :         210 :     memcpy(vchFingerprint, code+1, 4);
     526                 :         210 :     nChild = ReadBE32(code+5);
     527                 :         210 :     memcpy(chaincode.begin(), code+9, 32);
     528                 :         210 :     key.Set(code+42, code+BIP32_EXTKEY_SIZE, true);
     529   [ +  +  +  +  :         210 :     if ((nDepth == 0 && (nChild != 0 || ReadLE32(vchFingerprint) != 0)) || code[41] != 0) key = CKey();
             +  +  +  + ]
     530                 :         210 : }
     531                 :             : 
     532         [ +  - ]:         422 : KeyPair::KeyPair(const CKey& key, const uint256* merkle_root)
     533                 :             : {
     534                 :         422 :     static_assert(std::tuple_size<KeyType>() == sizeof(secp256k1_keypair));
     535         [ +  - ]:         422 :     MakeKeyPairData();
     536         [ +  - ]:         422 :     auto keypair = reinterpret_cast<secp256k1_keypair*>(m_keypair->data());
     537   [ +  -  +  - ]:         844 :     bool success = secp256k1_keypair_create(secp256k1_context_sign, keypair, UCharCast(key.data()));
     538         [ +  + ]:         422 :     if (success && merkle_root) {
     539                 :         105 :         secp256k1_xonly_pubkey pubkey;
     540                 :         105 :         unsigned char pubkey_bytes[32];
     541   [ +  -  -  + ]:         105 :         assert(secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey, nullptr, keypair));
     542   [ +  -  -  + ]:         105 :         assert(secp256k1_xonly_pubkey_serialize(secp256k1_context_static, pubkey_bytes, &pubkey));
     543   [ +  +  +  - ]:         300 :         uint256 tweak = XOnlyPubKey(pubkey_bytes).ComputeTapTweakHash(merkle_root->IsNull() ? nullptr : merkle_root);
     544         [ +  - ]:         105 :         success = secp256k1_keypair_xonly_tweak_add(secp256k1_context_static, keypair, tweak.data());
     545                 :             :     }
     546         [ -  + ]:         422 :     if (!success) ClearKeyPairData();
     547                 :         422 : }
     548                 :             : 
     549                 :         422 : bool KeyPair::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256& aux) const
     550                 :             : {
     551         [ -  + ]:         422 :     assert(sig.size() == 64);
     552         [ +  - ]:         422 :     if (!IsValid()) return false;
     553                 :         422 :     auto keypair = reinterpret_cast<const secp256k1_keypair*>(m_keypair->data());
     554                 :         422 :     bool ret = secp256k1_schnorrsig_sign32(secp256k1_context_sign, sig.data(), hash.data(), keypair, aux.data());
     555         [ +  - ]:         422 :     if (ret) {
     556                 :             :         // Additional verification step to prevent using a potentially corrupted signature
     557                 :         422 :         secp256k1_xonly_pubkey pubkey_verify;
     558                 :         422 :         ret = secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey_verify, nullptr, keypair);
     559                 :         422 :         ret &= secp256k1_schnorrsig_verify(secp256k1_context_static, sig.data(), hash.begin(), 32, &pubkey_verify);
     560                 :             :     }
     561         [ -  + ]:         422 :     if (!ret) memory_cleanse(sig.data(), sig.size());
     562                 :             :     return ret;
     563                 :             : }
     564                 :             : 
     565                 :           1 : bool ECC_InitSanityCheck() {
     566                 :           1 :     CKey key = GenerateRandomKey();
     567         [ +  - ]:           1 :     CPubKey pubkey = key.GetPubKey();
     568         [ +  - ]:           1 :     return key.VerifyPubKey(pubkey);
     569                 :           1 : }
     570                 :             : 
     571                 :             : /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */
     572                 :         626 : static void ECC_Start() {
     573         [ -  + ]:         626 :     assert(secp256k1_context_sign == nullptr);
     574                 :             : 
     575                 :         626 :     secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
     576         [ -  + ]:         626 :     assert(ctx != nullptr);
     577                 :             : 
     578                 :         626 :     {
     579                 :             :         // Pass in a random blinding seed to the secp256k1 context.
     580                 :         626 :         std::vector<unsigned char, secure_allocator<unsigned char>> vseed(32);
     581         [ -  + ]:         626 :         GetRandBytes(vseed);
     582         [ +  - ]:         626 :         bool ret = secp256k1_context_randomize(ctx, vseed.data());
     583         [ -  + ]:         626 :         assert(ret);
     584                 :         626 :     }
     585                 :             : 
     586                 :         626 :     secp256k1_context_sign = ctx;
     587                 :         626 : }
     588                 :             : 
     589                 :             : /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */
     590                 :         625 : static void ECC_Stop() {
     591                 :         625 :     secp256k1_context *ctx = secp256k1_context_sign;
     592                 :         625 :     secp256k1_context_sign = nullptr;
     593                 :             : 
     594         [ +  - ]:         625 :     if (ctx) {
     595                 :         625 :         secp256k1_context_destroy(ctx);
     596                 :             :     }
     597                 :         625 : }
     598                 :             : 
     599                 :         626 : ECC_Context::ECC_Context()
     600                 :             : {
     601                 :         626 :     ECC_Start();
     602                 :         626 : }
     603                 :             : 
     604                 :         625 : ECC_Context::~ECC_Context()
     605                 :             : {
     606                 :         625 :     ECC_Stop();
     607                 :         625 : }
        

Generated by: LCOV version 2.0-1