// File: occivink[P]pyct/pyct.cpp
// Function: decrypt(std::vector<unsigned char, std::allocator<unsigned char>>, std::array<unsigned char, 32ul> const&)
vector<u8> decrypt(vector<u8> input, const Hash& hash) {
    if (input.size() < (8 + 16 + 24))
        throw invalid_argument{"Not enough data"};
    size_t message_length = input.size() - 24 - 16;
    u8* message_data = input.data();
    u8* mac_data = message_data + message_length;
    u8* nonce_data = mac_data + 16;

    if (0 != crypto_unlock(message_data,
                           hash.data(),
                           nonce_data,
                           mac_data,
                           message_data, message_length))
        throw invalid_argument{"Couldn't decrypt, invalid password?"};

    u8* size_data = message_data + message_length - 8;
    u64 original_size = static_cast<u64>(size_data[7])       |
                        static_cast<u64>(size_data[6]) << 8  |
                        static_cast<u64>(size_data[5]) << 16 |
                        static_cast<u64>(size_data[4]) << 24 |
                        static_cast<u64>(size_data[3]) << 32 |
                        static_cast<u64>(size_data[2]) << 40 |
                        static_cast<u64>(size_data[1]) << 48 |
                        static_cast<u64>(size_data[0]) << 56;
    input.resize(original_size);
    return input;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rsi, -0x70(%rbp)
movq %rdi, %rax
movq -0x70(%rbp), %rdi
movq %rax, -0x68(%rbp)
movq %rax, %rcx
movq %rcx, -0x60(%rbp)
movq %rax, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
callq 0x17400
cmpq $0x30, %rax
jae 0x14e2b
movl $0x10, %edi
callq 0x3140
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x78(%rbp)
leaq 0x83ee(%rip), %rsi      # 0x1d1e1
callq 0x3530
jmp 0x14dfa
movq -0x78(%rbp), %rdi
movq 0xf1cb(%rip), %rsi      # 0x23fd0
movq 0xf1b4(%rip), %rdx      # 0x23fc0
callq 0x34c0
movq -0x78(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0x3200
jmp 0x14fa1
movq -0x70(%rbp), %rdi
callq 0x17400
movq -0x70(%rbp), %rdi
subq $0x18, %rax
subq $0x10, %rax
movq %rax, -0x30(%rbp)
callq 0x17380
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x18(%rbp), %rdi
callq 0x175c0
movq -0x80(%rbp), %rdi
movq %rax, %rsi
movq -0x48(%rbp), %rdx
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %r8
movq -0x30(%rbp), %r9
callq 0x12610
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
je 0x14ef6
movl $0x10, %edi
callq 0x3140
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x88(%rbp)
leaq 0x8339(%rip), %rsi      # 0x1d1f1
callq 0x3530
jmp 0x14ebf
movq -0x88(%rbp), %rdi
movq 0xf103(%rip), %rsi      # 0x23fd0
movq 0xf0ec(%rip), %rdx      # 0x23fc0
callq 0x34c0
movq -0x88(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0x3200
jmp 0x14fa1
movq -0x70(%rbp), %rdi
movq -0x38(%rbp), %rax
addq -0x30(%rbp), %rax
addq $-0x8, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movzbl 0x7(%rax), %eax
movq -0x50(%rbp), %rcx
movzbl 0x6(%rcx), %ecx
shlq $0x8, %rcx
orq %rcx, %rax
movq -0x50(%rbp), %rcx
movzbl 0x5(%rcx), %ecx
shlq $0x10, %rcx
orq %rcx, %rax
movq -0x50(%rbp), %rcx
movzbl 0x4(%rcx), %ecx
shlq $0x18, %rcx
orq %rcx, %rax
movq -0x50(%rbp), %rcx
movzbl 0x3(%rcx), %ecx
shlq $0x20, %rcx
orq %rcx, %rax
movq -0x50(%rbp), %rcx
movzbl 0x2(%rcx), %ecx
shlq $0x28, %rcx
orq %rcx, %rax
movq -0x50(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
shlq $0x30, %rcx
orq %rcx, %rax
movq -0x50(%rbp), %rcx
movzbl (%rcx), %ecx
shlq $0x38, %rcx
orq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rsi
callq 0x17470
movq -0x68(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x175e0
movq -0x60(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x34f0
nopw (%rax,%rax)