Files
ctf/training/IntroZ3/tasks/chall2_dreamer/test.py
2025-03-24 22:08:34 +01:00

53 lines
1.2 KiB
Python

import random
import z3
def ROL(X, N):
if isinstance(X, z3.BitVecRef):
return z3.RotateLeft(X,N)
else:
return ((((X) << (N)) | ((X) >> (64 - (N)))) % (2 ** 64))
def ROR(X, N):
if isinstance(X, z3.BitVecRef):
return z3.RotateRight(X,N)
else:
return ((((X) >> (N)) | ((X) << (64 - (N)))) % (2 ** 64))
def custom_random(state):
NEW_STATE = ROL(state,30) ^ ROR(state,12) ^ ROL(state,42) ^ ROL(state,4) ^ ROR(state,5)
return NEW_STATE % 256, NEW_STATE
def get_seed_for_sequence(bytesequence):
s = z3.Solver()
base_state = z3.BitVec("base_state", 64)
cur_state = base_state
s.add(base_state > 0)
for byte in bytesequence:
gen_byte, cur_state = custom_random(cur_state)
s.add(gen_byte == byte)
if s.check() != z3.sat:
raise RuntimeError()
m = s.model()
return m[base_state].as_long()
def gen_sequence(seed, length):
r = []
cs = seed
for _ in range(length):
v, cs = custom_random(cs)
r.append(v)
return bytes(r)
test = random.getrandbits(32).to_bytes(4, "little")
seed = get_seed_for_sequence(test)
print(seed)
print(test)
assert test == gen_sequence(seed, 4)