def rsa_dec(self, cipher, pub_key={}, appr="brute"):
        n = pub_key["n"]
        e = pub_key["e"]

        if appr == "brute":
            p = q = 3
            while p < n:
                if n % p == 0:
                    q = n / p
                    phi = (p - 1) * (q - 1)
                    d = cutils.modinv(e, phi)
                    return self.dec.rsa(cipher, {'d': d, 'p': p, 'q': q})
                p += 2
            return ""
        elif appr == "p-1":
            b = 3
            B = 2
            while True:
                b = pow(b, B, n)
                p = fractions.gcd(b - 1, n)
                if p > 1 and p < n:
                    q = n / p
                    phi = (p - 1) * (q - 1)
                    d = cutils.modinv(e, phi)
                    return self.dec.rsa(cipher, {'d': d, 'p': p, 'q': q})

                if B > math.sqrt(n):
                    return ""
                    #raise Exception("P-1 attack error: bound = {} possible no solution exists for n = {}".format(B, n))

                B += 2

            return ""
        else:
            return None
    def verify(self, signedmsg, key, option='e'):
        ''' Options:
        e = el_gamal
        r = rsa
        d = dsa
        '''
        msg = signedmsg[0].encode('hex')
        msg = int(msg, 16)

        # el gamal:
        if option == 'e':
            r = int(signedmsg[1], 16)
            s = int(signedmsg[2], 16)

            p = key['p']
            alpha = key['alpha']
            beta = key['beta']

            betator = pow(beta, r, p)
            rtos = pow(r, s, p)

            v1 = (betator * rtos) % p
            v2 = pow(alpha, msg, p)
            return v1 == v2

        # rsa
        elif option == 'r':
            sig = int(signedmsg[1], 16)

            e = key['e']
            p = key['p']
            q = key['q']
            n = p * q

            test = pow(sig, e, n)
            return msg == test

        elif option == 'd':
            r = int(signedmsg[1], 16)
            s = int(signedmsg[2], 16)

            p = key['p']
            q = key['q']
            alpha = key['alpha']
            beta = key['beta']

            sinv = utils.modinv(s, q)

            # u1 = s^(-1)*m mod q
            u1 = pow(sinv * msg, 1, q)

            # u2 = s^(-1)*r mod q
            u2 = pow(sinv * r, 1, q)

            # v = (alpha^u1 * beta^u2 mod p)mod q
            v = pow(pow(alpha, u1, p) * pow(beta, u2, p), 1, p) % q
            return v == r
        else:
            raise Exception("Unkown verification option:", option,
                            "(e: El Gamal, r: RSA, d: DSA)")
    def dsa(self, message, key={}):
        p = key['p']
        q = key['q']
        a = key['a']
        alpha = key['alpha']

        msg = message.encode('hex')
        msg = int(msg, 16)

        if msg > q:
            raise Exception(
                "WeakKeyError: message is larger than prime (q) potential loss of data"
            )

        if pow(key['alpha'], (p - 1) / 2, p) != 1:
            raise Exception(
                "KeyError: private key is not configured correctly")

        # pick k from 1 to q-1
        k = random.randint(1, q - 1)
        # r = (a^k mod p) mod q
        r = pow(alpha, k, p) % q

        # s = k^(-1)(m + a*r) mod q
        kinv = utils.modinv(k, q)
        ar = pow(a * r, 1, q)
        s = pow(kinv * (msg + ar), 1, q)

        hex_r = hex(int(r))[2:]
        hex_s = hex(int(s))[2:]
        if hex_r[-1] == "L":
            hex_r = hex_r[:-1]
        if hex_s[-1] == "L":
            hex_s = hex_s[:-1]
        return (message, hex_r, hex_s)
    def el_gamal(self, message, key={}):
        p = key['p']
        alpha = key['alpha']
        a = key['a']
        msg = message.encode('hex')
        msg = int(msg, 16)
        if msg > p:
            raise Exception(
                "WeakKeyError: message is larger than prime (p) potential loss of data"
            )

        # choose k gcd(k,p-1)=1
        k = random.randint(3, p - 1)
        g, _, _ = utils.egcd(k, p - 1)
        while g != 1:
            k = random.randint(3, p - 1)
            g, _, _ = utils.egcd(k, p - 1)
        # r = alpha**k mod p
        r = pow(alpha, k, p)

        # s = k**-1 *(m-a*r) mod p-1
        k_inv = utils.modinv(k, p - 1)
        s = (k_inv * (msg - a * r)) % (p - 1)

        hex_r = hex(int(r))[2:]
        hex_s = hex(int(s))[2:]
        if hex_r[-1] == "L":
            hex_r = hex_r[:-1]
        if hex_s[-1] == "L":
            hex_s = hex_s[:-1]
        return (message, hex_r, hex_s)
    def el_gamal(self, cipher, key={}):
        p = key['p']
        a = key['a']
        r = int(cipher[0], 16)
        t = int(cipher[1], 16)

        r_pow = pow(r, a, p)
        r_inv = cutils.modinv(r_pow, p)
        m = pow(t*r_inv, 1, p)

        m = hex(int(m))[2:]

        return m.decode('hex')
