Advertisement
zeroSteiner

sponges.py

Feb 27th, 2017
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.38 KB | None | 0 0
  1. from Crypto.Cipher import AES
  2. from SocketServer import ThreadingMixIn
  3. from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
  4. import sys
  5.  
  6. class Hasher:
  7.   def __init__(self):
  8.     self.aes = AES.new('\x00'*16)
  9.  
  10.   def reset(self):
  11.     self.state = '\x00'*16
  12.  
  13.   def ingest(self, block):
  14.     """Ingest a block of 10 characters """
  15.     block += '\x00'*6
  16.     state = ""
  17.     for i in range(16):
  18.       state += chr(ord(self.state[i]) ^ ord(block[i]))
  19.     self.state = self.aes.encrypt(state)
  20.  
  21.   def final_ingest(self, block):
  22.     """Call this for the final ingestion.
  23.  
  24.    Calling this with a 0 length block is the same as calling it one round
  25.    earlier with a 10 length block.
  26.    """
  27.     if len(block) == 10:
  28.       self.ingest(block)
  29.       self.ingest('\x80' + '\x00'*8 + '\x01')
  30.     elif len(block) == 9:
  31.       self.ingest(block + '\x81')
  32.     else:
  33.       self.ingest(block + '\x80' + '\x00'*(8-len(block)) + '\x01')
  34.  
  35.   def squeeze(self):
  36.     """Output a block of hash information"""
  37.     result = self.state[:10]
  38.     self.state = self.aes.encrypt(self.state)
  39.     return result
  40.  
  41.   def hash(self, s):
  42.     """Hash an input of any length of bytes.  Return a 160-bit digest."""
  43.     self.reset()
  44.     blocks = len(s) // 10
  45.     for i in range(blocks):
  46.       self.ingest(s[10*i:10*(i+1)])
  47.     self.final_ingest(s[blocks*10:])
  48.  
  49.     return self.squeeze() + self.squeeze()
  50.  
  51. class HashHandler(BaseHTTPRequestHandler):
  52.   def do_GET(self):
  53.     if self.path in ['/favicon.ico', '/index.html']:
  54.       # Stop.
  55.       self.send_response(409)
  56.       return
  57.  
  58.     try:
  59.       to_hash = self.path[1:].decode('hex')
  60.     except TypeError:
  61.       # Bad hex.
  62.       self.send_response(418)
  63.       return
  64.  
  65.     if to_hash == GIVEN:
  66.       # Nice try.
  67.       self.send_response(451)
  68.       return
  69.  
  70.     result = HASHER.hash(to_hash)
  71.     print(result)
  72.     print(TARGET)
  73.     if result != TARGET:
  74.       # Wrong
  75.       self.send_response(400)
  76.       return
  77.     self.send_response(200)
  78.     self.end_headers()
  79.     self.wfile.write(FLAG)
  80.  
  81. class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
  82.   pass
  83.  
  84. if __name__=='__main__':
  85.   assert(len(sys.argv) >= 3)
  86.   HASHER = Hasher()
  87.   with open('FLAG.txt') as f:
  88.     FLAG = f.read()
  89.   GIVEN = 'I love using sponges for crypto'
  90.   TARGET = HASHER.hash(GIVEN)
  91.   server = ThreadedHTTPServer((sys.argv[1], int(sys.argv[2])), HashHandler)
  92.   server.serve_forever()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement