// File: /workspace/github_c_makefile_star2_O3/mjosaarinen[P]brutus/crypto_aead/minalpherv11/ref/minalpher.c
// Function: MAC_GEN
int MAC_GEN(
  const unsigned char     *_K,    /* I    Secret key              */
  const unsigned char     *_M,    /* I    Message                 */
  unsigned long long      _mlen,  /* I    Length of Message       */

  unsigned char           *C_,    /* O    Tag                     */
  unsigned long long      *clen_  /* O    Length of Tag           */
  )
{
  int d, pad;
  unsigned long long i, blocknum;
  const unsigned char *mp;
  unsigned char *cp, in[BLOCK_SIZE], out[BLOCK_SIZE], t[BLOCK_SIZE], zero[NONCEBYTES];

  i = 1;
  mp = _M;
  cp = C_;

  pad = _mlen%BLOCK_SIZE;
  blocknum = _mlen/BLOCK_SIZE;
  if( (pad!=0) || (_mlen==0) ) blocknum += 1;
  Clear( t, BLOCK_SIZE );
  Clear( zero, NONCEBYTES );

  while( blocknum > 1 ){

    Copy( in, mp, BLOCK_SIZE );
    TEM_ENC( _K, FLG_MAC, zero, i, 0, in, out );
    Xor( t, out, BLOCK_SIZE );

    i++;
    blocknum--;
    mp += BLOCK_SIZE;
  }

  /* blocknum == 1 */
  if( (pad==0) && (_mlen!=0) ){
    Copy( in, mp, BLOCK_SIZE );
  }else{
    Copy( in, mp, pad );
    in[pad] = 0x80;
    for( d=pad+1; d<BLOCK_SIZE; d++ ) in[d] = 0x00;
  }

  Xor( in, t, BLOCK_SIZE );
  if( (pad==0) && (_mlen!=0) ){
    TEM_ENC( _K, FLG_MAC, zero, i-1, 1, in, out );
  }else{
    TEM_ENC( _K, FLG_MAC, zero, i-1, 2, in, out );
  }
  Copy( cp, out, TAGBYTES );
  *clen_ = TAGBYTES;

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %r8, %rbx
movq %rcx, %r14
movq %rsi, %rbp
movl %edx, %r9d
andl $0x1f, %r9d
setne %al
testq %rdx, %rdx
sete %cl
orb %al, %cl
movzbl %cl, %eax
movq %rdx, %r13
shrq $0x5, %r13
addq %rax, %r13
xorl %r12d, %r12d
movq %r12, 0x15(%rsp)
movq %r12, 0x10(%rsp)
vxorps %xmm0, %xmm0, %xmm0
leaq 0x80(%rsp), %r15
cmpq $0x2, %r13
jb 0x197d
movq %rdx, 0x48(%rsp)
movl %r9d, 0xc(%rsp)
movq %r14, 0x50(%rsp)
movq %rbx, 0x58(%rsp)
movl $0x1, %r12d
leaq 0x20(%rsp), %r14
vmovups %ymm0, 0x60(%rsp)
vmovups (%rbp), %ymm0
vmovups %ymm0, 0x20(%rsp)
movq %r15, (%rsp)
movq %rdi, %rbx
movl $0x80, %esi
leaq 0x10(%rsp), %rdx
movq %r12, %rcx
xorl %r8d, %r8d
movq %r14, %r9
vzeroupper
callq 0x1a70
vmovups 0x60(%rsp), %ymm0
movq %rbx, %rdi
vxorps 0x80(%rsp), %ymm0, %ymm0
incq %r12
addq $0x20, %rbp
cmpq %r12, %r13
jne 0x1915
decq %r12
movq 0x58(%rsp), %rbx
movq 0x50(%rsp), %r14
movl 0xc(%rsp), %r9d
movq 0x48(%rsp), %rdx
testl %r9d, %r9d
setne %al
testq %rdx, %rdx
sete %cl
orb %al, %cl
jne 0x19a8
xorl %eax, %eax
movb (%rbp,%rax), %cl
movb %cl, 0x20(%rsp,%rax)
incq %rax
cmpq $0x20, %rax
jne 0x198f
movl $0x1, %r8d
jmp 0x1a1f
movl %edx, %eax
andl $0x1f, %eax
testl %r9d, %r9d
je 0x19de
xorl %ecx, %ecx
movb (%rbp,%rcx), %r8b
movb %r8b, 0x20(%rsp,%rcx)
incq %rcx
cmpq %rcx, %rax
jne 0x19b4
movl %edx, %eax
andl $0x1f, %eax
movb $-0x80, 0x20(%rsp,%rax)
movl $0x2, %r8d
cmpl $0x1f, %r9d
jne 0x19e3
jmp 0x1a1f
movb $-0x80, 0x20(%rsp,%rax)
andl $0x1f, %edx
movq %rdi, %r13
leaq (%rsp,%rdx), %rdi
addq $0x21, %rdi
xorl %eax, %eax
movl $0x1e, %edx
subl %r9d, %edx
cmovbl %eax, %edx
incl %edx
xorl %esi, %esi
vmovups %ymm0, 0x60(%rsp)
vzeroupper
callq 0x1040
vmovups 0x60(%rsp), %ymm0
movq %r13, %rdi
movl $0x2, %r8d
leaq 0x20(%rsp), %r9
vxorps (%r9), %ymm0, %ymm0
vmovups %ymm0, (%r9)
movq %r15, (%rsp)
leaq 0x10(%rsp), %rdx
movl $0x80, %esi
movq %r12, %rcx
vzeroupper
callq 0x1a70
vmovaps 0x80(%rsp), %xmm0
vmovups %xmm0, (%r14)
movq $0x10, (%rbx)
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq