diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1694,6 +1694,7 @@
 bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey,
                   uint32_t flags, const BaseSignatureChecker &checker,
                   ScriptError *serror) {
+    ScriptExecutionMetrics metrics;
     set_error(serror, ScriptError::UNKNOWN);
 
     // If FORKID is enabled, we also ensure strict encoding.
@@ -1706,14 +1707,14 @@
     }
 
     std::vector<valtype> stack, stackCopy;
-    if (!EvalScript(stack, scriptSig, flags, checker, serror)) {
+    if (!EvalScript(stack, scriptSig, flags, checker, metrics, serror)) {
         // serror is set
         return false;
     }
     if (flags & SCRIPT_VERIFY_P2SH) {
         stackCopy = stack;
     }
-    if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) {
+    if (!EvalScript(stack, scriptPubKey, flags, checker, metrics, serror)) {
         // serror is set
         return false;
     }
@@ -1751,7 +1752,7 @@
             return set_success(serror);
         }
 
-        if (!EvalScript(stack, pubKey2, flags, checker, serror)) {
+        if (!EvalScript(stack, pubKey2, flags, checker, metrics, serror)) {
             // serror is set
             return false;
         }
@@ -1777,5 +1778,27 @@
         }
     }
 
+    if (flags & SCRIPT_VERIFY_INPUT_SIGCHECKS) {
+        // This limit is intended for standard use, and is based on an
+        // examination of typical and historical standard uses.
+        // - allowing P2SH ECDSA multisig with compressed keys, which at an
+        // extreme (1-of-15) may have 15 SigChecks in ~590 bytes of scriptSig.
+        // - allowing Bare ECDSA multisig, which at an extreme (1-of-3) may have
+        // 3 sigchecks in ~72 bytes of scriptSig.
+        // - further restricting SigChecks for very short scriptSigs (<69
+        // bytes), which in normal usage would only have at most one SigCheck.
+        // (Historically, three inputs have violated this limit; all were
+        // nonstandard scriptPubKeys by today's measure.)
+        static_assert(INT_MAX > MAX_SCRIPT_SIZE,
+                      "overflow sanity check on max script size");
+        static_assert(INT_MAX / 43 / 3 > MAX_OPS_PER_SCRIPT,
+                      "overflow sanity check on maximum possible sigchecks "
+                      "from sig+redeem+pub scripts");
+        if (int(scriptSig.size()) <
+            std::max(metrics.nSigChecks * 23, metrics.nSigChecks * 43 - 60)) {
+            return set_error(serror, ScriptError::INPUT_SIGCHECKS);
+        }
+    }
+
     return set_success(serror);
 }
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
@@ -19,6 +19,7 @@
     STACK_SIZE,
     SIG_COUNT,
     PUBKEY_COUNT,
+    INPUT_SIGCHECKS,
 
     /* Operands checks */
     INVALID_OPERAND_SIZE,
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
@@ -36,6 +36,8 @@
             return "Signature count negative or greater than pubkey count";
         case ScriptError::PUBKEY_COUNT:
             return "Pubkey count negative or limit exceeded";
+        case ScriptError::INPUT_SIGCHECKS:
+            return "Input SigChecks limit exceeded";
         case ScriptError::INVALID_OPERAND_SIZE:
             return "Invalid operand size";
         case ScriptError::INVALID_NUMBER_RANGE:
diff --git a/src/script/script_flags.h b/src/script/script_flags.h
--- a/src/script/script_flags.h
+++ b/src/script/script_flags.h
@@ -105,6 +105,12 @@
     // Whether to allow new OP_CHECKMULTISIG logic to trigger. (new multisig
     // logic verifies faster, and only allows Schnorr signatures)
     SCRIPT_ENABLE_SCHNORR_MULTISIG = (1U << 21),
+
+    // Require the number of sigchecks in an input to satisfy a specific
+    // bound, defined by scriptSig length.
+    // Note: The Segwit Recovery feature is a (currently moot) exception to
+    // VERIFY_INPUT_SIGCHECKS
+    SCRIPT_VERIFY_INPUT_SIGCHECKS = (1U << 22),
 };
 
 #endif // BITCOIN_SCRIPT_SCRIPT_FLAGS_H
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
@@ -3342,6 +3342,97 @@
     "SIG_NONSCHNORR",
     "CHECKMULTISIG 3-of-3 Schnorr with mixed-in ECDSA signature"
 ],
+[
+    "0 0x47 0x3044022031feb7bc6e213668042b34749aa7aa99a4b40dc8ba53f872fb270442a2e69ecf0220012df792d5bc247a4ebe12f4de300d70aa768f5d9f49a5db752aef86e23f1bd501",
+    "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "SigChecks on bare CHECKMULTISIG 1-of-3 ECDSA"
+],
+[
+    "0x03 0x010000 0x41 0x071da33a41ccc6ff5fcb275cae36e953e6a6092af5c8d256ca640387d36c42ae25117b502bae0881437ad0ff7db7ab23afba59fbcb03563471941733e67fb1ac01",
+    "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0x01 0x14 CHECKMULTISIG",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "SigChecks on bare CHECKMULTISIG 1-of-20 Schnorr"
+],
+[
+    "0x41 0xd78d543b601bc93b394b5c669933d16d860dc7480383efcaae9521d6ceb4065ba17c02a6d9289efef762fa7a0482eff9c5bce4dd95f8bea421ee70bdd8d5488d01",
+    "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "SigChecks on P2PK Schnorr"
+],
+[
+    "0x47 0x30440220355bca231b5c6eac1c304ece6391404a5e8c9683f1c20749736e56f35969954302205d4af886536352ddf065407828763f3fc41755c34fd08afa4934505fd75e14ed01",
+    "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "SigChecks on P2PK ECDSA"
+],
+[
+    "0 0x47 0x3044022007a5b776fff5a7540301e9abbe29198575ce549333b47c90e2949c08d4ecaf8002203f8d71618b7a5cd3e99eeba0fb3c4cad4115e550ea27563d65074899d074a2d301 0x4d0102 0x51210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff46405fae",
+    "HASH160 0x14 0xf12c94c5293b608240ce28dc992a3ee1110926c1 EQUAL",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "SigChecks on P2SH CHECKMULTISIG 1-of-15 ECDSA with compressed keys"
+],
+[
+    "0x44 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817980078ac78ac78ac78ac78ac78ac78ac78ac78ac78ac78ac78ac78ac78ac78ac78ac75",
+    "HASH160 0x14 0xe35559f8e010a9efb62973594c029ddc6f52b031 EQUAL",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "Null signatures make no SigChecks (CHECKSIG)"
+],
+[
+    "0x47 0x00210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798000070ba70ba70ba70ba70ba70ba70ba70ba70ba70ba70ba70ba70ba70ba70ba70ba6d77",
+    "HASH160 0x14 0x0c01c2ac37ed03194c339b0f9915ae6acd0afeba EQUAL",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "Null signatures make no SigChecks (CHECKDATASIG)"
+],
+[
+    "0 0 0x32 0x766e6f6f6f6f60210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798766e6f6f6f6f60ae91",
+    "HASH160 0x14 0x653b2bb5171f68633c8e3437d075e23640fdf4d1 EQUAL",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "Null signatures make no SigChecks (CHECKMULTISIG)"
+],
+[
+    "0 0x47 0x304402200c90f014caff5716cd50749d52c5a4b5f1d6b79c67c96f71713f6fa3e84f3a8a02203ab681add2f4f908c41f083c982d24b62871e6c4f6eaa5d677572fc7c43c5e2201",
+    "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 DUP 4 CHECKMULTISIG",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "INPUT_SIGCHECKS",
+    "SigChecks on bare CHECKMULTISIG 1-of-4 ECDSA"
+],
+[
+    "0 0x47 0x30440220418df29b58de691affb63165b3276a3932e80d56eb3392114b438f4f61fc9d2902207270492c16a9c56be78f6d926448038de44dd0de7d4ecea61f04f590be8c321401 0x4de001 0x514f210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff46405fae",
+    "HASH160 0x14 0x5493830eb1862c448c66236c694e2b3b37d8fd60 EQUAL",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "INPUT_SIGCHECKS",
+    "SigChecks on P2SH CHECKMULTISIG 1-of-15 ECDSA with a runt key"
+],
+[
+    "0x02 0x0200 0x41 0xc33a73f6c920c95d79d4abf75a3471daac41cfb76a40a40eac752e0c522d1ce7be10d486c52aad12b1a1802f78f860d20dc6be065bebb672e641d17edc7ea7d501 0x4de001 0x514f210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817982103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464021038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff46405fae",
+    "HASH160 0x14 0x5493830eb1862c448c66236c694e2b3b37d8fd60 EQUAL",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "SigChecks on P2SH CHECKMULTISIG 1-of-15 Schnorr with a runt key"
+],
+[
+    "0 0x0d 0x004f4f4f4f4f4f4f4f4f4f5aae",
+    "HASH160 0x14 0xa3ef8a4b54cc4437e684c5072535acbbf1f29598 EQUAL",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "Very short P2SH multisig 0-of-10, spent with legacy mode (0 sigchecks)"
+],
+[
+    "0x02 0x0000 0x0d 0x004f4f4f4f4f4f4f4f4f4f5aae",
+    "HASH160 0x14 0xa3ef8a4b54cc4437e684c5072535acbbf1f29598 EQUAL",
+    "INPUT_SIGCHECKS,MINIMALDATA,NULLFAIL,P2SH,SCHNORR_MULTISIG,STRICTENC",
+    "OK",
+    "Very short P2SH multisig 0-of-10, spent with schnorr mode (0 sigchecks)"
+],
 
 ["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
@@ -56,6 +56,7 @@
     {ScriptError::STACK_SIZE, "STACK_SIZE"},
     {ScriptError::SIG_COUNT, "SIG_COUNT"},
     {ScriptError::PUBKEY_COUNT, "PUBKEY_COUNT"},
+    {ScriptError::INPUT_SIGCHECKS, "INPUT_SIGCHECKS"},
     {ScriptError::INVALID_OPERAND_SIZE, "OPERAND_SIZE"},
     {ScriptError::INVALID_NUMBER_RANGE, "INVALID_NUMBER_RANGE"},
     {ScriptError::IMPOSSIBLE_ENCODING, "IMPOSSIBLE_ENCODING"},
@@ -2243,6 +2244,163 @@
             .PushSigSchnorr(keys.key2)
             .SetScriptError(ScriptError::SIG_NONSCHNORR));
 
