aboutsummaryrefslogtreecommitdiff
path: root/src/script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script.cpp')
-rw-r--r--src/script.cpp72
1 files changed, 39 insertions, 33 deletions
diff --git a/src/script.cpp b/src/script.cpp
index 810ba16d28..ac6d4b316f 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -5,7 +5,6 @@
#include "script.h"
-#include "bignum.h"
#include "core.h"
#include "hash.h"
#include "key.h"
@@ -25,22 +24,13 @@ typedef vector<unsigned char> valtype;
static const valtype vchFalse(0);
static const valtype vchZero(0);
static const valtype vchTrue(1, 1);
-static const CBigNum bnZero(0);
-static const CBigNum bnOne(1);
-static const CBigNum bnFalse(0);
-static const CBigNum bnTrue(1);
-static const size_t nMaxNumSize = 4;
+static const CScriptNum bnZero(0);
+static const CScriptNum bnOne(1);
+static const CScriptNum bnFalse(0);
+static const CScriptNum bnTrue(1);
bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags);
-CBigNum CastToBigNum(const valtype& vch)
-{
- if (vch.size() > nMaxNumSize)
- throw runtime_error("CastToBigNum() : overflow");
- // Get rid of extra leading zeros
- return CBigNum(CBigNum(vch).getvch());
-}
-
bool CastToBool(const valtype& vch)
{
for (unsigned int i = 0; i < vch.size(); i++)
@@ -296,9 +286,12 @@ bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) {
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");
+ if (flags & SCRIPT_VERIFY_LOW_S) {
+ // 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;
@@ -306,7 +299,6 @@ bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) {
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType)
{
- CAutoBN_CTX pctx;
CScript::const_iterator pc = script.begin();
CScript::const_iterator pend = script.end();
CScript::const_iterator pbegincodehash = script.begin();
@@ -380,7 +372,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
case OP_16:
{
// ( -- value)
- CBigNum bn((int)opcode - (int)(OP_1 - 1));
+ CScriptNum bn((int)opcode - (int)(OP_1 - 1));
stack.push_back(bn.getvch());
}
break;
@@ -556,7 +548,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
case OP_DEPTH:
{
// -- stacksize
- CBigNum bn(stack.size());
+ CScriptNum bn(stack.size());
stack.push_back(bn.getvch());
}
break;
@@ -606,7 +598,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
if (stack.size() < 2)
return false;
- int n = CastToBigNum(stacktop(-1)).getint();
+ int n = CScriptNum(stacktop(-1)).getint();
popstack(stack);
if (n < 0 || n >= (int)stack.size())
return false;
@@ -654,7 +646,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// (in -- in size)
if (stack.size() < 1)
return false;
- CBigNum bn(stacktop(-1).size());
+ CScriptNum bn(stacktop(-1).size());
stack.push_back(bn.getvch());
}
break;
@@ -705,7 +697,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// (in -- out)
if (stack.size() < 1)
return false;
- CBigNum bn = CastToBigNum(stacktop(-1));
+ CScriptNum bn(stacktop(-1));
switch (opcode)
{
case OP_1ADD: bn += bnOne; break;
@@ -738,9 +730,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// (x1 x2 -- out)
if (stack.size() < 2)
return false;
- CBigNum bn1 = CastToBigNum(stacktop(-2));
- CBigNum bn2 = CastToBigNum(stacktop(-1));
- CBigNum bn;
+ CScriptNum bn1(stacktop(-2));
+ CScriptNum bn2(stacktop(-1));
+ CScriptNum bn(0);
switch (opcode)
{
case OP_ADD:
@@ -783,9 +775,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// (x min max -- out)
if (stack.size() < 3)
return false;
- CBigNum bn1 = CastToBigNum(stacktop(-3));
- CBigNum bn2 = CastToBigNum(stacktop(-2));
- CBigNum bn3 = CastToBigNum(stacktop(-1));
+ CScriptNum bn1(stacktop(-3));
+ CScriptNum bn2(stacktop(-2));
+ CScriptNum bn3(stacktop(-1));
bool fValue = (bn2 <= bn1 && bn1 < bn3);
popstack(stack);
popstack(stack);
@@ -882,7 +874,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
if ((int)stack.size() < i)
return false;
- int nKeysCount = CastToBigNum(stacktop(-i)).getint();
+ int nKeysCount = CScriptNum(stacktop(-i)).getint();
if (nKeysCount < 0 || nKeysCount > 20)
return false;
nOpCount += nKeysCount;
@@ -893,7 +885,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
if ((int)stack.size() < i)
return false;
- int nSigsCount = CastToBigNum(stacktop(-i)).getint();
+ int nSigsCount = CScriptNum(stacktop(-i)).getint();
if (nSigsCount < 0 || nSigsCount > nKeysCount)
return false;
int isig = ++i;
@@ -934,8 +926,22 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
fSuccess = false;
}
- while (i-- > 0)
+ // Clean up stack of actual arguments
+ while (i-- > 1)
popstack(stack);
+
+ // A bug causes CHECKMULTISIG to consume one extra argument
+ // whose contents were not checked in any way.
+ //
+ // Unfortunately this is a potential source of mutability,
+ // so optionally verify it is exactly equal to zero prior
+ // to removing it from the stack.
+ if (stack.size() < 1)
+ return false;
+ if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size())
+ return error("CHECKMULTISIG dummy argument not null");
+ popstack(stack);
+
stack.push_back(fSuccess ? vchTrue : vchFalse);
if (opcode == OP_CHECKMULTISIGVERIFY)
@@ -1670,7 +1676,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransa
}
// Test solution
- return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, 0);
+ return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STANDARD_SCRIPT_VERIFY_FLAGS, 0);
}
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType)