Currently in our tests, all ECDSA signatures passing verification have sizes of 69 bytes and above (that’s the DER-encoded size, i.e. counted without the sighash flag byte) [1]. This PR adds test coverage for the minimum-sized valid case of 8 bytes, by taking an interesting testnet transaction that I stumbled upon:
https://mempool.space/testnet/tx/c6c232a36395fa338da458b86ff1327395a9afc28c5d2daa4273e410089fd433
Note that this is a very obscure construction that only works because the public key used isn’t contained in the locking script, but calculated and provided later at spending time (see https://bitcointalk.org/index.php?topic=1729534.msg17309060#msg17309060 for an explainer), to match the message (sighash) and picked signature. So this doesn’t represent a use-case that really makes sense in practice, but it can still appear in a block (not in mempool though, due to SCRIPT_VERIFY_CONST_SCRIPTCODE
), and having test-coverage seems useful.
Can be tested with same patch below (tests crash with the condition >= 9
, but pass with >= 8
).
[1] this can be verified by applying the following patch and running the tests:
0diff --git a/src/pubkey.cpp b/src/pubkey.cpp
1index a4ca9a170a..bee0caa603 100644
2--- a/src/pubkey.cpp
3+++ b/src/pubkey.cpp
4@@ -288,7 +288,9 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
5 /* libsecp256k1's ECDSA verification requires lower-S signatures, which have
6 * not historically been enforced in Bitcoin, so normalize them first. */
7 secp256k1_ecdsa_signature_normalize(secp256k1_context_static, &sig, &sig);
8- return secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey);
9+ bool ret = secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey);
10+ if (ret) assert(vchSig.size() >= 69);
11+ return ret;
12 }