https://furutsuki.hatenablog.com/entry/2020/09/21/092947
#!/usr/bin/python3 s = [] p = 0 def init(): global s,p s = [i for i in range(0,64)] p = 0 return def randgen(): global s,p a = 3 b = 13 c = 37 s0 = s[p] p = (p + 1) & 63 s1 = s[p] res = (s0 + s1) & ((1<<64)-1) s1 ^= (s1 << a) & ((1<<64)-1) s[p] = (s1 ^ s0 ^ (s1 >> b) ^ (s0 >> c)) & ((1<<64)-1) return res def jump(to): # Deleted... return def check_jump(): ... check_jump() init() for a in range(31337):randgen() flag = open("flag.txt").read() assert len(flag) == 256 enc = b"" for x in range(len(flag)): buf = randgen() sh = x//2 if sh > 64:sh = 64 mask = (1 << sh) - 1 buf &= mask jump(buf) enc += bytes([ ord(flag[x]) ^ (randgen() & 0xff) ]) print ("%r" % enc) open("enc.dat","wb").write(bytearray(enc))
N = 64 F = GF(2) def L(n): m = [[0 for x in range(N)] for y in range(N)] for i in range(N - n): m[i + n][i] = 1 return matrix(F, m) def R(n): m = [[0 for x in range(N)] for y in range(N)] for i in range(N - n): m[i][i + n] = 1 return matrix(F, m) def I(): m = [[0 for x in range(N)] for y in range(N)] for i in range(N): m[i][i] = 1 return matrix(F, m) def O(): m = [[0 for x in range(N)] for y in range(N)] return matrix(F, m) def genM(): a = 3 b = 13 c = 37 o = O() i = I() la = L(a) rb = R(b) rc = R(c) blocks = [ [i + rc, i + la + rb + la*rb] + [o for _ in range(62)] ] for j in range(1, N): row = [o for _ in range(N)] row[(j+1) % N] = i blocks.append(row) M = block_matrix(F, [*zip(*blocks)]) return M def initial_state(): s = "".join(["{:064b}".format(i) for i in range(N)]) vec = [] for c in s: vec.append(F(int(c))) return Matrix(F, vec) def getvalue(row, index): v = 0 for i in range(N): v = v*2 + int(row[0][index*N + i]) return v def dumpstate(a): xs = [] for i in range(N): xs.append(getvalue(a, i)) print(xs) s = initial_state() M = genM() def init(): global s, M s = initial_state() M = genM() def randgen(): global s, M res = (getvalue(s, 0) + getvalue(s, 1)) % ((1<<64)-1) s = s * M return res def jump(n): global s,M s = s * (M^n) init() jump(31337) for x in range(256): buf = randgen() sh = x//2 if sh > 64:sh = 64 mask = (1 << sh) - 1 buf &= mask jump(buf) print(randgen() & 0xff)