// File: adamjanovsky[P]PA193_test_parser_monero/src/keccak/Keccak-readable-and-compact.c
// Function: Keccak
void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen)
{
    UINT8 state[200];
    unsigned int rateInBytes = rate/8;
    unsigned int blockSize = 0;
    unsigned int i;
    
    if (((rate + capacity) != 1600) || ((rate % 8) != 0))
        return;
    
    /* === Initialize the state === */
    memset(state, 0, sizeof(state));
    
    /* === Absorb all the input blocks === */
    while(inputByteLen > 0) {
        blockSize = MIN((unsigned int)inputByteLen, rateInBytes);
        for(i=0; i<blockSize; i++)
            state[i] ^= input[i];
        input += blockSize;
        inputByteLen -= blockSize;
        
        if (blockSize == rateInBytes) {
            KeccakF1600_StatePermute(state);
            blockSize = 0;
        }
    }
    
    /* === Do the padding and switch to the squeezing phase === */
    /* Absorb the last few bits and add the first bit of padding (which coincides with the delimiter in delimitedSuffix) */
    state[blockSize] ^= delimitedSuffix;
    /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */
    if (((delimitedSuffix & 0x80) != 0) && (blockSize == (rateInBytes-1)))
        KeccakF1600_StatePermute(state);
    /* Add the second bit of padding */
    state[rateInBytes-1] ^= 0x80;
    /* Switch to the squeezing phase */
    KeccakF1600_StatePermute(state);
    
    /* === Squeeze out all the output blocks === */
    while(outputByteLen > 0) {
        blockSize = MIN((unsigned int)outputByteLen, rateInBytes);
        memcpy(output, state, blockSize);
        output += blockSize;
        outputByteLen -= blockSize;
        
        if (outputByteLen > 0)
            KeccakF1600_StatePermute(state);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movb %r8b, %al
movq 0x10(%rbp), %r8
movl %edi, -0x4(%rbp)
movl %esi, -0x8(%rbp)
movq %rdx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movb %al, -0x19(%rbp)
movq %r9, -0x28(%rbp)
movl -0x4(%rbp), %eax
shrl $0x3, %eax
movl %eax, -0xf4(%rbp)
movl $0x0, -0xf8(%rbp)
movl -0x4(%rbp), %eax
addl -0x8(%rbp), %eax
cmpl $0x640, %eax            # imm = 0x640
jne 0x8625
movl -0x4(%rbp), %eax
andl $0x7, %eax
cmpl $0x0, %eax
je 0x862a
jmp 0x881a
leaq -0xf0(%rbp), %rdi
xorl %esi, %esi
movl $0xc8, %edx
callq 0x20f0
cmpq $0x0, -0x18(%rbp)
jbe 0x8715
movq -0x18(%rbp), %rax
cmpl -0xf4(%rbp), %eax
jae 0x8660
movq -0x18(%rbp), %rax
movl %eax, -0x100(%rbp)
jmp 0x866c
movl -0xf4(%rbp), %eax
movl %eax, -0x100(%rbp)
movl -0x100(%rbp), %eax
movl %eax, -0xf8(%rbp)
movl $0x0, -0xfc(%rbp)
movl -0xfc(%rbp), %eax
cmpl -0xf8(%rbp), %eax
jae 0x86c6
movq -0x10(%rbp), %rax
movl -0xfc(%rbp), %ecx
movzbl (%rax,%rcx), %edx
movl -0xfc(%rbp), %eax
movzbl -0xf0(%rbp,%rax), %ecx
xorl %edx, %ecx
movb %cl, -0xf0(%rbp,%rax)
movl -0xfc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xfc(%rbp)
jmp 0x8682
movl -0xf8(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x10(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x18(%rbp)
movl -0xf8(%rbp), %eax
cmpl -0xf4(%rbp), %eax
jne 0x8710
leaq -0xf0(%rbp), %rdi
callq 0x8a20
movl $0x0, -0xf8(%rbp)
jmp 0x863d
movzbl -0x19(%rbp), %edx
movl -0xf8(%rbp), %eax
movzbl -0xf0(%rbp,%rax), %ecx
xorl %edx, %ecx
movb %cl, -0xf0(%rbp,%rax)
movzbl -0x19(%rbp), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x875d
movl -0xf8(%rbp), %eax
movl -0xf4(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x875d
leaq -0xf0(%rbp), %rdi
callq 0x8a20
movl -0xf4(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movzbl -0xf0(%rbp,%rax), %ecx
xorl $0x80, %ecx
movb %cl, -0xf0(%rbp,%rax)
leaq -0xf0(%rbp), %rdi
callq 0x8a20
cmpq $0x0, 0x10(%rbp)
jbe 0x881a
movq 0x10(%rbp), %rax
cmpl -0xf4(%rbp), %eax
jae 0x87ac
movq 0x10(%rbp), %rax
movl %eax, -0x104(%rbp)
jmp 0x87b8
movl -0xf4(%rbp), %eax
movl %eax, -0x104(%rbp)
movl -0x104(%rbp), %eax
movl %eax, -0xf8(%rbp)
movq -0x28(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
movl -0xf8(%rbp), %eax
movl %eax, %edx
callq 0x2120
movl -0xf8(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, %ecx
movq 0x10(%rbp), %rax
subq %rcx, %rax
movq %rax, 0x10(%rbp)
cmpq $0x0, 0x10(%rbp)
jbe 0x8815
leaq -0xf0(%rbp), %rdi
callq 0x8a20
jmp 0x8789
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
nopw %cs:(%rax,%rax)