// File: /workspace/github_c_makefile_star2_O0/mjosaarinen[P]brutus/crypto_aead/aezv3/ref/aez_ref.c
// Function: E
static void E(byte *K, unsigned kbytes, int i, unsigned j,
                                                byte src[16], byte dst[16]) {
    byte k, extracted_key[3*16], iJ[16], jJ[16], buf[16], I[16], J[16], L[16];

    Extract(K, kbytes, extracted_key);
    memcpy(I,extracted_key,16);
    memcpy(J,extracted_key+16,16);
    memcpy(L,extracted_key+32,16);

    /* Encipher */
    if (i < 0) {
        u32 aes_key[4*11];
        memset(aes_key,0,16);                                  /* 0        */
        memcpy((byte*)aes_key+ 16, I, 16);                     /* I        */
        memcpy((byte*)aes_key+ 32, L, 16);                     /* L        */
        memcpy((byte*)aes_key+ 48, J, 16);                     /* J        */
        correct_key(aes_key,4*16);
        memcpy((byte*)aes_key+ 64, (byte*)aes_key+16, 48);     /* I L J    */
        memcpy((byte*)aes_key+112, (byte*)aes_key+16, 48);     /* I L J    */
        memcpy((byte*)aes_key+160, (byte*)aes_key+16, 16);     /* I        */
        mult_block(j,J,jJ); xor_bytes(jJ,src,16,buf);
        rijndaelEncryptRound(aes_key, 11, buf, 10); /* incl final MixColumns */
    } else {
        u32 aes4_key[4*5];
        unsigned first = (i>=3?0:i);  /* Which key comes first in aes4_key */
        /* Build AES4 key in use */
        memset((byte *)aes4_key, 0, 16);
        for (k=0; k<3; k++)
            memcpy((byte*)aes4_key+16+k*16, extracted_key+(k+first)%3*16, 16);
        if (i==2) memcpy((byte*)aes4_key+64, I, 16);
        else      memset((byte*)aes4_key+64, 0, 16);
        correct_key(aes4_key,5*16);
        /* Build encryption buffer from src and various offsets used */
        memcpy(buf, src, 16);
        if (i == 0) {
            mult_block(j,J,jJ); xor_bytes(buf,jJ,16,buf);
        } else if (i==1 || i==2) {
            mult_block(j%8,J,jJ); xor_bytes(buf,jJ,16,buf);
            for ( ; j>8; j-=8) mult_block(2,L,L);  /* L = 2^((j-1)/8) L */
            xor_bytes(buf, L, 16, buf);
        } else /* i >= 3 */ {
            mult_block((i-2)*8,J,iJ); xor_bytes(buf,iJ,16,buf);
            if (j>0) {
                mult_block(j%8,J,jJ); xor_bytes(buf,jJ,16,buf);
                for ( ; j>8; j-=8) mult_block(2,L,L);  /* L = 2^((j-1)/8) L */
                xor_bytes(buf, L, 16, buf);
            }
        }
        rijndaelEncryptRound(aes4_key, 10, buf, 4);
    }
    memcpy(dst, buf, 16);
}

