Skip to content

Commit 781ee86

Browse files
author
tkhaew
committed
add keyscan and supernova
1 parent dd183af commit 781ee86

File tree

4 files changed

+210
-0
lines changed

4 files changed

+210
-0
lines changed

README

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ Place to put small code scraps and pull in other small repos.
33
scripts:
44
qrclip - capture qr code from webcam/img to clipboard
55
entropy - monitor entropy available by showing every 1 second
6+
keyscan - brute force a Bitcoin private key (wif) for single digit typos
7+
supernova - generate a Bitcoin black hole address matching prefix
68

79
greasemonkey:
810
collapsetips - script to collapse ChangeTips on /r/bitcoin

scripts/bfxlog

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/usr/bin/python
2+
3+
import os, sys, getopt, daemon, time, datetime, signal, pwd, getpass, pickle
4+
import json, requests
5+
6+
version = "0.1.0"
7+
api_url = "https://api.bitfinex.com/v1/trades/btcusd?timestamp=%d"
8+
cfg = { 'poll':60, 'log':sys.argv[0]+'.json', 'pid':sys.argv[0]+'.pid' }
9+
10+
def main():
11+
if not 'last' in cfg:
12+
resetlog()
13+
if cfg['debug']:
14+
try:
15+
run()
16+
except KeyboardInterrupt:
17+
sys.exit(1)
18+
else:
19+
with daemon.DaemonContext(working_directory='.', stdout=open(sys.argv[0]+'.log','a'), stderr=open(sys.argv[0]+'.log','a'),
20+
signal_map={signal.SIGTERM:sigterm}):
21+
run()
22+
23+
def run():
24+
print logts(), "Started pid:", os.getpid()
25+
with file(cfg['pid'],'w') as f: f.write(str(os.getpid()))
26+
sys.stdout.flush()
27+
while 1:
28+
update()
29+
sys.stdout.flush()
30+
time.sleep(cfg['poll'])
31+
32+
def update():
33+
try:
34+
r = requests.get(api_url % cfg['last']['timestamp'])
35+
if r.status_code == requests.codes.ok:
36+
data = r.json()
37+
if data[0]:
38+
with open(cfg['log'], "r+") as f:
39+
f.seek (-1, os.SEEK_END)
40+
if cfg['last']['tid'] > 0:
41+
f.write(',')
42+
for trade in data[::-1]:
43+
if trade['tid'] > cfg['last']['tid']:
44+
f.write(json.dumps(trade))
45+
f.write(',')
46+
f.seek (-1, os.SEEK_END)
47+
f.write(']')
48+
cfg['last'] = data[0]
49+
savecfg()
50+
print logts(), "Updated tid:", cfg['last']['tid']
51+
except requests.exceptions.ConnectionError:
52+
pass
53+
54+
def loadcfg():
55+
global cfg
56+
try:
57+
with open(sys.argv[0]+'.cfg') as f:
58+
cfg = pickle.load(f)
59+
except IOError:
60+
print logts(),'No cfg file.\n',
61+
finally:
62+
cfg['debug'] = False
63+
options()
64+
65+
def savecfg():
66+
try:
67+
with open(sys.argv[0]+'.cfg', 'w') as f:
68+
pickle.dump(cfg, f)
69+
except IOError:
70+
print logts(),'Cannot save cfg file'
71+
72+
def options():
73+
try:
74+
opts,args = getopt.getopt(sys.argv[1:], "hvrp:u:l:i:s",
75+
["help", "version", "debug", "reset", "poll=", "user=", "log=", "pid=", "defaults" ])
76+
except getopt.GetoptError:
77+
usage()
78+
for opt,arg in opts:
79+
if opt in ("-h", "--help"):
80+
usage()
81+
elif opt in ("-v", "--version"):
82+
sys.exit('Version: '+version)
83+
elif opt in ("-p", "--poll"):
84+
cfg['poll'] = int(arg)
85+
elif opt in ("-u", "--user"):
86+
cfg['user'] = arg
87+
elif opt in ("-l", "--log"):
88+
cfg['log'] = arg
89+
elif opt in ("-i", "--pid"):
90+
cfg['pid'] = arg
91+
elif opt in ("-r", "--reset"):
92+
resetlog()
93+
elif opt in ("-s", "--defaults"):
94+
savecfg()
95+
print "%s updated" % (sys.argv[0]+'.cfg')
96+
sys.exit()
97+
elif opt in ("--debug"):
98+
cfg['debug'] = True
99+
100+
def usage():
101+
print """Command options are:\n-h,--help\tShow this help info\n-v,--version\tShow version info\n-s,--defaults\tUpdate cfg and exit\n
102+
Cfg file is %s.cfg\nThese options get saved in cfg file as default.\n-r,--reset\tReset last trade id to 0, truncate log file\n
103+
-p,--poll\tPoll interval in seconds\n-u,--user\tRun as user\n-l,--log\tSet log file path
104+
-i,--pid\tSet pid file path""" % sys.argv[0]
105+
sys.exit(1)
106+
107+
def sigterm(signum, frame):
108+
print "%s SIGTERM - Shutting down" % logts()
109+
os.unlink(cfg['pid'])
110+
sys.exit(2)
111+
112+
def logts():
113+
return datetime.datetime.now().strftime('%d-%m-%Y %H:%M:%S')
114+
115+
def resetlog():
116+
cfg['last'] = { 'timestamp':0, 'tid':0 }
117+
savecfg()
118+
with open(cfg['log'], "w") as f:
119+
f.write("[]")
120+
121+
if __name__ == '__main__':
122+
loadcfg()
123+
if 'user' in cfg:
124+
print logts(),"Running as:",cfg['user']
125+
uid = pwd.getpwnam(cfg['user']).pw_uid
126+
os.setgid(uid)
127+
os.setuid(uid)
128+
129+
main()
130+

scripts/keyscan

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python
2+
#
3+
# brute force a given private key with single digit variations
4+
# and compare to known address for match.
5+
#
6+
import sys, ecdsa, hashlib
7+
8+
priv_key_wif = "5JYRjeoR3E69Zx5Jr3RByy372bKp4z186swYfSLW43iivHrCt5e" # testing for 5JYRieoR3E69Zx5Jr3RByy372bKp4z186swYfSLW43iivHrCt5e
9+
target_addr = "165MdrCVNhHgBKckY5CNePqatLKjFmkZ7M"
10+
11+
# secp256k1, http://www.oid-info.com/get/1.3.132.0.10
12+
_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
13+
_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
14+
_b = 0x0000000000000000000000000000000000000000000000000000000000000007L
15+
_a = 0x0000000000000000000000000000000000000000000000000000000000000000L
16+
_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
17+
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
18+
curve_secp256k1 = ecdsa.ellipticcurve.CurveFp( _p, _a, _b )
19+
generator_secp256k1 = ecdsa.ellipticcurve.Point( curve_secp256k1, _Gx, _Gy, _r )
20+
oid_secp256k1 = (1,3,132,0,10)
21+
SECP256k1 = ecdsa.curves.Curve("SECP256k1", curve_secp256k1, generator_secp256k1, oid_secp256k1 )
22+
23+
# support functions - formatting and conversion
24+
25+
alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
26+
27+
def b58encode(addr):
28+
global alphabet
29+
long_value = 0L
30+
for (i, c) in enumerate(addr[::-1]):
31+
long_value += (256**i) * ord(c)
32+
33+
result = ''
34+
while long_value >= 58:
35+
div, mod = divmod(long_value, 58)
36+
result = alphabet[mod] + result
37+
long_value = div
38+
result = alphabet[long_value] + result
39+
40+
nPad = 0
41+
for c in addr:
42+
if c == '\0': nPad += 1
43+
else: break
44+
45+
return (alphabet[0]*nPad) + result
46+
47+
def public_key_to_address(public_key):
48+
vh160 = chr(0) + ripemd160( sha256( public_key ))
49+
hash = sha256(sha256( vh160 ))
50+
return b58encode( vh160 + hash[0:4] )
51+
52+
def sha256(msg):
53+
return hashlib.sha256(msg).digest()
54+
55+
def ripemd160(msg):
56+
md = hashlib.new('ripemd160')
57+
md.update( msg )
58+
return md.digest()
59+
60+
def b58hex(s58):
61+
num = 0L
62+
for (i, c) in enumerate(s58[::-1]):
63+
num += alphabet.find(c) * (58**i)
64+
return hex(num)[4:-9].upper()
65+
66+
for pos in range(len(priv_key_wif)-1):
67+
print "scanning digit", pos+1
68+
for c in alphabet:
69+
priv_key_chk = list(priv_key_wif)
70+
priv_key_chk[pos+1] = c
71+
priv_key = "".join(priv_key_chk)
72+
pub_key = chr(4) + ecdsa.SigningKey.from_secret_exponent(long(b58hex(priv_key), 16), curve=SECP256k1 ).get_verifying_key().to_string()
73+
if public_key_to_address(pub_key) == target_addr:
74+
print priv_key
75+
exit(0)
76+
77+
78+

supernova scripts/supernova

File renamed without changes.

0 commit comments

Comments
 (0)