예제 #1
0
def rsa_recovery(dp, dq, ciphertext, keysize=1024, start=3):
    '''
    This extensive process loops through all unknown e, typically between 3..65537
    and given the dP and dQ will search for primes p and q, then attempt to
    decrypt the ciphertext that is known to have been encrypted with them.
    '''
    # init counters
    r, p, q, d, count, count2, count3 = (0L, 0L, 0L, 0L, 0, 0, 0) 
    # start generalised loop for an unknown e
    for j in range(start, 65538, 2):
        dp1 = long(gmpy2.mul(dp, j) - 1)
        for k in range(3, j):
            d = long(k)
            a, r = gmpy2.t_divmod(dp1, d)
            assert(dp1 == (k * a) + r)
            if r == 0:
                count += 1
                p = long(a + 1)
                if gmpy2.is_odd(p) and gmpy2.is_strong_prp(p, 10):
                    count2 += 1
                    dq1 = long(gmpy2.mul(dq, j) - 1)
                    for l in range(3, j):
                        d = long(l)
                        a, r = gmpy2.t_divmod(dq1, d)
                        assert(dq1 == (l * a) + r)
                        if r == 0:
                            q = long(a + 1)
                            if gmpy2.is_odd(q) and gmpy2.is_strong_prp(q, 10):
                                count3 += 1
                                # just some basic progress on the console
                                if count3 % 10 == 0:
                                    sys.stdout.write('.')
                                    sys.stdout.flush()
                                # only attempt the decrypt if p,q are expected bitlength
                                if p.bit_length() + q.bit_length() == keysize:
                                    try:
                                        result = rsa_decrypt(p, q, ciphertext, j)
                                        if len(result) == 0 or result == "None":
                                            # indicates a failed decryption attempt
                                            sys.stdout.write('x')
                                        else:
                                            # SUCCESS! This is your decrypted message, sir...
                                            print "\n:: DECRYPTED::\n message = %s" % result
                                        # show all the p, q candidates just in case
                                        print "\np = %X\nq = %X\n" % (p, q)
                                    except Exception as e:
                                        print "ERROR: ", e # if cipher text length wrong, change decryption padding etc.
                                        pass # do nothing
    # finish with a counter summary
    print "count: %d  count2: %d  count3: %d\n\n" % (count, count2, count3)
    def initialize(self, num, den, Precision):
        num = mpz(num)
        den = mpz(den)
        self.precision = Precision
        quotient = gmpy2.f_div(num, den)
        if gmpy2.is_odd(quotient):
            self.decimal = 1
        else:
            self.decimal = 0
        remainder = gmpy2.fmod(num, den)

        self.value = []
        remainder *= 2
        i = 0
        while i < self.precision:
            if remainder < den:
                remainder *= 2
                self.value.append(False)
            elif remainder > den:
                self.value.append(True)
                remainder -= den
                remainder *= 2
            elif remainder == den:
                self.value.append(True)
                remainder -= den
            elif remainder == 0:
                self.value.append(False)
            i += 1
예제 #3
0
def train_rsa_reduction(n, e, d) :
    """You are given an RSA secret key.
        Find p and q and convert them to bytes
        
        code from : https://gist.github.com/ddddavidee/b34c2b67757a54ce75cb
    """
    k = d * e - 1
    if gmpy2.is_odd(k) :
        raise ValueError('Prime factors p and q not found')
    else:
        t = 0
        r = k
        while(not gmpy2.is_odd(r)):
            r = int(r // 2)
            t += 1
        for i in range(1, 101):
            rs = gmpy2.random_state(hash(gmpy2.random_state()))
            g = int(gmpy2.mpz_random(rs, n)) # random g in [0, n-1]
            y = pow(g, r, n)
            if y == 1 or y == n - 1:
                continue
            else:
                for j in range(1, t): # j \in [1, t-1]
                    x = pow(y, 2, n)
                    if x == 1:
                        p, q = outputPrimes(y - 1, n)
                        return (base64.b16decode(hex(p)[2:], casefold=True), 
                                base64.b16decode(hex(q)[2:], casefold=True))
                    elif x == n - 1:
                        continue
                    y = x
                    x = pow(y, 2, n)
                    if  x == 1:
                        p, q = outputPrimes(y - 1, n)
                        return (base64.b16decode(hex(p)[2:], casefold=True), 
                                base64.b16decode(hex(q)[2:], casefold=True))
예제 #4
0
def get_prime(dimension : int):
    dim = dimension
    start_prime = 1351
    repit_flag = True
    p = mpz(start_prime)
    while p.num_digits() <= dim:
        if repit_flag:
            repit_flag = False
            # Используется теорема Диемитко https://studfile.net/preview/6268704/page:28/
            # Она позволяет строить большие числа на основе существуюших меньших простых чисел
            # n=qR+1, где q – простое число, R – четное, R<4(q+1).
            # Высчитаем число N
            N = f_div(mpz(10 ** (dim - 1)), mpz(start_prime)) + f_div(mpz(10 ** (dim - 1) * mpfr(random())),mpz(start_prime))
            # Если оно нечетное, то добавляем 1
            N = N + 1 if is_odd(N) else N
            U = 0
            # получаем число и проверяем его на условие теоремы
        p = (N + U) * start_prime + 1
        # если условия выполнены, то ищем новое простое число для расчета
        if pow(2, p - 1, p) == 1 and pow(2, N + U, p) != 1:
            return int(p)
        else:
            U += 2
예제 #5
0
U = 0

# пока число имеет порядок меньше задаваемого
while p.num_digits() <= dim:
    if repit_flag:
        repit_flag = False
        # Используется теорема Диемитко https://studfile.net/preview/6268704/page:28/
        # Она позволяет строить большие числа на основе существуюших меньших простых чисел
        # n=qR+1, где q – простое число, R – четное, R<4(q+1).
        # Высчитаем число N
        print(1)
        N = f_div(mpz(10**(dim - 1)), mpz(current_prime)) + f_div(
            mpz(10**(dim - 1) * mpfr(random())), mpz(current_prime))
        print(2)
        # Если оно нечетное, то добавляем 1
        N = N + 1 if is_odd(N) else N
        U = 0
        # получаем число и проверяем его на условие теоремы
    p = (N + U) * current_prime + 1
    print(p)
    # если условия выполнены, то ищем новое простое число для расчета
    if pow(2, p - 1, p) == 1 and pow(2, N + U, p) != 1:
        print(p)
        repit_flag = True
        break
    else:
        U += 2

print()
print("Общее время:" + str(time() - start_time))
summ = 0