Changeset View
Changeset View
Standalone View
Standalone View
src/key.cpp
Show First 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | CPubKey CKey::GetPubKey() const { | ||||
secp256k1_ec_pubkey_serialize( | secp256k1_ec_pubkey_serialize( | ||||
secp256k1_context_sign, (uint8_t *)result.begin(), &clen, &pubkey, | secp256k1_context_sign, (uint8_t *)result.begin(), &clen, &pubkey, | ||||
fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); | fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); | ||||
assert(result.size() == clen); | assert(result.size() == clen); | ||||
assert(result.IsValid()); | assert(result.IsValid()); | ||||
return result; | return result; | ||||
} | } | ||||
// Check that the sig has a low R value and will be less than 71 bytes | |||||
static bool SigHasLowR(const secp256k1_ecdsa_signature *sig) { | |||||
uint8_t compact_sig[64]; | |||||
secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_sign, | |||||
compact_sig, sig); | |||||
// In DER serialization, all values are interpreted as big-endian, signed | |||||
// integers. The highest bit in the integer indicates its signed-ness; 0 is | |||||
// positive, 1 is negative. When the value is interpreted as a negative | |||||
// integer, it must be converted to a positive value by prepending a 0x00 | |||||
// byte so that the highest bit is 0. We can avoid this prepending by | |||||
// ensuring that our highest bit is always 0, and thus we must check that | |||||
// the first byte is less than 0x80. | |||||
return compact_sig[0] < 0x80; | |||||
} | |||||
bool CKey::SignECDSA(const uint256 &hash, std::vector<uint8_t> &vchSig, | bool CKey::SignECDSA(const uint256 &hash, std::vector<uint8_t> &vchSig, | ||||
uint32_t test_case) const { | bool grind, uint32_t test_case) const { | ||||
if (!fValid) { | if (!fValid) { | ||||
return false; | return false; | ||||
} | } | ||||
vchSig.resize(CPubKey::SIGNATURE_SIZE); | vchSig.resize(CPubKey::SIGNATURE_SIZE); | ||||
size_t nSigLen = CPubKey::SIGNATURE_SIZE; | size_t nSigLen = CPubKey::SIGNATURE_SIZE; | ||||
uint8_t extra_entropy[32] = {0}; | uint8_t extra_entropy[32] = {0}; | ||||
WriteLE32(extra_entropy, test_case); | WriteLE32(extra_entropy, test_case); | ||||
secp256k1_ecdsa_signature sig; | secp256k1_ecdsa_signature sig; | ||||
int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), | uint32_t counter = 0; | ||||
int ret = | |||||
secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), | |||||
begin(), secp256k1_nonce_function_rfc6979, | begin(), secp256k1_nonce_function_rfc6979, | ||||
test_case ? extra_entropy : nullptr); | (!grind && test_case) ? extra_entropy : nullptr); | ||||
// Grind for low R | |||||
while (ret && !SigHasLowR(&sig) && grind) { | |||||
WriteLE32(extra_entropy, ++counter); | |||||
ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), | |||||
begin(), secp256k1_nonce_function_rfc6979, | |||||
extra_entropy); | |||||
} | |||||
assert(ret); | assert(ret); | ||||
secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, | secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, | ||||
vchSig.data(), &nSigLen, &sig); | vchSig.data(), &nSigLen, &sig); | ||||
vchSig.resize(nSigLen); | vchSig.resize(nSigLen); | ||||
return true; | return true; | ||||
} | } | ||||
bool CKey::SignSchnorr(const uint256 &hash, std::vector<uint8_t> &vchSig, | bool CKey::SignSchnorr(const uint256 &hash, std::vector<uint8_t> &vchSig, | ||||
▲ Show 20 Lines • Show All 175 Lines • Show Last 20 Lines |