// File: /workspace/github_c_makefile_star2_O3/mjosaarinen[P]brutus/crypto_aead/aes256otrpv3/ni_p8m1/encrypt.c
// Function: AFunc
__m128i AFunc(
	const uint8 *header,
	uint32 h_len)
{
	uint32 i;
	uint32 m, last;
	block tmp[PIPE], mask[PIPE + 1], ASum = _mm_setzero_si128();
	uint32 rest_len = h_len;
	const __m128i *hdp = (__m128i*)header;

	mask[0] = _mm_load_si128(&Q);
	while (rest_len > (BLOCK*PIPE)){
		mul2_PIPE(mask);
		for (i = 0; i < PIPE; i++){
			tmp[i] = _mm_xor_si128(mask[i], hdp[i]);
		}
		AES_ecb_encrypt_PIPE(tmp, encrypt_key);
		for (i = 0; i < PIPE; i++){
			ASum = _mm_xor_si128(ASum, tmp[i]);
		}
		rest_len -= (BLOCK*PIPE);
		hdp += PIPE;
		mask[0] = _mm_load_si128(&mask[PIPE]);
	}

	last = rest_len % BLOCK;
	if (last == 0) last = BLOCK;
	m = (rest_len - last) / BLOCK; //header = m blocks + last bytes

	for (i = 0; i < m; i++){
		tmp[0] = _mm_xor_si128(mask[0], hdp[i]);
		AES_encrypt(tmp[0], &tmp[0], encrypt_key);
		ASum = _mm_xor_si128(ASum, tmp[0]);
		mul2(mask[0], &mask[0]);
	}
	hdp += m;
	/* last block */
	ozp(last, (uint8*)&hdp[0], &tmp[0]);
	ASum = _mm_xor_si128(ASum, tmp[0]);
	if (last != BLOCK){
		mul3(mask[0], &mask[0]);
	}
	else{
		mul3twice(mask[0], &mask[0]);
	}
	ASum = _mm_xor_si128(ASum, mask[0]);
	AES_encrypt(ASum, &ASum, encrypt_key);
	return ASum; //TA
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x150, %rsp            # imm = 0x150
movq %rdi, %rax
movq 0x58a7(%rip), %rcx      # 0x7fe0
vmovdqa64 (%rcx), %xmm18
vmovdqa64 %xmm18, 0xc0(%rsp)
cmpl $0x81, %esi
jb 0x29f0
movq 0x5896(%rip), %rcx      # 0x7ff0
vmovdqa (%rcx), %xmm0
vmovdqa 0xe0(%rcx), %xmm1
vpxord %xmm20, %xmm20, %xmm20
vmovdqa 0x188c(%rip), %xmm2     # 0x4000
movq 0x586d(%rip), %rdx      # 0x7fe8
movq 0x5876(%rip), %rdi      # 0x7ff8
vmovdqa 0x1886(%rip), %xmm3     # 0x4010
vmovdqa 0x188e(%rip), %xmm4     # 0x4020
vmovdqa 0x1896(%rip), %xmm5     # 0x4030
vmovdqa 0x189e(%rip), %xmm6     # 0x4040
vpextrb $0x0, %xmm18, %r8d
vpextrb $0x8, %xmm18, %r9d
shll $0x4, %r8d
vmovdqa (%rdx,%r8), %xmm7
vpshufb %xmm2, %xmm18, %xmm8
shll $0x4, %r9d
vmovdqa (%rdi,%r9), %xmm9
vpunpcklqdq %xmm9, %xmm7, %xmm10 # xmm10 = xmm7[0],xmm9[0]
vpunpckhqdq %xmm9, %xmm7, %xmm7 # xmm7 = xmm7[1],xmm9[1]
vpaddq %xmm8, %xmm8, %xmm9
vpshufb %xmm3, %xmm10, %xmm11
vpshufb %xmm2, %xmm9, %xmm9
vpxor %xmm9, %xmm11, %xmm9
vmovdqa %xmm9, 0xd0(%rsp)
vpsllq $0x2, %xmm8, %xmm9
vpshufb %xmm4, %xmm10, %xmm11
vpshufb %xmm2, %xmm9, %xmm9
vpxor %xmm9, %xmm11, %xmm9
vmovdqa %xmm9, 0xe0(%rsp)
vpsllq $0x3, %xmm8, %xmm9
vpshufb %xmm5, %xmm10, %xmm11
vpshufb %xmm2, %xmm9, %xmm9
vpxor %xmm9, %xmm11, %xmm9
vmovdqa %xmm9, 0xf0(%rsp)
vpsllq $0x4, %xmm8, %xmm9
vpshufb %xmm6, %xmm10, %xmm10
vpshufb %xmm2, %xmm9, %xmm9
vpxor %xmm9, %xmm10, %xmm9
vmovdqa %xmm9, 0x100(%rsp)
vpsllq $0x5, %xmm8, %xmm9
vpshufb %xmm3, %xmm7, %xmm10
vpshufb %xmm2, %xmm9, %xmm9
vpxor %xmm9, %xmm10, %xmm9
vmovdqa %xmm9, 0x110(%rsp)
vpsllq $0x6, %xmm8, %xmm9
vpshufb %xmm4, %xmm7, %xmm10
vpshufb %xmm2, %xmm9, %xmm9
vpxor %xmm9, %xmm10, %xmm9
vmovdqa %xmm9, 0x120(%rsp)
vpsllq $0x7, %xmm8, %xmm8
vpshufb %xmm5, %xmm7, %xmm9
vpshufb %xmm2, %xmm8, %xmm8
vpxor %xmm8, %xmm9, %xmm8
vmovdqa %xmm8, 0x130(%rsp)
vpshufb %xmm6, %xmm7, %xmm7
vpsrlq $0x8, %xmm18, %xmm8
vpxorq %xmm8, %xmm7, %xmm18
vmovdqa64 %xmm18, 0x140(%rsp)
xorl %r8d, %r8d
vmovdqa (%rax,%r8), %xmm7
vpxor 0xc0(%rsp,%r8), %xmm7, %xmm7
vmovdqa %xmm7, 0x20(%rsp,%r8)
addq $0x10, %r8
cmpq $0x80, %r8
jne 0x28c2
vpxor 0x20(%rsp), %xmm0, %xmm14
vpxor 0x30(%rsp), %xmm0, %xmm13
vpxor 0x40(%rsp), %xmm0, %xmm12
vpxor 0x50(%rsp), %xmm0, %xmm11
vpxor 0x60(%rsp), %xmm0, %xmm10
vpxor 0x70(%rsp), %xmm0, %xmm9
vpxor 0x80(%rsp), %xmm0, %xmm8
vpxor 0x90(%rsp), %xmm0, %xmm7
movl $0x10, %r8d
vmovdqa (%rcx,%r8), %xmm15
vaesenc %xmm15, %xmm14, %xmm14
vaesenc %xmm15, %xmm13, %xmm13
vaesenc %xmm15, %xmm12, %xmm12
vaesenc %xmm15, %xmm11, %xmm11
vaesenc %xmm15, %xmm10, %xmm10
vaesenc %xmm15, %xmm9, %xmm9
vaesenc %xmm15, %xmm8, %xmm8
vaesenc %xmm15, %xmm7, %xmm7
addq $0x10, %r8
cmpq $0xe0, %r8
jne 0x2922
vaesenclast %xmm1, %xmm14, %xmm14
vmovdqa %xmm14, 0x20(%rsp)
vaesenclast %xmm1, %xmm13, %xmm13
vmovdqa %xmm13, 0x30(%rsp)
vaesenclast %xmm1, %xmm12, %xmm12
vmovdqa %xmm12, 0x40(%rsp)
vaesenclast %xmm1, %xmm11, %xmm11
vmovdqa %xmm11, 0x50(%rsp)
vaesenclast %xmm1, %xmm10, %xmm10
vmovdqa %xmm10, 0x60(%rsp)
vaesenclast %xmm1, %xmm9, %xmm9
vmovdqa %xmm9, 0x70(%rsp)
vaesenclast %xmm1, %xmm8, %xmm8
vmovdqa %xmm8, 0x80(%rsp)
vaesenclast %xmm1, %xmm7, %xmm7
vmovdqa %xmm7, 0x90(%rsp)
xorl %r8d, %r8d
vpxorq 0x20(%rsp,%r8), %xmm20, %xmm20
addq $0x10, %r8
cmpq $0x80, %r8
jne 0x29be
addl $-0x80, %esi
subq $-0x80, %rax
vmovdqa64 %xmm18, 0xc0(%rsp)
cmpl $0x80, %esi
ja 0x27a2
jmp 0x29f6
vpxord %xmm20, %xmm20, %xmm20
movl %esi, %ebp
andl $0xf, %ebp
movl $0x10, %ecx
cmovnel %ebp, %ecx
subl %ecx, %esi
movl %esi, %edx
shrl $0x4, %edx
cmpl $0x10, %esi
jb 0x2b34
movq 0x55d6(%rip), %rsi      # 0x7ff0
vmovdqa64 (%rsi), %xmm17
vmovdqa 0x10(%rsi), %xmm1
vmovdqa 0x20(%rsi), %xmm2
vmovdqa 0x30(%rsi), %xmm3
vmovdqa 0x40(%rsi), %xmm4
vmovdqa 0x50(%rsi), %xmm5
vmovdqa 0x60(%rsi), %xmm6
vmovdqa 0x70(%rsi), %xmm7
vmovdqa 0x80(%rsi), %xmm8
vmovdqa 0x90(%rsi), %xmm9
vmovdqa 0xa0(%rsi), %xmm10
vmovdqa 0xb0(%rsi), %xmm11
vmovdqa 0xc0(%rsi), %xmm12
vmovdqa 0xd0(%rsi), %xmm13
vmovdqa 0xe0(%rsi), %xmm14
cmpl $0x1, %edx
movl %edx, %esi
adcl $0x0, %esi
shll $0x4, %esi
xorl %edi, %edi
vmovdqa 0x1570(%rip), %xmm15    # 0x4000
vpmovzxbd 0x15e6(%rip), %xmm16 # 0x4080
vmovdqa (%rax,%rdi), %xmm0
vpternlogq $0x96, %xmm18, %xmm17, %xmm0
vaesenc %xmm1, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm3, %xmm0, %xmm0
vaesenc %xmm4, %xmm0, %xmm0
vaesenc %xmm5, %xmm0, %xmm0
vaesenc %xmm6, %xmm0, %xmm0
vaesenc %xmm7, %xmm0, %xmm0
vaesenc %xmm8, %xmm0, %xmm0
vaesenc %xmm9, %xmm0, %xmm0
vaesenc %xmm10, %xmm0, %xmm0
vaesenc %xmm11, %xmm0, %xmm0
vaesenc %xmm12, %xmm0, %xmm0
vaesenc %xmm13, %xmm0, %xmm0
vaesenclast %xmm14, %xmm0, %xmm0
vmovdqa %xmm0, 0x20(%rsp)
vpshufb %xmm15, %xmm18, %xmm18
vpshufd $0x93, %xmm18, %xmm19   # xmm19 = xmm18[3,0,1,2]
vpsrad $0x1f, %xmm19, %xmm19
vpaddd %xmm18, %xmm18, %xmm18
vpxorq %xmm20, %xmm0, %xmm20
vpternlogd $0x78, %xmm16, %xmm19, %xmm18
vpshufb %xmm15, %xmm18, %xmm18
vmovdqa64 %xmm18, 0xc0(%rsp)
addq $0x10, %rdi
cmpq %rdi, %rsi
jne 0x2a9a
vmovdqa64 %xmm18, (%rsp)
vmovdqa64 %xmm20, 0x10(%rsp)
shll $0x4, %edx
addq %rdx, %rax
vpxor %xmm0, %xmm0, %xmm0
leaq 0xa0(%rsp), %rbx
vmovdqa %xmm0, (%rbx)
movb $0x0, 0x10(%rbx)
movl %ecx, %r14d
movq %rbx, %rdi
movq %rax, %rsi
movq %r14, %rdx
callq 0x10a0
movb $-0x80, 0xa0(%rsp,%r14)
vmovdqa (%rbx), %xmm0
vmovdqa 0x147d(%rip), %xmm1     # 0x4000
testl %ebp, %ebp
je 0x2bb5
vmovdqa (%rsp), %xmm2
vpshufb %xmm1, %xmm2, %xmm2
vpshufd $0x93, %xmm2, %xmm3     # xmm3 = xmm2[3,0,1,2]
vpsrad $0x1f, %xmm3, %xmm3
vpand 0x14ad(%rip), %xmm3, %xmm3 # 0x4050
vpaddd %xmm2, %xmm2, %xmm4
vpternlogq $0x96, %xmm3, %xmm2, %xmm4
vpshufb %xmm1, %xmm4, %xmm1
jmp 0x2bfb
vmovdqa (%rsp), %xmm5
vpshufb %xmm1, %xmm5, %xmm2
vpshufd $0x93, %xmm2, %xmm3     # xmm3 = xmm2[3,0,1,2]
vpsrad $0x1f, %xmm3, %xmm3
vpshufd $0x93, 0x148e(%rip), %xmm4 # xmm4 = mem[3,0,1,2]
vpaddd %xmm2, %xmm2, %xmm2
vpternlogd $0x6c, %xmm4, %xmm2, %xmm3
vpshufd $0x93, %xmm2, %xmm2     # xmm2 = xmm2[3,0,1,2]
vpsrad $0x1f, %xmm2, %xmm2
vpaddd %xmm3, %xmm3, %xmm3
vpternlogd $0x78, %xmm4, %xmm2, %xmm3
vpshufb %xmm1, %xmm3, %xmm1
vpxor %xmm5, %xmm1, %xmm1
vmovdqa 0x10(%rsp), %xmm2
vpxor %xmm1, %xmm2, %xmm1
movq 0x53e4(%rip), %rax      # 0x7ff0
vpternlogq $0x96, (%rax), %xmm1, %xmm0
vaesenc 0x10(%rax), %xmm0, %xmm0
vaesenc 0x20(%rax), %xmm0, %xmm0
vaesenc 0x30(%rax), %xmm0, %xmm0
vaesenc 0x40(%rax), %xmm0, %xmm0
vaesenc 0x50(%rax), %xmm0, %xmm0
vaesenc 0x60(%rax), %xmm0, %xmm0
vaesenc 0x70(%rax), %xmm0, %xmm0
vaesenc 0x80(%rax), %xmm0, %xmm0
vaesenc 0x90(%rax), %xmm0, %xmm0
vaesenc 0xa0(%rax), %xmm0, %xmm0
vaesenc 0xb0(%rax), %xmm0, %xmm0
vaesenc 0xc0(%rax), %xmm0, %xmm0
vaesenc 0xd0(%rax), %xmm0, %xmm0
vaesenclast 0xe0(%rax), %xmm0, %xmm0
addq $0x150, %rsp            # imm = 0x150
popq %rbx
popq %r14
popq %rbp
retq