stuff
This commit is contained in:
96
training/IntroZ3/tasks/chall1_rot128/server.py
Normal file
96
training/IntroZ3/tasks/chall1_rot128/server.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import random, os, signal
|
||||
from Crypto.Util.number import long_to_bytes as l2b, bytes_to_long as b2l
|
||||
from secret import FLAG
|
||||
|
||||
ROUNDS = 3
|
||||
USED_STATES = []
|
||||
_ROL_ = lambda x, i : ((x << i) | (x >> (N-i))) & (2**N - 1)
|
||||
N = 128
|
||||
|
||||
def handler(signum, frame):
|
||||
print("\n\nToo slow, don't try to do sneaky things.")
|
||||
exit()
|
||||
|
||||
def validate_state(state):
|
||||
if not all(0 < s < 2**N-1 for s in user_state[-2:]) or not all(0 <= s < N for s in user_state[:4]):
|
||||
print('Please, make sure your input satisfies the upper and lower bounds.')
|
||||
return False
|
||||
|
||||
if sorted(state[:4]) in USED_STATES:
|
||||
print('You cannot reuse the same state')
|
||||
return False
|
||||
|
||||
if sum(user_state[:4]) < 2:
|
||||
print('We have to deal with some edge cases...')
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
class HashRoll:
|
||||
def __init__(self):
|
||||
self.reset_state()
|
||||
|
||||
def hash_step(self, i):
|
||||
r1, r2 = self.state[2*i], self.state[2*i+1]
|
||||
return _ROL_(self.state[-2], r1) ^ _ROL_(self.state[-1], r2)
|
||||
|
||||
def update_state(self, state=None):
|
||||
if not state:
|
||||
self.state = [0] * 6
|
||||
self.state[:4] = [random.randint(0, N) for _ in range(4)]
|
||||
self.state[-2:] = [random.randint(0, 2**N) for _ in range(2)]
|
||||
else:
|
||||
self.state = state
|
||||
|
||||
def reset_state(self):
|
||||
self.update_state()
|
||||
|
||||
def digest(self, buffer):
|
||||
buffer = int.from_bytes(buffer, byteorder='big')
|
||||
m1 = buffer >> N
|
||||
m2 = buffer & (2**N - 1)
|
||||
self.h = b''
|
||||
for i in range(2):
|
||||
self.h += int.to_bytes(self.hash_step(i) ^ (m1 if not i else m2), length=N//8, byteorder='big')
|
||||
return self.h
|
||||
|
||||
|
||||
print('Can you test my hash function for second preimage resistance? You get to select the state and I get to choose the message ... Good luck!')
|
||||
|
||||
hashfunc = HashRoll()
|
||||
|
||||
for _ in range(ROUNDS):
|
||||
print(f'ROUND {_+1}/{ROUNDS}!')
|
||||
|
||||
server_msg = os.urandom(32)
|
||||
hashfunc.reset_state()
|
||||
server_hash = hashfunc.digest(server_msg)
|
||||
print(f'You know H({server_msg.hex()}) = {server_hash.hex()}')
|
||||
|
||||
signal.signal(signal.SIGALRM, handler)
|
||||
signal.alarm(2)
|
||||
|
||||
user_state = input('Send your hash function state (format: a,b,c,d,e,f) :: ').split(',')
|
||||
|
||||
try:
|
||||
user_state = list(map(int, user_state))
|
||||
|
||||
if not validate_state(user_state):
|
||||
print("The state is not valid! Try again.")
|
||||
exit()
|
||||
|
||||
hashfunc.update_state(user_state)
|
||||
|
||||
if hashfunc.digest(server_msg) == server_hash:
|
||||
print(f'Moving on to the next round!')
|
||||
USED_STATES.append(sorted(user_state[:4]))
|
||||
else:
|
||||
print('Not today.')
|
||||
exit()
|
||||
except:
|
||||
print("The hash function's state must be all integers.")
|
||||
exit()
|
||||
finally:
|
||||
signal.alarm(0)
|
||||
|
||||
print(f'Uhm... how did you do that? I thought I had cryptanalyzed it enough ... {FLAG}')
|
||||
Reference in New Issue
Block a user