"""

MIF29 - Cryptographie - TP1

Exercice 1 : RSA

/* ici les réponses aux questions ouvertes de l'exercice 1 */


Exercice 2 : Pailler

/* ici les réponses aux questions ouvertes de l'exercice 1 */

"""

from math import gcd, lcm
from Crypto.Util.number import getPrime, inverse
from Crypto.Random.random import randint, getrandbits


def textbook_rsa_keygen(k: int, p=None, q=None, e=None):
    """Textbook RSA key generation

    Parameters
    ----------
    k : int
        le nombre de bits de la clef
    p : int, optional
        premier facteur, by default None, auquel cas on le tire au hasard
    q : int, optional
        second facteur, by default None, auquel cas on le tire au hasard
    e : int, optional
        exposant, by default None, le plus petit entier premier avec ϕ(n) strictement supérieur à 1.

    Returns
    -------
    ((int, int), (int, int))
        une paire de paires : (public_key, secret_key), chacune composée de (n, e) ou (n, d).

    Raises
    ------
    ArithmeticError
        si e et ϕ ne sont pas premiers entre eux
    """

    raise NotImplementedError("TODO: implement textbook_rsa_keygen")


def textbook_rsa_encrypt(pk, m):
    """Textbook RSA encryption

    Parameters
    ----------
    pk : (int, int)
        la clef publique
    m : int
        le message en clair, déjà mis sous forme d'entier

    Returns
    -------
    int
        le message chiffré
    """
    raise NotImplementedError("TODO: implement textbook_rsa_encrypt")


def textbook_rsa_decrypt(sk, c):
    """Textbook RSA decryption

    Parameters
    ----------
    sk : (int, int)
        la clef secrète
    c : int
        le message chiffré

    Returns
    -------
    int
        le message déchiffré
    """
    raise NotImplementedError("TODO: implement textbook_rsa_decrypt")


if __name__ == "__main__":
    print(
        "Vérification de la correction de textbook_rsa_keygen, textbook_rsa_encrypt et textbook_rsa_decrypt"
    )


if __name__ == "__main__":
    print(
        "Evaluation empirique des performances de textbook_rsa_keygen, textbook_rsa_encrypt et textbook_rsa_decrypt"
    )


def pailler_keygen(k: int, p=None, q=None):
    """Generate keypairs for Pailler's.

    Parameters
    ----------
    k: int
        Number of bits

    Returns
    -------
    (int, int)
        A pair (public_key, secret_key)

    """
    raise NotImplementedError("TODO: implement pailler_keygen")


def pailler_encrypt(pk, m, r=None):
    """Pailler's encryption function"""
    raise NotImplementedError("TODO: implement pailler_keygen")


def pailler_decrypt(pk, sk, c):
    """Pailler's decryption function"""
    raise NotImplementedError("TODO: implement pailler_keygen")


if __name__ == "__main__":
    print(
        "Vérification de la correction de pailler_keygen, pailler_encrypt et pailler_decrypt"
    )
