Skip to content

Instantly share code, notes, and snippets.

@nealmcb
Last active May 26, 2021 09:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nealmcb/c919653d5b0da2b6bbd841205ba0b518 to your computer and use it in GitHub Desktop.
Save nealmcb/c919653d5b0da2b6bbd841205ba0b518 to your computer and use it in GitHub Desktop.
Calculate Bitcoin address corresponding to given ECDSA private key. Handy for verifying document timestamps provided by OriginStamp.org.
#!/usr/bin/env python
"""Calculate Bitcoin address corresponding to given ECDSA private key.
Handy for verifying document timestamps provided by OriginStamp.org.
Usage: ecdsa_to_bitocin_addy.py ecdsa_private_key # that's a 64-character hex string
Prerequisite:
pip install ecdsa
Core logic from https://bitcointalk.org/index.php?topic=84238.0
See also https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses#How_to_create_Bitcoin_Address
"""
import sys
import ecdsa
usage = "Usage: %s ecdsa_private_key (64-character hex)" % sys.argv[0]
secp256k1curve=ecdsa.ellipticcurve.CurveFp(115792089237316195423570985008687907853269984665640564039457584007908834671663,0,7)
secp256k1point=ecdsa.ellipticcurve.Point(secp256k1curve,0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8,0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
secp256k1=ecdsa.curves.Curve('secp256k1',secp256k1curve,secp256k1point,(1,3,132,0,10))
#--------------------------------------
import binascii, hashlib
def addy(pk):
"""
Return Bitcoin address corresponding to given ECDSA private key.
E.g. to verify https://app.originstamp.org/s/9f05ce06f0ca898f883cd32e54381448f440072a5545e9318c63d7ed425fcc84
>>> addy(0x8f650ae299dbdf92558579fd4524e29df2424b0a3c5ce3c715fd2c6160681853)
'1NS3x99PykY5Aa9J8fSstu2NcAws5kBrVy'
"""
pko=ecdsa.SigningKey.from_secret_exponent(pk,secp256k1)
pubkey=binascii.hexlify(pko.get_verifying_key().to_string())
pubkey2=hashlib.sha256(binascii.unhexlify('04'+pubkey)).hexdigest()
pubkey3=hashlib.new('ripemd160',binascii.unhexlify(pubkey2)).hexdigest()
pubkey4=hashlib.sha256(binascii.unhexlify('00'+pubkey3)).hexdigest()
pubkey5=hashlib.sha256(binascii.unhexlify(pubkey4)).hexdigest()
pubkey6=pubkey3+pubkey5[:8]
pubnum=int(pubkey6,16)
pubnumlist=[]
while pubnum!=0: pubnumlist.append(pubnum%58); pubnum/=58
address=''
for l in ['123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'[x] for x in pubnumlist]:
address=l+address
return '1'+address
if __name__ == "__main__":
# print addy(0x18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725)
# print addy(int(hashlib.sha256('something small and easy to remember but not easy to guess').hexdigest(),16))
# print addy(int(hashlib.sha256(file('hiddeninplainsight.jpg','rb+').read()).hexdigest(),16))
if len(sys.argv) < 2:
print(usage)
sys.exit(1)
ecdsa_private = sys.argv[1]
print("Bitcoin address is %s for ECDSA private key\n %s" % (addy(int(ecdsa_private, 16)), ecdsa_private))
@Nikolaj-K
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment