// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/twine80n6t4clocv2/ref/twine.c
// Function: Decode
void Decode(uint8 cipher[8], uint8 text[8])
{
	uint8	i, tmp;
	uint8	data1[16];

	//Set ciphertext
	data1[0] = cipher[0]>>4;
	data1[1] = cipher[0]&0xf;
	data1[2] = cipher[1]>>4;
	data1[3] = cipher[1]&0xf;
	data1[4] = cipher[2]>>4;
	data1[5] = cipher[2]&0xf;
	data1[6] = cipher[3]>>4;
	data1[7] = cipher[3]&0xf;
	data1[8] = cipher[4]>>4;
	data1[9] = cipher[4]&0xf;
	data1[10] = cipher[5]>>4;
	data1[11] = cipher[5]&0xf;
	data1[12] = cipher[6]>>4;
	data1[13] = cipher[6]&0xf;
	data1[14] = cipher[7]>>4;
	data1[15] = cipher[7]&0xf;

	//Round functions
	for(i=ROUND-1; ; i--)
	{
		data1[1] ^= S[data1[0] ^ ek[i][0]];
		data1[3] ^= S[data1[2] ^ ek[i][1]];
		data1[5] ^= S[data1[4] ^ ek[i][2]];
		data1[7] ^= S[data1[6] ^ ek[i][3]];
		data1[9] ^= S[data1[8] ^ ek[i][4]];
		data1[11] ^= S[data1[10] ^ ek[i][5]];
		data1[13] ^= S[data1[12] ^ ek[i][6]];
		data1[15] ^= S[data1[14] ^ ek[i][7]];

		i--;
		data1[0] ^= S[data1[5] ^ ek[i][0]];
		data1[4] ^= S[data1[1] ^ ek[i][1]];
		data1[12] ^= S[data1[7] ^ ek[i][2]];
		data1[8] ^= S[data1[3] ^ ek[i][3]];
		data1[6] ^= S[data1[13] ^ ek[i][4]];
		data1[2] ^= S[data1[9] ^ ek[i][5]];
		data1[10] ^= S[data1[15] ^ ek[i][6]];
		data1[14] ^= S[data1[11] ^ ek[i][7]];

		if(i == 0)
			break;

		tmp = data1[1];
		data1[1] = data1[5];
		data1[5] = data1[15];
		data1[15] = data1[11];
		data1[11] = tmp;

		tmp = data1[3];
		data1[3] = data1[7];
		data1[7] = data1[13];
		data1[13] = data1[9];
		data1[9] = tmp;

		tmp = data1[0];
		data1[0] = data1[12];
		data1[12] = data1[14];
		data1[14] = data1[2];
		data1[2] = tmp;

		tmp = data1[4];
		data1[4] = data1[8];
		data1[8] = data1[10];
		data1[10] = data1[6];
		data1[6] = tmp;
    
	}

	//Set plaintext
	text[0] = (data1[5]<<4) ^ data1[0];
	text[1] = (data1[1]<<4) ^ data1[4];
	text[2] = (data1[7]<<4) ^ data1[12];
	text[3] = (data1[3]<<4) ^ data1[8];
	text[4] = (data1[13]<<4) ^ data1[6];
	text[5] = (data1[9]<<4) ^ data1[2];
	text[6] = (data1[15]<<4) ^ data1[10];
	text[7] = (data1[11]<<4) ^ data1[14];
#ifdef _PRINT
	printf("Twine (decode) output: ");
	pstate(text, 8);
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
vmovq (%rdi), %xmm1
vpsrlw $0x4, %xmm1, %xmm0
vpshufb 0x13e1(%rip), %xmm0, %xmm0 # 0x30a0
vpbroadcastb 0x1359(%rip), %xmm2 # 0x3021
vpand %xmm2, %xmm0, %xmm0
vpshufb 0x13db(%rip), %xmm1, %xmm1 # 0x30b0
vpand %xmm2, %xmm1, %xmm3
movl $0x120, %eax            # imm = 0x120
movq 0x32eb(%rip), %rcx      # 0x4fd0
movq 0x3304(%rip), %rdx      # 0x4ff0
vmovq 0x13cc(%rip), %xmm1     # 0x30c0
vmovq 0x13d4(%rip), %xmm2     # 0x30d0
vpextrb $0x2, %xmm0, %edi
xorb -0x8(%rcx,%rax), %dil
movzbl %dil, %edi
vmovd %xmm0, %r8d
xorb -0x7(%rcx,%rax), %r8b
movzbl %r8b, %r8d
vpextrb $0x3, %xmm0, %r9d
xorb -0x6(%rcx,%rax), %r9b
movzbl %r9b, %r9d
vpextrb $0x1, %xmm0, %r10d
xorb -0x5(%rcx,%rax), %r10b
vpextrb $0x6, %xmm0, %r11d
movzbl %r10b, %r10d
xorb -0x4(%rcx,%rax), %r11b
movzbl %r11b, %r11d
vpextrb $0x4, %xmm0, %ebx
xorb -0x3(%rcx,%rax), %bl
vpextrb $0x7, %xmm0, %ebp
xorb -0x2(%rcx,%rax), %bpl
movzbl %bl, %ebx
movzbl %bpl, %r14d
vpextrb $0x5, %xmm0, %ebp
xorb -0x1(%rcx,%rax), %bpl
movzbl (%rdx,%rdi), %edi
vmovd %edi, %xmm4
vpinsrb $0x1, (%rdx,%rbx), %xmm4, %xmm4
vpinsrb $0x2, (%rdx,%r8), %xmm4, %xmm4
vpinsrb $0x3, (%rdx,%r11), %xmm4, %xmm4
vpinsrb $0x4, (%rdx,%r10), %xmm4, %xmm4
vpinsrb $0x5, (%rdx,%r14), %xmm4, %xmm4
movzbl %bpl, %edi
vpinsrb $0x6, (%rdx,%r9), %xmm4, %xmm4
vpinsrb $0x7, (%rdx,%rdi), %xmm4, %xmm4
vpxor %xmm3, %xmm4, %xmm4
vpextrb $0x1, %xmm4, %edi
vpextrb $0x7, %xmm4, %r8d
vpextrb $0x3, %xmm4, %r9d
vpextrb $0x5, %xmm4, %r11d
vpextrb $0x2, %xmm4, %ebx
vpextrb $0x4, %xmm4, %ebp
vmovd %xmm4, %r14d
vpextrb $0x6, %xmm4, %r10d
xorb -0x10(%rcx,%rax), %r10b
movzbl %r10b, %r10d
xorb -0xf(%rcx,%rax), %r14b
movzbl %r14b, %r14d
xorb -0xe(%rcx,%rax), %bpl
movzbl %bpl, %r15d
xorb -0xd(%rcx,%rax), %bl
movzbl %bl, %ebx
xorb -0xc(%rcx,%rax), %r11b
movzbl %r11b, %r11d
xorb -0xb(%rcx,%rax), %r9b
movzbl %r9b, %r9d
xorb -0xa(%rcx,%rax), %r8b
movzbl %r8b, %r8d
xorb -0x9(%rcx,%rax), %dil
movzbl %dil, %edi
movzbl (%rdx,%r9), %r9d
vmovd %r9d, %xmm3
vpinsrb $0x1, (%rdx,%r11), %xmm3, %xmm3
vpinsrb $0x2, (%rdx,%r10), %xmm3, %xmm3
vpinsrb $0x3, (%rdx,%r14), %xmm3, %xmm3
vpinsrb $0x4, (%rdx,%r8), %xmm3, %xmm3
vpinsrb $0x5, (%rdx,%rdi), %xmm3, %xmm3
vpinsrb $0x6, (%rdx,%rbx), %xmm3, %xmm3
vpinsrb $0x7, (%rdx,%r15), %xmm3, %xmm3
vpxor %xmm0, %xmm3, %xmm5
vpshufb %xmm1, %xmm5, %xmm0
vpshufb %xmm2, %xmm4, %xmm3
addq $-0x10, %rax
jne 0x1cfc
vpsllw $0x4, %xmm4, %xmm0
vpshufb 0x123c(%rip), %xmm5, %xmm1 # 0x30c0
vpshufb 0x1243(%rip), %xmm0, %xmm0 # 0x30d0
vpbroadcastb 0x118c(%rip), %xmm2 # 0x3022
vpternlogq $0x6c, %xmm0, %xmm1, %xmm2
vmovq %xmm2, (%rsi)
popq %rbx
popq %r14
popq %r15
popq %rbp
retq