Skip to content

Commit 53f1044

Browse files
Relax standardness rules regarding CHECKMULTISIG
In PR bitcoin#5247, the STRICTENC standardness rules were tightned with regards to CHECKMULTISIG so that unparsable public keys fail the script when they are encountered. The overall purpose here was to disallow the use of confusing hybrid public keys by policy while remaining keeping policy compatible (i.e. strictly stronger) than consensus rules. Comments in PR bitcoin#5247 note that "I don't believe it should affect any system in production", however this believe is/was false. Counterparty was stuffing data blobs into multisig pubkey lists. But these UTXOs were meant to be spendable because, although some pubkeys were unparsable, some keys were parsable, and the UTXOs were meant to be spent buy those valid keys. But in tackling the hybrid key issue, PR bitcoin#5247 disallowed any unparsable keys in multisigs, whether or not they were hybrid, and whether or not the signature was meant to satify a hybrid key. In production Counterparty UTXOs were inadvertantly caught up in this standardness rule change and became "soft confiscated", that is not longer spendable by policy but still recoverable if users are able to somehow bypass standardness by mining their transactions themselves, or getting out-of-band assistance from some other miner. I understand that Bitcoin Core never intended to "soft confiscate" any UTXOs by policy changes. This change addresses the problem. With this change standardness rules intended for hybrid keys are only checked after passing a signature check in CHECKMULTISIG operations. Failing signature checks revert to their consensus behaviour of testing subsequent public keys. Counterparty UTXOs were never intended to make use of hybrid keys, and thus shouldn't have any passing signatures using hybrid keys.
1 parent 305384a commit 53f1044

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

src/script/interpreter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
11581158
// Note how this makes the exact order of pubkey/signature evaluation
11591159
// distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set.
11601160
// See the script_(in)valid tests for details.
1161-
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) {
1161+
if (!CheckSignatureEncoding(vchSig, flags, serror)) {
11621162
// serror is set
11631163
return false;
11641164
}
@@ -1167,6 +1167,10 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
11671167
bool fOk = checker.CheckECDSASignature(vchSig, vchPubKey, scriptCode, sigversion);
11681168

11691169
if (fOk) {
1170+
if (!CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) {
1171+
// serror is set
1172+
return false;
1173+
}
11701174
isig++;
11711175
nSigsCount--;
11721176
}

0 commit comments

Comments
 (0)