// File: /workspace/github_c_makefile_star2_O3/mjosaarinen[P]brutus/crypto_aead/aezv3/ref/aez_ref.c
// Function: AEZcore
static void AEZcore(byte *K, unsigned kbytes, byte delta[16],
                        byte *in, unsigned inbytes, unsigned d, byte *out) {
    byte tmp[16], X[16], Y[16], S[16];
    byte *in_orig = in, *out_orig = out;
    unsigned j, inbytes_orig = inbytes;

    memset(X,0,16); memset(Y,0,16);
    
    /* Pass 1 over in[0:-32], store intermediate values in out[0:-32] */
    for (j=1; inbytes >= 64; j++, inbytes-=32, in+=32, out+=32) {
        E(K, kbytes, 1, j, in+16, tmp); xor_bytes(in, tmp, 16, out);
        E(K, kbytes, 0, 0, out, tmp); xor_bytes(in+16, tmp, 16, out+16);
        xor_bytes(out+16, X, 16, X);
    }

    /* Finish X calculation */
    inbytes -= 32;                /* inbytes now has fragment length 0..31 */
    if (inbytes >= 16) {
        E(K, kbytes, 0, 4, in, tmp); xor_bytes(X, tmp, 16, X);
        inbytes -= 16; in += 16; out += 16;
        memset(tmp,0,16); memcpy(tmp,in,inbytes); tmp[inbytes] = 0x80;
        E(K, kbytes, 0, 5, tmp, tmp); xor_bytes(X, tmp, 16, X);
    } else if (inbytes > 0) {
        memset(tmp,0,16); memcpy(tmp,in,inbytes); tmp[inbytes] = 0x80;
        E(K, kbytes, 0, 4, tmp, tmp); xor_bytes(X, tmp, 16, X);
    }
    in += inbytes; out += inbytes;

    /* Calculate S */
    E(K, kbytes, 0, 1+d, in+16, tmp);
    xor_bytes(X, in, 16, out);
    xor_bytes(delta, out, 16, out);
    xor_bytes(tmp, out, 16, out);
    E(K, kbytes, -1, 1+d, out, tmp);
    xor_bytes(in+16, tmp, 16, out+16);
    xor_bytes(out, out+16, 16, S);

    /* Pass 2 over intermediate values in out[32..]. Final values written */
    inbytes = inbytes_orig; out = out_orig; in = in_orig;
    for (j=1; inbytes >= 64; j++, inbytes-=32, in+=32, out+=32) {
        E(K, kbytes, 2, j, S, tmp);
        xor_bytes(out, tmp, 16, out); xor_bytes(out+16, tmp, 16, out+16);
        xor_bytes(out, Y, 16, Y);
        E(K, kbytes, 0, 0, out+16, tmp); xor_bytes(out, tmp, 16, out);
        E(K, kbytes, 1, j, out, tmp); xor_bytes(out+16, tmp, 16, out+16);
        memcpy(tmp, out, 16); memcpy(out, out+16, 16); memcpy(out+16, tmp, 16);
    }

    /* Finish Y calculation and finish encryption of fragment bytes */
    inbytes -= 32;                /* inbytes now has fragment length 0..31 */
    if (inbytes >= 16) {
        E(K, kbytes, -1, 4, S, tmp); xor_bytes(in, tmp, 16, out);
        E(K, kbytes, 0, 4, out, tmp); xor_bytes(Y, tmp, 16, Y);
        inbytes -= 16; in += 16; out += 16;
        E(K, kbytes, -1, 5, S, tmp); xor_bytes(in, tmp, inbytes, tmp);
        memcpy(out,tmp,inbytes);
        memset(tmp+inbytes,0,16-inbytes); tmp[inbytes] = 0x80;
        E(K, kbytes, 0, 5, tmp, tmp); xor_bytes(Y, tmp, 16, Y);
    } else if (inbytes > 0) {
        E(K, kbytes, -1, 4, S, tmp); xor_bytes(in, tmp, inbytes, tmp);
        memcpy(out,tmp,inbytes);
        memset(tmp+inbytes,0,16-inbytes); tmp[inbytes] = 0x80;
        E(K, kbytes, 0, 4, tmp, tmp); xor_bytes(Y, tmp, 16, Y);
    }
    in += inbytes; out += inbytes;

    /* Finish encryption of last two blocks */
    E(K, kbytes, -1, 2-d, out+16, tmp);
    xor_bytes(out, tmp, 16, out);
    E(K, kbytes, 0, 2-d, out, tmp);
    xor_bytes(tmp, out+16, 16, out+16);
    xor_bytes(delta, out+16, 16, out+16);
    xor_bytes(Y, out+16, 16, out+16);
    memcpy(tmp, out, 16); memcpy(out, out+16, 16); memcpy(out+16, tmp, 16);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %r9, 0x68(%rsp)
movq %rcx, %r12
movq %rdx, 0x60(%rsp)
movl %esi, 0xc(%rsp)
movq %rdi, 0x28(%rsp)
movq 0xe0(%rsp), %r14
vxorps %xmm0, %xmm0, %xmm0
vmovaps %xmm0, 0x50(%rsp)
vmovaps %xmm0, 0x40(%rsp)
movl %r8d, %r13d
movq %rcx, 0x30(%rsp)
movq %r8, 0x38(%rsp)
cmpl $0x40, %r8d
jb 0x2656
movq 0x38(%rsp), %r13
leal -0x40(%r13), %r15d
shrl $0x5, %r15d
incl %r15d
movl $0x1, %ebp
vmovaps 0x50(%rsp), %xmm0
leaq 0x10(%rsp), %rbx
movq 0x30(%rsp), %r12
vmovaps %xmm0, 0x70(%rsp)
leaq 0x10(%r12), %r8
movq 0x28(%rsp), %rdi
movl 0xc(%rsp), %esi
movl $0x1, %edx
movl %ebp, %ecx
movq %rbx, %r9
callq 0x19ae
movl $0xf, %eax
movb 0x10(%rsp,%rax), %cl
xorb (%r12,%rax), %cl
movb %cl, (%r14,%rax)
addq $-0x1, %rax
jb 0x25e7
movq 0x28(%rsp), %rdi
movl 0xc(%rsp), %esi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r14, %r8
movq %rbx, %r9
callq 0x19ae
movl $0x1f, %eax
movb (%rsp,%rax), %cl
xorb (%r12,%rax), %cl
movb %cl, (%r14,%rax)
decq %rax
cmpq $0xf, %rax
jne 0x2616
vmovaps 0x70(%rsp), %xmm0
vxorps 0x10(%r14), %xmm0, %xmm0
vmovaps %xmm0, 0x50(%rsp)
leal 0x1(%rbp), %eax
addl $-0x20, %r13d
addq $0x20, %r12
addq $0x20, %r14
cmpl %r15d, %ebp
movl %eax, %ebp
jne 0x25bf
leal -0x20(%r13), %ebp
cmpl $0x10, %ebp
jb 0x26ef
leaq 0x10(%rsp), %r15
movq 0x28(%rsp), %rbp
movq %rbp, %rdi
movl 0xc(%rsp), %ebx
movl %ebx, %esi
xorl %edx, %edx
movl $0x4, %ecx
movq %r12, %r8
movq %r15, %r9
callq 0x19ae
vmovaps (%r15), %xmm0
vxorps 0x50(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x50(%rsp)
addl $-0x30, %r13d
addq $0x10, %r12
vxorps %xmm0, %xmm0, %xmm0
vmovaps %xmm0, (%r15)
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x10d0
movb $-0x80, 0x10(%rsp,%r13)
movq %rbp, %rdi
movl %ebx, %esi
xorl %edx, %edx
movl $0x5, %ecx
movq %r15, %r8
movq %r15, %r9
callq 0x19ae
vmovaps (%r15), %xmm0
vxorps 0x50(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x50(%rsp)
addq $0x10, %r14
movl %r13d, %ebp
jmp 0x2751
testl %ebp, %ebp
je 0x274b
vxorps %xmm0, %xmm0, %xmm0
leaq 0x10(%rsp), %r15
vmovaps %xmm0, (%r15)
movl %ebp, %r13d
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x10d0
movb $-0x80, 0x10(%rsp,%r13)
movq 0x28(%rsp), %r13
movq %r13, %rdi
movl 0xc(%rsp), %ebx
movl %ebx, %esi
xorl %edx, %edx
movl $0x4, %ecx
movq %r15, %r8
movq %r15, %r9
callq 0x19ae
vmovaps (%r15), %xmm0
vxorps 0x50(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x50(%rsp)
jmp 0x2756
xorl %ebp, %ebp
movl 0xc(%rsp), %ebx
movq 0x28(%rsp), %r13
movl %ebp, %eax
leaq (%r12,%rax), %r15
addq %rax, %r14
movq 0x68(%rsp), %rcx
leal 0x1(%rcx), %ebp
leaq (%r12,%rax), %r8
addq $0x10, %r8
leaq 0x10(%rsp), %r9
movq %r13, %rdi
movl %ebx, %esi
xorl %edx, %edx
movl %ebp, %ecx
callq 0x19ae
movl $0xf, %eax
movq 0xe0(%rsp), %r13
movb (%r15,%rax), %cl
xorb 0x50(%rsp,%rax), %cl
movb %cl, (%r14,%rax)
addq $-0x1, %rax
jb 0x278f
movl $0xf, %eax
movq 0x60(%rsp), %r12
movb (%r12,%rax), %cl
xorb %cl, (%r14,%rax)
addq $-0x1, %rax
jb 0x27ab
movl $0xf, %eax
movb 0x10(%rsp,%rax), %cl
xorb %cl, (%r14,%rax)
addq $-0x1, %rax
jb 0x27be
leaq 0x10(%rsp), %r9
movq 0x28(%rsp), %rdi
movl %ebx, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl %ebp, %ecx
movq %r14, %r8
callq 0x19ae
movl $0x1f, %eax
movb (%rsp,%rax), %cl
xorb (%r15,%rax), %cl
movb %cl, (%r14,%rax)
decq %rax
cmpq $0xf, %rax
jne 0x27ec
movl $0xf, %eax
movb 0x10(%r14,%rax), %cl
xorb (%r14,%rax), %cl
movb %cl, 0x80(%rsp,%rax)
addq $-0x1, %rax
jb 0x2805
movq 0x38(%rsp), %r14
cmpl $0x40, %r14d
jb 0x29a6
leal -0x40(%r14), %eax
shrl $0x5, %eax
vmovaps 0x40(%rsp), %xmm0
vmovaps %xmm0, 0x70(%rsp)
negl %eax
movq %rax, 0x90(%rsp)
movl $0x1, %r12d
xorl %ebx, %ebx
xorl %edx, %edx
movq 0x28(%rsp), %r14
movl 0xc(%rsp), %r15d
movq %rdx, 0xa0(%rsp)
leaq (%rbx,%r13), %rax
movq %rax, 0x98(%rsp)
movq %r14, %rdi
movl %r15d, %esi
movl $0x2, %edx
movl %r12d, %ecx
leaq 0x80(%rsp), %r8
leaq 0x10(%rsp), %rbp
movq %rbp, %r9
callq 0x19ae
vmovaps 0x10(%rsp), %xmm0
movq 0xe0(%rsp), %rax
leaq (%rax,%rbx), %r13
addq $0x10, %r13
vxorps -0x10(%r13), %xmm0, %xmm1
vmovups %xmm1, -0x10(%r13)
vxorps (%r13), %xmm0, %xmm0
vmovups %xmm0, (%r13)
vmovaps 0x70(%rsp), %xmm0
vxorps %xmm1, %xmm0, %xmm0
vmovaps %xmm0, 0x70(%rsp)
vmovaps %xmm0, 0x40(%rsp)
movq %r14, %rdi
movl %r15d, %esi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r13, %r8
movq %rbp, %r9
callq 0x19ae
vmovaps 0x10(%rsp), %xmm0
vxorps -0x10(%r13), %xmm0, %xmm0
vmovups %xmm0, -0x10(%r13)
movq %r14, %rdi
movl %r15d, %esi
movl $0x1, %edx
movl %r12d, %ecx
movq 0x98(%rsp), %r8
movq %rbp, %r9
callq 0x19ae
movq 0xa0(%rsp), %rdx
vmovaps 0x10(%rsp), %xmm0
vxorps (%r13), %xmm0, %xmm0
vmovups %xmm0, (%r13)
vmovups -0x10(%r13), %xmm0
vmovaps %xmm0, 0x10(%rsp)
vmovups (%r13), %xmm0
vmovups %xmm0, -0x10(%r13)
vmovaps 0x10(%rsp), %xmm0
vmovups %xmm0, (%r13)
movq 0xe0(%rsp), %r13
addq $-0x20, %rdx
movq 0x90(%rsp), %rax
addl %r12d, %eax
incl %eax
movl %r12d, %ecx
incl %ecx
addq $0x20, %rbx
movl %ecx, %r12d
cmpl $0x2, %eax
jne 0x285b
movq 0x30(%rsp), %rax
subq %rdx, %rax
movq 0x38(%rsp), %r14
subl %ebx, %r14d
subq %rdx, %r13
movq 0x60(%rsp), %r12
movq 0x28(%rsp), %r15
jmp 0x29b0
movq 0x28(%rsp), %r15
movq 0x30(%rsp), %rax
leal -0x20(%r14), %ebp
cmpl $0x10, %ebp
jb 0x2ac9
movq %r14, 0x38(%rsp)
movq %rax, 0x30(%rsp)
leaq 0x80(%rsp), %r8
leaq 0x10(%rsp), %r9
movq %r15, %rdi
movl 0xc(%rsp), %ebp
movl %ebp, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl $0x4, %ecx
callq 0x19ae
movq 0x30(%rsp), %rdx
movl $0xf, %eax
movb 0x10(%rsp,%rax), %cl
xorb (%rdx,%rax), %cl
movb %cl, (%r13,%rax)
addq $-0x1, %rax
jb 0x29f6
xorl %ebx, %ebx
leaq 0x10(%rsp), %r14
movq %r15, %rdi
movl %ebp, %esi
xorl %edx, %edx
movl $0x4, %ecx
movq %r13, %r8
movq %r14, %r9
callq 0x19ae
vmovaps (%r14), %xmm0
vxorps 0x40(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x40(%rsp)
addq $0x10, %r13
leaq 0x80(%rsp), %r8
movq %r15, %rdi
movl %ebp, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl $0x5, %ecx
movq %r14, %r9
callq 0x19ae
movq 0x38(%rsp), %r14
movl %r14d, %ebp
addl $-0x30, %ebp
je 0x2a7e
movl %ebp, %ebx
movq %rbx, %rax
movq 0x30(%rsp), %rdx
movb 0xf(%rdx,%rax), %cl
xorb %cl, 0xf(%rsp,%rax)
decq %rax
jne 0x2a71
leaq 0x10(%rsp), %r15
movq %r13, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x10d0
addq %rsp, %rbx
addq $0x10, %rbx
movl $0x40, %edx
subl %r14d, %edx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1040
movb $-0x80, (%rbx)
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
movl 0xc(%rsp), %r14d
movl %r14d, %esi
xorl %edx, %edx
movl $0x5, %ecx
jmp 0x2b52
testl %ebp, %ebp
je 0x2c43
movq %rax, %rbx
leaq 0x80(%rsp), %r8
leaq 0x10(%rsp), %r9
movq %r15, %rdi
movl 0xc(%rsp), %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl $0x4, %ecx
callq 0x19ae
movq %rbx, %rdx
movl %ebp, %ebx
movq %rbx, %rax
movb -0x1(%rdx,%rax), %cl
xorb %cl, 0xf(%rsp,%rax)
decq %rax
jne 0x2aff
leaq 0x10(%rsp), %r15
movq %r13, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x10d0
addq %rsp, %rbx
addq $0x10, %rbx
movl $0x30, %edx
subl %r14d, %edx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1040
movb $-0x80, (%rbx)
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
movl 0xc(%rsp), %r14d
movl %r14d, %esi
xorl %edx, %edx
movl $0x4, %ecx
movq %r15, %r8
movq %r15, %r9
callq 0x19ae
movq %rbx, %rdi
vmovaps (%r15), %xmm0
vxorps 0x40(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x40(%rsp)
movl %ebp, %r15d
leaq (%r15,%r13), %rbx
movl $0x2, %ebp
subl 0x68(%rsp), %ebp
leaq (%r15,%r13), %rax
addq $0x10, %rax
leaq 0x10(%rsp), %r9
movl %r14d, %esi
movq %rax, %r14
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl %ebp, %ecx
movq %rax, %r8
callq 0x19ae
movl $0xf, %eax
movb 0x10(%rsp,%rax), %cl
xorb %cl, (%rbx,%rax)
addq $-0x1, %rax
jb 0x2ba8
leaq 0x10(%rsp), %r9
movq 0x28(%rsp), %rdi
movl 0xc(%rsp), %esi
xorl %edx, %edx
movl %ebp, %ecx
movq %rbx, %r8
callq 0x19ae
movl $0x1f, %eax
movb (%rsp,%rax), %cl
xorb %cl, (%rbx,%rax)
decq %rax
cmpq $0xf, %rax
jne 0x2bd4
leaq (%r15,%r13), %rax
addq $0x1f, %rax
xorl %ecx, %ecx
movb 0xf(%r12,%rcx), %dl
xorb %dl, (%rax,%rcx)
decq %rcx
cmpq $-0x10, %rcx
jne 0x2bed
movl $0x1f, %eax
movb 0x30(%rsp,%rax), %cl
xorb %cl, (%rbx,%rax)
decq %rax
cmpq $0xf, %rax
jne 0x2c03
vmovups (%rbx), %xmm0
vmovaps %xmm0, 0x10(%rsp)
vmovups (%r14), %xmm0
vmovups %xmm0, (%rbx)
vmovaps 0x10(%rsp), %xmm0
vmovups %xmm0, (%r14)
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ebp, %ebp
movl 0xc(%rsp), %r14d
movq %r15, %rdi
jmp 0x2b71
nop