// File: /workspace/github_cpp_makefile_star2_O2/permutationlock[P]aes_math/lib/aes.cpp
// Function: encrypt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int)
string encrypt(string plaintext, string key, int rounds){
    // Set up Galois Field
    GaloisPolynomial::globalSetModulus(rijndael_Mod);
    
    // Convert strings to unsigned characters
    vector<unsigned char> vplaintext(plaintext.begin(), plaintext.end());
    vector<unsigned char> vkey(key.begin(), key.end());
    
    // Expand key
    vector<QSMatrix<GaloisPolynomial>> keyMatrices = expandKey(vkey, rounds);
    
    // Convert plaintext to matrix representation
    vector<GaloisPolynomial> sVec;
    sVec.reserve(16);
    for(int i=0; i<16; i++){
        sVec.push_back(extractPoly(vplaintext));
    }
    QSMatrix<GaloisPolynomial> state(4, 4, sVec);
    
    // Perform rounds on plaintext
    addRoundKey(state, keyMatrices[0]);
    for(int i=1; i<rounds; i++){
        subBytes(state);
        shiftRows(state);
        mixColumns(state);
        addRoundKey(state, keyMatrices[i]);
    }
    subBytes(state);
    shiftRows(state);
    addRoundKey(state, keyMatrices[rounds]);
    
    // Convert back to string
    vector<unsigned char> vciphertext;
    for(int i=0; i<4; i++){
        for(int j=0; j<4; j++){
            vciphertext.push_back(polyToChar(state(i,j)));
        }
    }
    string ciphertext(vciphertext.begin(), vciphertext.end());
    
    return ciphertext;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movl %ecx, %ebp
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x7e70(%rip), %rdi      # 0xd158
callq 0x3e98
movq (%r15), %rsi
movq 0x8(%r15), %rdx
addq %rsi, %rdx
leaq 0xc0(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x5df6
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
leaq 0xa8(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x5df6
leaq 0x90(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x5e28
leaq 0x38(%rsp), %rdi
leaq 0x90(%rsp), %rsi
movl %ebp, %edx
callq 0x5070
leaq 0x90(%rsp), %rdi
callq 0x77d6
xorps %xmm0, %xmm0
leaq 0x70(%rsp), %rdi
movaps %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
pushq $0x10
popq %rsi
callq 0x5d22
pushq $0x10
popq %r13
leaq 0x10(%rsp), %r14
leaq 0xc0(%rsp), %r15
leaq 0x70(%rsp), %r12
subl $0x1, %r13d
jb 0x53af
movq %r14, %rdi
movq %r15, %rsi
callq 0x4ef2
movq %r12, %rdi
movq %r14, %rsi
callq 0x6ace
movq %r14, %rdi
callq 0x4360
jmp 0x5389
leaq 0x10(%rsp), %rdi
pushq $0x4
popq %rdx
leaq 0x70(%rsp), %rcx
movl %edx, %esi
callq 0x58a4
movq 0x38(%rsp), %rsi
leaq 0x10(%rsp), %rdi
callq 0x5c70
movslq %ebp, %r15
pushq $0x1
popq %r12
pushq $0x28
popq %r13
leaq 0x10(%rsp), %r14
cmpq %r15, %r12
jge 0x5418
movq %r14, %rdi
callq 0x4bd3
movq %r14, %rdi
callq 0x4c93
movq %r14, %rdi
callq 0x4e3c
movq 0x38(%rsp), %rsi
addq %r13, %rsi
movq %r14, %rdi
callq 0x5c70
incq %r12
addq $0x28, %r13
jmp 0x53e2
leaq 0x10(%rsp), %rdi
callq 0x4bd3
leaq 0x10(%rsp), %rdi
callq 0x4c93
imulq $0x28, %r15, %rsi
addq 0x38(%rsp), %rsi
leaq 0x10(%rsp), %rdi
callq 0x5c70
leaq 0x50(%rsp), %r14
andq $0x0, 0x10(%r14)
xorps %xmm0, %xmm0
movaps %xmm0, (%r14)
xorl %r12d, %r12d
leaq 0xf(%rsp), %r15
cmpq $0x4, %r12
je 0x5498
imulq $0x18, %r12, %r13
xorl %ebp, %ebp
cmpq $0x80, %rbp
je 0x5493
movq 0x18(%rsp), %rax
movq (%rax,%r13), %rdi
addq %rbp, %rdi
callq 0x3e92
movb %al, 0xf(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x7882
addq $0x20, %rbp
jmp 0x5464
incq %r12
jmp 0x5458
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
leaq 0x10(%rbx), %rax
movq %rax, (%rbx)
movq %rbx, %rdi
callq 0x7996
leaq 0x50(%rsp), %rdi
callq 0x77d6
leaq 0x10(%rsp), %rdi
callq 0x59da
leaq 0x70(%rsp), %rdi
callq 0x59b8
leaq 0x38(%rsp), %rdi
callq 0x5dd4
leaq 0xa8(%rsp), %rdi
callq 0x77d6
leaq 0xc0(%rsp), %rdi
callq 0x77d6
movq %rbx, %rax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x5545
jmp 0x552c
jmp 0x552c
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x77d6
jmp 0x5570
movq %rax, %rbx
jmp 0x5570
movq %rax, %rbx
jmp 0x557d
jmp 0x5540
movq %rax, %rbx
jmp 0x555c
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x4360
jmp 0x555c
movq %rax, %rbx
jmp 0x5552
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x77d6
leaq 0x10(%rsp), %rdi
callq 0x59da
leaq 0x70(%rsp), %rdi
callq 0x59b8
leaq 0x38(%rsp), %rdi
callq 0x5dd4
leaq 0xa8(%rsp), %rdi
callq 0x77d6
leaq 0xc0(%rsp), %rdi
callq 0x77d6
movq %rbx, %rdi
callq 0x21c0