Как использовать функцию ECDSA в библиотеке medtls - PullRequest
0 голосов
/ 25 декабря 2018

Я использую библиотеку mbedtls (https://github.com/ARMmbed/mbedtls) на микроконтроллере ARM (Ambiq).

Мне нужно использовать функцию mbedtls_ecdsa_sign_det () для подписания транзакции биткойнов.

На самом деле, я не уверен, что это правильная функция.

Вот документация по этой функции:

Compute ECDSA signature of a previously hashed message, deterministic version (RFC 6979).

Parameters:
grp ECP group
r   First output integer
s   Second output integer
d   Private signing key
buf Message hash
blen    Length of buf
md_alg  MD algorithm used to hash the message
Returns:
0 if successful, or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code

The header file includes the following description:
/**
 * \brief           This function computes the ECDSA signature of a
 *                  previously-hashed message, deterministic version.
 *
 *                  For more information, see <em>RFC-6979: Deterministic
 *                  Usage of the Digital Signature Algorithm (DSA) and Elliptic
 *                  Curve Digital Signature Algorithm (ECDSA)</em>.
 *
 * \note            If the bitlength of the message hash is larger than the
 *                  bitlength of the group order, then the hash is truncated as
 *                  defined in <em>Standards for Efficient Cryptography Group
 *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
 *                  4.1.3, step 5.
 *
 * \see             ecp.h
 *
 * \param grp       The context for the elliptic curve to use.
 *                  This must be initialized and have group parameters
 *                  set, for example through mbedtls_ecp_group_load().
 * \param r         The MPI context in which to store the first part
 *                  the signature. This must be initialized.
 * \param s         The MPI context in which to store the second part
 *                  the signature. This must be initialized.
 * \param d         The private signing key. This must be initialized
 *                  and setup, for example through mbedtls_ecp_gen_privkey().
 * \param buf       The hashed content to be signed. This must be a readable
 *                  buffer of length \p blen Bytes. It may be \c NULL if
 *                  \p blen is zero.
 * \param blen      The length of \p buf in Bytes.
 * \param md_alg    The hash algorithm used to hash the original data.
 *
 * \return          \c 0 on success.
 * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
 *                  error code on failure.
 */
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
                            mbedtls_mpi *s, const mbedtls_mpi *d,
                            const unsigned char *buf, size_t blen,
                            mbedtls_md_type_t md_alg );

Кроме того, я не нашел ни одного примера, как использоватьэта функция.

Я не знаю, как инициализировать переданные указатели, grp, r, s и d.

1 Ответ

0 голосов
/ 25 декабря 2018

Математически говоря, ECDSA-подпись представляет собой пару из двух целых чисел ( r , s ).Функция mbedtls_ecdsa_sign_det дает вам два целых числа r и s в качестве выходных данных, и вам решать, как вы хотите вывести эти целые числа.Существует два общих представления сигнатур ECDSA: взять представление фиксированного размера r и s и сложить эти два вместе или собрать их в ASN.1 последовательность, как правило, в форме DER (ASN.1 допускает несколько представлений, например, с ведущими нулями или без них, а DER - это конкретное представление ASN.1 без начальных нулей). Биткойн использует представление DER .К счастью для вас, Mbed TLS имеет функцию, которая напрямую выводит это представление DER: mbedtls_ecdsa_write_signature.

Существует два варианта ECDSA: рандомизированный и детерминированный.В любом случае они создают совместимые подписи (в детерминированном варианте используется определенный выбор случайного параметра).mbedtls_ecdsa_write_signature использует детерминированный вариант, если ваша сборка поддерживает его, и случайный вариант в противном случае.

Вот как выглядит вызов этой функции.Он принимает следующие входные данные:

  • Закрытый ключ ECDSA key.
  • Хэш SHA-256 для подписи hash.
  • Генератор случайных чиселкоторую вы должны инициализировать в начале вашей программы (не при каждом создании подписи!).См. https://tls.mbed.org/kb/how-to/generate-an-aes-key для примера.
unsigned char signature[2 * 32 + 9]; // "at least twice as large as the size of the curve used, plus 9"
size_t signature_length;
ret = mbedtls_ecdsa_write_signature(key, MBEDTLS_MD_SHA256, hash, 32,
                                    signature, &signature_length,
                                    mbedtls_ctr_drbg_random, &ctr_drbg);
if (ret == 0) {
    // The signature is in the signature array. It is signature_length bytes long. 
} else ERROR();
...