Skip to content

Instantly share code, notes, and snippets.

@saucecode
Created January 24, 2015 07:57
Show Gist options
  • Save saucecode/86362662842bd78f4d46 to your computer and use it in GitHub Desktop.
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
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