// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/aezv4/aesni/encrypt.c
// Function: aez_hash
block aez_hash(aez_ctx_t *ctx, char *n, unsigned nbytes, char *ad,
               unsigned adbytes, unsigned abytes) {
    block o0, o1, o2, o3, o4, o5, o6, o7, sum, offset, tmp;
    block I=ctx->I[0], L=ctx->L, J=ctx->J[0];
    block Jfordoubling = double_block(bswap16(ctx->J[2]));  /* 8J */
    block J8 = bswap16(Jfordoubling);
    block L2 = bswap16(tmp = double_block(bswap16(L)));
    block L4 = bswap16(tmp = double_block(tmp));
    
    /* Process abytes and nonce */
    offset = vxor(L,J8);
    tmp = zero_set_byte((char)(8*abytes),15);
    sum = aes4(vxor(offset,tmp),J,I,L,offset);
    offset = L2;
    if (nbytes==16) offset = vxor(offset, J8);
    tmp = one_zero_pad(load_partial(n,nbytes),16-nbytes);
    sum = vxor(sum, aes4(vxor(offset,tmp),J,I,L,offset));
    
    if (adbytes==0) {
        offset = L4;
        ctx->delta3_cache = aes4(vxor(offset,loadu(pad+32)),J,I,L,offset);
    } else if (ad) {
        block delta3 = zero;
        offset = vxor(L4, J8);
        while (adbytes >= 8*16) {
            o0 = offset;
            o1 = vxor(o0,ctx->J[0]);
            o2 = vxor(o0,ctx->J[1]);
            o3 = vxor(o1,ctx->J[1]);
            o4 = vxor(o0,ctx->J[2]);
            o5 = vxor(o1,ctx->J[2]);
            o6 = vxor(o2,ctx->J[2]);
            o7 = vxor(o3,ctx->J[2]);
            offset = vxor(L4, bswap16(Jfordoubling = double_block(Jfordoubling)));
            delta3 = vxor(delta3, aes4(vxor(load(ad+  0),o0), J, I, L, o0));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 16),o1), J, I, L, o1));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 32),o2), J, I, L, o2));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 48),o3), J, I, L, o3));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 64),o4), J, I, L, o4));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 80),o5), J, I, L, o5));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 96),o6), J, I, L, o6));
            delta3 = vxor(delta3, aes4(vxor(load(ad+112),o7), J, I, L, o7));
            adbytes-=8*16; ad+=8*16;
        }
        if (adbytes >= 4*16) {
            o0 = offset;
            o1 = vxor(o0,ctx->J[0]);
            o2 = vxor(o0,ctx->J[1]);
            o3 = vxor(o1,ctx->J[1]);
            offset = vxor(o0,ctx->J[2]);
            delta3 = vxor(delta3, aes4(vxor(load(ad+  0),o0), J, I, L, o0));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 16),o1), J, I, L, o1));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 32),o2), J, I, L, o2));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 48),o3), J, I, L, o3));
            adbytes-=4*16; ad+=4*16;
        }
        if (adbytes >= 2*16) {
            o0 = offset;
            o1 = vxor(o0,ctx->J[0]);
            offset = vxor(o0,ctx->J[1]);
            delta3 = vxor(delta3, aes4(vxor(load(ad+  0),o0), J, I, L, o0));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 16),o1), J, I, L, o1));
            adbytes-=2*16; ad+=2*16;
        }
        if (adbytes >= 1*16) {
            o0 = offset;
            delta3 = vxor(delta3, aes4(vxor(load(ad+  0),o0), J, I, L, o0));
            adbytes-=1*16; ad+=1*16;
        }
        if (adbytes) {
            tmp = one_zero_pad(load(ad),16-adbytes);
            delta3 = vxor(delta3,aes4(vxor(tmp,L4), J, I, L, L4));
        }
        ctx->delta3_cache = delta3;
    }
    return vxor(sum,ctx->delta3_cache);
}

