// File: /workspace/github_c_makefile_star2_O0/ioerror[P]csidh-reference-implementation/csidh.c
// Function: validate_rec
static bool validate_rec(proj *P, proj const *A, size_t lower, size_t upper, ui *order, bool *is_supersingular)
{
    assert(lower < upper);

    if (upper - lower == 1) {

        /* now P is [(p+1) / l_lower] times the original random point */
        /* we only gain information if this multiple is non-zero */

        if (memcmp(&P->z, &fp_0, sizeof(fp))) {

            ui tmp;
            ui_set(&tmp, primes[lower]);
            xMUL(P, A, P, &tmp);

            if (memcmp(&P->z, &fp_0, sizeof(fp))) {
                /* order does not divide p+1. */
                *is_supersingular = false;
                return true;
            }

            ui_mul3_64(order, order, primes[lower]);

            if (ui_sub3(&tmp, &four_sqrt_p, order)) { /* returns borrow */
                /* order > 4 sqrt(p), hence definitely supersingular */
                *is_supersingular = true;
                return true;
            }
        }

        /* inconclusive */
        return false;
    }

    size_t mid = lower + (upper - lower + 1) / 2;

    ui cl = ui_1, cu = ui_1;
    for (size_t i = lower; i < mid; ++i)
        ui_mul3_64(&cu, &cu, primes[i]);
    for (size_t i = mid; i < upper; ++i)
        ui_mul3_64(&cl, &cl, primes[i]);

    proj Q;

    xMUL(&Q, A, P, &cu);
    xMUL(P, A, P, &cl);

    /* start with the right half; bigger primes help more */
    return validate_rec(&Q, A, mid, upper, order, is_supersingular)
        || validate_rec(P, A, lower, mid, order, is_supersingular);
}

// Assembly:
subq $0x198, %rsp            # imm = 0x198
movq %rdi, 0x188(%rsp)
movq %rsi, 0x180(%rsp)
movq %rdx, 0x178(%rsp)
movq %rcx, 0x170(%rsp)
movq %r8, 0x168(%rsp)
movq %r9, 0x160(%rsp)
movq 0x178(%rsp), %rax
cmpq 0x170(%rsp), %rax
jae 0x37ab
jmp 0x37ca
leaq 0x1ca2(%rip), %rdi      # 0x5454
leaq 0x1c50(%rip), %rsi      # 0x5409
movl $0x21, %edx
leaq 0x1c9d(%rip), %rcx      # 0x5462
callq 0x1050
movq 0x170(%rsp), %rax
subq 0x178(%rsp), %rax
cmpq $0x1, %rax
jne 0x38fc
movq 0x188(%rsp), %rdi
addq $0x40, %rdi
leaq 0x1859(%rip), %rsi      # 0x5050
movl $0x40, %edx
callq 0x1080
cmpl $0x0, %eax
je 0x38ef
movq 0x178(%rsp), %rcx
leaq 0x1aa7(%rip), %rax      # 0x52c0
movl (%rax,%rcx,4), %eax
movl %eax, %esi
leaq 0x120(%rsp), %rdi
callq 0x1274
movq 0x188(%rsp), %rdi
movq 0x180(%rsp), %rsi
movq 0x188(%rsp), %rdx
leaq 0x120(%rsp), %rcx
callq 0x2af0
movq 0x188(%rsp), %rdi
addq $0x40, %rdi
leaq 0x17ed(%rip), %rsi      # 0x5050
movl $0x40, %edx
callq 0x1080
cmpl $0x0, %eax
je 0x388a
movq 0x160(%rsp), %rax
movb $0x0, (%rax)
movb $0x1, 0x197(%rsp)
jmp 0x3adc
movq 0x168(%rsp), %rdi
movq 0x168(%rsp), %rsi
movq 0x178(%rsp), %rcx
leaq 0x1a17(%rip), %rax      # 0x52c0
movl (%rax,%rcx,4), %eax
movl %eax, %edx
callq 0x1369
movq 0x168(%rsp), %rdx
leaq 0x120(%rsp), %rdi
leaq 0x18ce(%rip), %rsi      # 0x5198
callq 0x1304
testb $0x1, %al
jne 0x38d5
jmp 0x38ed
movq 0x160(%rsp), %rax
movb $0x1, (%rax)
movb $0x1, 0x197(%rsp)
jmp 0x3adc
jmp 0x38ef
movb $0x0, 0x197(%rsp)
jmp 0x3adc
movq 0x178(%rsp), %rax
movq 0x170(%rsp), %rcx
subq 0x178(%rsp), %rcx
addq $0x1, %rcx
shrq %rcx
addq %rcx, %rax
movq %rax, 0x118(%rsp)
leaq 0xd8(%rsp), %rdi
leaq 0x18b0(%rip), %rsi      # 0x51e5
movl $0x40, %edx
callq 0x1090
leaq 0x98(%rsp), %rdi
leaq 0x1897(%rip), %rsi      # 0x51e5
movl $0x40, %edx
callq 0x1090
movq 0x178(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
cmpq 0x118(%rsp), %rax
jae 0x39b4
movq 0x90(%rsp), %rcx
leaq 0x1937(%rip), %rax      # 0x52c0
movl (%rax,%rcx,4), %eax
movl %eax, %edx
leaq 0x98(%rsp), %rsi
movq %rsi, %rdi
callq 0x1369
movq 0x90(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x90(%rsp)
jmp 0x3968
movq 0x118(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rax
cmpq 0x170(%rsp), %rax
jae 0x3a10
movq 0x88(%rsp), %rcx
leaq 0x18db(%rip), %rax      # 0x52c0
movl (%rax,%rcx,4), %eax
movl %eax, %edx
leaq 0xd8(%rsp), %rsi
movq %rsi, %rdi
callq 0x1369
movq 0x88(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x88(%rsp)
jmp 0x39c4
movq 0x180(%rsp), %rsi
movq 0x188(%rsp), %rdx
leaq 0x8(%rsp), %rdi
leaq 0x98(%rsp), %rcx
callq 0x2af0
movq 0x188(%rsp), %rdi
movq 0x180(%rsp), %rsi
movq 0x188(%rsp), %rdx
leaq 0xd8(%rsp), %rcx
callq 0x2af0
movq 0x180(%rsp), %rsi
movq 0x118(%rsp), %rdx
movq 0x170(%rsp), %rcx
movq 0x168(%rsp), %r8
movq 0x160(%rsp), %r9
leaq 0x8(%rsp), %rdi
callq 0x3760
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0x7(%rsp)
jne 0x3acf
movq 0x188(%rsp), %rdi
movq 0x180(%rsp), %rsi
movq 0x178(%rsp), %rdx
movq 0x118(%rsp), %rcx
movq 0x168(%rsp), %r8
movq 0x160(%rsp), %r9
callq 0x3760
movb %al, 0x7(%rsp)
movb 0x7(%rsp), %al
andb $0x1, %al
movb %al, 0x197(%rsp)
movb 0x197(%rsp), %al
andb $0x1, %al
addq $0x198, %rsp            # imm = 0x198
retq
nopl (%rax)