Changeset View
Changeset View
Standalone View
Standalone View
src/script/sigencoding.cpp
Show First 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | static bool CheckRawECDSASignatureEncoding(const slicedvaltype &sig, | ||||
if ((flags & SCRIPT_VERIFY_LOW_S) && !CPubKey::CheckLowS(sig)) { | if ((flags & SCRIPT_VERIFY_LOW_S) && !CPubKey::CheckLowS(sig)) { | ||||
return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); | return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CheckDataSignatureEncoding(const valtype &vchSig, uint32_t flags, | static bool CheckRawSignatureEncoding(const slicedvaltype &sig, uint32_t flags, | ||||
ScriptError *serror) { | ScriptError *serror) { | ||||
// Empty signature. Not strictly DER encoded, but allowed to provide a | return CheckRawECDSASignatureEncoding(sig, flags, serror); | ||||
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG | |||||
if (vchSig.size() == 0) { | |||||
return true; | |||||
} | |||||
return CheckRawECDSASignatureEncoding( | |||||
vchSig | boost::adaptors::sliced(0, vchSig.size()), flags, serror); | |||||
} | } | ||||
bool CheckTransactionECDSASignatureEncoding(const valtype &vchSig, | bool CheckDataSignatureEncoding(const valtype &vchSig, uint32_t flags, | ||||
uint32_t flags, | |||||
ScriptError *serror) { | ScriptError *serror) { | ||||
// Empty signature. Not strictly DER encoded, but allowed to provide a | // Empty signature. Not strictly DER encoded, but allowed to provide a | ||||
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG | // compact way to provide an invalid signature for use with CHECK(MULTI)SIG | ||||
if (vchSig.size() == 0) { | if (vchSig.size() == 0) { | ||||
return true; | return true; | ||||
} | } | ||||
if (!CheckRawECDSASignatureEncoding( | return CheckRawSignatureEncoding( | ||||
vchSig | boost::adaptors::sliced(0, vchSig.size() - 1), flags, | vchSig | boost::adaptors::sliced(0, vchSig.size()), flags, serror); | ||||
serror)) { | |||||
// serror is set | |||||
return false; | |||||
} | } | ||||
static bool CheckSighashEncoding(const valtype &vchSig, uint32_t flags, | |||||
ScriptError *serror) { | |||||
if (flags & SCRIPT_VERIFY_STRICTENC) { | if (flags & SCRIPT_VERIFY_STRICTENC) { | ||||
if (!GetHashType(vchSig).isDefined()) { | if (!GetHashType(vchSig).isDefined()) { | ||||
return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); | return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); | ||||
} | } | ||||
bool usesForkId = GetHashType(vchSig).hasForkId(); | bool usesForkId = GetHashType(vchSig).hasForkId(); | ||||
bool forkIdEnabled = flags & SCRIPT_ENABLE_SIGHASH_FORKID; | bool forkIdEnabled = flags & SCRIPT_ENABLE_SIGHASH_FORKID; | ||||
if (!forkIdEnabled && usesForkId) { | if (!forkIdEnabled && usesForkId) { | ||||
return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID); | return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID); | ||||
} | } | ||||
if (forkIdEnabled && !usesForkId) { | if (forkIdEnabled && !usesForkId) { | ||||
return set_error(serror, SCRIPT_ERR_MUST_USE_FORKID); | return set_error(serror, SCRIPT_ERR_MUST_USE_FORKID); | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CheckTransactionECDSASignatureEncoding(const valtype &vchSig, | |||||
uint32_t flags, | |||||
ScriptError *serror) { | |||||
// Empty signature. Not strictly DER encoded, but allowed to provide a | |||||
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG | |||||
if (vchSig.size() == 0) { | |||||
return true; | |||||
} | |||||
if (!CheckRawECDSASignatureEncoding( | |||||
vchSig | boost::adaptors::sliced(0, vchSig.size() - 1), flags, | |||||
serror)) { | |||||
// serror is set | |||||
return false; | |||||
} | |||||
return CheckSighashEncoding(vchSig, flags, serror); | |||||
} | |||||
bool CheckTransactionSignatureEncoding(const valtype &vchSig, uint32_t flags, | bool CheckTransactionSignatureEncoding(const valtype &vchSig, uint32_t flags, | ||||
ScriptError *serror) { | ScriptError *serror) { | ||||
return CheckTransactionECDSASignatureEncoding(vchSig, flags, serror); | // Empty signature. Not strictly DER encoded, but allowed to provide a | ||||
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG | |||||
if (vchSig.size() == 0) { | |||||
return true; | |||||
} | |||||
if (!CheckRawSignatureEncoding( | |||||
vchSig | boost::adaptors::sliced(0, vchSig.size() - 1), flags, | |||||
serror)) { | |||||
// serror is set | |||||
return false; | |||||
} | |||||
return CheckSighashEncoding(vchSig, flags, serror); | |||||
} | } | ||||
static bool IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { | static bool IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { | ||||
switch (vchPubKey.size()) { | switch (vchPubKey.size()) { | ||||
case 33: | case 33: | ||||
// Compressed public key: must start with 0x02 or 0x03. | // Compressed public key: must start with 0x02 or 0x03. | ||||
return vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03; | return vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03; | ||||
Show All 36 Lines |