Table of Contents

## What is a private key exactly?

Private keys are based on secret 256-bit long string of letters and numbers which are randomly selected when you create a bitcoin wallet. This address enables you to send the bitcoins to a recipients destination address. The private keys themselves are not shared with anyone else exact for the sender or creator, as this may allow others to have control over funds on that address.

The kind of cryptographic functions and numbers implemented for the security of the address, show just how random and unique the keys can become. Private uncompressed keys always begin with a 5, an example of this is:

## How Public keys work

Public keys consist of different numbers and letters which is derived from the private keys, after it has been encrypted via the use of mathematical functions. This encryption process can almost not be reversed, making it almost impossible to find out the original private keys. The hash of a pubic key in bitcoin usually always starts with a 1, if it is based on a Legacy version.

The public address is given on to the sender in order to receive bitcoins, there are also no limits to the amount of address that can be generated. There are a number of conversions that are applied to the private keys in order to generate keys and subsequent wallets addresses. This conversion is known as hash function and can be generated in a number of ways. Like swiping your mouse across a specific part of your computer screen and after this process is done it is irreversible.

## Creating Public keys with ECDSA

You have to apply an ECDSA to your private key as one of the first steps, this is also known as a Elliptic Curve Digital Signature Algorithm. Elliptic curves are defined by these equations (y2 = X3 + ax + b) with a and b being selected values. There are a variety of these equations curves that can be applied, Bitcoin uses the secp256k1 curve.

Through the application of the ECDSA the private key will result in a 64-byte integer, which will then be composed of two 32-byte integers. This will be represented by x and y on the elliptic curve.

The code required in Python language would be:

*private_key_bytes = codecs.decode(private_key, ‘hex’)*

*# Get ECDSA public key*

*Key = ends.SigningKey.from_string(private_key_bytes,*

*curve=ecdsa.SECP256k1).verifying_key*

*key_bytes = key.to_string()*

*key_hex = codecs.encode(key_bytes, ‘hex’)*

The above provided code was decoded using codecs. Users will be able to find at least two classes in Python that can keep the private and public keys. The first one is “str”, which is an array of string, together with “bytes” which is a byte array.

However, be careful when coding, as things can get a little confusing because an X string array is not the same as or equal to an X byte array. But the byte array becomes equal with two elements, which are O<. The codecs. Decode method that converts a string into a byte array. After the ECDSA is applied, the 0x04 will be added to the resulted public key and the 04 can be used as a prefix.This will generate a Bitcoin full public key. The compressing of the public key is next. Even though the long version of the public key can be used for the compression of the public key, it is used to make the compression of the public key much shorter.

This can be done manually by taking the X from the ECDSA’s public key and adding it to a 0x02, but only if the last byte of Y is equal and using the 0x03 byte if the last byte is odd.

## Encrypting keys with SHA-256 and RIPEMD-160

Its time to create a wallet address, the method that is applied to the public key is not that important as the procedures remains the same. However, this will cause different resulting addresses.

The application of two hash functions will be applied: the SHA-256 to the public key, then encrypting the result of the public key using RIPEMD-160. Make sure that all algorithms are applied in these exact orders. There will be a 160-bit integer at the end of this process that will be represented by an encrypted public key.

Encrypt this public key code in Python:

*# Run SHA-256 for the pubic key*

*sha256_bpk = hash lib.sha256(public_key_bytes)*

*sha256_bpk_digest = sha256_bpk.digest()*

*# Run RIPEMD-160 for the SHA-256*

*ripemd 160_bpk = hash lib.new(‘ripemd160’)*

*ripemd160_bpk.update(sha256_bpk_digest)*

*ripmd160_bpk_hex = codecs.encode(ripemd160_bpk_digest, ‘hex’)*

## The Checksum calculation

The following steps will be in order to calculate the checksum of the Mainnet key result. The checksum will be in order to ensure that the keys still maintain its integrity during the process. The checksums have to match for the address to be marked as valid. The code that are required in order to calculate a checksum address is:

*# Double SHA256 to get checksum*

*sha256_nbpk= hash lib.sha256(network_bitcoin_public_key_bytes)*

*sha256_2_nbpk_digest= sha256_nbpk.digest()*

*sha256_2_nbpk=hashlib.sha256(sha256_nbpk_digest)*

*sha256_2_nbpk_digest=sha256_2_nbpk_digest()*

*sha256_2_hex=codecs.encode(sha256_2_nbpk_digest, ‘hex’)*

*Checksum = sha256_2_hex[:8]*

## The Encoding of the keys with Base58

The keys are not the same as the BTC addresses, as these are because it has converted to a Base58 address. How to convert the hex address into a Base58 address will be shown below.

*Def base58(address_hex):*

*alphabet=’123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz*

*b58_string = “*

*# Get the number of leading zeros*

*Leading_zeros = len(address_hex) – len(address_hex.Istrip(‘0’))*

*# Convert hex to decimal*

*address_int= int(address_hex, 16)*

*#Append digits to the start of string*

*while address_int>0:*

*digit_char=alphabet[digit]*

*digit_string= digit_char + b587_string*

*address_int//=58*

*# Add’1′ for each 2 leading zeros*

*ones = leading_zeros // 2*

*for one in range(ones):*

*b58_string = ‘1’ + b58_string*

*return b58_string*

The string will represented as a compressed bitcoin wallet address to the creator. Make sure your private key is not compressed or it will look different, however, both will be just as valid.