// File: /workspace/github_c_makefile_star2_O0/dubeyalok7[P]crypto-algo/des/des/des.c
// Function: key_schedule
void key_schedule(uint64_t *key, uint64_t *nxt_key, int round)
{
  uint64_t key_left = 0;
  uint64_t key_right = 0;

  uint64_t key_left_tmp = 0;
  uint64_t key_right_tmp = 0;

  nxt_key = 0;

  if(0 == round){ // 1. first round permuted choice 1
    for(int i=0; i<56; i++) {
      if(i<28)
        addbit(&key_left, *key, PC1[i] -1, i);
      else
        addbit(&key_right, *key, PC1[i] -1, i%28);
    }
  }
  else // other rounds -> seperate key into two key halves.
  {
    for(int i=0; i<56; i++)
    {
      if(i<28)
        addbit(&key_left, *key, i, i);
      else
        addbit(&key_right, *key, i, i%28);
    }
  }

  // rotations
  key_left_tmp = rotations[round] == 1 ? FIRSTBIT : 0xc000000000000000;
  key_right_tmp = rotations[round] == 1 ? FIRSTBIT : 0xc000000000000000;
  key_left_tmp = (key_left & key_left_tmp) >> (28 - rotations[round]);
  key_right_tmp = (key_right & key_right_tmp) >> (28 - rotations[round]);

  key_left_tmp += (key_left << rotations[round]);
  key_right_tmp += (key_right << rotations[round]);

  //combine the 2 keys into 1 (nxt_key)
  //nxt_key will be used for following rounds

  for(int i=0; i<56; i++)
  {
    if(i<28)
      addbit(nxt_key, key_left_tmp, i, i);
    else
      addbit(nxt_key, key_right_tmp, i%28, i);
  }

  *key = 0;

  for(int i=0; i<48; i++)
    addbit(key, *nxt_key, PC2[i]-1, i);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq $0x0, -0x10(%rbp)
xorl %eax, %eax
cmpl -0x14(%rbp), %eax
jne 0x1398
movl $0x0, -0x3c(%rbp)
cmpl $0x38, -0x3c(%rbp)
jge 0x1396
cmpl $0x1c, -0x3c(%rbp)
jge 0x1353
movq -0x8(%rbp), %rax
movq (%rax), %rsi
movslq -0x3c(%rbp), %rcx
leaq 0x2355(%rip), %rax      # 0x3690
movq (%rax,%rcx,8), %rax
subq $0x1, %rax
movl %eax, %edx
movl -0x3c(%rbp), %ecx
leaq -0x20(%rbp), %rdi
callq 0x11e0
jmp 0x1389
movq -0x8(%rbp), %rax
movq (%rax), %rsi
movslq -0x3c(%rbp), %rcx
leaq 0x232b(%rip), %rax      # 0x3690
movq (%rax,%rcx,8), %rax
subq $0x1, %rax
movl %eax, -0x4c(%rbp)
movl -0x3c(%rbp), %eax
movl $0x1c, %ecx
cltd
idivl %ecx
movl %edx, %ecx
movl -0x4c(%rbp), %edx
leaq -0x28(%rbp), %rdi
callq 0x11e0
jmp 0x138b
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x131d
jmp 0x13f8
movl $0x0, -0x40(%rbp)
cmpl $0x38, -0x40(%rbp)
jge 0x13f6
cmpl $0x1c, -0x40(%rbp)
jge 0x13c3
movq -0x8(%rbp), %rax
movq (%rax), %rsi
movl -0x40(%rbp), %edx
movl -0x40(%rbp), %ecx
leaq -0x20(%rbp), %rdi
callq 0x11e0
jmp 0x13e9
movq -0x8(%rbp), %rax
movq (%rax), %rsi
movl -0x40(%rbp), %eax
movl %eax, -0x50(%rbp)
movl -0x40(%rbp), %eax
movl $0x1c, %ecx
cltd
idivl %ecx
movl %edx, %ecx
movl -0x50(%rbp), %edx
leaq -0x28(%rbp), %rdi
callq 0x11e0
jmp 0x13eb
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x139f
jmp 0x13f8
movslq -0x14(%rbp), %rcx
leaq 0x25cd(%rip), %rax      # 0x39d0
movq (%rax,%rcx,8), %rdx
movabsq $-0x4000000000000000, %rax # imm = 0xC000000000000000
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
cmpq $0x1, %rdx
cmoveq %rcx, %rax
movq %rax, -0x30(%rbp)
movslq -0x14(%rbp), %rcx
leaq 0x259e(%rip), %rax      # 0x39d0
movq (%rax,%rcx,8), %rdx
movabsq $-0x4000000000000000, %rax # imm = 0xC000000000000000
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
cmpq $0x1, %rdx
cmoveq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
andq -0x30(%rbp), %rax
movslq -0x14(%rbp), %rsi
movl $0x1c, %ecx
leaq 0x2562(%rip), %rdx      # 0x39d0
subq (%rdx,%rsi,8), %rcx
shrq %cl, %rax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
andq -0x38(%rbp), %rax
movslq -0x14(%rbp), %rsi
movl $0x1c, %ecx
leaq 0x253f(%rip), %rdx      # 0x39d0
subq (%rdx,%rsi,8), %rcx
shrq %cl, %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movslq -0x14(%rbp), %rdx
leaq 0x2525(%rip), %rcx      # 0x39d0
movq (%rcx,%rdx,8), %rcx
shlq %cl, %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movslq -0x14(%rbp), %rdx
leaq 0x2507(%rip), %rcx      # 0x39d0
movq (%rcx,%rdx,8), %rcx
shlq %cl, %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x44(%rbp)
cmpl $0x38, -0x44(%rbp)
jge 0x1528
cmpl $0x1c, -0x44(%rbp)
jge 0x1500
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movl -0x44(%rbp), %edx
movl -0x44(%rbp), %ecx
callq 0x11e0
jmp 0x151b
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl -0x44(%rbp), %eax
movl $0x1c, %ecx
cltd
idivl %ecx
movl -0x44(%rbp), %ecx
callq 0x11e0
jmp 0x151d
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x14df
movq -0x8(%rbp), %rax
movq $0x0, (%rax)
movl $0x0, -0x48(%rbp)
cmpl $0x30, -0x48(%rbp)
jge 0x1573
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
movslq -0x48(%rbp), %rcx
leaq 0x22fa(%rip), %rax      # 0x3850
movq (%rax,%rcx,8), %rax
subq $0x1, %rax
movl %eax, %edx
movl -0x48(%rbp), %ecx
callq 0x11e0
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x153a
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)