Changeset View
Changeset View
Standalone View
Standalone View
src/script/interpreter.cpp
Show First 20 Lines • Show All 870 Lines • ▼ Show 20 Lines | try { | ||||
// (sig pubkey -- bool) | // (sig pubkey -- bool) | ||||
if (stack.size() < 2) { | if (stack.size() < 2) { | ||||
return set_error( | return set_error( | ||||
serror, SCRIPT_ERR_INVALID_STACK_OPERATION); | serror, SCRIPT_ERR_INVALID_STACK_OPERATION); | ||||
} | } | ||||
valtype &vchSig = stacktop(-2); | valtype &vchSig = stacktop(-2); | ||||
valtype &vchPubKey = stacktop(-1); | valtype &vchPubKey = stacktop(-1); | ||||
if (!CheckTransactionSignatureEncoding(vchSig, flags, | if (!CheckTransactionECDSASignatureEncoding( | ||||
deadalnix: See comments on checkdatasig. | |||||
serror) || | vchSig, flags, serror) || | ||||
!CheckPubKeyEncoding(vchPubKey, flags, serror)) { | !CheckPubKeyEncoding(vchPubKey, flags, serror)) { | ||||
// serror is set | // serror is set | ||||
return false; | return false; | ||||
} | } | ||||
// Subset of script starting at the most recent | // Subset of script starting at the most recent | ||||
// codeseparator | // codeseparator | ||||
CScript scriptCode(pbegincodehash, pend); | CScript scriptCode(pbegincodehash, pend); | ||||
// Remove signature for pre-fork scripts | // Remove signature for pre-fork scripts | ||||
CleanupScriptCode(scriptCode, vchSig, flags); | CleanupScriptCode(scriptCode, vchSig, flags); | ||||
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, | bool fSuccess = checker.CheckSigECDSA( | ||||
scriptCode, flags); | vchSig, vchPubKey, scriptCode, flags); | ||||
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && | if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && | ||||
vchSig.size()) { | vchSig.size()) { | ||||
return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); | return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); | ||||
} | } | ||||
popstack(stack); | popstack(stack); | ||||
popstack(stack); | popstack(stack); | ||||
Show All 20 Lines | try { | ||||
return set_error( | return set_error( | ||||
serror, SCRIPT_ERR_INVALID_STACK_OPERATION); | serror, SCRIPT_ERR_INVALID_STACK_OPERATION); | ||||
} | } | ||||
valtype &vchSig = stacktop(-3); | valtype &vchSig = stacktop(-3); | ||||
valtype &vchMessage = stacktop(-2); | valtype &vchMessage = stacktop(-2); | ||||
valtype &vchPubKey = stacktop(-1); | valtype &vchPubKey = stacktop(-1); | ||||
if (!CheckDataSignatureEncoding(vchSig, flags, | if (!CheckDataECDSASignatureEncoding(vchSig, flags, | ||||
deadalnixUnsubmitted Not Done Inline ActionsYou don't want to be doing this as this isn't a codepath that is specific to ECDSA. t is not the responsability of the opcode to know what is the encoding of the signature. deadalnix: You don't want to be doing this as this isn't a codepath that is specific to ECDSA. t is not… | |||||
deadalnixUnsubmitted Not Done Inline ActionsSee this comment ^ deadalnix: See this comment ^ | |||||
markblundebergAuthorUnsubmitted Done Inline ActionsFor 'naked' 64 byte Schnorr signatures, EvalScript is the only place where all necessary information is available on which signatures are acceptable / accepted. Inspection of flags and vchSig is not sufficient. markblundeberg: For 'naked' 64 byte Schnorr signatures, EvalScript is the only place where all necessary… | |||||
serror) || | serror) || | ||||
!CheckPubKeyEncoding(vchPubKey, flags, serror)) { | !CheckPubKeyEncoding(vchPubKey, flags, serror)) { | ||||
// serror is set | // serror is set | ||||
return false; | return false; | ||||
} | } | ||||
bool fSuccess = false; | bool fSuccess = false; | ||||
if (vchSig.size()) { | if (vchSig.size()) { | ||||
valtype vchHash(32); | valtype vchHash(32); | ||||
CSHA256() | CSHA256() | ||||
.Write(vchMessage.data(), vchMessage.size()) | .Write(vchMessage.data(), vchMessage.size()) | ||||
.Finalize(vchHash.data()); | .Finalize(vchHash.data()); | ||||
fSuccess = checker.VerifySignature( | fSuccess = checker.VerifySignatureECDSA( | ||||
vchSig, CPubKey(vchPubKey), uint256(vchHash)); | vchSig, CPubKey(vchPubKey), uint256(vchHash)); | ||||
} | } | ||||
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && | if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && | ||||
vchSig.size()) { | vchSig.size()) { | ||||
return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); | return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | try { | ||||
while (fSuccess && nSigsCount > 0) { | while (fSuccess && nSigsCount > 0) { | ||||
valtype &vchSig = stacktop(-isig); | valtype &vchSig = stacktop(-isig); | ||||
valtype &vchPubKey = stacktop(-ikey); | valtype &vchPubKey = stacktop(-ikey); | ||||
// Note how this makes the exact order of | // Note how this makes the exact order of | ||||
// pubkey/signature evaluation distinguishable by | // pubkey/signature evaluation distinguishable by | ||||
// CHECKMULTISIG NOT if the STRICTENC flag is set. | // CHECKMULTISIG NOT if the STRICTENC flag is set. | ||||
// See the script_(in)valid tests for details. | // See the script_(in)valid tests for details. | ||||
if (!CheckTransactionSignatureEncoding( | if (!CheckTransactionECDSASignatureEncoding( | ||||
deadalnixUnsubmitted Not Done Inline ActionsThis is the only place where you want to have a change in the interpreter because multisig is the only opcode that care about the sig being ECDSA or schnorr. deadalnix: This is the only place where you want to have a change in the interpreter because multisig is… | |||||
vchSig, flags, serror) || | vchSig, flags, serror) || | ||||
!CheckPubKeyEncoding(vchPubKey, flags, | !CheckPubKeyEncoding(vchPubKey, flags, | ||||
serror)) { | serror)) { | ||||
// serror is set | // serror is set | ||||
return false; | return false; | ||||
} | } | ||||
// Check signature | // Check signature | ||||
bool fOk = checker.CheckSig(vchSig, vchPubKey, | bool fOk = checker.CheckSigECDSA(vchSig, vchPubKey, | ||||
scriptCode, flags); | scriptCode, flags); | ||||
if (fOk) { | if (fOk) { | ||||
isig++; | isig++; | ||||
nSigsCount--; | nSigsCount--; | ||||
} | } | ||||
ikey++; | ikey++; | ||||
nKeysCount--; | nKeysCount--; | ||||
▲ Show 20 Lines • Show All 407 Lines • ▼ Show 20 Lines | uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, | ||||
CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, sigHashType); | CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, sigHashType); | ||||
// Serialize and hash | // Serialize and hash | ||||
CHashWriter ss(SER_GETHASH, 0); | CHashWriter ss(SER_GETHASH, 0); | ||||
ss << txTmp << sigHashType; | ss << txTmp << sigHashType; | ||||
return ss.GetHash(); | return ss.GetHash(); | ||||
} | } | ||||
bool BaseSignatureChecker::VerifySignature(const std::vector<uint8_t> &vchSig, | bool BaseSignatureChecker::VerifySignatureECDSA( | ||||
const CPubKey &pubkey, | const std::vector<uint8_t> &vchSig, const CPubKey &pubkey, | ||||
const uint256 &sighash) const { | const uint256 &sighash) const { | ||||
return pubkey.Verify(sighash, vchSig); | return pubkey.Verify(sighash, vchSig); | ||||
} | } | ||||
bool TransactionSignatureChecker::CheckSig( | bool TransactionSignatureChecker::CheckSigECDSA( | ||||
const std::vector<uint8_t> &vchSigIn, const std::vector<uint8_t> &vchPubKey, | const std::vector<uint8_t> &vchSigIn, const std::vector<uint8_t> &vchPubKey, | ||||
const CScript &scriptCode, uint32_t flags) const { | const CScript &scriptCode, uint32_t flags) const { | ||||
CPubKey pubkey(vchPubKey); | CPubKey pubkey(vchPubKey); | ||||
if (!pubkey.IsValid()) { | if (!pubkey.IsValid()) { | ||||
return false; | return false; | ||||
} | } | ||||
// Hash type is one byte tacked on to the end of the signature | // Hash type is one byte tacked on to the end of the signature | ||||
std::vector<uint8_t> vchSig(vchSigIn); | std::vector<uint8_t> vchSig(vchSigIn); | ||||
if (vchSig.empty()) { | if (vchSig.empty()) { | ||||
return false; | return false; | ||||
} | } | ||||
SigHashType sigHashType = GetHashType(vchSig); | SigHashType sigHashType = GetHashType(vchSig); | ||||
vchSig.pop_back(); | vchSig.pop_back(); | ||||
uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, sigHashType, amount, | uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, sigHashType, amount, | ||||
this->txdata, flags); | this->txdata, flags); | ||||
if (!VerifySignature(vchSig, pubkey, sighash)) { | if (!VerifySignatureECDSA(vchSig, pubkey, sighash)) { | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool TransactionSignatureChecker::CheckLockTime( | bool TransactionSignatureChecker::CheckLockTime( | ||||
const CScriptNum &nLockTime) const { | const CScriptNum &nLockTime) const { | ||||
▲ Show 20 Lines • Show All 166 Lines • Show Last 20 Lines |
See comments on checkdatasig.