Private key exported from Electrum, unable to recreate Address with Python I have created a new Electrum wallet, and here is an address:

1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA


By right-clicking on it, I choose "Private key" which gives:

Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx


Now I want to be able (to learn how it works) to go from this private key to the address, via elliptic curve multiplication.

Here is what I tried:

import bitcoin #pybitcointools
import base58
import binascii

pvt = 'Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx'
pvtdecoded = base58.b58decode(pvt)
pvthex = binascii.hexlify(pvtdecoded)[2:-8]     # remove the first initial byte for version and 4 final bytes for checksum
pvt2 = bitcoin.decode_privkey(pvthex, 'hex')    # decode as a decimal

# generate pubkey from pvtkey with elliptic curve multiplication
public_key = bitcoin.fast_multiply(bitcoin.G, pvt2)
addr = bitcoin.pubkey_to_address(public_key)
print addr


which gives: 1LNSuE4NKHTyHygeKwnU1equ7MjPMhayxB which is not the original address.

What's wrong? How to recover the original address (1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA) from the Private key by using elliptic curve multiplication?



Edit: As Kz....Wx private key looks like a WIF-compressed one, I tried to replace:

pvt2 = bitcoin.decode_privkey(pvthex, 'hex')    # decode as a decimal


by

pvt2 = bitcoin.decode_privkey('Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx', 'wif')


but then after elliptic curve multiplication, it gives another address, which is still not the good one! (18dFF3EQoPxR44TygdGxHPMe3LSLFeQe4U)
In both cases, you are not generating the address that corresponds to the compressed public key.

In the first case, you are creating what looks to be an invalid address. At the very least, the private key it is using is incorrect because it has the compression byte. This will change the value that you get for the private key when it is decoded. In order to get the same outcome as the second case, you would need to drop an additional byte from the decoded WIF key as that byte specifies compression. The key you are using there is 33 bytes rather than the 32 bytes for actual private keys.

In the second case, you are not creating the compressed public key to generate the address. It is still using the uncompressed public key. Instead of using fast_multiply and creating the public key yourself, you should be using privkey_to_pubkey. fast_multiply is a mathematical operation, it has no concept of compressed public keys. However privkey_to_pubkey does so it will create the proper public key. Then you can use that public key to generate the address.

Instead of doing

public_key = bitcoin.fast_multiply(bitcoin.G, pvt2)


you should be doing

public_key = bitcoin.privkey_to_pubkey(pvt)