// Assembly:
vmovdqa (%rdi), %xmm1
vmovdqa 0x30(%rdi), %xmm3
vmovdqa 0x50(%rdi), %xmm10
vmovdqa 0x60(%rdi), %xmm2
vmovdqa 0x2bd9(%rip), %xmm0     # 0x4000
vpshufb %xmm0, %xmm10, %xmm4
vpshufd $0x93, %xmm4, %xmm5     # xmm5 = xmm4[3,0,1,2]
vpshufd $0x93, 0x2bd6(%rip), %xmm6 # xmm6 = mem[3,0,1,2]
vpsrad $0x1f, %xmm5, %xmm5
vpaddd %xmm4, %xmm4, %xmm11
vpternlogd $0x78, %xmm6, %xmm5, %xmm11
vpshufb %xmm0, %xmm11, %xmm19
vpshufb %xmm0, %xmm2, %xmm4
vpshufd $0x93, %xmm4, %xmm5     # xmm5 = xmm4[3,0,1,2]
vpsrad $0x1f, %xmm5, %xmm20
vpaddd %xmm4, %xmm4, %xmm4
vpternlogd $0x6c, %xmm6, %xmm4, %xmm20
vpshufd $0x93, %xmm4, %xmm4     # xmm4 = xmm4[3,0,1,2]
vpsrad $0x1f, %xmm4, %xmm4
vpaddd %xmm20, %xmm20, %xmm5
vpternlogd $0x78, %xmm6, %xmm4, %xmm5
vpshufb %xmm0, %xmm5, %xmm9
vmovdqu64 (%rsi), %xmm16
pushq $0x10
popq %rsi
subl %edx, %esi
leaq 0x2bf6(%rip), %rax      # 0x4090
vmovdqu64 (%rsi,%rax), %xmm18
vmovdqu64 0x10(%rsi,%rax), %xmm17
testl %r8d, %r8d
je 0x16c1
testq %rcx, %rcx
je 0x16e2
addq $0x40, %rcx
vpxor %xmm0, %xmm0, %xmm0
vpmovzxbd 0x2ba3(%rip), %xmm21 # 0x4070
vmovdqa64 0x2b29(%rip), %xmm22 # 0x4000
vmovdqa64 %xmm19, %xmm15
vpxor %xmm9, %xmm15, %xmm14
vpxor %xmm3, %xmm14, %xmm6
cmpl $0x80, %r8d
jb 0x162d
vmovdqa 0x40(%rdi), %xmm4
vpxor %xmm4, %xmm14, %xmm12
vpxor %xmm6, %xmm4, %xmm13
vpxor %xmm10, %xmm14, %xmm5
vpxor %xmm6, %xmm10, %xmm4
vpxor %xmm10, %xmm12, %xmm8
vpxor %xmm10, %xmm13, %xmm7
vpshufd $0x93, %xmm11, %xmm15   # xmm15 = xmm11[3,0,1,2]
vpsrad $0x1f, %xmm15, %xmm15
vpaddd %xmm11, %xmm11, %xmm11
vpternlogd $0x78, %xmm21, %xmm15, %xmm11
vpshufb %xmm22, %xmm11, %xmm15
vmovdqa64 %xmm9, %xmm23
vpxor -0x40(%rcx), %xmm14, %xmm9
vaesenc %xmm3, %xmm9, %xmm9
vaesenc %xmm1, %xmm9, %xmm9
vaesenc %xmm2, %xmm9, %xmm9
vaesenc %xmm14, %xmm9, %xmm14
vpxor -0x30(%rcx), %xmm6, %xmm9
vaesenc %xmm3, %xmm9, %xmm9
vaesenc %xmm1, %xmm9, %xmm9
vaesenc %xmm2, %xmm9, %xmm9
vaesenc %xmm6, %xmm9, %xmm9
vpxor -0x20(%rcx), %xmm12, %xmm6
vaesenc %xmm3, %xmm6, %xmm6
vaesenc %xmm1, %xmm6, %xmm6
vaesenc %xmm2, %xmm6, %xmm6
vaesenc %xmm12, %xmm6, %xmm6
vpxor -0x10(%rcx), %xmm13, %xmm12
vaesenc %xmm3, %xmm12, %xmm12
vaesenc %xmm1, %xmm12, %xmm12
vaesenc %xmm2, %xmm12, %xmm12
vaesenc %xmm13, %xmm12, %xmm12
vpxor (%rcx), %xmm5, %xmm13
vaesenc %xmm3, %xmm13, %xmm13
vaesenc %xmm1, %xmm13, %xmm13
vaesenc %xmm2, %xmm13, %xmm13
vaesenc %xmm5, %xmm13, %xmm5
vpxor 0x10(%rcx), %xmm4, %xmm13
vaesenc %xmm3, %xmm13, %xmm13
vaesenc %xmm1, %xmm13, %xmm13
vaesenc %xmm2, %xmm13, %xmm13
vaesenc %xmm4, %xmm13, %xmm4
vpxor 0x20(%rcx), %xmm8, %xmm13
vaesenc %xmm3, %xmm13, %xmm13
vaesenc %xmm1, %xmm13, %xmm13
vaesenc %xmm2, %xmm13, %xmm13
vaesenc %xmm8, %xmm13, %xmm8
vpxor 0x30(%rcx), %xmm7, %xmm13
vaesenc %xmm3, %xmm13, %xmm13
vaesenc %xmm1, %xmm13, %xmm13
vaesenc %xmm2, %xmm13, %xmm13
vaesenc %xmm7, %xmm13, %xmm7
vpternlogq $0x96, %xmm9, %xmm14, %xmm6
vmovdqa64 %xmm23, %xmm9
vpternlogq $0x96, %xmm12, %xmm5, %xmm6
vpternlogq $0x96, %xmm4, %xmm8, %xmm6
vpternlogq $0x96, %xmm7, %xmm6, %xmm0
addl $-0x80, %r8d
subq $-0x80, %rcx
jmp 0x14dd
cmpl $0x40, %r8d
jb 0x16ec
vmovdqa 0x40(%rdi), %xmm4
vpxor %xmm4, %xmm14, %xmm5
vpxor -0x40(%rcx), %xmm14, %xmm7
vaesenc %xmm3, %xmm7, %xmm7
vaesenc %xmm1, %xmm7, %xmm7
vaesenc %xmm2, %xmm7, %xmm7
vaesenc %xmm14, %xmm7, %xmm7
vpxor %xmm10, %xmm14, %xmm14
vpxor %xmm6, %xmm4, %xmm4
vpxor -0x30(%rcx), %xmm6, %xmm8
vaesenc %xmm3, %xmm8, %xmm8
vaesenc %xmm1, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm6, %xmm8, %xmm6
vpxor -0x20(%rcx), %xmm5, %xmm8
vaesenc %xmm3, %xmm8, %xmm8
vaesenc %xmm1, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm5, %xmm8, %xmm5
vpxor -0x10(%rcx), %xmm4, %xmm8
vaesenc %xmm3, %xmm8, %xmm8
vaesenc %xmm1, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm4, %xmm8, %xmm4
vpternlogq $0x96, %xmm6, %xmm7, %xmm5
vpternlogq $0x96, %xmm4, %xmm5, %xmm0
addl $-0x40, %r8d
jmp 0x16f0
vpxor 0x2967(%rip), %xmm9, %xmm0 # 0x4030
vaesenc %xmm3, %xmm0, %xmm0
vaesenc %xmm1, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm9, %xmm0, %xmm0
jmp 0x179d
vmovdqa 0x70(%rdi), %xmm0
jmp 0x17a2
addq $-0x40, %rcx
cmpl $0x20, %r8d
jb 0x173f
vpxor %xmm3, %xmm14, %xmm4
vpxor (%rcx), %xmm14, %xmm5
vaesenc %xmm3, %xmm5, %xmm5
vaesenc %xmm1, %xmm5, %xmm5
vaesenc %xmm2, %xmm5, %xmm5
vaesenc %xmm14, %xmm5, %xmm5
vpxor 0x40(%rdi), %xmm14, %xmm14
vpxor 0x10(%rcx), %xmm4, %xmm6
vaesenc %xmm3, %xmm6, %xmm6
vaesenc %xmm1, %xmm6, %xmm6
vaesenc %xmm2, %xmm6, %xmm6
vaesenc %xmm4, %xmm6, %xmm4
vpternlogq $0x96, %xmm4, %xmm5, %xmm0
addl $-0x20, %r8d
addq $0x20, %rcx
cmpl $0x10, %r8d
jb 0x1769
vpxor (%rcx), %xmm14, %xmm4
vaesenc %xmm3, %xmm4, %xmm4
vaesenc %xmm1, %xmm4, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm14, %xmm4, %xmm4
vpxor %xmm0, %xmm4, %xmm0
addl $-0x10, %r8d
addq $0x10, %rcx
testl %r8d, %r8d
je 0x179d
movl %r8d, %esi
subq %rsi, %rax
vmovdqu 0x10(%rax), %xmm4
vpand (%rcx), %xmm4, %xmm4
vpternlogq $0x36, 0x20(%rax), %xmm9, %xmm4
vaesenc %xmm3, %xmm4, %xmm4
vaesenc %xmm1, %xmm4, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm9, %xmm4, %xmm4
vpxor %xmm0, %xmm4, %xmm0
vmovdqa %xmm0, 0x70(%rdi)
vpxorq %xmm19, %xmm2, %xmm4
shlb $0x3, %r9b
vpxor %xmm5, %xmm5, %xmm5
vpinsrb $0xf, %r9d, %xmm5, %xmm5
vpxor %xmm5, %xmm4, %xmm5
vaesenc %xmm3, %xmm5, %xmm5
vaesenc %xmm1, %xmm5, %xmm5
vaesenc %xmm2, %xmm5, %xmm5
vaesenc %xmm4, %xmm5, %xmm4
cmpl $0x10, %edx
je 0x17d9
vpxord %xmm19, %xmm19, %xmm19
vpshufb 0x281d(%rip), %xmm20, %xmm5 # 0x4000
vpxorq %xmm5, %xmm19, %xmm5
vpandq %xmm16, %xmm18, %xmm6
vpternlogq $0x36, %xmm17, %xmm5, %xmm6
vaesenc %xmm3, %xmm6, %xmm3
vaesenc %xmm1, %xmm3, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
vaesenc %xmm5, %xmm1, %xmm1
vpternlogq $0x96, %xmm4, %xmm1, %xmm0
retq