Correct way to convert a 256-bit private key to WIF?

3

2

On the Bitcoin wiki it has steps to convert a private key to WIF. So I tried following these steps in attempt to get the same result.

So I took the private key.

0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D

I put 80 on the front.

800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D

And then I performed SHA-256 on it using this.

e2e4146a36e9c455cf95a4f259f162c353cd419cc3fd0e69ae36d7d1b6cd2c09

And that is where I run into a problem. On the wiki page it says the result of SHA-256 should be...

8147786C4D15106333BF278D71DADAF1079EF2D2440A4DDE37D747DED5403592

And that does not match my SHA-256 result.

Not sure what I am doing wrong.

Nick

Posted 2016-05-22T19:36:12.253

Reputation: 33

Answers

3

You're performing a SHA256 on an ASCII string, not on the actual number. That ASCII string is actually the hexadecimal representation of the actual number.

This is a little code snippet that uses a hex2bin function to turn the hexadecimal representation (from your question) into an actual number before performing the sha256 on it.

Riaan Swart

Posted 2016-05-22T19:36:12.253

Reputation: 318

1

The value

e2e4146a36e9c455cf95a4f259f162c353cd419cc3fd0e69ae36d7d1b6cd2c09

corresponds to the SHA-256 hash of the string:

800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D

In order to obtain the desired result, the key has to be interpreted as a hexadecimal value. For instance, using this website to compute the hash, we obtain the same result than in the wiki:

8147786c4d15106333bf278d71dadaf1079ef2d2440a4dde37d747ded5403592

cpsola

Posted 2016-05-22T19:36:12.253

Reputation: 1 523

1

Here is how to use the bitcoin-explorer command line to generate an uncompressed WIF private key on a UNIX box:

% echo 0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D | bx base58check-encode -v 128

5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ

The following provides feedback for going the opposite direction:

% echo 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ | bx base58check-decode

wrapper 
{ 
  checksum 2371582544    
  payload  0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d   
  version  128 
}

To create a compressed WIF private key just suffix the private hex encoded key with 01:

% echo 0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D01 | bx base58check-encode -v 128

KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617

Alternatively the following set of piped commands perform the same functionality:

% echo 0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D | sed 's/$/01/' | bx wrap-encode -v 128 | bx base58-encode

0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D01 800c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d01a62019d2 KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617

The following double checks the compressed WIF key encoding:

% echo KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617 | bx base58check-decode

wrapper 
{
  checksum 3524862118
  payload 0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d01
  version 128 
}

skaht

Posted 2016-05-22T19:36:12.253

Reputation: 2 751

1

you need to use bytes.fromhex() function.

here is a related example (python3)

import hashlib
import ecdsa
import base58


def generate_private_and_public_keys(secret):
    #hash digest
    digest = hashlib.sha256(secret.encode()).hexdigest()

    #signing and verification keys
    signing_key = ecdsa.SigningKey.from_string(bytes.fromhex(digest), curve=ecdsa.SECP256k1)

    verifying_key = signing_key.verifying_key
    public_key = '04' + verifying_key.to_string().hex()

    return signing_key.to_string().hex(), public_key;


def get_wif_public_key(public_key):
    ripemd160 = hashlib.new('ripemd160')
    ripemd160.update(hashlib.sha256(bytes.fromhex(public_key)).digest())
    mm = '00' + ripemd160.digest().hex()

    checksum = hashlib.sha256((hashlib.sha256(bytes.fromhex(mm)).digest())).digest()[0:4]

    binary_addr = mm + checksum.hex()
    return base58.b58encode(bytes.fromhex(binary_addr))


private_key, public_key = generate_private_and_public_keys('erfjer;ljfecfv kfk  gf 74764 dlr;f;cmiofmsr')
print ('Private_key: {}'.format(private_key))
print ('Public key: {}'.format(public_key))

wif = get_wif_public_key(public_key)
print ('Bitcoin address: {}'.format(wif))

Mircea Stanciu

Posted 2016-05-22T19:36:12.253

Reputation: 151