// File: /workspace/github_c_makefile_star2_O3/LoupVaillant[P]Monocypher-Utils/src/monocypher.c
// Function: ge_scalarmult_base
static void ge_scalarmult_base(ge *p, const u8 scalar[32])
{
    // 5-bits signed comb, from Mike Hamburg's
    // Fast and compact elliptic-curve cryptography (2012)
    static const u8 half_mod_L[32] = { // 1 / 2 modulo L
        0xf7, 0xe9, 0x7a, 0x2e, 0x8d, 0x31, 0x09, 0x2c,
        0x6b, 0xce, 0x7b, 0x51, 0xef, 0x7c, 0x6f, 0x0a,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
    };
    static const u8 half_ones[32] = { // (2^255 - 1) / 2 modulo L
        0x42, 0x9a, 0xa3, 0xba, 0x23, 0xa5, 0xbf, 0xcb,
        0x11, 0x5b, 0x9d, 0xc5, 0x74, 0x95, 0xf3, 0xb6,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07,
    };
    // All bits set form: 1 means 1, 0 means -1
    u8 s_scalar[32];
    mul_add(s_scalar, scalar, half_mod_L, half_ones);

    // Double and add ladder
    fe yp, ym, t2, n2, a, b; // temporaries for addition
    ge dbl;                  // temporary for doublings
    ge_zero(p);
    for (int i = 50; i >= 0; i--) {
        if (i < 50) {
            ge_double(p, p, &dbl);
        }
        fe_1(yp);
        fe_1(ym);
        fe_0(t2);
        u8 teeth =  scalar_bit(s_scalar, i)
            +      (scalar_bit(s_scalar, i +  51) << 1)
            +      (scalar_bit(s_scalar, i + 102) << 2)
            +      (scalar_bit(s_scalar, i + 153) << 3)
            +      (scalar_bit(s_scalar, i + 204) << 4);
        u8 high  = teeth >> 4;
        u8 index = (teeth ^ (high - 1)) & 15;
        FOR (j, 0, 16) {
            i32 select = 1 & (((j ^ index) - 1) >> 8);
            fe_ccopy(yp, comb_Yp[j], select);
            fe_ccopy(ym, comb_Ym[j], select);
            fe_ccopy(t2, comb_T2[j], select);
        }

        fe_neg(n2, t2);
        fe_cswap(t2, n2, high);
        fe_cswap(yp, ym, high);
        ge_madd(p, p, ym, yp, n2, a, b);
    }
    WIPE_CTX(&dbl);
    WIPE_BUFFER(a);  WIPE_BUFFER(yp);  WIPE_BUFFER(t2);
    WIPE_BUFFER(b);  WIPE_BUFFER(ym);  WIPE_BUFFER(n2);
    WIPE_BUFFER(s_scalar);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rdi, %rbx
leaq 0x3ad6(%rip), %rdx      # 0x96a0
leaq 0x3aef(%rip), %rcx      # 0x96c0
leaq 0x40(%rsp), %rdi
callq 0x6384
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rbx)
movups %xmm0, (%rbx)
movq $0x0, 0x20(%rbx)
leaq 0x28(%rbx), %rax
movq %rax, (%rsp)
movl $0x1, 0x28(%rbx)
movups %xmm0, 0x2c(%rbx)
movups %xmm0, 0x3c(%rbx)
movabsq $0x100000000, %rax      # imm = 0x100000000
movq %rax, 0x4c(%rbx)
leaq 0x50(%rbx), %rax
movq %rax, 0x8(%rsp)
movups %xmm0, 0x54(%rbx)
movups %xmm0, 0x64(%rbx)
movups %xmm0, 0x74(%rbx)
movups %xmm0, 0x84(%rbx)
movups %xmm0, 0x90(%rbx)
leaq 0x78(%rbx), %r12
movl $0x32, %r15d
leaq 0xf0(%rsp), %r13
leaq 0xc0(%rsp), %rbp
movq %rbp, %r14
movq %r13, %rbp
cmpl $0x31, %r15d
ja 0x5c6e
movq %rbx, %rdi
movq %rbx, %rsi
leaq 0x148(%rsp), %rdx
callq 0x7f99
movl $0x1, %esi
movl %esi, 0x90(%rsp)
leaq 0x94(%rsp), %rax
xorl %ecx, %ecx
movl %ecx, 0x20(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
movl %esi, 0x60(%rsp)
leaq 0x64(%rsp), %rax
movl %ecx, 0x20(%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movl %r15d, %eax
shrl $0x3, %eax
movzbl 0x40(%rsp,%rax), %eax
movl %r15d, %ecx
andl $0x7, %ecx
xorl %edx, %edx
btl %ecx, %eax
setb %dl
leal 0x33(%r15), %ecx
movl %ecx, %eax
shrl $0x3, %eax
movzbl 0x40(%rsp,%rax), %eax
andb $0x7, %cl
shrl %cl, %eax
movq $0x0, 0x30(%rsp)
andl %esi, %eax
leal (%rdx,%rax,2), %eax
leal 0x66(%r15), %ecx
movl %ecx, %edx
shrl $0x3, %edx
movzbl 0x40(%rsp,%rdx), %edx
andb $0x7, %cl
shrl %cl, %edx
andl %esi, %edx
leal (%rax,%rdx,4), %eax
leal 0x99(%r15), %ecx
movl %ecx, %edx
shrl $0x3, %edx
movzbl 0x40(%rsp,%rdx), %edx
andb $0x7, %cl
shrl %cl, %edx
andl %esi, %edx
leal (%rax,%rdx,8), %edx
leal 0xcc(%r15), %ecx
movl %ecx, %eax
shrl $0x3, %eax
movzbl 0x40(%rsp,%rax), %esi
andl $0x7, %ecx
xorl %eax, %eax
btl %ecx, %esi
setb %al
leal -0x1(%rax), %ecx
andl $0xf, %ecx
xorl %edx, %ecx
leaq 0x3e9a(%rip), %rdx      # 0x9be0
leaq 0x3c13(%rip), %rsi      # 0x9960
leaq 0x398c(%rip), %rdi      # 0x96e0
xorl %r8d, %r8d
movl %ecx, %r9d
xorl %r8d, %r9d
shll $0x17, %r9d
addl $0xff800000, %r9d       # imm = 0xFF800000
sarl $0x1f, %r9d
xorl %r10d, %r10d
movl 0x90(%rsp,%r10,4), %r11d
movl (%rdi,%r10,4), %r13d
xorl %r11d, %r13d
andl %r9d, %r13d
xorl %r11d, %r13d
movl %r13d, 0x90(%rsp,%r10,4)
incq %r10
cmpq $0xa, %r10
jne 0x5d6f
xorl %r10d, %r10d
movl 0x60(%rsp,%r10,4), %r11d
movl (%rsi,%r10,4), %r13d
xorl %r11d, %r13d
andl %r9d, %r13d
xorl %r11d, %r13d
movl %r13d, 0x60(%rsp,%r10,4)
incq %r10
cmpq $0xa, %r10
jne 0x5d98
xorl %r10d, %r10d
movl 0x10(%rsp,%r10,4), %r11d
movl (%rdx,%r10,4), %r13d
xorl %r11d, %r13d
andl %r9d, %r13d
xorl %r11d, %r13d
movl %r13d, 0x10(%rsp,%r10,4)
incq %r10
cmpq $0xa, %r10
jne 0x5dbb
incq %r8
addq $0x28, %rdi
addq $0x28, %rsi
addq $0x28, %rdx
cmpq $0x10, %r8
jne 0x5d57
xorl %ecx, %ecx
xorl %edx, %edx
subl 0x10(%rsp,%rcx,4), %edx
movl %edx, 0x120(%rsp,%rcx,4)
incq %rcx
cmpq $0xa, %rcx
jne 0x5df6
negl %eax
xorl %ecx, %ecx
movq %rbp, %r13
movl 0x10(%rsp,%rcx,4), %edx
movl 0x120(%rsp,%rcx,4), %esi
movl %esi, %edi
xorl %edx, %edi
andl %eax, %edi
xorl %edi, %edx
movl %edx, 0x10(%rsp,%rcx,4)
xorl %esi, %edi
movl %edi, 0x120(%rsp,%rcx,4)
incq %rcx
cmpq $0xa, %rcx
jne 0x5e13
xorl %ecx, %ecx
movq %r14, %rbp
movl 0x90(%rsp,%rcx,4), %edx
movl 0x60(%rsp,%rcx,4), %esi
movl %esi, %edi
xorl %edx, %edi
andl %eax, %edi
xorl %edi, %edx
movl %edx, 0x90(%rsp,%rcx,4)
xorl %esi, %edi
movl %edi, 0x60(%rsp,%rcx,4)
incq %rcx
cmpq $0xa, %rcx
jne 0x5e41
xorl %eax, %eax
movl (%rbx,%rax,4), %ecx
addl 0x28(%rbx,%rax,4), %ecx
movl %ecx, 0xf0(%rsp,%rax,4)
incq %rax
cmpq $0xa, %rax
jne 0x5e6c
xorl %eax, %eax
movl 0x28(%rbx,%rax,4), %ecx
subl (%rbx,%rax,4), %ecx
movl %ecx, 0xc0(%rsp,%rax,4)
incq %rax
cmpq $0xa, %rax
jne 0x5e85
movq %r13, %rdi
movq %r13, %rsi
leaq 0x60(%rsp), %rdx
callq 0x494b
movq %rbp, %rdi
movq %rbp, %rsi
leaq 0x90(%rsp), %rdx
callq 0x494b
xorl %eax, %eax
movl 0xc0(%rsp,%rax,4), %ecx
addl 0xf0(%rsp,%rax,4), %ecx
movl %ecx, 0x28(%rbx,%rax,4)
incq %rax
cmpq $0xa, %rax
jne 0x5ec1
xorl %eax, %eax
movl 0xf0(%rsp,%rax,4), %ecx
subl 0xc0(%rsp,%rax,4), %ecx
movl %ecx, (%rbx,%rax,4)
incq %rax
cmpq $0xa, %rax
jne 0x5ede
movl $0x14, %eax
shll (%rbx,%rax,4)
incq %rax
cmpq $0x1e, %rax
jne 0x5efd
movq %r12, %rdi
movq %r12, %rsi
leaq 0x120(%rsp), %rdx
callq 0x494b
movl $0x14, %eax
movl 0x28(%rbx,%rax,4), %ecx
addl (%rbx,%rax,4), %ecx
movl %ecx, 0xa0(%rsp,%rax,4)
incq %rax
cmpq $0x1e, %rax
jne 0x5f21
movl $0x14, %eax
movl (%rbx,%rax,4), %ecx
subl 0x28(%rbx,%rax,4), %ecx
movl %ecx, 0x70(%rsp,%rax,4)
incq %rax
cmpq $0x1e, %rax
jne 0x5f3d
movq %r12, %rdi
movq %rbx, %rsi
movq (%rsp), %r14
movq %r14, %rdx
callq 0x494b
movq %rbx, %rdi
movq %rbx, %rsi
movq %rbp, %rdx
callq 0x494b
movq %r14, %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0x494b
movq 0x8(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x494b
subl $0x1, %r15d
jae 0x5c4f
xorl %eax, %eax
movb $0x0, 0x148(%rsp,%rax)
incq %rax
cmpq $0xa0, %rax
jne 0x5f9b
xorl %eax, %eax
movb $0x0, 0xf0(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x5fb0
xorl %eax, %eax
movb $0x0, 0x90(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x5fc3
xorl %eax, %eax
movb $0x0, 0x10(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x5fd6
xorl %eax, %eax
movb $0x0, 0xc0(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x5fe6
xorl %eax, %eax
movb $0x0, 0x60(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x5ff9
xorl %eax, %eax
movb $0x0, 0x120(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x6009
xorl %eax, %eax
movb $0x0, 0x40(%rsp,%rax)
incq %rax
cmpq $0x20, %rax
jne 0x601c
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq