// File: /workspace/github_c_makefile_star2_O1/mjosaarinen[P]brutus/crypto_aead/twine80n6t4clocv2/vperm/twine.h
// Function: Keyschedule80
void Keyschedule80(const unsigned char sk[80/8])
{
	lsbox = LOAD(S);
	usbox = SHL4(lsbox);

	int	i;
	unsigned char	tmp[80/4];
	unsigned char	wk[4];

	for(i=0; i<(80/4); i+=2)
	{
		tmp[i] = sk[i/2] >> 4;
		tmp[i+1] = sk[i/2] & 0x0f;
	}

	for(i=0; ; i+=2)
	{
		//ek for two rounds
		ek[i][0] = tmp[1];
		ek[i][1] = tmp[3];
		ek[i][2] = tmp[4];
		ek[i][3] = tmp[6];
		ek[i][4] = tmp[13];
		ek[i][5] = tmp[14];
		ek[i][6] = tmp[15];
		ek[i][7] = tmp[16];

		ek[i+1][0] = tmp[5];
		ek[i+1][1] = tmp[7] ^ CON_H[i];
		ek[i+1][2] = tmp[8];
		ek[i+1][3] = tmp[10];
		ek[i+1][4] = tmp[17];
		ek[i+1][5] = tmp[18];
		ek[i+1][6] = tmp[19] ^ CON_L[i];
		ek[i+1][7] = tmp[1] ^ S[tmp[0]];

		//to the last two rounds
		if(i == (ROUND-2))
			break;

		//rotations for two rounds
		wk[3] = tmp[4] ^ S[tmp[16]];
		wk[0] = tmp[5] ^ S[wk[3]];
		wk[1] = tmp[6];
		wk[2] = ek[i+1][1];

		tmp[4] = tmp[12];
		tmp[5] = tmp[13];
		tmp[6] = tmp[14];
		tmp[7] = tmp[15];

		tmp[12] = ek[i+1][7];
		tmp[13] = tmp[2];
		tmp[14] = tmp[3];
		tmp[15] = tmp[0] ^ CON_L[i+1];

		tmp[0] = tmp[8] ^ S[ek[i+1][7]];
		tmp[1] = tmp[9];
		tmp[2] = tmp[10];
		tmp[3] = tmp[11] ^ CON_H[i+1];

		tmp[8] = tmp[16];
		tmp[9] = tmp[17];
		tmp[10] = tmp[18];
		tmp[11] = tmp[19] ^ CON_L[i];

		tmp[16] = wk[0];
		tmp[17] = wk[1];
		tmp[18] = wk[2];
		tmp[19] = wk[3];
	}

	for(i = 0; i < ROUND; i++)
	{
#ifndef TWINE_OPTIMIZED
		rks[i] = LOADS(ek[i]);
		rks[i] = SHR8(XOR(MASK4L(rks[i]), MASK4U(SHL4(rks[i]))));
#else
        /* key setup for the optimized implementation */
		rks[i] = LOAD64(ek[i]);
		switch(i%4){
			case 0:
				rks[i] = PSHUFB(rks[i], _mm_setr_epi8(0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7));
				break;
			case 1:
				rks[i] = PSHUFB(rks[i], _mm_setr_epi8(0,2,6,4,3,1,5,7,0,2,6,4,3,1,5,7));
				break;
			case 2:
				rks[i] = PSHUFB(rks[i], _mm_setr_epi8(0,6,5,3,4,2,1,7,0,6,5,3,4,2,1,7));
				break;
			case 3:
				rks[i] = PSHUFB(rks[i], _mm_setr_epi8(0,5,1,4,3,6,2,7,0,5,1,4,3,6,2,7));
				break;
		}
#endif
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
vmovaps 0x1f97(%rip), %xmm0     # 0x3210
movq 0x3d60(%rip), %rax      # 0x4fe0
vmovaps %xmm0, (%rax)
vmovaps 0x1f94(%rip), %xmm0     # 0x3220
movq 0x3d15(%rip), %rax      # 0x4fa8
vmovaps %xmm0, (%rax)
movq $-0x2, %rax
movb (%rdi), %cl
movl %ecx, %edx
shrb $0x4, %dl
movb %dl, -0x1e(%rsp,%rax)
andb $0xf, %cl
movb %cl, -0x1d(%rsp,%rax)
addq $0x2, %rax
incq %rdi
cmpq $0x12, %rax
jb 0x129e
movb -0x10(%rsp), %r10b
movb -0xf(%rsp), %dl
movb -0xe(%rsp), %r9b
movb -0xd(%rsp), %r11b
movl $0x1, %ecx
vmovdqa -0x20(%rsp), %xmm1
vmovd 0x1f4d(%rip), %xmm0     # 0x3230
movq 0x3cde(%rip), %rax      # 0x4fc8
movq 0x3d07(%rip), %rsi      # 0x4ff8
movq 0x3cc0(%rip), %rdi      # 0x4fb8
movq 0x3cf1(%rip), %r8       # 0x4ff0
vmovdqa 0x1f39(%rip), %xmm2     # 0x3240
vpshufb %xmm0, %xmm1, %xmm3
vmovd %xmm3, -0x8(%rax,%rcx,8)
vpextrb $0xd, %xmm1, -0x4(%rax,%rcx,8)
vpextrb $0xe, %xmm1, -0x3(%rax,%rcx,8)
vpextrb $0xf, %xmm1, -0x2(%rax,%rcx,8)
vpextrb $0x1, %xmm1, %ebp
movb %r10b, -0x1(%rax,%rcx,8)
vpextrb $0x5, %xmm1, (%rax,%rcx,8)
vpextrb $0x7, %xmm1, %ebx
xorb -0x1(%rsi,%rcx), %bl
movb %bl, 0x1(%rax,%rcx,8)
vpextrb $0x8, %xmm1, 0x2(%rax,%rcx,8)
vpextrb $0xa, %xmm1, 0x3(%rax,%rcx,8)
movb %dl, 0x4(%rax,%rcx,8)
movb %r9b, 0x5(%rax,%rcx,8)
movb -0x1(%rdi,%rcx), %r15b
xorb %r11b, %r15b
movb %r15b, 0x6(%rax,%rcx,8)
vmovd %xmm1, %r14d
movzbl %r14b, %r12d
xorb (%r8,%r12), %bpl
movb %bpl, 0x7(%rax,%rcx,8)
cmpq $0x23, %rcx
je 0x140e
vpextrb $0x8, %xmm1, %r11d
movzbl %bpl, %r12d
xorb (%r8,%r12), %r11b
vpextrb $0xb, %xmm1, %r12d
xorb (%rsi,%rcx), %r12b
vpshufb %xmm2, %xmm1, %xmm3
vpinsrb $0x0, %r11d, %xmm3, %xmm3
vpinsrb $0x3, %r12d, %xmm3, %xmm3
vpinsrb $0x8, %r10d, %xmm3, %xmm3
vpextrb $0x5, %xmm1, %r12d
movzbl %r10b, %r10d
vpextrb $0x4, %xmm1, %r11d
xorb (%r8,%r10), %r11b
movzbl %r11b, %r10d
xorb (%r8,%r10), %r12b
xorb (%rdi,%rcx), %r14b
vpinsrb $0x9, %edx, %xmm3, %xmm3
vpinsrb $0xa, %r9d, %xmm3, %xmm3
vpinsrb $0xb, %r15d, %xmm3, %xmm3
vpinsrb $0xc, %ebp, %xmm3, %xmm3
vpextrb $0x6, %xmm1, %edx
vpinsrb $0xf, %r14d, %xmm3, %xmm1
addq $0x2, %rcx
movl %ebx, %r9d
movl %r12d, %r10d
jmp 0x1307
movb %r10b, -0x10(%rsp)
movb %dl, -0xf(%rsp)
movb %r9b, -0xe(%rsp)
movb %r11b, -0xd(%rsp)
vmovdqa %xmm1, -0x20(%rsp)
movq 0x3b72(%rip), %rcx      # 0x4fa0
xorl %edx, %edx
vmovq (%rax,%rdx,8), %xmm0
vmovdqa %xmm0, (%rcx)
xorl %edi, %edi
andl $0x3, %edi
leaq 0x1bbf(%rip), %rsi      # 0x3004
movslq (%rsi,%rdi,4), %rdi
addq %rsi, %rdi
jmpq *%rdi
vmovq (%rax,%rdx,8), %xmm0
addq $0x10, %rcx
vmovdqa %xmm0, (%rcx)
movl %edx, %edi
andl $0x3, %edi
movslq (%rsi,%rdi,4), %rdi
addq %rsi, %rdi
jmpq *%rdi
vpbroadcastq %xmm0, %xmm0
jmp 0x148f
vpshufb 0x1dd7(%rip), %xmm0, %xmm0 # 0x3250
jmp 0x148f
vpshufb 0x1dec(%rip), %xmm0, %xmm0 # 0x3270
jmp 0x148f
vpshufb 0x1dd1(%rip), %xmm0, %xmm0 # 0x3260
vmovdqa %xmm0, (%rcx)
incq %rdx
cmpq $0x24, %rdx
jne 0x144e
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq