// File: /workspace/github_cpp_makefile_star2_O1/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, %r14
movq %rdi, %rbp
leaq 0x80(%rsp), %r15
movq %r15, (%rsp)
leaq 0x60(%rsp), %rax
movq %rax, 0x8(%rsp)
movsbq (%rcx), %r13
movsbq 0x1(%rcx), %r12
movswl 0x2(%rcx), %edx
leal 0x7(%rdx), %eax
addl $0xe, %edx
testl %eax, %eax
cmovnsl %eax, %edx
sarl $0x3, %edx
movq %r15, %rdi
callq 0x1b19
leaq 0x20(%rsp), %rdi
movq %rbp, %rsi
movl %r12d, %edx
callq 0x1b19
movq %r13, 0x18(%rsp)
leaq (%rsp,%r13,8), %rdi
addq $0x20, %rdi
addq %r12, %rbp
movq %rbp, %rsi
movl %r12d, %edx
callq 0x1b19
movq %r15, %rdi
movq %r15, %rsi
leaq 0x60(%rsp), %rdx
movq %rbx, %rcx
callq 0x1b7d
movq %rax, %rbp
xorl %r15d, %r15d
cmpq $0x0, 0x7653(%rip)      # 0x90b0
je 0x1a7d
movq (%rsp,%rbp,8), %r13
leaq 0x8(%rbx), %rsi
movsbl 0x18(%rsp), %edx
movq %r13, %rdi
callq 0x186e
testl %eax, %eax
jne 0x1a80
jmp 0x1b04
xorl %r13d, %r13d
xorl $0x1, %ebp
movq (%rsp,%rbp,8), %rdx
movzwl 0x2(%rbx), %eax
incl %eax
movswl %ax, %r8d
leaq 0x20(%rsp), %rdi
movq %rdi, %rsi
movq %r13, %rcx
movq %rbx, %r9
callq 0x1c3c
testb %r12b, %r12b
jle 0x1ade
movslq %r12d, %rax
leal -0x8(,%r12,8), %edx
leal -0x1(%r12), %esi
xorl %edi, %edi
movl %esi, %ecx
andl $-0x8, %ecx
movq 0x20(%rsp,%rcx), %r8
movl %edx, %ecx
andb $0x38, %cl
shrq %cl, %r8
movb %r8b, (%r14,%rdi)
incq %rdi
addl $-0x8, %edx
decl %esi
cmpq %rdi, %rax
jne 0x1abb
movb (%rbx), %al
addb %al, %al
testb %al, %al
jle 0x1b04
movzbl %al, %eax
xorl %ecx, %ecx
xorl %edx, %edx
orq 0x20(%rsp,%rcx,8), %rdx
incq %rcx
cmpq %rcx, %rax
jne 0x1aed
xorl %r15d, %r15d
testq %rdx, %rdx
setne %r15b
movl %r15d, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq