// Copyright (c) 2009-2010 Satoshi Nakamoto
// 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
#include
#include
using namespace std;
using namespace boost;
#include "script.h"
#include "keystore.h"
#include "bignum.h"
#include "key.h"
#include "main.h"
#include "sync.h"
#include "util.h"
bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
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;
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++)
{
if (vch[i] != 0)
{
// Can be negative zero
if (i == vch.size()-1 && vch[i] == 0x80)
return false;
return true;
}
}
return false;
}
//
// WARNING: This does not work as expected for signed integers; the sign-bit
// is left in place as the integer is zero-extended. The correct behavior
// would be to move the most significant bit of the last byte during the
// resize process. MakeSameSize() is currently only used by the disabled
// opcodes OP_AND, OP_OR, and OP_XOR.
//
void MakeSameSize(valtype& vch1, valtype& vch2)
{
// Lengthen the shorter one
if (vch1.size() < vch2.size())
// PATCH:
// +unsigned char msb = vch1[vch1.size()-1];
// +vch1[vch1.size()-1] &= 0x7f;
// vch1.resize(vch2.size(), 0);
// +vch1[vch1.size()-1] = msb;
vch1.resize(vch2.size(), 0);
if (vch2.size() < vch1.size())
// PATCH:
// +unsigned char msb = vch2[vch2.size()-1];
// +vch2[vch2.size()-1] &= 0x7f;
// vch2.resize(vch1.size(), 0);
// +vch2[vch2.size()-1] = msb;
vch2.resize(vch1.size(), 0);
}
//
// Script is a stack machine (like Forth) that evaluates a predicate
// returning a bool indicating valid or not. There are no loops.
//
#define stacktop(i) (stack.at(stack.size()+(i)))
#define altstacktop(i) (altstack.at(altstack.size()+(i)))
static inline void popstack(vector& stack)
{
if (stack.empty())
throw runtime_error("popstack() : stack empty");
stack.pop_back();
}
const char* GetTxnOutputType(txnouttype t)
{
switch (t)
{
case TX_NONSTANDARD: return "nonstandard";
case TX_PUBKEY: return "pubkey";
case TX_PUBKEYHASH: return "pubkeyhash";
case TX_SCRIPTHASH: return "scripthash";
case TX_MULTISIG: return "multisig";
}
return NULL;
}
const char* GetOpName(opcodetype opcode)
{
switch (opcode)
{
// push value
case OP_0 : return "0";
case OP_PUSHDATA1 : return "OP_PUSHDATA1";
case OP_PUSHDATA2 : return "OP_PUSHDATA2";
case OP_PUSHDATA4 : return "OP_PUSHDATA4";
case OP_1NEGATE : return "-1";
case OP_RESERVED : return "OP_RESERVED";
case OP_1 : return "1";
case OP_2 : return "2";
case OP_3 : return "3";
case OP_4 : return "4";
case OP_5 : return "5";
case OP_6 : return "6";
case OP_7 : return "7";
case OP_8 : return "8";
case OP_9 : return "9";
case OP_10 : return "10";
case OP_11 : return "11";
case OP_12 : return "12";
case OP_13 : return "13";
case OP_14 : return "14";
case OP_15 : return "15";
case OP_16 : return "16";
// control
case OP_NOP : return "OP_NOP";
case OP_VER : return "OP_VER";
case OP_IF : return "OP_IF";
case OP_NOTIF : return "OP_NOTIF";
case OP_VERIF : return "OP_VERIF";
case OP_VERNOTIF : return "OP_VERNOTIF";
case OP_ELSE : return "OP_ELSE";
case OP_ENDIF : return "OP_ENDIF";
case OP_VERIFY : return "OP_VERIFY";
case OP_RETURN : return "OP_RETURN";
// stack ops
case OP_TOALTSTACK : return "OP_TOALTSTACK";
case OP_FROMALTSTACK : return "OP_FROMALTSTACK";
case OP_2DROP : return "OP_2DROP";
case OP_2DUP : return "OP_2DUP";
case OP_3DUP : return "OP_3DUP";
case OP_2OVER : return "OP_2OVER";
case OP_2ROT : return "OP_2ROT";
case OP_2SWAP : return "OP_2SWAP";
case OP_IFDUP : return "OP_IFDUP";
case OP_DEPTH : return "OP_DEPTH";
case OP_DROP : return "OP_DROP";
case OP_DUP : return "OP_DUP";
case OP_NIP : return "OP_NIP";
case OP_OVER : return "OP_OVER";
case OP_PICK : return "OP_PICK";
case OP_ROLL : return "OP_ROLL";
case OP_ROT : return "OP_ROT";
case OP_SWAP : return "OP_SWAP";
case OP_TUCK : return "OP_TUCK";
// splice ops
case OP_CAT : return "OP_CAT";
case OP_SUBSTR : return "OP_SUBSTR";
case OP_LEFT : return "OP_LEFT";
case OP_RIGHT : return "OP_RIGHT";
case OP_SIZE : return "OP_SIZE";
// bit logic
case OP_INVERT : return "OP_INVERT";
case OP_AND : return "OP_AND";
case OP_OR : return "OP_OR";
case OP_XOR : return "OP_XOR";
case OP_EQUAL : return "OP_EQUAL";
case OP_EQUALVERIFY : return "OP_EQUALVERIFY";
case OP_RESERVED1 : return "OP_RESERVED1";
case OP_RESERVED2 : return "OP_RESERVED2";
// numeric
case OP_1ADD : return "OP_1ADD";
case OP_1SUB : return "OP_1SUB";
case OP_2MUL : return "OP_2MUL";
case OP_2DIV : return "OP_2DIV";
case OP_NEGATE : return "OP_NEGATE";
case OP_ABS : return "OP_ABS";
case OP_NOT : return "OP_NOT";
case OP_0NOTEQUAL : return "OP_0NOTEQUAL";
case OP_ADD : return "OP_ADD";
case OP_SUB : return "OP_SUB";
case OP_MUL : return "OP_MUL";
case OP_DIV : return "OP_DIV";
case OP_MOD : return "OP_MOD";
case OP_LSHIFT : return "OP_LSHIFT";
case OP_RSHIFT : return "OP_RSHIFT";
case OP_BOOLAND : return "OP_BOOLAND";
case OP_BOOLOR : return "OP_BOOLOR";
case OP_NUMEQUAL : return "OP_NUMEQUAL";
case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY";
case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL";
case OP_LESSTHAN : return "OP_LESSTHAN";
case OP_GREATERTHAN : return "OP_GREATERTHAN";
case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL";
case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL";
case OP_MIN : return "OP_MIN";
case OP_MAX : return "OP_MAX";
case OP_WITHIN : return "OP_WITHIN";
// crypto
case OP_RIPEMD160 : return "OP_RIPEMD160";
case OP_SHA1 : return "OP_SHA1";
case OP_SHA256 : return "OP_SHA256";
case OP_HASH160 : return "OP_HASH160";
case OP_HASH256 : return "OP_HASH256";
case OP_CODESEPARATOR : return "OP_CODESEPARATOR";
case OP_CHECKSIG : return "OP_CHECKSIG";
case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY";
case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG";
case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY";
// expanson
case OP_NOP1 : return "OP_NOP1";
case OP_NOP2 : return "OP_NOP2";
case OP_NOP3 : return "OP_NOP3";
case OP_NOP4 : return "OP_NOP4";
case OP_NOP5 : return "OP_NOP5";
case OP_NOP6 : return "OP_NOP6";
case OP_NOP7 : return "OP_NOP7";
case OP_NOP8 : return "OP_NOP8";
case OP_NOP9 : return "OP_NOP9";
case OP_NOP10 : return "OP_NOP10";
// template matching params
case OP_PUBKEYHASH : return "OP_PUBKEYHASH";
case OP_PUBKEY : return "OP_PUBKEY";
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
default:
return "OP_UNKNOWN";
}
}
static bool IsCanonicalPubKey(const valtype &vchPubKey) {
if (vchPubKey.size() < 33)
return error("Non-canonical public key: too short");
if (vchPubKey[0] == 0x04) {
if (vchPubKey.size() != 65)
return error("Non-canonical public key: invalid length for uncompressed key");
} else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {
if (vchPubKey.size() != 33)
return error("Non-canonical public key: invalid length for compressed key");
} else {
return error("Non-canonical public key: compressed nor uncompressed");
}
return true;
}
static bool IsCanonicalSignature(const valtype &vchSig) {
// See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
// A canonical signature exists of:
// Where R and S are not negative (their first byte has its highest bit not set), and not
// excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
// in which case a single 0 byte is necessary and even required).
if (vchSig.size() < 9)
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)
return error("Non-canonical signature: wrong length marker");
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())
return error("Non-canonical signature: R+S length mismatch");
const unsigned char *R = &vchSig[4];
if (R[-2] != 0x02)
return error("Non-canonical signature: R value type mismatch");
if (nLenR == 0)
return error("Non-canonical signature: R length is zero");
if (R[0] & 0x80)
return error("Non-canonical signature: R value negative");
if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80))
return error("Non-canonical signature: R value excessively padded");
const unsigned char *S = &vchSig[6+nLenR];
if (S[-2] != 0x02)
return error("Non-canonical signature: S value type mismatch");
if (nLenS == 0)
return error("Non-canonical signature: S length is zero");
if (S[0] & 0x80)
return error("Non-canonical signature: S value negative");
if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80))
return error("Non-canonical signature: S value excessively padded");
// If the above rules hold, and the S data is 33 bytes (or more), then
// the S value is above 2^255, which isn't necessary (its negative
// modulo the order of the curve could have been used).
if (nLenS > 32)
return error("Non-canonical signature: S value is unnecessarily high");
return true;
}
bool EvalScript(vector& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
CAutoBN_CTX pctx;
CScript::const_iterator pc = script.begin();
CScript::const_iterator pend = script.end();
CScript::const_iterator pbegincodehash = script.begin();
opcodetype opcode;
valtype vchPushValue;
vector vfExec;
vector altstack;
if (script.size() > 10000)
return false;
int nOpCount = 0;
try
{
while (pc < pend)
{
bool fExec = !count(vfExec.begin(), vfExec.end(), false);
//
// Read instruction
//
if (!script.GetOp(pc, opcode, vchPushValue))
return false;
if (vchPushValue.size() > 520)
return false;
if (opcode > OP_16 && ++nOpCount > 201)
return false;
if (opcode == OP_CAT ||
opcode == OP_SUBSTR ||
opcode == OP_LEFT ||
opcode == OP_RIGHT ||
opcode == OP_INVERT ||
opcode == OP_AND ||
opcode == OP_OR ||
opcode == OP_XOR ||
opcode == OP_2MUL ||
opcode == OP_2DIV ||
opcode == OP_MUL ||
opcode == OP_DIV ||
opcode == OP_MOD ||
opcode == OP_LSHIFT ||
opcode == OP_RSHIFT)
return false;
if (fExec && 0 (int)vch.size())
nEnd = vch.size();
vch.erase(vch.begin() + nEnd, vch.end());
vch.erase(vch.begin(), vch.begin() + nBegin);
popstack(stack);
popstack(stack);
}
break;
case OP_LEFT:
case OP_RIGHT:
{
// (in size -- out)
if (stack.size() < 2)
return false;
valtype& vch = stacktop(-2);
int nSize = CastToBigNum(stacktop(-1)).getint();
if (nSize < 0)
return false;
if (nSize > (int)vch.size())
nSize = vch.size();
if (opcode == OP_LEFT)
vch.erase(vch.begin() + nSize, vch.end());
else
vch.erase(vch.begin(), vch.end() - nSize);
popstack(stack);
}
break;
case OP_SIZE:
{
// (in -- in size)
if (stack.size() < 1)
return false;
CBigNum bn(stacktop(-1).size());
stack.push_back(bn.getvch());
}
break;
//
// Bitwise logic
//
case OP_INVERT:
{
// (in - out)
if (stack.size() < 1)
return false;
valtype& vch = stacktop(-1);
for (unsigned int i = 0; i < vch.size(); i++)
vch[i] = ~vch[i];
}
break;
//
// WARNING: These disabled opcodes exhibit unexpected behavior
// when used on signed integers due to a bug in MakeSameSize()
// [see definition of MakeSameSize() above].
//
case OP_AND:
case OP_OR:
case OP_XOR:
{
// (x1 x2 - out)
if (stack.size() < 2)
return false;
valtype& vch1 = stacktop(-2);
valtype& vch2 = stacktop(-1);
MakeSameSize(vch1, vch2); // CBigNum(2048))
return false;
bn = bn1 CBigNum(2048))
return false;
bn = bn1 >> bn2.getulong();
break;
case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break;
case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break;
case OP_NUMEQUAL: bn = (bn1 == bn2); break;
case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break;
case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break;
case OP_LESSTHAN: bn = (bn1 < bn2); break;
case OP_GREATERTHAN: bn = (bn1 > bn2); break;
case OP_LESSTHANOREQUAL: bn = (bn1 = bn2); break;
case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break;
case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break;
default: assert(!"invalid opcode"); break;
}
popstack(stack);
popstack(stack);
stack.push_back(bn.getvch());
if (opcode == OP_NUMEQUALVERIFY)
{
if (CastToBool(stacktop(-1)))
popstack(stack);
else
return false;
}
}
break;
case OP_WITHIN:
{
// (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));
bool fValue = (bn2 0)
{
valtype& vchSig = stacktop(-isig);
valtype& vchPubKey = stacktop(-ikey);
// Check signature
bool fOk = IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey) &&
CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
if (fOk)
{
isig++;
nSigsCount--;
}
ikey++;
nKeysCount--;
// If there are more signatures left than keys left,
// then too many signatures have failed
if (nSigsCount > nKeysCount)
fSuccess = false;
}
while (i-- > 0)
popstack(stack);
stack.push_back(fSuccess ? vchTrue : vchFalse);
if (opcode == OP_CHECKMULTISIGVERIFY)
{
if (fSuccess)
popstack(stack);
else
return false;
}
}
break;
default:
return false;
}
// Size limits
if (stack.size() + altstack.size() > 1000)
return false;
}
}
catch (...)
{
return false;
}
if (!vfExec.empty())
return false;
return true;
}
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
if (nIn >= txTo.vin.size())
{
printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
return 1;
}
CTransaction txTmp(txTo);
// In case concatenating two scripts ends up with two codeseparators,
// or an extra one at the end, this prevents all those possible incompatibilities.
scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));
// Blank out other inputs' signatures
for (unsigned int i = 0; i < txTmp.vin.size(); i++)
txTmp.vin[i].scriptSig = CScript();
txTmp.vin[nIn].scriptSig = scriptCode;
// Blank out some of the outputs
if ((nHashType & 0x1f) == SIGHASH_NONE)
{
// Wildcard payee
txTmp.vout.clear();
// Let the others update at will
for (unsigned int i = 0; i < txTmp.vin.size(); i++)
if (i != nIn)
txTmp.vin[i].nSequence = 0;
}
else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
{
// Only lock-in the txout payee at same index as txin
unsigned int nOut = nIn;
if (nOut >= txTmp.vout.size())
{
printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
return 1;
}
txTmp.vout.resize(nOut+1);
for (unsigned int i = 0; i < nOut; i++)
txTmp.vout[i].SetNull();
// Let the others update at will
for (unsigned int i = 0; i < txTmp.vin.size(); i++)
if (i != nIn)
txTmp.vin[i].nSequence = 0;
}
// Blank out other inputs completely, not recommended for open transactions
if (nHashType & SIGHASH_ANYONECANPAY)
{
txTmp.vin[0] = txTmp.vin[nIn];
txTmp.vin.resize(1);
}
// Serialize and hash
CDataStream ss(SER_GETHASH, 0);
ss.reserve(10000);
ss signature by matching sigs to pubkeys:
assert(vSolutions.size() > 1);
unsigned int nSigsRequired = vSolutions.front()[0];
unsigned int nPubKeys = vSolutions.size()-2;
map sigs;
BOOST_FOREACH(const valtype& sig, allsigs)
{
for (unsigned int i = 0; i < nPubKeys; i++)
{
const valtype& pubkey = vSolutions[i+1];
if (sigs.count(pubkey))
continue; // Already got a sig for this pubkey
if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0))
{
sigs[pubkey] = sig;
break;
}
}
}
// Now build a merged CScript:
unsigned int nSigsHave = 0;
CScript result; result