Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ####################################Python Bitcoin KeyChain
- #This program takes an initial private key (seed) and and increment (customincr), and generates a list of keys (wallet).
- #Then it saves a .txt file holding the list of related keys.
- #No need for custom libraries, the eliptic equations are built in!
- #For good security, roll lots of d10 dice to sequence a key somewhere between 2^50 and 2^253.
- #Then pick an increment, the larger the better, but keep it below 2^150.
- #This program WILL generate any address, the limits are suggestions, and invalid keys should close program.
- #Keep those two numbers safe, they can be used to recreate the entire wallet!
- #Also, this is a ready to use application, to enable prompt for seeds, scroll down and uncomment blocks noted.
- ##### Lawsky Aug, '14 , some of this code is from other sources, and is free for all purposes.
- import hashlib, binascii # local imports required for conversions, they are standard with Python
- #import urllib2 #for blockchain query that is disabled
- #import json #for blockchain query that is disabled
- Pcurve = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 -1 # The proven prime
- N=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 # Number of points in the field
- Acurve = 0; Bcurve = 7 # These two defines the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve
- Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240 #x coordinate of GPoint
- Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424 #y coordinate of GPoint
- GPoint = (Gx,Gy) # This is our generator point. Trillions of dif ones possible
- t='123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' # Base58 Charset
- def Byte2Hex(b): #Convert a byte string to hex number
- out="";
- for x in b:
- y=hex(ord(x))[2:]
- if len(y)==1:
- y="0"+y
- out+="%2s"%y
- return out
- def Hex2Byte(hexStr): # convert hex number into a byte string
- bytes = []
- hexStr = ''.join( hexStr.split(" ") )
- for i in range(0, len(hexStr), 2):
- bytes.append( chr( int (hexStr[i:i+2], 16 ) ) )
- return ''.join( bytes )
- def Int2Byte(n,b): #Convert a integer to a byte string of length b
- out=""
- for i in range(b):
- (n,m)=divmod(n,256)
- out=chr(m)+out
- return out
- def modinv(a,n=Pcurve): #Extended Euclidean Algorithm/'division' in elliptic curves
- lm, hm = 1,0
- low, high = a%n,n
- while low > 1:
- ratio = high/low
- nm, new = hm-lm*ratio, high-low*ratio
- lm, low, hm, high = nm, new, lm, low
- return lm % n
- def ECadd(a,b): # Not true addition, invented for EC. Could have been called anything.
- LamAdd = ((b[1]-a[1]) * modinv(b[0]-a[0],Pcurve)) % Pcurve
- x = (LamAdd*LamAdd-a[0]-b[0]) % Pcurve
- y = (LamAdd*(a[0]-x)-a[1]) % Pcurve
- return (x,y)
- def ECdouble(a): # This is called point doubling, also invented for EC.
- Lam = ((3*a[0]*a[0]+Acurve) * modinv((2*a[1]),Pcurve)) % Pcurve
- x = (Lam*Lam-2*a[0]) % Pcurve
- y = (Lam*(a[0]-x)-a[1]) % Pcurve
- return (x,y)
- def EccMultiply(GenPoint,ScalarHex): #Double & add. Not true multiplication
- if ScalarHex == 0 or ScalarHex >= N: raise Exception("Invalid Scalar/Private Key")
- ScalarBin = str(bin(ScalarHex))[2:]
- Q=GenPoint
- for i in range (1, len(ScalarBin)): # This is invented EC multiplication.
- Q=ECdouble(Q); # print "DUB", Q[0]; print
- if ScalarBin[i] == "1":
- Q=ECadd(Q,GenPoint); # print "ADD", Q[0]; print
- return (Q)
- def numtowif(numpriv): #converts numerical private key to WIF
- step1 = '80'+hex(numpriv)[2:].strip('L').zfill(64)
- step2 = hashlib.sha256(binascii.unhexlify(step1)).hexdigest()
- step3 = hashlib.sha256(binascii.unhexlify(step2)).hexdigest()
- step4 = int(step1 + step3[:8] , 16)
- return ''.join([t[step4/(58**l)%58] for l in range(100)])[::-1].lstrip('1')
- def wiftonum(wifpriv): #converts from WIF to numerical private key
- return sum([t.index(wifpriv[::-1][l])*(58**l) for l in range(len(wifpriv))])/(2**32)%(2**256)
- def validwif(wifpriv): #validates WIF generated by converting it back and forth
- return numtowif(wiftonum(wifpriv))==wifpriv
- def b58encode(v): #Encode a byte string to the Base58
- base=len(t)
- val=0
- for c in v:
- val*=256
- val+=ord(c)
- result=""
- while val:
- (val,mod)=divmod(val,base)
- result=t[mod]+result
- pad=0
- for c in v:
- if c=="\0":
- pad+=1
- else:
- break
- return (t[0]*pad)+result
- def pubtoaddy(puk): #converts uncompressed public key to public address
- version=chr(0)
- h=hashlib.new("SHA256")
- h.update(puk)
- s=h.digest()
- h=hashlib.new("RIPEMD160")
- h.update(s)
- kh=version+h.digest()
- h=hashlib.new("SHA256")
- h.update(kh)
- cs=h.digest()
- h=hashlib.new("SHA256")
- h.update(cs)
- cs=h.digest()[:4]
- adr=b58encode(kh+cs)
- return adr
- ###Enable to allow blockchain query:
- #def GetBCIbalance(query):
- # url = 'https://blockchain.info/q/addressbalance/' + query
- # json_obj = urllib2.urlopen(url)
- # data = json.load(json_obj)
- # return data
- def genwallet(): # the main generator
- totalbalance = 0
- walletname = "DEFAULTWALLET.txt"
- #################Change these############ GENERATOR SEEDS: Initial numerical private key and numerical increment between keys, thus: key chain
- seedbtc=13787023450987234098623465093474584872345908273452360908908071097932145987679 # default seed = first numerical private key to use in generation
- customincr = 10873345756478567985678956481319876234879623450 # default increment between private keys
- ###################################################################################################################
- customcount = 50 # default address count
- #######DO NOT MOVE###########Enable the following to have Prompt for custom filename,seed and customincr -- these two numbers are all you need with this scrip to recover all keys, so pick smart.
- #customseed = input('Enter a seed number between 2^50 and 2^253: ') #Overrides default seed with prompt
- #seedbtc = customseed
- #customcount = input('How many wallets, 144 max: ')
- #if customcount >> 144:
- # customcount = 144
- #customincr = input('Enter an increment number between 2^3 and 2^116: ')
- #walletname = raw_input('Pick a filename: ')
- ########DO NOT MOVE##########You can also recover wallets made with this software with just the first two numerical private keys, prk2-prk1=customincr
- text_file = open(walletname, "w") #creates new file to store all keys, change the name of this file after/during creation to NOT LOSE KEYS!!!
- multn = 0 #don't change this or you'll have to remember it too!!! this is the multipier that spaces your private keys
- for looper in range(0,customcount): # for each address
- balance = 0
- privKey = seedbtc+customincr*multn # equals seedbtc on first run, then counts up by customincr. These are your numerical private keys.
- multn=multn+1 #counter for customincr multiplier
- hexprkstr= '%x' % privKey #removes 0x and 'L' for printing purposes
- PublicKey = EccMultiply(GPoint,privKey) #gets public key from Eliptic function
- WIFKEY = numtowif(privKey) #gets WIF
- wifvalid = validwif(numtowif(privKey)) #checks if WIF validates by double conversion
- ucpuk = "04" + "%064x" % PublicKey[0] + "%064x" % PublicKey[1]; #uncompressed public key
- if PublicKey[1] % 2 == 1: #odd compressed public key
- cpuk ="03"+str(hex(PublicKey[0])[2:-1]).zfill(64)
- else: #even compressed public key
- cpuk ="02"+str(hex(PublicKey[0])[2:-1]).zfill(64)
- PubAd = pubtoaddy(Hex2Byte(ucpuk)) #gets public address
- #balance = float(GetBCIbalance(PubAd))/100000000; balchen = true #Enable to do api balance check on blockchain.info
- #totalbalance = totalbalance + balance #tracks total balance for disabled query
- newhex = hexprkstr
- for padhexpr in range (0, (64 - len(hexprkstr))): #makes hex private key ready to copy
- newhex = "0"+ newhex # just padding left side with zeros until 64 characters
- hexprkstr = newhex
- print >>text_file
- print >>text_file,"PublicAddress",looper+1,": ",PubAd#, " ",balance #enable ', " ",balance' to print
- print >>text_file,"NumericalPrivteKey: "
- print >>text_file," ",privKey
- print >>text_file,"HexPrivateKey: "
- print >>text_file," ",hexprkstr
- print >>text_file,"WalletImportFormat: "
- print >>text_file," ",WIFKEY," : Use this to validate"
- if wifvalid:
- donothing=0 #does not print if WIF is valid
- else:
- print >>text_file," ","WIFValid: ",wifvalid #prints if WIF is invalid
- print >>text_file,"UncompressedPublicKey: "
- print >>text_file," ",ucpuk
- print >>text_file,"CompressedPublicKey: "
- print >>text_file," ",cpuk
- print PubAd#, " ",balance #enable ', " ",balance' to print
- text_file.close()
- print "File has been created with", multn, "key sets."# + " Total balance of: ", totalbalance #enable ' + " Total balance of: ", totalbalance' to print balance
- genwallet() # Start Generator
- ########################################This section enables restart
- #newwalletstart = "y"
- #yesido = "y"
- #while newwalletstart is yesido:
- # newwalletstart = raw_input('Create another wallet? y, else close:')
- # if newwalletstart is yesido:
- # genwallet()
- #########################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement