// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/src/speed.c
// Function: run_speed
int run_speed(caesar_t *aead,
                unsigned long long mlen, unsigned long long adlen,
                clock_t limit)
{
    int ret, i, sta, stb;
    unsigned long long clen, t, bytes;
    clock_t stim, etim;
    uint8_t key[80], nsec[64], osec[64], npub[64];
    // that 524304 ABYTES factor comes from Trivia. Don't ask.
    uint8_t pt[0x10000], ad[0x10000], ct[0x10000 + 524304];
    double encspeed, decspeed;

    if (mlen > sizeof(pt) || adlen > sizeof(ad)) {
        fprintf(stderr, "run_speed(): invalid parameters\n");
        return -1;
    }

    limit *= CLOCKS_PER_SEC;

    // random fill contents
    detseq_fill(pt, mlen);
    detseq_fill(ad, adlen);
    detseq_fill(key, aead->keybytes);
    detseq_fill(nsec, aead->nsecbytes);
    detseq_fill(npub, aead->npubbytes);

    encspeed = 0.0;
    decspeed = 0.0;

    stim = clock();
    bytes = 0;
    sta = 1;
    stb = 1;
    do {
        for (i = 0; i < sta; i++) {
            clen = 0;
            ret = aead->encrypt(ct, &clen, pt, mlen, ad, adlen,
                nsec, npub, key);
            if (ret != 0 || clen <= 0) {
                fprintf(stderr, "!ERROR\t%s encrypt(%llu)=%d\n",
                    aead->name, mlen, ret);
                return -1;
            }
        }
        bytes += i * (mlen + adlen);
        sta += stb;
        stb = i;

        etim = clock() - stim;
    } while (etim < limit);

    encspeed = ((double) CLOCKS_PER_SEC) * ((double) bytes) / ((double) etim);
    printf("[%s] %.2f kB/s  encrypt(mlen=%llu adlen=%llu)\n",
        aead->name, encspeed / 1000.0, mlen, adlen);

    stim = clock();
    bytes = 0;
    sta = 1;
    stb = 1;
    do {
        for (i = 0; i < sta; i++) {
            ret = aead->decrypt(pt, &t, osec, ct, clen, ad,
                adlen, npub, key);
            if (ret != 0) {
                fprintf(stderr, "!ERROR\t%s decrypt(%llu)=%d\n",
                    aead->name, clen, ret);
                return -2;
            }
        }
        bytes += i * (mlen + adlen);
        sta += stb;
        stb = i;

        etim = clock() - stim;
    } while (etim < limit);

    decspeed = ((double) CLOCKS_PER_SEC) * ((double) bytes) / ((double) etim);
    printf("[%s] %.2f kB/s  decrypt(mlen=%llu adlen=%llu)\n",
        aead->name, decspeed / 1000.0, mlen, adlen);
    fflush(stdout);

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb0168, %rsp          # imm = 0xB0168
movq %rsi, 0x8(%rsp)
cmpq $0x10000, %rsi          # imm = 0x10000
ja 0x1e53
movq %rdx, %r14
cmpq $0x10001, %rdx          # imm = 0x10001
jae 0x1e53
movq %rdi, %r15
imulq $0xf4240, %rcx, %rax    # imm = 0xF4240
movq %rax, 0x30(%rsp)
leaq 0x10150(%rsp), %rdi
movq 0x8(%rsp), %rbx
movl %ebx, %esi
callq 0x196e
leaq 0x150(%rsp), %rdi
movl %r14d, %esi
callq 0x196e
movl 0x10(%r15), %esi
leaq 0x80(%rsp), %rdi
callq 0x196e
movl 0x14(%r15), %esi
leaq 0xd0(%rsp), %rdi
callq 0x196e
movl 0x18(%r15), %esi
leaq 0x40(%rsp), %rdi
callq 0x196e
callq 0x1090
movq %rax, 0x20(%rsp)
leaq (%r14,%rbx), %rax
movq %rax, 0x28(%rsp)
pushq $0x1
popq %rcx
xorl %r13d, %r13d
leaq 0x20150(%rsp), %rbp
leaq 0x18(%rsp), %rbx
movl %ecx, %r12d
movl %r12d, 0x4(%rsp)
movq %r13, 0x10(%rsp)
movl %ecx, %r12d
pushq $-0x1
popq %r13
incl %r13d
cmpl %r13d, %r12d
je 0x1ca5
andq $0x0, 0x18(%rsp)
subq $0x8, %rsp
movq %rbp, %rdi
movq %rbx, %rsi
leaq 0x10158(%rsp), %rdx
movq 0x10(%rsp), %rcx
leaq 0x158(%rsp), %r8
movq %r14, %r9
leaq 0x88(%rsp), %rax
pushq %rax
leaq 0x50(%rsp), %rax
pushq %rax
leaq 0xe8(%rsp), %rax
pushq %rax
callq *0x28(%r15)
addq $0x20, %rsp
testl %eax, %eax
jne 0x1df2
cmpq $0x0, 0x18(%rsp)
jne 0x1c40
jmp 0x1df2
movl %r12d, %eax
imulq 0x28(%rsp), %rax
movq 0x10(%rsp), %r13
addq %rax, %r13
addl %r12d, 0x4(%rsp)
callq 0x1090
subq 0x20(%rsp), %rax
movl 0x4(%rsp), %ecx
cmpq 0x30(%rsp), %rax
jl 0x1c2f
vcvtusi2sd %r13, %xmm0, %xmm0
vcvtsi2sd %rax, %xmm1, %xmm1
movq 0x8(%r15), %rsi
vmulsd 0x19e5(%rip), %xmm0, %xmm0 # 0x36d0
vdivsd %xmm1, %xmm0, %xmm0
leaq 0x1a1f(%rip), %rdi      # 0x3715
movq 0x8(%rsp), %rdx
movq %r14, %rcx
movb $0x1, %al
callq 0x10b0
pushq $0x1
popq %rbp
movq $0x0, 0x10(%rsp)
callq 0x1090
movq %rax, 0x20(%rsp)
leaq 0x20150(%rsp), %r12
leaq 0x150(%rsp), %rbx
movl %ebp, %r13d
movl %r13d, 0x4(%rsp)
movl %ebp, %r13d
pushq $-0x1
popq %rbp
incl %ebp
cmpl %ebp, %r13d
je 0x1d86
movq 0x18(%rsp), %r8
subq $0x8, %rsp
leaq 0x10158(%rsp), %rdi
leaq 0x40(%rsp), %rsi
leaq 0x118(%rsp), %rdx
movq %r12, %rcx
movq %rbx, %r9
leaq 0x88(%rsp), %rax
pushq %rax
leaq 0x50(%rsp), %rax
pushq %rax
pushq %r14
callq *0x30(%r15)
addq $0x20, %rsp
testl %eax, %eax
je 0x1d39
jmp 0x1e1a
movl %r13d, %eax
imulq 0x28(%rsp), %rax
addq %rax, 0x10(%rsp)
movl 0x4(%rsp), %ebp
addl %r13d, %ebp
callq 0x1090
subq 0x20(%rsp), %rax
cmpq 0x30(%rsp), %rax
jl 0x1d2e
vcvtusi2sdq 0x10(%rsp), %xmm2, %xmm0
vcvtsi2sd %rax, %xmm2, %xmm1
movq 0x8(%r15), %rsi
vmulsd 0x190b(%rip), %xmm0, %xmm0 # 0x36d0
vdivsd %xmm1, %xmm0, %xmm0
leaq 0x1990(%rip), %rdi      # 0x3760
movq 0x8(%rsp), %rdx
movq %r14, %rcx
movb $0x1, %al
callq 0x10b0
movq 0x41f2(%rip), %rax      # 0x5fd8
movq (%rax), %rdi
callq 0x1160
xorl %eax, %eax
jmp 0x1e41
movq 0x41ff(%rip), %rcx      # 0x5ff8
movq (%rcx), %rdi
movq 0x8(%r15), %rdx
leaq 0x18f2(%rip), %rsi      # 0x36f9
movq 0x8(%rsp), %rcx
movl %eax, %r8d
xorl %eax, %eax
callq 0x1110
pushq $-0x1
jmp 0x1e40
movq 0x41d7(%rip), %rcx      # 0x5ff8
movq (%rcx), %rdi
movq 0x8(%r15), %rdx
movq 0x18(%rsp), %rcx
leaq 0x1910(%rip), %rsi      # 0x3744
movl %eax, %r8d
xorl %eax, %eax
callq 0x1110
pushq $-0x2
popq %rax
addq $0xb0168, %rsp          # imm = 0xB0168
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x419e(%rip), %rax      # 0x5ff8
movq (%rax), %rcx
leaq 0x1874(%rip), %rdi      # 0x36d8
pushq $0x20
popq %rsi
pushq $0x1
popq %rdx
callq 0x11f0
jmp 0x1e16