// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/aes128n8t8clocv2/ref/cloc.c
// Function: process_ad
int process_ad(ae_cxt* cxt, const byte* ad, unsigned long long adlen, const byte* nonce, unsigned long long nlen)
{
	byte* state = cxt->es;
	AES_KEY *ekey = cxt->pt_ekey;

	cxt->ad = (byte*) ad;
	cxt->adlen = adlen;
	cxt->nonce = (byte*) nonce;
	cxt->nlen = nlen;
	/* process the first block */
	int ozp = 0;
	if(adlen < STATE_LEN){       // less than one block
		memcpy(state, ad, adlen);
		memset(state+adlen, 0, STATE_LEN-adlen);
		state[adlen] = 0x80;
		ozp = 1;                // one-zero padding works only if the adlen < 16
	}
	else{                       // full first block
		memcpy(state, ad, STATE_LEN);
	}

	/* apply fix0 and the E_k */
	int fix0 = state[0] & 0x80;    /* test if the MSB is zero */
	state[0] &= 0x7f;

	/* apply the first encryption */
	AES_encrypt(state, state, ekey);
	/* when fix0 works, apply h */
	if(fix0){
		u32* wd = (u32*) state;
        pstate2("h: ", state, STATE_LEN);
		h(wd[0], wd[1], wd[2], wd[3]);
        pstate2("", state, STATE_LEN);
	}
	else{
        // do nothing
	}

	/* process the middle normal blocks of ad */
	unsigned long long i;
	for(i = 1; i < (unsigned long long)adlen/STATE_LEN; i++){
		xor_block((block*)state, (block*)ad+i);
		AES_encrypt(state, state, ekey);
	}
	/* process the last block partial block if any */
	unsigned long long lastblocklen = adlen % STATE_LEN;
	if((adlen > STATE_LEN) && lastblocklen){
		xor_bytes(state, ad+i*STATE_LEN, lastblocklen);
		state[lastblocklen] ^= 0x80;
		AES_encrypt(state, state, ekey);
		ozp = 1;
	}

	/* process the nonce 
	 * 1. first byte is: PARAM
	 * 2. then the nonce value
	 * 3. padding if any (at the moment, the parameter set contains padding for all choices)
	 */
	state[0] ^= PARAM;
	xor_bytes(state+1, nonce, nlen);

	/* apply padding to nonce */
	if((nlen+1) != STATE_LEN)
		state[nlen+1] ^= 0x80;

	/* apply f1 or f2 to get V */
	if(ozp){ // apply f2
		u32* wd = (u32*) state;
        pstate2("f2: ", state, STATE_LEN);
		f2(wd[0], wd[1], wd[2], wd[3]);
        pstate2("", state, STATE_LEN);
	}
	else{ // apply f1
		u32* wd = (u32*) state;
        pstate2("f1: ", state, STATE_LEN);
		f1(wd[0], wd[1], wd[2], wd[3]);
        pstate2("", state, STATE_LEN);
	}

	memcpy(cxt->ts, state, STATE_LEN);
	AES_encrypt(state, state, ekey);

	return SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %r12
movq %rsi, %rbp
movq %rdi, %r14
movq 0x118(%rdi), %rbx
movq %rsi, 0x130(%rdi)
movq %rdx, 0x138(%rdi)
movq %rcx, 0x8(%rsp)
movq %rcx, 0x140(%rdi)
movq %r8, 0x148(%rdi)
cmpq $0xf, %rdx
movq %r8, 0x10(%rsp)
ja 0x30fd
movq %r14, %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq 0x10e0
leaq (%r14,%r12), %rdi
pushq $0x10
popq %rdx
subq %r12, %rdx
xorl %esi, %esi
callq 0x1040
movb $-0x80, (%r14,%r12)
pushq $0x1
popq %rax
jmp 0x3109
vmovups (%rbp), %xmm0
vmovups %xmm0, (%r14)
xorl %eax, %eax
movl %eax, 0x4(%rsp)
movb (%r14), %r15b
movl %r15d, %eax
andb $0x7f, %al
movb %al, (%r14)
movq %r14, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x1070
testb %r15b, %r15b
jns 0x3179
leaq 0x3706(%rip), %rdi      # 0x6838
pushq $0x10
popq %r15
movq %r14, %rsi
movl %r15d, %edx
callq 0x10f0
movl 0x4(%r14), %eax
movl 0x8(%r14), %ecx
movl (%r14), %edx
xorl %eax, %edx
movl %edx, (%r14)
xorl %ecx, %eax
movl %eax, 0x4(%r14)
movl 0xc(%r14), %eax
xorl %eax, %ecx
movl %ecx, 0x8(%r14)
xorl %eax, %edx
movl %edx, 0xc(%r14)
leaq 0x3775(%rip), %rdi      # 0x68e3
movq %r14, %rsi
movl %r15d, %edx
callq 0x10f0
movq %r12, %r13
shrq $0x4, %r13
addq $0x10, %rbp
pushq $0x1
popq %r15
cmpq %r13, %r15
jae 0x31af
movq %r14, %rdi
movq %rbp, %rsi
callq 0x10c0
movq %r14, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x1070
incq %r15
addq $0x10, %rbp
jmp 0x3188
cmpq $0x11, %r12
setb %al
andq $0xf, %r12
sete %cl
orb %al, %cl
movl 0x4(%rsp), %r13d
jne 0x31eb
movq %r14, %rdi
movq %rbp, %rsi
movl %r12d, %edx
callq 0x10d0
xorb $-0x80, (%r14,%r12)
movq %r14, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x1070
pushq $0x1
popq %r13
xorb $-0x30, (%r14)
leaq 0x1(%r14), %rdi
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %r15
movl %r15d, %edx
callq 0x10d0
incq %r15
cmpq $0x10, %r15
je 0x3213
xorb $-0x80, (%r14,%r15)
testl %r13d, %r13d
je 0x3244
leaq 0x361d(%rip), %rdi      # 0x683c
pushq $0x10
popq %rdx
movq %r14, %rsi
callq 0x10f0
movq 0x4(%r14), %rax
movl (%r14), %ecx
xorl %eax, %ecx
movq %rax, (%r14)
movl 0xc(%r14), %eax
movl %eax, 0x8(%r14)
movl %ecx, 0xc(%r14)
jmp 0x327c
leaq 0x35f6(%rip), %rdi      # 0x6841
pushq $0x10
popq %rdx
movq %r14, %rsi
callq 0x10f0
movl 0x4(%r14), %eax
movl 0x8(%r14), %ecx
movl (%r14), %edx
xorl %ecx, %edx
movl %edx, (%r14)
movl 0xc(%r14), %esi
xorl %eax, %esi
movl %esi, 0x4(%r14)
xorl %ecx, %esi
movl %esi, 0xc(%r14)
xorl %eax, %edx
movl %edx, 0x8(%r14)
leaq 0x3660(%rip), %rdi      # 0x68e3
pushq $0x10
popq %rdx
movq %r14, %rsi
callq 0x10f0
vmovups (%r14), %xmm0
vmovups %xmm0, 0x10(%r14)
movq %r14, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x1070
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq