F = GF(2) R. = PolynomialRing(F) S. = R.quotient_ring(x^64 + 1) T. = PolynomialRing(S) Ti. = T.quotient_ring(X^64 + 1) Tj. = T.quotient_ring(X^64) def num_to_poly(num): out = 0 i = 0 while num != 0: if num % 2 == 1: out += xi^i i += 1 num //= 2 return out def poly_to_num(poly): out = 0 for i in range(0, 64): if poly[i] == 1: out |= 1 << i return out with open("./07_weird_assembly_machine.data") as f: data = [int(line) for line in f.readlines() if line] f = reduce(lambda a, b: a * X + b, [num_to_poly(a) for a in data[:128]]) g = reduce(lambda a, b: a * X + b, [num_to_poly(a) for a in data[128:]]) fg = f(g) fgi = Ti([fg[i] for i in range(0, fg.degree())]) fgj = Tj([fg[i] for i in range(0, fg.degree())]) print("\n\n======= f(g(x)) =======") for i in reversed(range(0, 64)): print(poly_to_num(fgi.lift()[i])) print("\n\n======= f(g(x)) =======") for i in reversed(range(0, 64)): print(poly_to_num(fgj.lift()[i]))