// File: /workspace/github_c_makefile_star2_O3/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 0x2adf(%rip), %xmm0     # 0x4030
vpshufb %xmm0, %xmm10, %xmm4
vpshufd $0x93, %xmm4, %xmm5     # xmm5 = xmm4[3,0,1,2]
vpshufd $0x93, 0x2adc(%rip), %xmm6 # xmm6 = mem[3,0,1,2]
vpsrad $0x1f, %xmm5, %xmm5
vpaddd %xmm4, %xmm4, %xmm11
vpternlogd $0x78, %xmm6, %xmm5, %xmm11
vpshufb %xmm0, %xmm11, %xmm21
vpshufb %xmm0, %xmm2, %xmm7
vpshufd $0x93, %xmm7, %xmm5     # xmm5 = xmm7[3,0,1,2]
vpsrad $0x1f, %xmm5, %xmm22
vpaddd %xmm7, %xmm7, %xmm7
vpternlogd $0x6c, %xmm6, %xmm7, %xmm22
vpshufd $0x93, %xmm7, %xmm7     # xmm7 = xmm7[3,0,1,2]
vpsrad $0x1f, %xmm7, %xmm7
vpaddd %xmm22, %xmm22, %xmm13
vpternlogd $0x78, %xmm6, %xmm7, %xmm13
vpshufb %xmm0, %xmm13, %xmm4
vmovdqu64 (%rsi), %xmm18
movl $0x10, %esi
subl %edx, %esi
leaq 0x2afa(%rip), %rax      # 0x40c0
vmovdqu64 (%rsi,%rax), %xmm20
vmovdqu64 0x10(%rsi,%rax), %xmm19
testl %r8d, %r8d
je 0x18af
testq %rcx, %rcx
je 0x18d2
vmovdqa64 %xmm4, %xmm25
vpxorq %xmm4, %xmm21, %xmm12
vpxor %xmm0, %xmm0, %xmm0
cmpl $0x80, %r8d
jb 0x1761
vmovdqa 0x40(%rdi), %xmm14
vpxord %xmm17, %xmm17, %xmm17
vpmovzxbd 0x2a8b(%rip), %xmm24 # 0x40a4
vmovdqa64 0x2a0d(%rip), %xmm16 # 0x4030
vpxor %xmm3, %xmm12, %xmm0
vpxor %xmm12, %xmm14, %xmm4
vpxor %xmm0, %xmm14, %xmm5
vpxor %xmm10, %xmm12, %xmm9
vpxor %xmm0, %xmm10, %xmm8
vpxor %xmm4, %xmm10, %xmm7
vpxor %xmm5, %xmm10, %xmm6
vpshufd $0x93, %xmm11, %xmm23   # xmm23 = xmm11[3,0,1,2]
vpsrad $0x1f, %xmm23, %xmm23
vpaddd %xmm11, %xmm11, %xmm11
vpternlogd $0x78, %xmm24, %xmm23, %xmm11
vpxor (%rcx), %xmm12, %xmm15
vaesenc %xmm3, %xmm15, %xmm15
vaesenc %xmm1, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vaesenc %xmm12, %xmm15, %xmm12
vpxor 0x10(%rcx), %xmm0, %xmm15
vaesenc %xmm3, %xmm15, %xmm15
vaesenc %xmm1, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vaesenc %xmm0, %xmm15, %xmm0
vpxor 0x20(%rcx), %xmm4, %xmm15
vaesenc %xmm3, %xmm15, %xmm15
vaesenc %xmm1, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vaesenc %xmm4, %xmm15, %xmm4
vpxor 0x30(%rcx), %xmm5, %xmm15
vaesenc %xmm3, %xmm15, %xmm15
vaesenc %xmm1, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vaesenc %xmm5, %xmm15, %xmm5
vpxor 0x40(%rcx), %xmm9, %xmm15
vaesenc %xmm3, %xmm15, %xmm15
vaesenc %xmm1, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vaesenc %xmm9, %xmm15, %xmm9
vpxor 0x50(%rcx), %xmm8, %xmm15
vaesenc %xmm3, %xmm15, %xmm15
vaesenc %xmm1, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vaesenc %xmm8, %xmm15, %xmm8
vpxor 0x60(%rcx), %xmm7, %xmm15
vaesenc %xmm3, %xmm15, %xmm15
vaesenc %xmm1, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vaesenc %xmm7, %xmm15, %xmm7
vpxor 0x70(%rcx), %xmm6, %xmm15
vaesenc %xmm3, %xmm15, %xmm15
vaesenc %xmm1, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vaesenc %xmm6, %xmm15, %xmm6
vpternlogq $0x96, %xmm17, %xmm12, %xmm0
vpternlogq $0x96, %xmm4, %xmm5, %xmm0
vpternlogq $0x96, %xmm9, %xmm8, %xmm0
vpternlogq $0x96, %xmm7, %xmm6, %xmm0
addl $-0x80, %r8d
subq $-0x80, %rcx
vpxor %xmm13, %xmm11, %xmm4
vpshufb %xmm16, %xmm4, %xmm12
vmovdqa64 %xmm0, %xmm17
cmpl $0x7f, %r8d
ja 0x1623
cmpl $0x40, %r8d
jb 0x17fa
vpxor %xmm3, %xmm12, %xmm4
vmovdqa 0x40(%rdi), %xmm5
vpxor %xmm5, %xmm12, %xmm6
vpxor %xmm4, %xmm5, %xmm5
vpxor (%rcx), %xmm12, %xmm7
vaesenc %xmm3, %xmm7, %xmm7
vaesenc %xmm1, %xmm7, %xmm7
vaesenc %xmm2, %xmm7, %xmm7
vaesenc %xmm12, %xmm7, %xmm7
vpxor %xmm10, %xmm12, %xmm12
vpxor 0x10(%rcx), %xmm4, %xmm8
vaesenc %xmm3, %xmm8, %xmm8
vaesenc %xmm1, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm4, %xmm8, %xmm4
vpxor 0x20(%rcx), %xmm6, %xmm8
vaesenc %xmm3, %xmm8, %xmm8
vaesenc %xmm1, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm6, %xmm8, %xmm6
vpxor 0x30(%rcx), %xmm5, %xmm8
vaesenc %xmm3, %xmm8, %xmm8
vaesenc %xmm1, %xmm8, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm5, %xmm8, %xmm5
vpternlogq $0x96, %xmm4, %xmm7, %xmm6
vpternlogq $0x96, %xmm5, %xmm6, %xmm0
addl $-0x40, %r8d
addq $0x40, %rcx
cmpl $0x20, %r8d
jb 0x1849
vpxor %xmm3, %xmm12, %xmm4
vpxor (%rcx), %xmm12, %xmm5
vaesenc %xmm3, %xmm5, %xmm5
vaesenc %xmm1, %xmm5, %xmm5
vaesenc %xmm2, %xmm5, %xmm5
vaesenc %xmm12, %xmm5, %xmm5
vpxor 0x40(%rdi), %xmm12, %xmm12
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 0x1873
vpxor (%rcx), %xmm12, %xmm4
vaesenc %xmm3, %xmm4, %xmm4
vaesenc %xmm1, %xmm4, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm12, %xmm4, %xmm4
vpxor %xmm0, %xmm4, %xmm0
addl $-0x10, %r8d
addq $0x10, %rcx
testl %r8d, %r8d
je 0x18cb
movl %r8d, %esi
subq %rsi, %rax
vmovdqu 0x10(%rax), %xmm4
vpand (%rcx), %xmm4, %xmm4
vmovdqa64 %xmm25, %xmm5
vpternlogq $0x36, 0x20(%rax), %xmm25, %xmm4
vaesenc %xmm3, %xmm4, %xmm4
vaesenc %xmm1, %xmm4, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm5, %xmm4, %xmm4
vpxor %xmm0, %xmm4, %xmm0
jmp 0x18cb
vpxor 0x27a9(%rip), %xmm4, %xmm0 # 0x4060
vaesenc %xmm3, %xmm0, %xmm0
vaesenc %xmm1, %xmm0, %xmm0
vaesenc %xmm2, %xmm0, %xmm0
vaesenc %xmm4, %xmm0, %xmm0
vmovdqa %xmm0, 0x70(%rdi)
jmp 0x18d7
vmovdqa 0x70(%rdi), %xmm0
vpxorq %xmm21, %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, %xmm6
cmpl $0x10, %edx
je 0x190e
vpxord %xmm21, %xmm21, %xmm21
vpshufb 0x2718(%rip), %xmm22, %xmm4 # 0x4030
vpxorq %xmm4, %xmm21, %xmm4
vpandq %xmm18, %xmm20, %xmm5
vpternlogq $0x36, %xmm19, %xmm4, %xmm5
vaesenc %xmm3, %xmm5, %xmm3
vaesenc %xmm1, %xmm3, %xmm1
vaesenc %xmm2, %xmm1, %xmm1
vaesenc %xmm4, %xmm1, %xmm1
vpternlogq $0x96, %xmm6, %xmm1, %xmm0
retq