| 198 | } |
| 199 | |
| 200 | bool CPubKey::RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig) |
| 201 | { |
| 202 | if (vchSig.size() != COMPACT_SIGNATURE_SIZE) |
| 203 | return false; |
| 204 | |
| 205 | unsigned char hashMsg[64]; |
| 206 | memcpy(&hashMsg[0], hash.begin(), 32); |
| 207 | memset(&hashMsg[32], 0, 32); |
| 208 | |
| 209 | int recid = (vchSig[0] - 27) & 3; |
| 210 | bool fComp = ((vchSig[0] - 27) & 4) != 0; |
| 211 | secp256k1_pubkey pubkey; |
| 212 | secp256k1_ecdsa_recoverable_signature sig; |
| 213 | if (secp256k1_context_verify == nullptr) { |
| 214 | LogPrintf("%s: bad context for secp256k1_ecdsa_recover()\n", __func__); |
| 215 | return false; |
| 216 | } |
| 217 | if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) { |
| 218 | return false; |
| 219 | } |
| 220 | if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hashMsg)) { |
| 221 | return false; |
| 222 | } |
| 223 | unsigned char pub[PUBLIC_KEY_SIZE]; |
| 224 | size_t publen = PUBLIC_KEY_SIZE; |
| 225 | secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); |
| 226 | Set(pub, pub + publen); |
| 227 | return true; |
| 228 | } |
| 229 | |
| 230 | bool CPubKey::IsFullyValid() const |
| 231 | { |