I used data that comes from https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#p2sh-p2wpkh. It is easy to know how to get sigHash. But when I try to recover public key, everything out off my expected.

And my question is

  1. The message to be signed was not 64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6?
  2. If the message is 64f3b0f4dd2bb3a...59fb6, is anything wrong to my code?

My code

import ecdsa

from ecdsa.ecdsa import int_to_string, string_to_int
from binascii import hexlify

prik = "eb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf"
prik = bytes.fromhex(prik)

pubk = "03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873"

sig = '3044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb'
sig = bytes.fromhex(sig)

raw_msg = "64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6"
raw_msg = bytes.fromhex(raw_msg)

    pubkey = ecdsa.VerifyingKey.from_public_key_recovery(
        signature=sig, data=raw_msg, curve=ecdsa.curves.SECP256k1, sigdecode=ecdsa.util.sigdecode_der)
    print([hexlify(pub.to_string()) for pub in pubkey])

except Exception as e:
    raise e

def check_recovery(pub):

    padx = (b'\0'*32 + int_to_string(pub.pubkey.point.x()))[-32:]
    if pub.pubkey.point.y() & 1:
        ck = b'\3'+padx
        ck = b'\2'+padx

    return hexlify(ck)

lists = [check_recovery(p) for p in pubkey]
print([l == pubk for l in lists])

What I got was: [b'519e33c6b146628b4010ae2b56aa9127ae9b795c82df021979436296daf4cceac17eb495101c3c15011e9d5a08163122054ad375730ee2e219504540eb658211', b'd28ba1b718b542f52fe42b51635850b5900f111affbbdcbb63465e9a3dd79ffb80251268ba8d5b5ba4aaec8a682145af51b87bd7c7ab9e956895d31db24c4d4b'] [b'03519e33c6b146628b4010ae2b56aa9127ae9b795c82df021979436296daf4ccea', b'03d28ba1b718b542f52fe42b51635850b5900f111affbbdcbb63465e9a3dd79ffb'] [False, False]

What did I miss?

1 Answer 1


What i missed?

You are hashing sigHash (ie. the already hashed message) with SHA1 and then recover public key using that result which will give you 03519e33c6b146628b4010ae2b56aa9127ae9b795c82df021979436296daf4ccea as the recovered public key (can't re-calculate the second one with my c# code)! I believe that this is the source code of the from_public_key_recovery function you are using. You probably have to use another function like from_public_key_recovery_with_digest


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.