import random

class RSAKey:

    def __init__(self):
        return

    # calculates amount of rows of given filen
    def fileLen(self, filename):

        if not isinstance(filename, str):
            return -1

        try:
            f = open(filename, "r")
            for j, l in enumerate(f):
                pass
            f.close()
            return j + 1
        except IOError:
            return -1

    # returns a prime number from the file primeNumbers.txt
    def getRandomPrime(self):

        #randomRow = random.randrange(0, self.fileLen("primeNumbers.txt"))
        randomRow = random.randrange(0, 50)

        if randomRow == -1:
            return -1

        f = open("primeNumbers.txt", "r")
        lineNumber = 1
        for line in f:
            if lineNumber == randomRow:
                print("Line = ", line)
                break
            lineNumber = lineNumber + 1
        print("RValue = ", randomRow)
        value = line.split("\n")
        print("Value = ", value)
        prime = int(value[0])
        print("Prime = ", prime)
        f.close()
        return prime

    # calculates greatest common divisor between a and b
    def ggT(self, a, b):

        if not isinstance(a, int):
            return -1

        if not isinstance(b, int):
            return -1

        if a <= 0 or b <= 0:
            return -1

        print("ggT")
        ggt = 1
        h = 0
        if a > b:
            h = b
        else:
            h = a
        x = 0

        for x in range (h, 1, -1):
            if (a % x) == 0 and (b % x) == 0:
                print("Teiler war", x)
                return x
        return 1

    # calculates multiplicative inverse of a and m
    def inverse(self, a, m):

        if not isinstance(a, int):
            return -1

        if not isinstance(m, int):
            return -1

        m0 = m
        y = 0
        x = 1

        if (m == 1):
            return 0

        while (a > 1):
            q = a // m
            t = m
            m = a % m
            a = t
            t = y
            y = x - q * y
            x = t
        if (x < 0):
            x = x + m0
        return x

    # creates private and public key
    def createPrivateAndPublicKey(self):

        p = self.getRandomPrime()
        q = self.getRandomPrime()
        print("Start")
        while p == q:
            p = self.getRandomPrime()
            q = self.getRandomPrime()

            if p == -1 or q == -1:
                return -1

        print("Calculated p and q. p = ", p, ", q = ", q)
        n = p * q
        print("n = ", n)
        phi = (p-1) * (q-1)
        print("Phi = ", phi)

        e = 0
        ggt = 0
        while e <= 1 or e >= phi or ggt != 1:
            e = random.randrange(2, phi - 1)
            ggt = self.ggT(e, phi)

            if ggt == -1:
                return -1

        print("e = ", e)
        d = self.inverse(e, phi)

        if d == -1:
            return -1

        print("d = ", d)
        modulo = (e * d) % phi
        print("(e * d) % phi = ", modulo)
        privateKey = [d, n]
        publicKey = [e, n]
        return privateKey, publicKey
import random

class RSAKey:

    def __init__(self):
        return

    # calculates amount of rows of given filen
    def fileLen(self, filename):

        if not isinstance(filename, str):
            return -1

        try:
            f = open(filename, "r")
            for j, l in enumerate(f):
                pass
            f.close()
            return j + 1
        except IOError:
            return -1

    # returns a prime number from the file primeNumbers.txt
    def getRandomPrime(self):

        #randomRow = random.randrange(0, self.fileLen("primeNumbers.txt"))
        randomRow = random.randrange(0, 50)

        if randomRow == -1:
            return -1

        f = open("primeNumbers.txt", "r")
        lineNumber = 1
        for line in f:
            if lineNumber == randomRow:
                print("Line = ", line)
                break
            lineNumber = lineNumber + 1
        print("RValue = ", randomRow)
        value = line.split("\n")
        print("Value = ", value)
        prime = int(value[0])
        print("Prime = ", prime)
        f.close()
        return prime

    # calculates greatest common divisor between a and b
    def ggT(self, a, b):

        if not isinstance(a, int):
            return -1

        if not isinstance(b, int):
            return -1

        if a <= 0 or b <= 0:
            return -1

        print("ggT")
        ggt = 1
        h = 0
        if a > b:
            h = b
        else:
            h = a
        x = 0

        for x in range (h, 1, -1):
            if (a % x) == 0 and (b % x) == 0:
                print("Teiler war", x)
                return x
        return 1

    # calculates multiplicative inverse of a and m
    def inverse(self, a, m):

        if not isinstance(a, int):
            return -1

        if not isinstance(m, int):
            return -1

        m0 = m
        y = 0
        x = 1

        if (m == 1):
            return 0

        while (a > 1):
            q = a // m
            t = m
            m = a % m
            a = t
            t = y
            y = x - q * y
            x = t
        if (x < 0):
            x = x + m0
        return x

    # creates private and public key
    def createPrivateAndPublicKey(self):

        p = self.getRandomPrime()
        q = self.getRandomPrime()
        print("Start")
        while p == q:
            p = self.getRandomPrime()
            q = self.getRandomPrime()

            if p == -1 or q == -1:
                return -1

        print("Calculated p and q. p = ", p, ", q = ", q)
        n = p * q
        print("n = ", n)
        phi = (p-1) * (q-1)
        print("Phi = ", phi)

        e = 0
        ggt = 0
        while e <= 1 or e >= phi or ggt != 1:
            e = random.randrange(2, phi - 1)
            ggt = self.ggT(e, phi)

            if ggt == -1:
                return -1

        print("e = ", e)
        d = self.inverse(e, phi)

        if d == -1:
            return -1

        print("d = ", d)
        modulo = (e * d) % phi
        print("(e * d) % phi = ", modulo)
        privateKey = [d, n]
        publicKey = [e, n]
        return privateKey, publicKey
# calculates amount of rows of given filen # returns a prime number from the file primeNumbers.txt #randomRow = random.randrange(0, self.fileLen("primeNumbers.txt")) # calculates greatest common divisor between a and b # calculates multiplicative inverse of a and m # creates private and public key