// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/paeq160/ref/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;
					//printf("Constant for acc%d: %d\n",r,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 0x12d4
xorl %edx, %edx
cmpq $0x10, %rdx
je 0x12c7
movb (%rdi,%rdx), %r8b
movb %r8b, (%rax,%rdx)
incq %rdx
jmp 0x12b4
incq %rcx
addq $0x10, %rdi
addq $0x10, %rax
jmp 0x12ac
movq %rsi, (%rsp)
xorl %eax, %eax
leaq 0x10(%rsp), %r13
movq 0x3cf2(%rip), %rbp      # 0x4fd8
cmpl $0xa, %eax
je 0x13eb
movq %rax, 0x8(%rsp)
leal (,%rax,8), %r12d
xorl %r15d, %r15d
cmpq $0x4, %r15
je 0x134b
movq %r15, %rax
shlq $0x4, %rax
leaq (%rsp,%rax), %r14
addq $0x10, %r14
xorl %ebx, %ebx
cmpl $0x2, %ebx
je 0x1342
movq %r14, %rdi
callq 0x10a0
leal (%r12,%rbx,4), %eax
orl %r15d, %eax
incb %al
xorl %ecx, %ecx
cmpq $0x4, %rcx
je 0x133e
xorb %al, (%r13,%rcx,4)
incq %rcx
jmp 0x132e
incl %ebx
jmp 0x1316
incq %r15
addq $0x10, %r13
jmp 0x12ff
leaq 0x50(%rsp), %r8
movq %r8, %rax
leaq 0x10(%rsp), %r13
movq %r13, %rcx
xorl %edx, %edx
cmpq $0x4, %rdx
je 0x1385
xorl %esi, %esi
cmpq $0x10, %rsi
je 0x1378
movb (%rcx,%rsi), %dil
movb %dil, (%rax,%rsi)
incq %rsi
jmp 0x1365
incq %rdx
addq $0x10, %rcx
addq $0x10, %rax
jmp 0x135d
movq %r8, %rax
xorl %ecx, %ecx
cmpq $0x4, %rcx
je 0x13df
leaq (,%rcx,4), %rdx
movq %rax, %rsi
xorl %edi, %edi
cmpq $0x4, %rdi
je 0x13d6
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 0x13cd
movb (%rsi,%r9), %r10b
movb %r10b, (%r8,%r9)
incq %r9
jmp 0x13ba
incq %rdi
addq $0x4, %rsi
jmp 0x139d
incq %rcx
addq $0x10, %rax
jmp 0x138a
movq 0x8(%rsp), %rax
incl %eax
jmp 0x12e6
leaq 0x10(%rsp), %rax
xorl %ecx, %ecx
movq (%rsp), %rdi
cmpq $0x4, %rcx
je 0x141e
xorl %edx, %edx
cmpq $0x10, %rdx
je 0x1411
movb (%rax,%rdx), %sil
movb %sil, (%rdi,%rdx)
incq %rdx
jmp 0x13fe
incq %rcx
addq $0x10, %rdi
addq $0x10, %rax
jmp 0x13f6
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq