// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/acorn128v2/opt/encrypt.c
// Function: encrypt_32bits
void encrypt_32bits(unsigned long long *state, unsigned int plaintextword, unsigned int *ciphertextword, unsigned int *ks, unsigned int ca, unsigned int cb)
{
    unsigned long long f;
    unsigned long long word_244, word_23, word_160, word_111, word_66, word_196, word_0, word_107, word_230;
    unsigned long long word_12,word_154,word_235,word_61,word_193;


	word_235 = state[5] >> 5;
	word_196 = state[4] >> 3;
	word_160 = state[3] >> 6;
	word_111 = state[2] >> 4;
	word_66  = state[1] >> 5;
	word_23  = state[0] >> 23;
    word_244 = state[5] >> 14;
	word_12  = state[0] >> 12;

    //update using those 6 LFSRs
	state[6] ^= (state[5] ^ word_235) & 0xffffffff;
	state[5] ^= (state[4] ^ word_196) & 0xffffffff;
	state[4] ^= (state[3] ^ word_160) & 0xffffffff;
	state[3] ^= (state[2] ^ word_111) & 0xffffffff;
	state[2] ^= (state[1] ^ word_66)  & 0xffffffff;
	state[1] ^= (state[0] ^ word_23)  & 0xffffffff;

	/*
    word_0   = state[0];
    word_107 = state[2];
    word_230 = state[5];
    word_154 = state[3];
    word_61  = state[1];
    word_193 = state[4];
    */

	//compute keystream
	*ks = word_12 ^ state[3] ^ maj(word_235, state[1], state[4]);

    //f  = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ (ca & state[196]) ^ (cb & (*ks));
	f = state[0] ^ (state[2] ^ 0xffffffff) ^ maj(word_244, word_23, word_160) ^ ch32(state[5], word_111, word_66) ^ (word_196 & ca) ^ (cb & *ks);
    *ciphertextword = plaintextword ^ *ks;
	f = (f ^ plaintextword) & 0xffffffff;
	state[6] = state[6] ^ (f << 4);

    //shift by 32 bits
    state[0] = (state[0] >> 32) | ((state[1] & 0xffffffff) << 29);  //32-(64-61) = 29
    state[1] = (state[1] >> 32) | ((state[2] & 0xffffffff) << 14);  //32-(64-46) = 14
    state[2] = (state[2] >> 32) | ((state[3] & 0xffffffff) << 15);  //32-(64-47) = 15
    state[3] = (state[3] >> 32) | ((state[4] & 0xffffffff) << 7);   //32-(64-39) = 7
    state[4] = (state[4] >> 32) | ((state[5] & 0xffffffff) << 5);   //32-(64-37) = 5
    state[5] = (state[5] >> 32) | ((state[6] & 0xffffffff) << 27);  //32-(64-59) = 27
    state[6] =  state[6] >> 32;

    //perform encryption

    return;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
vmovdqu (%rdi), %ymm0
vpsrlvq 0xe53(%rip), %ymm0, %ymm2 # 0x2000
movq (%rdi), %rax
movq %rax, %r10
shrq $0xc, %r10
vpxor %ymm0, %ymm2, %ymm1
vpxor %xmm3, %xmm3, %xmm3
vpblendd $0xaa, %ymm3, %ymm1, %ymm3 # ymm3 = ymm1[0],ymm3[1],ymm1[2],ymm3[3],ymm1[4],ymm3[5],ymm1[6],ymm3[7]
vmovdqu 0x20(%rdi), %xmm1
valignq $0x1, %ymm0, %ymm1, %ymm4 # ymm4 = ymm0[1,2,3],ymm1[0]
vpxor %ymm4, %ymm3, %ymm3
vmovq %xmm3, %r11
vextracti128 $0x1, %ymm3, %xmm4
vpextrq $0x1, %xmm4, %rbx
movl %r11d, %ebp
xorl %ebx, %ebp
andl %ebx, %r11d
movq 0x28(%rdi), %rbx
xorl %r11d, %r10d
movq %rbx, %r11
shrq $0x5, %r11
andl %r11d, %ebp
xorl %ebx, %r11d
xorq 0x30(%rdi), %r11
xorl %ebp, %r10d
vmovq %xmm4, %r14
xorl %r10d, %r14d
movq 0x20(%rdi), %r10
movl %r14d, (%rcx)
vmovq %xmm2, %rcx
vextracti128 $0x1, %ymm2, %xmm4
andl %r14d, %r9d
xorl %esi, %r14d
movl %r14d, (%rdx)
vpextrq $0x1, %xmm4, %rdx
movl %ecx, %ebp
xorl %edx, %ebp
andl %edx, %ecx
movq %r10, %rdx
shrq $0x3, %rdx
xorl %edx, %r10d
andl %edx, %r8d
xorl %ecx, %r8d
vmovq %xmm4, %rcx
xorq %rbx, %r10
shrq $0xe, %rbx
andl %ebp, %ebx
vpextrq $0x1, %xmm2, %rdx
andl %r10d, %ecx
andnl %edx, %r10d, %edx
orl %ecx, %edx
xorl %r8d, %edx
vpextrq $0x1, %xmm3, %rcx
xorl %ebx, %ecx
xorl %edx, %ecx
xorl %ecx, %eax
xorl %esi, %eax
xorl %r9d, %eax
notl %eax
shlq $0x4, %rax
xorq %r11, %rax
vpsrlq $0x20, %ymm0, %ymm0
vpsllvq 0xd8f(%rip), %ymm3, %ymm2 # 0x2020
vpternlogq $0xec, 0xda4(%rip), %ymm0, %ymm2 # 0x2040
vmovdqu %ymm2, (%rdi)
vmovq %r10, %xmm0
vpsrlq $0x20, %xmm1, %xmm1
vmovq %rax, %xmm2
vpunpcklqdq %xmm2, %xmm0, %xmm0 # xmm0 = xmm0[0],xmm2[0]
vpsllvq 0xe04(%rip), %xmm0, %xmm0 # 0x20c0
vpternlogq $0xec, 0xe09(%rip), %xmm1, %xmm0 # 0x20d0
vmovdqu %xmm0, 0x20(%rdi)
shrq $0x20, %rax
movq %rax, 0x30(%rdi)
popq %rbx
popq %r14
popq %rbp
vzeroupper
retq