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