diff options
Diffstat (limited to 'src/script.cpp')
| -rw-r--r-- | src/script.cpp | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/src/script.cpp b/src/script.cpp index 14fe80e20..0fe295354 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -2,12 +2,6 @@ // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <boost/foreach.hpp> -#include <boost/tuple/tuple.hpp> - -using namespace std; -using namespace boost; - #include "script.h" #include "core.h" #include "keystore.h" @@ -16,6 +10,12 @@ using namespace boost; #include "sync.h" #include "util.h" +#include <boost/foreach.hpp> +#include <boost/tuple/tuple.hpp> + +using namespace std; +using namespace boost; + bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags); @@ -227,7 +227,10 @@ const char* GetOpName(opcodetype opcode) } } -bool IsCanonicalPubKey(const valtype &vchPubKey) { +bool IsCanonicalPubKey(const valtype &vchPubKey, unsigned int flags) { + if (!(flags & SCRIPT_VERIFY_STRICTENC)) + return true; + if (vchPubKey.size() < 33) return error("Non-canonical public key: too short"); if (vchPubKey[0] == 0x04) { @@ -242,7 +245,10 @@ bool IsCanonicalPubKey(const valtype &vchPubKey) { return true; } -bool IsCanonicalSignature(const valtype &vchSig) { +bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) { + if (!(flags & SCRIPT_VERIFY_STRICTENC)) + return true; + // 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 @@ -286,6 +292,11 @@ bool IsCanonicalSignature(const valtype &vchSig) { if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80)) return error("Non-canonical signature: S value excessively padded"); + if (flags & SCRIPT_VERIFY_EVEN_S) { + if (S[nLenS-1] & 1) + return error("Non-canonical signature: S value odd"); + } + return true; } @@ -302,7 +313,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co if (script.size() > 10000) return false; int nOpCount = 0; - bool fStrictEncodings = flags & SCRIPT_VERIFY_STRICTENC; try { @@ -317,6 +327,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co return false; if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE) return false; + + // Note how OP_RESERVED does not count towards the opcode limit. if (opcode > OP_16 && ++nOpCount > 201) return false; @@ -841,9 +853,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // Drop the signature, since there's no way for a signature to sign itself scriptCode.FindAndDelete(CScript(vchSig)); - bool fSuccess = (!fStrictEncodings || (IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey))); - if (fSuccess) - fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); + bool fSuccess = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && + CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); popstack(stack); popstack(stack); @@ -903,9 +914,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co valtype& vchPubKey = stacktop(-ikey); // Check signature - bool fOk = (!fStrictEncodings || (IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey))); - if (fOk) - fOk = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); + bool fOk = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && + CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType, flags); if (fOk) { isig++; @@ -967,7 +977,7 @@ uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int { if (nIn >= txTo.vin.size()) { - printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + LogPrintf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); return 1; } CTransaction txTmp(txTo); @@ -998,7 +1008,7 @@ uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int unsigned int nOut = nIn; if (nOut >= txTmp.vout.size()) { - printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); + LogPrintf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); return 1; } txTmp.vout.resize(nOut+1); @@ -1163,7 +1173,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi // Compare CScript::const_iterator pc1 = script1.begin(); CScript::const_iterator pc2 = script2.begin(); - loop + while (true) { if (pc1 == script1.end() && pc2 == script2.end()) { |