// File: /workspace/github_cpp_makefile_star2_O3/occivink[P]pyct/monocypher.cpp
// Function: ge_scalarmult_base(ge*, unsigned char const*)
static void ge_scalarmult_base(ge *p, const u8 scalar[32])
{
    // twin 4-bits signed combs, from Mike Hamburg's
    // Fast and compact elliptic-curve cryptography (2012)
    // 1 / 2 modulo L
    static const u8 half_mod_L[32] = {
        247,233,122,46,141,49,9,44,107,206,123,81,239,124,111,10,
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8, };
    // (2^256 - 1) / 2 modulo L
    static const u8 half_ones[32] = {
        142,74,204,70,186,24,118,107,184,231,190,57,250,173,119,99,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7, };

    // 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 tmp_a, tmp_b;  // temporaries for addition
    ge_precomp tmp_c; // temporary for comb lookup
    ge tmp_d;         // temporary for doubling
    fe_1(tmp_c.Yp);
    fe_1(tmp_c.Ym);
    fe_0(tmp_c.T2);

    // Save a double on the first iteration
    ge_zero(p);
    lookup_add(p, &tmp_c, tmp_a, tmp_b, b_comb_low , s_scalar, 31);
    lookup_add(p, &tmp_c, tmp_a, tmp_b, b_comb_high, s_scalar, 31+128);
    // Regular double & add for the rest
    for (int i = 30; i >= 0; i--) {
        ge_double(p, p, &tmp_d);
        lookup_add(p, &tmp_c, tmp_a, tmp_b, b_comb_low , s_scalar, i);
        lookup_add(p, &tmp_c, tmp_a, tmp_b, b_comb_high, s_scalar, i+128);
    }
    // Note: we could save one addition at the end if we assumed the
    // scalar fit in 252 bits.  Which it does in practice if it is
    // selected at random.  However, non-random, non-hashed scalars
    // *can* overflow 252 bits in practice.  Better account for that
    // than leaving that kind of subtle corner case.

    WIPE_BUFFER(tmp_a);  WIPE_CTX(&tmp_d);
    WIPE_BUFFER(tmp_b);  WIPE_CTX(&tmp_c);
    WIPE_BUFFER(s_scalar);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rdi, %rbx
leaq 0x6f67(%rip), %rdx      # 0xd230
leaq 0x6f80(%rip), %rcx      # 0xd250
leaq 0x10(%rsp), %r14
movq %r14, %rdi
callq 0x6756
movl $0x1, %eax
leaq 0x90(%rsp), %r15
movl %eax, (%r15)
xorps %xmm0, %xmm0
movups %xmm0, 0x4(%r15)
movups %xmm0, 0x14(%r15)
movabsq $0x100000000, %rcx      # imm = 0x100000000
movq %rcx, 0x24(%r15)
movups %xmm0, 0x2c(%r15)
movups %xmm0, 0x3c(%r15)
movups %xmm0, 0x4c(%r15)
movups %xmm0, 0x5c(%r15)
movups %xmm0, 0x68(%r15)
movups %xmm0, 0x10(%rbx)
movups %xmm0, (%rbx)
movq $0x0, 0x20(%rbx)
movl %eax, 0x28(%rbx)
movups %xmm0, 0x2c(%rbx)
movups %xmm0, 0x3c(%rbx)
movq %rcx, 0x4c(%rbx)
movups %xmm0, 0x54(%rbx)
movups %xmm0, 0x64(%rbx)
movups %xmm0, 0x74(%rbx)
movups %xmm0, 0x84(%rbx)
movups %xmm0, 0x90(%rbx)
movl $0x1f, (%rsp)
leaq 0x6f09(%rip), %r8       # 0xd270
leaq 0x60(%rsp), %r13
leaq 0x30(%rsp), %rbp
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbp, %rcx
movq %r14, %r9
callq 0x981a
movl $0x9f, (%rsp)
leaq 0x729d(%rip), %r8       # 0xd630
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbp, %rcx
movq %r14, %r9
callq 0x981a
movl $0x1e, %r12d
movq %rbx, %rdi
movq %rbx, %rsi
leaq 0x108(%rsp), %rdx
callq 0x99c3
movl %r12d, (%rsp)
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbp, %rcx
leaq 0x6e99(%rip), %r8       # 0xd270
movq %r14, %r9
callq 0x981a
leal 0x80(%r12), %eax
movl %eax, (%rsp)
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
movq %rbp, %rcx
leaq 0x7233(%rip), %r8       # 0xd630
movq %r14, %r9
callq 0x981a
subl $0x1, %r12d
jae 0x63ad
xorl %eax, %eax
movb $0x0, 0x60(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x640d
xorl %eax, %eax
movb $0x0, 0x108(%rsp,%rax)
incq %rax
cmpq $0xa0, %rax
jne 0x641d
xorl %eax, %eax
movb $0x0, 0x30(%rsp,%rax)
incq %rax
cmpq $0x28, %rax
jne 0x6432
xorl %eax, %eax
movb $0x0, 0x90(%rsp,%rax)
incq %rax
cmpq $0x78, %rax
jne 0x6442
xorl %eax, %eax
movb $0x0, 0x10(%rsp,%rax)
incq %rax
cmpq $0x20, %rax
jne 0x6455
addq $0x1a8, %rsp            # imm = 0x1A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq