diff --git a/dap_chain_cert.c b/dap_chain_cert.c
index 7f0f05ca62a3ded158ef488b3f2e6c9f7301b713..a0f881fc7485eed95e8fdd51527fe40f96c23b4d 100644
--- a/dap_chain_cert.c
+++ b/dap_chain_cert.c
@@ -29,7 +29,7 @@
 #include "dap_common.h"
 #include "dap_chain_cert.h"
 #include "dap_chain_cert_file.h"
-#include "dap_hash.h"
+//#include "dap_hash.h"
 #define LOG_TAG "dap_chain_cert"
 
 
@@ -87,11 +87,8 @@ size_t dap_chain_cert_sign_output_size(dap_chain_cert_t * a_cert, size_t a_size_
 dap_chain_addr_t * dap_chain_cert_to_addr(dap_chain_cert_t * a_cert, dap_chain_net_id_t a_net_id)
 {
     dap_chain_addr_t * l_addr = DAP_NEW_Z(dap_chain_addr_t);
-    l_addr->addr_ver = 1;
-    l_addr->net_id.uint64 = a_net_id.uint64;
-    l_addr->sig_type.raw = dap_chain_sign_type_from_key_type( a_cert->enc_key->type).raw;
-   // dap_hash(&l_addr);
-    l_addr->checksum;
+    dap_chain_addr_fill(l_addr, a_cert->enc_key, &a_net_id);
+    return l_addr;
 }
 
 /**
@@ -103,11 +100,11 @@ dap_chain_addr_t * dap_chain_cert_to_addr(dap_chain_cert_t * a_cert, dap_chain_n
  * @param a_output_siz
  * @return
  */
-int dap_chain_cert_sign_output(dap_chain_cert_t * a_cert, const void * a_data, size_t a_data_size,
+/*int dap_chain_cert_sign_output(dap_chain_cert_t * a_cert, const void * a_data, size_t a_data_size,
                                         void * a_output, size_t a_output_size)
 {
     return dap_chain_sign_create_output( a_cert->enc_key,a_data,a_data_size,a_output,a_output_size);
-}
+}*/
 
 /**
  * @brief dap_chain_cert_sign
@@ -121,19 +118,8 @@ dap_chain_sign_t * dap_chain_cert_sign(dap_chain_cert_t * a_cert, const void * a
                                        , size_t a_data_size, size_t a_output_size_wished )
 {
     dap_enc_key_t * l_key = a_cert->enc_key;
-    size_t l_ret_size = dap_chain_sign_create_output_cals_size( l_key,a_output_size_wished);
-    if (l_ret_size > 0 ) {
-        dap_chain_sign_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_sign_t,
-                                                  l_ret_size );
-        if (l_ret){
-            if ( dap_chain_sign_create_output(l_key,a_data,a_data_size,l_ret,l_ret_size) !=0 ){
-                DAP_DELETE(l_ret);
-                return NULL;
-            }else
-                return l_ret;
-        }
-    }else
-        return NULL;
+    dap_chain_sign_t *l_ret = dap_chain_sign_create(l_key, a_data, a_data_size, a_output_size_wished);
+    return l_ret;
 }
 
 /**
@@ -203,6 +189,7 @@ dap_chain_cert_t * dap_chain_cert_generate(const char * a_cert_name
     } else {
         log_it(L_ERROR,"Can't generate certificat in memory!");
     }
+    return NULL;
 }
 
 /**
diff --git a/dap_chain_cert.h b/dap_chain_cert.h
index a809353fc0a19db6b3021ebc7433e01624df7851..385edd983ae534c08de1d5bac7f6592394b38493 100644
--- a/dap_chain_cert.h
+++ b/dap_chain_cert.h
@@ -66,8 +66,8 @@ int dap_chain_cert_compare_with_sign (dap_chain_cert_t * a_cert,dap_chain_sign_t
 size_t dap_chain_cert_sign_output_size(dap_chain_cert_t * a_cert, size_t a_size_wished);
 
 
-int dap_chain_cert_sign_output(dap_chain_cert_t * a_cert, const void * a_data, size_t a_data_size
-                                        , void * a_output , size_t a_output_size);
+//int dap_chain_cert_sign_output(dap_chain_cert_t * a_cert, const void * a_data, size_t a_data_size
+//                                        , void * a_output , size_t a_output_size);
 
 
 int dap_chain_cert_add_cert_sign(dap_chain_cert_t * a_cert, dap_chain_cert_t * a_cert_signer);
diff --git a/dap_chain_cert_file.c b/dap_chain_cert_file.c
index 628491bab2928d5e603a1da10774949cf05d8668..b6af8f33013a5236206aea1d2f3fa4dd59339a32 100644
--- a/dap_chain_cert_file.c
+++ b/dap_chain_cert_file.c
@@ -32,20 +32,6 @@
 
 #define LOG_TAG "dap_chain_cert_file"
 
-
-/**
- * @brief dap_chain_cert_file_save_to_mem_size
- * @param a_cert
- * @return
- */
-size_t dap_chain_cert_save_mem_size(dap_chain_cert_t * a_cert )
-{
-    return sizeof (dap_chain_cert_file_hdr_t)
-            + a_cert->enc_key->pub_key_data_size
-            + a_cert->enc_key->priv_key_data_size
-            + (a_cert->metadata?strlen(a_cert->metadata):0);
-}
-
 /**
  * @brief dap_chain_cert_file_save
  * @param a_cert
@@ -56,15 +42,16 @@ int dap_chain_cert_save_file(dap_chain_cert_t * a_cert, const char * a_cert_file
 {
     FILE * l_file = fopen(a_cert_file_path,"w");
     if( l_file ){
-        size_t l_data_size = dap_chain_cert_save_mem_size(a_cert);
-        void * l_data = DAP_NEW_SIZE(void,l_data_size);
-        if ( dap_chain_cert_save_mem(a_cert,l_data) == 0 ){
+        uint32_t l_data_size = 0;
+        void * l_data = dap_chain_cert_save_mem(a_cert, &l_data_size);
+        if ( l_data ){
             size_t l_retbytes;
             if ( (l_retbytes = fwrite(l_data,1,l_data_size,l_file)) != l_data_size ){
                 log_it(L_ERROR, "Can't write %u bytes on disk (processed only %u)!", l_data_size,l_retbytes);
                 return -3;
             }
             fclose(l_file);
+            DAP_DELETE(l_data);
             return 0;
         }else{
             log_it(L_ERROR,"Can't serialize certificate in memory");
@@ -80,56 +67,67 @@ int dap_chain_cert_save_file(dap_chain_cert_t * a_cert, const char * a_cert_file
 /**
  * @brief dap_chain_cert_file_save_to_mem
  * @param a_cert
- * @param a_data
+ * @param a_cert_size_out
  * @return
  */
-int dap_chain_cert_save_mem(dap_chain_cert_t * a_cert, void * a_data )
+uint8_t* dap_chain_cert_save_mem(dap_chain_cert_t * a_cert, uint32_t *a_cert_size_out)
 {
     dap_chain_cert_file_hdr_t l_hdr={0};
-    uint8_t * l_data = (uint8_t *) a_data;
-    size_t l_data_offset = 0;
+    uint32_t l_data_offset = 0;
     dap_enc_key_t * l_key = a_cert->enc_key;
-    int ret = 0;
+    uint8_t *l_data = NULL;
+
+    size_t l_priv_key_data_size, l_pub_key_data_size;
+    uint8_t *l_pub_key_data = dap_enc_key_serealize_pub_key(l_key, &l_pub_key_data_size);
+    uint8_t *l_priv_key_data = dap_enc_key_serealize_priv_key(l_key, &l_priv_key_data_size);
 
     l_hdr.sign = DAP_CHAIN_CERT_FILE_HDR_SIGN;
     l_hdr.type = DAP_CHAIN_CERT_FILE_TYPE_PUBLIC;
-    if ( l_key->priv_key_data ){
+    if ( l_priv_key_data ){
         l_hdr.type =  DAP_CHAIN_CERT_FILE_TYPE_PRIVATE;
-        log_it(L_DEBUG,"Private key size %u",l_key->priv_key_data_size);
+        log_it(L_DEBUG,"Private key size %u",l_priv_key_data_size);
     }
-    if (l_key->pub_key_data){
-        log_it(L_DEBUG,"Public key size %u",l_key->pub_key_data_size);
+    if (l_pub_key_data){
+        log_it(L_DEBUG,"Public key size %u",l_pub_key_data_size);
     }else{
         log_it(L_ERROR,"No public or private key in certificate, nothing to save");
-        ret = -1;
         goto lb_exit;
     }
     log_it(L_DEBUG,"Metadata size %u",l_key->_inheritor_size);
 
     l_hdr.version = DAP_CHAIN_CERT_FILE_VERSION;
-    l_hdr.data_size = l_key->pub_key_data_size;
-    l_hdr.data_pvt_size = l_key->priv_key_data_size;
-    l_hdr.metadata_size = 0;
+    l_hdr.data_size = l_pub_key_data_size;
+    l_hdr.data_pvt_size = l_priv_key_data_size;
+    l_hdr.metadata_size = l_key->_inheritor_size;
 
     l_hdr.ts_last_used = l_key->last_used_timestamp;
     l_hdr.sign_type = dap_chain_sign_type_from_key_type ( l_key->type );
 
+    l_data = DAP_NEW_SIZE(void, sizeof(l_hdr) + l_priv_key_data_size + l_pub_key_data_size + l_hdr.metadata_size);
+
     memcpy(l_data +l_data_offset, &l_hdr ,sizeof(l_hdr) );
     l_data_offset += sizeof(l_hdr);
 
-    memcpy(l_data +l_data_offset, l_key->pub_key_data ,l_key->pub_key_data_size );
-    l_data_offset += l_key->pub_key_data_size;
+    memcpy(l_data +l_data_offset, l_pub_key_data ,l_pub_key_data_size );
+    l_data_offset += l_pub_key_data_size;
 
-    memcpy(l_data +l_data_offset, l_key->priv_key_data ,l_key->priv_key_data_size );
-    l_data_offset += l_key->priv_key_data_size;
+    memcpy(l_data +l_data_offset, l_priv_key_data ,l_priv_key_data_size );
+    l_data_offset += l_priv_key_data_size;
 
+    memcpy(l_data +l_data_offset, l_key->_inheritor ,l_key->_inheritor_size );
+    l_data_offset += l_key->_inheritor_size;
 
-lb_exit:
 
-    if (ret == 0)
+lb_exit:
+    DAP_DELETE(l_pub_key_data);
+    DAP_DELETE(l_priv_key_data);
+    if (l_data)
         log_it(L_NOTICE,"Certificate \"%s\" successfully serialized",a_cert->name);
-
-    return ret;
+    else
+        log_it(L_ERROR,"Certificate \"%s\" was not serialized",a_cert->name);
+    if(a_cert_size_out)
+        *a_cert_size_out = l_data_offset;
+    return l_data;
 }
 
 /**
@@ -175,36 +173,39 @@ dap_chain_cert_t* dap_chain_cert_mem_load(void * a_data, size_t a_data_size)
     dap_chain_cert_t * l_ret = NULL;
     dap_chain_cert_file_hdr_t l_hdr={0};
     uint8_t * l_data = (uint8_t *) a_data;
+    uint32_t l_data_offset = 0;
     memcpy(&l_hdr,l_data, sizeof(l_hdr));
+    l_data_offset += sizeof(l_hdr);
     if (l_hdr.sign != DAP_CHAIN_CERT_FILE_HDR_SIGN ){
         log_it(L_ERROR, "Wrong cert signature, corrupted header!");
         goto l_exit;
     }
     if (l_hdr.version >= 1 ){
-        if ( (l_hdr.data_size+l_hdr.data_pvt_size +l_hdr.metadata_size) > a_data_size ){
+        if ( (sizeof(l_hdr) + l_hdr.data_size+l_hdr.data_pvt_size +l_hdr.metadata_size) > a_data_size ){
             log_it(L_ERROR,"Corrupted cert data, data sections size is smaller than exists on the disk! (%llu expected, %llu on disk)",
-                   l_hdr.data_pvt_size+l_hdr.data_size+l_hdr.metadata_size, a_data_size);
+                    sizeof(l_hdr)+l_hdr.data_pvt_size+l_hdr.data_size+l_hdr.metadata_size, a_data_size);
             goto l_exit;
         }
 
         l_ret = DAP_NEW_Z(dap_chain_cert_t);
         l_ret->enc_key = dap_enc_key_new( dap_chain_sign_type_to_key_type( l_hdr.sign_type ));
         l_ret->enc_key->last_used_timestamp = l_hdr.ts_last_used;
+
         if ( l_hdr.data_size > 0 ){
-            l_ret->enc_key->pub_key_data_size = l_hdr.data_size;
-            l_ret->enc_key->pub_key_data = DAP_NEW_SIZE (void,l_hdr.data_size);
-            memcpy(l_ret->enc_key->pub_key_data, l_data + sizeof(l_hdr),l_ret->enc_key->pub_key_data_size);
+
+            dap_enc_key_deserealize_pub_key(l_ret->enc_key, l_data + l_data_offset, l_hdr.data_size);
+            l_data_offset += l_hdr.data_size;
         }
-        l_ret->enc_key->priv_key_data_size = l_hdr.data_pvt_size;
         if ( l_hdr.data_pvt_size > 0 ){
-            l_ret->enc_key->priv_key_data = DAP_NEW_SIZE (void,l_ret->enc_key->priv_key_data_size);
-            memcpy(l_ret->enc_key->priv_key_data, l_data + sizeof(l_hdr)
-                                                        + l_ret->enc_key->pub_key_data_size
-                   ,l_ret->enc_key->priv_key_data_size);
-        }
-        log_it(L_NOTICE,"Successfuly loaded certificate");
 
-//        log_it(L_NOTICE,"Successfuly loaded certificate \"%s\" from the file %s",l_ret->name);
+            dap_enc_key_deserealize_priv_key(l_ret->enc_key, l_data + l_data_offset, l_hdr.data_pvt_size);
+            l_data_offset += l_hdr.data_pvt_size;
+        }
+        if(l_hdr.metadata_size > 0 && l_ret->enc_key->_inheritor && l_ret->enc_key->_inheritor_size == l_hdr.metadata_size) {
+            memcpy(l_ret->enc_key->_inheritor, l_data + l_data_offset, l_ret->enc_key->_inheritor_size);
+        }
+        dap_enc_key_update(l_ret->enc_key);
+        log_it(L_NOTICE,"Successfully loaded certificate");
     }else
         log_it(L_ERROR,"Unrecognizable certificate version, corrupted file or you have too old software");
 
diff --git a/dap_chain_cert_file.h b/dap_chain_cert_file.h
index 46e5f25121e05efe1a54f5e1f2135e42d21adb80..30f2ec9e73265708be451f0137d673fea0381ca8 100644
--- a/dap_chain_cert_file.h
+++ b/dap_chain_cert_file.h
@@ -54,8 +54,7 @@ typedef struct dap_chain_cert_file{
 }DAP_ALIGN_PACKED dap_chain_cert_file_t;
 
 int dap_chain_cert_save_file(dap_chain_cert_t * a_cert, const char * a_cert_file_path);
-int dap_chain_cert_save_mem(dap_chain_cert_t * a_cert, void * a_data );
-size_t dap_chain_cert_save_mem_size(dap_chain_cert_t * a_cert );
+uint8_t* dap_chain_cert_save_mem(dap_chain_cert_t * a_cert, uint32_t *a_cert_size_out);
 
 dap_chain_cert_t* dap_chain_cert_file_load(const char * a_cert_file_path);
 dap_chain_cert_t* dap_chain_cert_mem_load(void * a_data, size_t a_data_size);
diff --git a/dap_chain_pkey.c b/dap_chain_pkey.c
index 284506fda92396f0bb205a2e4c7041697f793c63..6aafa38bd81ad22d32042c713f5599187b05ab46 100644
--- a/dap_chain_pkey.c
+++ b/dap_chain_pkey.c
@@ -26,7 +26,7 @@
 #include "dap_chain_pkey.h"
 
 #define LOG_TAG "chain_key"
-static dap_chain_pkey_t m_dap_chain_pkey_null={0}; // For sizeof nothing more
+//static dap_chain_pkey_t m_dap_chain_pkey_null={0}; // For sizeof nothing more
 
 
 /**
diff --git a/dap_chain_sign.c b/dap_chain_sign.c
index 562accfcd70b4637edaa2889d1fd89b87ef573dc..65cd84e3b73dde0ba408b926577fe096432fbe71 100644
--- a/dap_chain_sign.c
+++ b/dap_chain_sign.c
@@ -34,6 +34,8 @@
 
 dap_chain_sign_t * s_sign_null = NULL;
 bliss_signature_t s_sign_bliss_null = {0};
+
+// calc signature size
 size_t dap_chain_sign_create_output_cals_size(dap_enc_key_t * a_key, size_t a_output_wish_size )
 {
     size_t l_sign_size = 0;
@@ -44,7 +46,8 @@ size_t dap_chain_sign_create_output_cals_size(dap_enc_key_t * a_key, size_t a_ou
         default : return 0;
 
     }
-    return sizeof(s_sign_null->header)+ a_key->pub_key_data_size + l_sign_size;
+    return l_sign_size;
+    //return sizeof(s_sign_null->header)+ a_key->pub_key_data_size + l_sign_size;
 }
 
 /**
@@ -61,7 +64,6 @@ dap_chain_sign_type_t dap_chain_sign_type_from_key_type( dap_enc_key_type_t a_ke
         case DAP_ENC_KEY_TYPE_SIG_TESLA: l_sign_type.type = SIG_TYPE_TESLA; break;
     }
     return l_sign_type;
-
 }
 
 /**
@@ -118,61 +120,91 @@ dap_chain_sign_type_t dap_chain_sign_type_from_str(const char * a_type_str)
 }
 
 /**
- * @brief dap_chain_sign_create
+ * @brief dap_chain_sign_create_output
  * @param a_key
  * @param a_data
  * @param a_data_size
- * @param a_output_wish_size
+ * @param a_output [in/out]
  * @return
  */
-dap_chain_sign_t * dap_chain_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size,
-                                      size_t a_output_wish_size )
+static int dap_chain_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 l_ret_size = dap_chain_sign_create_output_cals_size(a_key,a_output_wish_size);
-    if (l_ret_size > 0 ) {
-        //size_t l_ret_size = sizeof(dap_chain_sign_t) + a_key->pub_key_data_size + l_sign_size;
-        dap_chain_sign_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_sign_t, l_ret_size );
-        if (l_ret){
-            l_ret->header.sign_pkey_size = a_key->pub_key_data_size;
-            l_ret->header.sign_size = ( l_ret_size - sizeof(l_ret->header) - a_key->pub_key_data_size );
-            if ( dap_chain_sign_create_output(a_key,a_data,a_data_size,l_ret->pkey_n_sign + a_key->pub_key_data_size ,
-                                              l_ret->header.sign_size ) !=0 ){
-                DAP_DELETE(l_ret);
-                return NULL;
-            }else{
-                memcpy(l_ret->pkey_n_sign, a_key->pub_key_data, a_key->pub_key_data_size);
-                l_ret->header.type = dap_chain_sign_type_from_key_type(a_key->type);
-                return l_ret;
-            }
-        }
-    }else
-        return NULL;
-
+    switch (a_key->type) {
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+            // For PICNIC a_output_size should decrease
+        *a_output_size = a_key->enc_na(a_key, a_data, a_data_size, a_output, *a_output_size);
+        return (*a_output_size > 0) ? 0 : -1;
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        return (dap_enc_sig_bliss_get_sign(a_key, a_data, a_data_size, a_output, *a_output_size) == BLISS_B_NO_ERROR)
+               ? 0 : -1;
+    default:
+        return -1;
+    }
 }
 
 /**
- * @brief dap_chain_sign_create_output
+ * @brief dap_chain_sign_create
  * @param a_key
  * @param a_data
  * @param a_data_size
- * @param a_output
+ * @param a_output_wish_size
  * @return
  */
-int dap_chain_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)
+dap_chain_sign_t * dap_chain_sign_create(dap_enc_key_t *a_key, const void * a_data,
+        const size_t a_data_size, size_t a_output_wish_size)
 {
-    switch (a_key->type){
-        case DAP_ENC_KEY_TYPE_SIG_TESLA:
-        case DAP_ENC_KEY_TYPE_SIG_PICNIC:
-            return (a_key->enc_na(a_key, a_data, a_data_size, a_output, a_output_size) > 0 )
-                    ? 0 : -1;
-        case DAP_ENC_KEY_TYPE_SIG_BLISS:
-            return dap_enc_sig_bliss_get_sign( a_key, a_data, a_data_size, a_output, a_output_size) == BLISS_B_NO_ERROR
-                    ? 0: -1;
-        default: return -1;
+    // calculate max signature size
+    size_t l_sign_size = dap_chain_sign_create_output_cals_size(a_key, a_output_wish_size);
+    if(l_sign_size > 0) {
+        size_t l_pub_key_size = 0;
+        uint8_t *l_pub_key = dap_enc_key_serealize_pub_key(a_key, &l_pub_key_size);
+        if(!l_pub_key)
+            return NULL;
+        uint8_t* l_sign = DAP_NEW_Z_SIZE(uint8_t, l_sign_size);
+        // calc signature [sign_size may decrease slightly]
+        if(dap_chain_sign_create_output(a_key, a_data, a_data_size, l_sign, &l_sign_size) != 0) {
+            DAP_DELETE(l_sign);
+            DAP_DELETE(l_pub_key);
+            return NULL;
+        } else {
+            uint8_t *l_sign_ser = dap_enc_key_serealize_sign(a_key->type, l_sign, &l_sign_size);
+            dap_chain_sign_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_sign_t,
+                    sizeof(dap_chain_sign_t) + l_sign_size + l_pub_key_size);
+            // write serialized public key to dap_chain_sign_t
+            memcpy(l_ret->pkey_n_sign, l_pub_key, l_pub_key_size);
+            l_ret->header.type = dap_chain_sign_type_from_key_type(a_key->type);
+            // write serialized signature to dap_chain_sign_t
+            memcpy(l_ret->pkey_n_sign + l_pub_key_size, l_sign_ser, l_sign_size);
+            l_ret->header.sign_pkey_size = l_pub_key_size;
+            l_ret->header.sign_size = l_sign_size;
+            DAP_DELETE(l_sign_ser);
+            DAP_DELETE(l_sign);
+            DAP_DELETE(l_pub_key);
+            return l_ret;
+        }
     }
+    return NULL;
 }
 
+uint8_t* dap_chain_sign_get_sign(dap_chain_sign_t *a_sign, size_t *a_sign_out)
+{
+    if(!a_sign)
+        return NULL;
+    if(a_sign_out)
+    *a_sign_out = a_sign->header.sign_size;
+    return a_sign->pkey_n_sign + a_sign->header.sign_pkey_size;
+}
+
+uint8_t* dap_chain_sign_get_pkey(dap_chain_sign_t *a_sign, size_t *a_pub_key_out)
+{
+    if(!a_sign)
+        return NULL;
+    if(a_pub_key_out)
+        *a_pub_key_out = a_sign->header.sign_pkey_size;
+    return a_sign->pkey_n_sign;
+}
 
 /**
  * @brief dap_chain_sign_to_enc_key
@@ -182,8 +214,10 @@ int dap_chain_sign_create_output(dap_enc_key_t *a_key, const void * a_data, cons
 dap_enc_key_t *dap_chain_sign_to_enc_key(dap_chain_sign_t * a_chain_sign)
 {
     dap_enc_key_t * l_ret =  dap_enc_key_new( dap_chain_sign_type_to_key_type( a_chain_sign->header.type  ) );
-    l_ret->pub_key_data_size = a_chain_sign->header.sign_pkey_size;
-    l_ret->pub_key_data = a_chain_sign->pkey_n_sign;
+    size_t l_pkey_size = 0;
+    uint8_t *l_pkey = dap_chain_sign_get_pkey(a_chain_sign, &l_pkey_size);
+    // deserialize public key
+    dap_enc_key_deserealize_pub_key(l_ret, l_pkey, l_pkey_size);
     return l_ret;
 }
 
@@ -194,21 +228,35 @@ dap_enc_key_t *dap_chain_sign_to_enc_key(dap_chain_sign_t * a_chain_sign)
  * @param a_data_size
  * @return 1 valid signature, 0 invalid signature, -1 unsupported sign type
  */