// Assembly:
subq $0x1d8, %rsp            # imm = 0x1D8
movq %rdi, 0x1d0(%rsp)
movl %esi, 0x1cc(%rsp)
movl %edx, 0x1c8(%rsp)
movl %ecx, 0x1c4(%rsp)
movq %r8, 0x1b8(%rsp)
movq %r9, 0x1b0(%rsp)
movq 0x1d0(%rsp), %rdi
movl 0x1cc(%rsp), %esi
leaq 0x170(%rsp), %rdx
callq 0x21d0
movq 0x170(%rsp), %rax
movq %rax, 0x130(%rsp)
movq 0x178(%rsp), %rax
movq %rax, 0x138(%rsp)
movq 0x180(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x188(%rsp), %rax
movq %rax, 0x128(%rsp)
movq 0x190(%rsp), %rax
movq %rax, 0x110(%rsp)
movq 0x198(%rsp), %rax
movq %rax, 0x118(%rsp)
cmpl $0x0, 0x1c8(%rsp)
jge 0x1e29
leaq 0x60(%rsp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x1040
movq 0x130(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x138(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x110(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x118(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x120(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x98(%rsp)
leaq 0x60(%rsp), %rdi
movl $0x40, %esi
callq 0x25c0
leaq 0x60(%rsp), %rdi
addq $0x40, %rdi
leaq 0x60(%rsp), %rsi
addq $0x10, %rsi
movl $0x30, %edx
callq 0x10d0
leaq 0x60(%rsp), %rdi
addq $0x70, %rdi
leaq 0x60(%rsp), %rsi
addq $0x10, %rsi
movl $0x30, %edx
callq 0x10d0
movq 0x70(%rsp), %rax
movq %rax, 0x100(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x108(%rsp)
movl 0x1c4(%rsp), %edi
leaq 0x120(%rsp), %rsi
leaq 0x150(%rsp), %rdx
callq 0x2620
leaq 0x150(%rsp), %rdi
movq 0x1b8(%rsp), %rsi
leaq 0x140(%rsp), %rcx
movl $0x10, %edx
callq 0x2170
leaq 0x60(%rsp), %rdi
leaq 0x140(%rsp), %rdx
movl $0xb, %esi
movl $0xa, %ecx
callq 0x10c0
jmp 0x2148
cmpl $0x3, 0x1c8(%rsp)
jl 0x1e3b
xorl %eax, %eax
movl %eax, 0x8(%rsp)
jmp 0x1e46
movl 0x1c8(%rsp), %eax
movl %eax, 0x8(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0xc(%rsp)
leaq 0x10(%rsp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x1040
movb $0x0, 0x1af(%rsp)
movzbl 0x1af(%rsp), %eax
cmpl $0x3, %eax
jge 0x1ecf
movzbl 0x1af(%rsp), %eax
shll $0x4, %eax
cltq
movq %rax, (%rsp)
movzbl 0x1af(%rsp), %eax
addl 0xc(%rsp), %eax
movl $0x3, %ecx
xorl %edx, %edx
divl %ecx
movq (%rsp), %rax
shll $0x4, %edx
movl %edx, %ecx
movq 0x170(%rsp,%rcx), %rdx
movq %rdx, 0x20(%rsp,%rax)
movq 0x178(%rsp,%rcx), %rcx
movq %rcx, 0x28(%rsp,%rax)
movb 0x1af(%rsp), %al
addb $0x1, %al
movb %al, 0x1af(%rsp)
jmp 0x1e67
cmpl $0x2, 0x1c8(%rsp)
jne 0x1ef5
movq 0x130(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x138(%rsp), %rax
movq %rax, 0x58(%rsp)
jmp 0x1f0a
leaq 0x10(%rsp), %rdi
addq $0x40, %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x1040
leaq 0x10(%rsp), %rdi
movl $0x50, %esi
callq 0x25c0
movq 0x1b8(%rsp), %rax
movq (%rax), %rcx
movq %rcx, 0x140(%rsp)
movq 0x8(%rax), %rax
movq %rax, 0x148(%rsp)
cmpl $0x0, 0x1c8(%rsp)
jne 0x1f85
movl 0x1c4(%rsp), %edi
leaq 0x120(%rsp), %rsi
leaq 0x150(%rsp), %rdx
callq 0x2620
leaq 0x140(%rsp), %rdi
leaq 0x150(%rsp), %rsi
leaq 0x140(%rsp), %rcx
movl $0x10, %edx
callq 0x2170
jmp 0x212c
cmpl $0x1, 0x1c8(%rsp)
je 0x1f9d
cmpl $0x2, 0x1c8(%rsp)
jne 0x203c
movl 0x1c4(%rsp), %edi
andl $0x7, %edi
leaq 0x120(%rsp), %rsi
leaq 0x150(%rsp), %rdx
callq 0x2620
leaq 0x140(%rsp), %rdi
leaq 0x150(%rsp), %rsi
leaq 0x140(%rsp), %rcx
movl $0x10, %edx
callq 0x2170
cmpl $0x8, 0x1c4(%rsp)
jbe 0x2015
leaq 0x110(%rsp), %rsi
leaq 0x110(%rsp), %rdx
movl $0x2, %edi
callq 0x2620
movl 0x1c4(%rsp), %eax
subl $0x8, %eax
movl %eax, 0x1c4(%rsp)
jmp 0x1fde
leaq 0x140(%rsp), %rdi
leaq 0x110(%rsp), %rsi
leaq 0x140(%rsp), %rcx
movl $0x10, %edx
callq 0x2170
jmp 0x212a
movl 0x1c8(%rsp), %edi
subl $0x2, %edi
shll $0x3, %edi
leaq 0x120(%rsp), %rsi
leaq 0x160(%rsp), %rdx
callq 0x2620
leaq 0x140(%rsp), %rdi
leaq 0x160(%rsp), %rsi
leaq 0x140(%rsp), %rcx
movl $0x10, %edx
callq 0x2170
cmpl $0x0, 0x1c4(%rsp)
jbe 0x2128
movl 0x1c4(%rsp), %edi
andl $0x7, %edi
leaq 0x120(%rsp), %rsi
leaq 0x150(%rsp), %rdx
callq 0x2620
leaq 0x140(%rsp), %rdi
leaq 0x150(%rsp), %rsi
leaq 0x140(%rsp), %rcx
movl $0x10, %edx
callq 0x2170
cmpl $0x8, 0x1c4(%rsp)
jbe 0x2106
leaq 0x110(%rsp), %rsi
leaq 0x110(%rsp), %rdx
movl $0x2, %edi
callq 0x2620
movl 0x1c4(%rsp), %eax
subl $0x8, %eax
movl %eax, 0x1c4(%rsp)
jmp 0x20cf
leaq 0x140(%rsp), %rdi
leaq 0x110(%rsp), %rsi
leaq 0x140(%rsp), %rcx
movl $0x10, %edx
callq 0x2170
jmp 0x212a
jmp 0x212c
leaq 0x10(%rsp), %rdi
leaq 0x140(%rsp), %rdx
movl $0xa, %esi
movl $0x4, %ecx
callq 0x10c0
movq 0x1b0(%rsp), %rax
movq 0x140(%rsp), %rcx
movq %rcx, (%rax)
movq 0x148(%rsp), %rcx
movq %rcx, 0x8(%rax)
addq $0x1d8, %rsp            # imm = 0x1D8
retq
nop