diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1011,55 +1011,125 @@ // codeseparator CScript scriptCode(pbegincodehash, pend); - // 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. - if ((flags & SCRIPT_VERIFY_NULLDUMMY) && - stacktop(-idummy).size()) { - return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY); - } - - // Remove signature for pre-fork scripts - for (int k = 0; k < nSigsCount; k++) { - valtype &vchSig = stacktop(-isig - k); - CleanupScriptCode(scriptCode, vchSig, flags); - } - - while (fSuccess && nSigsCount > 0) { - valtype &vchSig = stacktop(-isig); - valtype &vchPubKey = stacktop(-ikey); - - // Note how this makes the exact order of - // pubkey/signature evaluation distinguishable by - // CHECKMULTISIG NOT if the STRICTENC flag is set. - // See the script_(in)valid tests for details. - if (!CheckTransactionECDSASignatureEncoding( - vchSig, flags, serror) || - !CheckPubKeyEncoding(vchPubKey, flags, - serror)) { - // serror is set - return false; + if ((flags & SCRIPT_ENABLE_NEW_MULTISIG) && + (stacktop(-idummy).size() != 0)) { + // NEW MULTISIG (SCHNORR / NULL) + + // "Dummy" element is now an integer whose bits + // represent which pubkeys should be checked. Note + // that the int type must support numbers as large + // as 1 << MAX_PUBKEYS_PER_MULTISIG for the getint() + // overflow clamping to work correctly here. + int nCheckBits = + CScriptNum(stacktop(-idummy), fRequireMinimal) + .getint(); + if (nCheckBits < 0) { + return set_error(serror, + SCRIPT_ERR_INVALID_CHECKBITS); } - // Check signature - bool fOk = checker.CheckSig(vchSig, vchPubKey, - scriptCode, flags); + while (nSigsCount > 0 && nKeysCount > 0) { + if (nCheckBits & 1) { + // Check signature as requested + valtype &vchPubKey = stacktop(-ikey); + valtype &vchSig = stacktop(-isig); + if (!CheckTransactionSchnorrSignatureEncoding( + vchSig, flags, serror) || + !CheckPubKeyEncoding(vchPubKey, flags, + serror)) { + // serror is set + return false; + } + if (!checker.CheckSig(vchSig, vchPubKey, + scriptCode, flags)) { + // It is forbidden to request invalid + // signature. Make the error message a + // bit informative though. + return set_error( + serror, + vchSig.size() + ? SCRIPT_ERR_SIG_NULLFAIL + : SCRIPT_ERR_SIG_NULLDUMMY); + } + // A successful checksig is the only way to + // decrement nSigsCount. + isig++; + nSigsCount--; + } + nCheckBits >>= 1; + ikey++; + nKeysCount--; + } + if (nCheckBits != 0) { + // Ended before consuming all bits, because too + // many bits were set, or too-high bits were + // set. + return set_error(serror, + SCRIPT_ERR_INVALID_CHECKBITS); + } + if (nSigsCount > 0) { + // Ended before checking all signatures, because + // too few bits were set. This can return false + // (without error) if all signatures were null + // and nCheckBits was 0 to start. + fSuccess = false; + } + } else { + // LEGACY MULTISIG (ECDSA / NULL) + // 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. + if ((flags & SCRIPT_VERIFY_NULLDUMMY) && + stacktop(-idummy).size()) { + return set_error(serror, + SCRIPT_ERR_SIG_NULLDUMMY); + } - if (fOk) { - isig++; - nSigsCount--; + // Remove signature for pre-fork scripts + for (int k = 0; k < nSigsCount; k++) { + valtype &vchSig = stacktop(-isig - k); + CleanupScriptCode(scriptCode, vchSig, flags); } - ikey++; - nKeysCount--; - // If there are more signatures left than keys left, - // then too many signatures have failed. Exit early, - // without checking any further signatures. - if (nSigsCount > nKeysCount) { - fSuccess = false; + while (fSuccess && nSigsCount > 0) { + valtype &vchSig = stacktop(-isig); + valtype &vchPubKey = stacktop(-ikey); + + // Note how this makes the exact order of + // pubkey/signature evaluation distinguishable + // by CHECKMULTISIG NOT if the STRICTENC flag is + // set. See the script_(in)valid tests for + // details. + if (!CheckTransactionECDSASignatureEncoding( + vchSig, flags, serror) || + !CheckPubKeyEncoding(vchPubKey, flags, + serror)) { + // serror is set + return false; + } + + // Check signature + bool fOk = checker.CheckSig(vchSig, vchPubKey, + scriptCode, flags); + + if (fOk) { + isig++; + nSigsCount--; + } + ikey++; + nKeysCount--; + + // If there are more signatures left than keys + // left, then too many signatures have failed. + // Exit early, without checking any further + // signatures. + if (nSigsCount > nKeysCount) { + fSuccess = false; + } } } diff --git a/src/script/script_error.h b/src/script/script_error.h --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -25,6 +25,7 @@ SCRIPT_ERR_INVALID_NUMBER_RANGE, SCRIPT_ERR_IMPOSSIBLE_ENCODING, SCRIPT_ERR_INVALID_SPLIT_RANGE, + SCRIPT_ERR_INVALID_CHECKBITS, /* Failed verify operations */ SCRIPT_ERR_VERIFY, diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -45,6 +45,8 @@ return "The requested encoding is impossible to satisfy"; case SCRIPT_ERR_INVALID_SPLIT_RANGE: return "Invalid OP_SPLIT range"; + case SCRIPT_ERR_INVALID_CHECKBITS: + return "Invalid checkbits value in OP_CHECKMULTISIG"; case SCRIPT_ERR_BAD_OPCODE: return "Opcode missing or not understood"; case SCRIPT_ERR_DISABLED_OPCODE: diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -2942,6 +2942,244 @@ "SIG_BADLENGTH", "recovered-pubkey CHECKMULTISIG with 64-byte DER w/ NEW_MULTISIG" ], +[ + "1 0x41 0x105e4fed395e64ca013ac1ce020ef69b9990a577fe4b74648faafb69e499f76dd53d5c64aa866924361dd3aadde9b7184bbcb4f79520396c9ed17c4d8489a59701", + "1 0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 1 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 1-of-1" +], +[ + "0x02 0x0100 0x41 0x105e4fed395e64ca013ac1ce020ef69b9990a577fe4b74648faafb69e499f76dd53d5c64aa866924361dd3aadde9b7184bbcb4f79520396c9ed17c4d8489a59701", + "1 0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 1 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "UNKNOWN_ERROR", + "New-CHECKMULTISIG 1-of-1 nonminimal bits" +], +[ + "7 0x41 0x833682d4f60cc916a22a2c263e658fa662c49badb1e2a8c6208987bf99b1abd740498371480069e7a7a6e7471bf78c27bd9a1fd04fb212a92017346250ac187b01 0x41 0xea4a8d20562a950f4695dc24804565482e9fa111704886179d0c348f2b8a15fe691a305cd599c59c131677146661d5b98cb935330989a85f33afc70d0a21add101 0x41 0xce9011d76a4df05d6280b2382b4d91490dbec7c3e72dc826be1fc9b4718f627955190745cac96521ea46d6d324c7376461e225310e6cd605b9f266d170769b7901", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 3-of-3" +], +[ + "15 0x41 0x6d1d1f8db2b4e43a51b4f5f16367045f9c1832b8103ce2bab3a21afc223351a685e84bca02c863110e7ad22d4735cd31e1908e741530e3a07863292c3ff21df901 0x41 0x6d1d1f8db2b4e43a51b4f5f16367045f9c1832b8103ce2bab3a21afc223351a685e84bca02c863110e7ad22d4735cd31e1908e741530e3a07863292c3ff21df901 0x41 0x98ac816c0adb14db2a593f6402bf70e347a219fba0ccad805a5e37a67e265c800b1d493440965634fe740852fbe4164ec45a722a463099ae8a9872896da972ef01 0x41 0xe62867a73ae91b390f6ae11717d360fbc7e813a6dc3917040556834350d5b3cfb464e7222a716f37a32ba3fee353ad4957aa3f47cf7ea1285873bc9a0e64759801", + "4 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "SIG_COUNT", + "New-CHECKMULTISIG 4-of-3" +], +[ + "3 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001 0x41 0xa3fac6b1aa2cc8bb222ee379711c243b26a164ced7f2e2f4a0e184a3e53352bfaee598c6446861e5a7e819871b7ce948f5562ecf214c19dfa5112c19d74adc7101", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 2-of-3 (011)" +], +[ + "5 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101 0x41 0xa3fac6b1aa2cc8bb222ee379711c243b26a164ced7f2e2f4a0e184a3e53352bfaee598c6446861e5a7e819871b7ce948f5562ecf214c19dfa5112c19d74adc7101", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 2-of-3 (101)" +], +[ + "6 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 2-of-3 (110)" +], +[ + "5 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "NULLFAIL", + "New-CHECKMULTISIG 2-of-3 mismatched bits" +], +[ + "7 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001 0x41 0xa3fac6b1aa2cc8bb222ee379711c243b26a164ced7f2e2f4a0e184a3e53352bfaee598c6446861e5a7e819871b7ce948f5562ecf214c19dfa5112c19d74adc7101", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "CHECKBITS", + "New-CHECKMULTISIG 2-of-3 all bits set" +], +[ + "14 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "CHECKBITS", + "New-CHECKMULTISIG 2-of-3 extra high bit set" +], +[ + "10 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "CHECKBITS", + "New-CHECKMULTISIG 2-of-3 too high bit set" +], +[ + "2 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "NULLFAIL", + "New-CHECKMULTISIG 2-of-3 too few bits set" +], +[ + "0x01 0x86 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "CHECKBITS", + "New-CHECKMULTISIG 2-of-3 negative bits" +], +[ + "0 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "SIG_BADLENGTH", + "CHECKMULTISIG null dummy with schnorr sigs (with SCRIPT_ENABLE_NEW_MULTISIG on)" +], +[ + "6 0x41 0x4829a4df8042001ba6a3ee6ec1e9c26de662aade55a49f8d018acff0bac0df2edd881cf21f2a1aa651b6f703f0cde22fedaa9b8bc3451101bcac37bcb89dcc8001 0x41 0xb8c744ebecfa75ef478b2b8852795d93b99640e5c05421ef6f651d4044be6cf2db2c61d0b5395e685731556c87e501433fb6e6a3b44c113d0ba19df8fd01c18101", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "NULLFAIL", + "New-CHECKMULTISIG 2-of-3 misordered signatures" +], +[ + "0x02 0x8100 0x41 0x34b9918c9cd9aa3ad0f642f1dd435164e7bed979e539b2890b8d465b70db47385c514a21b1c6659ab40b8e5395ceae8f6c67c6f4c24e940cbe0a6fe496e7d15e01 0x41 0x057e3e62dbcf8a1bd3526271ad63f568bdae4d248bd87dfcf4a80b9f6da28e0994e04c670a56e624301141f53efc9a40f7d503171809e3f70d5aee203a90567d01", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 DUP 2DUP 2DUP 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 8 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 2-of-8 right way to represent 0b10000001" +], +[ + "0x01 0x81 0x41 0x34b9918c9cd9aa3ad0f642f1dd435164e7bed979e539b2890b8d465b70db47385c514a21b1c6659ab40b8e5395ceae8f6c67c6f4c24e940cbe0a6fe496e7d15e01 0x41 0x057e3e62dbcf8a1bd3526271ad63f568bdae4d248bd87dfcf4a80b9f6da28e0994e04c670a56e624301141f53efc9a40f7d503171809e3f70d5aee203a90567d01", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 DUP 2DUP 2DUP 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 8 CHECKMULTISIG", + "NEW_MULTISIG,NULLFAIL,STRICTENC", + "CHECKBITS", + "New-CHECKMULTISIG 2-of-8 wrong way to represent 0b10000001" +], +[ + "0x03 0xffff0f 0x41 0x5f4f7ffff1fa44347dbc148d51fe661b60fbc44b5abe22a04d97ecfb891bdb2568eb91aa38a426dfd7b82e0b45b57af6f3e56143fabc850ebfdfcf6a0d03c4b001 0x41 0x28add881f6fa489a9016f066022ed80acecbafc351a6d17025cf87bf2b0d9b09f6d001f5df2b1be0d1909a8fe9280b59b5a8cb6d1e37425e733ff3267ce1e1b401 0x41 0x9f66f20bca4a64fc3cc170c3e1ef2bcb62f86b719b2f8e7154407e9210fde99164d754f787bf65020dc7db3838c8aae3591eaf465f45433fcb3d0a94bea4090401", + "OVER DUP DUP 2DUP 3DUP 3DUP 3DUP 3DUP 0x01 0x14 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 OVER DUP DUP 2DUP 3DUP 3DUP 3DUP 3DUP 0x01 0x14 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 20-of-20" +], +[ + "0x03 0x000010 0x41 0x5f4f7ffff1fa44347dbc148d51fe661b60fbc44b5abe22a04d97ecfb891bdb2568eb91aa38a426dfd7b82e0b45b57af6f3e56143fabc850ebfdfcf6a0d03c4b001 0x41 0x28add881f6fa489a9016f066022ed80acecbafc351a6d17025cf87bf2b0d9b09f6d001f5df2b1be0d1909a8fe9280b59b5a8cb6d1e37425e733ff3267ce1e1b401 0x41 0x9f66f20bca4a64fc3cc170c3e1ef2bcb62f86b719b2f8e7154407e9210fde99164d754f787bf65020dc7db3838c8aae3591eaf465f45433fcb3d0a94bea4090401", + "OVER DUP DUP 2DUP 3DUP 3DUP 3DUP 3DUP 0x01 0x14 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 OVER DUP DUP 2DUP 3DUP 3DUP 3DUP 3DUP 0x01 0x14 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "CHECKBITS", + "New-CHECKMULTISIG 20-of-20 checkbits 1 extra" +], +[ + "0x03 0x000010 0x41 0xbe6635b93b92ff98d0d929d3537bf2941bbc33b9b4adc14d928e1b6eae1aa1fd23455e4094764f70dd896f47b3279b57965ecad1b4d32c1000be27be8cf83ece01", + "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 DUP 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 3DUP 3DUP 3DUP 3DUP 3DUP 3DUP 0x01 0x15 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "PUBKEY_COUNT", + "New-CHECKMULTISIG 1-of-21" +], +[ + "0x03 0x000008 0x41 0x7bf9f002605a3ca5c0c784f8af89a4447f8d8e152dce2752f43db1087d16924c8b7db72a188bc2dfe6e4da7c6f21f8aed79e307d8731b5628b215d94b352e91e01", + "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 DUP 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 3DUP 3DUP 3DUP 3DUP 3DUP 2DUP 0x01 0x14 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 1-of-20" +], +[ + "3 0x41 0x3dfd744897afdad123edf671b9f7ad99f884cf714ada36f4c1cba12f7bdc71c6369832821a91964eb7d05552f1e32e5506d6dc2262e3ca5d1238690e3ddb075401 0x41 0x84aa5be4ebc905d6390a5be1b0101a0f2aab9563603a52c864db5deb459266cf1ea4376d378aa69a907a4e255919ecbff044d21b76dd004d34266c7ad8b84af501", + "2 0x02 0xbeef 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 2-of-3 (011), first key garbage" +], +[ + "3 0x41 0x7e57eab163176c372e6f2baa2446998817b429d9cd8e3ee3a6841a95bf19fa128562848b590bf2ada480a23bbb6697f3e920594e7bf410b3b8af489862ee660601 0x41 0x64b53fe45bc169d53366fe20f7340596ba9ad86566ae725535e32c5a40d4d3dbd448bc898d0528395eca1c634e4ce422c856c6063cb947d8191127317da4a5a001", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x02 0xbeef 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "PUBKEYTYPE", + "New-CHECKMULTISIG 2-of-3 (011), last key garbage" +], +[ + "6 0x41 0xb7aa94db79ecf22bdfd4d986ac4ba294fc044dd75696a6f95b12fef2dee48e02e06ccda571e0d513a03c585f86a8df1223a02556c11d7f1da71ba10544e9bc9501 0x41 0x3dfd744897afdad123edf671b9f7ad99f884cf714ada36f4c1cba12f7bdc71c6369832821a91964eb7d05552f1e32e5506d6dc2262e3ca5d1238690e3ddb075401", + "2 0x02 0xbeef 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "PUBKEYTYPE", + "New-CHECKMULTISIG 2-of-3 (110), first key garbage" +], +[ + "6 0x41 0xc09a62bbf5b7e45503a682cc72559b4d060edf1144023b47e765375a8e0cb017da3b0b72e2912a772989ce922f7f298890e66ff9f36c813b872682fc6b95a04b01 0x41 0x7e57eab163176c372e6f2baa2446998817b429d9cd8e3ee3a6841a95bf19fa128562848b590bf2ada480a23bbb6697f3e920594e7bf410b3b8af489862ee660601", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x02 0xbeef 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL,STRICTENC", + "OK", + "New-CHECKMULTISIG 2-of-3 (110), last key garbage" +], +[ + "0x01 0x00 0x41 0x6c6e55f998fd86e88e65ef00e89339773034ba372077118cb351d9247ba21582b302e0cc76afeffafd2de04bb02bcd2d509900d62c589f64fa0186c378bb4dce01 0x41 0x3d49f57bfa8aad284158b34c0bbda845c2b91a0a577db6ce1aed31d74badb51c1068001146a52857bdfd830ff149ac394655a243eff3caf33fa139ce8935739501", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", + "NEW_MULTISIG,NULLFAIL", + "NULLFAIL", + "New-CHECKMULTISIG non-null checkbits=0 with sigs" +], +[ + "0x01 0x00 0x41 0x6c6e55f998fd86e88e65ef00e89339773034ba372077118cb351d9247ba21582b302e0cc76afeffafd2de04bb02bcd2d509900d62c589f64fa0186c378bb4dce01 0x41 0x3d49f57bfa8aad284158b34c0bbda845c2b91a0a577db6ce1aed31d74badb51c1068001146a52857bdfd830ff149ac394655a243eff3caf33fa139ce8935739501", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", + "NEW_MULTISIG", + "OK", + "New-CHECKMULTISIG non-null checkbits=0 with sigs without NULLFAIL" +], +[ + "0x01 0x00 0x47 0x304402206dd1a6218f9da46eab9596cfc03b80c3dfb52a52865c999abc927e163cdaaa9002203c725fef4ce6283d3a35abeb940b95d6e07c9aba94ebae5f0d32f03650b0633101 0x47 0x3044022064e2f79fd4b381ce0d93abdde4cb735f42880ef7014f810ed9f2e03c2d4824f3022034da7827255e98bc7fc96267892b6511efaf57d9bd66cd9bd254bd147b900d5e01", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", + "NEW_MULTISIG,NULLFAIL", + "NULLFAIL", + "New-CHECKMULTISIG non-null checkbits=0 with ECDSA sigs" +], +[ + "0x01 0x00 0x47 0x304402206dd1a6218f9da46eab9596cfc03b80c3dfb52a52865c999abc927e163cdaaa9002203c725fef4ce6283d3a35abeb940b95d6e07c9aba94ebae5f0d32f03650b0633101 0x47 0x3044022064e2f79fd4b381ce0d93abdde4cb735f42880ef7014f810ed9f2e03c2d4824f3022034da7827255e98bc7fc96267892b6511efaf57d9bd66cd9bd254bd147b900d5e01", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", + "NEW_MULTISIG", + "OK", + "New-CHECKMULTISIG non-null checkbits=0 with ECDSA sigs without NULLFAIL" +], +[ + "0x01 0x00 0 0", + "2 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", + "NEW_MULTISIG,NULLFAIL", + "OK", + "New-CHECKMULTISIG non-null checkbits=0 and null sigs" +], +[ + "0x01 0x00", + "0 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "NEW_MULTISIG,NULLFAIL", + "OK", + "New-CHECKMULTISIG non-null checkbits=0 nSigsCount=0" +], +[ + "0x04 0x00000080", + "0 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "NEW_MULTISIG,NULLFAIL", + "OK", + "New-CHECKMULTISIG 4-byte checkbits=0 nSigsCount=0" +], +[ + "0x05 0x0000000000", + "0 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "NEW_MULTISIG,NULLFAIL", + "UNKNOWN_ERROR", + "New-CHECKMULTISIG 5-byte checkbits=0 nSigsCount=0" +], +[ + "0x01 0x80", + "0 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "MINIMALDATA,NEW_MULTISIG,NULLFAIL", + "UNKNOWN_ERROR", + "New-CHECKMULTISIG non-null checkbits=0 nSigsCount=0 with MINIMALDATA" +], ["CHECKSEQUENCEVERIFY tests"], ["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on an empty stack"], diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -60,6 +60,7 @@ {SCRIPT_ERR_INVALID_NUMBER_RANGE, "INVALID_NUMBER_RANGE"}, {SCRIPT_ERR_IMPOSSIBLE_ENCODING, "IMPOSSIBLE_ENCODING"}, {SCRIPT_ERR_INVALID_SPLIT_RANGE, "SPLIT_RANGE"}, + {SCRIPT_ERR_INVALID_CHECKBITS, "CHECKBITS"}, {SCRIPT_ERR_VERIFY, "VERIFY"}, {SCRIPT_ERR_EQUALVERIFY, "EQUALVERIFY"}, {SCRIPT_ERR_CHECKMULTISIGVERIFY, "CHECKMULTISIGVERIFY"}, @@ -1844,6 +1845,355 @@ .ScriptError(SCRIPT_ERR_SIG_BADLENGTH)); } + // Tests of new-checkmultisig actually turned on (flag on & dummy element is + // not null). + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0) + << OP_1 << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 1-of-1", newmultisigflags) + .Num(0b1) + .PushSigSchnorr(keys.key0)); + tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0) + << OP_1 << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 1-of-1 nonminimal bits", + newmultisigflags) + .Push("0100") + .PushSigSchnorr(keys.key0) + .ScriptError(SCRIPT_ERR_UNKNOWN_ERROR)); + tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 3-of-3", newmultisigflags) + .Num(0b111) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key2)); + tests.push_back(TestBuilder(CScript() << OP_4 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 4-of-3", newmultisigflags) + .Num(0b1111) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key2) + .ScriptError(SCRIPT_ERR_SIG_COUNT)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 (011)", + newmultisigflags) + .Num(0b011) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key2)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 (101)", + newmultisigflags) + .Num(0b101) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key2)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 (110)", + newmultisigflags) + .Num(0b110) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 mismatched bits", + newmultisigflags) + .Num(0b101) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .ScriptError(SCRIPT_ERR_SIG_NULLFAIL)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 all bits set", + newmultisigflags) + .Num(0b111) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key2) + .ScriptError(SCRIPT_ERR_INVALID_CHECKBITS)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 extra high bit set", + newmultisigflags) + .Num(0b1110) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .ScriptError(SCRIPT_ERR_INVALID_CHECKBITS)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 too high bit set", + newmultisigflags) + .Num(0b1010) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .ScriptError(SCRIPT_ERR_INVALID_CHECKBITS)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 too few bits set", + newmultisigflags) + .Num(0b010) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .ScriptError(SCRIPT_ERR_SIG_NULLFAIL)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 negative bits", + newmultisigflags) + .Num(-0b110) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .ScriptError(SCRIPT_ERR_INVALID_CHECKBITS)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "CHECKMULTISIG null dummy with schnorr sigs " + "(with SCRIPT_ENABLE_NEW_MULTISIG on)", + newmultisigflags) + .Num(0) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .ScriptError(SCRIPT_ERR_SIG_BADLENGTH)); + tests.push_back( + TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 misordered signatures", + newmultisigflags) + .Num(0b110) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key0) + .ScriptError(SCRIPT_ERR_SIG_NULLFAIL)); + tests.push_back( + TestBuilder( + CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) << OP_DUP << OP_2DUP + << OP_2DUP << ToByteVector(keys.pubkey2C) << OP_8 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-8 right way to represent 0b10000001", + newmultisigflags) + .Push("8100") + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key2)); + tests.push_back( + TestBuilder( + CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) << OP_DUP << OP_2DUP + << OP_2DUP << ToByteVector(keys.pubkey2C) << OP_8 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-8 wrong way to represent 0b10000001", + newmultisigflags & ~SCRIPT_VERIFY_MINIMALDATA) + .Push("81") + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key2) + .ScriptError(SCRIPT_ERR_INVALID_CHECKBITS)); + tests.push_back(TestBuilder(CScript() + << OP_OVER << OP_DUP << OP_DUP << OP_2DUP + << OP_3DUP << OP_3DUP << OP_3DUP << OP_3DUP + << 20 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_OVER + << OP_DUP << OP_DUP << OP_2DUP << OP_3DUP + << OP_3DUP << OP_3DUP << OP_3DUP << 20 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 20-of-20", newmultisigflags) + .Num(0xfffff) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key2)); + tests.push_back( + TestBuilder( + CScript() << OP_OVER << OP_DUP << OP_DUP << OP_2DUP << OP_3DUP + << OP_3DUP << OP_3DUP << OP_3DUP << 20 + << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_OVER << OP_DUP + << OP_DUP << OP_2DUP << OP_3DUP << OP_3DUP << OP_3DUP + << OP_3DUP << 20 << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 20-of-20 checkbits 1 extra", newmultisigflags) + .Num(0xfffff + 1) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key2) + .ScriptError(SCRIPT_ERR_INVALID_CHECKBITS)); + tests.push_back( + TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0C) << OP_DUP + << ToByteVector(keys.pubkey1C) << OP_3DUP + << OP_3DUP << OP_3DUP << OP_3DUP << OP_3DUP + << OP_3DUP << 21 << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 1-of-21", newmultisigflags) + .Num(0x100000) + .PushSigSchnorr(keys.key0) + .ScriptError(SCRIPT_ERR_PUBKEY_COUNT)); + tests.push_back( + TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0C) << OP_DUP + << ToByteVector(keys.pubkey1C) << OP_3DUP + << OP_3DUP << OP_3DUP << OP_3DUP << OP_3DUP + << OP_2DUP << 20 << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 1-of-20", newmultisigflags) + .Num(0x80000) + .PushSigSchnorr(keys.key0)); + tests.push_back( + TestBuilder(CScript() << OP_2 << ToByteVector(ParseHex("BEEF")) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 (011), first key garbage", + newmultisigflags) + .Num(0b011) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key2)); + tests.push_back( + TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(ParseHex("BEEF")) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 (011), last key garbage", + newmultisigflags) + .Num(0b011) + .PushSigSchnorr(keys.key1) + .PushSigSchnorr(keys.key2) + .ScriptError(SCRIPT_ERR_PUBKEYTYPE)); + tests.push_back( + TestBuilder(CScript() << OP_2 << ToByteVector(ParseHex("BEEF")) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 (110), first key garbage", + newmultisigflags) + .Num(0b110) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .ScriptError(SCRIPT_ERR_PUBKEYTYPE)); + tests.push_back( + TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(ParseHex("BEEF")) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 2-of-3 (110), last key garbage", + newmultisigflags) + .Num(0b110) + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1)); + + // Tests of new-checkmultisig with unreal flag combinations. For example + // checkbits=0 (but not null) is testable by leaving MINIMALDATA off and + // pushing a non-null representation of 0. + tests.push_back( + TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG << OP_NOT, + "New-CHECKMULTISIG non-null checkbits=0 with sigs", + SCRIPT_ENABLE_NEW_MULTISIG | SCRIPT_VERIFY_NULLFAIL) + .Push("00") + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1) + .ScriptError(SCRIPT_ERR_SIG_NULLFAIL)); + tests.push_back( + TestBuilder( + CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG + << OP_NOT, + "New-CHECKMULTISIG non-null checkbits=0 with sigs without NULLFAIL", + SCRIPT_ENABLE_NEW_MULTISIG) + .Push("00") + .PushSigSchnorr(keys.key0) + .PushSigSchnorr(keys.key1)); + tests.push_back( + TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG << OP_NOT, + "New-CHECKMULTISIG non-null checkbits=0 with ECDSA sigs", + SCRIPT_ENABLE_NEW_MULTISIG | SCRIPT_VERIFY_NULLFAIL) + .Push("00") + .PushSigECDSA(keys.key0) + .PushSigECDSA(keys.key1) + .ScriptError(SCRIPT_ERR_SIG_NULLFAIL)); + tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG << OP_NOT, + "New-CHECKMULTISIG non-null checkbits=0 with " + "ECDSA sigs without NULLFAIL", + SCRIPT_ENABLE_NEW_MULTISIG) + .Push("00") + .PushSigECDSA(keys.key0) + .PushSigECDSA(keys.key1)); + tests.push_back( + TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG << OP_NOT, + "New-CHECKMULTISIG non-null checkbits=0 and null sigs", + SCRIPT_ENABLE_NEW_MULTISIG | SCRIPT_VERIFY_NULLFAIL) + .Push("00") + .Num(0) + .Num(0)); + tests.push_back( + TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG non-null checkbits=0 nSigsCount=0", + SCRIPT_ENABLE_NEW_MULTISIG | SCRIPT_VERIFY_NULLFAIL) + .Push("00")); + tests.push_back( + TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 4-byte checkbits=0 nSigsCount=0", + SCRIPT_ENABLE_NEW_MULTISIG | SCRIPT_VERIFY_NULLFAIL) + .Push("00000080")); + tests.push_back( + TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG 5-byte checkbits=0 nSigsCount=0", + SCRIPT_ENABLE_NEW_MULTISIG | SCRIPT_VERIFY_NULLFAIL) + .Push("0000000000") + .ScriptError(SCRIPT_ERR_UNKNOWN_ERROR)); + // And, a test with minimaldata on. + tests.push_back(TestBuilder(CScript() << OP_0 << ToByteVector(keys.pubkey0C) + << ToByteVector(keys.pubkey1C) + << ToByteVector(keys.pubkey2C) << OP_3 + << OP_CHECKMULTISIG, + "New-CHECKMULTISIG non-null checkbits=0 " + "nSigsCount=0 with MINIMALDATA", + SCRIPT_ENABLE_NEW_MULTISIG | + SCRIPT_VERIFY_NULLFAIL | + SCRIPT_VERIFY_MINIMALDATA) + .Push("80") + .ScriptError(SCRIPT_ERR_UNKNOWN_ERROR)); + std::set tests_set; {