A-001.Algha_Porthos.2020 年 9 月运动会.20210925.2e2ded26.7z

This script is used for downloading and decrypting a file from the Arweave network. The file is first loaded from a specific location on Arweave (https://arweave.net/) using the get function, which repeatedly tries to download the file until it is successful. The file is then verified for integrity by checking its checksum against the expected value, and if the checksum is valid, the file is decrypted using the AES-GCM algorithm. The decryption key is derived from an initial seed key, which is passed through a key derivation function. The decrypted file is saved to the local file system using the filename variable, which is specified in the code. If the debug variable is set to True, the script will instead print the decrypted files without saving them to the file system.

import os
from base64 import urlsafe_b64decode
from hashlib import sha3_256, sha3_512
from json import loads

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from requests.models import Response
from requests.sessions import Session

filename: str = r"A-001.Algha_Porthos.2020 年 9 月运动会.20210925.2e2ded26.7z"
debug: bool = False


class Seed:
    key: bytes = urlsafe_b64decode(
        b"qj9ENpsLjg3we3P2UNeAfCuRvhD33TWq0HiiAPx55paHiP41pOy0fui31qg55IQS7UbAsgvd2vvVZ_KJNbQClA=="
    )
    ar: str = "45lnefx-m-cQlzDSrtkBaPee9KkQKn7tTj9Iq8oTiU8"
    checksum: str = "ucpRqnqj4PL3QtzFMOsz5qQZ-u95NPd_kqZvSkXAxSQ="


class KeyDerivation:
    def __init__(self, iv: bytes, next: bytes) -> None:
        assert len(iv) == 256, "iv must be 2048 bits"
        assert len(next) == 64, "next must be 512 bits"
        self.__generator__ = sha3_512(iv)
        self.__next__ = next

    def __call__(self) -> bytes:
        self.__generator__.update(self.__generator__.digest())
        self.__generator__.update(self.__next__)
        return self.__generator__.digest()


def decrypt(data: bytes, key: bytes) -> bytes:
    assert len(key) == 64, "key must be 512 bits"
    return AESGCM(key=key[:32]).decrypt(
        nonce=key[-12:], data=data, associated_data=key[32:-12]
    )


session = Session()


def get(ar: str) -> Response:
    print("ar", ar)
    while True:
        try:
            resp = session.get(f"https://arweave.net/{ar}/d")
            resp.raise_for_status()
            return resp
        except Exception as err:
            print("error", err)


def extract(key: bytes, ar: str, checksum: str) -> bytes:
    checksum = urlsafe_b64decode(checksum)
    checked = False
    while not checked:
        data = get(ar).content[12:]
        checked = checksum == (sha3_256(data).digest())
    return decrypt(data=data, key=key)


if __name__ == "__main__":
    seed = loads(extract(key=Seed.key, ar=Seed.ar, checksum=Seed.checksum))
    keyDerivation = KeyDerivation(
        iv=urlsafe_b64decode(seed["crypto"]["iv"]),
        next=urlsafe_b64decode(seed["crypto"]["next"]),
    )

    print("debug", debug)
    if debug:
        for obj in seed["store"]:
            key = keyDerivation()
            extract(key=key, ar=obj["ar"], checksum=obj["checksum"])
    else:
        import sys

        if getattr(sys, "frozen", False):
            current = os.path.dirname(sys.executable)
        else:
            current = os.path.dirname(os.path.abspath(__file__))

        with open(os.path.join(current, filename), "wb") as fout:
            for obj in seed["store"]:
                key = keyDerivation()
                fout.write(extract(key=key, ar=obj["ar"], checksum=obj["checksum"]))