// File: /workspace/github_c_makefile_star2_O3/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 $0xb0178, %rsp          # imm = 0xB0178
movq %rsi, 0x10(%rsp)
cmpq $0x10000, %rsi          # imm = 0x10000
ja 0x1f06
movq %rdx, %r14
cmpq $0x10001, %rdx          # imm = 0x10001
jae 0x1f06
movq %rdi, %r15
imulq $0xf4240, %rcx, %rax    # imm = 0xF4240
movq %rax, 0x40(%rsp)
leaq 0x10160(%rsp), %rdi
movq 0x10(%rsp), %rbx
movl %ebx, %esi
callq 0x19fa
leaq 0x160(%rsp), %rdi
movl %r14d, %esi
callq 0x19fa
movl 0x10(%r15), %esi
leaq 0x90(%rsp), %rdi
callq 0x19fa
movl 0x14(%r15), %esi
leaq 0x120(%rsp), %r13
movq %r13, %rdi
callq 0x19fa
movl 0x18(%r15), %esi
leaq 0x50(%rsp), %rdi
callq 0x19fa
callq 0x1090
movq %rax, 0x28(%rsp)
leaq (%r14,%rbx), %rax
movq %rax, 0x38(%rsp)
movl $0x1, %ecx
xorl %r12d, %r12d
leaq 0x20160(%rsp), %rbp
leaq 0x20(%rsp), %rbx
movl $0x1, %edx
movl %edx, 0xc(%rsp)
movq %r12, 0x30(%rsp)
cmpl $0x1, %ecx
movl %ecx, 0x8(%rsp)
movl %ecx, %r12d
adcl $0x0, %r12d
movl %r12d, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
subq $0x8, %rsp
movq %rbp, %rdi
movq %rbx, %rsi
leaq 0x10168(%rsp), %rdx
movq 0x18(%rsp), %rcx
leaq 0x168(%rsp), %r8
movq %r14, %r9
leaq 0x98(%rsp), %rax
pushq %rax
leaq 0x60(%rsp), %rax
pushq %rax
pushq %r13
callq *0x28(%r15)
addq $0x20, %rsp
testl %eax, %eax
jne 0x1ea0
cmpq $0x0, 0x20(%rsp)
je 0x1ea0
decl %r12d
jne 0x1cd2
movl 0x18(%rsp), %eax
imulq 0x38(%rsp), %rax
movq 0x30(%rsp), %r12
addq %rax, %r12
movl 0x8(%rsp), %eax
addl 0xc(%rsp), %eax
movl %eax, 0x8(%rsp)
callq 0x1090
movl 0x8(%rsp), %ecx
subq 0x28(%rsp), %rax
movl 0x18(%rsp), %edx
cmpq 0x40(%rsp), %rax
jl 0x1cb6
vcvtusi2sd %r12, %xmm0, %xmm0
vcvtsi2sd %rax, %xmm1, %xmm1
movq 0x8(%r15), %rsi
vmulsd 0x294f(%rip), %xmm0, %xmm0 # 0x46d0
vdivsd %xmm1, %xmm0, %xmm0
leaq 0x2989(%rip), %rdi      # 0x4715
movq 0x10(%rsp), %rdx
movq %r14, %rcx
movb $0x1, %al
callq 0x10b0
movl $0x1, %ebp
xorl %r13d, %r13d
callq 0x1090
movq %rax, 0x28(%rsp)
leaq 0x20160(%rsp), %r12
leaq 0x160(%rsp), %rbx
movl $0x1, %ecx
movl %ecx, 0xc(%rsp)
movq %r13, 0x18(%rsp)
cmpl $0x1, %ebp
movl %ebp, 0x30(%rsp)
adcl $0x0, %ebp
movl %ebp, 0x8(%rsp)
movl %ebp, %r13d
leaq 0x10160(%rsp), %rbp
movq 0x20(%rsp), %r8
subq $0x8, %rsp
movq %rbp, %rdi
leaq 0x50(%rsp), %rsi
leaq 0xe8(%rsp), %rdx
movq %r12, %rcx
movq %rbx, %r9
leaq 0x98(%rsp), %rax
pushq %rax
leaq 0x60(%rsp), %rax
pushq %rax
pushq %r14
callq *0x30(%r15)
addq $0x20, %rsp
testl %eax, %eax
jne 0x1ecb
decl %r13d
jne 0x1de4
movl 0x8(%rsp), %eax
imulq 0x38(%rsp), %rax
movq 0x18(%rsp), %r13
addq %rax, %r13
movl 0x30(%rsp), %ebp
addl 0xc(%rsp), %ebp
callq 0x1090
subq 0x28(%rsp), %rax
movl 0x8(%rsp), %ecx
cmpq 0x40(%rsp), %rax
jl 0x1dc2
vcvtusi2sd %r13, %xmm2, %xmm0
vcvtsi2sd %rax, %xmm2, %xmm1
movq 0x8(%r15), %rsi
vmulsd 0x285d(%rip), %xmm0, %xmm0 # 0x46d0
vdivsd %xmm1, %xmm0, %xmm0
leaq 0x28e2(%rip), %rdi      # 0x4760
movq 0x10(%rsp), %rdx
movq %r14, %rcx
movb $0x1, %al
callq 0x10b0
movq 0x5144(%rip), %rax      # 0x6fd8
movq (%rax), %rdi
callq 0x1160
xorl %eax, %eax
jmp 0x1ef4
movq 0x5151(%rip), %rcx      # 0x6ff8
movq (%rcx), %rdi
movq 0x8(%r15), %rdx
leaq 0x2844(%rip), %rsi      # 0x46f9
movq 0x10(%rsp), %rcx
movl %eax, %r8d
xorl %eax, %eax
callq 0x1110
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x1ef4
movq 0x5126(%rip), %rcx      # 0x6ff8
movq (%rcx), %rdi
movq 0x8(%r15), %rdx
movq 0x20(%rsp), %rcx
leaq 0x285f(%rip), %rsi      # 0x4744
movl %eax, %r8d
xorl %eax, %eax
callq 0x1110
movl $0xfffffffe, %eax       # imm = 0xFFFFFFFE
addq $0xb0178, %rsp          # imm = 0xB0178
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x1264
jmp 0x1ec4