Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2021 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_extrakeys.h>
# 15 : : #include <secp256k1_recovery.h>
# 16 : : #include <secp256k1_schnorrsig.h>
# 17 : :
# 18 : : static secp256k1_context* secp256k1_context_sign = nullptr;
# 19 : :
# 20 : : /** These functions are taken from the libsecp256k1 distribution and are very ugly. */
# 21 : :
# 22 : : /**
# 23 : : * This parses a format loosely based on a DER encoding of the ECPrivateKey type from
# 24 : : * section C.4 of SEC 1 <https://www.secg.org/sec1-v2.pdf>, with the following caveats:
# 25 : : *
# 26 : : * * The octet-length of the SEQUENCE must be encoded as 1 or 2 octets. It is not
# 27 : : * required to be encoded as one octet if it is less than 256, as DER would require.
# 28 : : * * The octet-length of the SEQUENCE must not be greater than the remaining
# 29 : : * length of the key encoding, but need not match it (i.e. the encoding may contain
# 30 : : * junk after the encoded SEQUENCE).
# 31 : : * * The privateKey OCTET STRING is zero-filled on the left to 32 octets.
# 32 : : * * Anything after the encoding of the privateKey OCTET STRING is ignored, whether
# 33 : : * or not it is validly encoded DER.
# 34 : : *
# 35 : : * out32 must point to an output buffer of length at least 32 bytes.
# 36 : : */
# 37 : 11879 : int ec_seckey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *seckey, size_t seckeylen) {
# 38 : 11879 : const unsigned char *end = seckey + seckeylen;
# 39 : 11879 : memset(out32, 0, 32);
# 40 : : /* sequence header */
# 41 [ - + ][ - + ]: 11879 : if (end - seckey < 1 || *seckey != 0x30u) {
# 42 : 0 : return 0;
# 43 : 0 : }
# 44 : 11879 : seckey++;
# 45 : : /* sequence length constructor */
# 46 [ - + ][ - + ]: 11879 : if (end - seckey < 1 || !(*seckey & 0x80u)) {
# 47 : 0 : return 0;
# 48 : 0 : }
# 49 : 11879 : ptrdiff_t lenb = *seckey & ~0x80u; seckey++;
# 50 [ - + ][ - + ]: 11879 : if (lenb < 1 || lenb > 2) {
# 51 : 0 : return 0;
# 52 : 0 : }
# 53 [ - + ]: 11879 : if (end - seckey < lenb) {
# 54 : 0 : return 0;
# 55 : 0 : }
# 56 : : /* sequence length */
# 57 [ - + ]: 11879 : ptrdiff_t len = seckey[lenb-1] | (lenb > 1 ? seckey[lenb-2] << 8 : 0u);
# 58 : 11879 : seckey += lenb;
# 59 [ - + ]: 11879 : if (end - seckey < len) {
# 60 : 0 : return 0;
# 61 : 0 : }
# 62 : : /* sequence element 0: version number (=1) */
# 63 [ - + ][ - + ]: 11879 : if (end - seckey < 3 || seckey[0] != 0x02u || seckey[1] != 0x01u || seckey[2] != 0x01u) {
# [ - + ][ - + ]
# 64 : 0 : return 0;
# 65 : 0 : }
# 66 : 11879 : seckey += 3;
# 67 : : /* sequence element 1: octet string, up to 32 bytes */
# 68 [ - + ][ - + ]: 11879 : if (end - seckey < 2 || seckey[0] != 0x04u) {
# 69 : 0 : return 0;
# 70 : 0 : }
# 71 : 11879 : ptrdiff_t oslen = seckey[1];
# 72 : 11879 : seckey += 2;
# 73 [ - + ][ - + ]: 11879 : if (oslen > 32 || end - seckey < oslen) {
# 74 : 0 : return 0;
# 75 : 0 : }
# 76 : 11879 : memcpy(out32 + (32 - oslen), seckey, oslen);
# 77 [ - + ]: 11879 : if (!secp256k1_ec_seckey_verify(ctx, out32)) {
# 78 : 0 : memset(out32, 0, 32);
# 79 : 0 : return 0;
# 80 : 0 : }
# 81 : 11879 : return 1;
# 82 : 11879 : }
# 83 : :
# 84 : : /**
# 85 : : * This serializes to a DER encoding of the ECPrivateKey type from section C.4 of SEC 1
# 86 : : * <https://www.secg.org/sec1-v2.pdf>. The optional parameters and publicKey fields are
# 87 : : * included.
# 88 : : *
# 89 : : * seckey must point to an output buffer of length at least CKey::SIZE bytes.
# 90 : : * seckeylen must initially be set to the size of the seckey buffer. Upon return it
# 91 : : * will be set to the number of bytes used in the buffer.
# 92 : : * key32 must point to a 32-byte raw private key.
# 93 : : */
# 94 : 21932 : int ec_seckey_export_der(const secp256k1_context *ctx, unsigned char *seckey, size_t *seckeylen, const unsigned char *key32, bool compressed) {
# 95 : 21932 : assert(*seckeylen >= CKey::SIZE);
# 96 : 0 : secp256k1_pubkey pubkey;
# 97 : 21932 : size_t pubkeylen = 0;
# 98 [ - + ]: 21932 : if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) {
# 99 : 0 : *seckeylen = 0;
# 100 : 0 : return 0;
# 101 : 0 : }
# 102 [ + + ]: 21932 : if (compressed) {
# 103 : 21923 : static const unsigned char begin[] = {
# 104 : 21923 : 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
# 105 : 21923 : };
# 106 : 21923 : static const unsigned char middle[] = {
# 107 : 21923 : 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
# 108 : 21923 : 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
# 109 : 21923 : 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
# 110 : 21923 : 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
# 111 : 21923 : 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
# 112 : 21923 : 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
# 113 : 21923 : 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
# 114 : 21923 : 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
# 115 : 21923 : 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00
# 116 : 21923 : };
# 117 : 21923 : unsigned char *ptr = seckey;
# 118 : 21923 : memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
# 119 : 21923 : memcpy(ptr, key32, 32); ptr += 32;
# 120 : 21923 : memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
# 121 : 21923 : pubkeylen = CPubKey::COMPRESSED_SIZE;
# 122 : 21923 : secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED);
# 123 : 21923 : ptr += pubkeylen;
# 124 : 21923 : *seckeylen = ptr - seckey;
# 125 : 21923 : assert(*seckeylen == CKey::COMPRESSED_SIZE);
# 126 : 21923 : } else {
# 127 : 9 : static const unsigned char begin[] = {
# 128 : 9 : 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20
# 129 : 9 : };
# 130 : 9 : static const unsigned char middle[] = {
# 131 : 9 : 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
# 132 : 9 : 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
# 133 : 9 : 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
# 134 : 9 : 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
# 135 : 9 : 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
# 136 : 9 : 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
# 137 : 9 : 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11,
# 138 : 9 : 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10,
# 139 : 9 : 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
# 140 : 9 : 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
# 141 : 9 : 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00
# 142 : 9 : };
# 143 : 9 : unsigned char *ptr = seckey;
# 144 : 9 : memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
# 145 : 9 : memcpy(ptr, key32, 32); ptr += 32;
# 146 : 9 : memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
# 147 : 9 : pubkeylen = CPubKey::SIZE;
# 148 : 9 : secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
# 149 : 9 : ptr += pubkeylen;
# 150 : 9 : *seckeylen = ptr - seckey;
# 151 : 9 : assert(*seckeylen == CKey::SIZE);
# 152 : 9 : }
# 153 : 0 : return 1;
# 154 : 21932 : }
# 155 : :
# 156 : 29842 : bool CKey::Check(const unsigned char *vch) {
# 157 : 29842 : return secp256k1_ec_seckey_verify(secp256k1_context_sign, vch);
# 158 : 29842 : }
# 159 : :
# 160 : 1406 : void CKey::MakeNewKey(bool fCompressedIn) {
# 161 : 1406 : do {
# 162 : 1406 : GetStrongRandBytes(keydata.data(), keydata.size());
# 163 [ - + ]: 1406 : } while (!Check(keydata.data()));
# 164 : 1406 : fValid = true;
# 165 : 1406 : fCompressed = fCompressedIn;
# 166 : 1406 : }
# 167 : :
# 168 : : bool CKey::Negate()
# 169 : 4 : {
# 170 : 4 : assert(fValid);
# 171 : 0 : return secp256k1_ec_seckey_negate(secp256k1_context_sign, keydata.data());
# 172 : 4 : }
# 173 : :
# 174 : 21932 : CPrivKey CKey::GetPrivKey() const {
# 175 : 21932 : assert(fValid);
# 176 : 0 : CPrivKey seckey;
# 177 : 21932 : int ret;
# 178 : 21932 : size_t seckeylen;
# 179 : 21932 : seckey.resize(SIZE);
# 180 : 21932 : seckeylen = SIZE;
# 181 : 21932 : ret = ec_seckey_export_der(secp256k1_context_sign, seckey.data(), &seckeylen, begin(), fCompressed);
# 182 : 21932 : assert(ret);
# 183 : 0 : seckey.resize(seckeylen);
# 184 : 21932 : return seckey;
# 185 : 21932 : }
# 186 : :
# 187 : 1292915 : CPubKey CKey::GetPubKey() const {
# 188 : 1292915 : assert(fValid);
# 189 : 0 : secp256k1_pubkey pubkey;
# 190 : 1292915 : size_t clen = CPubKey::SIZE;
# 191 : 1292915 : CPubKey result;
# 192 : 1292915 : int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin());
# 193 : 1292915 : assert(ret);
# 194 [ + + ]: 1292915 : secp256k1_ec_pubkey_serialize(secp256k1_context_sign, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
# 195 : 1292915 : assert(result.size() == clen);
# 196 : 0 : assert(result.IsValid());
# 197 : 0 : return result;
# 198 : 1292915 : }
# 199 : :
# 200 : : // Check that the sig has a low R value and will be less than 71 bytes
# 201 : : bool SigHasLowR(const secp256k1_ecdsa_signature* sig)
# 202 : 132833 : {
# 203 : 132833 : unsigned char compact_sig[64];
# 204 : 132833 : secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_sign, compact_sig, sig);
# 205 : :
# 206 : : // In DER serialization, all values are interpreted as big-endian, signed integers. The highest bit in the integer indicates
# 207 : : // its signed-ness; 0 is positive, 1 is negative. When the value is interpreted as a negative integer, it must be converted
# 208 : : // to a positive value by prepending a 0x00 byte so that the highest bit is 0. We can avoid this prepending by ensuring that
# 209 : : // our highest bit is always 0, and thus we must check that the first byte is less than 0x80.
# 210 : 132833 : return compact_sig[0] < 0x80;
# 211 : 132833 : }
# 212 : :
# 213 : 68078 : bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool grind, uint32_t test_case) const {
# 214 [ - + ]: 68078 : if (!fValid)
# 215 : 0 : return false;
# 216 : 68078 : vchSig.resize(CPubKey::SIGNATURE_SIZE);
# 217 : 68078 : size_t nSigLen = CPubKey::SIGNATURE_SIZE;
# 218 : 68078 : unsigned char extra_entropy[32] = {0};
# 219 : 68078 : WriteLE32(extra_entropy, test_case);
# 220 : 68078 : secp256k1_ecdsa_signature sig;
# 221 : 68078 : uint32_t counter = 0;
# 222 [ + + ][ + + ]: 68078 : int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, (!grind && test_case) ? extra_entropy : nullptr);
# 223 : :
# 224 : : // Grind for low R
# 225 [ + - ][ + + ]: 132833 : while (ret && !SigHasLowR(&sig) && grind) {
# [ + + ]
# 226 : 64755 : WriteLE32(extra_entropy, ++counter);
# 227 : 64755 : ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, extra_entropy);
# 228 : 64755 : }
# 229 : 68078 : assert(ret);
# 230 : 0 : secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, vchSig.data(), &nSigLen, &sig);
# 231 : 68078 : vchSig.resize(nSigLen);
# 232 : : // Additional verification step to prevent using a potentially corrupted signature
# 233 : 68078 : secp256k1_pubkey pk;
# 234 : 68078 : ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pk, begin());
# 235 : 68078 : assert(ret);
# 236 : 0 : ret = secp256k1_ecdsa_verify(GetVerifyContext(), &sig, hash.begin(), &pk);
# 237 : 68078 : assert(ret);
# 238 : 0 : return true;
# 239 : 68078 : }
# 240 : :
# 241 : 28419 : bool CKey::VerifyPubKey(const CPubKey& pubkey) const {
# 242 [ + + ]: 28419 : if (pubkey.IsCompressed() != fCompressed) {
# 243 : 16 : return false;
# 244 : 16 : }
# 245 : 28403 : unsigned char rnd[8];
# 246 : 28403 : std::string str = "Bitcoin key verification\n";
# 247 : 28403 : GetRandBytes(rnd, sizeof(rnd));
# 248 : 28403 : uint256 hash;
# 249 : 28403 : CHash256().Write(MakeUCharSpan(str)).Write(rnd).Finalize(hash);
# 250 : 28403 : std::vector<unsigned char> vchSig;
# 251 : 28403 : Sign(hash, vchSig);
# 252 : 28403 : return pubkey.Verify(hash, vchSig);
# 253 : 28419 : }
# 254 : :
# 255 : 152 : bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
# 256 [ + + ]: 152 : if (!fValid)
# 257 : 1 : return false;
# 258 : 151 : vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE);
# 259 : 151 : int rec = -1;
# 260 : 151 : secp256k1_ecdsa_recoverable_signature rsig;
# 261 : 151 : int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &rsig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, nullptr);
# 262 : 151 : assert(ret);
# 263 : 0 : ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_sign, &vchSig[1], &rec, &rsig);
# 264 : 151 : assert(ret);
# 265 : 0 : assert(rec != -1);
# 266 [ + + ]: 151 : vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
# 267 : : // Additional verification step to prevent using a potentially corrupted signature
# 268 : 151 : secp256k1_pubkey epk, rpk;
# 269 : 151 : ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &epk, begin());
# 270 : 151 : assert(ret);
# 271 : 0 : ret = secp256k1_ecdsa_recover(GetVerifyContext(), &rpk, &rsig, hash.begin());
# 272 : 151 : assert(ret);
# 273 : 0 : ret = secp256k1_ec_pubkey_cmp(GetVerifyContext(), &epk, &rpk);
# 274 : 151 : assert(ret == 0);
# 275 : 0 : return true;
# 276 : 152 : }
# 277 : :
# 278 : : bool CKey::SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const
# 279 : 389 : {
# 280 : 389 : assert(sig.size() == 64);
# 281 : 0 : secp256k1_keypair keypair;
# 282 [ - + ]: 389 : if (!secp256k1_keypair_create(secp256k1_context_sign, &keypair, begin())) return false;
# 283 [ + + ]: 389 : if (merkle_root) {
# 284 : 202 : secp256k1_xonly_pubkey pubkey;
# 285 [ - + ]: 202 : if (!secp256k1_keypair_xonly_pub(secp256k1_context_sign, &pubkey, nullptr, &keypair)) return false;
# 286 : 202 : unsigned char pubkey_bytes[32];
# 287 [ - + ]: 202 : if (!secp256k1_xonly_pubkey_serialize(secp256k1_context_sign, pubkey_bytes, &pubkey)) return false;
# 288 [ + + ]: 202 : uint256 tweak = XOnlyPubKey(pubkey_bytes).ComputeTapTweakHash(merkle_root->IsNull() ? nullptr : merkle_root);
# 289 [ - + ]: 202 : if (!secp256k1_keypair_xonly_tweak_add(GetVerifyContext(), &keypair, tweak.data())) return false;
# 290 : 202 : }
# 291 : 389 : bool ret = secp256k1_schnorrsig_sign32(secp256k1_context_sign, sig.data(), hash.data(), &keypair, aux.data());
# 292 [ + - ]: 389 : if (ret) {
# 293 : : // Additional verification step to prevent using a potentially corrupted signature
# 294 : 389 : secp256k1_xonly_pubkey pubkey_verify;
# 295 : 389 : ret = secp256k1_keypair_xonly_pub(GetVerifyContext(), &pubkey_verify, nullptr, &keypair);
# 296 : 389 : ret &= secp256k1_schnorrsig_verify(GetVerifyContext(), sig.data(), hash.begin(), 32, &pubkey_verify);
# 297 : 389 : }
# 298 [ - + ]: 389 : if (!ret) memory_cleanse(sig.data(), sig.size());
# 299 : 389 : memory_cleanse(&keypair, sizeof(keypair));
# 300 : 389 : return ret;
# 301 : 389 : }
# 302 : :
# 303 : 11879 : bool CKey::Load(const CPrivKey &seckey, const CPubKey &vchPubKey, bool fSkipCheck=false) {
# 304 [ - + ]: 11879 : if (!ec_seckey_import_der(secp256k1_context_sign, (unsigned char*)begin(), seckey.data(), seckey.size()))
# 305 : 0 : return false;
# 306 : 11879 : fCompressed = vchPubKey.IsCompressed();
# 307 : 11879 : fValid = true;
# 308 : :
# 309 [ + - ]: 11879 : if (fSkipCheck)
# 310 : 11879 : return true;
# 311 : :
# 312 : 0 : return VerifyPubKey(vchPubKey);
# 313 : 11879 : }
# 314 : :
# 315 : 117219 : bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
# 316 : 117219 : assert(IsValid());
# 317 : 0 : assert(IsCompressed());
# 318 : 0 : std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
# 319 [ + + ]: 117219 : if ((nChild >> 31) == 0) {
# 320 : 19621 : CPubKey pubkey = GetPubKey();
# 321 : 19621 : assert(pubkey.size() == CPubKey::COMPRESSED_SIZE);
# 322 : 0 : BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin()+1, vout.data());
# 323 : 97598 : } else {
# 324 : 97598 : assert(size() == 32);
# 325 : 0 : BIP32Hash(cc, nChild, 0, begin(), vout.data());
# 326 : 97598 : }
# 327 : 0 : memcpy(ccChild.begin(), vout.data()+32, 32);
# 328 : 117219 : memcpy((unsigned char*)keyChild.begin(), begin(), 32);
# 329 : 117219 : bool ret = secp256k1_ec_seckey_tweak_add(secp256k1_context_sign, (unsigned char*)keyChild.begin(), vout.data());
# 330 : 117219 : keyChild.fCompressed = true;
# 331 : 117219 : keyChild.fValid = ret;
# 332 : 117219 : return ret;
# 333 : 117219 : }
# 334 : :
# 335 : 117219 : bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const {
# 336 : 117219 : out.nDepth = nDepth + 1;
# 337 : 117219 : CKeyID id = key.GetPubKey().GetID();
# 338 : 117219 : memcpy(out.vchFingerprint, &id, 4);
# 339 : 117219 : out.nChild = _nChild;
# 340 : 117219 : return key.Derive(out.key, out.chaincode, _nChild, chaincode);
# 341 : 117219 : }
# 342 : :
# 343 : : void CExtKey::SetSeed(Span<const uint8_t> seed)
# 344 : 20015 : {
# 345 : 20015 : static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
# 346 : 20015 : std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
# 347 : 20015 : CHMAC_SHA512{hashkey, sizeof(hashkey)}.Write(seed.data(), seed.size()).Finalize(vout.data());
# 348 : 20015 : key.Set(vout.data(), vout.data() + 32, true);
# 349 : 20015 : memcpy(chaincode.begin(), vout.data() + 32, 32);
# 350 : 20015 : nDepth = 0;
# 351 : 20015 : nChild = 0;
# 352 : 20015 : memset(vchFingerprint, 0, sizeof(vchFingerprint));
# 353 : 20015 : }
# 354 : :
# 355 : 41216 : CExtPubKey CExtKey::Neuter() const {
# 356 : 41216 : CExtPubKey ret;
# 357 : 41216 : ret.nDepth = nDepth;
# 358 : 41216 : memcpy(ret.vchFingerprint, vchFingerprint, 4);
# 359 : 41216 : ret.nChild = nChild;
# 360 : 41216 : ret.pubkey = key.GetPubKey();
# 361 : 41216 : ret.chaincode = chaincode;
# 362 : 41216 : return ret;
# 363 : 41216 : }
# 364 : :
# 365 : 320 : void CExtKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
# 366 : 320 : code[0] = nDepth;
# 367 : 320 : memcpy(code+1, vchFingerprint, 4);
# 368 : 320 : WriteBE32(code+5, nChild);
# 369 : 320 : memcpy(code+9, chaincode.begin(), 32);
# 370 : 320 : code[41] = 0;
# 371 : 320 : assert(key.size() == 32);
# 372 : 0 : memcpy(code+42, key.begin(), 32);
# 373 : 320 : }
# 374 : :
# 375 : 553 : void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
# 376 : 553 : nDepth = code[0];
# 377 : 553 : memcpy(vchFingerprint, code+1, 4);
# 378 : 553 : nChild = ReadBE32(code+5);
# 379 : 553 : memcpy(chaincode.begin(), code+9, 32);
# 380 : 553 : key.Set(code+42, code+BIP32_EXTKEY_SIZE, true);
# 381 [ + + ][ + + ]: 553 : if ((nDepth == 0 && (nChild != 0 || ReadLE32(vchFingerprint) != 0)) || code[41] != 0) key = CKey();
# [ + + ][ + + ]
# 382 : 553 : }
# 383 : :
# 384 : 797 : bool ECC_InitSanityCheck() {
# 385 : 797 : CKey key;
# 386 : 797 : key.MakeNewKey(true);
# 387 : 797 : CPubKey pubkey = key.GetPubKey();
# 388 : 797 : return key.VerifyPubKey(pubkey);
# 389 : 797 : }
# 390 : :
# 391 : 1687 : void ECC_Start() {
# 392 : 1687 : assert(secp256k1_context_sign == nullptr);
# 393 : :
# 394 : 1687 : secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
# 395 : 1687 : assert(ctx != nullptr);
# 396 : :
# 397 : 0 : {
# 398 : : // Pass in a random blinding seed to the secp256k1 context.
# 399 : 1687 : std::vector<unsigned char, secure_allocator<unsigned char>> vseed(32);
# 400 : 1687 : GetRandBytes(vseed.data(), 32);
# 401 : 1687 : bool ret = secp256k1_context_randomize(ctx, vseed.data());
# 402 : 1687 : assert(ret);
# 403 : 1687 : }
# 404 : :
# 405 : 0 : secp256k1_context_sign = ctx;
# 406 : 1687 : }
# 407 : :
# 408 : 1651 : void ECC_Stop() {
# 409 : 1651 : secp256k1_context *ctx = secp256k1_context_sign;
# 410 : 1651 : secp256k1_context_sign = nullptr;
# 411 : :
# 412 [ + - ]: 1651 : if (ctx) {
# 413 : 1651 : secp256k1_context_destroy(ctx);
# 414 : 1651 : }
# 415 : 1651 : }
|