// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/paeq128/aesni/encrypt.cpp
// Function: FPerm(unsigned char const*, unsigned char*)
void FPerm(const unsigned char* input, unsigned char* output)//AESQ permutation
{

	unsigned char Registers[4][16];  //AES state registers
	unsigned char Registers_tmp[4][16];  //AES state registers

	for (unsigned i = 0; i<4; ++i)//Filling registers
	{
		for (unsigned j = 0; j<16; ++j)
			Registers[i][j] = input[16 * i + j];
	}

	//Main permutation
	for (unsigned i = 0; i<AES_GROUPS; ++i)//Group loop
	{
		//AES rounds
		for (unsigned r = 0; r<4; ++r)//Register loop
		{
			for (unsigned j = 0; j<AES_GROUP_ROUNDS; ++j)//Middle rounds
			{
				AES_Round(Registers[r]); //SB-SR-MC
				for (unsigned k = 0; k<4; ++k)  //Round constants
				{
					Registers[r][4 * k] ^= 8 * i + 4 * j + r + 1;
				}
			}
		}
		//Permutation
		for (unsigned r = 0; r<4; ++r)//Register loop
			for (unsigned j = 0; j<16; ++j)
				Registers_tmp[r][j] = Registers[r][j];

		for (unsigned r = 0; r<4; ++r)//Register loop
		{
			for (unsigned i = 0; i<4; ++i)//Column loop
			{
				unsigned char r_out = Shuffle[4 * r + i] / 4;  //Register index
				unsigned char c_out = Shuffle[4 * r + i] % 4;  //Column index
				for (unsigned j = 0; j<4; ++j)
					Registers[r_out][4 * c_out + j] = Registers_tmp[r][4 * i + j];
			}
		}


	}
	for (unsigned i = 0; i<4; ++i)//Filling registers
	{
		for (unsigned j = 0; j<16; ++j)
			output[16 * i + j] = Registers[i][j];
	}

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
leaq 0x10(%rsp), %rax
xorl %ecx, %ecx
cmpq $0x4, %rcx
je 0x1304
xorl %edx, %edx
cmpq $0x10, %rdx
je 0x12f7
movb (%rdi,%rdx), %r8b
movb %r8b, (%rax,%rdx)
incq %rdx
jmp 0x12e4
incq %rcx
addq $0x10, %rdi
addq $0x10, %rax
jmp 0x12dc
movq %rsi, (%rsp)
xorl %eax, %eax
leaq 0x10(%rsp), %r13
movq 0x3cc2(%rip), %rbp      # 0x4fd8
cmpl $0xa, %eax
je 0x141b
movq %rax, 0x8(%rsp)
leal (,%rax,8), %r12d
xorl %r15d, %r15d
cmpq $0x4, %r15
je 0x137b
movq %r15, %rax
shlq $0x4, %rax
leaq (%rsp,%rax), %r14
addq $0x10, %r14
xorl %ebx, %ebx
cmpl $0x2, %ebx
je 0x1372
movq %r14, %rdi
callq 0x10d0
leal (%r12,%rbx,4), %eax
orl %r15d, %eax
incb %al
xorl %ecx, %ecx
cmpq $0x4, %rcx
je 0x136e
xorb %al, (%r13,%rcx,4)
incq %rcx
jmp 0x135e
incl %ebx
jmp 0x1346
incq %r15
addq $0x10, %r13
jmp 0x132f
leaq 0x50(%rsp), %r8
movq %r8, %rax
leaq 0x10(%rsp), %r13
movq %r13, %rcx
xorl %edx, %edx
cmpq $0x4, %rdx
je 0x13b5
xorl %esi, %esi
cmpq $0x10, %rsi
je 0x13a8
movb (%rcx,%rsi), %dil
movb %dil, (%rax,%rsi)
incq %rsi
jmp 0x1395
incq %rdx
addq $0x10, %rcx
addq $0x10, %rax
jmp 0x138d
movq %r8, %rax
xorl %ecx, %ecx
cmpq $0x4, %rcx
je 0x140f
leaq (,%rcx,4), %rdx
movq %rax, %rsi
xorl %edi, %edi
cmpq $0x4, %rdi
je 0x1406
movq %rdi, %r8
orq %rdx, %r8
movzbl (%rbp,%r8), %r8d
leaq (%rsp,%r8,4), %r8
addq $0x10, %r8
xorl %r9d, %r9d
cmpq $0x4, %r9
je 0x13fd
movb (%rsi,%r9), %r10b
movb %r10b, (%r8,%r9)
incq %r9
jmp 0x13ea
incq %rdi
addq $0x4, %rsi
jmp 0x13cd
incq %rcx
addq $0x10, %rax
jmp 0x13ba
movq 0x8(%rsp), %rax
incl %eax
jmp 0x1316
leaq 0x10(%rsp), %rax
xorl %ecx, %ecx
movq (%rsp), %rdi
cmpq $0x4, %rcx
je 0x144e
xorl %edx, %edx
cmpq $0x10, %rdx
je 0x1441
movb (%rax,%rdx), %sil
movb %sil, (%rdi,%rdx)
incq %rdx
jmp 0x142e
incq %rcx
addq $0x10, %rdi
addq $0x10, %rax
jmp 0x1426
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq