// File: /workspace/github_cpp_makefile_star2_O1/simap[P]ecctools/lib/uECC.c
// Function: uECC_sign_deterministic
int uECC_sign_deterministic(const uint8_t *private_key,
                            const uint8_t *message_hash,
                            unsigned hash_size,
                            const uECC_HashContext *hash_context,
                            uint8_t *signature,
                            uECC_Curve curve) {
    uint8_t *K = hash_context->tmp;
    uint8_t *V = K + hash_context->result_size;
    wordcount_t num_bytes = curve->num_bytes;
    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
    bitcount_t num_n_bits = curve->num_n_bits;
    uECC_word_t tries;
    unsigned i;
    for (i = 0; i < hash_context->result_size; ++i) {
        V[i] = 0x01;
        K[i] = 0;
    }

    /* K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) */
    HMAC_init(hash_context, K);
    V[hash_context->result_size] = 0x00;
    HMAC_update(hash_context, V, hash_context->result_size + 1);
    HMAC_update(hash_context, private_key, num_bytes);
    HMAC_update(hash_context, message_hash, hash_size);
    HMAC_finish(hash_context, K, K);

    update_V(hash_context, K, V);

    /* K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) */
    HMAC_init(hash_context, K);
    V[hash_context->result_size] = 0x01;
    HMAC_update(hash_context, V, hash_context->result_size + 1);
    HMAC_update(hash_context, private_key, num_bytes);
    HMAC_update(hash_context, message_hash, hash_size);
    HMAC_finish(hash_context, K, K);

    update_V(hash_context, K, V);

    for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
        uECC_word_t T[uECC_MAX_WORDS];
        uint8_t *T_ptr = (uint8_t *)T;
        wordcount_t T_bytes = 0;
        for (;;) {
            update_V(hash_context, K, V);
            for (i = 0; i < hash_context->result_size; ++i) {
                T_ptr[T_bytes++] = V[i];
                if (T_bytes >= num_n_words * uECC_WORD_SIZE) {
                    goto filled;
                }
            }
        }
    filled:
        if ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8 > num_n_bits) {
            uECC_word_t mask = (uECC_word_t)-1;
            T[num_n_words - 1] &=
                mask >> ((bitcount_t)(num_n_words * uECC_WORD_SIZE * 8 - num_n_bits));
        }

        if (uECC_sign_with_k(private_key, message_hash, hash_size, T, signature, curve)) {
            return 1;
        }

        /* K = HMAC_K(V || 0x00) */
        HMAC_init(hash_context, K);
        V[hash_context->result_size] = 0x00;
        HMAC_update(hash_context, V, hash_context->result_size + 1);
        HMAC_finish(hash_context, K, K);

        update_V(hash_context, K, V);
    }
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %r8, 0x30(%rsp)
movq %rcx, %r15
movl %edx, 0x4(%rsp)
movq %rsi, 0x20(%rsp)
movq %rdi, 0x18(%rsp)
movq 0x20(%rcx), %r14
movl 0x1c(%rcx), %eax
movswl 0x2(%r9), %edx
leal 0x3f(%rdx), %ecx
movq %rdx, 0x10(%rsp)
addl $0x7e, %edx
testl %ecx, %ecx
cmovnsl %ecx, %edx
leaq (%r14,%rax), %rbx
sarl $0x6, %edx
movl %edx, (%rsp)
movq %r9, 0x38(%rsp)
movsbl 0x1(%r9), %ebp
testq %rax, %rax
je 0x27f5
xorl %eax, %eax
movb $0x1, (%rbx,%rax)
movb $0x0, (%r14,%rax)
incq %rax
movl 0x1c(%r15), %ecx
cmpq %rcx, %rax
jb 0x27e0
movq %r15, %rdi
movq %r14, %rsi
callq 0x2a3f
movl 0x1c(%r15), %eax
movb $0x0, (%rbx,%rax)
movl 0x1c(%r15), %edx
incl %edx
movq %r15, %rdi
movq %rbx, %rsi
callq *0x8(%r15)
movq %r15, %rdi
movq 0x18(%rsp), %r13
movq %r13, %rsi
movl %ebp, %edx
callq *0x8(%r15)
movq %r15, %rdi
movq 0x20(%rsp), %r12
movq %r12, %rsi
movl %ebp, 0x8(%rsp)
movl 0x4(%rsp), %ebp
movl %ebp, %edx
callq *0x8(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %r14, %rdx
callq 0x2aa2
movq %r15, %rdi
movq %r14, %rsi
callq 0x2a3f
movl 0x1c(%r15), %edx
movq %r15, %rdi
movq %rbx, %rsi
callq *0x8(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x2aa2
movq %r15, %rdi
movq %r14, %rsi
callq 0x2a3f
movl 0x1c(%r15), %eax
movb $0x1, (%rbx,%rax)
movl 0x1c(%r15), %edx
incl %edx
movq %r15, %rdi
movq %rbx, %rsi
callq *0x8(%r15)
movq %r15, %rdi
movq %r13, %rsi
movl 0x8(%rsp), %edx
callq *0x8(%r15)
movq %r15, %rdi
movq %r12, %rsi
movl %ebp, %edx
callq *0x8(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %r14, %rdx
callq 0x2aa2
movq %r15, %rdi
movq %r14, %rsi
callq 0x2a3f
movl 0x1c(%r15), %edx
movq %r15, %rdi
movq %rbx, %rsi
callq *0x8(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x2aa2
movl (%rsp), %eax
movl %eax, %ecx
shll $0x18, %ecx
movl %ecx, %r12d
sarl $0x15, %r12d
movsbl %al, %eax
sarl $0x12, %ecx
movl %ecx, (%rsp)
subl 0x10(%rsp), %ecx
movq $-0x1, %rdx
shrq %cl, %rdx
movq %rdx, 0x8(%rsp)
decl %eax
cltq
movq %rax, 0x28(%rsp)
xorl %ebp, %ebp
xorl %r13d, %r13d
movq %r15, %rdi
movq %r14, %rsi
callq 0x2a3f
movl 0x1c(%r15), %edx
movq %r15, %rdi
movq %rbx, %rsi
callq *0x8(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x2aa2
movl 0x1c(%r15), %eax
testq %rax, %rax
je 0x2922
negq %rax
movl $0x1, %ecx
movb -0x1(%rbx,%rcx), %dl
movsbq %r13b, %rsi
incb %r13b
movb %dl, 0x40(%rsp,%rsi)
movsbl %r13b, %edx
cmpl %edx, %r12d
jle 0x2984
leaq (%rax,%rcx), %rdx
incq %rdx
incq %rcx
cmpq $0x1, %rdx
jne 0x295a
jmp 0x2922
movl (%rsp), %eax
cmpl 0x10(%rsp), %eax
jle 0x299c
movq 0x8(%rsp), %rax
movq 0x28(%rsp), %rcx
andq %rax, 0x40(%rsp,%rcx,8)
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rsi
movl 0x4(%rsp), %edx
leaq 0x40(%rsp), %rcx
movq 0x30(%rsp), %r8
movq 0x38(%rsp), %r9
callq 0x2489
testl %eax, %eax
jne 0x2a2b
movq %r15, %rdi
movq %r14, %rsi
callq 0x2a3f
movl 0x1c(%r15), %eax
movb $0x0, (%rbx,%rax)
movl 0x1c(%r15), %edx
incl %edx
movq %r15, %rdi
movq %rbx, %rsi
callq *0x8(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %r14, %rdx
callq 0x2aa2
movq %r15, %rdi
movq %r14, %rsi
callq 0x2a3f
movl 0x1c(%r15), %edx
movq %r15, %rdi
movq %rbx, %rsi
callq *0x8(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x2aa2
incq %rbp
cmpq $0x40, %rbp
jne 0x291f
xorl %eax, %eax
jmp 0x2a30
movl $0x1, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq