// File: simap[P]ecctools/lib/uECC.c
// Function: EccPoint_mult(unsigned long*, unsigned long const*, unsigned long const*, unsigned long const*, short, uECC_Curve_t const*)
static void EccPoint_mult(uECC_word_t * result,
                          const uECC_word_t * point,
                          const uECC_word_t * scalar,
                          const uECC_word_t * initial_Z,
                          bitcount_t num_bits,
                          uECC_Curve curve) {
    /* R0 and R1 */
    uECC_word_t Rx[2][uECC_MAX_WORDS];
    uECC_word_t Ry[2][uECC_MAX_WORDS];
    uECC_word_t z[uECC_MAX_WORDS];
    bitcount_t i;
    uECC_word_t nb;
    wordcount_t num_words = curve->num_words;

    uECC_vli_set(Rx[1], point, num_words);
    uECC_vli_set(Ry[1], point + num_words, num_words);

    XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve);

    for (i = num_bits - 2; i > 0; --i) {
        nb = !uECC_vli_testBit(scalar, i);
        XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
        XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
    }

    nb = !uECC_vli_testBit(scalar, 0);
    XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);

    /* Find final 1/Z value. */
    uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */
    uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve);               /* Yb * (X1 - X0) */
    uECC_vli_modMult_fast(z, z, point, curve);                    /* xP * Yb * (X1 - X0) */
    uECC_vli_modInv(z, z, curve->p, num_words);            /* 1 / (xP * Yb * (X1 - X0)) */
    /* yP / (xP * Yb * (X1 - X0)) */
    uECC_vli_modMult_fast(z, z, point + num_words, curve);
    uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */
    /* End 1/Z calculation */

    XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
    apply_z(Rx[0], Ry[0], z, curve);

    uECC_vli_set(result, Rx[0], num_words);
    uECC_vli_set(result + num_words, Ry[0], num_words);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movw %r8w, %ax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movw %ax, -0x22(%rbp)
movq %r9, -0x30(%rbp)
movq -0x30(%rbp), %rax
movb (%rax), %al
movb %al, -0xe1(%rbp)
leaq -0x70(%rbp), %rdi
addq $0x20, %rdi
movq -0x10(%rbp), %rsi
movsbl -0xe1(%rbp), %edx
callq 0x3db0
leaq -0xb0(%rbp), %rdi
addq $0x20, %rdi
movq -0x10(%rbp), %rsi
movsbl -0xe1(%rbp), %eax
cltq
shlq $0x3, %rax
addq %rax, %rsi
movsbl -0xe1(%rbp), %edx
callq 0x3db0
leaq -0x70(%rbp), %rdi
addq $0x20, %rdi
leaq -0xb0(%rbp), %rsi
addq $0x20, %rsi
leaq -0x70(%rbp), %rdx
leaq -0xb0(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x30(%rbp), %r9
callq 0x5d40
movswl -0x22(%rbp), %eax
subl $0x2, %eax
movw %ax, -0xd2(%rbp)
movswl -0xd2(%rbp), %eax
cmpl $0x0, %eax
jle 0x20ad
movq -0x18(%rbp), %rdi
movswl -0xd2(%rbp), %esi
callq 0x4130
cmpq $0x0, %rax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movq %rax, -0xe0(%rbp)
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdi
shlq $0x5, %rax
addq %rax, %rdi
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rsi
shlq $0x5, %rax
addq %rax, %rsi
movq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdx
shlq $0x5, %rax
addq %rax, %rdx
movq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rcx
shlq $0x5, %rax
addq %rax, %rcx
movq -0x30(%rbp), %r8
callq 0x5e10
movq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdi
shlq $0x5, %rax
addq %rax, %rdi
movq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rsi
shlq $0x5, %rax
addq %rax, %rsi
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdx
shlq $0x5, %rax
addq %rax, %rdx
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rcx
shlq $0x5, %rax
addq %rax, %rcx
movq -0x30(%rbp), %r8
callq 0x3e60
movw -0xd2(%rbp), %ax
addw $-0x1, %ax
movw %ax, -0xd2(%rbp)
jmp 0x1f9f
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x4130
cmpq $0x0, %rax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movq %rax, -0xe0(%rbp)
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdi
shlq $0x5, %rax
addq %rax, %rdi
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rsi
shlq $0x5, %rax
addq %rax, %rsi
movq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdx
shlq $0x5, %rax
addq %rax, %rdx
movq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rcx
shlq $0x5, %rax
addq %rax, %rcx
movq -0x30(%rbp), %r8
callq 0x5e10
leaq -0xd0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
addq $0x20, %rsi
leaq -0x70(%rbp), %rdx
movq -0x30(%rbp), %rcx
addq $0x8, %rcx
movsbl -0xe1(%rbp), %r8d
callq 0x3e00
leaq -0xd0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rdx
shlq $0x5, %rax
addq %rax, %rdx
movq -0x30(%rbp), %rcx
callq 0x41b0
leaq -0xd0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x30(%rbp), %rcx
callq 0x41b0
leaq -0xd0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
movq -0x30(%rbp), %rdx
addq $0x8, %rdx
movsbl -0xe1(%rbp), %ecx
callq 0x39c0
leaq -0xd0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
movq -0x10(%rbp), %rdx
movsbl -0xe1(%rbp), %eax
cltq
shlq $0x3, %rax
addq %rax, %rdx
movq -0x30(%rbp), %rcx
callq 0x41b0
leaq -0xd0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdx
shlq $0x5, %rax
addq %rax, %rdx
movq -0x30(%rbp), %rcx
callq 0x41b0
movq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdi
shlq $0x5, %rax
addq %rax, %rdi
movq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rsi
shlq $0x5, %rax
addq %rax, %rsi
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0x70(%rbp), %rdx
shlq $0x5, %rax
addq %rax, %rdx
movl $0x1, %eax
subq -0xe0(%rbp), %rax
leaq -0xb0(%rbp), %rcx
shlq $0x5, %rax
addq %rax, %rcx
movq -0x30(%rbp), %r8
callq 0x3e60
leaq -0x70(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
leaq -0xd0(%rbp), %rdx
movq -0x30(%rbp), %rcx
callq 0x3ff0
movq -0x8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
movsbl -0xe1(%rbp), %edx
callq 0x3db0
movq -0x8(%rbp), %rdi
movsbl -0xe1(%rbp), %eax
cltq
shlq $0x3, %rax
addq %rax, %rdi
leaq -0xb0(%rbp), %rsi
movsbl -0xe1(%rbp), %edx
callq 0x3db0
addq $0xf0, %rsp
popq %rbp
retq
nopl (%rax)