import random


'''
Actual use of public/private keys for encryption/decryption (RSA)
The program asks for public and private key pairs
'''


def encrypt(pk, plaintext):
    """
    :param pk: public key is a tuple of two integers e, n
    :param plaintext: The message to be encrypted
    :return: encrypted message
    It uses the ascii valuse of the plain message characters and encrypts each one
    """

    # Unpack the key into it's components
    key, n = pk
    # Convert each letter in the plaintext to numbers based on the character using a^b mod m
    cipher = [pow(ord(char), key, n) for char in plaintext]
    # Return the array of bytes
    return cipher


def decrypt(pk, ciphertext):
    # Unpack the key into its components
    key, n = pk
    # Generate the plaintext based on the ciphertext and key using a^b mod m
    aux = [str(pow(char, key, n)) for char in ciphertext]
    # Return the array of bytes as a string
    plain = [chr(int(char2)) for char2 in aux]
    return ''.join(plain)


if __name__ == '__main__':
    '''
    Detect if the script is being run directly by the user
    '''
    print("===========================================================================================================")
    print("================================== RSA Encryptor / Decrypter ==============================================")
    print(" ")

    pubin1 = input("Enter public key: (e,n)   ")
    priin1 = input("Enter public key: (d,n)   ")
    arr1 = pubin1.split(',')
    arr2 = priin1.split(',')
    pub1 = int(arr1[0])
    pub2 = int(arr1[1])
    pri1 = int(arr2[0])
    pri2 = int(arr2[1])

    public = (pub1, pub2)
    private = (pri1, pri2)

    message = input(" - Enter a message to encrypt with your public key: ")
    encrypted_msg = encrypt(public, message)
    print(" - Your encrypted message is: ",  encrypted_msg)

    print(" - Decrypting message with private key ", private, " . . .")
    print(" - Your message is: ", decrypt(private, encrypted_msg))
