// File: /workspace/github_cpp_makefile_star2_O3/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), %rax
movq %rax, (%rsp)
movq %rax, %rdi
leaq 0x60(%rsp), %rax
movq %rax, 0x8(%rsp)
movsbq (%rcx), %r13
movsbq 0x1(%rcx), %r12
movswl 0x2(%rcx), %r15d
leal 0x7(%r15), %eax
leal 0xe(%r15), %edx
testl %eax, %eax
cmovnsl %eax, %edx
sarl $0x3, %edx
callq 0x1b04
leaq 0x20(%rsp), %rdi
movq %rbp, %rsi
movl %r12d, %edx
callq 0x1b04
movq %r13, 0x18(%rsp)
leaq (%rsp,%r13,8), %rdi
addq $0x20, %rdi
addq %r12, %rbp
movq %rbp, %rsi
movl %r12d, %edx
callq 0x1b04
leaq 0x80(%rsp), %rdi
movq %rdi, %rsi
leaq 0x60(%rsp), %rdx
movq %rbx, %rcx
callq 0x1b68
movq %rax, %r13
cmpq $0x0, 0x767e(%rip)      # 0x90b0
je 0x1a58
movq (%rsp,%r13,8), %rbp
leaq 0x8(%rbx), %rsi
movsbl 0x18(%rsp), %edx
movq %rbp, %rdi
callq 0x182b
testl %eax, %eax
je 0x1af0
movzwl 0x2(%rbx), %r15d
jmp 0x1a5a
xorl %ebp, %ebp
xorl $0x1, %r13d
movq (%rsp,%r13,8), %rdx
incl %r15d
movswl %r15w, %r8d
leaq 0x20(%rsp), %rdi
movq %rdi, %rsi
movq %rbp, %rcx
movq %rbx, %r9
callq 0x1c27
testb %r12b, %r12b
jle 0x1ab6
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 0x1a93
movb (%rbx), %cl
addb %cl, %cl
testb %cl, %cl
movl $0x0, %eax
jle 0x1af2
movzbl %cl, %eax
pxor %xmm0, %xmm0
xorl %ecx, %ecx
por 0x20(%rsp,%rcx,8), %xmm0
addq $0x2, %rcx
cmpq %rcx, %rax
jne 0x1acc
pxor %xmm1, %xmm1
pcmpeqd %xmm1, %xmm0
movmskps %xmm0, %ecx
xorl %eax, %eax
xorl $0xf, %ecx
setne %al
jmp 0x1af2
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq