Skip to content

Commit e203010

Browse files
Fix BIP143 standardness rules for CHECKMULTISIG
From https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#restrictions-on-public-key-type > As a default policy, only compressed public keys are accepted in P2WPKH and > P2WSH. Each public key passed to a sigop inside version 0 witness program must > be a compressed key: the first byte MUST be either 0x02 or 0x03, and the size > MUST be 33 bytes. Transactions that break this rule will not be relayed or mined > by default. PR bitcoin#8499 's implemenation is insufficent to meet BIP143's requirements as it only checks those pubkeys processed by CHECKMULTISIG, whereas BIP143 requires that every public key passed to the CHECKMULTISIG be validated. Note: these restrictions are policy only and not consensus rules.
1 parent 305384a commit e203010

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

src/script/interpreter.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,10 @@ bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, script_ver
215215
return true;
216216
}
217217

218-
bool static CheckPubKeyEncoding(const valtype &vchPubKey, script_verify_flags flags, const SigVersion &sigversion, ScriptError* serror) {
218+
bool static CheckPubKeyEncoding(const valtype &vchPubKey, script_verify_flags flags, ScriptError* serror) {
219219
if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchPubKey)) {
220220
return set_error(serror, SCRIPT_ERR_PUBKEYTYPE);
221221
}
222-
// Only compressed keys are accepted in segwit
223-
if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SigVersion::WITNESS_V0 && !IsCompressedPubKey(vchPubKey)) {
224-
return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE);
225-
}
226222
return true;
227223
}
228224

@@ -332,10 +328,16 @@ static bool EvalChecksigPreTapscript(const valtype& vchSig, const valtype& vchPu
332328
return set_error(serror, SCRIPT_ERR_SIG_FINDANDDELETE);
333329
}
334330

335-
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) {
331+
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
336332
//serror is set
337333
return false;
338334
}
335+
336+
if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SigVersion::WITNESS_V0 && !IsCompressedPubKey(vchPubKey)) {
337+
// Only compressed keys are accepted in segwit
338+
return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE);
339+
}
340+
339341
fSuccess = checker.CheckECDSASignature(vchSig, vchPubKey, scriptCode, sigversion);
340342

341343
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size())
@@ -1149,6 +1151,16 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
11491151
}
11501152
}
11511153

1154+
if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SigVersion::WITNESS_V0) {
1155+
for (int k = 0; k < nKeysCount; k++) {
1156+
valtype& vchPubKey = stacktop(-ikey-k);
1157+
if (!IsCompressedPubKey(vchPubKey)) {
1158+
// Only compressed keys are accepted in segwit
1159+
return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE);
1160+
}
1161+
}
1162+
}
1163+
11521164
bool fSuccess = true;
11531165
while (fSuccess && nSigsCount > 0)
11541166
{
@@ -1158,7 +1170,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
11581170
// Note how this makes the exact order of pubkey/signature evaluation
11591171
// distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set.
11601172
// See the script_(in)valid tests for details.
1161-
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) {
1173+
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
11621174
// serror is set
11631175
return false;
11641176
}

0 commit comments

Comments
 (0)