+    // SigChecks tests follow. We want to primarily focus on behaviour with
+    // the modern set of (relevant) flags.
+    uint32_t sigchecksflags =
+        SCRIPT_ENABLE_SCHNORR_MULTISIG | SCRIPT_VERIFY_NULLFAIL |
+        SCRIPT_VERIFY_MINIMALDATA | SCRIPT_VERIFY_STRICTENC |
+        SCRIPT_VERIFY_INPUT_SIGCHECKS | SCRIPT_VERIFY_P2SH;
+    // First, try some important use cases that we want to make sure are
+    // supported but that have high density of sigchecks.
+    tests.push_back(TestBuilder(CScript() << 1 << ToByteVector(keys.pubkey0C)
+                                          << ToByteVector(keys.pubkey1C)
+                                          << ToByteVector(keys.pubkey2C) << 3
+                                          << OP_CHECKMULTISIG,
+                                "SigChecks on bare CHECKMULTISIG 1-of-3 ECDSA",
+                                sigchecksflags)
+                        .Num(0)
+                        .PushSigECDSA(keys.key0));
+    tests.push_back(
+        TestBuilder(CScript() << 1 << ToByteVector(keys.pubkey0C) << -1 << -1
+                              << -1 << -1 << -1 << -1 << -1 << -1 << -1 << -1
+                              << -1 << -1 << -1 << -1 << -1 << -1 << -1 << -1
+                              << -1 << 20 << OP_CHECKMULTISIG,
+                    "SigChecks on bare CHECKMULTISIG 1-of-20 Schnorr",
+                    sigchecksflags)
+            .Push("010000")
+            .PushSigSchnorr(keys.key0));
+    tests.push_back(
+        TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
+                    "SigChecks on P2PK Schnorr", sigchecksflags)
+            .PushSigSchnorr(keys.key0));
+    tests.push_back(
+        TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
+                    "SigChecks on P2PK ECDSA", sigchecksflags)
+            .PushSigECDSA(keys.key0));
+    tests.push_back(
+        TestBuilder(
+            CScript()
+                << 1 << ToByteVector(keys.pubkey0C)
+                << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C)
+                << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C)
+                << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C)
+                << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C)
+                << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C)
+                << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C)
+                << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C)
+                << 15 << OP_CHECKMULTISIG,
+            "SigChecks on P2SH CHECKMULTISIG 1-of-15 ECDSA with compressed "
+            "keys",
+            sigchecksflags, true)
+            .Num(0)
+            .PushSigECDSA(keys.key0)
+            .PushRedeem());
+    tests.push_back(
+        TestBuilder(CScript()
+                        << ToByteVector(keys.pubkey0C) << 0 << OP_OVER
+                        << OP_CHECKSIG << OP_OVER << OP_CHECKSIG << OP_OVER
+                        << OP_CHECKSIG << OP_OVER << OP_CHECKSIG << OP_OVER
+                        << OP_CHECKSIG << OP_OVER << OP_CHECKSIG << OP_OVER
+                        << OP_CHECKSIG << OP_OVER << OP_CHECKSIG << OP_OVER
+                        << OP_CHECKSIG << OP_OVER << OP_CHECKSIG << OP_OVER
+                        << OP_CHECKSIG << OP_OVER << OP_CHECKSIG << OP_OVER
+                        << OP_CHECKSIG << OP_OVER << OP_CHECKSIG << OP_OVER
+                        << OP_CHECKSIG << OP_OVER << OP_CHECKSIG << OP_DROP,
+                    "Null signatures make no SigChecks (CHECKSIG)",
+                    sigchecksflags, true)
+            .PushRedeem());
+    tests.push_back(
+        TestBuilder(CScript()
+                        << 0 << ToByteVector(keys.pubkey0C) << 0 << 0
+                        << OP_2OVER << OP_CHECKDATASIG << OP_2OVER
+                        << OP_CHECKDATASIG << OP_2OVER << OP_CHECKDATASIG
+                        << OP_2OVER << OP_CHECKDATASIG << OP_2OVER
+                        << OP_CHECKDATASIG << OP_2OVER << OP_CHECKDATASIG
+                        << OP_2OVER << OP_CHECKDATASIG << OP_2OVER
+                        << OP_CHECKDATASIG << OP_2OVER << OP_CHECKDATASIG
+                        << OP_2OVER << OP_CHECKDATASIG << OP_2OVER
+                        << OP_CHECKDATASIG << OP_2OVER << OP_CHECKDATASIG
+                        << OP_2OVER << OP_CHECKDATASIG << OP_2OVER
+                        << OP_CHECKDATASIG << OP_2OVER << OP_CHECKDATASIG
+                        << OP_2OVER << OP_CHECKDATASIG << OP_2DROP << OP_NIP,
+                    "Null signatures make no SigChecks (CHECKDATASIG)",
+                    sigchecksflags, true)
+            .PushRedeem());
+    // Note that the following test case is "legacy-only", there is no schnorr
+    // counterpart since schnorr mode does not permit any null signatures nor
+    // an incorrect popcount in checkbits.
+    tests.push_back(
+        TestBuilder(CScript()
+                        << OP_DUP << OP_2DUP << OP_3DUP << OP_3DUP << OP_3DUP
+                        << OP_3DUP << 16 << ToByteVector(keys.pubkey0C)
+                        << OP_DUP << OP_2DUP << OP_3DUP << OP_3DUP << OP_3DUP
+                        << OP_3DUP << 16 << OP_CHECKMULTISIG << OP_NOT,
+                    "Null signatures make no SigChecks (CHECKMULTISIG)",
+                    sigchecksflags, true)
+            .Num(0)
+            .Num(0)
+            .PushRedeem());
+
+    // Now some unusual use cases (some are unsupported behaviour)
+    tests.push_back(TestBuilder(CScript() << 1 << ToByteVector(keys.pubkey0C)
+                                          << ToByteVector(keys.pubkey1C)
+                                          << ToByteVector(keys.pubkey2C)
+                                          << OP_DUP << 4 << OP_CHECKMULTISIG,
+                                "SigChecks on bare CHECKMULTISIG 1-of-4 ECDSA",
+                                sigchecksflags)
+                        .Num(0)
+                        .PushSigECDSA(keys.key0)
+                        .SetScriptError(ScriptError::INPUT_SIGCHECKS));
+    tests.push_back(
+        TestBuilder(
+            CScript()
+                << 1 << -1 << ToByteVector(keys.pubkey0C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << 15 << OP_CHECKMULTISIG,
+            "SigChecks on P2SH CHECKMULTISIG 1-of-15 ECDSA with a runt key",
+            sigchecksflags, true)
+            .Num(0)
+            .PushSigECDSA(keys.key0)
+            .PushRedeem()
+            .SetScriptError(ScriptError::INPUT_SIGCHECKS));
+    tests.push_back(
+        TestBuilder(
+            CScript()
+                << 1 << -1 << ToByteVector(keys.pubkey0C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << ToByteVector(keys.pubkey1C)
+                << ToByteVector(keys.pubkey2C) << 15 << OP_CHECKMULTISIG,
+            "SigChecks on P2SH CHECKMULTISIG 1-of-15 Schnorr with a runt key",
+            sigchecksflags, true)
+            .Push("0200")
+            .PushSigSchnorr(keys.key0)
+            .PushRedeem());
+    tests.push_back(TestBuilder(CScript() << 0 << -1 << -1 << -1 << -1 << -1
+                                          << -1 << -1 << -1 << -1 << -1 << 10
+                                          << OP_CHECKMULTISIG,
+                                "Very short P2SH multisig 0-of-10, spent with "
+                                "legacy mode (0 sigchecks)",
+                                sigchecksflags, true)
+                        .Num(0)
+                        .PushRedeem());
+    tests.push_back(TestBuilder(CScript() << 0 << -1 << -1 << -1 << -1 << -1
+                                          << -1 << -1 << -1 << -1 << -1 << 10
+                                          << OP_CHECKMULTISIG,
+                                "Very short P2SH multisig 0-of-10, spent with "
+                                "schnorr mode (0 sigchecks)",
+                                sigchecksflags, true)
+                        .Push("0000")
+                        .PushRedeem());
+
     std::set<std::string> tests_set;
 
     {
diff --git a/src/test/scriptflags.cpp b/src/test/scriptflags.cpp
--- a/src/test/scriptflags.cpp
+++ b/src/test/scriptflags.cpp
@@ -33,6 +33,7 @@
     {"CHECKDATASIG", SCRIPT_VERIFY_CHECKDATASIG_SIGOPS},
     {"DISALLOW_SEGWIT_RECOVERY", SCRIPT_DISALLOW_SEGWIT_RECOVERY},
     {"SCHNORR_MULTISIG", SCRIPT_ENABLE_SCHNORR_MULTISIG},
+    {"INPUT_SIGCHECKS", SCRIPT_VERIFY_INPUT_SIGCHECKS},
 };
 
 uint32_t ParseScriptFlags(std::string strFlags) {