Esempio n. 1
0
    def attack(self, publickey, cipher=[], progress=True):
        """Same n huge e attack"""
        if not isinstance(publickey, list):
            return (None, None)

        with timeout(self.timeout):
            try:
                if len(set([_.n for _ in publickey])) == 1:
                    n = publickey[0].n

                    e_array = []
                    for k in publickey:
                        e_array.append(k.e)

                    if (cipher is None) or (len(cipher) < 2):
                        self.logger.info(
                            "[-] Lack of ciphertexts, skiping the same_n_huge_e test..."
                        )
                        return (None, None)

                    # e1*s1 + e2*s2 = 1
                    _, s1, s2 = gcdext(e_array[0], e_array[1])

                    # m ≡ c1^s1 * c2*s2 mod n
                    plain = (
                        powmod(int.from_bytes(cipher[0], "big"), s1, n) *
                        powmod(int.from_bytes(cipher[1], "big"), s2, n)) % n

                    return (None, number.long_to_bytes(plain))
            except TimeoutError:
                return (None, None)
        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 _fib_res(self, n, p):
     """ fibonacci sequence nth item modulo p """
     if n == 0:
         return (0, 1)
     a, b = self._fib_res(n >> 1, p)
     c = mod((mod(a, p) * mod(((b << 1) - a), p)), p)
     d = mod((powmod(a, 2, p) + powmod(b, 2, p)), p)
     if n & 1 == 0:
         return (c, d)
     return (d, mod((c + d), p))
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 solve(M, n, a, m, XX, invmod_Mn, F, x, beta):
    # I need to import it in the function otherwise multiprocessing doesn't find it in its context
    from sage_functions import coppersmith_howgrave_univariate

    base = int(65537)
    # the known part of p: 65537^a * M^-1 (mod N)
    known = int(powmod(base, a, M) * invmod_Mn)
    pol = x + known
    t = m + 1
    # Find a small root (x0 = k) using Coppersmith's algorithm
    roots = coppersmith_howgrave_univariate(pol, n, beta, m, t, XX)
    # There will be no roots for an incorrect guess of a.
    for k in roots:
        # reconstruct p from the recovered k
        p = int(k * M + powmod(base, a, M))
        if n % p == 0:
            return p, n // p
Esempio n. 6
0
 def get_n_mod_d(self, n, d, use="mersenne"):
     if n < 0:
         ValueError("Negative arguments not implemented")
     if use == "gmpy":
         return mod(fib(n), d)
     elif use == "mersenne":
         return powmod(2, n, d) - 1
     else:
         return self._fib_res(n, d)[0]
Esempio n. 7
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. 8
0
    def attack(self, publickey, cipher=[], progress=True):
        """use elliptic curve method
        only works if the sageworks() function returned True
        """

        try:
            sageresult = []
            try:
                sageresult = subprocess.check_output(
                    ["sage",
                     "%s/sage/ecm2.sage" % rootpath,
                     str(publickey.n)],
                    timeout=self.timeout,
                    stderr=subprocess.DEVNULL,
                )
                sageresult = sageresult[1:-2].split(b", ")
            except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
                return (None, None)

            if len(sageresult) > 0:
                plain = []
                sageresults = [int(_.decode("utf-8")) for _ in sageresult]
                phi = 1
                for fac in sageresults:
                    phi = phi * (int(fac) - 1)

                if cipher is not None and len(cipher) > 0:
                    for c in cipher:
                        try:
                            cipher_int = int.from_bytes(c, "big")
                            d = invert(publickey.e, phi)
                            m = hex(powmod(cipher_int, d, publickey.n))[2::]
                            plain.append(bytes.fromhex(m))
                        except:
                            continue

                return (None, plain)
            return (None, None)
        except KeyboardInterrupt:
            pass
        return (None, None)
Esempio n. 9
0
    def decrypt(self, cipher):
        """Uncipher data with private key
        :param cipher: input cipher
        :type cipher: string
        """
        if not isinstance(cipher, list):
            cipher = [cipher]

        plain = []
        for c in cipher:
            if self.n is not None and self.d is not None and self.key is None:
                try:
                    cipher_int = int.from_bytes(c, "big")
                    m_int = powmod(cipher_int, self.d, self.n)
                    m = binascii.unhexlify(hex(m_int)[2:]).decode()
                    plain.append(m)
                except:
                    pass

            try:
                rsakey = RSA.importKey(str(self))
                rsakey = PKCS1_OAEP.new(rsakey)
                plain.append(rsakey.decrypt(c))
            except:
                pass

            try:
                tmp_priv_key = tempfile.NamedTemporaryFile()
                with open(tmp_priv_key.name, "wb") as tmpfd:
                    tmpfd.write(str(self).encode("utf8"))
                tmp_priv_key_name = tmp_priv_key.name

                tmp_cipher = tempfile.NamedTemporaryFile()
                with open(tmp_cipher.name, "wb") as tmpfd:
                    tmpfd.write(c)
                tmp_cipher_name = tmp_cipher.name

                with open("/dev/null") as DN:
                    try:
                        openssl_result = subprocess.check_output(
                            [
                                "openssl",
                                "rsautl",
                                "-raw",
                                "-decrypt",
                                "-in",
                                "-oaep",
                                tmp_cipher_name,
                                "-inkey",
                                tmp_priv_key_name,
                            ],
                            stderr=DN,
                            timeout=30,
                        )
                        plain.append(openssl_result)
                    except:
                        pass

                    try:
                        openssl_result = subprocess.check_output(
                            [
                                "openssl",
                                "rsautl",
                                "-raw",
                                "-decrypt",
                                "-in",
                                tmp_cipher_name,
                                "-inkey",
                                tmp_priv_key_name,
                            ],
                            stderr=DN,
                            timeout=30,
                        )
                        plain.append(openssl_result)
                    except:
                        pass
            except:
                plain.append(cipher)
        return plain