// File: /workspace/github_c_makefile_star2_O3/mjosaarinen[P]brutus/crypto_aead/aezv3/aesni/aez_ni.c
// Function: aez_setup
void aez_setup(unsigned char *key, unsigned kbytes, aez_ctx_t *ctx) {
    __m128i tmp;
    if (kbytes==16) {
        __m128i K   = load(key);
        __m128i C11 = _mm_setr_epi8(0xCB,0xEC,0x5B,0xC6,0xB0,0x2F,0xFA,0xA8,
                                    0xA5,0x0D,0x52,0x99,0xA9,0x94,0xA2,0x0A);
        __m128i C12 = _mm_setr_epi8(0x0B,0x97,0x9B,0xB6,0x0A,0x61,0x7C,0x2C,
                                    0xBB,0x65,0x2B,0x68,0x7D,0x12,0xED,0x8D);
        __m128i C13 = _mm_setr_epi8(0x1D,0x8B,0x1E,0x93,0xA6,0x94,0x06,0x4D,
                                    0x4A,0xC9,0x92,0xAF,0xDE,0x78,0x67,0x0F);
        ctx->I      = aes4(vxor(K,C11),C11,C11,C11,C11);
        ctx->J[0]   = aes4(vxor(K,C12),C12,C12,C12,C12);
        ctx->L      = aes4(vxor(K,C13),C13,C13,C13,C13);
    } else {
        __m128i Z  = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
        __m128i i1 = _mm_insert_epi8(zero, 1, 7);
        __m128i i2 = _mm_insert_epi8(zero, 2, 7);
        __m128i i3 = _mm_insert_epi8(zero, 3, 7);
        __m128i j, one = _mm_insert_epi8(zero, 1, 15);
        ctx->I = ctx->J[0] = ctx->L = zero;
        if (kbytes==0) key = (unsigned char *)ctx->J; /* used as a flag later */
        for (j=one; kbytes>=16; key+=16, kbytes-=16, j = _mm_add_epi8(j,one)) {
            __m128i K   = load(key);
            __m128i C1j = aes4(vxor3(i1,j,Z),Z,Z,Z,Z);
            __m128i C2j = aes4(vxor3(i2,j,Z),Z,Z,Z,Z);
            __m128i C3j = aes4(vxor3(i3,j,Z),Z,Z,Z,Z);
            ctx->I      = vxor(ctx->I,    aes4(vxor(K,C1j),C1j,C1j,C1j,C1j));
            ctx->J[0]   = vxor(ctx->J[0], aes4(vxor(K,C2j),C2j,C2j,C2j,C2j));
            ctx->L      = vxor(ctx->L,    aes4(vxor(K,C3j),C3j,C3j,C3j,C3j));
        }
        if (kbytes || (key == (unsigned char *)ctx->J)) {
            __m128i K = one_zero_pad(load_partial(key,kbytes),16-kbytes);
            __m128i C10 = aes4(vxor(i1,Z),Z,Z,Z,Z);
            __m128i C20 = aes4(vxor(i2,Z),Z,Z,Z,Z);
            __m128i C30 = aes4(vxor(i3,Z),Z,Z,Z,Z);
            ctx->I      = vxor(ctx->I,    aes4(vxor(K,C10),C10,C10,C10,C10));
            ctx->J[0]   = vxor(ctx->J[0], aes4(vxor(K,C20),C20,C20,C20,C20));
            ctx->L      = vxor(ctx->L,    aes4(vxor(K,C30),C30,C30,C30,C30));
        }
    }

    /* Fill ctx */
    ctx->J[1] = bswap16(tmp = double_block(bswap16(ctx->J[0])));
    ctx->J[2] = bswap16(tmp = double_block(tmp));
    ctx->J[3] = bswap16(tmp = double_block(tmp));
    ctx->J[4] = bswap16(tmp = double_block(tmp));
    ctx->delta3_cache = zero;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x40, %rsp
movq %rdx, %rbx
movq %rdi, %rax
cmpl $0x10, %esi
jne 0x1252
vmovdqu (%rax), %xmm1
vmovdqa 0x2e64(%rip), %xmm0     # 0x4050
vpxor %xmm0, %xmm1, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm0
vmovdqa %xmm0, (%rbx)
vmovdqa 0x2e50(%rip), %xmm0     # 0x4060
vpxor %xmm0, %xmm1, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm0
vmovdqa %xmm0, 0x20(%rbx)
vmovdqa 0x2e3b(%rip), %xmm2     # 0x4070
vpxor %xmm2, %xmm1, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
jmp 0x14b8
leaq 0x20(%rbx), %rcx
testl %esi, %esi
cmoveq %rcx, %rax
vpxor %xmm0, %xmm0, %xmm0
vmovdqu %ymm0, 0x10(%rbx)
vmovdqu %ymm0, (%rbx)
cmpl $0x10, %esi
jb 0x1379
vmovdqa 0x2d86(%rip), %xmm0     # 0x4000
vpxor %xmm11, %xmm11, %xmm11
vmovdqa 0x2d89(%rip), %xmm1     # 0x4010
vmovdqa 0x2d91(%rip), %xmm2     # 0x4020
vmovdqa 0x2d99(%rip), %xmm3     # 0x4030
vmovdqa 0x2da1(%rip), %xmm4     # 0x4040
vmovdqa 0x2d59(%rip), %xmm5     # 0x4000
vpxor %xmm12, %xmm12, %xmm12
vpxor %xmm13, %xmm13, %xmm13
vmovdqu (%rax), %xmm6
vpxor %xmm1, %xmm0, %xmm7
vaesenc %xmm2, %xmm7, %xmm7
vaesenc %xmm2, %xmm7, %xmm7
vaesenc %xmm2, %xmm7, %xmm7
vaesenc %xmm2, %xmm7, %xmm7
vpxor %xmm3, %xmm0, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vpxor %xmm4, %xmm0, %xmm9
vaesenc %xmm2, %xmm9, %xmm9
vaesenc %xmm2, %xmm9, %xmm9
vaesenc %xmm2, %xmm9, %xmm9
vaesenc %xmm2, %xmm9, %xmm9
vpxor %xmm6, %xmm7, %xmm10
vaesenc %xmm7, %xmm10, %xmm10
vaesenc %xmm7, %xmm10, %xmm10
vaesenc %xmm7, %xmm10, %xmm10
vaesenc %xmm7, %xmm10, %xmm7
vpxor %xmm7, %xmm13, %xmm13
vmovdqa %xmm13, (%rbx)
vpxor %xmm6, %xmm8, %xmm7
vaesenc %xmm8, %xmm7, %xmm7
vaesenc %xmm8, %xmm7, %xmm7
vaesenc %xmm8, %xmm7, %xmm7
vaesenc %xmm8, %xmm7, %xmm7
vpxor %xmm7, %xmm12, %xmm12
vmovdqa %xmm12, 0x20(%rbx)
vpxor %xmm6, %xmm9, %xmm6
vaesenc %xmm9, %xmm6, %xmm6
vaesenc %xmm9, %xmm6, %xmm6
vaesenc %xmm9, %xmm6, %xmm6
vaesenc %xmm9, %xmm6, %xmm6
vpxor %xmm6, %xmm11, %xmm11
vmovdqa %xmm11, 0x10(%rbx)
addq $0x10, %rax
addl $-0x10, %esi
vpaddb %xmm5, %xmm0, %xmm0
cmpl $0xf, %esi
ja 0x12b1
vmovdqa %xmm12, %xmm0
jmp 0x138c
vpxor %xmm11, %xmm11, %xmm11
vpxor %xmm0, %xmm0, %xmm0
vpxor %xmm12, %xmm12, %xmm12
vpxor %xmm13, %xmm13, %xmm13
movl %esi, %r14d
testl %esi, %esi
je 0x13d6
testb $0xf, %al
je 0x13e4
leaq 0x30(%rsp), %r15
movq %r15, %rdi
movq %rax, %rsi
movq %r14, %rdx
vmovdqa %xmm11, 0x20(%rsp)
vmovdqa %xmm12, 0x10(%rsp)
vmovdqa %xmm13, (%rsp)
vzeroupper
callq 0x10c0
vmovdqa (%rsp), %xmm13
vmovdqa 0x10(%rsp), %xmm12
vmovdqa 0x20(%rsp), %xmm11
vmovdqa (%r15), %xmm0
jmp 0x13e8
cmpq %rcx, %rax
jne 0x14bd
testb $0xf, %cl
jne 0x13e8
vmovdqu (%rax), %xmm0
leaq 0x2d11(%rip), %rax      # 0x4100
subq %r14, %rax
vmovdqu 0x10(%rax), %xmm1
vpternlogq $0xea, 0x20(%rax), %xmm0, %xmm1
vmovdqa 0x2c19(%rip), %xmm0     # 0x4020
vmovdqa 0x2c01(%rip), %xmm2     # 0x4010
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm2
vmovdqa 0x2c05(%rip), %xmm3     # 0x4030
vaesenc %xmm0, %xmm3, %xmm3
vaesenc %xmm0, %xmm3, %xmm3
vaesenc %xmm0, %xmm3, %xmm3
vaesenc %xmm0, %xmm3, %xmm3
vmovdqa 0x2bf9(%rip), %xmm4     # 0x4040
vaesenc %xmm0, %xmm4, %xmm4
vaesenc %xmm0, %xmm4, %xmm4
vaesenc %xmm0, %xmm4, %xmm4
vaesenc %xmm0, %xmm4, %xmm4
vpxor %xmm1, %xmm2, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vpxor %xmm0, %xmm13, %xmm0
vmovdqa %xmm0, (%rbx)
vpxor %xmm1, %xmm3, %xmm0
vaesenc %xmm3, %xmm0, %xmm0
vaesenc %xmm3, %xmm0, %xmm0
vaesenc %xmm3, %xmm0, %xmm0
vaesenc %xmm3, %xmm0, %xmm0
vpxor %xmm0, %xmm12, %xmm0
vmovdqa %xmm0, 0x20(%rbx)
vpxor %xmm1, %xmm4, %xmm1
vaesenc %xmm4, %xmm1, %xmm1
vaesenc %xmm4, %xmm1, %xmm1
vaesenc %xmm4, %xmm1, %xmm1
vaesenc %xmm4, %xmm1, %xmm1
vpxor %xmm1, %xmm11, %xmm1
vmovdqa %xmm1, 0x10(%rbx)
vmovdqa 0x2bbb(%rip), %xmm1     # 0x4080
vpshufb %xmm1, %xmm0, %xmm0
vpshufd $0x93, %xmm0, %xmm2     # xmm2 = xmm0[3,0,1,2]
vpsrad $0x1f, %xmm2, %xmm2
vpshufd $0x93, 0x2bb3(%rip), %xmm3 # xmm3 = mem[3,0,1,2]
vpaddd %xmm0, %xmm0, %xmm0
vpternlogd $0x6c, %xmm3, %xmm0, %xmm2
vpshufb %xmm1, %xmm2, %xmm4
vmovdqa %xmm4, 0x30(%rbx)
vpshufd $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2]
vpsrad $0x1f, %xmm0, %xmm0
vpaddd %xmm2, %xmm2, %xmm2
vpternlogd $0x6c, %xmm3, %xmm2, %xmm0
vpshufb %xmm1, %xmm0, %xmm4
vmovdqa %xmm4, 0x40(%rbx)
vpshufd $0x93, %xmm2, %xmm2     # xmm2 = xmm2[3,0,1,2]
vpsrad $0x1f, %xmm2, %xmm2
vpaddd %xmm0, %xmm0, %xmm0
vpternlogd $0x6c, %xmm3, %xmm0, %xmm2
vpshufb %xmm1, %xmm2, %xmm4
vmovdqa %xmm4, 0x50(%rbx)
vpshufd $0x93, %xmm0, %xmm0     # xmm0 = xmm0[3,0,1,2]
vpsrad $0x1f, %xmm0, %xmm0
vpaddd %xmm2, %xmm2, %xmm2
vpternlogd $0x78, %xmm3, %xmm0, %xmm2
vpshufb %xmm1, %xmm2, %xmm0
vmovdqa %xmm0, 0x60(%rbx)
vpxor %xmm0, %xmm0, %xmm0
vmovdqa %xmm0, 0x70(%rbx)
addq $0x40, %rsp
popq %rbx
popq %r14
popq %r15
vzeroupper
retq