return true;
}
-bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) {
- if (!(flags & SCRIPT_VERIFY_STRICTENC))
- return true;
-
+bool IsDERSignature(const valtype &vchSig, bool fWithHashType, bool fCheckLow) {
// See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
// A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
// Where R and S are not negative (their first byte has its highest bit not set), and not
return error("Non-canonical signature: too short");
if (vchSig.size() > 73)
return error("Non-canonical signature: too long");
- unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));
- if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
- return error("Non-canonical signature: unknown hashtype byte");
if (vchSig[0] != 0x30)
return error("Non-canonical signature: wrong type");
- if (vchSig[1] != vchSig.size()-3)
+ if (vchSig[1] != vchSig.size() - (fWithHashType ? 3 : 2))
return error("Non-canonical signature: wrong length marker");
+ if (fWithHashType) {
+ unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));
+ if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
+ return error("Non-canonical signature: unknown hashtype byte");
+ }
unsigned int nLenR = vchSig[3];
if (5 + nLenR >= vchSig.size())
return error("Non-canonical signature: S length misplaced");
unsigned int nLenS = vchSig[5+nLenR];
- if ((unsigned long)(nLenR+nLenS+7) != vchSig.size())
+ if ((unsigned long)(nLenR + nLenS + (fWithHashType ? 7 : 6)) != vchSig.size())
return error("Non-canonical signature: R+S length mismatch");
const unsigned char *R = &vchSig[4];
if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80))
return error("Non-canonical signature: S value excessively padded");
- if (flags & SCRIPT_VERIFY_LOW_S) {
+ if (fCheckLow) {
+ unsigned int nLenR = vchSig[3];
+ unsigned int nLenS = vchSig[5+nLenR];
+ const unsigned char *S = &vchSig[6+nLenR];
+ // If the S value is above the order of the curve divided by two, its
+ // complement modulo the order could have been used instead, which is
+ // one byte shorter when encoded correctly.
if (!CKey::CheckSignatureElement(S, nLenS, true))
return error("Non-canonical signature: S value is unnecessarily high");
}
return true;
}
+bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) {
+ if (!(flags & SCRIPT_VERIFY_STRICTENC))
+ return true;
+
+ return IsDERSignature(vchSig, true, (flags & SCRIPT_VERIFY_LOW_S) != 0);
+}
+
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType)
{
CAutoBN_CTX pctx;
class CAffectedKeysVisitor : public boost::static_visitor<void> {
private:
const CKeyStore &keystore;
+ CAffectedKeysVisitor& operator=(CAffectedKeysVisitor const&);
std::vector<CKeyID> &vKeys;
public: