defbsgs(g, y, p): res = [] m = int(ceil(sqrt(p - 1))) S = {pow(g, j, p):j for j in range(m)} gs = pow(g, p - 1 - m, p) for i in range(m): if y in S: res.append(i * m + S[y]) y = y * gs % p return res
c1_p = c1 % p c1_q = c1 % q e_1 = bsgs(2, c1_p, p) e_2 = bsgs(2, c1_q, q) phi = (p - 1) * (q - 1) e_n = [] # e % phi for e_p in e_1: for e_q in e_2: try: e_n.append(crt([e_p, e_q], [p - 1, q - 1])) # e % phi except: pass d_n = [inverse(e, phi) for e in e_n]
m_n = set() c = 169169912654178 for d in d_n: m_n.add(pow(c, d, n)) m_n = list(m_n)
for m in m_n: print(b'npuctf{' + long_to_bytes(m) + b'}')
# In[3]: XOR = lambda s1 ,s2 : bytes([x1 ^ x2 for x1 ,x2 in zip(s1 , s2)])
# In[4]: prefix_mt_output = [] prefix = b'npuctf{' j = 0 for i in prefix: tmp = md5(chr(i).encode()).digest() randnum = XOR(tmp, cipher[16 * j : 16 * (j + 1)]) for k in range(4): prefix_mt_output.append(bytes_to_long(randnum[4 * k : 4 * (k + 1)])) j += 1
# In[5]: suffix_mt_output = [] #output[100]~output[103] suffix = b'}' tmp = md5(suffix).digest() randnum = XOR(tmp, cipher[16 * 25 : 16 * 26]) for i in range(4): suffix_mt_output.append(bytes_to_long(randnum[4 * i : 4 * (i + 1)]))
# In[6]: defunBitshiftLeftXor(value, shift, mask): i = 0 res = 0 while i * shift < 32: partMask = (0xffffffff >> (32 - shift)) << (shift * i) part = value & partMask value ^= (part << shift) & mask res |= part i += 1 return res
defunBitshiftRightXor(value, shift, mask): i = 0 res = 0 while i * shift < 32: partMask = ((0xffffffff << (32 - shift)) & 0xffffffff) >> (shift * i) part = value & partMask value ^= (part >> shift) & mask res |= part i += 1 return res
defrecoverState(value): value = unBitshiftRightXor(value, 18, 0x34adf670) value = unBitshiftLeftXor(value, 15, 0xefc65400) value = unBitshiftLeftXor(value, 7, 0x9ddf4680) value = unBitshiftRightXor(value, 11, 0xffffffff) return value
# In[7]: prefix_state = [] for value in prefix_mt_output: prefix_state.append(recoverState(value)) suffix_state = [] #state[100]~state[103] for value in suffix_mt_output: suffix_state.append(recoverState(value))
# In[27]: coef = inverse(1812433253, 0x100000000) definv_srand(value, i): value &= 0xffffffff value += i value *= coef value = unBitshiftRightXor(value, 27, 0xffffffff) return value
# In[28]: if inv_srand(s104_1, 103) & 0x80000000 == cur & 0x80000000: if inv_srand(s104_2, 103) & 0x80000000 == cur & 0x80000000: print("two cases found") else: s104 = s104_1 else: s104 = s104_2
# In[29]: cur = s104 for i in range(103, -1, -1): cur = inv_srand(cur, i) seed = cur
# In[30]: classmt73991: def__init__(self , seed): self.state = [seed] + [0] * 232 self.flag = 0 self.srand() self.generate() defsrand(self): for i in range(232): self.state[i+1] = 1812433253 * (self.state[i] ^ (self.state[i] >> 27)) - i self.state[i+1] &= 0xffffffff
from Crypto.Util.number import * from gmpy2 import next_prime, gcd import sympy
lcm = e = assert(GCD(lcm, e) == 2) n = d = inverse(e // 2, lcm) m2 = pow(c, d, n) # m^2
defFactorize(n, e, d): g = 2 whileTrue: k = e * d - 1 whilenot k & 1: k //= 2 p = int(gcd(pow(g, k, n) - 1, n)) % n if p > 1: return (p, n // p) g = int(next_prime(g)) (p, q) = Factorize(n, e // 2, d)