From 7bc4371b0bcb7ee9ab6ca864b48b7cbdff1d2c98 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Fri, 26 Nov 2021 23:45:59 +0300 Subject: [PATCH 01/12] vcpkg ArmoryDB build fixes --- CMakeLists.txt | 5 ++++ include/btc/ecc.h | 5 ++++ include/btc/ecc_key.h | 2 +- src/commontools.c | 2 +- src/ecc_key.c | 8 +++---- src/ecc_libsecp256k1.c | 53 ++++++++++++++++++++++++++++++++++++++++++ src/tx.c | 2 +- 7 files changed, 70 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df54ba8fb..1efe11e20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,10 @@ add_definitions(-DUSE_SCALAR_INV_BUILTIN) add_definitions(-DRANDOM_DEVICE="/dev/urandom") add_definitions(-DENABLE_MODULE_RECOVERY) +IF (MSVC) + add_definitions(-DWIN32) +ENDIF (MSVC) + FILE(GLOB SOURCES src/*.c) list(REMOVE_ITEM SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/net.c) @@ -32,6 +36,7 @@ INCLUDE_DIRECTORIES( include ) INCLUDE_DIRECTORIES( src/logdb/include ) INCLUDE_DIRECTORIES( src/secp256k1 ) INCLUDE_DIRECTORIES( ${GMP_INSTALL_DIR}/include ) +INCLUDE_DIRECTORIES( ${GMP_INCLUDE_DIR} ) ADD_LIBRARY( ${BTC_LIB_NAME} ${SOURCES} ${LOGDB} ${SECP256K1} ${HEADERS}) TARGET_LINK_LIBRARIES(${BTC_LIB_NAME}) diff --git a/include/btc/ecc.h b/include/btc/ecc.h index 1f16da654..5eb27b1be 100644 --- a/include/btc/ecc.h +++ b/include/btc/ecc.h @@ -42,9 +42,14 @@ LIBBTC_API void btc_ecc_get_pubkey(const uint8_t* private_key, uint8_t* public_k //!ec mul tweak on given private key LIBBTC_API btc_bool btc_ecc_private_key_tweak_add(uint8_t* private_key, const uint8_t* tweak); +LIBBTC_API btc_bool btc_ecc_private_key_tweak_mul(uint8_t* private_key, const uint8_t* tweak); //!ec mul tweak on given public key LIBBTC_API btc_bool btc_ecc_public_key_tweak_add(uint8_t* public_key_inout, const uint8_t* tweak); +LIBBTC_API btc_bool btc_ecc_public_key_tweak_mul(uint8_t* public_key_inout, const uint8_t* tweak); + +LIBBTC_API btc_bool btc_ecc_public_key_compress(uint8_t* public_key_in, uint8_t* public_key_out); +LIBBTC_API btc_bool btc_ecc_public_key_uncompress(uint8_t* public_key_in, uint8_t* public_key_out); //!verifies a given 32byte key LIBBTC_API btc_bool btc_ecc_verify_privatekey(const uint8_t* private_key); diff --git a/include/btc/ecc_key.h b/include/btc/ecc_key.h index 28be6b132..596d5924e 100644 --- a/include/btc/ecc_key.h +++ b/include/btc/ecc_key.h @@ -58,7 +58,7 @@ LIBBTC_API unsigned int btc_pubkey_get_length(unsigned char ch_header); LIBBTC_API btc_bool btc_pubkey_is_valid(const btc_pubkey* pubkey); LIBBTC_API void btc_pubkey_cleanse(btc_pubkey* pubkey); -LIBBTC_API void btc_pubkey_from_key(const btc_key* privkey, btc_pubkey* pubkey_inout); +LIBBTC_API void btc_pubkey_from_key(const btc_key* privkey, btc_pubkey* pubkey_inout, btc_bool compressed); //get the hash160 (single SHA256 + RIPEMD160) LIBBTC_API void btc_pubkey_get_hash160(const btc_pubkey* pubkey, uint160 hash160); diff --git a/src/commontools.c b/src/commontools.c index aefa2fd72..be5299917 100644 --- a/src/commontools.c +++ b/src/commontools.c @@ -64,7 +64,7 @@ btc_bool pubkey_from_privatekey(const btc_chainparams* chain, const char* privke btc_pubkey pubkey; btc_pubkey_init(&pubkey); assert(btc_pubkey_is_valid(&pubkey) == 0); - btc_pubkey_from_key(&key, &pubkey); + btc_pubkey_from_key(&key, &pubkey, true); btc_privkey_cleanse(&key); btc_pubkey_get_hex(&pubkey, pubkey_hex, sizeout); diff --git a/src/ecc_key.c b/src/ecc_key.c index 0bdf755ae..7c1941f76 100644 --- a/src/ecc_key.c +++ b/src/ecc_key.c @@ -183,15 +183,15 @@ btc_bool btc_pubkey_get_hex(const btc_pubkey* pubkey, char* str, size_t* strsize } -void btc_pubkey_from_key(const btc_key* privkey, btc_pubkey* pubkey_inout) +void btc_pubkey_from_key(const btc_key* privkey, btc_pubkey* pubkey_inout, btc_bool compressed) { if (pubkey_inout == NULL || privkey == NULL) return; - size_t in_out_len = BTC_ECKEY_COMPRESSED_LENGTH; + size_t in_out_len = compressed ? BTC_ECKEY_COMPRESSED_LENGTH : BTC_ECKEY_UNCOMPRESSED_LENGTH; - btc_ecc_get_pubkey(privkey->privkey, pubkey_inout->pubkey, &in_out_len, true); - pubkey_inout->compressed = true; + btc_ecc_get_pubkey(privkey->privkey, pubkey_inout->pubkey, &in_out_len, compressed); + pubkey_inout->compressed = compressed; } diff --git a/src/ecc_libsecp256k1.c b/src/ecc_libsecp256k1.c index 18a655b63..3cc9825a2 100644 --- a/src/ecc_libsecp256k1.c +++ b/src/ecc_libsecp256k1.c @@ -83,6 +83,59 @@ btc_bool btc_ecc_public_key_tweak_add(uint8_t* public_key_inout, const uint8_t* return true; } +btc_bool btc_ecc_private_key_tweak_mul(uint8_t* private_key, const uint8_t* tweak) +{ + assert(secp256k1_ctx); + return secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, (unsigned char*)private_key, (const unsigned char*)tweak); +} + +btc_bool btc_ecc_public_key_tweak_mul(uint8_t* public_key_inout, const uint8_t* tweak) +{ + size_t out = BTC_ECKEY_UNCOMPRESSED_LENGTH; + secp256k1_pubkey pubkey; + + assert(secp256k1_ctx); + if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey, public_key_inout, 65)) + return false; + + if (!secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, &pubkey, (const unsigned char*)tweak)) + return false; + + if (!secp256k1_ec_pubkey_serialize(secp256k1_ctx, public_key_inout, &out, &pubkey, SECP256K1_EC_UNCOMPRESSED)) + return false; + + return true; +} + +btc_bool btc_ecc_public_key_compress(uint8_t* public_key_in, uint8_t* public_key_out) +{ + secp256k1_pubkey pubkey; + assert(secp256k1_ctx); + + if(!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey, public_key_in, 65)) + return false; + + size_t out = BTC_ECKEY_COMPRESSED_LENGTH; + if(!secp256k1_ec_pubkey_serialize(secp256k1_ctx, public_key_out, &out, &pubkey, SECP256K1_EC_COMPRESSED)) + return false; + + return true; +} + +btc_bool btc_ecc_public_key_uncompress(uint8_t* public_key_in, uint8_t* public_key_out) +{ + secp256k1_pubkey pubkey; + assert(secp256k1_ctx); + + if(!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey, public_key_in, 33)) + return false; + + size_t out = BTC_ECKEY_UNCOMPRESSED_LENGTH; + if(!secp256k1_ec_pubkey_serialize(secp256k1_ctx, public_key_out, &out, &pubkey, SECP256K1_EC_UNCOMPRESSED)) + return false; + + return true; +} btc_bool btc_ecc_verify_privatekey(const uint8_t* private_key) { diff --git a/src/tx.c b/src/tx.c index 8e42621f5..1adaf55a6 100644 --- a/src/tx.c +++ b/src/tx.c @@ -796,7 +796,7 @@ enum btc_tx_sign_result btc_tx_sign_input(btc_tx *tx_in_out, const cstring *scri // calculate pubkey btc_pubkey pubkey; btc_pubkey_init(&pubkey); - btc_pubkey_from_key(privkey, &pubkey); + btc_pubkey_from_key(privkey, &pubkey, true); if (!btc_pubkey_is_valid(&pubkey)) { return BTC_SIGN_INVALID_KEY; } From 6e90c2dbbce2cdca66c213b56cf0de508efe7465 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Tue, 11 Jan 2022 20:45:21 +0300 Subject: [PATCH 02/12] revert public key changes back --- include/btc/ecc_key.h | 2 +- src/ecc_key.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/btc/ecc_key.h b/include/btc/ecc_key.h index 596d5924e..28be6b132 100644 --- a/include/btc/ecc_key.h +++ b/include/btc/ecc_key.h @@ -58,7 +58,7 @@ LIBBTC_API unsigned int btc_pubkey_get_length(unsigned char ch_header); LIBBTC_API btc_bool btc_pubkey_is_valid(const btc_pubkey* pubkey); LIBBTC_API void btc_pubkey_cleanse(btc_pubkey* pubkey); -LIBBTC_API void btc_pubkey_from_key(const btc_key* privkey, btc_pubkey* pubkey_inout, btc_bool compressed); +LIBBTC_API void btc_pubkey_from_key(const btc_key* privkey, btc_pubkey* pubkey_inout); //get the hash160 (single SHA256 + RIPEMD160) LIBBTC_API void btc_pubkey_get_hash160(const btc_pubkey* pubkey, uint160 hash160); diff --git a/src/ecc_key.c b/src/ecc_key.c index 11fe893d0..68a59b7ef 100644 --- a/src/ecc_key.c +++ b/src/ecc_key.c @@ -184,8 +184,9 @@ btc_bool btc_pubkey_get_hex(const btc_pubkey* pubkey, char* str, size_t* strsize } -void btc_pubkey_from_key(const btc_key* privkey, btc_pubkey* pubkey_inout, btc_bool compressed) +void btc_pubkey_from_key(const btc_key* privkey, btc_pubkey* pubkey_inout) { + const btc_bool compressed = true; if (pubkey_inout == NULL || privkey == NULL) return; From 8370a3c853f4ac0d4ca4e35ada81e752c6df4368 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Wed, 12 Jan 2022 00:26:08 +0300 Subject: [PATCH 03/12] fixup --- src/commontools.c | 2 +- src/tx.c | 2 +- test/eckey_tests.c | 2 +- test/tx_tests.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commontools.c b/src/commontools.c index 61f32cedb..14c444794 100644 --- a/src/commontools.c +++ b/src/commontools.c @@ -66,7 +66,7 @@ btc_bool pubkey_from_privatekey(const btc_chainparams* chain, const char* privke btc_pubkey pubkey; btc_pubkey_init(&pubkey); assert(btc_pubkey_is_valid(&pubkey) == 0); - btc_pubkey_from_key(&key, &pubkey, true); + btc_pubkey_from_key(&key, &pubkey); btc_privkey_cleanse(&key); btc_pubkey_get_hex(&pubkey, pubkey_hex, sizeout); diff --git a/src/tx.c b/src/tx.c index 1adaf55a6..8e42621f5 100644 --- a/src/tx.c +++ b/src/tx.c @@ -796,7 +796,7 @@ enum btc_tx_sign_result btc_tx_sign_input(btc_tx *tx_in_out, const cstring *scri // calculate pubkey btc_pubkey pubkey; btc_pubkey_init(&pubkey); - btc_pubkey_from_key(privkey, &pubkey, true); + btc_pubkey_from_key(privkey, &pubkey); if (!btc_pubkey_is_valid(&pubkey)) { return BTC_SIGN_INVALID_KEY; } diff --git a/test/eckey_tests.c b/test/eckey_tests.c index c5ce6731c..b723132a1 100644 --- a/test/eckey_tests.c +++ b/test/eckey_tests.c @@ -46,7 +46,7 @@ void test_eckey() btc_pubkey pubkey; btc_pubkey_init(&pubkey); assert(btc_pubkey_is_valid(&pubkey) == 0); - btc_pubkey_from_key(&key, &pubkey, false); + btc_pubkey_from_key(&key, &pubkey); assert(btc_pubkey_is_valid(&pubkey) == 1); assert(btc_privkey_verify_pubkey(&key, &pubkey) == 1); diff --git a/test/tx_tests.c b/test/tx_tests.c index 8b5ca3e42..352bad5c7 100644 --- a/test/tx_tests.c +++ b/test/tx_tests.c @@ -1034,7 +1034,7 @@ void test_script_parse() btc_pubkey* pubkey = btc_malloc(sizeof(btc_pubkey)); btc_pubkey_init(pubkey); - btc_pubkey_from_key(&key, pubkey, false); + btc_pubkey_from_key(&key, pubkey); assert(btc_pubkey_is_valid(pubkey) == 1); vector_add(pubkeys, pubkey); @@ -1150,7 +1150,7 @@ void test_script_parse() btc_pubkey pubkeytx_rev; btc_pubkey_init(&pubkeytx_rev); - btc_pubkey_from_key(&key, &pubkeytx_rev, false); + btc_pubkey_from_key(&key, &pubkeytx_rev); tx = btc_tx_new(); btc_tx_add_data_out(tx, 100000, sigcmp, outlencmp); //0.001 BTC From 087fffa0253571c5f333aff6b6e4afe3e386886b Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Fri, 28 Jan 2022 14:44:01 +0300 Subject: [PATCH 04/12] malloc cast --- src/trezor-crypto/base58.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/trezor-crypto/base58.c b/src/trezor-crypto/base58.c index 72af3f94c..0c3dd41bf 100644 --- a/src/trezor-crypto/base58.c +++ b/src/trezor-crypto/base58.c @@ -59,7 +59,7 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { const unsigned char *b58u = (const unsigned char *)b58; unsigned char *binu = bin; const size_t outisz = (binsz + sizeof(b58_almostmaxint_t) - 1); - b58_almostmaxint_t *outi = malloc(outisz); + b58_almostmaxint_t *outi = (b58_almostmaxint_t *)malloc(outisz); b58_maxint_t t = 0; b58_almostmaxint_t c = 0; size_t i = 0, j = 0; @@ -160,7 +160,7 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { while (zcount < binsz && !bin[zcount]) ++zcount; const size_t size = (binsz - zcount) * 138 / 100 + 1; - uint8_t *buf = malloc(size); + uint8_t *buf = (uint8_t*)malloc(size); memzero(buf, size); for (i = zcount, high = size - 1; i < binsz; ++i, high = j) { @@ -198,7 +198,7 @@ int base58_encode_check(const uint8_t *data, int datalen, if (datalen > 128) { return 0; } - uint8_t *buf = malloc(datalen + 32); + uint8_t *buf = (uint8_t *)malloc(datalen + 32); memset(buf, 0, sizeof(buf)); uint8_t *hash = buf + datalen; memcpy(buf, data, datalen); @@ -215,7 +215,7 @@ int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, if (datalen > 128) { return 0; } - uint8_t *d = malloc(datalen + 4); + uint8_t *d = (uint8_t *)malloc(datalen + 4); memset(d, 0, sizeof(d)); size_t res = datalen + 4; if (b58tobin(d, &res, str) != true) { From 25e31fd32557db76fb28ce6b1ecf21ab133ffb24 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Fri, 28 Jan 2022 14:55:32 +0300 Subject: [PATCH 05/12] malloc wrappers --- src/logdb/test/logdb_tests.c | 2 +- src/secp256k1/src/tests.c | 24 ++++++++++++------------ src/trezor-crypto/base58.c | 8 ++++---- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/logdb/test/logdb_tests.c b/src/logdb/test/logdb_tests.c index b65b4a7fb..50412ca1e 100644 --- a/src/logdb/test/logdb_tests.c +++ b/src/logdb/test/logdb_tests.c @@ -148,7 +148,7 @@ void test_logdb(logdb_log_db* (*new_func)()) fsize = ftell(f); fseek(f, 0, SEEK_SET); - buf = malloc(fsize + 1); + buf = safe_malloc(fsize + 1); fread(buf, fsize, 1, f); fclose(f); diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c index e0c8c8560..86d81ce67 100644 --- a/src/secp256k1/src/tests.c +++ b/src/secp256k1/src/tests.c @@ -164,10 +164,10 @@ void run_context_tests(int use_prealloc) { secp256k1_scalar sigr, sigs; if (use_prealloc) { - none_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); - sign_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); - vrfy_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); - both_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); + none_prealloc = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); + sign_prealloc = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); + vrfy_prealloc = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); + both_prealloc = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); CHECK(none_prealloc != NULL); CHECK(sign_prealloc != NULL); CHECK(vrfy_prealloc != NULL); @@ -207,40 +207,40 @@ void run_context_tests(int use_prealloc) { if (use_prealloc) { /* clone into a non-preallocated context and then again into a new preallocated one. */ ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_preallocated_destroy(ctx_tmp); - free(none_prealloc); none_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); CHECK(none_prealloc != NULL); + free(none_prealloc); none_prealloc = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); CHECK(none_prealloc != NULL); ctx_tmp = none; none = secp256k1_context_preallocated_clone(none, none_prealloc); secp256k1_context_destroy(ctx_tmp); ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_preallocated_destroy(ctx_tmp); - free(sign_prealloc); sign_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); CHECK(sign_prealloc != NULL); + free(sign_prealloc); sign_prealloc = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); CHECK(sign_prealloc != NULL); ctx_tmp = sign; sign = secp256k1_context_preallocated_clone(sign, sign_prealloc); secp256k1_context_destroy(ctx_tmp); ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_preallocated_destroy(ctx_tmp); - free(vrfy_prealloc); vrfy_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); CHECK(vrfy_prealloc != NULL); + free(vrfy_prealloc); vrfy_prealloc = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); CHECK(vrfy_prealloc != NULL); ctx_tmp = vrfy; vrfy = secp256k1_context_preallocated_clone(vrfy, vrfy_prealloc); secp256k1_context_destroy(ctx_tmp); ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_preallocated_destroy(ctx_tmp); - free(both_prealloc); both_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); CHECK(both_prealloc != NULL); + free(both_prealloc); both_prealloc = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); CHECK(both_prealloc != NULL); ctx_tmp = both; both = secp256k1_context_preallocated_clone(both, both_prealloc); secp256k1_context_destroy(ctx_tmp); } else { /* clone into a preallocated context and then again into a new non-preallocated one. */ void *prealloc_tmp; - prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); CHECK(prealloc_tmp != NULL); + prealloc_tmp = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE)); CHECK(prealloc_tmp != NULL); ctx_tmp = none; none = secp256k1_context_preallocated_clone(none, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_preallocated_destroy(ctx_tmp); free(prealloc_tmp); - prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); CHECK(prealloc_tmp != NULL); + prealloc_tmp = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); CHECK(prealloc_tmp != NULL); ctx_tmp = sign; sign = secp256k1_context_preallocated_clone(sign, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_preallocated_destroy(ctx_tmp); free(prealloc_tmp); - prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); CHECK(prealloc_tmp != NULL); + prealloc_tmp = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); CHECK(prealloc_tmp != NULL); ctx_tmp = vrfy; vrfy = secp256k1_context_preallocated_clone(vrfy, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_preallocated_destroy(ctx_tmp); free(prealloc_tmp); - prealloc_tmp = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); CHECK(prealloc_tmp != NULL); + prealloc_tmp = checked_malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); CHECK(prealloc_tmp != NULL); ctx_tmp = both; both = secp256k1_context_preallocated_clone(both, prealloc_tmp); secp256k1_context_destroy(ctx_tmp); ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_preallocated_destroy(ctx_tmp); free(prealloc_tmp); diff --git a/src/trezor-crypto/base58.c b/src/trezor-crypto/base58.c index 0c3dd41bf..578838210 100644 --- a/src/trezor-crypto/base58.c +++ b/src/trezor-crypto/base58.c @@ -59,7 +59,7 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { const unsigned char *b58u = (const unsigned char *)b58; unsigned char *binu = bin; const size_t outisz = (binsz + sizeof(b58_almostmaxint_t) - 1); - b58_almostmaxint_t *outi = (b58_almostmaxint_t *)malloc(outisz); + b58_almostmaxint_t *outi = (b58_almostmaxint_t *)btc_malloc(outisz); b58_maxint_t t = 0; b58_almostmaxint_t c = 0; size_t i = 0, j = 0; @@ -160,7 +160,7 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { while (zcount < binsz && !bin[zcount]) ++zcount; const size_t size = (binsz - zcount) * 138 / 100 + 1; - uint8_t *buf = (uint8_t*)malloc(size); + uint8_t *buf = (uint8_t*)btc_malloc(size); memzero(buf, size); for (i = zcount, high = size - 1; i < binsz; ++i, high = j) { @@ -198,7 +198,7 @@ int base58_encode_check(const uint8_t *data, int datalen, if (datalen > 128) { return 0; } - uint8_t *buf = (uint8_t *)malloc(datalen + 32); + uint8_t *buf = (uint8_t *)btc_malloc(datalen + 32); memset(buf, 0, sizeof(buf)); uint8_t *hash = buf + datalen; memcpy(buf, data, datalen); @@ -215,7 +215,7 @@ int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, if (datalen > 128) { return 0; } - uint8_t *d = (uint8_t *)malloc(datalen + 4); + uint8_t *d = (uint8_t *)btc_malloc(datalen + 4); memset(d, 0, sizeof(d)); size_t res = datalen + 4; if (b58tobin(d, &res, str) != true) { From 0593dbc1c6f9e741654dd3cffbdbd952b3e763dd Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Fri, 28 Jan 2022 15:26:54 +0300 Subject: [PATCH 06/12] temp buf in b58enc is statically allocated (workaround) --- src/trezor-crypto/base58.c | 7 ++++--- src/trezor-crypto/memzero.c | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/trezor-crypto/base58.c b/src/trezor-crypto/base58.c index 578838210..b7f6e90c0 100644 --- a/src/trezor-crypto/base58.c +++ b/src/trezor-crypto/base58.c @@ -160,7 +160,8 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { while (zcount < binsz && !bin[zcount]) ++zcount; const size_t size = (binsz - zcount) * 138 / 100 + 1; - uint8_t *buf = (uint8_t*)btc_malloc(size); + /*uint8_t *buf = (uint8_t*)btc_malloc(size);*/ + uint8_t buf[4096]; memzero(buf, size); for (i = zcount, high = size - 1; i < binsz; ++i, high = j) { @@ -180,7 +181,7 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { if (*b58sz <= zcount + size - j) { *b58sz = zcount + size - j + 1; - free(buf); + /*free(buf);*/ return false; } @@ -189,7 +190,7 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { b58[i] = '\0'; *b58sz = i + 1; - free(buf); + /*free(buf);*/ return true; } diff --git a/src/trezor-crypto/memzero.c b/src/trezor-crypto/memzero.c index 1c5ea77a6..a34eaf18f 100644 --- a/src/trezor-crypto/memzero.c +++ b/src/trezor-crypto/memzero.c @@ -48,7 +48,8 @@ void memzero(void *const pnt, const size_t len) { #ifdef _WIN32 - SecureZeroMemory(pnt, len); + // SecureZeroMemory(pnt, len); + memset(pnt, 0, len); #elif defined(HAVE_MEMSET_S) memset_s(pnt, (rsize_t)len, 0, (rsize_t)len); #elif defined(HAVE_EXPLICIT_BZERO) From 3056e98523d82cb9feafcf7dd5735f36d574f329 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Fri, 28 Jan 2022 16:19:35 +0300 Subject: [PATCH 07/12] all static buffers in base58 --- src/trezor-crypto/base58.c | 43 +++++++++++++++++++++---------------- src/trezor-crypto/memzero.c | 3 +-- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/trezor-crypto/base58.c b/src/trezor-crypto/base58.c index b7f6e90c0..5d2f2331a 100644 --- a/src/trezor-crypto/base58.c +++ b/src/trezor-crypto/base58.c @@ -59,7 +59,12 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { const unsigned char *b58u = (const unsigned char *)b58; unsigned char *binu = bin; const size_t outisz = (binsz + sizeof(b58_almostmaxint_t) - 1); - b58_almostmaxint_t *outi = (b58_almostmaxint_t *)btc_malloc(outisz); + +#ifdef _MSC_VER + b58_almostmaxint_t outi[4096]; +#else + b58_almostmaxint_t outi[outisz]; +#endif b58_maxint_t t = 0; b58_almostmaxint_t c = 0; size_t i = 0, j = 0; @@ -70,7 +75,7 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { size_t b58sz = strlen(b58); - memzero(outi, sizeof(outi)); + memzero(outi, outisz); // Leading zeros, just count for (i = 0; i < b58sz && b58u[i] == '1'; ++i) ++zerocount; @@ -81,7 +86,6 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { return false; if (b58digits_map[b58u[i]] == -1) { // Invalid base58 digit - free(outi); return false; } c = (unsigned)b58digits_map[b58u[i]]; @@ -92,12 +96,10 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { } if (c) { // Output number too big (carry to the next int32) - free(outi); return false; } if (outi[0] & zeromask) { // Output number too big (last int32 filled too far) - free(outi); return false; } } @@ -116,8 +118,6 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { } } - free(outi); - // locate the most significant byte binu = bin; for (i = 0; i < binsz; ++i) { @@ -160,8 +160,11 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { while (zcount < binsz && !bin[zcount]) ++zcount; const size_t size = (binsz - zcount) * 138 / 100 + 1; - /*uint8_t *buf = (uint8_t*)btc_malloc(size);*/ +#ifdef _MSC_VER uint8_t buf[4096]; +#else + uint8_t buf[size]; +#endif memzero(buf, size); for (i = zcount, high = size - 1; i < binsz; ++i, high = j) { @@ -181,7 +184,6 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { if (*b58sz <= zcount + size - j) { *b58sz = zcount + size - j + 1; - /*free(buf);*/ return false; } @@ -190,7 +192,6 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { b58[i] = '\0'; *b58sz = i + 1; - /*free(buf);*/ return true; } @@ -199,15 +200,18 @@ int base58_encode_check(const uint8_t *data, int datalen, if (datalen > 128) { return 0; } - uint8_t *buf = (uint8_t *)btc_malloc(datalen + 32); - memset(buf, 0, sizeof(buf)); +#ifdef _MSC_VER + uint8_t buf[128 + 32]; +#else + uint8_t buf[datalen + 32]; +#endif + memset(buf, 0, datalen + 32); uint8_t *hash = buf + datalen; memcpy(buf, data, datalen); hasher_Raw(hasher_type, data, datalen, hash); size_t res = strsize; bool success = b58enc(str, &res, buf, datalen + 4); - memzero(buf, sizeof(buf)); - free(buf); + memzero(buf, datalen + 32); return success ? res : 0; } @@ -216,20 +220,21 @@ int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, if (datalen > 128) { return 0; } - uint8_t *d = (uint8_t *)btc_malloc(datalen + 4); - memset(d, 0, sizeof(d)); +#ifdef _MSC_VER + uint8_t d[128 + 4]; +#else + uint8_t d[datalen + 4]; +#endif + memset(d, 0, datalen + 4); size_t res = datalen + 4; if (b58tobin(d, &res, str) != true) { - free(d); return 0; } uint8_t *nd = d + datalen + 4 - res; if (b58check(nd, res, hasher_type, str) < 0) { - free(d); return 0; } memcpy(data, nd, res - 4); - free(d); return res - 4; } diff --git a/src/trezor-crypto/memzero.c b/src/trezor-crypto/memzero.c index a34eaf18f..1c5ea77a6 100644 --- a/src/trezor-crypto/memzero.c +++ b/src/trezor-crypto/memzero.c @@ -48,8 +48,7 @@ void memzero(void *const pnt, const size_t len) { #ifdef _WIN32 - // SecureZeroMemory(pnt, len); - memset(pnt, 0, len); + SecureZeroMemory(pnt, len); #elif defined(HAVE_MEMSET_S) memset_s(pnt, (rsize_t)len, 0, (rsize_t)len); #elif defined(HAVE_EXPLICIT_BZERO) From 3c7aba591273ffc66df9c5b4d576f3532786e742 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Fri, 28 Jan 2022 17:19:48 +0300 Subject: [PATCH 08/12] memzero size fix --- src/trezor-crypto/base58.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trezor-crypto/base58.c b/src/trezor-crypto/base58.c index 5d2f2331a..03f9444fe 100644 --- a/src/trezor-crypto/base58.c +++ b/src/trezor-crypto/base58.c @@ -75,7 +75,7 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { size_t b58sz = strlen(b58); - memzero(outi, outisz); + memzero(outi, outisz * sizeof(b58_almostmaxint_t)); // Leading zeros, just count for (i = 0; i < b58sz && b58u[i] == '1'; ++i) ++zerocount; From 5566b4b68c3bd340e8d03ae2dfb6249b48cb5f37 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Fri, 28 Jan 2022 19:27:23 +0300 Subject: [PATCH 09/12] possible fix for invalid outisz in b58tobin --- src/trezor-crypto/base58.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/trezor-crypto/base58.c b/src/trezor-crypto/base58.c index 03f9444fe..e80a85763 100644 --- a/src/trezor-crypto/base58.c +++ b/src/trezor-crypto/base58.c @@ -58,10 +58,13 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58) { const unsigned char *b58u = (const unsigned char *)b58; unsigned char *binu = bin; - const size_t outisz = (binsz + sizeof(b58_almostmaxint_t) - 1); + const size_t outisz = (binsz + sizeof(b58_almostmaxint_t) - 1) / sizeof(b58_almostmaxint_t); #ifdef _MSC_VER - b58_almostmaxint_t outi[4096]; + if (outisz > 1024) { // avoid buffer overflow + return false; + } + b58_almostmaxint_t outi[1024]; #else b58_almostmaxint_t outi[outisz]; #endif @@ -161,6 +164,9 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { const size_t size = (binsz - zcount) * 138 / 100 + 1; #ifdef _MSC_VER + if (size > 4096) { // avoid buffer overflow + return false; + } uint8_t buf[4096]; #else uint8_t buf[size]; From 792834f4f09c6116cceff43bac165d0f3294f398 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Fri, 28 Jan 2022 20:15:25 +0300 Subject: [PATCH 10/12] fix tests --- src/utils.c | 2 +- test/block_tests.c | 2 +- test/eckey_tests.c | 2 +- test/tx_tests.c | 13 ++++++------- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/utils.c b/src/utils.c index 1ee79dacb..96a5b553f 100644 --- a/src/utils.c +++ b/src/utils.c @@ -175,7 +175,7 @@ void utils_reverse_hex(char* h, int len) { char* copy = btc_malloc(len); int i; - strncpy(copy, h, len); + memcpy(copy, h, len); for (i = 0; i < len; i += 2) { h[i] = copy[len - i - 2]; h[i + 1] = copy[len - i - 1]; diff --git a/test/block_tests.c b/test/block_tests.c index 7d43ffc6e..2b04f1e25 100644 --- a/test/block_tests.c +++ b/test/block_tests.c @@ -135,7 +135,7 @@ void test_block_header() uint256 checkhash; btc_block_header_hash(&bheader, (uint8_t *)&checkhash); - char hashhex[sizeof(checkhash)*2]; + char hashhex[sizeof(checkhash) * 2 + 1]; utils_bin_to_hex(checkhash, sizeof(checkhash), hashhex); utils_reverse_hex(hashhex, strlen(hashhex)); u_assert_str_eq(blockheader_hash_h427928, hashhex); diff --git a/test/eckey_tests.c b/test/eckey_tests.c index b723132a1..0119fcc93 100644 --- a/test/eckey_tests.c +++ b/test/eckey_tests.c @@ -78,7 +78,7 @@ void test_eckey() size_t size = 66; - char str[66]; + char str[67]; int r = btc_pubkey_get_hex(&pubkey, str, &size); u_assert_int_eq(r, true); u_assert_int_eq(size, 66); diff --git a/test/tx_tests.c b/test/tx_tests.c index 352bad5c7..dda627505 100644 --- a/test/tx_tests.c +++ b/test/tx_tests.c @@ -932,7 +932,7 @@ void test_tx_sighash() btc_tx* tx = btc_tx_new(); btc_tx_deserialize(tx_data, outlen, tx, NULL, true); - uint8_t* script_data = malloc(strlen(test->script) / 2); + uint8_t script_data[512]; utils_hex_to_bin(test->script, script_data, strlen(test->script), &outlen); cstring* script = cstr_new_buf(script_data, outlen); uint256 sighash; @@ -949,12 +949,11 @@ void test_tx_sighash() cstr_free(script, true); - char hexbuf[sizeof(sighash)*2]; + char hexbuf[sizeof(sighash)*2 + 1]; utils_bin_to_hex(sighash, sizeof(sighash), hexbuf); - utils_reverse_hex(hexbuf, sizeof(hexbuf)); + utils_reverse_hex(hexbuf, strlen(hexbuf)); assert(strcmp(hexbuf, test->hashhex) == 0); - free(script_data); btc_tx_free(tx); } } @@ -1078,9 +1077,9 @@ void test_script_parse() uint256 txhash; btc_tx_hash(tx, txhash); - char txhashhex[sizeof(txhash)*2]; + char txhashhex[sizeof(txhash)*2 + 1]; utils_bin_to_hex((unsigned char*)txhash, sizeof(txhash), txhashhex); - utils_reverse_hex(txhashhex, sizeof(txhashhex)); + utils_reverse_hex(txhashhex, strlen(txhashhex)); u_assert_str_eq(txhashhex, "41a86af25423391b1d9d78df1143e3a237f20db27511d8b72e25f2dec7a81d80"); @@ -1135,7 +1134,7 @@ void test_script_parse() uint256 sig_hash; btc_hash(node.private_key, BTC_ECKEY_PKEY_LENGTH, rev_code); - uint8_t sigdata[38] = {0x42, 0x49, 0x50, 0x00, 0x00, 0x00, 0x00 }; + uint8_t sigdata[40] = {0x42, 0x49, 0x50, 0x00, 0x00, 0x00, 0x00 }; btc_hash(rev_code, BTC_HASH_LENGTH, &sigdata[7]); btc_hash(sigdata, sizeof(sigdata), sig_hash); From 5f54074a02d2f53869524f9a09c796bae74d7be4 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Mon, 29 May 2023 23:29:46 +0300 Subject: [PATCH 11/12] BIP39 support --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f68b24013..e4cb2dadb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,6 +101,7 @@ INSTALL(FILES INSTALL(FILES src/trezor-crypto/base58.h + src/trezor-crypto/bip39.h src/trezor-crypto/blake2_common.h src/trezor-crypto/blake2b.h src/trezor-crypto/blake256.h @@ -110,6 +111,8 @@ INSTALL(FILES src/trezor-crypto/hmac.h src/trezor-crypto/memzero.h src/trezor-crypto/options.h + src/trezor-crypto/pbkdf2.h + src/trezor-crypto/rand.h src/trezor-crypto/ripemd160.h src/trezor-crypto/segwit_addr.h src/trezor-crypto/sha2.h @@ -141,12 +144,16 @@ TARGET_SOURCES(${LIBBTC_NAME} PRIVATE TARGET_SOURCES(${LIBBTC_NAME} PRIVATE src/trezor-crypto/base58.c + src/trezor-crypto/bip39.c + src/trezor-crypto/bip39_english.h src/trezor-crypto/blake2b.c src/trezor-crypto/blake256.c src/trezor-crypto/groestl.c src/trezor-crypto/hasher.c src/trezor-crypto/hmac.c src/trezor-crypto/memzero.c + src/trezor-crypto/pbkdf2.c + src/trezor-crypto/rand.c src/trezor-crypto/ripemd160.c src/trezor-crypto/segwit_addr.c src/trezor-crypto/sha2.c From 9715824cd75d72e2fc5cdf74f8b815e3dbb89ea3 Mon Sep 17 00:00:00 2001 From: Sergey Chernikov Date: Mon, 29 May 2023 23:36:37 +0300 Subject: [PATCH 12/12] rand.c build fixes on Windows --- src/trezor-crypto/rand.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/trezor-crypto/rand.c b/src/trezor-crypto/rand.c index ea95d143b..b7ddb5ea5 100644 --- a/src/trezor-crypto/rand.c +++ b/src/trezor-crypto/rand.c @@ -54,7 +54,11 @@ uint32_t random32(void) { // The following code is platform independent // -void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len) { +void +#ifndef WIN32 +__attribute__((weak)) +#endif +random_buffer(uint8_t *buf, size_t len) { uint32_t r = 0; for (size_t i = 0; i < len; i++) { if (i % 4 == 0) {