# calculate the secret g_br = (inverse(pow(g, A, p), p) * c11) % p tmp = pow(c12 * inverse(pow(c2, B, p), p), inverse(1-B, q), p) m = tmp * inverse(pow(h, A * inverse(1-B, q), p), p)
c = n = m % p e = 0x1296 primes = [232087313537, 104280142799213, 28079229001363, 653551912583, 42044128297, 802576647765917] index = [5, 6, 14, 15, 6, 7]
# check the primes base = 1 for i in range(len(primes)): base = base * (primes[i]**index[i]) print(base == n)
phi = [] for i in range(len(primes)): phi.append(primes[i] ** (index[i]-1) * (primes[i]-1))
low_e = [] for i in phi: low_e.append(int(gcd(i, e)))
low_n = [] for i in range(len(primes)): low_n.append(primes[i] ** index[i])
low_c = [] for i in range(len(primes)): low_c.append(pow(c, inverse(e//low_e[i], phi[i]), low_n[i]))
for i in range(len(low_n)): print('\n%d primes'%(i+1)) print('n = ' + str(low_n[i])) print('root = ' + str(low_e[i])) print('c = ' + str(low_c[i]))
# check for i in range(len(candidate)): assert pow(candidate[i], e, low_n[i]) == c % low_n[i]
# find all roots roots = [] for i in range(len(candidate)): roots.append(all_roots_mod(low_n[i], candidate[i], low_e[i], phi[i]))
# check again for i in range(len(candidate)): for j in roots[i]: assert pow(j, e, low_n[i]) == c % low_n[i]
# solve for i_1 in range(6): for i_2 in range(6): if i_1 == i_2: continue for i in roots[i_1]: for j in roots[i_2]: possible = long_to_bytes(GCRT([low_n[i_1], low_n[i_2]], [i, j])[0]) if all_ascii(possible): print(possible) sys.exit()
AL = A.LLL() C = Matrix(ZZ, AL[0]) B = A.solve_left(C)[0]
phi_base = floor(e2 * (B[1] // B[0])) for j in range(-1, 2): phi = phi_base + j for e in E: d = int(Zmod(phi)(65537).inverse_of_unit()) m = int(Zmod(N)(c)**d) if m.bit_length() < 1024: print(m.to_bytes(64, byteorder='big')) sys.exit(1)
from Crypto.PublicKey import ElGamal from Crypto.Util.number import bytes_to_long import os from random import SystemRandom from Crypto_tools import *
p = g = y = pubkey = ElGamal.construct((p, g, y)) base = jacobi(y, p) for i in tqdm(range(2**10)): rnd = SystemRandom() msg1 = bytes_to_long(b"Head" + os.urandom(124)) msg2 = bytes_to_long(b"Tail" + os.urandom(124))
count = 0 whileTrue: coin = rnd.randrange(2) gift = pubkey._encrypt([msg1, msg2][coin], rnd.randrange(1, p - 1)) check_1 = jacobi(gift[0], p) check_2 = jacobi(gift[1], p) ans = 0 if check_1 == 1: if check_2 == 1: ans = 0 else: ans = 1 elif check_1 == -1and base == -1: if check_2 == 1: ans = 1 else: ans = 0 if ans == coin: count += 1 if count == 50: print('try %d times' % i) print('flag{LordRiot\'s test flag}') exit() else: break
limit = 1 for i in range(256): limit *= len(possible[i]) cnt += 1 print(cnt, limit.bit_length())
if limit < 50000: print("Trying all possibilities") for b in product(*possible): m = bytes_to_long(bytes(b[::-1])) % n if pow(m, e, n) == init_x0 - init_x1: main_connection.sendline(str(msg0)) main_connection.sendline(str((init_enc1 - m) % n)) print('Got') print(main_connection.recvline()) main_connection.interactive() print("Failed") attack_connection.close() main_connection.close() exit()