Bitcoin has notation method of some kinds in private key and public key.
Why Bitcoin has some kinds of notation?
Because if you adopted compressed notation, It's possible to reduce the size of the public key by 50%!
That means we can reduce greatly the size of transaction and blockchain prevents enlargement.
Problems caused by using compressed notation
Wallet has two types that correspond to compressed or uncompressed,
Which causes problems when importing private key into different type of wallet.
The receiving wallet needs to scan the blockchain to find the transaction corresponding to the sent private key.
At that time, it can not be determined whether the address based on compressed public key or uncompressed public key.
In order to solve the problem,private key use properly WIF format and WIF compression format.
Private key notation method
①Hexadecimal notation(64 hex characters)
The number was generated by random number(256-bit).
※About how to generate for raw private key,please check below past blog.
②WIF(prefix「5」:51 hex characters)
Format for importing private key into wallet(WIF).
It inform to came from new wallet that have compress function.
0x08 + private key → checksum 0x08 + private key + checksum → Base58checkencode → WIF
def ifchecksum(code): return hashlib.sha256(hashlib.sha256(code).digest()).digest()[:4] def private_key_to_wif(private_key): assert(len(private_key) == 32) checksum = wifchecksum(b"\x80" + private_key) return b58encode(b"\x80" + private_key + checksum) print (private_key_to_wif(private_key))
→Designated checksum for WIF
assert(len(private_key) == 32)
→If number of private key and 32 byte not equals,return error.
checksum = wifchecksum(b"\x80" + private_key)
→Add "0x08" to prefix of private key,generate checksum.
return b58encode(b"\x80" + private_key + checksum)
③WIF-compressed(prefix「K or L」:52-characters)
It indicate to came from new wallet that have compress function,and it means that must make compressed public key.
0x08 + private key + checksum + 0x01 → Base58checkencode
def private_key_to_wif_compressed(private_key): assert(len(private_key) == 32) checksum = wifchecksum(b"\x80" + private_key) return b58encode(b"\x80" +( private_key +b"\x01")+ checksum) print(private_key_to_wif_compressed(private_key))
→The only one difference to WIF format, it do checksum after add "0x01".
Public key notation method
①Hexadecimal number notation(130 hex characters)
※About how to generate for hexadecimal public key,please check below past blog.
②Compressed(66 hex characters)
We can calculate the y coordinate by below equation of solving when know the x coordinate .
y2 mod p = (x3 + 7) mod p
But notice that means the solution for y is a square root, which have a positive or negative value.
When calculating elliptic curve on the finite field of prime number order p,
that means y coordinate is either even or odd,corresponds to the positive and negative sign.
0x02 + X coodinateoo（Y coordinate is even) 0x03 + X coodinateoo（Y coordinate is odd)
(public_key_x, public_key_y) = public_key if (public_key_y % 2) == 0: compressed_prefix = '02' else: compressed_prefix = '03' encode_pubkey = "%x"%public_key hex_compressed_public_key = compressed_prefix + encode_pubkey print (hex_compressed_public_key)
(public_key_x, public_key_y) = public_key
→Public key divide to X coordinate and Y coordinate
compressed_prefix = '02', compressed_prefix = '03'
→Public key with the prefix 02 if the y is even, and 03 if it is odd
※1 If the wallet receiving the secret key does not correspond to the compressed format,it export private key in WIF format instead of WIF compressed format.
※2 If the wallet corresponde compressed format,when exporting private keys they are always output in compressed WIF format,and all transactions are done in compressed way.
The code used in this article is published in Github.