// File: LandonSwartz[P]TheGreatEncryptor/./EncryptionClass.cpp
// Function: encryption_base::encrypt_data()
bool encrypt_data() {
        if (this->hash_key == 0) {
            throw file_encryption_error("no hash key has been set");
            return false;
        }
        if (data_state == 0) {
            throw file_encryption_error("there is no data to encrypt");
            return false;
        } else if (data_state == 1) {
            throw file_encryption_error("the data is already encrypted");
            return false;
        }

        // Set up the structs for the threads which will encrypt the data.
        vector<alg_prms *> encryption_alg_prms_vect;
        int indices_per_thread;
        int num_threads;
        int end_additional_increment = 0;
        // Ensure there will be at least one string per thread
        if (data->size() >= NUM_ENCRYPTION_THREADS) {
            indices_per_thread = (data->size()) / NUM_ENCRYPTION_THREADS;
            end_additional_increment = (data->size()) % NUM_ENCRYPTION_THREADS;
            num_threads = NUM_ENCRYPTION_THREADS;
        }
        // If there will not be one string per thread, simply use one thread
        else {
            num_threads = 1;
            indices_per_thread = data->size();
        }

        // Create structs for each thread
        for (int i = 0; i < num_threads; i++) {
            alg_prms * alg_prms_strc = new alg_prms();
            alg_prms_strc->data = this->data;
            alg_prms_strc->hash_key = this->hash_key;
            alg_prms_strc->start_index = (i * indices_per_thread);
            alg_prms_strc->end_index = ((i + 1) * indices_per_thread) - 1;
            encryption_alg_prms_vect.push_back(alg_prms_strc);
        }
        // Add end_additional_increment
        encryption_alg_prms_vect.back()->end_index += end_additional_increment;

        // Create the threads to encrypt the data
        vector<pthread_t> encryption_threads;
        for (auto prm_vct : encryption_alg_prms_vect) {
            pthread_t new_thread;
            pthread_create(&new_thread, NULL, encryption_algorithm, prm_vct);
            encryption_threads.push_back(new_thread);
        }

        // Now that the threads are running, join them so the function will yield
        for (auto thread : encryption_threads) {
            pthread_join(thread, NULL);
        }

        // Delete the dynamically allocated structs once all thread operation has completed
        for (auto prm_vct : encryption_alg_prms_vect) {
            delete prm_vct;
        }

        // Return true to indicate the encryption was successful.
        return true;
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xd0(%rbp)
cmpl $0x0, 0x10(%rax)
jne 0x3afc
movl $0x10, %edi
callq 0x20e0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd8(%rbp)
leaq 0x4743(%rip), %rsi      # 0x8201
callq 0x3f20
jmp 0x3ac5
movq -0xd8(%rbp), %rdi
leaq 0x824d(%rip), %rsi      # 0xbd20
leaq 0x486(%rip), %rdx       # 0x3f60
callq 0x22d0
movq -0xd8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
callq 0x2130
jmp 0x3f0e
movq -0xd0(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x3b64
movl $0x10, %edi
callq 0x20e0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe0(%rbp)
leaq 0x46f4(%rip), %rsi      # 0x821a
callq 0x3f20
jmp 0x3b2d
movq -0xe0(%rbp), %rdi
leaq 0x81e5(%rip), %rsi      # 0xbd20
leaq 0x41e(%rip), %rdx       # 0x3f60
callq 0x22d0
movq -0xe0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
callq 0x2130
jmp 0x3f0e
movq -0xd0(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x3bcc
movl $0x10, %edi
callq 0x20e0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe8(%rbp)
leaq 0x46a8(%rip), %rsi      # 0x8236
callq 0x3f20
jmp 0x3b95
movq -0xe8(%rbp), %rdi
leaq 0x817d(%rip), %rsi      # 0xbd20
leaq 0x3b6(%rip), %rdx       # 0x3f60
callq 0x22d0
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
callq 0x2130
jmp 0x3f0e
jmp 0x3bce
leaq -0x30(%rbp), %rdi
callq 0x3f80
movq -0xd0(%rbp), %rax
movl $0x0, -0x3c(%rbp)
movq 0x8(%rax), %rdi
callq 0x3fa0
cmpq $0xa, %rax
jb 0x3c3c
movq -0xd0(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x3fa0
movl $0xa, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0xd0(%rbp), %rax
movl %ecx, -0x34(%rbp)
movq 0x8(%rax), %rdi
callq 0x3fa0
movl $0xa, %ecx
xorl %edx, %edx
divq %rcx
movl %edx, %eax
movl %eax, -0x3c(%rbp)
movl $0xa, -0x38(%rbp)
jmp 0x3c56
movq -0xd0(%rbp), %rax
movl $0x1, -0x38(%rbp)
movq 0x8(%rax), %rdi
callq 0x3fa0
movl %eax, -0x34(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x38(%rbp), %eax
jge 0x3d05
movl $0x18, %edi
callq 0x2190
movq %rax, -0xf0(%rbp)
jmp 0x3c7c
movq -0xd0(%rbp), %rax
movq -0xf0(%rbp), %rcx
xorps %xmm0, %xmm0
movaps %xmm0, (%rcx)
movq $0x0, 0x10(%rcx)
movq %rcx, -0x48(%rbp)
movq 0x8(%rax), %rdx
movq -0x48(%rbp), %rcx
movq %rdx, (%rcx)
movl 0x10(%rax), %ecx
movq -0x48(%rbp), %rax
movl %ecx, 0x10(%rax)
movl -0x40(%rbp), %ecx
movl -0x34(%rbp), %eax
imull %eax, %ecx
movq -0x48(%rbp), %rax
movl %ecx, 0x8(%rax)
movl -0x40(%rbp), %ecx
incl %ecx
movl -0x34(%rbp), %eax
imull %eax, %ecx
decl %ecx
movq -0x48(%rbp), %rax
movl %ecx, 0xc(%rax)
leaq -0x30(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x3fc0
jmp 0x3ce4
jmp 0x3ce6
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x3c5d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
jmp 0x3f05
movl -0x3c(%rbp), %eax
movl %eax, -0xf4(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x4030
movl -0xf4(%rbp), %ecx
movq (%rax), %rax
addl 0xc(%rax), %ecx
movl %ecx, 0xc(%rax)
leaq -0x60(%rbp), %rdi
callq 0x4070
leaq -0x30(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
callq 0x4090
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rdi
callq 0x40c0
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x40f0
testb $0x1, %al
jne 0x3d64
jmp 0x3dcf
leaq -0x70(%rbp), %rdi
callq 0x4130
movq (%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rcx
leaq 0x3d1(%rip), %rdx       # 0x4150
xorl %eax, %eax
movl %eax, %esi
leaq -0x88(%rbp), %rdi
movq %rdi, -0x100(%rbp)
callq 0x2310
movq -0x100(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x4230
jmp 0x3da8
jmp 0x3daa
leaq -0x70(%rbp), %rdi
callq 0x42a0
jmp 0x3d51
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x10(%rbp)
movl %eax, -0x14(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x43a0
jmp 0x3f05
leaq -0x60(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
callq 0x42c0
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rdi
callq 0x42f0
movq %rax, -0xa0(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x4320
testb $0x1, %al
jne 0x3e19
jmp 0x3e51
leaq -0x98(%rbp), %rdi
callq 0x4360
movq (%rax), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2170
jmp 0x3e41
jmp 0x3e43
leaq -0x98(%rbp), %rdi
callq 0x4380
jmp 0x3e00
leaq -0x30(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x4090
movq %rax, -0xb8(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x40c0
movq %rax, -0xc0(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x40f0
testb $0x1, %al
jne 0x3e9b
jmp 0x3ee6
leaq -0xb8(%rbp), %rdi
callq 0x4130
movq (%rax), %rax
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0x108(%rbp)
cmpq $0x0, %rax
je 0x3ed6
movq -0x108(%rbp), %rdi
movl $0x18, %esi
callq 0x21a0
jmp 0x3ed8
leaq -0xb8(%rbp), %rdi
callq 0x42a0
jmp 0x3e82
leaq -0x60(%rbp), %rdi
callq 0x43a0
leaq -0x30(%rbp), %rdi
callq 0x4400
movb $0x1, %al
andb $0x1, %al
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x4400
movq -0x10(%rbp), %rdi
callq 0x2300
nopw (%rax,%rax)