// File: /workspace/github_cpp_makefile_star2_O1/twekkel[P]mzpq/libzpaq.cpp
// Function: libzpaq::AES_CTR::AES_CTR(char const*, int, char const*)
AES_CTR::AES_CTR(const char* key, int keylen, const char* iv) {
  assert(key  != NULL);
  assert(keylen==16 || keylen==24 || keylen==32);

  // Initialize IV (default 0)
  iv0=iv1=0;
  if (iv) {
    LOAD32H(iv0, iv);
    LOAD32H(iv1, iv+4);
  }

  // Initialize encryption tables
  for (int i=0; i<256; ++i) {
    unsigned s1=
    "\x63\x7c\x77\x7b\xf2\x6b\x6f\xc5\x30\x01\x67\x2b\xfe\xd7\xab\x76"
    "\xca\x82\xc9\x7d\xfa\x59\x47\xf0\xad\xd4\xa2\xaf\x9c\xa4\x72\xc0"
    "\xb7\xfd\x93\x26\x36\x3f\xf7\xcc\x34\xa5\xe5\xf1\x71\xd8\x31\x15"
    "\x04\xc7\x23\xc3\x18\x96\x05\x9a\x07\x12\x80\xe2\xeb\x27\xb2\x75"
    "\x09\x83\x2c\x1a\x1b\x6e\x5a\xa0\x52\x3b\xd6\xb3\x29\xe3\x2f\x84"
    "\x53\xd1\x00\xed\x20\xfc\xb1\x5b\x6a\xcb\xbe\x39\x4a\x4c\x58\xcf"
    "\xd0\xef\xaa\xfb\x43\x4d\x33\x85\x45\xf9\x02\x7f\x50\x3c\x9f\xa8"
    "\x51\xa3\x40\x8f\x92\x9d\x38\xf5\xbc\xb6\xda\x21\x10\xff\xf3\xd2"
    "\xcd\x0c\x13\xec\x5f\x97\x44\x17\xc4\xa7\x7e\x3d\x64\x5d\x19\x73"
    "\x60\x81\x4f\xdc\x22\x2a\x90\x88\x46\xee\xb8\x14\xde\x5e\x0b\xdb"
    "\xe0\x32\x3a\x0a\x49\x06\x24\x5c\xc2\xd3\xac\x62\x91\x95\xe4\x79"
    "\xe7\xc8\x37\x6d\x8d\xd5\x4e\xa9\x6c\x56\xf4\xea\x65\x7a\xae\x08"
    "\xba\x78\x25\x2e\x1c\xa6\xb4\xc6\xe8\xdd\x74\x1f\x4b\xbd\x8b\x8a"
    "\x70\x3e\xb5\x66\x48\x03\xf6\x0e\x61\x35\x57\xb9\x86\xc1\x1d\x9e"
    "\xe1\xf8\x98\x11\x69\xd9\x8e\x94\x9b\x1e\x87\xe9\xce\x55\x28\xdf"
    "\x8c\xa1\x89\x0d\xbf\xe6\x42\x68\x41\x99\x2d\x0f\xb0\x54\xbb\x16"
    [i]&255;
    unsigned s2=s1<<1;
    if (s2>=0x100) s2^=0x11b;
    unsigned s3=s1^s2;
    Te0[i]=s2<<24|s1<<16|s1<<8|s3;
    Te1[i]=s3<<24|s2<<16|s1<<8|s1;
    Te2[i]=s1<<24|s3<<16|s2<<8|s1;
    Te3[i]=s1<<24|s1<<16|s3<<8|s2;
    Te4[i]=s1<<24|s1<<16|s1<<8|s1;
  }

  // setup the forward key
  Nr = 10 + ((keylen/8)-2)*2;  // 10, 12, or 14 rounds
  int i = 0;
  U32* rk = &ek[0];
  U32 temp;
  static const U32 rcon[10] = {
    0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
    0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
    0x1B000000UL, 0x36000000UL};  // round constants

  LOAD32H(rk[0], key   );
  LOAD32H(rk[1], key +  4);
  LOAD32H(rk[2], key +  8);
  LOAD32H(rk[3], key + 12);
  if (keylen == 16) {
    for (;;) {
      temp  = rk[3];
      rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
      rk[5] = rk[1] ^ rk[4];
      rk[6] = rk[2] ^ rk[5];
      rk[7] = rk[3] ^ rk[6];
      if (++i == 10) {
         break;
      }
      rk += 4;
    }
  }
  else if (keylen == 24) {
    LOAD32H(rk[4], key + 16);
    LOAD32H(rk[5], key + 20);
    for (;;) {
      temp = rk[5];
      rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
      rk[ 7] = rk[ 1] ^ rk[ 6];
      rk[ 8] = rk[ 2] ^ rk[ 7];
      rk[ 9] = rk[ 3] ^ rk[ 8];
      if (++i == 8) {
        break;
      }
      rk[10] = rk[ 4] ^ rk[ 9];
      rk[11] = rk[ 5] ^ rk[10];
      rk += 6;
    }
  }
  else if (keylen == 32) {
    LOAD32H(rk[4], key + 16);
    LOAD32H(rk[5], key + 20);
    LOAD32H(rk[6], key + 24);
    LOAD32H(rk[7], key + 28);
    for (;;) {
      temp = rk[7];
      rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
      rk[ 9] = rk[ 1] ^ rk[ 8];
      rk[10] = rk[ 2] ^ rk[ 9];
      rk[11] = rk[ 3] ^ rk[10];
      if (++i == 7) {
        break;
      }
      temp = rk[11];
      rk[12] = rk[ 4] ^ setup_mix(temp<<24|temp>>8);
      rk[13] = rk[ 5] ^ rk[12];
      rk[14] = rk[ 6] ^ rk[13];
      rk[15] = rk[ 7] ^ rk[14];
      rk += 8;
    }
  }
}

// Assembly:
movq $0x0, 0x14f4(%rdi)
testq %rcx, %rcx
je 0x89a9
movl (%rcx), %eax
bswapl %eax
movl %eax, 0x14f4(%rdi)
movl 0x4(%rcx), %eax
bswapl %eax
movl %eax, 0x14f8(%rdi)
pushq %rbp
pushq %r14
pushq %rbx
xorl %eax, %eax
leaq 0x42fca(%rip), %rcx     # 0x4b980
movzbl (%rax,%rcx), %r9d
leal (%r9,%r9), %r10d
movl %r10d, %r8d
xorl $0x11b, %r8d            # imm = 0x11B
testb %r9b, %r9b
cmovnsl %r10d, %r8d
movl %r8d, %r10d
xorl %r9d, %r10d
movl %r8d, %ebp
shll $0x18, %ebp
movl %r9d, %ebx
shll $0x10, %ebx
orl %ebx, %ebp
movl %r9d, %r11d
shll $0x8, %r11d
orl %r11d, %ebp
orl %r10d, %ebp
movl %ebp, (%rdi,%rax,4)
movl %r10d, %ebp
shll $0x18, %ebp
movl %r8d, %r14d
shll $0x10, %r14d
orl %ebp, %r14d
orl %r9d, %r14d
orl %r11d, %r14d
movl %r14d, 0x400(%rdi,%rax,4)
movl %r10d, %ebp
shll $0x10, %ebp
movl %r8d, %r14d
shll $0x8, %r14d
orl %ebp, %r14d
orl %r9d, %r14d
orl %r9d, %r11d
shll $0x18, %r9d
orl %r9d, %r14d
movl %r14d, 0x800(%rdi,%rax,4)
orl %ebx, %r9d
shll $0x8, %r10d
orl %r9d, %r8d
orl %r10d, %r8d
movl %r8d, 0xc00(%rdi,%rax,4)
orl %r9d, %r11d
movl %r11d, 0x1000(%rdi,%rax,4)
incq %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x89b6
leal 0x7(%rdx), %eax
testl %edx, %edx
cmovnsl %edx, %eax
sarl $0x3, %eax
leal 0x6(,%rax,2), %eax
movl %eax, 0x14f0(%rdi)
movl (%rsi), %eax
bswapl %eax
movl %eax, 0x1400(%rdi)
movl 0x4(%rsi), %eax
bswapl %eax
movl %eax, 0x1404(%rdi)
movl 0x8(%rsi), %eax
bswapl %eax
movl %eax, 0x1408(%rdi)
movl 0xc(%rsi), %eax
bswapl %eax
movl %eax, 0x140c(%rdi)
cmpl $0x20, %edx
je 0x8c65
cmpl $0x18, %edx
je 0x8b8c
cmpl $0x10, %edx
jne 0x8b87
xorl %eax, %eax
movl $0xff, %ecx
leaq 0x42fbe(%rip), %rdx     # 0x4ba90
movl 0x140c(%rdi,%rax,4), %esi
movl %esi, %r8d
shrl $0xe, %r8d
andl $0x3fc, %r8d            # imm = 0x3FC
movzbl 0x1003(%rdi,%r8), %r8d
shll $0x18, %r8d
movl %esi, %r9d
shrl $0x8, %r9d
andl %ecx, %r9d
movzbl 0x1002(%rdi,%r9,4), %r9d
shll $0x10, %r9d
orl %r8d, %r9d
movl %esi, %r8d
andl %ecx, %r8d
movzbl 0x1001(%rdi,%r8,4), %r8d
shll $0x8, %r8d
orl %r9d, %r8d
movl %esi, %r9d
shrl $0x18, %r9d
movzbl 0x1000(%rdi,%r9,4), %r9d
orl %r8d, %r9d
movl (%rax,%rdx), %r8d
xorl 0x1400(%rdi,%rax,4), %r8d
xorl %r9d, %r8d
movl %r8d, 0x1410(%rdi,%rax,4)
xorl 0x1404(%rdi,%rax,4), %r8d
movl %r8d, 0x1414(%rdi,%rax,4)
xorl 0x1408(%rdi,%rax,4), %r8d
movl %r8d, 0x1418(%rdi,%rax,4)
xorl %esi, %r8d
movl %r8d, 0x141c(%rdi,%rax,4)
addq $0x4, %rax
cmpq $0x28, %rax
jne 0x8ad2
popq %rbx
popq %r14
popq %rbp
retq
movl 0x10(%rsi), %eax
bswapl %eax
movl %eax, 0x1410(%rdi)
movl 0x14(%rsi), %eax
bswapl %eax
movl %eax, 0x1414(%rdi)
leaq 0x142c(%rdi), %rax
xorl %ecx, %ecx
movl $0xff, %edx
leaq 0x42ed9(%rip), %rsi     # 0x4ba90
movl -0x18(%rax), %r8d
movl %r8d, %r9d
shrl $0xe, %r9d
andl $0x3fc, %r9d            # imm = 0x3FC
movzbl 0x1003(%rdi,%r9), %r9d
shll $0x18, %r9d
movl %r8d, %r10d
shrl $0x8, %r10d
andl %edx, %r10d
movzbl 0x1002(%rdi,%r10,4), %r10d
shll $0x10, %r10d
orl %r9d, %r10d
movl %r8d, %r9d
andl %edx, %r9d
movzbl 0x1001(%rdi,%r9,4), %r9d
shll $0x8, %r9d
orl %r10d, %r9d
movl %r8d, %r10d
shrl $0x18, %r10d
movzbl 0x1000(%rdi,%r10,4), %r10d
orl %r9d, %r10d
movl (%rcx,%rsi), %r9d
xorl -0x2c(%rax), %r9d
xorl %r10d, %r9d
movl %r9d, -0x14(%rax)
xorl -0x28(%rax), %r9d
movl %r9d, -0x10(%rax)
xorl -0x24(%rax), %r9d
movl %r9d, -0xc(%rax)
xorl -0x20(%rax), %r9d
movl %r9d, -0x8(%rax)
cmpq $0x1c, %rcx
je 0x8b87
xorl -0x1c(%rax), %r9d
movl %r9d, -0x4(%rax)
xorl %r8d, %r9d
movl %r9d, (%rax)
addq $0x4, %rcx
addq $0x18, %rax
jmp 0x8bb7
movl 0x10(%rsi), %eax
bswapl %eax
movl %eax, 0x1410(%rdi)
movl 0x14(%rsi), %eax
bswapl %eax
movl %eax, 0x1414(%rdi)
movl 0x18(%rsi), %eax
bswapl %eax
movl %eax, 0x1418(%rdi)
movl 0x1c(%rsi), %eax
bswapl %eax
movl %eax, 0x141c(%rdi)
xorl %eax, %eax
movl $0xff, %ecx
leaq 0x42df1(%rip), %rdx     # 0x4ba90
movl 0x141c(%rdi,%rax,8), %esi
movl %esi, %r8d
shrl $0xe, %r8d
andl $0x3fc, %r8d            # imm = 0x3FC
movzbl 0x1003(%rdi,%r8), %r8d
shll $0x18, %r8d
movl %esi, %r9d
shrl $0x8, %r9d
andl %ecx, %r9d
movzbl 0x1002(%rdi,%r9,4), %r9d
shll $0x10, %r9d
orl %r8d, %r9d
movl %esi, %r8d
andl %ecx, %r8d
movzbl 0x1001(%rdi,%r8,4), %r8d
shll $0x8, %r8d
orl %r9d, %r8d
movl %esi, %r9d
shrl $0x18, %r9d
movzbl 0x1000(%rdi,%r9,4), %r9d
orl %r8d, %r9d
movl (%rax,%rdx), %r8d
xorl 0x1400(%rdi,%rax,8), %r8d
xorl %r9d, %r8d
movl %r8d, 0x1420(%rdi,%rax,8)
xorl 0x1404(%rdi,%rax,8), %r8d
movl %r8d, 0x1424(%rdi,%rax,8)
xorl 0x1408(%rdi,%rax,8), %r8d
movl %r8d, 0x1428(%rdi,%rax,8)
xorl 0x140c(%rdi,%rax,8), %r8d
movl %r8d, 0x142c(%rdi,%rax,8)
cmpq $0x18, %rax
je 0x8b87
roll $0x18, %r8d
movl %r8d, %r9d
shrl $0xe, %r9d
andl $0x3fc, %r9d            # imm = 0x3FC
movzbl 0x1003(%rdi,%r9), %r9d
shll $0x18, %r9d
movl %r8d, %r10d
shrl $0x8, %r10d
andl %ecx, %r10d
movzbl 0x1002(%rdi,%r10,4), %r10d
shll $0x10, %r10d
orl %r9d, %r10d
movl %r8d, %r9d
andl %ecx, %r9d
movzbl 0x1001(%rdi,%r9,4), %r9d
shll $0x8, %r9d
orl %r10d, %r9d
shrl $0x18, %r8d
movzbl 0x1000(%rdi,%r8,4), %r8d
orl %r9d, %r8d
xorl 0x1410(%rdi,%rax,8), %r8d
movl %r8d, 0x1430(%rdi,%rax,8)
xorl 0x1414(%rdi,%rax,8), %r8d
movl %r8d, 0x1434(%rdi,%rax,8)
xorl 0x1418(%rdi,%rax,8), %r8d
movl %r8d, 0x1438(%rdi,%rax,8)
xorl %esi, %r8d
movl %r8d, 0x143c(%rdi,%rax,8)
addq $0x4, %rax
jmp 0x8c9f