Exemplo n.º 1
0
def pollard(N,factors): # completely factors N using Pollard Rho, given a list
    
    rem = N
    while True:
        if is_probable_prime(rem):
            factors.append(rem)
            break

        f = brent(rem)
        while f == rem:#ensures pollard rho returns a smaller factor
            f = brent(rem)
            
        if f and f < rem: #found a factor
            if is_probable_prime(f): #ensure f is prime
                #print("Pollard rho (Brent): Prime factor found: %s" % f)
                factors.append(f)
                rem = rem//f #other factor
            else: #factor is composite
                #print("Pollard rho (Brent): Non-prime factor found: %s" % f)
                rem_f = factor(f,factors) #recursive part
                rem = (rem//f) * rem_f #combines the two remainders
                factors.remove(rem_f)#removes tricky duplicate that got appended in 1st if stmt
        else: #no more factors found, rem is prime
            #print("No (more) small factors found.")
            break
                 
    return rem
def semi(x):  # generate a random semiprime

    n = random.randint(1, x)
    k = 0
    p = 1
    while k < 2:
        if is_probable_prime(n):
            p *= n
            k += 1
        n = random.randint(1, x)
    print('size {}'.format(len(str(p))))
    return p
Exemplo n.º 3
0
def QS(n, B, I):
    #single polynomial version of quadratic sieve, given smoothness bound B and sieve interval I

    global N
    global root
    global T  #tolerance factor
    N, root, K, T = n, int(sqrt(n)), 0, 1

    if is_probable_prime(N):
        return "prime"

    if isinstance(sqrt(N), int):
        return isqrt(N)

    #print(root)
    print("Attempting to factor {}...".format(N))
    #F,I = size_bound(N)

    print("Generating {}-smooth factor base...".format(B))
    factor_base = find_base(N, B)  #generates a B-smooth factor base
    #print(factor_base)

    global F
    F = len(factor_base)

    print("Looking for {} {}-smooth relations...".format(F + T, B))
    smooth_nums, xlist, indices = find_smooth(factor_base, N, I)
    #finds B-smooth relations, using sieving and Tonelli-Shanks

    print("Found {} B-smooth numbers.".format(len(smooth_nums)))

    print(smooth_nums)

    if len(smooth_nums) < len(factor_base):
        return (
            "Not enough smooth numbers. Increase the sieve interval or size of the factor base."
        )

    print("Building exponent matrix...")
    is_square, t_matrix = build_matrix(smooth_nums, factor_base)
    #builds exponent matrix mod 2 from relations

    if is_square == True:
        x = smooth_nums.index(t_matrix)
        factor = gcd(xlist[x] + sqrt(t_matrix), N)
        print("Found a square!")
        return factor, N / factor

    print("Performing Gaussian Elimination...")
    sol_rows, marks, M = gauss_elim(
        t_matrix)  #solves the matrix for the null space, finds perfect square
    solution_vec = solve_row(sol_rows, M, marks, 0)
    '''vec = [0]*len(smooth_nums) # prints solution vector
    for i in solution_vec:
        vec[i] = 1
    print("Solution vector found: " + str(vec))'''

    print("Solving congruence of squares...")
    #print(solution_vec)
    factor = solve(solution_vec, smooth_nums, xlist,
                   N)  #solves the congruence of squares to obtain factors

    for K in range(1, len(sol_rows)):
        if (factor == 1 or factor == N):
            print("Didn't work. Trying different solution vector...")
            solution_vec = solve_row(sol_rows, M, marks, K)
            factor = solve(solution_vec, smooth_nums, xlist, N)
        else:
            print("Found factors!")
            return factor, int(N / factor)

    return ("Didn't find any nontrivial factors!")
Exemplo n.º 4
0
def GenPrime(n):
    p = random.getrandbits(n)
    while not is_probable_prime(p):
        p = random.getrandbits(n)
    return p
def QS(N, b=None, I=None):
    '''Single polynomial version of quadratic sieve, smoothness bound b and sieve interval I.
    Estimation is provided if unknown. Matrix becomes slow around B = 50000'''

    assert not is_probable_prime(N), "prime"

    for power in range(2, int(log2(N))):  # test for prime powers
        r = int(1000 * pow(N, 1 / power)) // 1000
        if pow(r, power) == N:
            print('found root')
            return r

    print("Data Collection Phase...")
    # set row_tol for extra solutions, bit_tol for sieve fudge factor
    root, row_tol, bit_tol = int(sqrt(N)), 0, 20
    global B
    B = b

    if not B:  # automatic parameter estimation
        B = size_bound(N)
        I = B
        print('Estimated B =', B, 'I =', I, '\n')
    elif not I:
        I = B

    factor_base = find_base(N, B)
    F = len(factor_base)
    print(F, 'factors in factor base')

    print("\nSearching for {}+{} B-smooth relations...".format(F, row_tol))
    print('Sieving for candidates...')
    smooth_nums, x_list, factors = find_smooth(N, factor_base, I, root,
                                               row_tol, bit_tol)

    if len(smooth_nums) < F:
        return ("Error: not enough smooth numbers")

    print("\nFound {} relations.".format(len(smooth_nums)))

    if len(smooth_nums) - 100 > F:  #reduce for smaller matrix
        print('trimming smooth relations...')
        del smooth_nums[F + row_tol:]
        del x_list[F + row_tol:]
        del factors[F + row_tol:]
        print(len(smooth_nums))
    '''for i in range(len(x_list)):
        print(x_list[i], smooth_nums[i], factors[i])'''

    print("\nMatrix Phase. Building exponent matrix...")
    is_square, t_matrix = build_matrix(factor_base, smooth_nums, factors)

    if is_square:
        print("Found a square!")
        x = smooth_nums.index(t_matrix)
        factor = (gcd(x_list[x] + isqrt(t_matrix), N))
        return factor, N / factor

    print("\nPerforming Gaussian Elimination...")
    sol_rows, marks, M = gauss_elim(t_matrix)

    print('Finding linear dependencies...')
    solution_vec = solve_row(sol_rows, M, marks, 0)
    factor_base.remove(-1)

    print("Solving congruence of squares...")
    factor = solve(solution_vec, smooth_nums, factors, x_list, N, factor_base)

    for K in range(1, len(sol_rows)):
        if (factor == 1 or factor == N):
            print("Trivial. Trying again...")
            solution_vec = solve_row(sol_rows, M, marks, K)
            factor = solve(solution_vec, smooth_nums, factors, x_list, N,
                           factor_base)
        else:
            print("Success!")
            return factor, N // factor

    return 'Fail. Increase B, I or T.'