from Crypto.Util.number import * import itertools from tqdm import tqdm, trange TARGET = 201431453607244229943761366749810895688 h0 = 0x6c62272e07bb014262b821756295c58d p = 0x0000000001000000000000000000013b MOD = 2^128
n = 16 M = Matrix.column([p^(n - i - 1) for i inrange(n)] + [-(TARGET - h0*p^n), MOD]) M = M.augment(identity_matrix(n+1).stack(vector([0] * (n+1)))) Q = Matrix.diagonal([2^128] + [2^4] * n + [2^8]) M *= Q M = M.BKZ() M /= Q for r in M: if r[0] == 0andabs(r[-1]) == 1: r *= r[-1] good = r[1:-1] print(good) break inp = [] y = int(h0*p) t = (h0*p^n + good[0] * p^(n-1)) % MOD for i inrange(n): for x inrange(256): y_ = (int(y) ^^ int(x)) * p^(n-i-1) % MOD if y_ == t: print('good', i, x) inp.append(x) if i < n-1: t = (t + good[i+1] * p^(n-i-2)) % MOD y = ((int(y) ^^ int(x)) * p) % MOD break else: print('bad', i) print(bytes(inp).hex())
#!/usr/bin/sage a, b, f, rlwe_modulus = load("rlwe_ciphertext.sobj") rlwe_dim = 64 names = ','.join(['x'] + [f's{i}'for i inrange(rlwe_dim)]) P = PolynomialRing(GF(rlwe_modulus), names = names) x = P.gen(0) a = sum(a_*x^i for i,a_ inenumerate(list(a))) b = sum(b_*x^i for i,b_ inenumerate(list(b))) f = sum(f_*x^i for i,f_ inenumerate(list(f))) Q = P.quo(f)
s = P.gens()[1:] t = Q(sum(a.monomial_coefficient(x^i)*x^i for i inrange(rlwe_dim))) * Q(sum(s_*x^i for i,s_ inenumerate(list(s)))) tl = t.lift() tm = tl.monomials() tc = tl.coefficients()
L = zero_matrix(ZZ, 2*rlwe_dim + 1, 2*rlwe_dim + 1) for c, m inzip(tc, tm): j = m.degree(x) i = s.index(m // x^j) L[i, j] = c
decoded_string = "" for i inrange(0, len(encoded_string), 2): encoded_pair = encoded_string[i:i+2] for key, value in output_mapping.items(): if value == encoded_pair: decoded_string += key break