// File: /workspace/github_cpp_makefile_star2_O2/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), %edx
movq %rdx, %rbx
addq %r14, %rbx
movsbl 0x1(%r9), %ebp
movq %r9, 0x38(%rsp)
movswl 0x2(%r9), %eax
movq %rax, 0x10(%rsp)
addl $0x3f, %eax
xorl %ecx, %ecx
movl %edx, %edx
cmpq %rdx, %rcx
jae 0x2416
movb $0x1, (%rbx,%rcx)
movb $0x0, (%r14,%rcx)
incq %rcx
movl 0x1c(%r15), %edx
jmp 0x23fd
pushq $0x40
popq %rcx
cltd
idivl %ecx
movl %eax, 0x8(%rsp)
movq %r15, %rdi
movq %r14, %rsi
callq 0x25f8
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, (%rsp)
movl 0x4(%rsp), %ebp
movl %ebp, %edx
callq *0x8(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %r14, %rdx
callq 0x2650
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x26d0
movq %r15, %rdi
movq %r14, %rsi
callq 0x25f8
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 (%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 0x2650
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x26d0
movl 0x8(%rsp), %edx
movl %edx, %ecx
shll $0x18, %ecx
movl %ecx, %r12d
sarl $0x12, %ecx
movl %ecx, (%rsp)
subl 0x10(%rsp), %ecx
pushq $-0x1
popq %rax
shrq %cl, %rax
movq %rax, 0x28(%rsp)
sarl $0x15, %r12d
movsbl %dl, %eax
decl %eax
cltq
movq %rax, 0x8(%rsp)
xorl %ebp, %ebp
cmpq $0x40, %rbp
je 0x25e2
xorl %r13d, %r13d
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x26d0
movl 0x1c(%r15), %eax
negq %rax
pushq $0x1
popq %rcx
leaq (%rax,%rcx), %rdx
cmpq $0x1, %rdx
je 0x2520
movb -0x1(%rbx,%rcx), %dl
movsbq %r13b, %rsi
incb %r13b
movb %dl, 0x40(%rsp,%rsi)
movsbl %r13b, %edx
incq %rcx
cmpl %edx, %r12d
jg 0x2538
movl (%rsp), %eax
cmpl 0x10(%rsp), %eax
jle 0x2575
movq 0x28(%rsp), %rax
movq 0x8(%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 0x215d
testl %eax, %eax
jne 0x25e6
movq %r15, %rdi
movq %r14, %rsi
callq 0x25f8
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 0x2650
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x26d0
incq %rbp
jmp 0x2513
xorl %eax, %eax
jmp 0x25e9
pushq $0x1
popq %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq