Created
January 24, 2015 07:57
-
-
Save saucecode/86362662842bd78f4d46 to your computer and use it in GitHub Desktop.
A proof of work challenge server that issues and checks POW challenges, keeping score
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket, random, string, hashlib | |
''' | |
challenge request packet format | |
\x08[HASH] [START] [SEED] | |
sends a hash algorithm (SHA1, MD5, etc), what the hash must start with, and what the prehashed string must start with | |
challenge response packet format | |
\x09[FULL PRE-HASH] | |
The [FULL PRE-HASH] must start with [SEED] and when hashed with [HASH] algorithm, the result starts with [START] | |
''' | |
randomstring = lambda x:''.join([random.choice(string.printable[:62]) for i in range(x)]) | |
sequential = lambda y: (lambda s: s(y, s))(lambda x, s: "" if not x else s(int((x-1) / 256), s) + chr((x % 256) - 1 if x % 256 != 0 else 255)) | |
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
sock.bind(('0.0.0.0', 9696)) | |
sock.settimeout(1) | |
users = {} | |
while 1: | |
try: | |
data,addr = sock.recvfrom(64000) | |
if data[0] == '\x05': # register me | |
users[addr] = {'score':0} | |
sock.sendto('\x05OK', addr) | |
print 'registered',addr | |
elif data[0] == '\x06': # unregister me | |
del users[addr] | |
sock.sendto('\x06OK', addr) | |
print 'unregistered',addr | |
elif data[0] == '\x07': # what is my score | |
if addr in users.keys(): | |
sock.sendto('\x07' + str(users[addr]), addr) | |
else: | |
sock.sendto('\x07NOT REGISTERED', addr) | |
elif data[0] == '\x08': # give me a challenge | |
if addr in users.keys(): | |
hashseed = randomstring(5) | |
sock.sendto('\x08SHA1 0000 ' + hashseed, addr) | |
users[addr]['challenge'] = {'hash':'SHA1', 'start':'0000', 'seed':hashseed} | |
print 'issued new challenge to',addr,'::',users[addr]['challenge'] | |
else: | |
sock.sendto('\x08NOT REGISTERED', addr) | |
elif data[0] == '\x09': # challenge answered | |
if not addr in users.keys(): | |
sock.sendto('\x09NOT REGISTERED', addr) | |
continue | |
if not 'challenge' in users[addr].keys(): | |
sock.sendto('\x09NOT CHALLENGED', addr) | |
continue | |
prehash = data[1:] | |
if prehash.startswith(users[addr]['challenge']['seed']) and hashlib.new(users[addr]['challenge']['hash'], prehash).hexdigest().startswith(users[addr]['challenge']['start']): | |
sock.sendto('\x09OK', addr) | |
users[addr]['score'] += 1 | |
del users[addr]['challenge'] | |
print addr,'solved their challenge' | |
else: | |
sock.sendto('\x09WRONG', addr) | |
del users[addr]['challenge'] | |
print addr,'failed their challenge' | |
except socket.timeout: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment