diff --git a/crypto/dap_enc_base58.c b/crypto/dap_enc_base58.c
index e04da0203e86ab31fa5bc6dfb8124853b52fed0d..0e908ff6d0f97cbfcfe69853df374bfd70347d5d 100755
--- a/crypto/dap_enc_base58.c
+++ b/crypto/dap_enc_base58.c
@@ -55,7 +55,6 @@ size_t dap_enc_base58_decode(const char * a_in, void * a_out)
     size_t l_out_size = l_out_size_max;
 
     const unsigned char *l_in_u8 = (const unsigned char*)a_in;
-    unsigned char *l_out_u8 = a_out;
     size_t l_outi_size = (l_out_size_max + 3) / 4;
 
     uint32_t l_outi[l_outi_size];
@@ -96,6 +95,8 @@ size_t dap_enc_base58_decode(const char * a_in, void * a_out)
             return 0;
     }
 
+    unsigned char l_out_u80[l_out_size_max];
+    unsigned char *l_out_u8 = l_out_u80;
     j = 0;
     switch (bytesleft) {
         case 3:
@@ -121,7 +122,7 @@ size_t dap_enc_base58_decode(const char * a_in, void * a_out)
     }
 
     // Count canonical base58 byte count
-    l_out_u8 = a_out;
+    l_out_u8 = l_out_u80;
     for (i = 0; i < l_out_size_max; ++i)
     {
         if (l_out_u8[i]) {
@@ -135,11 +136,13 @@ size_t dap_enc_base58_decode(const char * a_in, void * a_out)
     }
 
 
+    unsigned char *l_out = a_out;
+    memset(l_out, 0, zerocount);
     // shift result to beginning of the string
     for (j = 0; j < l_out_size; j++){
-        l_out_u8[j+zerocount] = l_out_u8[j+i];
+        l_out[j+zerocount] = l_out_u8[j+i];
     }
-    l_out_u8[j+zerocount] = 0;
+    l_out[j+zerocount] = 0;
     l_out_size += zerocount;
 
     return l_out_size;
@@ -183,7 +186,7 @@ size_t dap_enc_base58_encode(const void * a_in, size_t a_in_size, char * a_out)
         memset(a_out, '1', zcount);
     for (i = zcount; j < (ssize_t)size; ++i, ++j)
         a_out[i] = c_b58digits_ordered[buf[j]];
-    a_out[i] = '\0';
+    a_out[i+zcount] = '\0';
     l_out_size = i + 1;
 
     return l_out_size;
diff --git a/crypto/dap_enc_bliss.c b/crypto/dap_enc_bliss.c
index e2b103a1182f858b32a145286c68c948f9247382..9f167c609a4c07e3f6e67b4fd1e7fbd27357f3c5 100644
--- a/crypto/dap_enc_bliss.c
+++ b/crypto/dap_enc_bliss.c
@@ -1,3 +1,4 @@
+#include <stdint.h>
 #include <assert.h>
 #include <inttypes.h>
 #include <string.h>
@@ -43,28 +44,29 @@ int dap_enc_sig_bliss_key_pub_output(struct dap_enc_key *l_key, void * l_output)
 {
     int32_t retcode;
 
-    retcode = bliss_b_public_key_extract( (bliss_public_key_t *) l_output,
-                                          (const bliss_private_key_t *) l_key->priv_key_data);
-    if (retcode != BLISS_B_NO_ERROR) {
+    retcode = bliss_b_public_key_extract((bliss_public_key_t *) l_output,
+            (const bliss_private_key_t *) l_key->priv_key_data);
+    if(retcode != BLISS_B_NO_ERROR) {
         log_it(L_CRITICAL, "Can't extract public key from the private one");
         return -1;
     }
     return 0;
 }
 
-
 // generation key pair for sign Alice
 // OUTPUT:
 // a_key->data  --- Alice's public key
 // alice_priv  ---  Alice's private key
 // alice_msg_len --- Alice's private key length
 void dap_enc_sig_bliss_key_new_generate(struct dap_enc_key * a_key, const void *kex_buf,
-                                    size_t kex_size, const void * seed, size_t seed_size,
-                                    size_t key_size)
+        size_t kex_size, const void * seed, size_t seed_size,
+        size_t key_size)
 {
-    (void) kex_buf; (void) kex_size;
-    (void) seed; (void) seed_size;
-    (void)key_size;
+    (void) kex_buf;
+    (void) kex_size;
+    (void) seed;
+    (void) seed_size;
+    (void) key_size;
 
     int32_t l_retcode;
 
@@ -72,8 +74,8 @@ void dap_enc_sig_bliss_key_new_generate(struct dap_enc_key * a_key, const void *
 
     uint8_t seed_tmp[SHA3_512_DIGEST_LENGTH];
     entropy_t entropy;
-    randombytes( &seed_tmp, 64);
-    entropy_init( &entropy, seed_tmp);
+    randombytes(&seed_tmp, 64);
+    entropy_init(&entropy, seed_tmp);
 
     /* type is a param of sign-security
      * type = 0 - "toy" version                (< 60 bits)
@@ -81,12 +83,12 @@ void dap_enc_sig_bliss_key_new_generate(struct dap_enc_key * a_key, const void *
      * type = 2 - min size                     (128 bits)
      * type = 3 - good speed and good security (160 bits)
      * type = 4 - max securiry                 (192 bits)
-    */
+     */
     //int32_t type = 4;
     a_key->priv_key_data_size = sizeof(bliss_private_key_t);
-    a_key->priv_key_data = DAP_NEW_SIZE(void,a_key->priv_key_data_size);
+    a_key->priv_key_data = DAP_NEW_SIZE(void, a_key->priv_key_data_size);
     l_retcode = bliss_b_private_key_gen((bliss_private_key_t *) a_key->priv_key_data, _bliss_type, &entropy);
-    if (l_retcode != BLISS_B_NO_ERROR) {
+    if(l_retcode != BLISS_B_NO_ERROR) {
         bliss_b_private_key_delete(a_key->priv_key_data);
         a_key->priv_key_data = NULL;
         a_key->priv_key_data_size = 0;
@@ -95,9 +97,10 @@ void dap_enc_sig_bliss_key_new_generate(struct dap_enc_key * a_key, const void *
     }
 
     a_key->pub_key_data_size = sizeof(bliss_public_key_t);
-    a_key->pub_key_data = DAP_NEW_SIZE(void,a_key->pub_key_data_size );
-    l_retcode = bliss_b_public_key_extract( (bliss_public_key_t *) a_key->pub_key_data, (const bliss_private_key_t *) a_key->priv_key_data);
-    if (l_retcode != BLISS_B_NO_ERROR) {
+    a_key->pub_key_data = DAP_NEW_SIZE(void, a_key->pub_key_data_size);
+    l_retcode = bliss_b_public_key_extract((bliss_public_key_t *) a_key->pub_key_data,
+            (const bliss_private_key_t *) a_key->priv_key_data);
+    if(l_retcode != BLISS_B_NO_ERROR) {
         bliss_b_private_key_delete(a_key->priv_key_data);
         bliss_b_public_key_delete(a_key->pub_key_data);
         log_it(L_CRITICAL, "Error");
@@ -105,11 +108,10 @@ void dap_enc_sig_bliss_key_new_generate(struct dap_enc_key * a_key, const void *
     }
 }
 
-
-int dap_enc_sig_bliss_get_sign(struct dap_enc_key * key,const void * msg,
-                                  const size_t msg_size, void * signature, const size_t signature_size)
+int dap_enc_sig_bliss_get_sign(struct dap_enc_key * key, const void * msg,
+        const size_t msg_size, void * signature, const size_t signature_size)
 {
-    if(signature_size < sizeof (bliss_signature_t)) {
+    if(signature_size < sizeof(bliss_signature_t)) {
         log_it(L_ERROR, "bad signature size");
         return 0;
     }
@@ -118,17 +120,17 @@ int dap_enc_sig_bliss_get_sign(struct dap_enc_key * key,const void * msg,
     randombytes(&seed_tmp, 64);
     entropy_init(&entropy, seed_tmp);
 
-    return bliss_b_sign((bliss_signature_t *)signature,
-                        (const bliss_private_key_t *)key->priv_key_data,
-                        (const uint8_t *)msg,
-                        msg_size,
-                        &entropy);
+    return bliss_b_sign((bliss_signature_t *) signature,
+            (const bliss_private_key_t *) key->priv_key_data,
+            (const uint8_t *) msg,
+            msg_size,
+            &entropy);
 }
 
-int dap_enc_sig_bliss_verify_sign(struct dap_enc_key * key,const void * msg,
-                                     const size_t msg_size, void * signature, const size_t signature_size)
+int dap_enc_sig_bliss_verify_sign(struct dap_enc_key * key, const void * msg,
+        const size_t msg_size, void * signature, const size_t signature_size)
 {
-    if(signature_size < sizeof (bliss_signature_t)) {
+    if(signature_size < sizeof(bliss_signature_t)) {
         log_it(L_ERROR, "bad signature size");
         return -1;
     }
@@ -141,4 +143,160 @@ void dap_enc_sig_bliss_key_delete(struct dap_enc_key *key)
     bliss_b_public_key_delete(key->pub_key_data);
 }
 
+/* Serialize a signature */
+uint8_t* dap_enc_sig_bliss_write_signature(bliss_signature_t* a_sign, size_t *a_sign_out)
+{
+    bliss_param_t p;
+    if(!bliss_params_init(&p, a_sign->kind)) {
+        return NULL ;
+    }
+    size_t l_shift_mem = 0;
+    size_t l_buflen = sizeof(size_t) + sizeof(bliss_kind_t) + p.n * 2 * sizeof(int32_t) + p.kappa * sizeof(int32_t);
+
+    uint8_t *l_buf = DAP_NEW_SIZE(uint8_t, l_buflen);
+    memcpy(l_buf, &l_buflen, sizeof(size_t));
+    l_shift_mem += sizeof(size_t);
+    memcpy(l_buf + l_shift_mem, &a_sign->kind, sizeof(bliss_kind_t));
+    l_shift_mem += sizeof(bliss_kind_t);
+    memcpy(l_buf + l_shift_mem, a_sign->z1, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    memcpy(l_buf + l_shift_mem, a_sign->z2, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    memcpy(l_buf + l_shift_mem, a_sign->c, p.kappa * sizeof(int32_t));
+    l_shift_mem += p.kappa * sizeof(int32_t);
+
+    if(a_sign_out)
+        *a_sign_out = l_buflen;
+    return l_buf;
+}
+
+/* Deserialize a signature */
+bliss_signature_t* dap_enc_sig_bliss_read_signature(uint8_t *a_buf, size_t a_buflen)
+{
+    if(!a_buf || a_buflen < (sizeof(size_t) + sizeof(bliss_kind_t)))
+        return NULL ;
+    bliss_kind_t kind;
+    size_t l_buflen = 0;
+    memcpy(&l_buflen, a_buf, sizeof(size_t));
+    memcpy(&kind, a_buf + sizeof(size_t), sizeof(bliss_kind_t));
+    if(l_buflen != a_buflen)
+        return NULL ;
+    bliss_param_t p;
+    if(!bliss_params_init(&p, kind))
+        return NULL ;
+
+    bliss_signature_t* l_sign = DAP_NEW(bliss_signature_t);
+    l_sign->kind = kind;
+    l_sign->z1 = DAP_NEW_SIZE(int32_t, p.n * sizeof(int32_t));
+    l_sign->z2 = DAP_NEW_SIZE(int32_t, p.n * sizeof(int32_t));
+    l_sign->c = DAP_NEW_SIZE(uint32_t, p.kappa * sizeof(int32_t));
+    size_t l_shift_mem = sizeof(size_t) + sizeof(bliss_kind_t);
+    memcpy(l_sign->z1, a_buf + l_shift_mem, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    memcpy(l_sign->z2, a_buf + l_shift_mem, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    memcpy(l_sign->c, a_buf + l_shift_mem, p.kappa * sizeof(int32_t));
+    l_shift_mem += p.kappa * sizeof(int32_t);
+    return l_sign;
+}
 
+/* Serialize a private key. */
+uint8_t* dap_enc_sig_bliss_write_private_key(const bliss_private_key_t* a_private_key, size_t *a_buflen_out)
+{
+    bliss_param_t p;
+    if(!bliss_params_init(&p, a_private_key->kind)) {
+        return NULL;
+    }
+    size_t l_shift_mem = 0;
+    size_t l_buflen = sizeof(size_t) + sizeof(bliss_kind_t) + 3 * p.n * sizeof(int32_t);
+    uint8_t *l_buf = DAP_NEW_SIZE(uint8_t, l_buflen);
+    memcpy(l_buf, &l_buflen, sizeof(size_t));
+    l_shift_mem += sizeof(size_t);
+    memcpy(l_buf + l_shift_mem, &a_private_key->kind, sizeof(bliss_kind_t));
+    l_shift_mem += sizeof(bliss_kind_t);
+    memcpy(l_buf + l_shift_mem, a_private_key->s1, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    memcpy(l_buf + l_shift_mem, a_private_key->s2, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    memcpy(l_buf + l_shift_mem, a_private_key->a, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    if(a_buflen_out)
+        *a_buflen_out = l_buflen;
+    return l_buf;
+}
+
+/* Serialize a public key. */
+uint8_t* dap_enc_sig_bliss_write_public_key(const bliss_public_key_t* a_public_key, size_t *a_buflen_out)
+{
+    bliss_param_t p;
+
+    if(!bliss_params_init(&p, a_public_key->kind)) {
+        return NULL;
+    }
+
+    size_t l_shift_mem = 0;
+    size_t l_buflen = sizeof(size_t) + sizeof(bliss_kind_t) + p.n * sizeof(int32_t);
+    uint8_t *l_buf = DAP_NEW_SIZE(uint8_t, l_buflen);
+    memcpy(l_buf, &l_buflen, sizeof(size_t));
+    l_shift_mem += sizeof(size_t);
+    memcpy(l_buf + l_shift_mem, &a_public_key->kind, sizeof(bliss_kind_t));
+    l_shift_mem += sizeof(bliss_kind_t);
+    memcpy(l_buf + l_shift_mem, a_public_key->a, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    if(a_buflen_out)
+        *a_buflen_out = l_buflen;
+    return l_buf;
+}
+
+/* Deserialize a private key. */
+bliss_private_key_t* dap_enc_sig_bliss_read_private_key(uint8_t *a_buf, size_t a_buflen)
+{
+    if(!a_buf || a_buflen < (sizeof(size_t) + sizeof(bliss_kind_t)))
+        return NULL;
+    bliss_kind_t kind;
+    size_t l_buflen = 0;
+    memcpy(&l_buflen, a_buf, sizeof(size_t));
+    memcpy(&kind, a_buf + sizeof(size_t), sizeof(bliss_kind_t));
+    if(l_buflen != a_buflen)
+        return NULL;
+    bliss_param_t p;
+    if(!bliss_params_init(&p, kind))
+        return NULL;
+
+    bliss_private_key_t* l_private_key = DAP_NEW(bliss_private_key_t);
+    l_private_key->kind = kind;
+
+    l_private_key->s1 = DAP_NEW_SIZE(int32_t, p.n * sizeof(int32_t));
+    l_private_key->s2 = DAP_NEW_SIZE(int32_t, p.n * sizeof(int32_t));
+    l_private_key->a  = DAP_NEW_SIZE(int32_t, p.n * sizeof(int32_t));
+    size_t l_shift_mem = sizeof(size_t) + sizeof(bliss_kind_t);
+    memcpy(l_private_key->s1, a_buf + l_shift_mem, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    memcpy(l_private_key->s2, a_buf + l_shift_mem, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    memcpy(l_private_key->a, a_buf + l_shift_mem, p.n * sizeof(int32_t));
+    l_shift_mem += p.n * sizeof(int32_t);
+    return l_private_key;
+}
+
+/* Deserialize a public key. */
+bliss_public_key_t* dap_enc_sig_bliss_read_public_key(uint8_t *a_buf, size_t a_buflen)
+{
+    if(!a_buf || a_buflen < (sizeof(size_t) + sizeof(bliss_kind_t)))
+        return NULL;
+    bliss_kind_t kind;
+    size_t l_buflen = 0;
+    memcpy(&l_buflen, a_buf, sizeof(size_t));
+    memcpy(&kind, a_buf + sizeof(size_t), sizeof(bliss_kind_t));
+    if(l_buflen != a_buflen)
+        return NULL;
+    bliss_param_t p;
+    if(!bliss_params_init(&p, kind))
+        return NULL;
+    bliss_public_key_t* l_public_key = DAP_NEW(bliss_public_key_t);
+    l_public_key->kind = kind;
+
+    l_public_key->a = DAP_NEW_SIZE(int32_t, p.n * sizeof(int32_t));
+    memcpy(l_public_key->a, a_buf + sizeof(size_t) + sizeof(bliss_kind_t), p.n * sizeof(int32_t));
+    return l_public_key;
+}
diff --git a/crypto/dap_enc_bliss.h b/crypto/dap_enc_bliss.h
index 122b3fbb2d50d88f350cc14f1d4e576969ba195f..49c0d7af8439416f21b58510a4d691d566e5bd17 100644
--- a/crypto/dap_enc_bliss.h
+++ b/crypto/dap_enc_bliss.h
@@ -26,3 +26,12 @@ void dap_enc_sig_bliss_key_delete(struct dap_enc_key *key);
 size_t dap_enc_sig_bliss_key_pub_output_size(struct dap_enc_key *l_key);
 int dap_enc_sig_bliss_key_pub_output(struct dap_enc_key *l_key, void * l_output);
 
+
+uint8_t* dap_enc_sig_bliss_write_signature(bliss_signature_t* a_sign, size_t *a_sign_out);
+bliss_signature_t* dap_enc_sig_bliss_read_signature(uint8_t *a_buf, size_t a_buflen);
+uint8_t* dap_enc_sig_bliss_write_private_key(const bliss_private_key_t* a_private_key, size_t *a_buflen_out);
+uint8_t* dap_enc_sig_bliss_write_public_key(const bliss_public_key_t* a_public_key, size_t *a_buflen_out);
+bliss_private_key_t* dap_enc_sig_bliss_read_private_key(uint8_t *a_buf, size_t a_buflen);
+bliss_public_key_t* dap_enc_sig_bliss_read_public_key(uint8_t *a_buf, size_t a_buflen);
+
+
diff --git a/crypto/dap_enc_key.c b/crypto/dap_enc_key.c
index e350df611c1dc8c52e2aa0c1b49af81aee02c39f..e06bec89c567f1246ff374025ee2503841a00f95 100755
--- a/crypto/dap_enc_key.c
+++ b/crypto/dap_enc_key.c
@@ -204,6 +204,214 @@ void dap_enc_key_deinit()
 
 }
 
+/**
+ * @brief dap_enc_key_serealize_sign
+ *
+ * @param a_key_type
+ * @param a_sign
+ * @param a_sign_len [in/out]
+ * @return allocates memory with private key
+ */
+uint8_t* dap_enc_key_serealize_sign(dap_enc_key_type_t a_key_type, uint8_t *a_sign, size_t *a_sign_len)
+{
+    uint8_t *data = NULL;
+    switch (a_key_type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        data = dap_enc_sig_bliss_write_signature((bliss_signature_t*)a_sign, a_sign_len);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        data = dap_enc_tesla_write_signature((tesla_signature_t*)a_sign, a_sign_len);
+        break;
+    default:
+        data = DAP_NEW_Z_SIZE(uint8_t, *a_sign_len);
+        memcpy(data, a_sign, *a_sign_len);
+    }
+    return data;
+}
+
+/**
+ * @brief dap_enc_key_serealize_sign
+ *
+ * @param a_key_type
+ * @param a_sign
+ * @param a_sign_len [in/out]
+ * @return allocates memory with private key
+ */
+uint8_t* dap_enc_key_deserealize_sign(dap_enc_key_type_t a_key_type, uint8_t *a_sign, size_t *a_sign_len)
+{
+    uint8_t *data = NULL;
+    switch (a_key_type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        data = (uint8_t*)dap_enc_sig_bliss_read_signature(a_sign, *a_sign_len);
+        *a_sign_len = sizeof(bliss_signature_t);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        data = (uint8_t*)dap_enc_tesla_read_signature(a_sign, *a_sign_len);
+        *a_sign_len = sizeof(tesla_signature_t);
+        break;
+    default:
+        data = DAP_NEW_Z_SIZE(uint8_t, *a_sign_len);
+        memcpy(data, a_sign, *a_sign_len);
+    }
+    return data;
+}
+
+
+/**
+ * @brief dap_enc_key_serealize_priv_key
+ *
+ * @param a_key
+ * @param a_buflen_out
+ * @return allocates memory with private key
+ */
+uint8_t* dap_enc_key_serealize_priv_key(dap_enc_key_t *a_key, size_t *a_buflen_out)
+{
+    uint8_t *data = NULL;
+    switch (a_key->type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        data = dap_enc_sig_bliss_write_private_key(a_key->priv_key_data, a_buflen_out);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        data = dap_enc_tesla_write_private_key(a_key->priv_key_data, a_buflen_out);
+        break;
+    default:
+        data = DAP_NEW_Z_SIZE(uint8_t, a_key->priv_key_data_size);
+        memcpy(data, a_key->priv_key_data, a_key->priv_key_data_size);
+        if(a_buflen_out)
+            *a_buflen_out = a_key->priv_key_data_size;
+    }
+    return data;
+}
+
+/**
+ * @brief dap_enc_key_serealize_pub_key
+ *
+ * @param a_key
+ * @param a_buflen_out
+ * @return allocates memory with private key
+ */
+uint8_t* dap_enc_key_serealize_pub_key(dap_enc_key_t *a_key, size_t *a_buflen_out)
+{
+    uint8_t *data = NULL;
+    switch (a_key->type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        data = dap_enc_sig_bliss_write_public_key(a_key->pub_key_data, a_buflen_out);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        data = dap_enc_tesla_write_public_key(a_key->pub_key_data, a_buflen_out);
+        break;
+    default:
+        data = DAP_NEW_Z_SIZE(uint8_t, a_key->pub_key_data_size);
+        memcpy(data, a_key->pub_key_data, a_key->pub_key_data_size);
+        if(a_buflen_out)
+            *a_buflen_out = a_key->pub_key_data_size;
+    }
+    return data;
+}
+/**
+ * @brief dap_enc_key_deserealize_priv_key
+ *
+ * @param a_key
+ * @param a_buf
+ * @param a_buflen_out
+ * @return 0 Ok, -1 error
+ */
+int dap_enc_key_deserealize_priv_key(dap_enc_key_t *a_key, uint8_t *a_buf, size_t a_buflen)
+{
+    if(!a_key || !a_buf)
+        return -1;
+    switch (a_key->type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        if((a_key->priv_key_data)) {
+            bliss_b_private_key_delete((bliss_private_key_t *) a_key->priv_key_data);
+            DAP_DELETE(a_key->pub_key_data);
+        }
+        a_key->priv_key_data = (uint8_t*) dap_enc_sig_bliss_read_private_key(a_buf, a_buflen);
+        if(!a_key->priv_key_data)
+        {
+            a_key->priv_key_data_size = 0;
+            return -1;
+        }
+        a_key->priv_key_data_size = sizeof(bliss_private_key_t);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        tesla_private_key_delete((tesla_private_key_t *) a_key->priv_key_data);
+        a_key->priv_key_data = (uint8_t*) dap_enc_tesla_read_private_key(a_buf, a_buflen);
+        if(!a_key->priv_key_data)
+        {
+            a_key->priv_key_data_size = 0;
+            return -1;
+        }
+        a_key->priv_key_data_size = sizeof(tesla_private_key_t);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+        DAP_DELETE(a_key->priv_key_data);
+        a_key->priv_key_data_size = a_buflen;
+        a_key->priv_key_data = DAP_NEW_Z_SIZE(uint8_t, a_key->priv_key_data_size);
+        memcpy(a_key->priv_key_data, a_buf, a_key->priv_key_data_size);
+        dap_enc_sig_picnic_update(a_key);
+        break;
+    default:
+        DAP_DELETE(a_key->priv_key_data);
+        a_key->priv_key_data_size = a_buflen;
+        a_key->priv_key_data = DAP_NEW_Z_SIZE(uint8_t, a_key->priv_key_data_size);
+        memcpy(a_key->priv_key_data, a_buf, a_key->priv_key_data_size);
+    }
+    return 0;
+}
+
+/**
+ * @brief dap_enc_key_deserealize_pub_key
+ *
+ * @param a_key
+ * @param a_buf
+ * @param a_buflen_out
+ * @return 0 Ok, -1 error
+ */
+int dap_enc_key_deserealize_pub_key(dap_enc_key_t *a_key, uint8_t *a_buf, size_t a_buflen)
+{
+    if(!a_key || !a_buf)
+        return -1;
+    switch (a_key->type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        if((a_key->pub_key_data)) {
+            bliss_b_public_key_delete((bliss_public_key_t *) a_key->pub_key_data);
+            DAP_DELETE(a_key->pub_key_data);
+        }
+        a_key->pub_key_data = (uint8_t*) dap_enc_sig_bliss_read_public_key(a_buf, a_buflen);
+        if(!a_key->pub_key_data)
+        {
+            a_key->pub_key_data_size = 0;
+            return -1;
+        }
+        a_key->pub_key_data_size = sizeof(bliss_public_key_t);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        tesla_public_key_delete((tesla_public_key_t *) a_key->pub_key_data);
+        a_key->pub_key_data = (uint8_t*) dap_enc_tesla_read_public_key(a_buf, a_buflen);
+        if(!a_key->pub_key_data)
+        {
+            a_key->pub_key_data_size = 0;
+            return -1;
+        }
+        a_key->pub_key_data_size = sizeof(tesla_public_key_t);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+        DAP_DELETE(a_key->pub_key_data);
+        a_key->pub_key_data_size = a_buflen;
+        a_key->pub_key_data = DAP_NEW_Z_SIZE(uint8_t, a_key->pub_key_data_size);
+        memcpy(a_key->pub_key_data, a_buf, a_key->pub_key_data_size);
+        dap_enc_sig_picnic_update(a_key);
+        break;
+    default:
+        DAP_DELETE(a_key->pub_key_data);
+        a_key->pub_key_data_size = a_buflen;
+        a_key->pub_key_data = DAP_NEW_Z_SIZE(uint8_t, a_key->pub_key_data_size);
+        memcpy(a_key->pub_key_data, a_buf, a_key->pub_key_data_size);
+    }
+    return 0;
+}
+
 /**
  * @brief dap_enc_key_serealize
  * @param key
@@ -294,6 +502,26 @@ dap_enc_key_t *dap_enc_key_new_generate(dap_enc_key_type_t a_key_type, const voi
     return ret;
 }
 
+/**
+ * @brief dap_enc_key_update
+ * @param a_key_type
+ * @return
+ */
+void dap_enc_key_update(dap_enc_key_t *a_key)
+{
+    if(a_key)
+        switch (a_key->type) {
+        case DAP_ENC_KEY_TYPE_SIG_TESLA:
+            break;
+        case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+            dap_enc_sig_picnic_update(a_key);
+            break;
+        case DAP_ENC_KEY_TYPE_SIG_BLISS:
+            break;
+        default:
+            break;
+        }
+}
 
 size_t dap_enc_gen_key_public_size (dap_enc_key_t *a_key)
 {
@@ -315,6 +543,25 @@ int dap_enc_gen_key_public (dap_enc_key_t *a_key, void * a_output)
     return -1;
 }
 
+/**
+ * @brief dap_enc_key_delete
+ * @param a_key
+ */
+void dap_enc_key_signature_delete(dap_enc_key_type_t a_key_type, uint8_t *a_sig_buf)
+{
+    switch (a_key_type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        bliss_signature_delete((bliss_signature_t*)a_sig_buf);
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        tesla_signature_delete((tesla_signature_t*)a_sig_buf);
+        break;
+    default:
+        break;
+    }
+    DAP_DELETE(a_sig_buf);
+}
+
 /**
  * @brief dap_enc_key_delete
  * @param a_key
@@ -327,10 +574,9 @@ void dap_enc_key_delete(dap_enc_key_t * a_key)
         log_it(L_ERROR, "delete callback is null. Can be leak memory!");
     }
     /* a_key->_inheritor must be cleaned in delete_callback func */
-
-    free(a_key->pub_key_data);
-    free(a_key->priv_key_data);
-    free(a_key);
+    DAP_DELETE(a_key->pub_key_data);
+    DAP_DELETE(a_key->priv_key_data);
+    DAP_DELETE(a_key);
 }
 
 size_t dap_enc_key_get_enc_size(dap_enc_key_t * a_key, const size_t buf_in_size)
diff --git a/crypto/dap_enc_key.h b/crypto/dap_enc_key.h
index e27a635895414a9f7c83e68532b4fd5ca06177cf..11cc5dfe69d4ba7fd394f36d8de81b895ed4b6ac 100755
--- a/crypto/dap_enc_key.h
+++ b/crypto/dap_enc_key.h
@@ -221,6 +221,13 @@ void dap_enc_key_deinit(void);
 size_t dap_enc_key_get_enc_size(dap_enc_key_t * a_key, const size_t buf_in_size);
 size_t dap_enc_key_get_dec_size(dap_enc_key_t * a_key, const size_t buf_in_size);
 
+uint8_t* dap_enc_key_serealize_sign(dap_enc_key_type_t a_key_type, uint8_t *a_sign, size_t *a_sign_len);
+uint8_t* dap_enc_key_deserealize_sign(dap_enc_key_type_t a_key_type, uint8_t *a_sign, size_t *a_sign_len);
+uint8_t* dap_enc_key_serealize_priv_key(dap_enc_key_t *a_key, size_t *a_buflen_out);
+uint8_t* dap_enc_key_serealize_pub_key(dap_enc_key_t *a_key, size_t *a_buflen_out);
+int dap_enc_key_deserealize_priv_key(dap_enc_key_t *a_key, uint8_t *a_buf, size_t a_buflen);
+int dap_enc_key_deserealize_pub_key(dap_enc_key_t *a_key, uint8_t *a_buf, size_t a_buflen);
+
 dap_enc_key_serealize_t* dap_enc_key_serealize(dap_enc_key_t * key);
 dap_enc_key_t* dap_enc_key_deserealize(void *buf, size_t buf_size);
 
@@ -233,6 +240,9 @@ dap_enc_key_t *dap_enc_key_new_generate(dap_enc_key_type_t key_type, const void
                                                       size_t kex_size, const void* seed,
                                                       size_t seed_size, size_t key_size);
 
+// update struct dap_enc_key_t after insert foreign keys
+void dap_enc_key_update(dap_enc_key_t *a_key);
+
 // for asymmetric gen public key
 dap_enc_key_t *dap_enc_gen_pub_key_from_priv(struct dap_enc_key *a_key, void **priv_key, size_t *alice_msg_len);
 
@@ -240,6 +250,7 @@ dap_enc_key_t *dap_enc_gen_pub_key_from_priv(struct dap_enc_key *a_key, void **p
 size_t dap_enc_gen_key_public_size (dap_enc_key_t *a_key);
 int dap_enc_gen_key_public (dap_enc_key_t *a_key, void * a_output);
 
+void dap_enc_key_signature_delete(dap_enc_key_type_t a_key_type, uint8_t *a_sig_buf);
 void dap_enc_key_delete(dap_enc_key_t * a_key);
 
 #ifdef __cplusplus
diff --git a/crypto/dap_enc_picnic.c b/crypto/dap_enc_picnic.c
index b13116d2ceaa9ce11818b620c22206adb23c6123..437699958dfcab5565fdb18a06bf4f017746de36 100755
--- a/crypto/dap_enc_picnic.c
+++ b/crypto/dap_enc_picnic.c
@@ -16,8 +16,12 @@
 static void set_picnic_params_t(struct dap_enc_key *key)
 {
     picnic_params_t *param = (key) ? (picnic_params_t*) key->_inheritor : NULL;
-    if(param && key->_inheritor_size == sizeof(picnic_params_t))
+    if(param && key->_inheritor_size == sizeof(picnic_params_t)){
+        if(key->priv_key_data)
         *param = ((picnic_privatekey_t*) key->priv_key_data)->params;
+        else if(key->pub_key_data)
+            *param = ((picnic_publickey_t*) key->pub_key_data)->params;
+    }
 }
 
 /**
@@ -65,6 +69,15 @@ void dap_enc_sig_picnic_key_delete(struct dap_enc_key *key)
     key->pub_key_data_size = 0;
 }
 
+void dap_enc_sig_picnic_update(struct dap_enc_key * a_key)
+{
+    if(a_key) {
+        if(!a_key->priv_key_data ||
+           !picnic_validate_keypair((picnic_privatekey_t *) a_key->priv_key_data, (picnic_publickey_t *) a_key->pub_key_data))
+            set_picnic_params_t(a_key);
+    }
+}
+
 void dap_enc_sig_picnic_key_new_generate(struct dap_enc_key * key, const void *kex_buf, size_t kex_size,
         const void * seed, size_t seed_size, size_t key_size)
 {
@@ -80,8 +93,8 @@ void dap_enc_sig_picnic_key_new_generate(struct dap_enc_key * key, const void *k
 
     key->priv_key_data_size = sizeof(picnic_privatekey_t);
     key->pub_key_data_size = sizeof(picnic_publickey_t);
-    key->priv_key_data = malloc(key->priv_key_data_size);
-    key->pub_key_data = malloc(key->pub_key_data_size);
+    key->priv_key_data = calloc(1, key->priv_key_data_size);
+    key->pub_key_data = calloc(1, key->pub_key_data_size);
 
     picnic_keys_gen((picnic_privatekey_t *) key->priv_key_data, (picnic_publickey_t *) key->pub_key_data, parameters);
     if(!picnic_validate_keypair((picnic_privatekey_t *) key->priv_key_data, (picnic_publickey_t *) key->pub_key_data))
@@ -168,3 +181,32 @@ size_t dap_enc_sig_picnic_verify_sign(struct dap_enc_key * key, const void* mess
     return 0;
 }
 
+/*
+uint8_t* dap_enc_sig_picnic_write_public_key(struct dap_enc_key * a_key, size_t *a_buflen_out)
+{
+    const picnic_publickey_t *l_key = a_key->pub_key_data;
+    size_t buflen = picnic_get_public_key_size(l_key); // Get public key size for serialize
+    uint8_t* l_buf = DAP_NEW_SIZE(uint8_t, buflen);
+    // Serialize public key
+    if(picnic_write_public_key(l_key, l_buf, buflen)>0){
+        if(a_buflen_out)
+            *a_buflen_out = buflen;
+        return l_buf;
+    }
+    return NULL;
+}
+
+uint8_t* dap_enc_sig_picnic_read_public_key(struct dap_enc_key * a_key, uint8_t a_buf, size_t *a_buflen)
+{
+   const picnic_publickey_t *l_key = a_key->pub_key_data;
+    size_t buflen = picnic_get_public_key_size(l_key);  Get public key size for serialize
+    uint8_t* l_buf = DAP_NEW_SIZE(uint8_t, buflen);
+    // Deserialize public key
+    if(!picnic_read_public_key(l_key, a_l_buf, buflen)>0){
+        if(a_buflen_out)
+            *a_buflen_out = buflen;
+        return l_buf;
+    }
+    return NULL;
+}*/
+
diff --git a/crypto/dap_enc_picnic.h b/crypto/dap_enc_picnic.h
index 7338b6a40e741ce4f886d17e1d4ea5fe856f4613..5f2623039ce48a944a7b2a7e710e550d5878d2ae 100755
--- a/crypto/dap_enc_picnic.h
+++ b/crypto/dap_enc_picnic.h
@@ -37,6 +37,8 @@ void dap_enc_sig_picnic_key_new(struct dap_enc_key *key);
 
 void dap_enc_sig_picnic_key_delete(struct dap_enc_key *key);
 
+void dap_enc_sig_picnic_update(struct dap_enc_key * key);
+
 void dap_enc_sig_picnic_key_new_generate(struct dap_enc_key * key, const void *kex_buf, size_t kex_size,
         const void * seed, size_t seed_size,
         size_t key_size);
diff --git a/crypto/dap_enc_tesla.c b/crypto/dap_enc_tesla.c
index 3e23ed6552ccea47700bb43e7de48aba2b05f29e..484ed19cb5903ed11ee688c8240f259ed7ddabbe 100755
--- a/crypto/dap_enc_tesla.c
+++ b/crypto/dap_enc_tesla.c
@@ -103,3 +103,130 @@ size_t dap_enc_tesla_calc_signature_size(void)
     return sizeof(tesla_signature_t);
 }
 
+/* Serialize a signature */
+uint8_t* dap_enc_tesla_write_signature(tesla_signature_t* a_sign, size_t *a_sign_out)
+{
+    if(!a_sign || *a_sign_out!=sizeof(tesla_signature_t)) {
+        return NULL ;
+    }
+    size_t l_shift_mem = 0;
+    size_t l_buflen = sizeof(size_t) + sizeof(tesla_kind_t) + a_sign->sig_len + sizeof(unsigned long long);
+
+    uint8_t *l_buf = DAP_NEW_SIZE(uint8_t, l_buflen);
+    memcpy(l_buf, &l_buflen, sizeof(size_t));
+    l_shift_mem += sizeof(size_t);
+    memcpy(l_buf + l_shift_mem, &a_sign->kind, sizeof(tesla_kind_t));
+    l_shift_mem += sizeof(tesla_kind_t);
+    memcpy(l_buf + l_shift_mem, &a_sign->sig_len, sizeof(unsigned long long));
+    l_shift_mem += sizeof(unsigned long long);
+    memcpy(l_buf + l_shift_mem, a_sign->sig_data, a_sign->sig_len );
+    l_shift_mem += a_sign->sig_len ;
+
+    if(a_sign_out)
+        *a_sign_out = l_buflen;
+    return l_buf;
+}
+
+/* Deserialize a signature */
+tesla_signature_t* dap_enc_tesla_read_signature(uint8_t *a_buf, size_t a_buflen)
+{
+    if(!a_buf || a_buflen < (sizeof(size_t) + sizeof(tesla_kind_t)))
+        return NULL ;
+    tesla_kind_t kind;
+    size_t l_buflen = 0;
+    memcpy(&l_buflen, a_buf, sizeof(size_t));
+    memcpy(&kind, a_buf + sizeof(size_t), sizeof(tesla_kind_t));
+    if(l_buflen != a_buflen)
+        return NULL ;
+    tesla_param_t p;
+    if(!tesla_params_init(&p, kind))
+        return NULL ;
+
+    tesla_signature_t* l_sign = DAP_NEW(tesla_signature_t);
+    l_sign->kind = kind;
+    size_t l_shift_mem = sizeof(size_t) + sizeof(tesla_kind_t);
+    memcpy(&l_sign->sig_len, a_buf + l_shift_mem, sizeof(unsigned long long));
+    l_shift_mem += sizeof(unsigned long long);
+    l_sign->sig_data = DAP_NEW_SIZE(unsigned char, l_sign->sig_len);
+    memcpy(l_sign->sig_data, a_buf + l_shift_mem, l_sign->sig_len);
+    l_shift_mem += l_sign->sig_len;
+    return l_sign;
+}
+
+/* Serialize a private key. */
+uint8_t* dap_enc_tesla_write_private_key(const tesla_private_key_t* a_private_key, size_t *a_buflen_out)
+{
+    tesla_param_t p;// = malloc(sizeof(tesla_param_t));
+    if(!tesla_params_init(&p, a_private_key->kind))
+        return NULL;
+
+    size_t l_buflen = sizeof(size_t) + sizeof(tesla_kind_t) + p.CRYPTO_SECRETKEYBYTES; //CRYPTO_PUBLICKEYBYTES;
+    uint8_t *l_buf = DAP_NEW_SIZE(uint8_t, l_buflen);
+    memcpy(l_buf, &l_buflen, sizeof(size_t));
+    memcpy(l_buf + sizeof(size_t), &a_private_key->kind, sizeof(tesla_kind_t));
+    memcpy(l_buf + sizeof(size_t) + sizeof(tesla_kind_t), a_private_key->data, p.CRYPTO_SECRETKEYBYTES);
+    if(a_buflen_out)
+        *a_buflen_out = l_buflen;
+    return l_buf;
+}
+
+/* Serialize a public key. */
+uint8_t* dap_enc_tesla_write_public_key(const tesla_public_key_t* a_public_key, size_t *a_buflen_out)
+{
+    tesla_param_t p;
+    if(!tesla_params_init(&p, a_public_key->kind))
+        return NULL;
+
+    size_t l_buflen = sizeof(size_t) + sizeof(tesla_kind_t) + p.CRYPTO_PUBLICKEYBYTES;
+    uint8_t *l_buf = DAP_NEW_SIZE(uint8_t, l_buflen);
+    memcpy(l_buf, &l_buflen, sizeof(size_t));
+    memcpy(l_buf + sizeof(size_t), &a_public_key->kind, sizeof(tesla_kind_t));
+    memcpy(l_buf + sizeof(size_t) + sizeof(tesla_kind_t), a_public_key->data, p.CRYPTO_PUBLICKEYBYTES);
+    if(a_buflen_out)
+        *a_buflen_out = l_buflen;
+    return l_buf;
+}
+
+/* Deserialize a private key. */
+tesla_private_key_t* dap_enc_tesla_read_private_key(uint8_t *a_buf, size_t a_buflen)
+{
+    if(!a_buf || a_buflen < (sizeof(size_t) + sizeof(tesla_kind_t)))
+        return NULL;
+    tesla_kind_t kind;
+    size_t l_buflen = 0;
+    memcpy(&l_buflen, a_buf, sizeof(size_t));
+    memcpy(&kind, a_buf + sizeof(size_t), sizeof(tesla_kind_t));
+    if(l_buflen != a_buflen)
+        return NULL;
+    tesla_param_t p;
+    if(!tesla_params_init(&p, kind))
+        return NULL;
+    tesla_private_key_t* l_private_key = DAP_NEW(tesla_private_key_t);
+    l_private_key->kind = kind;
+
+    l_private_key->data = DAP_NEW_SIZE(unsigned char, p.CRYPTO_SECRETKEYBYTES);
+    memcpy(l_private_key->data, a_buf + sizeof(size_t) + sizeof(tesla_kind_t), p.CRYPTO_SECRETKEYBYTES);
+    return l_private_key;
+}
+
+/* Deserialize a public key. */
+tesla_public_key_t* dap_enc_tesla_read_public_key(uint8_t *a_buf, size_t a_buflen)
+{
+    if(!a_buf || a_buflen < (sizeof(size_t) + sizeof(tesla_kind_t)))
+        return NULL;
+    tesla_kind_t kind;
+    size_t l_buflen = 0;
+    memcpy(&l_buflen, a_buf, sizeof(size_t));
+    memcpy(&kind, a_buf + sizeof(size_t), sizeof(tesla_kind_t));
+    if(l_buflen != a_buflen)
+        return NULL;
+    tesla_param_t p;
+    if(!tesla_params_init(&p, kind))
+        return NULL;
+    tesla_public_key_t* l_public_key = DAP_NEW(tesla_public_key_t);
+    l_public_key->kind = kind;
+
+    l_public_key->data = DAP_NEW_SIZE(unsigned char, p.CRYPTO_PUBLICKEYBYTES);
+    memcpy(l_public_key->data, a_buf + sizeof(size_t) + sizeof(tesla_kind_t), p.CRYPTO_PUBLICKEYBYTES);
+    return l_public_key;
+}
diff --git a/crypto/dap_enc_tesla.h b/crypto/dap_enc_tesla.h
index a3e4c198bf96e4d7ab19fa74072a73a3a9687df9..a1e04cbaeaec5cff09ce40dfc836acd26c94c2f9 100755
--- a/crypto/dap_enc_tesla.h
+++ b/crypto/dap_enc_tesla.h
@@ -27,4 +27,11 @@ void dap_enc_sig_tesla_key_delete(struct dap_enc_key * key);
 
 size_t dap_enc_tesla_calc_signature_size(void);
 
+uint8_t* dap_enc_tesla_write_signature(tesla_signature_t* a_sign, size_t *a_sign_out);
+tesla_signature_t* dap_enc_tesla_read_signature(uint8_t *a_buf, size_t a_buflen);
+uint8_t* dap_enc_tesla_write_private_key(const tesla_private_key_t* a_private_key, size_t *a_buflen_out);
+uint8_t* dap_enc_tesla_write_public_key(const tesla_public_key_t* a_public_key, size_t *a_buflen_out);
+tesla_private_key_t* dap_enc_tesla_read_private_key(uint8_t *a_buf, size_t a_buflen);
+tesla_public_key_t* dap_enc_tesla_read_public_key(uint8_t *a_buf, size_t a_buflen);
+
 #endif
diff --git a/crypto/sig_bliss/bliss_b_signatures.c b/crypto/sig_bliss/bliss_b_signatures.c
index bdbe0b841bbe1ed13925620e9f4e1168a3674319..9c9cbb3f5da6252464867caee7bba0a231650a82 100644
--- a/crypto/sig_bliss/bliss_b_signatures.c
+++ b/crypto/sig_bliss/bliss_b_signatures.c
@@ -1,3 +1,4 @@
+#include <stdint.h>
 #include <assert.h>
 #include <string.h>
 #include <stdio.h>
diff --git a/crypto/sig_picnic/picnic.c b/crypto/sig_picnic/picnic.c
index 17a719f93a82fca0563d042092601ba691294a65..cc99c3b7d52f2f35ca6bf1f6b4ed9048ba64673a 100644
--- a/crypto/sig_picnic/picnic.c
+++ b/crypto/sig_picnic/picnic.c
@@ -212,6 +212,18 @@ int picnic_verify(picnic_publickey_t* pk, const uint8_t* message, size_t message
     return 0;
 }
 
+/* Get public key size for serialize */
+size_t picnic_get_public_key_size(const picnic_publickey_t* key)
+{
+    paramset_t paramset;
+    int ret = get_param_set(key->params, &paramset);
+    if (ret != EXIT_SUCCESS) {
+        return 0;
+    }
+    size_t bytesRequired = 1 + 2 * paramset.stateSizeBytes;
+    return bytesRequired;
+}
+
 /* Serialize public key */
 int picnic_write_public_key(const picnic_publickey_t* key, uint8_t* buf, size_t buflen)
 {
diff --git a/crypto/sig_picnic/picnic.h b/crypto/sig_picnic/picnic.h
index cb7501a16e66fffa39de1224b5385b479f28bd27..d6ed926f65a509c0392f02f14e5368baa83a646a 100644
--- a/crypto/sig_picnic/picnic.h
+++ b/crypto/sig_picnic/picnic.h
@@ -59,6 +59,7 @@ typedef struct {
 /* Signature API */
 
 size_t picnic_signature_size(picnic_params_t parameters);
+size_t picnic_get_public_key_size(const picnic_publickey_t* key);/* Get public key size for serialize */
 int picnic_write_public_key(const picnic_publickey_t* key, uint8_t* buf, size_t buflen);
 int picnic_read_public_key(picnic_publickey_t* key, const uint8_t* buf, size_t buflen);
 int picnic_write_private_key(const picnic_privatekey_t* key, uint8_t* buf, size_t buflen);
diff --git a/crypto/sig_tesla/sign.c b/crypto/sig_tesla/sign.c
index 0ce3699aec86ed4ffbbf629444bc915ece713a12..c0a0cce2d819ded604fc7268e1a0a7e2ed376d5a 100755
--- a/crypto/sig_tesla/sign.c
+++ b/crypto/sig_tesla/sign.c
@@ -584,6 +584,25 @@ static void sparse_mul32(poly *prod, const int32_t *pk, const uint32_t *pos_list
 }
 
 /********************************************************************************************/
+void tesla_private_key_delete(tesla_private_key_t *private_key)
+{
+
+    if(private_key) {
+        free(private_key->data);
+        private_key->data = NULL;
+        free(private_key);
+    }
+}
+
+void tesla_public_key_delete(tesla_public_key_t *public_key)
+{
+    if(public_key) {
+        free(public_key->data);
+        public_key->data = NULL;
+        free(public_key);
+    }
+}
+
 void tesla_private_and_public_keys_delete(tesla_private_key_t *private_key, tesla_public_key_t *public_key){
 
     free(private_key->data);
diff --git a/crypto/sig_tesla/tesla_params.h b/crypto/sig_tesla/tesla_params.h
index e2538ca35930b91a6a8c964fea3f6230139af0a8..e1c034a28d21cb557f715d8ac105a229cf4d2ddf 100755
--- a/crypto/sig_tesla/tesla_params.h
+++ b/crypto/sig_tesla/tesla_params.h
@@ -3,6 +3,7 @@
 
 #include <assert.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include "../dap_crypto_common.h"
 
 #define CRYPTO_RANDOMBYTES 32
@@ -77,6 +78,8 @@ int tesla_crypto_sign(tesla_signature_t *, const unsigned char *, unsigned long
 
 int tesla_crypto_sign_open(tesla_signature_t *, const unsigned char *, unsigned long long, const tesla_public_key_t *);
 
+void tesla_private_key_delete(tesla_private_key_t *private_key);
+void tesla_public_key_delete(tesla_public_key_t *public_key);
 void tesla_private_and_public_keys_delete(tesla_private_key_t *private_key, tesla_public_key_t *public_key);
 
 void tesla_signature_delete(tesla_signature_t *signature);
diff --git a/test/crypto/dap_enc_base58_test.c b/test/crypto/dap_enc_base58_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..a11ae9de3d6fbb9b83d7a40877b5dae01099eb78
--- /dev/null
+++ b/test/crypto/dap_enc_base58_test.c
@@ -0,0 +1,40 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "dap_common.h"
+#include "dap_test.h"
+#include "dap_test_generator.h"
+#include "dap_enc_base58.h"
+#include "dap_enc_base58_test.h"
+
+static void test_encode_decode_base58(void)
+{
+    static size_t source_size = 0;
+    int step = 1 + (rand() % 20);
+    source_size += (size_t) step;
+
+    uint8_t source[source_size];
+    generate_random_byte_array(source, source_size);
+    //source[0] = 0;
+    //source[1] = 0;
+    size_t encode_result_size = DAP_ENC_BASE58_ENCODE_SIZE(source_size);
+    char encode_result[encode_result_size];
+    uint8_t decode_result[source_size];
+
+    size_t encrypted_size = dap_enc_base58_encode(source, source_size, encode_result);
+    size_t out_size = dap_enc_base58_decode(encode_result, decode_result);
+    dap_assert_PIF(encrypted_size <= encode_result_size, "Calculate encrypted_size");
+    dap_assert_PIF(source_size == out_size, "Check result decode size");
+    dap_assert_PIF(memcmp(source, decode_result, source_size) == 0, "Check source and encode->decode data");
+}
+
+void dap_enc_base58_tests_run() {
+    dap_print_module_name("dap_enc_base58");
+
+    benchmark_mgs_time("Encode and decode DAP_ENC_STANDARD_B58 100 times",
+            benchmark_test_time(test_encode_decode_base58, 100));
+
+    benchmark_mgs_rate("Encode and decode DAP_ENC_STANDARD_B58",
+            benchmark_test_rate(test_encode_decode_base58, 1));
+
+}
diff --git a/test/crypto/dap_enc_base58_test.h b/test/crypto/dap_enc_base58_test.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69389d46aedcd4d3a017e08436c4b3c4c0dae49
--- /dev/null
+++ b/test/crypto/dap_enc_base58_test.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "dap_enc_base58.h"
+
+void dap_enc_base58_tests_run(void);
+
diff --git a/test/crypto/dap_enc_test.c b/test/crypto/dap_enc_test.c
index bdf5e3873937412a61d35144b3b29b47b88f1a5a..8811b9db96abacb3699e04be37d146ab8edb34cf 100644
--- a/test/crypto/dap_enc_test.c
+++ b/test/crypto/dap_enc_test.c
@@ -1,8 +1,13 @@
+#include <unistd.h>
+#include "dap_common.h"
 #include "dap_enc_test.h"
 #include "dap_test.h"
 #include "dap_test_generator.h"
 #include "dap_enc_key.h"
 #include "dap_enc_base64.h"
+#include "dap_enc_bliss.h"
+#include "dap_enc_picnic.h"
+#include "dap_enc_tesla.h"
 #include "dap_enc.h"
 
 #define TEST_SER_FILE_NAME "keystorage.txt"
@@ -117,21 +122,21 @@ static void cleanup_test_case()
     dap_enc_key_deinit();
 }
 
-static void _write_key_in_file(dap_enc_key_serealize_t* key,
+static void _write_key_in_file(void* key, size_t key_size,
                                const char* file_name)
 {
     FILE *f = fopen(file_name, "wb");
-    dap_assert(f, "Can't create file");
-    fwrite(key, sizeof (dap_enc_key_serealize_t), 1, f);
+    dap_assert(f, "Create file");
+    fwrite(key, key_size, 1, f);
     fclose(f);
 }
 
-dap_enc_key_serealize_t* _read_key_from_file(const char* file_name)
+void* _read_key_from_file(const char* file_name, size_t key_size)
 {
     FILE *f = fopen(file_name, "rb");
-    dap_assert(f, "Can't open key file");
-    dap_enc_key_serealize_t* resut_key = calloc(1, sizeof(dap_enc_key_serealize_t));
-    fread(resut_key, sizeof(dap_enc_key_serealize_t), 1, f);
+    dap_assert(f, "Open key file");
+    void* resut_key = calloc(1, key_size);//sizeof(dap_enc_key_serealize_t)
+    fread(resut_key, key_size, 1, f);// sizeof(dap_enc_key_serealize_t)
     fclose(f);
     return resut_key;
 }
@@ -151,8 +156,8 @@ static void test_serealize_deserealize(dap_enc_key_type_t key_type)
 //  for key_type==DAP_ENC_KEY_TYPE_OAES must be: key_size=[16|24|32] and kex_size>=key_size
     dap_enc_key_t* key = dap_enc_key_new_generate(key_type, kex_data, kex_size, seed, seed_size, 32);
     dap_enc_key_serealize_t* serealize_key = dap_enc_key_serealize(key);
-    _write_key_in_file(serealize_key, TEST_SER_FILE_NAME);
-    dap_enc_key_serealize_t* deserealize_key = _read_key_from_file(TEST_SER_FILE_NAME);
+    _write_key_in_file(serealize_key, sizeof (dap_enc_key_serealize_t), TEST_SER_FILE_NAME);
+    dap_enc_key_serealize_t* deserealize_key = _read_key_from_file(TEST_SER_FILE_NAME, sizeof(dap_enc_key_serealize_t));
     dap_assert(memcmp(serealize_key, deserealize_key, sizeof(dap_enc_key_serealize_t)) == 0,
                "dap_enc_key_serealize_t equals");
 
@@ -208,6 +213,118 @@ static void test_serealize_deserealize(dap_enc_key_type_t key_type)
     dap_enc_key_delete(key2);
 
     dap_pass_msg("Key serealize->deserealize");
+    unlink(TEST_SER_FILE_NAME);
+}
+
+/**
+ * @key_type may be DAP_ENC_KEY_TYPE_SIG_BLISS, DAP_ENC_KEY_TYPE_SIG_TESLA, DAP_ENC_KEY_TYPE_SIG_PICNIC
+ */
+static void test_serealize_deserealize_pub_priv(dap_enc_key_type_t key_type)
+{
+    const char *kex_data = "1234567890123456789012345678901234567890"; //"123";
+    size_t kex_size = strlen(kex_data);
+    const size_t seed_size = 1 + (rand() % 1000);
+    uint8_t seed[seed_size];
+    generate_random_byte_array(seed, seed_size);
+
+    // Generate key
+    dap_enc_key_t* key = dap_enc_key_new_generate(key_type, kex_data, kex_size, seed, seed_size, 32);
+    // Serialize key & save/read to/from buf
+    size_t l_data_pub_size = 0;
+    //uint8_t *l_data_pub = DAP_NEW_SIZE(uint8_t, l_data_pub_size);//dap_enc_key_serealize_pub_key(key, &l_data_pub_size);
+    uint8_t *l_data_pub = dap_enc_key_serealize_pub_key(key, &l_data_pub_size);
+    _write_key_in_file(l_data_pub, l_data_pub_size, TEST_SER_FILE_NAME);
+    uint8_t *l_data_pub_read = _read_key_from_file(TEST_SER_FILE_NAME, l_data_pub_size);
+
+    size_t l_data_priv_size = 0;
+    uint8_t *l_data_priv = dap_enc_key_serealize_priv_key(key, &l_data_priv_size);
+    _write_key_in_file(l_data_priv, l_data_priv_size, TEST_SER_FILE_NAME);
+    uint8_t *l_data_priv_read = _read_key_from_file(TEST_SER_FILE_NAME, l_data_priv_size);
+
+    // create new key2
+    dap_enc_key_t *key2 = dap_enc_key_new(key_type);
+    // Deserialize key2
+    dap_enc_key_deserealize_pub_key(key2, l_data_pub_read, l_data_pub_size);
+    dap_enc_key_deserealize_priv_key(key2, l_data_priv_read, l_data_priv_size);
+
+    DAP_DELETE(l_data_pub);
+    DAP_DELETE(l_data_pub_read);
+    DAP_DELETE(l_data_priv);
+    DAP_DELETE(l_data_priv_read);
+
+    dap_assert(key->priv_key_data_size == key2->priv_key_data_size, "Priv key data size");
+    dap_assert(key->pub_key_data_size == key2->pub_key_data_size, "Pub key data size");
+    dap_pass_msg("Key serealize->deserealize");
+
+    size_t source_size = 10 + (rand() % 20);
+    uint8_t source_buf[source_size];
+    size_t sig_buf_size = 0;
+    uint8_t *sig_buf = NULL;
+    generate_random_byte_array(source_buf, source_size);
+
+    // encode by key
+    int is_sig = 0, is_vefify = 0;
+    switch (key_type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        sig_buf_size = sizeof(bliss_signature_t);
+        sig_buf = calloc(sig_buf_size, 1);
+        if(dap_enc_sig_bliss_get_sign(key, source_buf, source_size, sig_buf, sig_buf_size) == BLISS_B_NO_ERROR)
+            is_sig = 1;
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+        sig_buf_size = dap_enc_picnic_calc_signature_size(key);
+        sig_buf = calloc(sig_buf_size, 1);
+        if(key->enc_na(key, source_buf, source_size, sig_buf, sig_buf_size) > 0)
+            is_sig = 1;
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        sig_buf_size = dap_enc_tesla_calc_signature_size();
+        sig_buf = calloc(sig_buf_size, 1);
+        if(key->enc_na(key, source_buf, source_size, sig_buf, sig_buf_size) > 0)
+            is_sig = 1;
+        break;
+    default:
+        sig_buf_size = 0;
+    }
+    dap_enc_key_delete(key);
+
+    dap_assert_PIF(sig_buf_size>0 && is_sig==1, "Check make signature");
+
+    // serealize & deserealize signature
+    size_t sig_buf_len = sig_buf_size;
+    uint8_t *l_sign_tmp = dap_enc_key_serealize_sign(key_type, sig_buf, &sig_buf_len);
+    dap_enc_key_signature_delete(key_type, sig_buf);
+    sig_buf = dap_enc_key_deserealize_sign(key_type, l_sign_tmp, &sig_buf_len);
+    DAP_DELETE(l_sign_tmp);
+
+    dap_assert_PIF(sig_buf, "Check serealize->deserealize signature");
+
+    // decode by key2
+    switch (key_type) {
+    case DAP_ENC_KEY_TYPE_SIG_BLISS:
+        if(dap_enc_sig_bliss_verify_sign(key2, source_buf, source_size, sig_buf, sig_buf_size) == BLISS_B_NO_ERROR)
+            is_vefify = 1;
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+        if(key2->dec_na(key2, source_buf, source_size, sig_buf, sig_buf_size) == 0)
+            is_vefify = 1;
+        break;
+    case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        if(key2->dec_na(key2, source_buf, source_size, sig_buf, sig_buf_size) == 0)
+            is_vefify = 1;
+        break;
+    default:
+        is_vefify = 0;
+    }
+    //dap_enc_key_delete(key);
+    dap_enc_key_delete(key2);
+    dap_enc_key_signature_delete(key_type, sig_buf);
+
+
+    dap_assert_PIF(is_vefify==1, "Check verify signature");
+
+    dap_pass_msg("Verify signature");
+    unlink(TEST_SER_FILE_NAME);
 }
 
 void dap_enc_tests_run() {
@@ -221,5 +338,12 @@ void dap_enc_tests_run() {
     test_serealize_deserealize(DAP_ENC_KEY_TYPE_IAES);
     dap_print_module_name("dap_enc serealize->deserealize OAES");
     test_serealize_deserealize(DAP_ENC_KEY_TYPE_OAES);
+
+    dap_print_module_name("dap_enc_sig serealize->deserealize BLISS");
+    test_serealize_deserealize_pub_priv(DAP_ENC_KEY_TYPE_SIG_BLISS);
+    dap_print_module_name("dap_enc_sig serealize->deserealize PICNIC");
+    test_serealize_deserealize_pub_priv(DAP_ENC_KEY_TYPE_SIG_PICNIC);
+    dap_print_module_name("dap_enc_sig serealize->deserealize TESLA");
+    test_serealize_deserealize_pub_priv(DAP_ENC_KEY_TYPE_SIG_TESLA);
     cleanup_test_case();
 }
diff --git a/test/crypto/main.c b/test/crypto/main.c
index 62f306237b7f318a2ca9989884040b7c17fdc6a6..b4e5953820706726f9dbd5d8d5a47ad5ca8644cd 100644
--- a/test/crypto/main.c
+++ b/test/crypto/main.c
@@ -1,6 +1,7 @@
 #include "dap_enc_iaes_test.h"
 #include "dap_enc_oaes_test.h"
 #include "dap_enc_base64_test.h"
+#include "dap_enc_base58_test.h"
 #include "dap_enc_test.h"
 #include "dap_enc_msrln_test.h"
 #include "dap_enc_defeo_test.h"
@@ -18,6 +19,7 @@ int main(void)
     dap_enc_aes_tests_run();
     dap_enc_oaes_tests_run();
     dap_enc_base64_tests_run();
+    dap_enc_base58_tests_run();
     dap_enc_msrln_tests_run();
     dap_enc_tests_run();
     dap_enc_sig_bliss_tests_run();