// File: permutationlock[P]aes_math/lib/galois_field.cpp
// Function: GaloisPolynomial::inverse() const
GaloisPolynomial GaloisPolynomial::inverse() const{
    // Return 0 on 0
    if(_polynomial.size()<1) return GaloisPolynomial(Polynomial(0,_polynomial.getPrime(),1));
    Polynomial p1 = _modulus;
    Polynomial p2 = _polynomial;
    vector<Polynomial> aux;
    aux.push_back(Polynomial(0,_polynomial.getPrime(),1));
    aux.push_back(Polynomial(1,_polynomial.getPrime(),1));
    
    // Divide until we hit 1
    while(p1.size()>1 && p2.size()>1){
        Polynomial quot = p1/p2;
        Polynomial rem = p1%p2;
        Polynomial a_n = aux.back();
        a_n*=quot;
        a_n+=aux[aux.size()-2];
        aux.push_back(a_n);
        p1 = p2;
        p2 = rem;
    }
    
    return GaloisPolynomial(aux.back());
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x18(%rsp)
movq %rdi, %rax
movq %rax, 0x20(%rsp)
movq %rdi, 0x160(%rsp)
movq %rsi, 0x158(%rsp)
movq 0x158(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x4700
cmpl $0x1, %eax
jge 0x5f19
movq 0x28(%rsp), %rdi
callq 0x5610
movl %eax, %edx
leaq 0x138(%rsp), %rdi
movq %rdi, 0x10(%rsp)
xorl %esi, %esi
movl $0x1, %ecx
callq 0x4370
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x5ce0
jmp 0x5ee1
leaq 0x138(%rsp), %rdi
callq 0x6b50
jmp 0x625b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x6b50
jmp 0x6268
leaq 0x18288(%rip), %rsi     # 0x1e1a8
leaq 0x108(%rsp), %rdi
callq 0x4630
movq 0x28(%rsp), %rsi
leaq 0xe8(%rsp), %rdi
callq 0x4630
jmp 0x5f41
leaq 0xd0(%rsp), %rdi
callq 0x6f10
movq 0x28(%rsp), %rdi
callq 0x5610
movl %eax, %edx
leaq 0xb0(%rsp), %rdi
xorl %esi, %esi
movl $0x1, %ecx
callq 0x4370
jmp 0x5f70
leaq 0xd0(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x6f20
jmp 0x5f87
leaq 0xb0(%rsp), %rdi
callq 0x6b50
movq 0x28(%rsp), %rdi
callq 0x5610
movl %eax, %edx
leaq 0x90(%rsp), %rdi
movl $0x1, %ecx
movl %ecx, %esi
callq 0x4370
jmp 0x5fb6
leaq 0xd0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x6f20
jmp 0x5fcd
leaq 0x90(%rsp), %rdi
callq 0x6b50
leaq 0x108(%rsp), %rdi
callq 0x4700
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x1, %ecx
movb %al, 0xf(%rsp)
jle 0x600b
leaq 0xe8(%rsp), %rdi
callq 0x4700
cmpl $0x1, %eax
setg %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x6018
jmp 0x61ed
leaq 0x70(%rsp), %rdi
leaq 0x108(%rsp), %rsi
leaq 0xe8(%rsp), %rdx
callq 0x54c0
jmp 0x6034
leaq 0x50(%rsp), %rdi
leaq 0x108(%rsp), %rsi
leaq 0xe8(%rsp), %rdx
callq 0x5420
jmp 0x6050
leaq 0xd0(%rsp), %rdi
callq 0x6f50
movq %rax, %rsi
leaq 0x30(%rsp), %rdi
callq 0x4630
jmp 0x606c
leaq 0x30(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x4a00
jmp 0x607d
leaq 0xd0(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x6fb0
movq (%rsp), %rdi
movq %rax, %rsi
addq $-0x2, %rsi
callq 0x6f90
movq %rax, %rsi
leaq 0x30(%rsp), %rdi
callq 0x4740
jmp 0x60ad
leaq 0xd0(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x6fd0
jmp 0x60c1
leaq 0x108(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x7040
jmp 0x60d8
leaq 0xe8(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x7040
jmp 0x60ec
leaq 0x30(%rsp), %rdi
callq 0x6b50
leaq 0x50(%rsp), %rdi
callq 0x6b50
leaq 0x70(%rsp), %rdi
callq 0x6b50
jmp 0x5fda
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x624c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x6232
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x6b50
jmp 0x6232
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x6b50
jmp 0x6232
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x61e1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0x61d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x6b50
leaq 0x50(%rsp), %rdi
callq 0x6b50
leaq 0x70(%rsp), %rdi
callq 0x6b50
jmp 0x6232
leaq 0xd0(%rsp), %rdi
callq 0x6f50
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x5ce0
jmp 0x6209
leaq 0xd0(%rsp), %rdi
callq 0x7080
leaq 0xe8(%rsp), %rdi
callq 0x6b50
leaq 0x108(%rsp), %rdi
callq 0x6b50
jmp 0x625b
leaq 0xd0(%rsp), %rdi
callq 0x7080
leaq 0xe8(%rsp), %rdi
callq 0x6b50
leaq 0x108(%rsp), %rdi
callq 0x6b50
jmp 0x6268
movq 0x20(%rsp), %rax
addq $0x168, %rsp            # imm = 0x168
retq
movq 0x130(%rsp), %rdi
callq 0x22b0
nopw %cs:(%rax,%rax)