#!/usr/bin/env sage

from sage.all import *
from sage.env import SAGE_VERSION

import hashlib
import os
import platform
import re
import sys


def die(message):
    print("[-] " + message)
    sys.exit(1)


def parse_version(version):
    parts = [int(x) for x in re.findall(r"\d+", version)]
    return tuple((parts + [0, 0, 0])[:3])


def running_in_wsl():
    if platform.system() != "Linux":
        return False

    candidates = [
        "/proc/sys/kernel/osrelease",
        "/proc/version",
    ]
    for path in candidates:
        try:
            with open(path, "r", encoding="utf-8", errors="ignore") as f:
                text = f.read().lower()
        except OSError:
            continue
        if "microsoft" in text or "wsl" in text:
            return True
    return bool(os.environ.get("WSL_DISTRO_NAME"))


def sage_103_feature_check():
    # Sage 10.3 added PARI as an explicit LLL backend:
    #     Matrix.LLL(algorithm="pari")
    M = identity_matrix(ZZ, 4)
    try:
        R, U = M.LLL(algorithm="pari", transformation=True)
    except Exception as exc:
        die("Sage 10.3 feature check failed: Matrix.LLL(algorithm='pari') cannot run.\n    " + repr(exc))

    if U * M != R:
        die("Sage 10.3 feature check failed: LLL transformation matrix is inconsistent.")

    return R, U


if parse_version(SAGE_VERSION) < (10, 3, 0):
    die("SageMath version is {}, but this challenge needs SageMath 10.3 or newer.".format(SAGE_VERSION))

if not running_in_wsl():
    die("This script must be run inside WSL. Native Windows SageMath and web SageMath are not accepted.")

R, U = sage_103_feature_check()

try:
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import unpad
except ImportError:
    die("pycryptodome is missing. Install it with: python -m pip install pycryptodome")

seed = "moectf-sage-wsl-v1|{}|{}".format(
    ",".join(str(x) for x in R.list()),
    ",".join(str(x) for x in U.list()),
)
key = hashlib.sha256(seed.encode()).digest()
iv = bytes.fromhex("536167654d61746831302e332057534c")
ciphertext = bytes.fromhex(
    "c4dc5084a57ea9f7305cfe462688902fcc139c339b76d94dc0a2f6"
    "74fd2da27c1d48912d2be4dd3b4affed1589bfbdd4"
)

flag = unpad(AES.new(key, AES.MODE_CBC, iv).decrypt(ciphertext), 16).decode()
print("[+] SageMath {} detected".format(SAGE_VERSION))
print("[+] WSL detected")
print("[+] pycryptodome detected")
print(flag)

