Esempio n. 1
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]
Esempio n. 2
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. 3
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. 4
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. 5
0
def privatekey_check(N, p, q, d, e):
    ret = False
    txt = ""

    nlen = getpubkeysz(N)
    if is_prime(p) == False:
        ret = True
        txt += "p IS NOT PROBABLE PRIME\n"
    if is_prime(q) == False:
        txt = "q IS NOT PROBABLE PRIME\n"
    if gcd(p, e) > 1:
        ret = True
        txt = "p and e ARE NOT RELATIVELY PRIME\n"
    if gcd(q, e) > 1:
        ret = True
        txt += "q and e ARE NOT RELATIVELY PRIME\n"
    if p * q != N:
        ret = True
        txt += "n IS NOT p * q\n"
    if not (abs(p - q) > (2**((nlen >> 1) - 100))):
        ret = True
        txt += "|p - q| IS NOT > 2^(nlen/2 - 100)\n"
    if not (p > 2**((nlen >> 1) - 1)):
        ret = True
        txt += "p IS NOT > 2^(nlen/2 - 1)\n"
    if not (q > 2**((nlen >> 1) - 1)):
        ret = True
        txt += "q IS NOT > 2^(nlen/2 - 1)\n"
    if not (d > 2**(nlen >> 1)):
        ret = True
        txt += "d IS NOT > 2^(nlen/2)\n"
    if not (d < lcm(p - 1, q - 1)):
        ret = True
        txt += "d IS NOT < lcm(p-1,q-1)\n"
    unc = (gcd(e - 1, p - 1) + 1) * (gcd(e - 1, q - 1) + 1)
    if unc > 9:
        ret = True
        txt += "The number of unconcealed messages is %d > min\n" % unc
    try:
        inv = invert(e, lcm(p - 1, q - 1))
    except:
        inv = None
        ret = True
        txt += "e IS NOT INVERTIBLE mod lcm(p-1,q-1)\n"
    if d != inv:
        ret = True
        txt += "d IS NOT e^(-1) mod lcm(p-1,q-1)"
    return (ret, txt)
Esempio n. 6
0
def attack(attack_rsa_obj, publickeys, cipher=[]):
    """ Common factor attack
    """
    if not isinstance(publickeys, list):
        return (None, None)

    # Try to find the gcd between each pair of moduli and resolve the private keys if gcd > 1
    priv_keys = []
    for x, y in itertools.combinations(publickeys, r=2):
        if x.n != y.n:
            g = gcd(x.n, y.n)
            if g != 1:
                logger.info("[*] Found common factor in modulus for " +
                            x.filename + " and " + y.filename)

                # update each attackobj with a private_key
                x.p = g
                x.q = x.n // g
                y.p = g
                y.q = y.n // g
                priv_key_1 = PrivateKey(int(x.p), int(x.q), int(x.e), int(x.n))
                priv_key_2 = PrivateKey(int(y.p), int(y.q), int(y.e), int(y.n))
                priv_keys.append(priv_key_1)
                priv_keys.append(priv_key_2)

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

    return (priv_keys, None)
Esempio n. 7
0
def attack(attack_rsa_obj, publickeys, cipher=[]):
    """ Common factor attack
    """
    if not isinstance(publickeys, list):
        return (None, None)

    # Try to find the gcd between each pair of moduli and resolve the private keys if gcd > 1
    priv_keys = []
    tmp = 1
    for x in publickeys:
        tmp *= x.n
    for x in publickeys:
        g = gcd(x.n, tmp)
        if 1 < g < x.n:
            logger.info("[*] Found common factor in modulus for " + x.filename)

            # update each attackobj with a private_key
            x.p = g
            x.q = x.n // g
            priv_key = PrivateKey(int(x.p), int(x.q), int(x.e), int(x.n))
            priv_keys.append(priv_key)

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

    return (priv_keys, None)
Esempio n. 8
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. 9
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)
Esempio n. 10
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. 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
Esempio n. 12
0
def comfact(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)
Esempio n. 13
0
def attack(attack_rsa_obj, publickey, cipher=[]):
    """Try an attack where the public key has a common factor with the ciphertext - sourcekris
    """
    if cipher:
        commonfactor = gcd(publickey.n, s2n(cipher))

        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. 14
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. 15
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. 16
0
 def pollard_rho(self, n, seed=2, p=2, mode=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
     if mode == 1:
         f = lambda x: x**p + 1
     else:
         f = lambda x: x**p - 1
     x, y, d = seed, seed, 1
     while d == 1:
         x = f(x) % n
         y = f(f(y)) % n
         d = gcd((x - y) % n, n)
     return None if d == n else d
Esempio n. 17
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. 18
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. 19
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
Esempio n. 20
0
def primefac(
    n,
    trial_limit=1000,
    rho_rounds=42000,
    verbose=False,
    methods=(
        _primefac.pollardRho_brent,
        _primefac.pollard_pm1,
        _primefac.williams_pp1,
        _primefac.ecm,
        _primefac.mpqs,
        _primefac.fermat,
        _primefac.factordb,
    ),
    timeout=60,
):
    """Primefac implementation
    """
    from _primefac import isprime, isqrt, primegen
    from six.moves import xrange, reduce
    from random import randrange
    import six

    timeout = timeout - 1
    if n < 2:
        return
    if isprime(n):
        yield n
        return

    factors, nroot = [], isqrt(n)
    # Note that we remove factors of 2 whether the user wants to or not.
    for p in primegen():
        if n % p == 0:
            while n % p == 0:
                yield p
                n //= p
            nroot = isqrt(n)
            if isprime(n):
                yield n
                return
        if p > nroot:
            if n != 1:
                yield n
            return
        if p >= trial_limit:
            break
    if isprime(n):
        yield n
        return

    if rho_rounds == "inf":
        factors = [n]
        while len(factors) != 0:
            n = min(factors)
            factors.remove(n)
            f = _primefac.pollardRho_brent(n)
            if isprime(f):
                yield f
            else:
                factors.append(f)
            n //= f
            if isprime(n):
                yield n
            else:
                factors.append(n)
        return

    factors, difficult = [n], []
    while len(factors) != 0:
        rhocount = 0
        n = factors.pop()
        try:
            g = n
            while g == n:
                x, c, g = randrange(1, n), randrange(1, n), 1
                y = x
                while g == 1:
                    if rhocount >= rho_rounds:
                        raise Exception
                    rhocount += 1
                    x = (x**2 + c) % n
                    y = (y**2 + c) % n
                    y = (y**2 + c) % n
                    g = gcd(x - y, n)
            # We now have a nontrivial factor g of n.  If we took too long to get here, we're actually at the except statement.
            if isprime(g):
                yield g
            else:
                factors.append(g)
            n //= g
            if isprime(n):
                yield n
            else:
                factors.append(n)
        except Exception:
            difficult.append(
                n
            )  # Factoring n took too long.  We'll have multifactor chug on it.

    factors = difficult
    while len(factors) != 0:
        n = min(factors)
        factors.remove(n)
        f = multifactor(n, methods=methods, verbose=verbose, timeout=timeout)
        if isprime(f):
            yield f
        else:
            factors.append(f)
        n //= f
        if isprime(n):
            yield n
        else:
            factors.append(n)
Esempio n. 21
0
def neg_pow(a, b, n):
    assert b < 0
    assert gcd(a, n) == 1
    res = int(gmpy2.invert(a, n))
    res = pow(res, b * (-1), n)
    return res