When trying to implement OP_CHECKSIG, I am unable to figure out how to do the actual signature verification in python (python3)

I obtained the signature, public key, and hashed message digest of a transaction, and now I want to verify the signature.

message = '692678553d1b85ccf87d4d4443095f276cdf600f2bb7dd44f6effbd7458fd4c2'
pubkey = '042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb'
signature = '30450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e'

Since python-ecdsa requires 64 byte input for creating the verifying key, I removed the first byte myself.

pubkey = pubkey[2:]

I also extracted r and s from the DER encoded signature, and concatenated these to create a 64 byte signature as python-ecdsa requires.

r = '9908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc413287'
s = '1aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e'
sig = r + s

However when I try to verify the message, I get a BadSignatureError signifying that the verification failed.

from ecdsa import VerifyingKey, SECP256k1
vk = VerifyingKey.from_string(bytes.fromhex(pubkey), curve=SECP256k1)
vk.verify(bytes.fromhex(sig), bytes.fromhex(message))

I am looking for a way to verify signatures that I have extracted from bitcoin transactions.

Thank you.

1 Answer 1


The way that VerifyingKey works is that it will actually hash the message before it verifies. The default hashing algorithm is sha1, so you will need to specify it to be sha256 as that is what Bitcoin uses. Furthermore, you are passing it the fully hashed message. What you need to do is pass it the step before hashing the message. Since Bitcoin uses SHA256 double, you need to give it the result of the first SHA256 hash and let it generate the second SHA256 hash by itself.

So your message should actually be


and your verify call should look like

vk.verify(bytes.fromhex(sig), bytes.fromhex(message), hashlib.sha256)
  • This worked. I always thought my error lay somewhere in the bitcoin part, but turns out it was in the ecdsa part. Thank you. Nov 12, 2017 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.