// File: /workspace/github_cpp_makefile_star2_O2/simap[P]ecctools/lib/uECC.c
// Function: uECC_shared_secret
int uECC_shared_secret(const uint8_t *public_key,
                       const uint8_t *private_key,
                       uint8_t *secret,
                       uECC_Curve curve) {
    uECC_word_t _public[uECC_MAX_WORDS * 2];
    uECC_word_t _private[uECC_MAX_WORDS];

    uECC_word_t tmp[uECC_MAX_WORDS];
    uECC_word_t *p2[2] = {_private, tmp};
    uECC_word_t *initial_Z = 0;
    uECC_word_t carry;
    wordcount_t num_words = curve->num_words;
    wordcount_t num_bytes = curve->num_bytes;

#if uECC_VLI_NATIVE_LITTLE_ENDIAN
    bcopy((uint8_t *) _private, private_key, num_bytes);
    bcopy((uint8_t *) _public, public_key, num_bytes*2);
#else
    uECC_vli_bytesToNative(_private, private_key, BITS_TO_BYTES(curve->num_n_bits));
    uECC_vli_bytesToNative(_public, public_key, num_bytes);
    uECC_vli_bytesToNative(_public + num_words, public_key + num_bytes, num_bytes);
#endif

    /* Regularize the bitcount for the private key so that attackers cannot use a side channel
       attack to learn the number of leading zeros. */
    carry = regularize_k(_private, _private, tmp, curve);

    /* If an RNG function was specified, try to get a random initial Z value to improve
       protection against side-channel attacks. */
    if (g_rng_function) {
        if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) {
            return 0;
        }
        initial_Z = p2[carry];
    }

    EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve);
#if uECC_VLI_NATIVE_LITTLE_ENDIAN
    bcopy((uint8_t *) secret, (uint8_t *) _public, num_bytes);
#else
    uECC_vli_nativeToBytes(secret, num_bytes, _public);
#endif
    return !EccPoint_isZero(_public, curve);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rcx, %rbx
movq %rdx, 0x18(%rsp)
movq %rdi, %rbp
leaq 0x80(%rsp), %r12
movq %r12, (%rsp)
leaq 0x20(%rsp), %rax
movq %rax, 0x8(%rsp)
movsbq (%rcx), %r13
movsbq 0x1(%rcx), %r15
movswl 0x2(%rcx), %r14d
leal 0x7(%r14), %eax
pushq $0x8
popq %rcx
cltd
idivl %ecx
movq %r12, %rdi
movl %eax, %edx
callq 0x19d5
leaq 0x40(%rsp), %rdi
movq %rbp, %rsi
movl %r15d, %edx
callq 0x19d5
movq %r13, 0x10(%rsp)
leaq (%rsp,%r13,8), %rdi
addq $0x40, %rdi
addq %r15, %rbp
movq %rbp, %rsi
movl %r15d, %edx
callq 0x19d5
movq %r12, %rdi
movq %r12, %rsi
leaq 0x20(%rsp), %rdx
movq %rbx, %rcx
callq 0x1a25
movq %rax, %r12
xorl %ebp, %ebp
cmpq $0x0, 0x676e(%rip)      # 0x80c0
je 0x1974
movq (%rsp,%r12,8), %r13
leaq 0x8(%rbx), %rsi
movsbl 0x10(%rsp), %edx
movq %r13, %rdi
callq 0x1776
testl %eax, %eax
je 0x19c1
movzwl 0x2(%rbx), %r14d
jmp 0x1977
xorl %r13d, %r13d
xorl $0x1, %r12d
movq (%rsp,%r12,8), %rdx
incl %r14d
movswl %r14w, %r8d
leaq 0x40(%rsp), %r12
movq %r12, %rdi
movq %r12, %rsi
movq %r13, %rcx
movq %rbx, %r9
callq 0x1ab8
movq 0x18(%rsp), %rdi
movl %r15d, %esi
movq %r12, %rdx
callq 0x1887
movb (%rbx), %al
addb %al, %al
movsbl %al, %esi
movq %r12, %rdi
callq 0x1d5d
movq %rax, %rbp
xorl $0x1, %ebp
movl %ebp, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq