// File: /workspace/github_c_makefile_star2_O0/mjosaarinen[P]brutus/src/coherence.c
// Function: test_coherence
int test_coherence(caesar_t *aead, int limit)
{
    int ret, forge, iter, off, bit;
    int forge_ok, forge_try;
    unsigned long long mlen, clen, adlen, t;
    time_t tim;
    const char *fcase[4] = { "key", "npub", "ad", "ct" };

    uint8_t key[80], nsec[64], osec[64], npub[64];

    // that 524304 ABYTES factor comes from Trivia. Don't ask.
    uint8_t pt[0x100], ad[0x100], xt[0x100], ct[0x100 + 524304];

    if (aead->name == NULL || aead->abytes + sizeof(pt) > sizeof(ct) ||
        aead->keybytes > sizeof(key) || aead->nsecbytes > sizeof(nsec) ||
        aead->nsecbytes > sizeof(osec) || aead->npubbytes > sizeof(npub)) {
        fprintf(stderr, "test_coherence(): invalid parameters\n");
        return -1;
    }

    if (brutus_verbose) {
        printf("[%s] Coherence Check (limit=%d sec)  "
            "key=%d  nsec=%d  npub=%d  a=%d\n",
            aead->name, limit, aead->keybytes, aead->nsecbytes,
            aead->npubbytes, aead->abytes);
    }
    limit *= CLOCKS_PER_SEC;

    // basic correctness test
    forge_ok = 0;
    forge_try = 0;

    tim = clock();
    for (iter = 0; iter < 20; iter++) {

        // limit time
        if (clock() - tim > limit) {
            if (brutus_verbose) {
                printf("!INFO\t%s timed out at iter=%d\n",
                    aead->name, iter);
            }
            break;
        }

        for (mlen = 0; mlen < sizeof(pt); mlen++) {

            // clearup
            memset(pt, 0x55, sizeof(pt));
            memset(xt, 0xAA, sizeof(xt));
            memset(ct, 0x33, sizeof(ct));
            memset(ad, 0xCC, sizeof(ad));
            memset(osec, 0xF0, sizeof(osec));

            // randomize cryptovariables
            detseq_fill(key, aead->keybytes);
            detseq_fill(nsec, aead->nsecbytes);
            detseq_fill(npub, aead->npubbytes);

            adlen = detseq32() % (sizeof(ad) + 1);
            detseq_fill(ad, adlen);
            detseq_fill(pt, mlen);

            // encrypt
            clen = 0;
            ret = aead->encrypt(ct, &clen, pt, mlen,
                ad, adlen, nsec, npub, key);
            if (ret != 0) {
                fprintf(stderr,
                    "!ERROR\t%s encrypt(%llu)=%d\n", aead->name, mlen, ret);
                return -1;
            }

            // decrypt
            ret = aead->decrypt(xt, &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;
            }

            // check that the plaintext matches
            if (t != mlen) {
                fprintf(stderr,
                    "!FAIL\t%s decrypt length=%llu "
                    "mlen=%llu adlen=%llu clen=%llu)\n",
                aead->name, t, mlen, adlen, clen);
                return -3;
            }
            if (memcmp(pt, xt, mlen) != 0) {
                fprintf(stderr,
                    "!FAIL\t%s decrypt mismatch "
                    "(mlen=%llu adlen=%llu clen=%llu\n)",
                    aead->name, mlen, adlen, clen);
                return -4;
            }
            if (aead->nsecbytes > 0 &&
                memcmp(nsec, osec, aead->nsecbytes) != 0) {
                fprintf(stderr,
                    "!FAIL\t%s nsec mismatch "
                    "(mlen=%llu adlen=%llu clen=%llu\n)",
                    aead->name, mlen, adlen, clen);
                return -5;
            }

            // attempt random forgery
            forge = detseq32() % 4;
            bit = 0x01 << (detseq32() % 8);
            switch (forge) {
                case 0:
                    off = detseq32() % aead->keybytes;
                    key[off] ^= bit;
                    break;

                case 1:
                    if (aead->npubbytes == 0)
                        continue;
                    off = detseq32() % aead->npubbytes;
                    npub[off] ^= bit;
                    break;

                case 2:
                    if (adlen == 0)
                        continue;
                    off = detseq32() % adlen;
                    ad[off] ^= bit;
                    break;

                case 3:
                    off = detseq32() % clen;
                    ct[off] ^= bit;
                    break;
            }

            // decrypt
            ret = aead->decrypt(xt, &t, osec, ct, clen, ad, adlen, npub, key);
            if (ret == 0) {
                if (brutus_verbose) {
                    printf("!FORGE\t%s %s[%d] ^= 0x%02X "
                        "(iter=%d mlen=%llu adlen=%llu clen=%llu)\n",
                        aead->name, fcase[forge], off, bit,
                        iter, mlen, adlen, clen);
                }
                forge_ok++;
            }
            forge_try++;
        }
    }
    if (forge_ok > 0) {
        fprintf(stderr, "!FORGE\t%s %d/%d = %g forgeries.\n", aead->name,
            forge_ok, forge_try, ((double) forge_ok) / ((double) forge_try));
        return -6;
    }

    return 0;
}

