53 lines
1.2 KiB
Python
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)
|