// File: /workspace/github_c_makefile_star2_O2/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 %rbp
pushq %rbx
subq $0x38, %rsp
movq %rdx, %rbx
cmpl $0x10, %esi
jne 0x123c
vmovdqu (%rdi), %xmm1
vmovdqa 0x2e7a(%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 0x2e66(%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 0x2e51(%rip), %xmm2     # 0x4070
vpxor %xmm2, %xmm1, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
jmp 0x146b
movl %esi, %ebp
leaq 0x20(%rbx), %rax
testl %esi, %esi
cmoveq %rax, %rdi
vpxor %xmm0, %xmm0, %xmm0
vmovdqu %ymm0, 0x10(%rbx)
vmovdqu %ymm0, (%rbx)
vmovdqa 0x2da3(%rip), %xmm1     # 0x4000
vpxor %xmm10, %xmm10, %xmm10
vpxor %xmm0, %xmm0, %xmm0
vmovdqa 0x2db2(%rip), %xmm2     # 0x4020
vmovdqa 0x2d9a(%rip), %xmm11    # 0x4010
vmovdqa 0x2db2(%rip), %xmm3     # 0x4030
vmovdqa 0x2dba(%rip), %xmm4     # 0x4040
vmovdqa 0x2d72(%rip), %xmm5     # 0x4000
vpxor %xmm13, %xmm13, %xmm13
vpxor %xmm12, %xmm12, %xmm12
cmpl $0x10, %ebp
jb 0x1363
vmovdqu (%rdi), %xmm6
vpxor %xmm2, %xmm1, %xmm0
vaesenc %xmm11, %xmm0, %xmm0
vaesenc %xmm11, %xmm0, %xmm0
vaesenc %xmm11, %xmm0, %xmm0
vaesenc %xmm11, %xmm0, %xmm0
vpxor %xmm3, %xmm1, %xmm7
vaesenc %xmm11, %xmm7, %xmm7
vaesenc %xmm11, %xmm7, %xmm7
vaesenc %xmm11, %xmm7, %xmm7
vaesenc %xmm11, %xmm7, %xmm7
vpxor %xmm4, %xmm1, %xmm8
vaesenc %xmm11, %xmm8, %xmm8
vaesenc %xmm11, %xmm8, %xmm8
vaesenc %xmm11, %xmm8, %xmm8
vpxor %xmm6, %xmm0, %xmm9
vaesenc %xmm0, %xmm9, %xmm9
vaesenc %xmm0, %xmm9, %xmm9
vaesenc %xmm0, %xmm9, %xmm9
vaesenc %xmm0, %xmm9, %xmm0
vpxor %xmm0, %xmm12, %xmm12
vmovdqa %xmm12, (%rbx)
vpxor %xmm6, %xmm7, %xmm0
vaesenc %xmm7, %xmm0, %xmm0
vaesenc %xmm7, %xmm0, %xmm0
vaesenc %xmm7, %xmm0, %xmm0
vaesenc %xmm7, %xmm0, %xmm0
vpxor %xmm0, %xmm13, %xmm0
vmovdqa %xmm0, 0x20(%rbx)
vaesenc %xmm11, %xmm8, %xmm7
vpxor %xmm6, %xmm7, %xmm6
vaesenc %xmm7, %xmm6, %xmm6
vaesenc %xmm7, %xmm6, %xmm6
vaesenc %xmm7, %xmm6, %xmm6
vaesenc %xmm7, %xmm6, %xmm6
vpxor %xmm6, %xmm10, %xmm10
vmovdqa %xmm10, 0x10(%rbx)
addq $0x10, %rdi
addl $-0x10, %ebp
vpaddb %xmm5, %xmm1, %xmm1
vmovdqa %xmm0, %xmm13
jmp 0x1298
testl %ebp, %ebp
setne %cl
cmpq %rax, %rdi
sete %al
orb %cl, %al
cmpb $0x1, %al
jne 0x1470
movl %ebp, %esi
vmovdqa %xmm10, 0x20(%rsp)
vmovdqa %xmm12, (%rsp)
vmovdqa %xmm13, 0x10(%rsp)
vzeroupper
callq 0x1515
pushq $0x10
popq %rax
subl %ebp, %eax
leaq 0x2d61(%rip), %rcx      # 0x4100
vmovdqu (%rax,%rcx), %xmm1
vpternlogq $0xea, 0x10(%rax,%rcx), %xmm0, %xmm1
vmovdqa 0x2c6b(%rip), %xmm0     # 0x4020
vmovdqa 0x2c53(%rip), %xmm4     # 0x4010
vaesenc %xmm4, %xmm0, %xmm0
vaesenc %xmm4, %xmm0, %xmm0
vaesenc %xmm4, %xmm0, %xmm0
vaesenc %xmm4, %xmm0, %xmm0
vmovdqa 0x2c57(%rip), %xmm2     # 0x4030
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vmovdqa 0x2c4b(%rip), %xmm3     # 0x4040
vaesenc %xmm4, %xmm3, %xmm3
vaesenc %xmm4, %xmm3, %xmm3
vaesenc %xmm4, %xmm3, %xmm3
vaesenc %xmm4, %xmm3, %xmm3
vpxor %xmm1, %xmm0, %xmm4
vaesenc %xmm0, %xmm4, %xmm4
vaesenc %xmm0, %xmm4, %xmm4
vaesenc %xmm0, %xmm4, %xmm4
vaesenc %xmm0, %xmm4, %xmm0
vpxor (%rsp), %xmm0, %xmm0
vmovdqa %xmm0, (%rbx)
vpxor %xmm1, %xmm2, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vpxor 0x10(%rsp), %xmm0, %xmm0
vmovdqa %xmm0, 0x20(%rbx)
vpxor %xmm1, %xmm3, %xmm1
vaesenc %xmm3, %xmm1, %xmm1
vaesenc %xmm3, %xmm1, %xmm1
vaesenc %xmm3, %xmm1, %xmm1
vaesenc %xmm3, %xmm1, %xmm1
vpxor 0x20(%rsp), %xmm1, %xmm1
vmovdqa %xmm1, 0x10(%rbx)
vmovdqa 0x2c08(%rip), %xmm1     # 0x4080
vpshufb %xmm1, %xmm0, %xmm0
vpshufd $0x93, %xmm0, %xmm2     # xmm2 = xmm0[3,0,1,2]
vpsrad $0x1f, %xmm2, %xmm2
vpshufd $0x93, 0x2c00(%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 $0x38, %rsp
popq %rbx
popq %rbp
vzeroupper
retq