// Assembly:
pushq %rbx
subq $0x805d0, %rsp          # imm = 0x805D0
movq %rdi, 0x805c0(%rsp)
movl %esi, 0x805bc(%rsp)
movq 0x3602(%rip), %rax      # 0x5db0
movq %rax, 0x80550(%rsp)
movq 0x35fb(%rip), %rax      # 0x5db8
movq %rax, 0x80558(%rsp)
movq 0x35f4(%rip), %rax      # 0x5dc0
movq %rax, 0x80560(%rsp)
movq 0x35ed(%rip), %rax      # 0x5dc8
movq %rax, 0x80568(%rsp)
movq 0x805c0(%rsp), %rax
cmpq $0x0, 0x8(%rax)
je 0x2854
movq 0x805c0(%rsp), %rax
movslq 0x1c(%rax), %rax
addq $0x100, %rax            # imm = 0x100
cmpq $0x80110, %rax          # imm = 0x80110
ja 0x2854
movq 0x805c0(%rsp), %rax
movslq 0x10(%rax), %rax
cmpq $0x50, %rax
ja 0x2854
movq 0x805c0(%rsp), %rax
movslq 0x14(%rax), %rax
cmpq $0x40, %rax
ja 0x2854
movq 0x805c0(%rsp), %rax
movslq 0x14(%rax), %rax
cmpq $0x40, %rax
ja 0x2854
movq 0x805c0(%rsp), %rax
movslq 0x18(%rax), %rax
cmpq $0x40, %rax
jbe 0x287c
movq 0x3795(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
leaq 0x1e92(%rip), %rsi      # 0x46f7
movb $0x0, %al
callq 0x1100
movl $0xffffffff, 0x805cc(%rsp) # imm = 0xFFFFFFFF
jmp 0x3089
leaq 0x388d(%rip), %rax      # 0x6110
cmpl $0x0, (%rax)
je 0x28da
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rsi
movl 0x805bc(%rsp), %edx
movq 0x805c0(%rsp), %rax
movl 0x10(%rax), %ecx
movq 0x805c0(%rsp), %rax
movl 0x14(%rax), %r8d
movq 0x805c0(%rsp), %rax
movl 0x18(%rax), %r9d
movq 0x805c0(%rsp), %rax
movl 0x1c(%rax), %eax
leaq 0x1e4d(%rip), %rdi      # 0x471d
movl %eax, (%rsp)
movb $0x0, %al
callq 0x10a0
movslq 0x805bc(%rsp), %rax
imulq $0xf4240, %rax, %rax    # imm = 0xF4240
movl %eax, 0x805bc(%rsp)
movl $0x0, 0x805a4(%rsp)
movl $0x0, 0x805a0(%rsp)
callq 0x1080
movq %rax, 0x80578(%rsp)
movl $0x0, 0x805b0(%rsp)
cmpl $0x14, 0x805b0(%rsp)
jge 0x301e
callq 0x1080
subq 0x80578(%rsp), %rax
movslq 0x805bc(%rsp), %rcx
cmpq %rcx, %rax
jle 0x2978
leaq 0x37c3(%rip), %rax      # 0x6110
cmpl $0x0, (%rax)
je 0x2973
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rsi
movl 0x805b0(%rsp), %edx
leaq 0x1df6(%rip), %rdi      # 0x4762
movb $0x0, %al
callq 0x10a0
jmp 0x301e
movq $0x0, 0x80598(%rsp)
cmpq $0x100, 0x80598(%rsp) # imm = 0x100
jae 0x3006
leaq 0x80340(%rsp), %rdi
movl $0x55, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x10b0
leaq 0x80140(%rsp), %rdi
movl $0xaa, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x10b0
leaq 0x30(%rsp), %rdi
movl $0x33, %esi
movl $0x80110, %edx          # imm = 0x80110
callq 0x10b0
leaq 0x80240(%rsp), %rdi
movl $0xcc, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x10b0
leaq 0x80480(%rsp), %rdi
movl $0xf0, %esi
movl $0x40, %edx
callq 0x10b0
leaq 0x80500(%rsp), %rdi
movq 0x805c0(%rsp), %rax
movl 0x10(%rax), %esi
callq 0x1dd0
leaq 0x804c0(%rsp), %rdi
movq 0x805c0(%rsp), %rax
movl 0x14(%rax), %esi
callq 0x1dd0
leaq 0x80440(%rsp), %rdi
movq 0x805c0(%rsp), %rax
movl 0x18(%rax), %esi
callq 0x1dd0
movb $0x0, %al
callq 0x1da0
movl %eax, %eax
movl $0x101, %ecx            # imm = 0x101
xorl %edx, %edx
divq %rcx
movq %rdx, 0x80588(%rsp)
leaq 0x80240(%rsp), %rdi
movq 0x80588(%rsp), %rax
movl %eax, %esi
callq 0x1dd0
leaq 0x80340(%rsp), %rdi
movq 0x80598(%rsp), %rax
movl %eax, %esi
callq 0x1dd0
movq $0x0, 0x80590(%rsp)
movq 0x805c0(%rsp), %rax
movq 0x28(%rax), %rax
leaq 0x30(%rsp), %rdi
leaq 0x80340(%rsp), %rdx
movq 0x80598(%rsp), %rcx
leaq 0x80240(%rsp), %r8
movq 0x80588(%rsp), %r9
leaq 0x804c0(%rsp), %rbx
leaq 0x80440(%rsp), %r11
leaq 0x80500(%rsp), %r10
leaq 0x80590(%rsp), %rsi
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
callq *%rax
movl %eax, 0x805b8(%rsp)
cmpl $0x0, 0x805b8(%rsp)
je 0x2b59
movq 0x34d4(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rdx
movq 0x80598(%rsp), %rcx
movl 0x805b8(%rsp), %r8d
leaq 0x1a7f(%rip), %rsi      # 0x45c1
movb $0x0, %al
callq 0x1100
movl $0xffffffff, 0x805cc(%rsp) # imm = 0xFFFFFFFF
jmp 0x3089
movq 0x805c0(%rsp), %rax
movq 0x30(%rax), %rax
leaq 0x80140(%rsp), %rdi
leaq 0x80480(%rsp), %rdx
leaq 0x30(%rsp), %rcx
movq 0x80590(%rsp), %r8
leaq 0x80240(%rsp), %r9
movq 0x80588(%rsp), %rbx
leaq 0x80440(%rsp), %r11
leaq 0x80500(%rsp), %r10
leaq 0x80580(%rsp), %rsi
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
callq *%rax
movl %eax, 0x805b8(%rsp)
cmpl $0x0, 0x805b8(%rsp)
je 0x2c0f
movq 0x341e(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rdx
movq 0x80590(%rsp), %rcx
movl 0x805b8(%rsp), %r8d
leaq 0x1a14(%rip), %rsi      # 0x460c
movb $0x0, %al
callq 0x1100
movl $0xfffffffe, 0x805cc(%rsp) # imm = 0xFFFFFFFE
jmp 0x3089
movq 0x80580(%rsp), %rax
cmpq 0x80598(%rsp), %rax
je 0x2c79
movq 0x33c8(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rdx
movq 0x80580(%rsp), %rcx
movq 0x80598(%rsp), %r8
movq 0x80588(%rsp), %r9
movq 0x80590(%rsp), %rax
leaq 0x1b23(%rip), %rsi      # 0x4781
movq %rax, (%rsp)
movb $0x0, %al
callq 0x1100
movl $0xfffffffd, 0x805cc(%rsp) # imm = 0xFFFFFFFD
jmp 0x3089
leaq 0x80340(%rsp), %rdi
leaq 0x80140(%rsp), %rsi
movq 0x80598(%rsp), %rdx
callq 0x10d0
cmpl $0x0, %eax
je 0x2ce7
movq 0x334e(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rdx
movq 0x80598(%rsp), %rcx
movq 0x80588(%rsp), %r8
movq 0x80590(%rsp), %r9
leaq 0x1aef(%rip), %rsi      # 0x47bf
movb $0x0, %al
callq 0x1100
movl $0xfffffffc, 0x805cc(%rsp) # imm = 0xFFFFFFFC
jmp 0x3089
movq 0x805c0(%rsp), %rax
cmpl $0x0, 0x14(%rax)
jle 0x2d67
leaq 0x804c0(%rsp), %rdi
leaq 0x80480(%rsp), %rsi
movq 0x805c0(%rsp), %rax
movslq 0x14(%rax), %rdx
callq 0x10d0
cmpl $0x0, %eax
je 0x2d67
movq 0x32ce(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rdx
movq 0x80598(%rsp), %rcx
movq 0x80588(%rsp), %r8
movq 0x80590(%rsp), %r9
leaq 0x1aab(%rip), %rsi      # 0x47fb
movb $0x0, %al
callq 0x1100
movl $0xfffffffb, 0x805cc(%rsp) # imm = 0xFFFFFFFB
jmp 0x3089
xorl %eax, %eax
movb %al, 0x27(%rsp)
callq 0x1da0
movl %eax, %ecx
movb 0x27(%rsp), %al
andl $0x3, %ecx
movl %ecx, 0x805b4(%rsp)
callq 0x1da0
andb $0x7, %al
movb %al, %cl
movl $0x1, %eax
shlxl %ecx, %eax, %eax
movl %eax, 0x805a8(%rsp)
movl 0x805b4(%rsp), %eax
movq %rax, 0x28(%rsp)
subq $0x3, %rax
ja 0x2ee2
movq 0x28(%rsp), %rax
leaq 0x191a(%rip), %rcx      # 0x46d8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x0, %al
callq 0x1da0
movq 0x805c0(%rsp), %rcx
xorl %edx, %edx
divl 0x10(%rcx)
movl %edx, 0x805ac(%rsp)
movl 0x805a8(%rsp), %edx
movslq 0x805ac(%rsp), %rax
movzbl 0x80500(%rsp,%rax), %ecx
xorl %edx, %ecx
movb %cl, 0x80500(%rsp,%rax)
jmp 0x2ee2
movq 0x805c0(%rsp), %rax
cmpl $0x0, 0x18(%rax)
jne 0x2e1a
jmp 0x2fed
movb $0x0, %al
callq 0x1da0
movq 0x805c0(%rsp), %rcx
xorl %edx, %edx
divl 0x18(%rcx)
movl %edx, 0x805ac(%rsp)
movl 0x805a8(%rsp), %edx
movslq 0x805ac(%rsp), %rax
movzbl 0x80440(%rsp,%rax), %ecx
xorl %edx, %ecx
movb %cl, 0x80440(%rsp,%rax)
jmp 0x2ee2
cmpq $0x0, 0x80588(%rsp)
jne 0x2e6a
jmp 0x2fed
movb $0x0, %al
callq 0x1da0
movl %eax, %eax
xorl %ecx, %ecx
movl %ecx, %edx
divq 0x80588(%rsp)
movl %edx, %eax
movl %eax, 0x805ac(%rsp)
movl 0x805a8(%rsp), %edx
movslq 0x805ac(%rsp), %rax
movzbl 0x80240(%rsp,%rax), %ecx
xorl %edx, %ecx
movb %cl, 0x80240(%rsp,%rax)
jmp 0x2ee2
movb $0x0, %al
callq 0x1da0
movl %eax, %eax
xorl %ecx, %ecx
movl %ecx, %edx
divq 0x80590(%rsp)
movl %edx, %eax
movl %eax, 0x805ac(%rsp)
movl 0x805a8(%rsp), %edx
movslq 0x805ac(%rsp), %rax
movzbl 0x30(%rsp,%rax), %ecx
xorl %edx, %ecx
movb %cl, 0x30(%rsp,%rax)
movq 0x805c0(%rsp), %rax
movq 0x30(%rax), %rax
leaq 0x80140(%rsp), %rdi
leaq 0x80480(%rsp), %rdx
leaq 0x30(%rsp), %rcx
movq 0x80590(%rsp), %r8
leaq 0x80240(%rsp), %r9
movq 0x80588(%rsp), %rbx
leaq 0x80440(%rsp), %r11
leaq 0x80500(%rsp), %r10
leaq 0x80580(%rsp), %rsi
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
callq *%rax
movl %eax, 0x805b8(%rsp)
cmpl $0x0, 0x805b8(%rsp)
jne 0x2fdc
leaq 0x31b1(%rip), %rax      # 0x6110
cmpl $0x0, (%rax)
je 0x2fcb
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rsi
movslq 0x805b4(%rsp), %rax
movq 0x80550(%rsp,%rax,8), %rdx
movl 0x805ac(%rsp), %ecx
movl 0x805a8(%rsp), %r8d
movl 0x805b0(%rsp), %r9d
movq 0x80598(%rsp), %r11
movq 0x80588(%rsp), %r10
movq 0x80590(%rsp), %rax
leaq 0x187e(%rip), %rdi      # 0x4834
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
movb $0x0, %al
callq 0x10a0
movl 0x805a4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x805a4(%rsp)
movl 0x805a0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x805a0(%rsp)
movq 0x80598(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x80598(%rsp)
jmp 0x2984
jmp 0x3008
movl 0x805b0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x805b0(%rsp)
jmp 0x291e
cmpl $0x0, 0x805a4(%rsp)
jle 0x307e
movq 0x2fc1(%rip), %rax      # 0x5ff0
movq (%rax), %rdi
movq 0x805c0(%rsp), %rax
movq 0x8(%rax), %rdx
movl 0x805a4(%rsp), %ecx
movl 0x805a0(%rsp), %r8d
vcvtsi2sdl 0x805a4(%rsp), %xmm0, %xmm0
vcvtsi2sdl 0x805a0(%rsp), %xmm1, %xmm1
vdivsd %xmm1, %xmm0, %xmm0
leaq 0x180f(%rip), %rsi      # 0x4879
movb $0x1, %al
callq 0x1100
movl $0xfffffffa, 0x805cc(%rsp) # imm = 0xFFFFFFFA
jmp 0x3089
movl $0x0, 0x805cc(%rsp)
movl 0x805cc(%rsp), %eax
addq $0x805d0, %rsp          # imm = 0x805D0
popq %rbx
retq
nopl (%rax)