Skip to content

Instantly share code, notes, and snippets.

@losh11
Created April 17, 2020 19:19
Show Gist options
  • Save losh11/c8eb4a33a20218d4426c030c6a033625 to your computer and use it in GitHub Desktop.
Save losh11/c8eb4a33a20218d4426c030c6a033625 to your computer and use it in GitHub Desktop.
Convert Bitcoin WIF to Litecoin WIF format
'''
Bitcoin WIF to Litecoin WIF converter
=== INFO ===
Idk
=== USAGE (example) ===
% python3 litecoinwif.py
what is your bitcoin WIF (the key dumped from bitcoin core)?
L1aW4aubDFB7yfras2S1mN3bqg9nwySY8nkoLmJebSLD5BWv3ENZ
your private key in litecoin format is: T7QmWLCmcd9ikWVTQfNsyiaynXo724TRwzf4CZwCAQWNb4zrE7RK
=== OWNERSHIP ===
Based on code written by Carlo Cervellin (carlo.cervellin.eu). https://github.com/crcarlo/btcwif/
'''
import hashlib
# base58 alphabet
alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def sha256(arg):
''' Return a sha256 hash of a hex string '''
byte_array = bytearray.fromhex(arg)
m = hashlib.sha256()
m.update(byte_array)
return m.hexdigest()
def b58encode(hex_string):
''' Return a base58 encoded string from hex string '''
num = int(hex_string, 16)
encode = ""
base_count = len(alphabet)
while (num > 0):
num, res = divmod(num, base_count)
encode = alphabet[res] + encode
return encode
def b58decode(v):
''' Decode a Base58 encoded string as an integer and return a hex string '''
if not isinstance(v, str):
v = v.decode('ascii')
decimal = 0
for char in v:
decimal = decimal * 58 + alphabet.index(char)
return hex(decimal)[2:] # (remove "0x" prefix)
def privToWif(priv, verbose=False):
''' Produce a WIF from a private key in the form of an hex string '''
# 1 - Take a private key
_priv = priv.lower() # just for aesthetics
if verbose:
print("Private key: "+_priv)
# 2 - Add a 0xB0 byte in front of it
# 0xB0 is the Litecoin WIF prefix
priv_add_x80 = "B0" + _priv
if verbose:
print("Private with x80 at beginning: "+priv_add_x80)
# 3 - Perform SHA-256 hash on the extended key
first_sha256 = sha256(priv_add_x80)
if verbose:
print("sha256: " + first_sha256.upper())
# 4 - Perform SHA-256 hash on result of SHA-256 hash
seconf_sha256 = sha256(first_sha256)
if verbose:
print("sha256: " + seconf_sha256.upper())
# 5 - Take the first 4 bytes of the second SHA-256 hash, this is the checksum
first_4_bytes = seconf_sha256[0:8]
if verbose:
print("First 4 bytes: " + first_4_bytes)
# 6 - Add the 4 checksum bytes from point 5 at the end of the extended key from point 2
resulting_hex = priv_add_x80 + first_4_bytes
if verbose:
print("Resulting WIF in HEX: " + resulting_hex)
# 7 - Convert the result from a byte string into a base58 string using Base58Check encoding. This is the Wallet Import Format
result_wif = b58encode(resulting_hex)
if verbose:
print("Resulting WIF: " + result_wif)
return result_wif
def wifToPriv(wif, verbose=False):
''' Produce the private ECDSA key in the form of a hex string from a WIF string '''
if not wifChecksum(wif):
raise Exception('The WIF is not correct (does not pass checksum)')
# 1 - Take a Wallet Import Format string
if verbose:
print("WIF: " + wif)
# 2 - Convert it to a byte string using Base58Check encoding
byte_str = b58decode(wif)
if verbose:
print("WIF base58 decoded: " + byte_str)
# 3 - Drop the last 4 checksum bytes from the byte string
byte_str_drop_last_4bytes = byte_str[0:-8]
if verbose:
print("Decoded WIF drop last 4 bytes: " + byte_str_drop_last_4bytes)
# 4 - Drop the first byte
byte_str_drop_first_byte = byte_str_drop_last_4bytes[2:]
if verbose:
print("ECDSA private key: " + byte_str_drop_first_byte)
return byte_str_drop_first_byte
def wifChecksum(wif, verbose=False):
''' Returns True if the WIF is positive to the checksum, False otherwise '''
# 1 - Take the Wallet Import Format string
if verbose:
print("WIF: " + wif)
# 2 - Convert it to a byte string using Base58Check encoding
byte_str = b58decode(wif)
if verbose:
print("WIF base58 decoded: " + byte_str)
# 3 - Drop the last 4 checksum bytes from the byte string
byte_str_drop_last_4bytes = byte_str[0:-8]
if verbose:
print("Decoded WIF drop last 4 bytes: " + byte_str_drop_last_4bytes)
# 3 - Perform SHA-256 hash on the shortened string
sha_256_1 = sha256(byte_str_drop_last_4bytes)
if verbose:
print("SHA256 1: " + sha_256_1)
# 4 - Perform SHA-256 hash on result of SHA-256 hash
sha_256_2 = sha256(sha_256_1)
if verbose:
print("SHA256 2: " + sha_256_2)
# 5 - Take the first 4 bytes of the second SHA-256 hash, this is the checksum
first_4_bytes = sha_256_2[0:8]
if verbose:
print("First 4 bytes: " + first_4_bytes)
# 6 - Make sure it is the same, as the last 4 bytes from point 2
last_4_bytes_WIF = byte_str[-8:]
if verbose:
print("Last 4 bytes of WIF: " + last_4_bytes_WIF)
bytes_check = False
if first_4_bytes == last_4_bytes_WIF:
bytes_check = True
if verbose:
print("4 bytes check: " + str(bytes_check))
# 7 - If they are, and the byte string from point 2 starts with 0x80 (0xef for testnet addresses), then there is no error.
check_sum = False
if bytes_check and byte_str[0:2] == "80":
check_sum = True
if verbose:
print("Checksum: " + str(check_sum))
return check_sum
def main():
user_bitcoin_wif = input(
'what is your bitcoin WIF (the key dumped from bitcoin core)?\n')
temp_priv = wifToPriv(user_bitcoin_wif)
temp_ltiecoin_wif = privToWif(temp_priv)
print('your private key in litecoin format is: ' + temp_ltiecoin_wif)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment