From 0e42b35c0b92b9b28482f6900be31e456ebd515b Mon Sep 17 00:00:00 2001
From: "pavel.uhanov" <pavel.uhanov@demlabs.net>
Date: Wed, 19 Feb 2025 06:36:36 +0000
Subject: [PATCH] backport-13637

---
 crypto/include/dap_cert.h                     |  10 +-
 crypto/include/dap_enc_ecdsa.h                |   1 +
 crypto/include/dap_enc_key.h                  |  10 ++
 crypto/include/dap_pkey.h                     |   9 +-
 crypto/include/dap_sign.h                     |  21 +++-
 crypto/src/dap_cert.c                         |  34 ++++--
 crypto/src/dap_enc_ecdsa.c                    |  11 +-
 crypto/src/dap_enc_key.c                      |  21 +++-
 crypto/src/dap_enc_multisign.c                |   2 +-
 crypto/src/dap_pkey.c                         |  99 ++++++++++++++-
 crypto/src/dap_sign.c                         | 113 +++++++++++++-----
 crypto/test/crypto/dap_enc_benchmark_test.c   |  51 +++++++-
 crypto/test/crypto/dap_enc_multithread_test.c |   4 +-
 crypto/test/crypto/dap_enc_test.c             |   2 +-
 crypto/test/crypto/main.c                     |   4 +-
 global-db/dap_global_db_pkt.c                 |   2 +-
 net/client/dap_client_pvt.c                   |   2 +-
 net/server/enc_server/dap_enc_http.c          |   2 +-
 .../rpc_core/src/dap_json_rpc_request.c       |   2 +-
 19 files changed, 330 insertions(+), 70 deletions(-)

diff --git a/crypto/include/dap_cert.h b/crypto/include/dap_cert.h
index e2d12de38..3f6dd5f9f 100755
--- a/crypto/include/dap_cert.h
+++ b/crypto/include/dap_cert.h
@@ -89,13 +89,18 @@ int dap_cert_get_pkey_hash(dap_cert_t *a_cert, dap_hash_fast_t *a_out_hash);
 dap_cert_t *dap_cert_find_by_name(const char *a_cert_name);
 dap_list_t *dap_cert_get_all_mem();
 
-dap_sign_t *dap_cert_sign(dap_cert_t *a_cert, const void *a_data, size_t a_data_size, size_t a_output_size_wished);
+dap_sign_t *dap_cert_sign_with_hash_type(dap_cert_t *a_cert, const void *a_data, size_t a_data_size, uint32_t a_hash_type);
+DAP_STATIC_INLINE dap_sign_t *dap_cert_sign(dap_cert_t *a_cert, const void *a_data, size_t a_data_size)
+{
+    return dap_cert_sign_with_hash_type(a_cert, a_data, a_data_size, DAP_SIGN_HASH_TYPE_DEFAULT);
+}
+
 // Sign raw data, without hashing
 int dap_cert_sign_output(dap_cert_t *a_cert, const void *a_data, size_t a_data_size, void *a_output, size_t *a_output_size);
 
 int dap_cert_compare_with_sign (dap_cert_t *a_cert,const dap_sign_t *a_sign);
 
-size_t dap_cert_sign_output_size(dap_cert_t *a_cert, size_t a_size_wished);
+size_t dap_cert_sign_output_size(dap_cert_t *a_cert);
 
 int dap_cert_add_cert_sign(dap_cert_t *a_cert, dap_cert_t *a_cert_signer);
 
@@ -125,6 +130,7 @@ time_t dap_cert_get_meta_period(dap_cert_t *a_cert, const char *a_field);
 dap_sign_t *dap_cert_get_meta_sign(dap_cert_t *a_cert, const char *a_field);
 void *dap_cert_get_meta_custom(dap_cert_t *a_cert, const char *a_field, size_t *a_meta_size_out);
 dap_enc_key_t *dap_cert_get_keys_from_certs(dap_cert_t **a_certs, size_t a_count, size_t a_key_start_index);
+char *dap_cert_get_pkey_str(dap_cert_t *a_cert, const char *a_str_type);
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/include/dap_enc_ecdsa.h b/crypto/include/dap_enc_ecdsa.h
index f1f926f6c..438d67be1 100755
--- a/crypto/include/dap_enc_ecdsa.h
+++ b/crypto/include/dap_enc_ecdsa.h
@@ -25,6 +25,7 @@ uint8_t *dap_enc_sig_ecdsa_write_signature(const void* a_sign, size_t *a_sign_ou
 uint8_t *dap_enc_sig_ecdsa_write_public_key(const void *a_public_key, size_t *a_buflen_out);
 void* dap_enc_sig_ecdsa_read_signature(const uint8_t *a_buf, size_t a_buflen);
 void* dap_enc_sig_ecdsa_read_public_key(const uint8_t *a_buf, size_t a_buflen);
+bool dap_enc_sig_ecdsa_hash_fast(const unsigned char *a_data, size_t a_data_size, dap_hash_fast_t *a_out);
 
 DAP_STATIC_INLINE uint64_t dap_enc_sig_ecdsa_ser_key_size(UNUSED_ARG const void *a_in) {
     return ECDSA_PRIVATE_KEY_SIZE;
diff --git a/crypto/include/dap_enc_key.h b/crypto/include/dap_enc_key.h
index 4070743b7..a24703c1b 100755
--- a/crypto/include/dap_enc_key.h
+++ b/crypto/include/dap_enc_key.h
@@ -334,6 +334,16 @@ dap_enc_key_t *dap_enc_merge_keys_to_multisign_key(dap_enc_key_t **a_keys, size_
 
 int dap_enc_key_get_pkey_hash(dap_enc_key_t *a_key, dap_hash_fast_t *a_hash_out);
 
+/**
+ * @brief check if this key type use insign hashing
+ * @param a_type checked enc_key type
+ * @return true if this enc_key type hashing signing data, false if not
+ */
+DAP_STATIC_INLINE bool dap_enc_key_is_insign_hashing(dap_enc_key_type_t a_type)
+{
+    return a_type == DAP_ENC_KEY_TYPE_SIG_ECDSA;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/include/dap_pkey.h b/crypto/include/dap_pkey.h
index f020031a6..3b66a2161 100755
--- a/crypto/include/dap_pkey.h
+++ b/crypto/include/dap_pkey.h
@@ -173,7 +173,7 @@ typedef struct dap_pkey {
     uint8_t pkey[];             // Raw pkey data
 } DAP_PACKED dap_pkey_t;
 
-DAP_STATIC_INLINE size_t dap_pkey_get_size(const dap_pkey_t *a_pkey) { return sizeof(dap_pkey_t) + a_pkey->header.size; }
+DAP_STATIC_INLINE size_t dap_pkey_get_size(const dap_pkey_t *a_pkey) { return a_pkey ? sizeof(dap_pkey_t) + a_pkey->header.size : 0; }
 
 dap_pkey_t *dap_pkey_from_enc_key(dap_enc_key_t *a_key);
 
@@ -194,3 +194,10 @@ DAP_STATIC_INLINE bool dap_pkey_compare(dap_pkey_t *a_pkey1, dap_pkey_t *a_pkey2
 }
 
 dap_pkey_t *dap_pkey_get_from_sign(dap_sign_t *a_sign);
+dap_pkey_t *dap_pkey_get_from_hex_str(const char *a_hex_str);
+dap_pkey_t *dap_pkey_get_from_base58_str(const char *a_base58_str);
+dap_pkey_t *dap_pkey_get_from_str( const char *a_pkey_str);
+
+char *dap_pkey_to_hex_str(const dap_pkey_t *a_pkey);
+char *dap_pkey_to_base58_str(const dap_pkey_t *a_pkey);
+char *dap_pkey_to_str(const dap_pkey_t *a_pkey, const char *a_str_type);
diff --git a/crypto/include/dap_sign.h b/crypto/include/dap_sign.h
index 325611ee8..36142a9d0 100755
--- a/crypto/include/dap_sign.h
+++ b/crypto/include/dap_sign.h
@@ -55,6 +55,13 @@ typedef uint32_t dap_sign_type_enum_t;
 #define DAP_SIGN_HASH_TYPE_NONE      0x00
 #define DAP_SIGN_HASH_TYPE_SHA3      0x01
 #define DAP_SIGN_HASH_TYPE_STREEBOG  0x02
+#define DAP_SIGN_HASH_TYPE_SIGN      0x0e
+#define DAP_SIGN_HASH_TYPE_DEFAULT   0x0f  // not transferred in network, first try use sign hash, if false, use s_sign_hash_type_default
+
+#define DAP_SIGN_PKEY_HASHING_FLAG ((uint32_t)1 << 7)
+#define DAP_SIGN_ADD_PKEY_HASHING_FLAG(a) ((a) | DAP_SIGN_PKEY_HASHING_FLAG)
+#define DAP_SIGN_REMOVE_PKEY_HASHING_FLAG(a) ((a) & ~DAP_SIGN_PKEY_HASHING_FLAG)
+#define DAP_SIGN_GET_PKEY_HASHING_FLAG(a) ((a) & DAP_SIGN_PKEY_HASHING_FLAG)
 
 typedef union dap_sign_type {
     dap_sign_type_enum_t type;
@@ -78,7 +85,8 @@ typedef struct dap_sign
     dap_sign_hdr_t header; /// Only header's hash is used for verification
     uint8_t pkey_n_sign[]; /// @param sig @brief raw signature data
 } DAP_ALIGN_PACKED dap_sign_t;
-
+typedef struct dap_pkey dap_pkey_t;
+typedef dap_pkey_t *(*dap_sign_callback_t)(const uint8_t *);
 
 #ifdef __cplusplus
 extern "C" {
@@ -126,11 +134,16 @@ static inline int dap_sign_verify_all(dap_sign_t * a_sign, const size_t a_sign_s
 const char *dap_sign_get_str_recommended_types();
 
 // Create sign of data hash with key provided algorythm of signing and hashing (independently)
-dap_sign_t * dap_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size, size_t a_output_wish_size );
+dap_sign_t * dap_sign_create_with_hash_type(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size, uint32_t a_hash_type);
+
+DAP_STATIC_INLINE dap_sign_t *dap_sign_create(dap_enc_key_t *a_key, const void *a_data, const size_t a_data_size)
+{
+    return dap_sign_create_with_hash_type(a_key, a_data, a_data_size, DAP_SIGN_HASH_TYPE_DEFAULT);
+}
 //Create sign on raw data without hashing. Singing algorythm is key provided
 int dap_sign_create_output(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size, void * a_output, size_t *a_output_size);
 
-size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t * a_key,size_t a_output_wish_size );
+size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t *a_key);
 //int dap_sign_create_output(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size
 //                                 , void * a_output, size_t a_output_size );
 
@@ -151,6 +164,8 @@ dap_sign_t **dap_sign_get_unique_signs(void *a_data, size_t a_data_size, size_t
 void dap_sign_get_information(dap_sign_t *a_sign, dap_string_t *a_str_out, const char *a_hash_out_type);
 void dap_sign_get_information_json(json_object* a_json_arr_reply, dap_sign_t* a_sign, json_object *a_json_out, const char *a_hash_out_type);
 
+int dap_sign_set_pkey_by_hash_callback (dap_sign_callback_t a_callback);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/crypto/src/dap_cert.c b/crypto/src/dap_cert.c
index 379fbf566..59864df5b 100755
--- a/crypto/src/dap_cert.c
+++ b/crypto/src/dap_cert.c
@@ -128,7 +128,7 @@ size_t dap_cert_parse_str_list(const char * a_certs_str, dap_cert_t *** a_certs,
         l_certs[l_certs_pos] = dap_cert_find_by_name(l_cert_str);
         // if certificate is found
         if(l_certs[l_certs_pos]) {
-            l_sign_total_size += dap_cert_sign_output_size(l_certs[l_certs_pos],0);
+            l_sign_total_size += dap_cert_sign_output_size(l_certs[l_certs_pos]);
             l_certs_pos++;
         } else {
             log_it(L_WARNING,"Can't load cert %s",l_cert_str);
@@ -149,12 +149,11 @@ size_t dap_cert_parse_str_list(const char * a_certs_str, dap_cert_t *** a_certs,
  * @brief
  * simply call dap_sign_create_output_unserialized_calc_size( a_cert->enc_key,a_size_wished)
  * @param a_cert dap_cert_t * certificate object
- * @param a_size_wished wished data size (don't used in current implementation)
  * @return size_t
  */
-size_t dap_cert_sign_output_size(dap_cert_t * a_cert, size_t a_size_wished)
+size_t dap_cert_sign_output_size(dap_cert_t * a_cert)
 {
-    return dap_sign_create_output_unserialized_calc_size( a_cert->enc_key,a_size_wished);
+    return dap_sign_create_output_unserialized_calc_size( a_cert->enc_key);
 }
 
 /**
@@ -173,19 +172,18 @@ int dap_cert_sign_output(dap_cert_t * a_cert, const void * a_data, size_t a_data
 }
 
 /**
- * @brief
- * sign data by encryption key from certificate
+ * @brief sign data by encryption key from certificate with choosed hash type
  * @param a_cert dap_cert_t * certificate object
  * @param a_data data for signing
  * @param a_data_size data size
- * @param a_output_size_wished wished data size (don't used in current implementation)
+ * @param a_hash_type data and pkey hash type
  * @return dap_sign_t*
  */
-dap_sign_t *dap_cert_sign(dap_cert_t *a_cert, const void *a_data, size_t a_data_size, size_t a_output_size_wished)
+dap_sign_t *dap_cert_sign_with_hash_type(dap_cert_t *a_cert, const void *a_data, size_t a_data_size, uint32_t a_hash_type)
 {
     dap_return_val_if_fail(a_cert && a_cert->enc_key && a_cert->enc_key->priv_key_data &&
                            a_cert->enc_key->priv_key_data_size && a_data && a_data_size, NULL);
-    dap_sign_t *l_ret = dap_sign_create(a_cert->enc_key, a_data, a_data_size, a_output_size_wished);
+    dap_sign_t *l_ret = dap_sign_create_with_hash_type(a_cert->enc_key, a_data, a_data_size, a_hash_type);
 
     if (l_ret)
         log_it(L_INFO, "Sign sizes: %d %d", l_ret->header.sign_size, l_ret->header.sign_pkey_size);
@@ -202,7 +200,7 @@ dap_sign_t *dap_cert_sign(dap_cert_t *a_cert, const void *a_data, size_t a_data_
  * @param a_cert_signer dap_cert_t certificate object, which signs a_cert
  * @return int
  */
-int dap_cert_add_cert_sign(dap_cert_t * a_cert, dap_cert_t * a_cert_signer)
+int dap_cert_add_cert_sign(dap_cert_t *a_cert, dap_cert_t *a_cert_signer)
 {
     if (a_cert->enc_key->pub_key_data_size && a_cert->enc_key->pub_key_data) {
         dap_sign_item_t * l_sign_item = DAP_NEW_Z(dap_sign_item_t);
@@ -210,7 +208,7 @@ int dap_cert_add_cert_sign(dap_cert_t * a_cert, dap_cert_t * a_cert_signer)
             log_it(L_CRITICAL, "%s", c_error_memory_alloc);
             return -1;
         }
-        l_sign_item->sign = dap_cert_sign (a_cert_signer,a_cert->enc_key->pub_key_data,a_cert->enc_key->pub_key_data_size,0);
+        l_sign_item->sign = dap_cert_sign(a_cert_signer,a_cert->enc_key->pub_key_data,a_cert->enc_key->pub_key_data_size);
         DL_APPEND ( PVT(a_cert)->signs, l_sign_item );
         return 0;
     } else {
@@ -924,3 +922,17 @@ DAP_INLINE const char *dap_cert_get_str_recommended_sign(){
 #endif
     ;
 }
+
+/**
+ * @brief get pkey_full str from cert
+ * @param a_cert pointer to certificate
+ * @param a_str_type str type, hex or base58
+ * @return pointer to pkey_full str
+ */
+char *dap_cert_get_pkey_str(dap_cert_t *a_cert, const char *a_str_type)
+{
+    dap_pkey_t *l_pkey = dap_cert_to_pkey(a_cert);
+    char *l_ret = dap_pkey_to_str(l_pkey, a_str_type);
+    DAP_DELETE(l_pkey);
+    return l_ret;
+}
diff --git a/crypto/src/dap_enc_ecdsa.c b/crypto/src/dap_enc_ecdsa.c
index a6ebc9504..3122b5a7b 100644
--- a/crypto/src/dap_enc_ecdsa.c
+++ b/crypto/src/dap_enc_ecdsa.c
@@ -46,12 +46,13 @@ static ecdsa_context_t *s_context_create()
     return s_context;
 }
 
-DAP_STATIC_INLINE void s_sha256_hashing(const unsigned char *a_data, size_t a_data_size, unsigned char *a_out)
+bool dap_enc_sig_ecdsa_hash_fast(const unsigned char *a_data, size_t a_data_size, dap_hash_fast_t *a_out)
 {
     secp256k1_sha256 l_hasher;
     secp256k1_sha256_initialize(&l_hasher);
     secp256k1_sha256_write(&l_hasher, a_data, a_data_size);
-    secp256k1_sha256_finalize(&l_hasher, a_out);
+    secp256k1_sha256_finalize(&l_hasher, (unsigned char *)a_out);
+    return true;
 }
 
 void dap_enc_sig_ecdsa_key_new(dap_enc_key_t *a_key) {
@@ -88,7 +89,7 @@ void dap_enc_sig_ecdsa_key_new_generate(dap_enc_key_t *a_key, UNUSED_ARG const v
     }
 // keypair generate
     if(a_seed && a_seed_size > 0) {
-        s_sha256_hashing((const unsigned char *)a_seed, a_seed_size, (unsigned char *)a_key->priv_key_data);
+        dap_enc_sig_ecdsa_hash_fast((const unsigned char *)a_seed, a_seed_size, (unsigned char *)a_key->priv_key_data);
         if (!secp256k1_ec_seckey_verify(l_ctx, (const unsigned char*)a_key->priv_key_data)) {
             log_it(L_ERROR, "Error verify ECDSA private key");
             DAP_DEL_Z(a_key->priv_key_data);
@@ -124,7 +125,7 @@ int dap_enc_sig_ecdsa_get_sign(struct dap_enc_key *l_key, const void *a_msg, con
     dap_return_val_if_pass_err(l_key->priv_key_data_size != sizeof(ecdsa_private_key_t), -3, "Invalid ecdsa private key size");
 // msg hashing
     byte_t l_msghash[32] = { '\0' };
-    s_sha256_hashing(a_msg, a_msg_size, l_msghash);
+    dap_enc_sig_ecdsa_hash_fast(a_msg, a_msg_size, l_msghash);
 // context create
     int l_ret = 0;
     ecdsa_context_t *l_ctx = s_context_create();
@@ -143,7 +144,7 @@ int dap_enc_sig_ecdsa_verify_sign(struct dap_enc_key *l_key, const void *a_msg,
     dap_return_val_if_pass_err(l_key->pub_key_data_size != sizeof(ecdsa_public_key_t), -3, "Invalid ecdsa public key size");
 // msg hashing
     byte_t l_msghash[32] = { '\0' };
-    s_sha256_hashing(a_msg, a_msg_size, l_msghash);
+    dap_enc_sig_ecdsa_hash_fast(a_msg, a_msg_size, l_msghash);
 // context create
     int l_ret = 0;
     ecdsa_context_t *l_ctx = s_context_create();
diff --git a/crypto/src/dap_enc_key.c b/crypto/src/dap_enc_key.c
index 68e230851..197db5dc7 100755
--- a/crypto/src/dap_enc_key.c
+++ b/crypto/src/dap_enc_key.c
@@ -1215,11 +1215,24 @@ dap_enc_key_t *dap_enc_merge_keys_to_multisign_key(dap_enc_key_t **a_keys, size_
 int dap_enc_key_get_pkey_hash(dap_enc_key_t *a_key, dap_hash_fast_t *a_hash_out)
 {
     dap_return_val_if_fail(a_key && a_key->pub_key_data && a_key->pub_key_data_size && a_hash_out, -1);
-    size_t l_pub_key_size;
+    size_t l_pub_key_size = 0;
+    int l_ret = -2;
     uint8_t *l_pub_key = dap_enc_key_serialize_pub_key(a_key, &l_pub_key_size);
     if (!l_pub_key)
-        return -2;
-    int ret = !dap_hash_fast(l_pub_key, l_pub_key_size, a_hash_out);
+        return l_ret;
+    switch (a_key->type) {
+        case DAP_ENC_KEY_TYPE_SIG_ECDSA:
+#ifdef DAP_ECDSA
+            l_ret = !dap_enc_sig_ecdsa_hash_fast((const unsigned char *)l_pub_key, l_pub_key_size, a_hash_out);
+            break;
+#else
+            log_it(L_ERROR, "Using DAP_ENC_KEY_TYPE_SIG_ECDSA hash without DAP_ECDSA defining");
+            break;
+#endif
+        default:
+            l_ret = !dap_hash_fast(l_pub_key, l_pub_key_size, a_hash_out);
+            break;
+    }
     DAP_DELETE(l_pub_key);
-    return ret;
+    return l_ret;
 }
diff --git a/crypto/src/dap_enc_multisign.c b/crypto/src/dap_enc_multisign.c
index e7914b477..adc99542e 100755
--- a/crypto/src/dap_enc_multisign.c
+++ b/crypto/src/dap_enc_multisign.c
@@ -336,7 +336,7 @@ int dap_enc_sig_multisign_get_sign(dap_enc_key_t *a_key, const void *a_msg_in, c
             return -4;
         }
         int l_num = l_sign->key_seq[i];
-        dap_sign_t *l_dap_sign_step = dap_sign_create(l_params->keys[l_num], &l_data_hash, sizeof(dap_chain_hash_fast_t), 0);
+        dap_sign_t *l_dap_sign_step = dap_sign_create(l_params->keys[l_num], &l_data_hash, sizeof(dap_chain_hash_fast_t));
         if (!l_dap_sign_step) {
             log_it (L_ERROR, "Can't create multi-signature step signature");
             DAP_DEL_MULTY(l_sign->key_hashes, l_sign->key_seq, l_sign->meta, l_sign->sign_data);
diff --git a/crypto/src/dap_pkey.c b/crypto/src/dap_pkey.c
index 1b61b0433..bc73a134c 100755
--- a/crypto/src/dap_pkey.c
+++ b/crypto/src/dap_pkey.c
@@ -24,9 +24,10 @@
 #include <string.h>
 #include "dap_common.h"
 #include "dap_pkey.h"
+#include "dap_enc_base58.h"
+#include "dap_strfuncs.h"
 
 #define LOG_TAG "chain_key"
-//static dap_pkey_t m_dap_pkey_null={0}; // For sizeof nothing more
 
 /**
  * @brief 
@@ -65,3 +66,99 @@ dap_pkey_t *dap_pkey_get_from_sign(dap_sign_t *a_sign)
     memcpy(l_pkey->pkey, a_sign->pkey_n_sign, l_pkey->header.size);
     return l_pkey;
 }
+
+/**
+ * @brief dap_pkey_get_hex_str
+ * @param a_hex_str
+ * @return pass - pointer to dap_pkey_t, error - NULL
+ */
+dap_pkey_t *dap_pkey_get_from_hex_str(const char *a_hex_str)
+{
+    dap_return_val_if_pass(!a_hex_str, NULL);
+    int l_str_len = dap_strlen(a_hex_str) - 2;
+    // from hex to binary 
+    if (l_str_len < 1 || dap_strncmp(a_hex_str, "0x", 2) || dap_is_hex_string(a_hex_str + 2, l_str_len)) {
+        return NULL;
+    }
+    dap_pkey_t *l_ret = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_pkey_t, l_str_len / 2 + 1, NULL);
+    size_t l_out_size = dap_hex2bin((uint8_t *)l_ret, a_hex_str + 2, l_str_len);
+    if (l_ret->header.type.type == DAP_PKEY_TYPE_NULL || l_out_size / 2 != dap_pkey_get_size(l_ret)) {
+        log_it(L_ERROR, "Error in read pkey from hex string");
+        DAP_DEL_Z(l_ret);
+    }
+    return l_ret;
+}
+
+/**
+ * @brief dap_pkey_get_base58_str
+ * @param a_base58_str
+ * @return pass - pointer to dap_pkey_t, error - NULL
+ */
+dap_pkey_t *dap_pkey_get_from_base58_str(const char *a_base58_str)
+{
+    dap_return_val_if_pass(!a_base58_str, NULL);
+    size_t l_str_len = dap_strlen(a_base58_str);
+    // from base58 to binary 
+    dap_pkey_t *l_ret = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_pkey_t, DAP_ENC_BASE58_DECODE_SIZE(l_str_len), NULL);
+    size_t l_out_size = dap_enc_base58_decode(a_base58_str, l_ret);
+    if (l_ret->header.type.type == DAP_PKEY_TYPE_NULL || l_out_size != dap_pkey_get_size(l_ret)) {
+        log_it(L_ERROR, "Error in read pkey from base58 string");
+        DAP_DEL_Z(l_ret);
+    }
+    return l_ret;
+}
+
+
+/**
+ * @brief dap_pkey_get_from_str
+ * @param a_pkey_str
+ * @return pass - pointer to dap_pkey_t, error - NULL
+ */
+DAP_INLINE dap_pkey_t *dap_pkey_get_from_str(const char *a_pkey_str)
+{
+    dap_pkey_t *l_ret = dap_pkey_get_from_hex_str(a_pkey_str);
+    return  l_ret ? l_ret : dap_pkey_get_from_base58_str(a_pkey_str);
+}
+
+/**
+ * @brief dap_pkey_get_hex_str
+ * @param a_pkey
+ * @return pass - pointer to hex str, error - NULL
+ */
+char *dap_pkey_to_hex_str(const dap_pkey_t *a_pkey)
+{
+    size_t l_pkey_size = dap_pkey_get_size(a_pkey);
+    dap_return_val_if_pass(!l_pkey_size, NULL);
+    // from binary to hex 
+    char *l_ret = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(char, (l_pkey_size * 2) + 3, NULL);
+    l_ret[0] = '0';
+    l_ret[1] = 'x';
+    dap_bin2hex(l_ret + 2, a_pkey, l_pkey_size);
+    return l_ret;
+}
+
+/**
+ * @brief dap_pkey_get_base58_str
+ * @param a_pkey
+ * @return pass - pointer to base58 str, error - NULL
+ */
+char *dap_pkey_to_base58_str(const dap_pkey_t *a_pkey)
+{
+    size_t l_pkey_size = dap_pkey_get_size(a_pkey);
+    dap_return_val_if_pass(!l_pkey_size, NULL);
+    // from binary to hex 
+    char *l_ret = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(char, DAP_ENC_BASE58_ENCODE_SIZE(l_pkey_size), NULL);
+    dap_enc_base58_encode(a_pkey, l_pkey_size, l_ret);
+    return l_ret;
+}
+
+/**
+ * @brief dap_pkey_get_base58_str
+ * @param a_pkey
+ * @param a_str_type - hex or base58
+ * @return pass - pointer to str, error - NULL
+ */
+DAP_INLINE char *dap_pkey_to_str(const dap_pkey_t *a_pkey, const char *a_str_type)
+{
+    return  dap_strcmp(a_str_type, "hex") ? dap_pkey_to_base58_str(a_pkey) : dap_pkey_to_hex_str(a_pkey);
+}
\ No newline at end of file
diff --git a/crypto/src/dap_sign.c b/crypto/src/dap_sign.c
index e3fb32c0f..33b95feca 100755
--- a/crypto/src/dap_sign.c
+++ b/crypto/src/dap_sign.c
@@ -32,11 +32,13 @@
 #include "dap_enc_base58.h"
 #include "dap_json_rpc_errors.h"
 #include "dap_config.h"
+#include "dap_pkey.h"
 
 #define LOG_TAG "dap_sign"
 
 static uint8_t s_sign_hash_type_default = DAP_SIGN_HASH_TYPE_SHA3;
 static bool s_dap_sign_debug_more = false;
+static dap_sign_callback_t s_get_pkey_by_hash_callback = NULL;
 
 /**
  * @brief dap_sign_init
@@ -55,10 +57,9 @@ int dap_sign_init(uint8_t a_sign_hash_type_default)
  * @brief get signature size (different for specific crypto algorithm)
  * 
  * @param a_key dap_enc_key_t * encryption key object
- * @param a_output_wish_size size_t output size
  * @return size_t 
  */
-size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t *a_key, UNUSED_ARG size_t a_output_wish_size )
+DAP_INLINE size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t *a_key)
 { 
     return dap_enc_calc_signature_unserialized_size(a_key);
 }
@@ -235,41 +236,61 @@ int dap_sign_create_output(dap_enc_key_t *a_key, const void * a_data, const size
 }
 
 /**
- * @brief sign data with specified key
- * 
+ * @brief sign data with specified key with choosed hash type
  * @param a_key dap_enc_key_t key object
  * @param a_data const void * buffer with data
  * @param a_data_size const size_t buffer size
- * @param a_output_wish_size size_t output buffer size
+ * @param a_hash_type data and pkey hash type
  * @return dap_sign_t* 
  */
-dap_sign_t * dap_sign_create(dap_enc_key_t *a_key, const void * a_data,
-        const size_t a_data_size, size_t a_output_wish_size)
+dap_sign_t *dap_sign_create_with_hash_type(dap_enc_key_t *a_key, const void * a_data,
+        const size_t a_data_size, uint32_t a_hash_type)
 {
     dap_return_val_if_fail(a_key && a_key->priv_key_data && a_key->priv_key_data_size, NULL);
-    const void * l_sign_data;
-    size_t l_sign_data_size;
-
-    dap_chain_hash_fast_t l_sign_data_hash;
+    const void *l_sign_data = NULL;
+    size_t l_sign_data_size = 0;
+    dap_chain_hash_fast_t l_sign_data_hash = {};
+    uint32_t l_hash_type = DAP_SIGN_REMOVE_PKEY_HASHING_FLAG(a_hash_type);
+    bool l_use_pkey_hash = DAP_SIGN_GET_PKEY_HASHING_FLAG(a_hash_type);
+    if (dap_enc_key_is_insign_hashing(a_key->type)) {
+        if (l_hash_type != DAP_SIGN_HASH_TYPE_SIGN && l_hash_type != DAP_SIGN_HASH_TYPE_DEFAULT)
+            log_it(L_WARNING, "%s enc key use insign hashing, hash type change to DAP_SIGN_HASH_TYPE_SIGN (0x%02x)", dap_enc_get_type_name(a_key->type), DAP_SIGN_HASH_TYPE_SIGN);
+        l_hash_type = DAP_SIGN_HASH_TYPE_SIGN;
+    } else {
+        if (l_hash_type == DAP_SIGN_HASH_TYPE_SIGN) {
+            log_it(L_WARNING, "%s enc key not use insign hashing, hash type change to default (0x%02x)", dap_enc_get_type_name(a_key->type), s_sign_hash_type_default);
+            l_hash_type = s_sign_hash_type_default;
+        }
+        if (l_hash_type == DAP_SIGN_HASH_TYPE_DEFAULT)
+            l_hash_type = s_sign_hash_type_default;
+    }
+    dap_return_val_if_pass_err(l_use_pkey_hash && l_hash_type == DAP_SIGN_HASH_TYPE_NONE, NULL, "Sign with DAP_PKEY_HASHING_FLAG can't have DAP_SIGN_HASH_TYPE_NONE (0x00)");
 
-    if(s_sign_hash_type_default == DAP_SIGN_HASH_TYPE_NONE || a_key->type == DAP_ENC_KEY_TYPE_SIG_ECDSA) {
+    if(l_hash_type == DAP_SIGN_HASH_TYPE_NONE || l_hash_type == DAP_SIGN_HASH_TYPE_SIGN) {
         l_sign_data = a_data;
         l_sign_data_size = a_data_size;
-    }else{
+    } else {
         l_sign_data = &l_sign_data_hash;
         l_sign_data_size = sizeof(l_sign_data_hash);
-        switch(s_sign_hash_type_default){
+        switch(l_hash_type){
             case DAP_SIGN_HASH_TYPE_SHA3: dap_hash_fast(a_data,a_data_size,&l_sign_data_hash); break;
-            default: log_it(L_CRITICAL, "We can't hash with hash type 0x%02x",s_sign_hash_type_default);
+            default: log_it(L_CRITICAL, "We can't hash with hash type 0x%02x", l_hash_type);
         }
     }
 
     // calculate max signature size
-    size_t l_sign_unserialized_size = dap_sign_create_output_unserialized_calc_size(a_key, a_output_wish_size);
+    size_t l_sign_unserialized_size = dap_sign_create_output_unserialized_calc_size(a_key);
     if(l_sign_unserialized_size > 0) {
         size_t l_pub_key_size = 0;
         uint8_t *l_sign_unserialized = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(uint8_t, l_sign_unserialized_size, NULL),
-                *l_pub_key = dap_enc_key_serialize_pub_key(a_key, &l_pub_key_size);
+                *l_pub_key = NULL;   
+        if (l_use_pkey_hash) {
+            l_pub_key = DAP_NEW_Z(dap_hash_fast_t);
+            dap_enc_key_get_pkey_hash(a_key, (dap_hash_fast_t *)l_pub_key);
+            l_pub_key_size = DAP_HASH_FAST_SIZE;
+        } else {
+            l_pub_key = dap_enc_key_serialize_pub_key(a_key, &l_pub_key_size);
+        }
         // calc signature [sign_size may decrease slightly]
         if( dap_sign_create_output(a_key, l_sign_data, l_sign_data_size,
                                          l_sign_unserialized, &l_sign_unserialized_size) != 0) {
@@ -287,7 +308,7 @@ dap_sign_t * dap_sign_create(dap_enc_key_t *a_key, const void * a_data,
                 memcpy(l_ret->pkey_n_sign + l_pub_key_size, l_sign_ser, l_sign_ser_size);
                 l_ret->header.sign_pkey_size =(uint32_t) l_pub_key_size;
                 l_ret->header.sign_size = (uint32_t) l_sign_ser_size;
-                l_ret->header.hash_type = s_sign_hash_type_default;
+                l_ret->header.hash_type = l_use_pkey_hash ? DAP_SIGN_ADD_PKEY_HASHING_FLAG(l_hash_type) : l_hash_type;
 
                 dap_enc_key_signature_delete(a_key->type, l_sign_unserialized);
                 DAP_DEL_MULTY(l_sign_ser, l_pub_key);
@@ -327,8 +348,22 @@ uint8_t* dap_sign_get_sign(dap_sign_t *a_sign, size_t *a_sign_size)
 uint8_t* dap_sign_get_pkey(dap_sign_t *a_sign, size_t *a_pub_key_out)
 {
     dap_return_val_if_pass(!a_sign, NULL);
-
-    if(a_pub_key_out)
+    bool l_use_pkey_hash = DAP_SIGN_GET_PKEY_HASHING_FLAG(a_sign->header.hash_type);
+    if (l_use_pkey_hash) {
+        if (!s_get_pkey_by_hash_callback) {
+            log_it(L_ERROR, "Can't get pkey by hash, callback s_get_pkey_by_hash_callback not inited");
+            return NULL;
+        }
+        dap_pkey_t *l_pkey = s_get_pkey_by_hash_callback(a_sign->pkey_n_sign);
+        if (!l_pkey) {
+            log_it(L_ERROR, "Can't get pkey by hash %s", dap_hash_fast_to_str_static((dap_hash_fast_t *)a_sign->pkey_n_sign));
+            return NULL;
+        }
+        if (a_pub_key_out)
+            *a_pub_key_out = l_pkey->header.size;
+        return l_pkey->pkey;
+    }
+    if (a_pub_key_out)
         *a_pub_key_out = a_sign->header.sign_pkey_size;
     return a_sign->pkey_n_sign;
 }
@@ -344,7 +379,14 @@ uint8_t* dap_sign_get_pkey(dap_sign_t *a_sign, size_t *a_pub_key_out)
 bool dap_sign_get_pkey_hash(dap_sign_t *a_sign, dap_chain_hash_fast_t *a_sign_hash)
 {
     dap_return_val_if_fail(a_sign && a_sign->header.sign_pkey_size, false);
-    return dap_hash_fast(a_sign->pkey_n_sign, a_sign->header.sign_pkey_size, a_sign_hash);
+    if (DAP_SIGN_GET_PKEY_HASHING_FLAG(a_sign->header.hash_type)) {
+        if (a_sign->header.sign_pkey_size > DAP_HASH_FAST_SIZE) {
+            log_it(L_ERROR, "Error in pkey size check, expected <= %zu, in sign %u", sizeof(dap_chain_hash_fast_t), a_sign->header.sign_pkey_size);
+            return false;
+        }
+        return memcpy(a_sign_hash, a_sign->pkey_n_sign, a_sign->header.sign_pkey_size) ? true : false;
+    }
+    return  dap_hash_fast(a_sign->pkey_n_sign, a_sign->header.sign_pkey_size, a_sign_hash);
 }
 
 /**
@@ -416,7 +458,7 @@ int dap_sign_verify(dap_sign_t *a_chain_sign, const void *a_data, const size_t a
         log_it(L_WARNING,"Incorrect signature, can't extract key");
         return -3;
     }
-    size_t l_sign_data_ser_size;
+    size_t l_sign_data_ser_size = 0;
     uint8_t *l_sign_data_ser = dap_sign_get_sign(a_chain_sign, &l_sign_data_ser_size);
 
     if ( !l_sign_data_ser ){
@@ -436,20 +478,22 @@ int dap_sign_verify(dap_sign_t *a_chain_sign, const void *a_data, const size_t a
     }
 
     int l_ret = 0;
-    //uint8_t * l_sign = a_chain_sign->pkey_n_sign + a_chain_sign->header.sign_pkey_size;
     const void *l_verify_data;
     size_t l_verify_data_size;
     dap_chain_hash_fast_t l_verify_data_hash;
+    uint32_t l_hash_type = DAP_SIGN_REMOVE_PKEY_HASHING_FLAG(a_chain_sign->header.hash_type);
+    if(l_hash_type == DAP_SIGN_HASH_TYPE_DEFAULT)
+        log_it(L_WARNING, "Detected DAP_SIGN_HASH_TYPE_DEFAULT (0x%02x) hash type in sign ", DAP_SIGN_HASH_TYPE_DEFAULT);
 
-    if(a_chain_sign->header.hash_type == DAP_SIGN_HASH_TYPE_NONE || l_key->type == DAP_ENC_KEY_TYPE_SIG_ECDSA){
+    if(l_hash_type == DAP_SIGN_HASH_TYPE_NONE || l_hash_type == DAP_SIGN_HASH_TYPE_SIGN){
         l_verify_data = a_data;
         l_verify_data_size = a_data_size;
-    }else{
+    } else {
         l_verify_data = &l_verify_data_hash;
-        l_verify_data_size = sizeof(l_verify_data_hash);
-        switch(s_sign_hash_type_default){
+        l_verify_data_size = DAP_CHAIN_HASH_FAST_SIZE;
+        switch(l_hash_type){
             case DAP_SIGN_HASH_TYPE_SHA3: dap_hash_fast(a_data,a_data_size,&l_verify_data_hash); break;
-            default: log_it(L_CRITICAL, "Incorrect signature: we can't check hash with hash type 0x%02x",s_sign_hash_type_default);
+            default: log_it(L_CRITICAL, "Incorrect signature: we can't check hash with hash type 0x%02x", s_sign_hash_type_default);
             dap_enc_key_signature_delete(l_key->type, l_sign_data);
             dap_enc_key_delete(l_key);
             return -5;
@@ -599,4 +643,15 @@ DAP_INLINE const char *dap_sign_get_str_recommended_types(){
     "sig_shipovnik\n"
 #endif
     "sig_sphincs\nsig_multi_chained\n";
-}
\ No newline at end of file
+}
+
+/**
+ * @brief init callback to search pkey by hash
+ * @return if pass 0, other - error
+ */
+int dap_sign_set_pkey_by_hash_callback(dap_sign_callback_t a_callback)
+{
+    dap_return_val_if_pass_err(s_get_pkey_by_hash_callback, -1, "s_get_pkey_by_hash_callback already inited");
+    s_get_pkey_by_hash_callback = a_callback;
+    return 0;
+}
diff --git a/crypto/test/crypto/dap_enc_benchmark_test.c b/crypto/test/crypto/dap_enc_benchmark_test.c
index e6a46601d..e70c2623f 100644
--- a/crypto/test/crypto/dap_enc_benchmark_test.c
+++ b/crypto/test/crypto/dap_enc_benchmark_test.c
@@ -1,10 +1,32 @@
 #include "dap_enc_benchmark_test.h"
 #include "dap_sign.h"
+#include "dap_pkey.h"
 #include "dap_test.h"
 #include "dap_enc_test.h"
 #include "rand/dap_rand.h"
+#include "uthash.h"
 #define LOG_TAG "dap_crypto_benchmark_tests"
 
+typedef struct pkey_hash_table {
+    uint8_t *pkey_hash;
+    dap_pkey_t *pkey;
+    UT_hash_handle hh;
+} pkey_hash_table_t;
+
+static pkey_hash_table_t *s_pkey_hash_table = NULL;
+
+static dap_pkey_t *s_get_pkey_by_hash_callback(const uint8_t *a_hash)
+{
+    pkey_hash_table_t *l_finded = NULL;
+
+    pkey_hash_table_t *l_temp, *l_current = NULL;
+    HASH_ITER(hh, s_pkey_hash_table, l_current, l_temp){
+        if (!memcmp(l_current->pkey_hash, a_hash, DAP_CHAIN_HASH_FAST_SIZE))
+            l_finded = l_current;
+    }
+    return l_finded->pkey;
+}
+
 #define KEYS_TOTAL_COUNT 10
 
 /*--------------------------TRANSFER TEST BLOCK--------------------------*/
@@ -76,7 +98,7 @@ static void s_sign_verify_test(dap_enc_key_type_t a_key_type, int a_times, int *
     dap_enc_key_t *l_keys[a_times];
     size_t l_source_size[a_times];
     dap_enc_key_t *l_key_temp = dap_enc_key_new_generate(a_key_type, NULL, 0, seed, seed_size, 0);
-    size_t max_signature_size = dap_sign_create_output_unserialized_calc_size(l_key_temp, 0);
+    size_t max_signature_size = dap_sign_create_output_unserialized_calc_size(l_key_temp);
     dap_enc_key_delete(l_key_temp);
 
     int l_t1 = 0;
@@ -157,12 +179,25 @@ static void s_sign_verify_ser_test(dap_enc_key_type_t a_key_type, int a_times, i
         
         l_t1 = get_cur_time_msec();
         dap_enc_key_t *key = dap_enc_key_new_generate(a_key_type, l_key, KEYS_TOTAL_COUNT, seed, seed_size, 0);
+        uint32_t l_hash_type = i % 2 ? DAP_SIGN_ADD_PKEY_HASHING_FLAG(DAP_SIGN_HASH_TYPE_DEFAULT) : DAP_SIGN_HASH_TYPE_DEFAULT;
+        
+        dap_chain_hash_fast_t l_hash = {};
         if (key->type == DAP_ENC_KEY_TYPE_SIG_ECDSA)
-            l_signs[i] = dap_sign_create(key, l_source[i], l_source_size[i], 0);
+            l_signs[i] = dap_sign_create_with_hash_type(key, l_source[i], l_source_size[i], l_hash_type);
         else {
-            dap_chain_hash_fast_t l_hash;
             dap_hash_fast(l_source[i], l_source_size[i], &l_hash);
-            l_signs[i] = dap_sign_create(key, &l_hash, sizeof(l_hash), 0);
+            l_signs[i] = dap_sign_create_with_hash_type(key, &l_hash, sizeof(l_hash), l_hash_type);
+        }
+        if (i % 2) {
+            pkey_hash_table_t *l_item = DAP_NEW_Z(pkey_hash_table_t);
+            l_item->pkey_hash = DAP_NEW_Z(dap_chain_hash_fast_t);
+            dap_enc_key_get_pkey_hash(key, (dap_chain_hash_fast_t *)l_item->pkey_hash);
+            
+            dap_assert_PIF(dap_sign_get_pkey_hash(l_signs[i], &l_hash), "Get pkeyhash by sign");
+            dap_assert_PIF(!memcmp(l_item->pkey_hash, &l_hash, DAP_CHAIN_HASH_FAST_SIZE), "pkey hash in enc_key and sign equal")
+
+            l_item->pkey = dap_pkey_from_enc_key (key);
+            HASH_ADD(hh, s_pkey_hash_table, pkey_hash, DAP_CHAIN_HASH_FAST_SIZE, l_item);
         }
         *a_sig_time += get_cur_time_msec() - l_t1;
         
@@ -173,7 +208,7 @@ static void s_sign_verify_ser_test(dap_enc_key_type_t a_key_type, int a_times, i
     l_t1 = get_cur_time_msec();
     for(int i = 0; i < a_times; ++i) {
         int l_verified = 0;
-       if (dap_sign_type_to_key_type(l_signs[i]->header.type) == DAP_ENC_KEY_TYPE_SIG_ECDSA)
+        if (dap_sign_type_to_key_type(l_signs[i]->header.type) == DAP_ENC_KEY_TYPE_SIG_ECDSA)
             l_verified = dap_sign_verify(l_signs[i], l_source[i], l_source_size[i]);
         else {
             dap_chain_hash_fast_t l_hash;
@@ -187,6 +222,11 @@ static void s_sign_verify_ser_test(dap_enc_key_type_t a_key_type, int a_times, i
     for(int i = 0; i < a_times; ++i) {
         DAP_DEL_MULTY(l_signs[i], l_source[i]);
     }
+    pkey_hash_table_t *l_temp, *l_current = NULL;
+    HASH_ITER(hh, s_pkey_hash_table, l_current, l_temp){
+        HASH_DEL(s_pkey_hash_table, l_current);
+        DAP_DEL_MULTY(l_current->pkey, l_current->pkey_hash, l_current);
+    }
 }
 
 static void s_sign_verify_test_becnhmark(const char *a_name, dap_enc_key_type_t a_key_type, int a_times) {
@@ -221,6 +261,7 @@ static void s_transfer_tests_run(int a_times)
 
 static void s_sign_verify_tests_run(int a_times)
 {
+    dap_sign_set_pkey_by_hash_callback(s_get_pkey_by_hash_callback);
     dap_init_test_case();
     for (size_t i = 0; i < c_keys_count; ++i) {
         s_sign_verify_test_becnhmark(s_key_type_to_str(c_key_type_arr[i]), c_key_type_arr[i], a_times);
diff --git a/crypto/test/crypto/dap_enc_multithread_test.c b/crypto/test/crypto/dap_enc_multithread_test.c
index e17f94b9f..08e15d7a9 100644
--- a/crypto/test/crypto/dap_enc_multithread_test.c
+++ b/crypto/test/crypto/dap_enc_multithread_test.c
@@ -37,11 +37,11 @@ static int s_test_thread(dap_enc_key_type_t a_key_type, int a_times)
         
         dap_enc_key_t *key = s_enc_key_new_generate(a_key_type, NULL, 0, seed, seed_size, 0);
         if (key->type == DAP_ENC_KEY_TYPE_SIG_ECDSA)
-            l_signs[i] = dap_sign_create(key, l_source[i], l_source_size[i], 0);
+            l_signs[i] = dap_sign_create(key, l_source[i], l_source_size[i]);
         else {
             dap_chain_hash_fast_t l_hash;
             dap_hash_fast(l_source[i], l_source_size[i], &l_hash);
-            l_signs[i] = dap_sign_create(key, &l_hash, sizeof(l_hash), 0);
+            l_signs[i] = dap_sign_create(key, &l_hash, sizeof(l_hash));
         }
         
         dap_assert_PIF(l_signs[i], "Signing message and serialize");
diff --git a/crypto/test/crypto/dap_enc_test.c b/crypto/test/crypto/dap_enc_test.c
index f4b734b34..c5b032a0f 100755
--- a/crypto/test/crypto/dap_enc_test.c
+++ b/crypto/test/crypto/dap_enc_test.c
@@ -465,7 +465,7 @@ static void test_serialize_deserialize_pub_priv(dap_enc_key_type_t key_type)
         case DAP_ENC_KEY_TYPE_SIG_SPHINCSPLUS:
         case DAP_ENC_KEY_TYPE_SIG_ECDSA:
         case DAP_ENC_KEY_TYPE_SIG_SHIPOVNIK:
-            sig_buf_size = dap_sign_create_output_unserialized_calc_size(key, 0);
+            sig_buf_size = dap_sign_create_output_unserialized_calc_size(key);
             sig_buf = calloc(sig_buf_size, 1);
             is_sig = key->sign_get(key, source_buf, source_size, sig_buf, sig_buf_size);
             break;
diff --git a/crypto/test/crypto/main.c b/crypto/test/crypto/main.c
index 45ff6301f..b3ffc63d6 100755
--- a/crypto/test/crypto/main.c
+++ b/crypto/test/crypto/main.c
@@ -9,8 +9,10 @@
 
 int main(void) {
     // switch off debug info from library
+    dap_log_level_set(L_WARNING);
+    dap_log_set_external_output(LOGGER_OUTPUT_STDOUT, NULL);
+    
     int l_ret = 0;
-    dap_log_level_set(L_ERROR);
     const int l_times = 5;
 
     test_encypt_decrypt(l_times, DAP_ENC_KEY_TYPE_SALSA2012, 32);
diff --git a/global-db/dap_global_db_pkt.c b/global-db/dap_global_db_pkt.c
index ef24b1ca9..0c2d5c0ca 100644
--- a/global-db/dap_global_db_pkt.c
+++ b/global-db/dap_global_db_pkt.c
@@ -98,7 +98,7 @@ dap_sign_t *dap_store_obj_sign(dap_store_obj_t *a_obj, dap_enc_key_t *a_key, uin
     if (a_key) {
         // Exclude CRC field from sign
         l_sign = dap_sign_create(a_key, (uint8_t *)l_pkt + sizeof(uint64_t),
-                                 dap_global_db_pkt_get_size(l_pkt) - sizeof(uint64_t), 0);
+                                 dap_global_db_pkt_get_size(l_pkt) - sizeof(uint64_t));
         if (!l_sign) {
             log_it(L_ERROR, "Can't sign serialized global DB object");
             DAP_DELETE(l_pkt);
diff --git a/net/client/dap_client_pvt.c b/net/client/dap_client_pvt.c
index 97a94e047..419800168 100644
--- a/net/client/dap_client_pvt.c
+++ b/net/client/dap_client_pvt.c
@@ -339,7 +339,7 @@ int s_add_cert_sign_to_data(const dap_cert_t *a_cert, uint8_t **a_data, size_t *
 {
     dap_return_val_if_pass(!a_cert || !a_size || !a_data, 0);
 
-    dap_sign_t *l_sign = dap_sign_create(a_cert->enc_key, a_signing_data, a_signing_size, 0);
+    dap_sign_t *l_sign = dap_sign_create(a_cert->enc_key, a_signing_data, a_signing_size);
     dap_return_val_if_fail(l_sign, 0);    
     size_t l_sign_size = dap_sign_get_size(l_sign), l_size = *a_size;
     byte_t *l_data = DAP_REALLOC_RET_VAL_IF_FAIL(*a_data, l_size + l_sign_size, 0, l_sign);
diff --git a/net/server/enc_server/dap_enc_http.c b/net/server/enc_server/dap_enc_http.c
index c8d41cc25..95b1baa89 100644
--- a/net/server/enc_server/dap_enc_http.c
+++ b/net/server/enc_server/dap_enc_http.c
@@ -199,7 +199,7 @@ void enc_http_proc(struct dap_http_simple *cl_st, void * arg)
             l_enc_key_ks->node_addr = dap_stream_node_addr_from_sign(l_sign);
 
             dap_cert_t *l_node_cert = dap_cert_find_by_name(DAP_STREAM_NODE_ADDR_CERT_NAME);
-            dap_sign_t *l_node_sign = dap_sign_create(l_node_cert->enc_key,l_pkey_exchange_key->pub_key_data, l_pkey_exchange_key->pub_key_data_size, 0);
+            dap_sign_t *l_node_sign = dap_sign_create(l_node_cert->enc_key,l_pkey_exchange_key->pub_key_data, l_pkey_exchange_key->pub_key_data_size);
             if (!l_node_sign) {
                 dap_enc_key_delete(l_pkey_exchange_key);
                 DAP_DELETE(encrypt_msg);
diff --git a/net/server/json_rpc/rpc_core/src/dap_json_rpc_request.c b/net/server/json_rpc/rpc_core/src/dap_json_rpc_request.c
index 18eda8317..451f3bbb5 100644
--- a/net/server/json_rpc/rpc_core/src/dap_json_rpc_request.c
+++ b/net/server/json_rpc/rpc_core/src/dap_json_rpc_request.c
@@ -331,7 +331,7 @@ dap_json_rpc_http_request_t *dap_json_rpc_request_sign_by_cert(dap_json_rpc_requ
     if (!l_str)
         return log_it(L_ERROR, "Can't convert JSON-request to string!"), NULL;
     int l_len = strlen(l_str);
-    dap_sign_t *l_sign = dap_cert_sign(a_cert, l_str, l_len, 0);
+    dap_sign_t *l_sign = dap_cert_sign(a_cert, l_str, l_len);
     if (!l_sign)
         return log_it(L_ERROR, "JSON request signing failed"), NULL;
     size_t l_sign_size = dap_sign_get_size(l_sign);
-- 
GitLab