Open cornwarecjp opened 7 months ago
I suspect this may be because these are signatures from very old Bitcoin transactions. IIRC, Bitcoin has soft-forked at some point, where it started requiring signatures to be in some canonical format. Maybe the failing signature was from before that soft-fork.
Decoding the DER format, a difference I noticed was that the second signature has an s-value that starts with 0x00:
00db2605b3d9b1732697926dec7b6a1e037fe5af7ac04cc01c7a83efdb37a6f476
If secp256k1 (or its Python wrapper) rejects non-canonical signatures, that leaves the question whether that's desirable. It's certainly necessary for checking signatures on new Bitcoin transactions, but for validating old (pre-softfork) transactions it isn't what you want. For non-Bitcoin applications, it might depend on your application (e.g. do you want compatibility with other libraries that might emit non-canonical signatures).
So maybe it should be an option that can be passed by the user (and this issue can be closed if that option already exists and I overlooked it).
I tried to use secp256k1-py to verify a couple of (simple P2PKH) signatures found on the Bitcoin blockchain, and some succeeded and some failed. I think it's safe to assume that all these signatures are correct, otherwise they wouldn't be accepted in the blockchain, so it's weird that some failed. That leaves some possibilities:
I found two transactions, where one succeeds and the other fails, that are nearly identical in format: 1 P2PKH input, 2 P2PKH outputs, same version number, no lock time & so on; they even have the same key used for their input. Manually looking at the sighash generation of the failing tx, it seems correct. So I wanted to see whether secp256k1-py contains a bug.
For comparison, I had the same signatures checked by another library, ecdsa (
pip install ecdsa
). It accepts both signatures, confirming that Bitcoin is OK and that my own code is OK. Here is the code for comparing both:I get the following output: