// File: /workspace/github_c_makefile_star2_O3/mjosaarinen[P]brutus/crypto_aead/aezv4/aesni/encrypt.c
// Function: cipher_aez_core
int cipher_aez_core(aez_ctx_t *ctx, block t, int d, char *src, unsigned bytes, unsigned abytes, char *dst) {
    block s, x, y, frag0, frag1, final0, final1;
    block I=ctx->I[0], L=ctx->L, J=ctx->J[0], I4=ctx->I[2];
    unsigned i, frag_bytes, initial_bytes;
    
    if (!d) bytes += abytes;
    frag_bytes = bytes % 32;
    initial_bytes = bytes - frag_bytes - 32;
    
    /* Compute x and store intermediate results */
    x = pass_one(ctx, (block*)src, initial_bytes, (block*)dst);
    if (frag_bytes >= 16) {
        frag0 = load(src + initial_bytes);
        frag1 = one_zero_pad(load(src + initial_bytes + 16), 32-frag_bytes);
        x  = aes4(vxor(frag0, I4),     J, I, L, x);
        x  = vxor(x, aes4(vxor3(frag1, I4, I), J, I, L, zero));
    } else if (frag_bytes) {
        frag0 = one_zero_pad(load(src + initial_bytes), 16-frag_bytes);
        x = aes4(vxor(frag0, I4),     J, I, L, x);
    }
    
    /* Calculate s and final block values (y xor'd to final1 later) */
    final0 = vxor3(loadu(src + (bytes - 32)), x, t);
    if (d || !abytes) final1 = loadu(src+(bytes-32)+16);
    else              final1 = zero_pad(loadu(src+(bytes-32)+16), abytes);
    final0 = aes4(vxor(final1, ctx->I[d]), J, I, L, final0);
    final1 = vxor(final1, aes((block*)ctx, final0, ctx->J[d]));
    s = vxor(final0, final1);
    final0 = vxor(final0, aes((block*)ctx, final1, ctx->J[d^1]));
    /* Decryption: final0 should hold abytes zero bytes. If not, failure */
    if (d && !is_zero(vandnot(loadu(pad+abytes),final0))) return -1;
    final1 = aes4(vxor(final0, ctx->I[d^1]), J, I, L, final1);
    
    /* Compute y and store final results */
    y = pass_two(ctx, s, initial_bytes, (block*)dst);
    if (frag_bytes >= 16) {
        frag0 = vxor(frag0, aes((block*)ctx, s, ctx->J[2]));
        frag1 = vxor(frag1, aes((block*)ctx, s, vxor(ctx->J[2], J)));
        frag1 = one_zero_pad(frag1, 32-frag_bytes);
        y  = aes4(vxor(frag0, I4),     J, I, L, y);
        y  = vxor(y, aes4(vxor3(frag1, I4, I), J, I, L, zero));
        store(dst + initial_bytes, frag0);
        store(dst + initial_bytes + 16, frag1);
    } else if (frag_bytes) {
        frag0 = vxor(frag0, aes((block*)ctx, s, ctx->J[2]));
        frag0 = one_zero_pad(frag0, 16-frag_bytes);
        y = aes4(vxor(frag0, I4), J, I, L, y);
        store(dst + initial_bytes, frag0);
    }
    
    storeu(dst + (bytes - 32), vxor3(final1, y, t));
    if (!d || !abytes)
        storeu(dst + (bytes - 32) + 16, final0);
    else {
        for (i=0; i<16-abytes; i++)
            ((char*)dst + (bytes - 16))[i] = ((char*)&final0)[i];
    }
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rdi, %r12
vmovaps (%rdi), %xmm1
vmovaps %xmm1, 0x50(%rsp)
vmovaps 0x20(%rdi), %xmm1
vmovaps %xmm1, 0x10(%rsp)
movq %rdx, %r13
movl %esi, %r14d
vmovaps %xmm0, 0x70(%rsp)
vmovaps 0x30(%rdi), %xmm0
vmovaps %xmm0, 0x30(%rsp)
vmovdqa 0x60(%rdi), %xmm0
vmovdqa %xmm0, 0x40(%rsp)
xorl %ebp, %ebp
testl %esi, %esi
movl %r8d, 0x4(%rsp)
cmovel %r8d, %ebp
addl %ecx, %ebp
movl %ebp, %ebx
andl $0x1f, %ebx
movl %ebp, %r15d
andl $-0x20, %r15d
addl $-0x20, %r15d
movq %rdx, %rsi
movl %r15d, %edx
movq %r9, 0x8(%rsp)
movq %r9, %rcx
callq 0x1060
cmpl $0x10, %ebx
jb 0x2683
movl %r15d, %eax
vmovdqu (%r13,%rax), %xmm2
movl %ebx, %ecx
leaq 0x1abb(%rip), %rdx      # 0x40c0
subq %rcx, %rdx
vmovdqu 0x20(%rdx), %xmm1
vmovdqu 0x30(%rdx), %xmm3
vpternlogq $0xf8, 0x10(%r13,%rax), %xmm1, %xmm3
vmovdqa %xmm2, 0x20(%rsp)
vmovdqa 0x10(%rsp), %xmm7
vpxor %xmm7, %xmm2, %xmm1
vmovdqa 0x30(%rsp), %xmm9
vaesenc %xmm9, %xmm1, %xmm1
vmovdqa 0x50(%rsp), %xmm6
vaesenc %xmm6, %xmm1, %xmm1
vmovdqa 0x40(%rsp), %xmm8
vaesenc %xmm8, %xmm1, %xmm1
vaesenc %xmm0, %xmm1, %xmm0
vmovdqa %xmm3, 0x80(%rsp)
vmovdqa %xmm3, %xmm1
vpternlogq $0x96, %xmm6, %xmm7, %xmm1
vaesenc %xmm9, %xmm1, %xmm1
vaesenc %xmm6, %xmm1, %xmm1
vaesenc %xmm8, %xmm1, %xmm1
vpxor %xmm2, %xmm2, %xmm2
vaesenc %xmm2, %xmm1, %xmm1
vpxor %xmm0, %xmm1, %xmm0
jmp 0x26e1
vmovdqa 0x30(%rsp), %xmm9
vmovdqa 0x40(%rsp), %xmm8
vmovdqa 0x10(%rsp), %xmm7
vmovdqa 0x50(%rsp), %xmm6
testl %ebx, %ebx
je 0x26e1
movl %r15d, %eax
movl %ebx, %ecx
leaq 0x1a15(%rip), %rdx      # 0x40c0
subq %rcx, %rdx
vmovdqu 0x10(%rdx), %xmm1
vmovdqu 0x20(%rdx), %xmm2
vpternlogq $0xf8, (%r13,%rax), %xmm1, %xmm2
vmovdqa %xmm2, 0x20(%rsp)
vpxor %xmm7, %xmm2, %xmm1
vaesenc %xmm9, %xmm1, %xmm1
vaesenc %xmm6, %xmm1, %xmm1
vaesenc %xmm8, %xmm1, %xmm1
vaesenc %xmm0, %xmm1, %xmm0
jmp 0x26e1
movl 0x4(%rsp), %esi
leaq 0x30(%r12), %rcx
leal -0x20(%rbp), %edi
vmovdqa 0x70(%rsp), %xmm1
vpternlogq $0x96, (%r13,%rdi), %xmm1, %xmm0
testl %r14d, %r14d
setne %al
testl %esi, %esi
sete %dl
vmovdqu 0x10(%r13,%rdi), %xmm1
orb %al, %dl
movl %esi, %eax
jne 0x2720
leaq 0x19a5(%rip), %rdx      # 0x40c0
vpand (%rax,%rdx), %xmm1, %xmm1
movq 0x8(%rsp), %r13
movslq %r14d, %rsi
shlq $0x4, %rsi
movl %r14d, %edx
xorl $0x1, %edx
movslq %edx, %rdx
vpxor (%r12,%rsi), %xmm1, %xmm2
vaesenc %xmm9, %xmm2, %xmm2
vaesenc %xmm6, %xmm2, %xmm2
vaesenc %xmm8, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm0
vpxor (%rcx,%rsi), %xmm0, %xmm2
vmovdqa (%r12), %xmm3
vmovdqa 0x30(%r12), %xmm4
shlq $0x4, %rdx
vmovdqa 0x60(%r12), %xmm5
vaesenc %xmm3, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm5, %xmm2, %xmm2
vaesenc %xmm3, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm5, %xmm2, %xmm2
vaesenc %xmm3, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm5, %xmm2, %xmm2
vaesenc %xmm3, %xmm2, %xmm2
vpxor %xmm1, %xmm2, %xmm10
vpxor (%rcx,%rdx), %xmm10, %xmm1
vaesenc %xmm3, %xmm1, %xmm1
vaesenc %xmm4, %xmm1, %xmm1
vaesenc %xmm5, %xmm1, %xmm1
vaesenc %xmm3, %xmm1, %xmm1
vaesenc %xmm4, %xmm1, %xmm1
vaesenc %xmm5, %xmm1, %xmm1
vaesenc %xmm3, %xmm1, %xmm1
vaesenc %xmm4, %xmm1, %xmm1
vaesenc %xmm5, %xmm1, %xmm1
vaesenc %xmm3, %xmm1, %xmm1
vpxor %xmm0, %xmm1, %xmm2
vmovdqa %xmm2, 0xc0(%rsp)
testl %r14d, %r14d
je 0x2802
leaq 0x18ce(%rip), %rcx      # 0x40c0
vmovdqu (%rax,%rcx), %xmm1
vptest %xmm2, %xmm1
jae 0x2a9e
movq %rdi, 0x8(%rsp)
vpxor %xmm0, %xmm10, %xmm0
vmovdqa %xmm2, 0x90(%rsp)
vpxor (%r12,%rdx), %xmm2, %xmm1
vmovdqa %xmm1, 0xb0(%rsp)
movq %r12, %rdi
vmovdqa %xmm0, 0x60(%rsp)
movl %r15d, %esi
movq %r13, %rdx
vmovdqa %xmm10, 0xa0(%rsp)
callq 0x1050
vmovdqa 0x30(%rsp), %xmm9
vmovdqa 0x40(%rsp), %xmm8
vmovdqa 0x50(%rsp), %xmm7
vmovdqa 0xb0(%rsp), %xmm1
vaesenc %xmm9, %xmm1, %xmm1
vaesenc %xmm7, %xmm1, %xmm1
vaesenc %xmm8, %xmm1, %xmm1
vaesenc 0xa0(%rsp), %xmm1, %xmm1
cmpl $0x10, %ebx
jb 0x2995
vmovdqa (%r12), %xmm2
vmovdqa 0x30(%r12), %xmm3
vmovdqa 0x50(%r12), %xmm4
vmovdqa 0x60(%r12), %xmm5
vmovdqa 0x60(%rsp), %xmm10
vpxor %xmm4, %xmm10, %xmm6
vaesenc %xmm2, %xmm6, %xmm6
vaesenc %xmm3, %xmm6, %xmm6
vaesenc %xmm5, %xmm6, %xmm6
vaesenc %xmm2, %xmm6, %xmm6
vaesenc %xmm3, %xmm6, %xmm6
vaesenc %xmm5, %xmm6, %xmm6
vaesenc %xmm2, %xmm6, %xmm6
vaesenc %xmm3, %xmm6, %xmm6
vaesenc %xmm5, %xmm6, %xmm6
vaesenc %xmm2, %xmm6, %xmm6
vpternlogq $0x96, %xmm9, %xmm10, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm3, %xmm4, %xmm4
vaesenc %xmm5, %xmm4, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm3, %xmm4, %xmm4
vaesenc %xmm5, %xmm4, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm3, %xmm4, %xmm3
vaesenc %xmm5, %xmm3, %xmm3
vaesenc %xmm2, %xmm3, %xmm2
vpxor 0x80(%rsp), %xmm2, %xmm2
movl %ebx, %eax
leaq 0x17a1(%rip), %rcx      # 0x40c0
subq %rax, %rcx
vmovdqu 0x20(%rcx), %xmm3
vpternlogq $0xea, 0x30(%rcx), %xmm2, %xmm3
vpxor 0x20(%rsp), %xmm6, %xmm2
vmovdqa 0x10(%rsp), %xmm5
vpxor %xmm5, %xmm2, %xmm4
vaesenc %xmm9, %xmm4, %xmm4
vaesenc %xmm7, %xmm4, %xmm4
vaesenc %xmm8, %xmm4, %xmm4
vaesenc %xmm0, %xmm4, %xmm0
vpternlogq $0x96, %xmm7, %xmm3, %xmm5
vaesenc %xmm9, %xmm5, %xmm4
vaesenc %xmm7, %xmm4, %xmm4
vaesenc %xmm8, %xmm4, %xmm4
vpxor %xmm5, %xmm5, %xmm5
vaesenc %xmm5, %xmm4, %xmm4
vpxor %xmm0, %xmm4, %xmm0
movl %r15d, %eax
vmovdqu %xmm2, (%r13,%rax)
vmovdqu %xmm3, 0x10(%r13,%rax)
movl 0x4(%rsp), %esi
movq 0x8(%rsp), %rdx
jmp 0x2a3c
vmovdqa 0x60(%rsp), %xmm2
testl %ebx, %ebx
movl 0x4(%rsp), %esi
movq 0x8(%rsp), %rdx
je 0x2a3c
vpxor 0x50(%r12), %xmm2, %xmm2
vmovdqa (%r12), %xmm3
vmovdqa 0x30(%r12), %xmm4
vmovdqa 0x60(%r12), %xmm5
vaesenc %xmm3, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm5, %xmm2, %xmm2
vaesenc %xmm3, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm5, %xmm2, %xmm2
vaesenc %xmm3, %xmm2, %xmm2
vaesenc %xmm4, %xmm2, %xmm2
vaesenc %xmm5, %xmm2, %xmm2
vaesenc %xmm3, %xmm2, %xmm2
vpxor 0x20(%rsp), %xmm2, %xmm2
movl %ebx, %eax
leaq 0x16b8(%rip), %rcx      # 0x40c0
subq %rax, %rcx
vmovdqu 0x10(%rcx), %xmm3
vpternlogq $0xea, 0x20(%rcx), %xmm2, %xmm3
vpxor 0x10(%rsp), %xmm3, %xmm2
vaesenc %xmm9, %xmm2, %xmm2
vaesenc %xmm7, %xmm2, %xmm2
vaesenc %xmm8, %xmm2, %xmm2
vaesenc %xmm0, %xmm2, %xmm0
movl %r15d, %eax
vmovdqu %xmm3, (%r13,%rax)
testl %esi, %esi
sete %al
testl %r14d, %r14d
sete %cl
vmovdqa 0x70(%rsp), %xmm2
vpternlogq $0x96, %xmm0, %xmm1, %xmm2
vmovdqu %xmm2, (%r13,%rdx)
orb %al, %cl
jne 0x2a89
xorl %r14d, %r14d
cmpl $0x10, %esi
je 0x2aa4
addl $-0x10, %ebp
addq %rbp, %r13
movl $0xf, %edx
subl %esi, %edx
incq %rdx
leaq 0xc0(%rsp), %rsi
movq %r13, %rdi
callq 0x10b0
jmp 0x2aa4
vmovdqa 0x90(%rsp), %xmm0
vmovdqu %xmm0, 0x10(%r13,%rdx)
xorl %r14d, %r14d
jmp 0x2aa4
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
movl %r14d, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq