def prob_solution(a, x, b, y, c, z):
    
    num_pp = len(safe_primes)
        
    plus = True
    minus = True
    
    for i in range(num_ps_tests):
        #using safe primes ensures that the order of a and b modulo m is high, thus ensuring the probability of a^x+/-b^y=c^z is low, on the order of 1/m
        m = safe_primes[randrange(num_pp)]
        
        ax, by, cz = exp_bs(a, x, m), exp_bs(b, y, m), exp_bs(c, z, m)
        
        if plus and (ax + by) % m != cz:
            plus = False
            s = '-'
            
            if not minus:
                break
        
        if minus and (ax - by) % m != cz:
            minus = False
            s = '+'
            
            if not plus:
                break
    else:
        
        return [True, s]
    
    return [False, s]
def get_y(a, x, c, z, b, lrab, max_yc, b_gp):
    
    y_res_mod = []
    
    max_ya = x * lrab
    max_y = max(max_ya, max_yc)
    
    p = 1
    
    for pprime, pprime_sq, prime_sq_tot, prime_div in b_gp:
        #squared prime modulus ensures totient is divisible by prime
        ax, cz = exp_bs(a, x, pprime_sq), exp_bs(c, z, pprime_sq)
        
        d = (ax - cz) % pprime_sq
        
        if is_coprime(d, pprime_sq):                
            y_sp = dlog_mod(b, d, pprime_sq, prime_sq_tot, prime_div)
            y_res_mod.append([y_sp, pprime])
            
            p *= pprime
            
            if p > max_y:
                break
    else:
        print("Not enough primes to get y")
        #raise Error("Not enough primes to get y")
    
    return crt(y_res_mod)
def get_x(a, x, c, z, m, mf, t, lt):
    
    cz = exp_bs(c, z, m)
    
    f = exp_bs(a, t - x, m)
    g = exp_bs(a, lt, m)
    h = f * cz % m
    
    p = dlog(g, h, m, mf)
    
    x += p * lt
    
    return x
def beals_solver(b, y, c, z, max_a, max_x):
    """finds a and x s.t. a^x + b^y = c^z
    
    b, c mutually coprime"""
    
    crt_mod = 1
    rep_crt = []
    
    for pprime in prob_primes:       
        
        pp_sq = pprime**2
        t = pprime * (pprime - 1)
        
        by = exp_bs(b, y, pp_sq)
        cz = exp_bs(c, z, pp_sq)
        d = (cz - by) % pp_sq
   
        res_exp_pairs = []
        
        for a in range(pp_sq):            
            l = 0 if a == 0 else 1
            
            for x in range(t):
                if l == d:
                    re_pair = [a % pprime, x % pprime]
                    
                    if re_pair not in res_exp_pairs:                        
                        res_exp_pairs.append(re_pair)
                else:
                    l = l * a % pp_sq
        
        rep_crt.append([pprime, res_exp_pairs])    
    
        crt_mod *= pprime
        
        if crt_mod > max_a and crt_mod > max_x:
            break
    
    np = reduce(lambda a, b: a * len(b[1]), rep_crt, 1)
    #np = reduce(lambda a, b: a * b[0], rep_crt, 1)
    print("{!s} chinese remainder theorem permutations".format(np))
    
    ax_pairs = crt_permutation(rep_crt, b, y, c, z)
    
    for axp in ax_pairs:
        
        a, x = axp
        
        print("\t{!s}^{!s} + {!s}^{!s} = {!s}^{!s}".format(a, x, b, y, c, z))
Esempio n. 5
0
def prob_beals(min_xyz=3, min_abc=2):
    
    populate_pprimes_list()
    
    #minimum sum is x+y+z=3+3+3=9 and a+b+c=2+3+5=10
    s = 19
    
    while True:
        #print("Shell with sum {!s} completed!".format(s))
        
        for a in range(min_abc, s + 1):
            s_1 = s - a
            
            for b in range(min_abc, s_1 + 1):
                s_2 = s_1 - b
                
                if b > a and is_coprime(a, b):         
                    
                    for c in range(min_abc, s_2 + 1):
                        s_3 = s_2 - c
                        
                        if is_coprime(a, c) and is_coprime(b, c):               
                            
                            for x in range(min_xyz, s_3 + 1):
                                s_4 = s_3 - x
                                
                                for y in range(min_xyz, s_4 + 1):
                                    z = s_4 - y
                                    
                                    if z >= min_xyz:
                                    
                                        for p in prob_primes:
                                            
                                            p_tot = p - 1
                                            
                                            a_m, b_m, c_m = a % p, b % p, c % p
                                            x_m, y_m, z_m = x % p_tot, y % p_tot, z % p_tot
                                            
                                            a_x, b_y, c_z = exp_bs(a, x, p), exp_bs(b, y, p), exp_bs(c, z, p)
                                            
                                            if (a_x + b_y) % p != c_z:
                                                break
                                        else:
                                            print("{!s}^{!s} + {!s}^{!s} = {!s}^{!s}".format(a, x, b, y, c, z))
                                        
        s += 1
def miller_rabin_test(n, pci=prob_comp_ind):
    
    nm = n - 1
    d = nm
    s = 0
    
    #number of tests required to establish probable primeness    
    k = math.ceil(-math.log(pci, 4))
    
    while d % 2 == 0:
        s += 1
        d //= 2
        
    sm = s - 1
    
    for i in range(k):
        a = randrange(2, nm)
        
        x = exp_bs(a, d, n)
        
        if x == 1 or x == nm:
            continue
        else:
            for j in range(sm):
            
                x = x**2 % n
                
                #early stopping x=1 for all powers of s > j
                if x == 1:
                    return False
                
                #early stopping, the condition we're trying to prevent
                if x == nm:
                    break
            else:
                return False
    
    return True