// File: /workspace/github_c_makefile_star2_O1/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, 0x20(%rsp)
movq 0xe0(%rsp), %r14
vxorps %xmm0, %xmm0, %xmm0
vmovaps %xmm0, 0x40(%rsp)
vmovaps %xmm0, 0x30(%rsp)
movl %r8d, %r13d
movq %rcx, 0x58(%rsp)
movq %r8, 0x28(%rsp)
cmpl $0x40, %r8d
jb 0x261c
movq 0x28(%rsp), %r13
leal -0x40(%r13), %r15d
shrl $0x5, %r15d
incl %r15d
movl $0x1, %ebp
vmovaps 0x40(%rsp), %xmm0
leaq 0x10(%rsp), %rbx
movq 0x58(%rsp), %r12
vmovaps %xmm0, 0x70(%rsp)
leaq 0x10(%r12), %r8
movq 0x20(%rsp), %rdi
movl 0xc(%rsp), %esi
movl $0x1, %edx
movl %ebp, %ecx
movq %rbx, %r9
callq 0x19a2
movl $0xf, %eax
movb 0x10(%rsp,%rax), %cl
xorb (%r12,%rax), %cl
movb %cl, (%r14,%rax)
addq $-0x1, %rax
jb 0x25ad
movq 0x20(%rsp), %rdi
movl 0xc(%rsp), %esi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r14, %r8
movq %rbx, %r9
callq 0x19a2
movl $0x1f, %eax
movb (%rsp,%rax), %cl
xorb (%r12,%rax), %cl
movb %cl, (%r14,%rax)
decq %rax
cmpq $0xf, %rax
jne 0x25dc
vmovaps 0x70(%rsp), %xmm0
vxorps 0x10(%r14), %xmm0, %xmm0
vmovaps %xmm0, 0x40(%rsp)
leal 0x1(%rbp), %eax
addl $-0x20, %r13d
addq $0x20, %r12
addq $0x20, %r14
cmpl %r15d, %ebp
movl %eax, %ebp
jne 0x2585
leal -0x20(%r13), %ebp
cmpl $0x10, %ebp
jb 0x26b5
leaq 0x10(%rsp), %r15
movq 0x20(%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 0x19a2
vmovaps (%r15), %xmm0
vxorps 0x40(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x40(%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 0x19a2
vmovaps (%r15), %xmm0
vxorps 0x40(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x40(%rsp)
addq $0x10, %r14
movl %r13d, %ebp
jmp 0x2717
testl %ebp, %ebp
je 0x2711
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 0x20(%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 0x19a2
vmovaps (%r15), %xmm0
vxorps 0x40(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x40(%rsp)
jmp 0x271c
xorl %ebp, %ebp
movl 0xc(%rsp), %ebx
movq 0x20(%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 0x19a2
movl $0xf, %eax
movq 0xe0(%rsp), %r13
movb (%r15,%rax), %cl
xorb 0x40(%rsp,%rax), %cl
movb %cl, (%r14,%rax)
addq $-0x1, %rax
jb 0x2755
movl $0xf, %eax
movq 0x60(%rsp), %r12
movb (%r12,%rax), %cl
xorb %cl, (%r14,%rax)
addq $-0x1, %rax
jb 0x2771
movl $0xf, %eax
movb 0x10(%rsp,%rax), %cl
xorb %cl, (%r14,%rax)
addq $-0x1, %rax
jb 0x2784
leaq 0x10(%rsp), %r9
movq 0x20(%rsp), %rdi
movl %ebx, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl %ebp, %ecx
movq %r14, %r8
callq 0x19a2
movl $0x1f, %eax
movb (%rsp,%rax), %cl
xorb (%r15,%rax), %cl
movb %cl, (%r14,%rax)
decq %rax
cmpq $0xf, %rax
jne 0x27b2
movl $0xf, %eax
movq 0x28(%rsp), %rdx
movb 0x10(%r14,%rax), %cl
xorb (%r14,%rax), %cl
movb %cl, 0x80(%rsp,%rax)
addq $-0x1, %rax
jb 0x27d0
cmpl $0x40, %edx
jb 0x2963
leal -0x40(%rdx), %eax
shrl $0x5, %eax
vmovaps 0x30(%rsp), %xmm0
vmovaps %xmm0, 0x70(%rsp)
negl %eax
movq %rax, 0x90(%rsp)
movl $0x1, %r12d
xorl %ebx, %ebx
xorl %esi, %esi
movq 0x20(%rsp), %r15
movl 0xc(%rsp), %ebp
movq %rsi, 0xa0(%rsp)
leaq (%rbx,%r13), %rax
movq %rax, 0x98(%rsp)
movq %r15, %rdi
movl %ebp, %esi
movl $0x2, %edx
movl %r12d, %ecx
leaq 0x80(%rsp), %r8
leaq 0x10(%rsp), %r14
movq %r14, %r9
callq 0x19a2
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, 0x30(%rsp)
movq %r15, %rdi
movl %ebp, %esi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r13, %r8
movq %r14, %r9
callq 0x19a2
vmovaps 0x10(%rsp), %xmm0
vxorps -0x10(%r13), %xmm0, %xmm0
vmovups %xmm0, -0x10(%r13)
movq %r15, %rdi
movl %ebp, %esi
movl $0x1, %edx
movl %r12d, %ecx
movq 0x98(%rsp), %r8
movq %r14, %r9
callq 0x19a2
movq 0xa0(%rsp), %rsi
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, %rsi
movq 0x90(%rsp), %rax
addl %r12d, %eax
incl %eax
movl %r12d, %ecx
incl %ecx
addq $0x20, %rbx
movl %ecx, %r12d
cmpl $0x2, %eax
jne 0x281e
movq 0x58(%rsp), %rax
subq %rsi, %rax
movq 0x28(%rsp), %rdx
subl %ebx, %edx
subq %rsi, %r13
movq %rax, %r15
movq 0x60(%rsp), %r12
jmp 0x2968
movq 0x58(%rsp), %r15
leal -0x20(%rdx), %ebp
cmpl $0x10, %ebp
movq 0x20(%rsp), %r14
jb 0x2a73
movq %rdx, 0x28(%rsp)
leaq 0x80(%rsp), %r8
leaq 0x10(%rsp), %r9
movq %r14, %rdi
movl 0xc(%rsp), %ebp
movl %ebp, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl $0x4, %ecx
callq 0x19a2
movl $0xf, %eax
movb 0x10(%rsp,%rax), %cl
xorb (%r15,%rax), %cl
movb %cl, (%r13,%rax)
addq $-0x1, %rax
jb 0x29a8
leaq 0x10(%rsp), %rbx
movq %r14, %rdi
movl %ebp, %esi
xorl %edx, %edx
movl $0x4, %ecx
movq %r13, %r8
movq %rbx, %r9
callq 0x19a2
vmovaps (%rbx), %xmm0
vxorps 0x30(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x30(%rsp)
addq $0x10, %r13
leaq 0x80(%rsp), %r8
movq %r14, %rdi
movl %ebp, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl $0x5, %ecx
movq %rbx, %r9
callq 0x19a2
movq 0x28(%rsp), %rax
movl %eax, %ebp
addl $-0x30, %ebp
movl %ebp, %ebx
je 0x2a29
movq %rbx, %rax
movb 0xf(%r15,%rax), %cl
xorb %cl, 0xf(%rsp,%rax)
decq %rax
jne 0x2a1b
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 0x28(%rsp), %edx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1040
movb $-0x80, (%rbx)
movq %r14, %rdi
movq %r14, %rbx
movl 0xc(%rsp), %r14d
movl %r14d, %esi
xorl %edx, %edx
movl $0x5, %ecx
jmp 0x2afb
testl %ebp, %ebp
je 0x2bec
movq %rdx, 0x28(%rsp)
leaq 0x80(%rsp), %r8
leaq 0x10(%rsp), %r9
movq %r14, %rdi
movl 0xc(%rsp), %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl $0x4, %ecx
callq 0x19a2
movl %ebp, %ebx
movq %rbx, %rax
movb -0x1(%r15,%rax), %cl
xorb %cl, 0xf(%rsp,%rax)
decq %rax
jne 0x2aa8
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 0x28(%rsp), %edx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1040
movb $-0x80, (%rbx)
movq %r14, %rdi
movq %r14, %rbx
movl 0xc(%rsp), %r14d
movl %r14d, %esi
xorl %edx, %edx
movl $0x4, %ecx
movq %r15, %r8
movq %r15, %r9
callq 0x19a2
movq %rbx, %rdi
vmovaps (%r15), %xmm0
vxorps 0x30(%rsp), %xmm0, %xmm0
vmovaps %xmm0, 0x30(%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 0x19a2
movl $0xf, %eax
movb 0x10(%rsp,%rax), %cl
xorb %cl, (%rbx,%rax)
addq $-0x1, %rax
jb 0x2b51
leaq 0x10(%rsp), %r9
movq 0x20(%rsp), %rdi
movl 0xc(%rsp), %esi
xorl %edx, %edx
movl %ebp, %ecx
movq %rbx, %r8
callq 0x19a2
movl $0x1f, %eax
movb (%rsp,%rax), %cl
xorb %cl, (%rbx,%rax)
decq %rax
cmpq $0xf, %rax
jne 0x2b7d
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 0x2b96
movl $0x1f, %eax
movb 0x20(%rsp,%rax), %cl
xorb %cl, (%rbx,%rax)
decq %rax
cmpq $0xf, %rax
jne 0x2bac
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
movq %r14, %rdi
movl 0xc(%rsp), %r14d
jmp 0x2b1a
nop