How do you recover the EC public key from a VRS style signature in python?
I am trying to setup some encryption between two parties via ECIES, but I first wanted to obtain the public key via recovery from a transaction. The following is an example transaction from my geth console I've been working with.
eth.getTransaction("0x912b33e09311a72b988af66918abcd53f43831688c7acb6b44870c491f073dab")
{
blockHash: "0xfdc5a1c9e1a0dcdfb2b9884919b79157a04eb15b0b58c91131e957f2803f8195",
blockNumber: 100449,
from: "0xc6f4f527587ea4a03aa85e0322783592367c1b9a",
gas: 100000,
gasPrice: 18000000000,
hash: "0x912b33e09311a72b988af66918abcd53f43831688c7acb6b44870c491f073dab",
input: "0x",
nonce: 21,
r: "0xab90122dc4e4bbdbb14ef22ad3ae21aecc19a1c90a9c8989c68b26cc782ff303",
s: "0x36e5f275147049d3afd5d33b735cc9313d2c1aad3ab401aefdce678128e2f1d0",
to: "0xa593094cebb06bf34df7311845c2a34996b52324",
transactionIndex: 0,
v: "0x1c",
value: 1000000000000
}
web3.sha3(eth.getRawTransaction("0x912b33e09311a72b988af66918abcd53f43831688c7acb6b44870c491f073dab"),{encoding:'hex'})
"0x912b33e09311a72b988af66918abcd53f43831688c7acb6b44870c491f073dab"
From the transaction above, I have the raw material for the signature (e.g., V, R, S) and the sender (i.e., "from" field) which I can use to verify the address.
I'm trying to do this in python.
sender = "0xc6f4f527587ea4a03aa85e0322783592367c1b9a"
hash = "0x912b33e09311a72b988af66918abcd53f43831688c7acb6b44870c491f073dab"
r = "0xab90122dc4e4bbdbb14ef22ad3ae21aecc19a1c90a9c8989c68b26cc782ff303"
s ="0x36e5f275147049d3afd5d33b735cc9313d2c1aad3ab401aefdce678128e2f1d0"
v = "0x1c"
import bitcoin
import ethereum.keys #for a good sha3 implementation
from rlp.utils import decode_hex, encode_hex
rawhash = decode_hex(hash[2:]) # omit the 0x
vrs = (int(v[2:],16),int(r[2:],16),int(s[2:],16)) # omit the 0x and convert to integers based on base16 (hex)
rec_pub = bitcoin.ecdsa_raw_recover(rawhash,vrs) ## Trouble line!
enc_rec_pub = bitcoin.encode_pubkey(rec_pub,"bin")
rec_address = encode_hex(ethereum.keys.sha3(enc_rec_pub[1:]))[24:]
if rec_address == sender[2:]:
print "[+++] The address was recovered from the public key! :-)"
else:
print "[-] This address is not the same :-("
The ecdsa_raw_recover never results in the correct value. I've opened up the keyfile to verify the public/private key and the following line never results in the correct value.
rec_pub = bitcoin.ecdsa_raw_recover(rawhash,vrs)
Is there some aspect to this that I am missing or a better recommendation on how to achieve this? Thanks in advance!