Beispiel #1
0
    def close_factor(self, n, b, progress=True):
        # approximate phi
        phi_approx = n - 2 * isqrt(n) + 1

        # create a look-up table
        look_up = {}
        z = 1
        for i in tqdm(range(0, b + 1), disable=(not progress)):
            look_up[z] = i
            z = (z * 2) % n

        # check the table
        mu = invmod(powmod(2, phi_approx, n), n)
        fac = powmod(2, b, n)

        for i in tqdm(range(0, b + 1), disable=(not progress)):
            if mu in look_up:
                phi = phi_approx + (look_up[mu] - i * b)
                break
            mu = (mu * fac) % n
        else:
            return None

        m = n - phi + 1
        roots = ((m - isqrt(m**2 - 4 * n)) >> 1,
                 (m + isqrt(m**2 - 4 * n)) >> 1)

        if roots[0] * roots[1] == n:
            return roots
Beispiel #2
0
 def euler(self, n):
     if n & 1 == 0:
         return (n >> 1, 2) if n > 2 else (2, 1)
     end = isqrt(n)
     a = 0
     solutionsFound = []
     firstb = -1
     while a < end and len(solutionsFound) < 2:
         bsquare = n - a**2
         if bsquare > 0:
             b = isqrt(bsquare)
             if (b**2 == bsquare) and (a != firstb) and (b != firstb):
                 firstb = b
                 solutionsFound.append([int(b), a])
         a += 1
     if len(solutionsFound) < 2:
         return -1
     a = solutionsFound[0][0]
     b = solutionsFound[0][1]
     c = solutionsFound[1][0]
     d = solutionsFound[1][1]
     k = gcd(a - c, d - b)
     h = gcd(a + c, d + b)
     m = gcd(a + c, d - b)
     l = gcd(a - c, d + b)
     n = (k**2 + h**2) * (l**2 + m**2)
     return [int(k**2 + h**2) >> 1, int(l**2 + m**2) >> 1]
Beispiel #3
0
 def fermat(self, n):
     """Fermat attack"""
     a = b = isqrt(n)
     b2 = pow(a, 2) - n
     while pow(b, 2) != b2:
         a += 1
         b2 = pow(a, 2) - n
         b = isqrt(b2)
     p, q = (a + b), (a - b)
     assert n == p * q
     return p, q
Beispiel #4
0
 def pre_attack_check(self, publickeys):
     """Basic pre Attack checks implementation"""
     if not isinstance(publickeys, list):
         publickeys = [publickeys]
     tmp = []
     ok = True
     for publickey in publickeys:
         if publickey.n & 1 == 0:
             self.logger.error("[!] Public key: %s modulus should be odd." %
                               publickey.filename)
             ok = False
         if gcd(publickey.n, publickey.e) > 1:
             self.logger.error(
                 "[!] Public key: %s modulus is coprime with exponent." %
                 publickey.filename)
             ok = False
         if not (publickey.n > 3):
             self.logger.error("[!] Public key: %s modulus should be > 3." %
                               publickey.filename)
             ok = False
         if is_prime(publickey.n):
             self.logger.error(
                 "[!] Public key: %s modulus should not be prime." %
                 publickey.filename)
             ok = False
         i = isqrt(publickey.n)
         if publickey.n == (i**2):
             self.logger.error(
                 "[!] Public key: %s modulus should not be a perfect square."
                 % publickey.filename)
             publickey.p = i
             publickey.q = i
             tmp.append(publickey)
             ok = False
     return (tmp, ok)
Beispiel #5
0
    def __init__(self, n, e, progress=True):
        """Constructor"""
        self.d = None
        self.p = None
        self.q = None
        sys.setrecursionlimit(100000)
        frac = self.rational_to_contfrac(e, n)
        convergents = self.convergents_from_contfrac(frac, progress)

        for (k, d) in tqdm(convergents, disable=(not progress)):
            if k != 0:
                ed1 = e * d - 1
                phi = ed1 // k
                if ed1 - (k * phi) == 0:  # same as ed1 % k == 0
                    s = n - phi + 1
                    discr = pow(s, 2) - (n << 2)  # same as  s**2 - 4*n
                    if discr >= 0:
                        t = isqrt(discr)
                        if pow(t, 2) == discr:
                            if (s + t) & 1 == 0:
                                self.d = d
                                x = Symbol("x")
                                roots = solve(pow(x, 2) - s * x + n, x)
                                if len(roots) == 2:
                                    self.p = roots[0]
                                    self.q = roots[1]
                                break
Beispiel #6
0
    def pollard_P_1(self, n, progress=True):
        """Pollard P1 implementation"""
        z = []
        logn = math.log(int(isqrt(n)))
        prime = primes(997)

        for j in range(0, len(prime)):
            primej = prime[j]
            logp = math.log(primej)
            for i in range(1, int(logn / logp) + 1):
                z.append(primej)

        try:
            for pp in tqdm(prime, disable=(not progress)):
                i = 0
                x = pp
                while 1:
                    x = powmod(x, z[i], n)
                    i = i + 1
                    y = gcd(n, x - 1)
                    if y != 1:
                        p = y
                        q = n // y
                        return p, q
                    if i >= len(z):
                        return 0, None
        except TypeError:
            return 0, None
Beispiel #7
0
 def z3_solve(self, n, timeout_amount):
     """ Integer factorization using z3 theorem prover implementation:
     We can factor composite integers by SAT solving the model N=PQ directly using the clasuse (n==p*q),
     wich gives a lot of degree of freedom to z3, so we want to contraint the search space.
     Since every composite number n=pq, there always exists some p>sqrt(n) and q<sqrt(n).
     We can safely asume the divisor p is in the range n > p >= next_prime(sqrt(n)) 
     if this later clause doesn't hold and sqrt(p) is prime the number is a perfect square.
     We can also asume that p and q are alyaws odd otherwise our whole composite is even.
     Not all composite numbers generate a valid model that z3 can SAT.
     SAT solving is efficient with low bit count set in the factors, 
     the complexity of the algorithm grows exponential with every bit set.
     The problem of SAT solving integer factorization still is NP complete,
     making this just a showcase. Don't expect big gains.
     """
     s = Solver()
     s.set("timeout", timeout_amount * 1000)
     p = Int("p")
     q = Int("q")
     i = int(isqrt(n))
     np = int(next_prime(i))
     s.add(p * q == n, n > p, n > q, p >= np, q < i, q > 1, p > 1,
           q % 2 != 0, p % 2 != 0)
     try:
         s_check_output = s.check()
         if s_check_output == sat:
             res = s.model()
             P, Q = res[p].as_long(), res[q].as_long()
             assert P * Q == n
             return P, Q
         else:
             return None, None
     except:
         return None, None
Beispiel #8
0
    def __init__(self, n, e, progress=True):
        """Constructor"""
        self.d = None
        self.p = None
        self.q = None
        sys.setrecursionlimit(100000)
        frac = self.rational_to_contfrac(e, n)
        convergents = self.convergents_from_contfrac(frac, progress)

        for (k, d) in tqdm(convergents, disable=(not progress)):
            if k != 0 and (e * d - 1) % k == 0:
                phi = (e * d - 1) // k
                s = n - phi + 1
                discr = s * s - 4 * n
                if discr >= 0:
                    t = isqrt(discr)
                    if t**2 == discr:
                        if (s + t) & 1 == 0:
                            self.d = d
                            x = Symbol("x")
                            roots = solve(x**2 - s * x + n, x)
                            if len(roots) == 2:
                                self.p = roots[0]
                                self.q = roots[1]
                            break
Beispiel #9
0
def SQUFOF(N):
    s = int(isqrt(N) + 0.5)
    L = int(2 * isqrt(2 * s))
    
    if (s ** 2 == N):
        return s
    for k in range(0,len(multiplier)):
        D = multiplier[k] * N
        Po = Pprev = P = isqrt(D)
        Qprev = 1
        Q = D - pow(Po, 2)
        B = 3 * L
        c0 = True
        i = 2
        while c0:
            b = int((Po + P) // Q)
            P = b * Q - P
            q = Q
            Q = Qprev + b * (Pprev - P)
            r = int(isqrt(Q) + 0.5)
            if (not(i & 1) and (pow(r, 2) == Q)):
                break
            Qprev = q
            Pprev = P
            i += 1
            c0 = (i <= B)
        b = ((Po - P) // r)
        Pprev = P = b * r + P
        Qprev = r
        Q = (D - pow(Pprev, 2)) // Qprev
        i = 0
        c1 = True
        while(c1):
            b = int((Po + P) // Q)
            Pprev = P
            P = b * Q - P
            q = Q;
            Q = Qprev + b * (Pprev - P)
            Qprev = q
            i += 1
            c1 = (P != Pprev)
        r = gcd(N, Qprev)
        if (1 < r < N): 
            return r,N // r
    return -1
Beispiel #10
0
    def euler(self, n):
        if n & 1 == 0:
            return (n >> 1, 2) if n > 2 else (2, 1)
        end = isqrt(n)
        a = 0
        solutionsFound = []
        firstb = -1

        while a < end and len(solutionsFound) < 2:
            bsquare = n - pow(a, 2)
            if bsquare > 0:
                b = isqrt(bsquare)
                if (pow(b, 2) == bsquare) and (a != firstb) and (b != firstb):
                    firstb = b
                    solutionsFound.append([b, a])
            a += 1
        if len(solutionsFound) < 2:
            return None

        a = solutionsFound[0][0]
        b = solutionsFound[0][1]
        c = solutionsFound[1][0]
        d = solutionsFound[1][1]

        k = pow(gcd(a - c, d - b), 2)
        h = pow(gcd(a + c, d + b), 2)
        m = pow(gcd(a + c, d - b), 2)
        l = pow(gcd(a - c, d + b), 2)

        p, q = gcd(k + h, n), gcd(l + m, n)

        if n > p > 1:
            return p, n // p

        if n > q > 1:
            return q, n // q
Beispiel #11
0
def dixon_factor(N, B=7, explain=False):

    if is_prime(N):
        return N, 1

    start = isqrt(N)

    if (start ** 2) == N:
        return start, start

    base = primes(B)
    lqbf = pow(base[-1], 2) + 1
    QBF = bitarray.bitarray(lqbf)  # This is our quasi-bloom-filter

    basej2N = []
    for j in range(0, len(base)):
        p = powmod(base[j], 2, N)
        basej2N.append(p)
        QBF[p] = 1  # We populate our quasi-bloom-filter

    i = start
    while i < N:
        i2N = pow(i, 2, N)
        if i2N < lqbf and QBF[i2N] == 1:
            for k in range(0, len(base)):
                if QBF[basej2N[k]] == 1:
                    # if i2N == basej2N[k]: # this is replaced with a quasi-bloom-filter
                    f = gcd(i - base[k], N)
                    if explain:
                        print("N = %d" % N)
                        print("%d = isqrt(N)" % start)
                        print("%d = pow(%d,2,n)" % (i2N, i))
                        print("%d = pow(%d,2,n)" % (basej2N[k], base[k]))
                        print("%d - %d = %d" % (i, base[k], f))
                        print("%d = gcd(%d - % d, N)" % (f, i, base[k]))
                        print(
                            "%d = gcd(%d + % d, N)" % (gcd(i + base[k], N), i, base[k])
                        )
                    if 1 < f < N:
                        return f, N // f
        i += 1
    return None, None
Beispiel #12
0
    def close_factor(self, n, b, progress=True):
        # approximate phi
        phi_approx = n - 2 * isqrt(n) + 1

        # create a look-up table
        look_up = {}
        z = 1
        for i in tqdm(range(0, b + 1), disable=(not progress)):
            look_up[z] = i
            z = (z << 1) % n

        # check the table
        mu = invmod(powmod(2, phi_approx, n), n)
        fac = powmod(2, b, n)

        for i in tqdm(range(0, b + 1), disable=(not progress)):
            if mu in look_up:
                phi = phi_approx + (look_up[mu] - (i * b))
                r = trivial_factorization_with_n_phi(n, phi)
                if r != None:
                    return r
            mu = (mu * fac) % n
        else:
            return None