def affine_dec(ctext_num, a, b, m):
    a_inv = modinv(a, m)
    ptext_num = [(a_inv * (num - b)) % m for num in ctext_num]
    return ptext_num
Exemple #7
0
# Resources: https://infoscience.epfl.ch/record/164524/files/nscan20.PDF

from math import gcd
from crypto_utils import modinv

x = 0xdeadc0de
y = 0x17d7f90a4597fb2bbbb41d1a70f505f0d8c5cb53faaafea259150eb6910fb08fbf1ba40e42de70c596fb0032d132c9c6ce46c650999ad5f14a990d205984260146e2949b819dc8732beceed452701d88b2c8723b410fce739009df89930424c566af5102403981c26c3e75d9c62065a347e815b26984dcd3b5f02fc8a8092051
n = 0x90def3c2c91ae9bf6089ec8857960d567fdbcd7c2c3ea713046977231e65f44e1b91550971d4e5d43b51675fae4ba640add3af02dad4bf68c3ddef3a98907e1e01156de7a4474d9fce2ba8c055f44673c703a72a111a06f8a7b2fe582463938d802e91630e1e1b5483b1774e608eb4368c6bbf4da375319d9a2799bf8a5ae453
e = 0x10001

if __name__ == '__main__':
    p = gcd(y**e - x, n)
    q = n // p
    tot = (p - 1) * (q - 1)
    d = modinv(e, tot)
    print(d % 1000000007)
    def el_gamal_dec(self, cipher, pub_key={}, appr="shanks"):
        p = pub_key['p']
        alpha = pub_key['alpha']
        beta = pub_key['beta']
        a = 0

        r = cipher[0]
        t = cipher[1]

        if appr == "brute":
            i = 3
            while i < p - 1:
                if beta == pow(alpha, i, p):
                    a = i
                    break
                i += 1

            if i == p - 1:
                raise Exception("El Gamal brute force attack failed")

            #print("Private key:",a)

            return self.dec.el_gamal(cipher=cipher,
                                     key={
                                         'p': p,
                                         'beta': beta,
                                         'alpha': alpha,
                                         'a': a
                                     })
        elif appr == "shanks":
            alpha_inv = cutils.modinv(alpha, p)
            N = int(math.ceil(p**0.5))
            if N**2 < p - 1:
                raise Exception("Shanks attack error: bad choice of N")

            j_list = []
            k_list = []
            i = 0
            match = set([])
            while i <= N:
                j_list.append(pow(alpha, i, p))
                k_list.append(pow(beta * pow(alpha_inv, N * i, p), 1, p))
                i += 1

            #print(j_list)
            #print(k_list)
            match = set(j_list).intersection(k_list)

            if len(match) == 0:
                raise Exception(
                    "El Gamal shanks attack failed: match={}".format(match))

            match = list(match)[0]
            j = j_list.index(match)
            k = k_list.index(match)

            a = j + N * k

            #print("Private key:",a)

            return self.dec.el_gamal(cipher=cipher,
                                     key={
                                         'p': p,
                                         'beta': beta,
                                         'alpha': alpha,
                                         'a': a
                                     })
        elif appr == "pohlig":
            factors = cutils.prime_factors(p - 1)
            #print(factors)
            alpha_inv = cutils.modinv(alpha, p)
            x = 0
            left = pow(alpha, (p - 1) / 2, p)
            right = pow(beta, (p - 1) / 2, p)
            if left == 1:
                raise Exception(
                    "Pollig-Hellman error: left equal to 1 mod {} therefore solution impossible"
                    .format(p))

            if right == 1:
                x = 0
            else:
                x = 1
            i = 2
            while (p - 1) % (2**i) == 0:
                right = pow(pow(alpha_inv, x, p) * beta, 1, p)
                right = pow(right, (p - 1) / (2**i), p)
                x = x + 2**(i - 1) * 1 if right == left else x
                i += 1
            a = (x, 2**(i - 1))
            limit = math.sqrt(p)
            #print("a is {} mod {}".format(x, 2**(i-1)))

            if len(factors) > 1:
                for prime in factors[1:]:
                    left = pow(alpha, (p - 1) / prime, p)
                    right = pow(beta, (p - 1) / prime, p)
                    #print(right, p, left)
                    x = cutils.dlog(right, p, left, prime) % prime
                    i = 2
                    while (p - 1) % (prime**i) == 0:
                        right = pow(pow(alpha_inv, x, p) * beta, 1, p)
                        right = pow(right, (p - 1) / (prime**i), p)
                        if right == left:
                            x = (x + prime**(i - 1) * 1)
                        elif right != 0:
                            x = x + prime**(i - 1) * (
                                cutils.dlog(right, p, left, prime**
                                            (i - 1)) % prime**(i - 1))
                        else:
                            x = x
                        i += 1
                    #print("a is {} mod {}".format(x, prime**(i-1)))
                    a = (cutils.rem(a[0], a[1], x,
                                    prime**(i - 1)), a[1] * prime**(i - 1))

            #print("Using a as {} mod {}".format(a[0], a[1]))
            return self.dec.el_gamal(cipher=cipher,
                                     key={
                                         'p': p,
                                         'beta': beta,
                                         'alpha': alpha,
                                         'a': a[0]
                                     })
        else:
            raise Exception("Unknown attack: {}".format(appr))
Exemple #9
0
    def generate_keys(algo="el_gamal", prime_length = 31, key = ""):
        if algo == "el_gamal":
            p = cutils.find_large_prime(prime_length)
            alpha = cutils.randroot(p, 2, 100)
            a = random.randint(3, p-1) # private key
            beta = pow(alpha, a, p)
            return {'p': p, 'alpha': alpha, 'beta': beta, 'a': a}

        elif algo == "rsa":
            # HMB, this is about to be some Grade A "excellent" code
            e = 3
            while True:
                p = q = cutils.find_large_prime(prime_length // 2 + 1)
                while p == q:
                    p = cutils.find_large_prime(prime_length // 2 + 1)
                phi = (p - 1) * (q - 1)
                try:
                    d = cutils.modinv(e, phi)
                except:
                    e += 1
                    continue
                return {'d': d, 'e': e, 'p': p, 'q': q}


        elif algo == "dsa":
            q = cutils.find_large_prime(prime_length)
            p = 2*q + 1
            while (p - 1) % q != 0 or not cutils.isPrime(p):
                #print("Testing Prime:", p)
                p = p + q
                while not cutils.isPrime(p):
                    p = p + q
            #print("Found (p, q): {},{}".format(p, q))

            g = cutils.randroot(p)
            alpha = pow(g, (p-1) / q, p)
            while pow(alpha, q, p) != 1:
                g = cutils.randroot(p, 2, q-1)
                alpha = pow(g, (p-1) / q, p)

            a = random.randint(3, q-1) # private key
            beta = pow(alpha, a, p)
            return {'p': p, 'q': q, 'alpha': alpha, 'beta': beta, 'a': a}

        elif algo == "des":
            round_keys = []

            # Convert key to binary before permutations
            # Translate message
            binary_key = bin(int(key.encode('hex'), 16))[2:]
            while len(binary_key) % 64 != 0:
                binary_key = "0" + binary_key

            perm_key = [0] * len(key_perms)
            for i in range(len(key_perms)):
                perm_key[i] = binary_key[key_perms[i]]

            c = perm_key[:28]
            d = perm_key[28:]

            for i in range(16):
                # Circular shift
                c.append(c.pop(0))
                d.append(d.pop(0))
                if i not in [0, 1, 8, 15]:
                    # Shift twice
                    c.append(c.pop(0))
                    d.append(d.pop(0))

                pre_perm_key = c + d

                ## Permutation with discard
                left_side = ""
                right_side = ""
                # Left
                for i in range(len(left_perm)):
                    left_side += pre_perm_key[left_perm[i]]
                # Right
                for i in range(len(right_perm)):
                    right_side += pre_perm_key[right_perm[i]]

                round_key = left_side + right_side

                round_keys.append(round_key)
            return {'k': round_keys}

        elif algo == 'otp':
            # Generate key of same length
            binary_key = ""
            for _ in range(len(key)):
                bit = random.getrandbits(1)
                binary_key += str(bit)
            return {'key': binary_key}

        else:
            return {}