First, what you defining as public key and personal key are literally a bitcoin deal with
and a non-public key
encoded in Pockets Import Format (WIF)
.
So as to verify that the WIF
and the bitcoin addresses
are from the identical key pair, we might want to decode the non-public key
from its WIF
format (checking that the encoding is okay), derive the public key
from the non-public key
, and generate the bitcoin deal with
utilizing the public key
. If the generated bitcoin deal with
matches with the supplied one, then the supplied one and the WIF
are created from the identical key pair.
So as to decode the WIF
we’ll observe the steps from the bitcoin wiki.
Lets see how we will do that in python:
from binascii import hexlify, unhexlify
from ecdsa import SigningKey, SECP256k1
from hashlib import sha256
from bitcoin_tools.pockets import generate_btc_addr, WIF, TESTNET_WIF
def wif_to_sk(wif, community='foremost'):
if community not in ['main', 'test']:
# Add extra networks if wanted.
elevate Exception('Bad community')
else:
if community is 'foremost':
model = WIF
else:
model = TESTNET_WIF
decoded_wif = b58decode(wif)
c = decoded_wif[-4:]
v = decoded_wif[:1]
# The byte defines the model, assert that's appropriate.
assert v == chr(model)
# The 4 final bytes of the WIF are the 4 first bytes of the checksum, verify that it holds
checksum = sha256(sha256(decoded_wif[:-4]).digest()).digest()
assert checksum[:4] == c
# If the non-public key within the WIF corresponds to a compressed public key, you have to additionally drop the final byte, that can
# be 01. We will verify that by checking the size of the present key. 32 bytes wil imply uncompressed, whereas 33 and
# a number one 01 means compressed.
sk = hexlify(decoded_wif[1:-4])
compressed = False
# Discover that since now we have hexlified the sk, the sizes are doubled.
if len(sk) is 66 and sk[-2:] == '01':
sk = unhexlify(sk[:-2])
compressed = True
else:
sk = unhexlify(sk)
return sk, compressed
# Your supplied knowledge
wif="KwfNqMip1ZdgG2o6wYQUBXv8BqkMQ8VWWeScVU5TLPZp31M5EHeq"
btc_addr="13YcHBzsBX8SxHoBftb69cXJkdXLfAVQos"
community = 'foremost'
sk, compressed = wif_to_sk(wif, community=community)
# Derive the general public key from the non-public key
pk = SigningKey.from_string(sk, curve=SECP256k1).get_verifying_key()
# Assert that the computed bitcoin deal with and the supplied one matches.
assert generate_btc_addr(pk, v=community, compressed=compressed) == btc_addr
To decode the WIF
format there’s a few issues that you could be know. First, the model
of the community (usually both mainnet
or testnet
) after which, if the non-public key
corresponds to a compressed or uncompressed public key
. The model of the community will decide the primary byte of the WIF
format, whereas whether or not the associated public key
is compressed or uncompressed will decide the final byte earlier than the checksum
.
Disclaimer: The supplied code makes use of a perform generate_btc_addr
, from a python library I’ve developed, that computes a bitcoin deal with
from a given public key
. Such perform name a bunch of different easy features to derive the bitcoin deal with
, however together with all on the reply will make it even longer that what it’s. You’ll be able to both get the library from GitHub, or get the features from the particular file.