-int dap_chain_sign_verify (dap_chain_sign_t * a_chain_sign, const void * a_data, const size_t a_data_size)
+int dap_chain_sign_verify(dap_chain_sign_t * a_chain_sign, const void * a_data, const size_t a_data_size)
 {
-    dap_enc_key_t * l_key = dap_chain_sign_to_enc_key (a_chain_sign);
-    uint8_t * l_sign = a_chain_sign->pkey_n_sign + a_chain_sign->header.sign_pkey_size;
+    int l_ret;
+    dap_enc_key_t * l_key = dap_chain_sign_to_enc_key(a_chain_sign);
     size_t l_sign_size = a_chain_sign->header.sign_size;
-    switch (l_key->type){
-        case DAP_ENC_KEY_TYPE_SIG_TESLA:
-        case DAP_ENC_KEY_TYPE_SIG_PICNIC:
-            return (l_key->dec_na ( l_key, a_data, a_data_size, l_sign, l_sign_size) > 0 )
-                    ? 0 : 1;
-        case DAP_ENC_KEY_TYPE_SIG_BLISS:
-            return (dap_enc_sig_bliss_verify_sign( l_key, a_data, a_data_size, l_sign, l_sign_size) != BLISS_B_NO_ERROR)
-                    ? 0 : 1;
-        default: return -1;
+    uint8_t *l_sign_ser = dap_chain_sign_get_sign(a_chain_sign, &l_sign_size);
+    // deserialize signature
+    uint8_t * l_sign = dap_enc_key_deserealize_sign(l_key->type, l_sign_ser, &l_sign_size);
+
+    //uint8_t * l_sign = a_chain_sign->pkey_n_sign + a_chain_sign->header.sign_pkey_size;
+    switch (l_key->type) {
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+    case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+        if(l_key->dec_na(l_key, a_data, a_data_size, l_sign, l_sign_size) > 0)
+            l_ret = 0;
+        else
+            l_ret = 1;
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        if(dap_enc_sig_bliss_verify_sign(l_key, a_data, a_data_size, l_sign, l_sign_size) != BLISS_B_NO_ERROR)
+            l_ret = 0;
+        else
+            l_ret = 1;
+        break;
+    default:
+        l_ret = -1;
     }
+    DAP_DELETE(l_sign);
+    return l_ret;
 }
 
 /**
diff --git a/dap_chain_sign.h b/dap_chain_sign.h
index a02f121da4d8c555604e3dc1bd5f57ae259e664c..d393a3fda7c5f675db86068c92403d0f72f8cf5a 100644
--- a/dap_chain_sign.h
+++ b/dap_chain_sign.h
@@ -41,7 +41,7 @@ typedef struct dap_chain_sign{
     struct {
         dap_chain_sign_type_t type; /// Signature type
         uint16_t sign_size; /// Signature size
-        uint32_t sign_pkey_size; /// Signature public key size
+        uint32_t sign_pkey_size; /// Signature serialized public key size
     } header; /// Only header's hash is used for verification
     uint8_t pkey_n_sign[]; /// @param sig @brief raw signature data
 } DAP_ALIGN_PACKED dap_chain_sign_t;
@@ -53,13 +53,16 @@ int dap_chain_sign_verify (dap_chain_sign_t * a_chain_sign, const void * a_data,
 dap_chain_sign_t * dap_chain_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size
                                          ,  size_t a_output_wish_size );
 size_t dap_chain_sign_create_output_cals_size(dap_enc_key_t * a_key,size_t a_output_wish_size );
-int dap_chain_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 );
+//int dap_chain_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 );
 
 
 dap_chain_sign_type_t dap_chain_sign_type_from_key_type( dap_enc_key_type_t a_key_type);
 dap_enc_key_type_t  dap_chain_sign_type_to_key_type(dap_chain_sign_type_t  a_chain_sign_type);
 
+uint8_t* dap_chain_sign_get_sign(dap_chain_sign_t *a_sign, size_t *a_sign_out);
+uint8_t* dap_chain_sign_get_pkey(dap_chain_sign_t *a_sign, size_t *a_pub_key_out);
+
 dap_enc_key_t *dap_chain_sign_to_enc_key(dap_chain_sign_t * a_chain_sign);
 const char * dap_chain_sign_type_to_str(dap_chain_sign_type_t a_chain_sign_type);
 dap_chain_sign_type_t dap_chain_sign_type_from_str(const char * a_type_str);
diff --git a/dap_hash.c b/dap_hash.c
index cb4396336f1e848a401de772fc78874a75f00573..ea7de00c4051e346cff98d3f8808db6b09826a6b 100644
--- a/dap_hash.c
+++ b/dap_hash.c
@@ -26,3 +26,28 @@
 #include "dap_hash.h"
 
 #define LOG_TAG "dap_hash"
+
+int dap_hash_fast(void *a_data_in, size_t a_data_in_size, dap_chain_hash_fast_t *a_hash_out)
+{
+    if(!a_data_in || !a_data_in_size || !a_hash_out)
+        return -1;
+    dap_hash(a_data_in, a_data_in_size, a_hash_out->raw, sizeof(a_hash_out->raw),
+            DAP_HASH_TYPE_KECCAK);
+    return 1;
+}
+bool dap_hash_fast_is_blank(dap_chain_hash_fast_t *a_hash)
+{
+    uint8_t *l_hast_bytes = (uint8_t*) a_hash;
+    for(int i = 0; i < sizeof(dap_chain_hash_fast_t); i++) {
+        if(l_hast_bytes[i])
+            return false;
+    }
+    return true;
+}
+
+bool dap_hash_fast_compare(dap_chain_hash_fast_t *a_hash1, dap_chain_hash_fast_t *a_hash2)
+{
+    if(!memcmp(a_hash1, a_hash2, sizeof(dap_chain_hash_fast_t)))
+        return true;
+    return false;
+}
diff --git a/dap_hash.h b/dap_hash.h
index 889a60f135d3bdd4addf5a8ad6f22fe82ccae1dd..743887c7b4417f202ebbf8c2e6b7e356d8fb76f9 100644
--- a/dap_hash.h
+++ b/dap_hash.h
@@ -23,10 +23,11 @@
 */
 #pragma once
 #include <stddef.h>
+#include <stdbool.h>
 
 #include "dap_hash_slow.h"
 #include "dap_hash_keccak.h"
-
+#include "dap_chain_common.h"
 
 
 typedef enum dap_hash_type {
@@ -49,3 +50,7 @@ inline static void dap_hash(void * a_data_in, size_t a_data_in_size,
     }
 
 }
+
+int dap_hash_fast(void *a_data_in, size_t a_data_in_size, dap_chain_hash_fast_t *a_hash_out);
+bool dap_hash_fast_is_blank(dap_chain_hash_fast_t *a_hash);
+bool dap_hash_fast_compare(dap_chain_hash_fast_t *a_hash1, dap_chain_hash_fast_t *a_hash2);