Esempio n. 1
0
 def attack(self, publickey, cipher=[], progress=True):
     """Run tests against mersenne composites"""
     with timeout(self.timeout):
         try:
             p = q = None
             for i in tqdm(range(2, ilog2(publickey.n)),
                           disable=(not progress)):
                 i2 = 2**i
                 mersenne = [i2 - 1, i2 + 1]
                 g0, g1 = gcd(mersenne[0],
                              publickey.n), gcd(mersenne[1], publickey.n)
                 if 1 < g0 < publickey.n:
                     p = publickey.n // g0
                     q = g0
                     break
                 if 1 < g1 < publickey.n:
                     p = publickey.n // g1
                     q = g1
                     break
             if p is not None and q is not None:
                 priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                       int(publickey.n))
                 return (priv_key, None)
             return (None, None)
         except TimeoutError:
             return (None, None)
Esempio n. 2
0
def brent(N):
    """ Pollard rho with brent optimizations taken from: https://gist.github.com/ssanin82/18582bf4a1849dfb8afd"""
    if N & 1 == 0:
        return 2
    g = N
    while g == N:
        y, c, m = randint(1, N - 1), randint(1, N - 1), randint(1, N - 1)
        g, r, q = 1, 1, 1
        while g == 1:
            x = y
            i = 0
            while i <= r:
                y = (powmod(y, 2, N) + c) % N
                i += 1
            k = 0
            while k < r and g == 1:
                ys = y
                i = 0
                while i <= min(m, r - k):
                    y = (powmod(y, 2, N) + c) % N
                    q = q * (abs(x - y)) % N
                    i += 1
                g, k = gcd(q, N), k + m
                if N > g > 1:
                    return g
            r <<= 1
        if g == N:
            while True:
                ys = (powmod(ys, 2, N) + c) % N
                g = gcd(abs(x - ys), N)
                if N > g > 1:
                    return g
Esempio n. 3
0
 def attack(self, publickey, cipher=[], progress=True):
     """Run tests against primorial +-1 composites"""
     with timeout(self.timeout):
         try:
             limit = 10000
             prime = 1
             primorial = 1
             p = q = None
             for x in tqdm(range(0, limit), disable=(not progress)):
                 prime = next_prime(prime)
                 primorial *= prime
                 primorial_p1 = [primorial - 1, primorial + 1]
                 g0, g1 = gcd(primorial_p1[0],
                              publickey.n), gcd(primorial_p1[1],
                                                publickey.n)
                 if 1 < g0 < publickey.n:
                     p = publickey.n // g0
                     q = g0
                     break
                 if 1 < g1 < publickey.n:
                     p = publickey.n // g1
                     q = g1
                     break
             if p is not None and q is not None:
                 priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                       int(publickey.n))
                 return (priv_key, None)
             return (None, None)
         except TimeoutError:
             return (None, None)
Esempio n. 4
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
Esempio n. 5
0
    def common_modulus_attack(self, c1, c2, k1, k2):
        if k1.n != k2.n:
            return None

        if gcd(k1.e, k2.e) != 1:
            return None

        deciphered_message = common_modulus(k1.e, k2.e, k1.n, c1, c2)
        return long_to_bytes(deciphered_message)
Esempio n. 6
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
Esempio n. 7
0
    def comfact(self, cipher, publickey):
        for c in cipher:
            commonfactor = gcd(publickey.n, s2n(c))

            if commonfactor > 1:
                publickey.q = commonfactor
                publickey.p = publickey.n // publickey.q
                priv_key = PrivateKey(
                    int(publickey.p),
                    int(publickey.q),
                    int(publickey.e),
                    int(publickey.n),
                )
                return (priv_key, None)
        return (None, None)
Esempio n. 8
0
 def pollard_rho(self, n, seed=2, p=2, c=1):
     if n & 1 == 0:
         return 2
     if n % 3 == 0:
         return 3
     if n % 5 == 0:
         return 5
     if is_prime(n):
         return n
     f = lambda x: x**p + c
     x, y = seed, seed
     while True:
         x = f(x) % n
         y = f(f(y)) % n
         d = gcd((x - y), n)
         if d > 1:
             return d
Esempio n. 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
Esempio n. 10
0
 def attack(self, publickey, cipher=[], progress=True):
     """Run tests against fermat composites"""
     with timeout(self.timeout):
         try:
             limit = 10000
             p = q = None
             for x in tqdm(range(1, limit), disable=(not progress)):
                 f = gcd(fib(x), publickey.n)
                 if 1 < f < publickey.n:
                     p = publickey.n // f
                     q = f
                     break
             if p is not None and q is not None:
                 priv_key = PrivateKey(int(p), int(q), int(publickey.e),
                                       int(publickey.n))
                 return (priv_key, None)
             return (None, None)
         except TimeoutError:
             return (None, None)
Esempio n. 11
0
 def attack(self, publickey, cipher=[], progress=True):
     """System primes in crypto constants"""
     with timeout(self.timeout):
         try:
             primes = load_system_consts()
             for prp in tqdm(primes, disable=(not progress)):
                 g = gcd(publickey.n, prp)
                 if publickey.n > g > 1:
                     publickey.q = g
                     publickey.p = publickey.n // publickey.q
                     priv_key = PrivateKey(
                         int(publickey.p),
                         int(publickey.q),
                         int(publickey.e),
                         int(publickey.n),
                     )
                     return (priv_key, None)
         except TimeoutError:
             return (None, None)
     return (None, None)
Esempio n. 12
0
    def attack(self, publickeys, cipher=[]):
        """Common factor attack"""
        if not isinstance(publickeys, list):
            return (None, None)

        with timeout(self.timeout):
            try:
                pubs = [pub.n for pub in publickeys]
                # Try to find the gcd between each pair of moduli and resolve the private keys if gcd > 1
                priv_keys = []
                M = ProductTree(pubs)
                for i in range(0, len(pubs) - 1):
                    pub = pubs[i]
                    x = publickeys[i]
                    R = M // pub
                    g = gcd(pub, R)
                    if pub > g > 1:
                        try:
                            p = g
                            q = pub // g
                            x.p = p
                            x.q = q
                            # update each attackobj with a private_key
                            priv_key_1 = PrivateKey(
                                int(x.p), int(x.q), int(x.e), int(x.n)
                            )
                            priv_keys.append(priv_key_1)

                            self.logger.info(
                                "[*] Found common factor in modulus for " + x.filename
                            )
                        except ValueError:
                            continue
            except TimeoutError:
                return (None, None)

        priv_keys = list(set(priv_keys))
        if len(priv_keys) == 0:
            priv_keys = None

        return (priv_keys, None)
Esempio n. 13
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