A-001.Algha_Porthos.音乐.20211001.ca8b0265.7z

This script is used to download and decrypt a file from the Arweave network. The file is stored in multiple parts and is encrypted with AESGCM and a 512-bit key. The script uses a seed key and an AR address to retrieve the file's metadata, which contains information about the parts of the file and their checksums. The script then uses the seed key and metadata to derive a new key for each part, which is then used to decrypt the part and check its integrity. Finally, the script writes the decrypted parts to a file on the local machine. If the variable "debug" is set to true, the script will print the decrypted parts instead of writing them to a file.

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.音乐.20211001.ca8b0265.7z"
debug: bool = False


class Seed:
    key: bytes = urlsafe_b64decode(
        b"_-cALsBktKYUVrhsZkS7XlVnDBVcPcdvd6WF_JWSuPVGr8JbM6uKni9OZT4AJELVrzl1yhQlwwHs_9FmAYfmpg=="
    )
    ar: str = "-Bb3n9Fa1Ant0xh8yhQPFtRP8-ZpuQbr5aG1XLQgXX0"
    checksum: str = "PVbpZBW0T7LdtIv3g7vemRyxN9CxPdifLa7d0pAjJSw="


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"]))