import random
import binascii
from Crypto.Cipher import AES
from Crypto.Hash import CMAC, HMAC, SHA256


KEY = b'1337133713371337'


def pkcs7(message: bytes, block_size: int = 16) -> bytes:
    gap_size = block_size - (len(message) % block_size)
    return message + bytes([gap_size] * gap_size)


def calc_cbc_mac(message: bytes, iv: bytes, key: bytes) -> bytes:
    cipher = AES.new(key, AES.MODE_CBC, iv)
    message = pkcs7(message)
    last_block = cipher.encrypt(message)[-16:]
    return last_block

def calc_hmac(message: bytes, key: bytes) -> bytes:
    # Create HMAC object with the key and message using SHA-256
    hmac = HMAC.new(KEY, msg=message, digestmod=SHA256)

    # Calculate the HMAC
    mac = hmac.hexdigest()
    return mac



def calc_cmac(message: bytes, key: bytes) -> bytes:
    c = CMAC.new(key, ciphermod=AES)
    c.update(message)
    return c.digest()


def check_challenge(challenge: bytes):
    return (
        calc_cbc_mac(challenge, b'\x00' * 16, KEY),
        calc_cmac(challenge, KEY),
        calc_hmac(challenge, KEY)
    )

def decode_message(msg):
    return binascii.unhexlify(msg)


def main():
    challenge = "f681e8625406c40419ae7771eac8f8a2eb6a6fcb1fc0396ab8fdca793a27c93a6dafbb"
    challenge = decode_message(challenge)
    print(check_challenge(challenge))


if __name__ == "__main__":
    main()