import sys, os, itertools, json, base64

from playcrypt.primitives import *
from playcrypt.tools import *
from playcrypt.ideal.function_family import *

from playcrypt.games.game_lr import GameLR
from playcrypt.games.game_kr import GameKR
from playcrypt.simulator.kr_sim import KRSim
from playcrypt.simulator.lr_sim import LRSim

"""
The XOR cipher is implemented as follows:
"""

def xor_cipher(k, m):
    C = ""
    for i in range(len(m)):
        C += xor_strings(k[i % len(k)], m[i])
    return C

""" Problem 1 [3 points] Give an adversary that wins the adversarial
indistinguishability experiment with probability 1.
"""

def A1(challenger):
    """You must fill in this method. This is the adversary that the problem is
    asking for.

    :param challenger: This function implements the challenger, which
    inputs two messages m_0 and m_1 and outputs a ciphertext
    corresponding to the encryption of one of them.
    
    :return: return 0 to indicate your adversary believes it received
    the encryption of m_0 and 1 to indicate your adversary believes it
    received the encryption of m_1.

    """

    return 0

""" Problem 2 [3 points] Give an adversary A2 that successfully
recovers the key after one chosen-plaintext query with a success
probability of 1.  """

def A2(challenger):
    """You must fill in this method. This is the adversary that the problem is
    asking for.

    :param challenger: The challenger inputs a message and returns the
    encryption of the message with a random key.
    :return: return what
    you believe to be the key value.

    """

    return None

if __name__ == '__main__':
    print("Testing A1 adversary in the indistinguishable encryption game:")
    k=64
    k_bytes = k//8
    g1 = GameLR(1, xor_cipher, k_bytes)
    s1 = LRSim(g1, A1)
    adv1 = s1.compute_advantage(1000)
    print("The advantage of your adversary A1 is approximately " + str(adv1))
    print("Testing A2 adversary in the key recovery game:")
    g2 = GameKR(1, xor_cipher, k_bytes, None)
    s2 = KRSim(g2, A2)
    adv2 = s2.compute_advantage(1000)
    print("The advantage of your adversary A2 is approximately " + str(adv2))

"""
Problem 3 [4 points]
Using the XOR-cipher defined above, Bob sent a message (in English) to Alice.
Your goal is to decrypt it, recover the secret token from the decrypted message,
and replace the token variable in the P3 function below.
Also, include the code you wrote to break the cipher and recover the text
in the function titled P3_code
"""

# This is the code that Bob used to generate the ciphertext, except that Alice
# doesn't know the secret key.  This is here for your reference.
def example_generate_ciphertext(message):
    k = "kumquats" # Bob used a different key.
    ciphertext = xor_cipher(k, message).encode('iso-8859-1')
    ciphertext_base64 = base64.b64encode(ciphertext).decode()
    return ciphertext_base64

# This function's output will be graded by the autograder.
# Replace the token variable with the 64 character token you got from the recovered plaintext.
def P3():
    token = "0000000000000000000000000000000000000000000000000000000000000000"
    return(token)

# This function will not be autograded.
# Replace the P3_code function with the code you wrote to decrypt the text to solve the above.
# If your process was partly manual or written in a language other than Python, explain your
# process and code in comments.  Your code shouldn't execute itself or take any actions
# that might cause errors with the autograder.
def P3_code():
    pass
