def get_weak_wiener(bits): while True: p, q = generate_two_random_primes(bits) N = p * q etf = (p - 1) * (q - 1) d = abs(random.getrandbits(bits // 2)) e = ext_euc(d, etf)[1] if (ext_euc(d, etf)[0] == 1) and (9 * pow(d, 4) < N) and (e > 0): if wiener(e, N)[0]: break return e, N, d
def pollard_rho(h, g, p): T = {} T[0] = [h, 0, 1] h_i, deg_a, deg_h = h, 0, 1 h_i_, deg_a_, deg_h_ = h, 0, 1 for i in range(1, p): h_i, deg_a, deg_h = f(h, p, g, h_i, deg_a, deg_h) h_i_, deg_a_, deg_h_ = f(h, p, g, h_i_, deg_a_, deg_h_) h_i_, deg_a_, deg_h_ = f(h, p, g, h_i_, deg_a_, deg_h_) #print(h_i, deg_a, deg_h) #print(h_i_, deg_a_, deg_h_) #print(h_i, h_i_) if h_i == h_i_: dx = (deg_a - deg_a_) # dx = dx if dx >= 0 else dx + p dy = (deg_h_ - deg_h) # dy = dy if dy >= 0 else dy + p inv_dy = ext_euc(dy, (p-1)//2)[1] # inv_dy = inv_dy if inv_dy >= 0 else inv_dy + p # print(dx, inv_dy, dy, p, 'p') res = (dx * inv_dy) % ((p-1)//2) return res if res >= 0 else res #+ (p-1)//2 else: continue #print(h_i, deg_a, deg_h) for k in T.keys(): if T[k][0] == h_i: dx = (deg_a - T[k][1]) #dx = dx if dx >= 0 else dx + p dy = (T[k][2] - deg_h) #dy = dy if dy >= 0 else dy + p inv_dy = ext_euc(dy, (p-1)//2)[1] #inv_dy = inv_dy if inv_dy >= 0 else inv_dy + p #print(dx, inv_dy, dy, p, 'p') res = (dx * inv_dy) % ((p-1)//2) return res + ((p-1)//2)if res <= 0 else res T[v(i)] = [h_i, deg_a, deg_h] return None
def gen_keys(bits): p, q = generate_two_random_primes(bits) n = p * q etf_val = (p - 1) * (q - 1) e = 65537 d = ext_euc(e, etf_val)[1] % etf_val print('p and q', p, q) if (d * e) % etf_val != 1: raise Exception('Try again.') pub_k = (p * q, e) priv_k = (p * q, d) return pub_k, priv_k
def pohlig_hellman_attack(h, g, p): primes = get_factor_counts_dict(p - 1) crt_dict = dict() for prime, power in primes.items(): x_list = [] h_sub = h for j in range(1, power + 1): i = 0 q = (p - 1) // pow(prime, j) h_pow = pow(h_sub, q, p) g_pow = pow(g, (p - 1) // prime, p) while True: if pow(g_pow, i, p) == h_pow: x_list += [i] break i += 1 h_sub = (h_sub * pow(ext_euc(g, p)[1], i * pow(prime, j - 1))) % p res_mod_prime = 0 for j in range(power): res_mod_prime += pow(prime, j) * x_list[j] crt_dict[res_mod_prime % pow(prime, power)] = pow(prime, power) return crt(crt_dict)
else: filtered_attacks = {name :dict(zip(names, attacks))[name] for name in args.attacks.split(',')} if 'Wiener' in filtered_attacks.keys(): signal.signal(signal.SIGALRM, signal_handler) signal.alarm(60 * args.attack_time) try: e, N, d = get_weak_wiener(args.complexity) except: print('No key found. Time out.') sys.exit() else: bits = args.complexity p, q = generate_two_random_primes(bits) N = p * q etf = (p - 1) * (q - 1) e = abs(random.getrandbits(bits // 2)) d = ext_euc(e, etf)[1] while (ext_euc(e, etf) != 1) and ((e * d) % etf != 1): e = abs(random.getrandbits(bits // 2)) d = ext_euc(e, etf)[1] for k in [k for k in filtered_attacks.keys() if k != 'Wiener']: signal.signal(signal.SIGALRM, signal_handler) signal.alarm(60 * args.attack_time) res = None try: res, _ = filtered_attacks[k](e, N) except: print('No key found. Time out.') sys.exit() print('e={}. d={}, N={}'.format(e, d, N))