from Crypto.Util.number import * import itertools import hashlib from Crypto.Cipher import AES
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree() R = f.base_ring() N = R.cardinality()
f /= f.coefficients().pop(0) f = f.change_ring(ZZ)
G = Sequence([], f.parent()) for i inrange(m + 1): base = N ^ (m - i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = base * prod(map(power, f.variables(), shifts)) G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1 / factor)
H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B * monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots
return []
msg = b'welcome to n1ctf2023!' msg_hash = bytes_to_long(hashlib.sha256(msg).digest())
s = 98064531907276862129345013436610988187051831712632166876574510656675679745081 r = 9821122129422509893435671316433203251343263825232865092134497361752993786340
p = 115792089210356248762697446949407573529996955224135760342422259061068512044369 leak = int("10000111001100100010110100100000000100101000111011000001001011010100001010010000101001100011011010100000010010011011100010111001", 2) P.<low,small> = PolynomialRing(Zmod(p))
from Crypto.Util.number import * import os FLAG = os.environ.get('FLAG', b'n1ctf{XXXXFAKE_FLAGXXXX}') assert FLAG[:6] == b'n1ctf{'and FLAG[-1:] == b'}' FLAG = FLAG[6:-1]
defkeygen(nbits): whileTrue: q = getPrime(nbits) if isPrime(2*q+1): ifpow(0x10001, q, 2*q+1) == 1: return2*q+1
p = keygen(512) flag = bytes_to_long(FLAG) messages = [getRandomNBitInteger(flag.bit_length()) for i inrange(200)] enc = [encrypt(p, message, flag) for message in messages]
m_l = 159 dim = 200 L = matrix(ZZ, dim, dim+m_l+1) g = 2 ^ 512 for i inrange(dim): L[i, i] = 1 L[i, dim+m_l] = g
for i inrange(dim): line = bin(message[i])[2:].rjust(m_l, '0') for j inrange(len(line)): ifint(line[j]): L[i, dim+j] = g else: L[i, dim+j] = 0
basis = L.LLL()[:40] p = [] for item in basis: g1 = 1 g2 = 1 vec = item[:dim] for i inrange(len(vec)): if vec[i] >= 0: g1 *= pow(enc[i], vec[i]) else: g2 *= pow(enc[i], -vec[i]) p.append(g1-g2)
p = list(factor(reduce(GCD, p)))[-1][0] q = (p-1)//2 A = matrix(Zmod(q), dim, m_l) for i inrange(dim): line = bin(message[i])[2:].rjust(m_l, '0') for j inrange(len(line)): ifint(line[j]): A[i, j] = -1 enc[i] = enc[i]*inverse_mod(pow(0x10001, 2 ^ (m_l-1-j), p), p) % p else: A[i, j] = 1
m = ''
for _ in tqdm(range(m_l)): v = vector(Zmod(q), [0]*_+[1]+[0]*(m_l-1-_)) u = A.solve_left(v) sign = 1 for i inrange(len(u)): if u[i] >= 0: sign = sign*pow(enc[i], int(u[i]), p) % p else: sign = sign*inverse_mod(pow(enc[i], -int(u[i]), p), p) % p if sign != 1: m += '1' else: m += '0'