import base64, itertools, sys q, n, m = 12289, 256, 13 d = sys.argv[1] if len(sys.argv) > 1 else './files' def polys(b): return [[int.from_bytes(b[2*(k*n+i):2*(k*n+i)+2], 'little') for i in range(n)] for k in range(len(b)//(2*n))] pk = polys(base64.b64decode(open(d+'/pk_b64.txt').read().strip())) ct = polys(base64.b64decode(open(d+'/ct_b64.txt').read().strip())) A = [(pk[2*i], pk[2*i+1]) for i in range(m)] c0, c1 = ct for r in itertools.product([0,1], repeat=m): s = [0]*n for ri,(a,_) in zip(r,A): if ri: s = [(x+y) % q for x,y in zip(s,a)] if s == c0: v = c1[:] for ri,(_,b) in zip(r,A): if ri: v = [(x-y) % q for x,y in zip(v,b)] bits = ''.join('1' if x == q//2 else '0' for x in v) assert all(x in (0, q//2) for x in v) print(r, bytes(int(bits[i:i+8],2) for i in range(0,n,8)).rstrip(b'\0')) break