diff --git a/include/dap_cert.h b/include/dap_cert.h
new file mode 100755
index 0000000000000000000000000000000000000000..16c43b9d80ae36a05a135327783e8c083e68923f
--- /dev/null
+++ b/include/dap_cert.h
@@ -0,0 +1,82 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * CellFrame       https://cellframe.net
+ * Sources         https://gitlab.demlabs.net/cellframe
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of CellFrame SDK the open source project
+
+    CellFrame SDK is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    CellFrame SDK is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+
+#include "dap_sign.h"
+#include "dap_pkey.h"
+
+#include "dap_enc.h"
+#include "dap_enc_key.h"
+
+#define DAP_CERT_ITEM_NAME_MAX 40
+
+typedef struct dap_cert {
+    dap_enc_key_t * enc_key;
+    char name[DAP_CERT_ITEM_NAME_MAX];
+    void * _pvt;
+    char * metadata;
+} dap_cert_t;
+
+int dap_cert_init();
+
+
+dap_cert_t * dap_cert_new(const char * a_name);
+
+size_t dap_cert_parse_str_list(const char * a_certs_str, dap_cert_t *** a_certs, size_t * a_certs_size);
+
+dap_cert_t * dap_cert_generate(const char * a_cert_name,const char * a_file_path,dap_enc_key_type_t a_key_type );
+
+dap_cert_t * dap_cert_generate_mem(const char * a_cert_name,
+                                               dap_enc_key_type_t a_key_type );
+
+
+dap_cert_t * dap_cert_add_file(const char * a_cert_name,const char *a_folder_path);
+int dap_cert_save_to_folder(dap_cert_t * a_cert, const char *a_file_dir_path);
+void dap_cert_add_folder(const char *a_folder_path);
+void dap_cert_dump(dap_cert_t * a_cert);
+dap_pkey_t * dap_cert_to_pkey(dap_cert_t * a_cert);
+
+dap_cert_t * dap_cert_find_by_name(const char * a_cert_name);
+
+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 );
+
+int dap_cert_compare_with_sign (dap_cert_t * a_cert,dap_sign_t * a_sign);
+
+
+size_t dap_cert_sign_output_size(dap_cert_t * a_cert, size_t a_size_wished);
+
+
+//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_add_cert_sign(dap_cert_t * a_cert, dap_cert_t * a_cert_signer);
+
+size_t dap_cert_count_cert_sign(dap_cert_t * a_cert);
+
+void dap_cert_deinit();
+
+void dap_cert_delete(dap_cert_t * a_cert);
+void dap_cert_delete_by_name(const char * a_cert_name);
diff --git a/include/dap_cert_file.h b/include/dap_cert_file.h
new file mode 100755
index 0000000000000000000000000000000000000000..5ba7f1fbabe38e5b913cbbf277ae9cffc790b182
--- /dev/null
+++ b/include/dap_cert_file.h
@@ -0,0 +1,60 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net    https:/gitlab.com/demlabs
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+#include <stdint.h>
+#include "dap_common.h"
+#include "dap_cert.h"
+
+// Magic .dapcert signature
+#define dap_cert_FILE_HDR_SIGN 0x0F300C4711E29380
+#define dap_cert_FILE_VERSION 1
+
+// Default certificate with private key and optionaly some signs
+#define dap_cert_FILE_TYPE_PRIVATE 0x00
+// Default certificate with public key and optionaly some signs
+#define dap_cert_FILE_TYPE_PUBLIC 0xf0
+
+
+typedef struct dap_cert_file_hdr
+{
+    uint64_t sign;
+    int version;
+    uint8_t type;
+    dap_sign_type_t sign_type;
+    uint64_t data_size;
+    uint64_t data_pvt_size;
+    uint64_t metadata_size;
+    time_t ts_last_used;
+} DAP_ALIGN_PACKED dap_cert_file_hdr_t;
+
+typedef struct dap_cert_file{
+    dap_cert_file_hdr_t hdr;
+    uint8_t data[];
+}DAP_ALIGN_PACKED dap_cert_file_t;
+
+int dap_cert_file_save(dap_cert_t * a_cert, const char * a_cert_file_path);
+uint8_t* dap_cert_mem_save(dap_cert_t * a_cert, uint32_t *a_cert_size_out);
+
+dap_cert_t* dap_cert_file_load(const char * a_cert_file_path);
+dap_cert_t* dap_cert_mem_load(void * a_data, size_t a_data_size);
diff --git a/include/dap_hash.h b/include/dap_hash.h
new file mode 100755
index 0000000000000000000000000000000000000000..3d968c6a31ae548f8844ea43fc430cb1637ff1e4
--- /dev/null
+++ b/include/dap_hash.h
@@ -0,0 +1,108 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * CellFrame       https://cellframe.net
+ * Sources         https://gitlab.demlabs.net/cellframe
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of CellFrame SDK the open source project
+
+    CellFrame SDK is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    CellFrame SDK is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "dap_common.h"
+#include "dap_hash_keccak.h"
+
+#include "KeccakHash.h"
+#include "SimpleFIPS202.h"
+
+#define DAP_HASH_FAST_SIZE  32
+#define DAP_CHAIN_HASH_FAST_SIZE    32
+
+typedef enum dap_hash_type {
+    DAP_HASH_TYPE_KECCAK = 0,
+    DAP_HASH_TYPE_SLOW_0 = 1,
+} dap_hash_type_t;
+
+typedef union dap_chain_hash_fast{
+    uint8_t raw[DAP_CHAIN_HASH_FAST_SIZE];
+} dap_chain_hash_fast_t;
+
+//size_t dap_chain_hash_fast_to_str(dap_chain_hash_fast_t * a_hash, char * a_str, size_t a_str_max);
+int dap_chain_str_to_hash_fast( const char * a_hash_str, dap_chain_hash_fast_t * a_hash);
+
+static inline bool dap_hash_fast( const void *a_data_in, size_t a_data_in_size, dap_chain_hash_fast_t *a_hash_out )
+{
+    if ( (a_data_in == NULL) || (a_data_in_size == 0) || (a_hash_out == NULL) )
+        return false;
+
+    //            dap_hash_keccak( a_data_in, a_data_in_size, a_data_out, a_data_out_size );
+
+    SHA3_256( (unsigned char *)a_hash_out, (const unsigned char *)a_data_in, a_data_in_size );
+
+  //SHA3_256( (unsigned char *)a_hash_out, (const unsigned char *)a_data_in, a_data_in_size );
+
+  return true;
+}
+
+
+/**
+ * @brief dap_hash_fast_compare
+ * @param a_hash1
+ * @param a_hash2
+ * @return
+ */
+static inline bool dap_hash_fast_compare(dap_chain_hash_fast_t *a_hash1, dap_chain_hash_fast_t *a_hash2)
+{
+    if(!a_hash1 || !a_hash2)
+        return false;
+    if(!memcmp(a_hash1, a_hash2, sizeof(dap_chain_hash_fast_t)))
+        return true;
+    return false;
+}
+
+static inline bool dap_hash_fast_is_blank( dap_chain_hash_fast_t *a_hash )
+{
+    static dap_chain_hash_fast_t l_blank_hash = { 0};
+//    uint8_t *l_hast_bytes = (uint8_t*) a_hash;
+//    for(size_t i = 0; i < sizeof(dap_chain_hash_fast_t); i++) {
+//        if(l_hast_bytes[i])
+//            return false;
+//    }
+    return dap_hash_fast_compare( a_hash, &l_blank_hash);
+}
+
+
+DAP_STATIC_INLINE int dap_chain_hash_fast_to_str( dap_chain_hash_fast_t *a_hash, char *a_str, size_t a_str_max )
+{
+  a_str[0] = '0';
+  a_str[1] = 'x';
+  a_str[ DAP_CHAIN_HASH_FAST_SIZE * 2 + 2 ] = 0;
+  dap_htoa64( (a_str + 2), a_hash->raw, DAP_CHAIN_HASH_FAST_SIZE );
+  return DAP_CHAIN_HASH_FAST_SIZE * 2 + 2;
+}
+
+static inline char *dap_chain_hash_fast_to_str_new(dap_chain_hash_fast_t * a_hash)
+{
+    const size_t c_hash_str_size = sizeof(*a_hash)*2 +1 /*trailing zero*/ +2 /* heading 0x */+4/*just to be sure*/ ;
+    char * ret = DAP_NEW_Z_SIZE(char, c_hash_str_size);
+    dap_chain_hash_fast_to_str( a_hash, ret, c_hash_str_size );
+    return ret;
+}
diff --git a/include/dap_hash_fusion.h b/include/dap_hash_fusion.h
new file mode 100755
index 0000000000000000000000000000000000000000..a2d8d85b13846b79597c3778b96cc37dcf86c986
--- /dev/null
+++ b/include/dap_hash_fusion.h
@@ -0,0 +1,25 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
diff --git a/include/dap_hash_keccak.h b/include/dap_hash_keccak.h
new file mode 100755
index 0000000000000000000000000000000000000000..f94db1cb1738a5e0017802e106488f37d1095e69
--- /dev/null
+++ b/include/dap_hash_keccak.h
@@ -0,0 +1,35 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+/*
+#include "keccak.h"
+
+static inline void dap_hash_keccak(const void * a_in, size_t a_in_size, void * a_out, size_t a_out_size)
+{
+    keccak((const uint8_t*) a_in, a_in_size, (uint8_t *) a_out,(int)  a_out_size );
+}*/
+
+
diff --git a/include/dap_pkey.h b/include/dap_pkey.h
new file mode 100755
index 0000000000000000000000000000000000000000..af9d930a84a25993ca47faef8136b9928874fcea
--- /dev/null
+++ b/include/dap_pkey.h
@@ -0,0 +1,63 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net    https:/gitlab.com/demlabs
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+
+#include <stdint.h>
+#include "dap_common.h"
+#include "dap_enc_key.h"
+
+typedef union dap_pkey_type{
+    enum {
+        PKEY_TYPE_NULL = 0x0000,
+        PKEY_TYPE_SIGN_BLISS = 0x0901,
+        PKEY_TYPE_SIGN_TESLA = 0x0902,
+        PKEY_TYPE_SIGN_DILITHIUM =  0x0903,
+        PKEY_TYPE_SIGN_PICNIC = 0x0102,
+        PKEY_TYPE_MULTI = 0xffff ///  @brief Has inside subset of different keys
+
+    } type: 16;
+    uint16_t raw;
+} dap_pkey_type_t;
+/**
+  * @struct dap_pkey
+  * @brief Public keys
+  */
+typedef struct dap_pkey{
+    struct {
+        dap_pkey_type_t type; /// Pkey type
+        uint32_t size; /// Pkey size
+    } header; /// Only header's hash is used for verification
+    uint8_t pkey[]; /// @param pkey @brief raw pkey dat
+} DAP_ALIGN_PACKED dap_pkey_t;
+
+static dap_pkey_t m_dap_pkey_null; // For sizeof nothing more
+
+dap_pkey_t *dap_pkey_from_enc_key(dap_enc_key_t *a_key);
+static inline size_t dap_pkey_from_enc_key_output_calc(dap_enc_key_t *a_key)
+{
+    return sizeof(m_dap_pkey_null.header)+ a_key->pub_key_data_size;
+}
+
+int dap_pkey_from_enc_key_output(dap_enc_key_t *a_key, void * a_output);
+
diff --git a/include/dap_sign.h b/include/dap_sign.h
new file mode 100755
index 0000000000000000000000000000000000000000..8a5542e6c9d4ca414246d2c6b8bc5c3df855f1d8
--- /dev/null
+++ b/include/dap_sign.h
@@ -0,0 +1,87 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net    https:/gitlab.com/demlabs
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include <stdint.h>
+#include "dap_common.h"
+#include "dap_enc_ca.h"
+#include "dap_enc_key.h"
+#include "dap_pkey.h"
+#include "dap_hash.h"
+
+typedef union dap_sign_type{
+    enum {
+        SIG_TYPE_NULL = 0x0000,
+        SIG_TYPE_BLISS = 0x0001,
+        SIG_TYPE_DEFO = 0x0002, /// @brief key image for anonymous transaction
+        SIG_TYPE_TESLA = 0x0003, /// @brief
+        SIG_TYPE_PICNIC = 0x0101, /// @brief
+        SIG_TYPE_DILITHIUM = 0x0102, /// @brief
+        SIG_TYPE_MULTI = 0xffff ///  @brief Has inside subset of different signatures and sign composed with all of them
+    } type: 16;
+    uint16_t raw;
+} dap_sign_type_t;
+
+typedef struct dap_sign_hdr{
+        dap_sign_type_t type; /// Signature type
+        uint8_t padding[2]; /// Padding for better aligmnent
+        uint16_t sign_size; /// Signature size
+        uint32_t sign_pkey_size; /// Signature serialized public key size
+} DAP_ALIGN_PACKED dap_sign_hdr_t;
+
+/**
+  * @struct dap_sign
+  * @brief Chain storage format for digital signature
+  */
+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;
+
+size_t dap_sign_get_size(dap_sign_t * a_chain_sign);
+
+int dap_sign_verify (dap_sign_t * a_chain_sign, const void * a_data, const size_t a_data_size);
+
+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 );
+size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t * a_key,size_t a_output_wish_size );
+//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 );
+
+
+dap_sign_type_t dap_sign_type_from_key_type( dap_enc_key_type_t a_key_type);
+dap_enc_key_type_t  dap_sign_type_to_key_type(dap_sign_type_t  a_chain_sign_type);
+
+dap_sign_type_t dap_pkey_type_from_sign( dap_pkey_type_t a_pkey_type);
+
+uint8_t* dap_sign_get_sign(dap_sign_t *a_sign, size_t *a_sign_out);
+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_enc_key_t *dap_sign_to_enc_key(dap_sign_t * a_chain_sign);
+const char * dap_sign_type_to_str(dap_sign_type_t a_chain_sign_type);
+dap_sign_type_t dap_sign_type_from_str(const char * a_type_str);
+
diff --git a/src/dap_cert.c b/src/dap_cert.c
new file mode 100755
index 0000000000000000000000000000000000000000..e82d29d395a34606da772837c5eeaaf3074d293a
--- /dev/null
+++ b/src/dap_cert.c
@@ -0,0 +1,481 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net    https:/gitlab.com/demlabs
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "uthash.h"
+#include "utlist.h"
+#include "dap_common.h"
+#include "dap_config.h"
+#include "dap_string.h"
+#include "dap_strfuncs.h"
+#include "dap_cert.h"
+#include "dap_cert_file.h"
+//#include "dap_hash.h"
+#define LOG_TAG "dap_cert"
+
+
+typedef struct dap_sign_item
+{
+    dap_sign_t * sign;
+    struct dap_sign_item * next;
+    struct dap_sign_item * prev;
+} dap_sign_item_t;
+
+typedef struct dap_cert_item
+{
+    char name[DAP_CERT_ITEM_NAME_MAX];
+    dap_cert_t * cert;
+    UT_hash_handle hh;
+} dap_cert_item_t;
+
+typedef struct dap_cert_pvt
+{
+    dap_sign_item_t *signs;
+} dap_cert_pvt_t;
+
+
+#define PVT(a) ( ( dap_cert_pvt_t *)((a)->_pvt) )
+
+static dap_cert_item_t * s_certs = NULL;
+
+/**
+ * @brief dap_cert_init
+ * @return
+ */
+int dap_cert_init()
+{
+    return 0;
+}
+
+/**
+ * @brief dap_cert_parse_str_list
+ * @param a_certs_str
+ * @param a_certs
+ * @param a_certs_size_t
+ * @return summary size for signatures of all certs in list
+ */
+size_t dap_cert_parse_str_list(const char * a_certs_str, dap_cert_t *** a_certs, size_t * a_certs_size)
+{
+    char * l_certs_tmp_ptrs = NULL;
+    char * l_certs_str_dup = strdup(a_certs_str);
+    char *l_cert_str = strtok_r(l_certs_str_dup, ",", &l_certs_tmp_ptrs);
+
+    // First we just calc items
+    while(l_cert_str) {
+        l_cert_str = strtok_r(NULL, ",", &l_certs_tmp_ptrs);
+        (*a_certs_size)++;
+    }
+    // init certs array
+    dap_cert_t **l_certs;
+    *a_certs = l_certs = DAP_NEW_Z_SIZE(dap_cert_t*, (*a_certs_size) * sizeof(dap_cert_t*) );
+
+    // Second pass we parse them all
+    strcpy(l_certs_str_dup, a_certs_str);
+    l_cert_str = strtok_r(l_certs_str_dup, ",", &l_certs_tmp_ptrs);
+
+    size_t l_certs_pos = 0;
+    size_t l_sign_total_size =0;
+    while(l_cert_str) {
+        // trim whitespace in certificate's name
+        l_cert_str = dap_strstrip(l_cert_str);// removes leading and trailing spaces
+        // get certificate by name
+        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_certs_pos++;
+        } else {
+            log_it(L_WARNING,"Can't load cert %s",l_cert_str);
+            DAP_DELETE(*a_certs);
+            *a_certs = NULL;
+            *a_certs_size = 0;
+            break;
+        }
+        l_cert_str = strtok_r(NULL, ",", &l_certs_tmp_ptrs);
+    }
+    free(l_certs_str_dup);
+    return  l_sign_total_size;
+}
+
+
+
+/**
+ * @brief dap_cert_sign_output_size
+ * @param a_cert
+ * @param a_size_wished
+ * @return
+ */
+size_t dap_cert_sign_output_size(dap_cert_t * a_cert, size_t a_size_wished)
+{
+    return dap_sign_create_output_unserialized_calc_size( a_cert->enc_key,a_size_wished);
+}
+
+/**
+ * @brief dap_cert_sign_output
+ * @param a_cert
+ * @param a_data
+ * @param a_data_size
+ * @param a_output
+ * @param a_output_siz
+ * @return
+ */
+/*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)
+{
+    return dap_sign_create_output( a_cert->enc_key,a_data,a_data_size,a_output,a_output_size);
+}*/
+
+/**
+ * @brief dap_cert_sign
+ * @param a_cert
+ * @param a_data
+ * @param a_data_size
+ * @param a_output_size_wished
+ * @return
+ */
+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_enc_key_t * l_key = a_cert->enc_key;
+    dap_sign_t *l_ret = dap_sign_create(l_key, a_data, a_data_size, a_output_size_wished);
+    return l_ret;
+}
+
+/**
+ * @brief dap_cert_add_cert_sign
+ * @param a_cert
+ * @param a_cert_signer
+ * @return
+ */
+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);
+        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);
+        DL_APPEND ( PVT(a_cert)->signs, l_sign_item );
+        return 0;
+    } else {
+        log_it (L_ERROR, "No public key in cert \"%s\" that we are trying to sign with \"%s\"", a_cert->name,a_cert_signer->name);
+        return -1;
+    }
+}
+
+
+/**
+ * @brief dap_cert_generate_mem
+ * @param a_cert_name
+ * @param a_key_type
+ * @return
+ */
+dap_cert_t * dap_cert_generate_mem(const char * a_cert_name,
+                                               dap_enc_key_type_t a_key_type )
+{
+    dap_enc_key_t *l_enc_key = dap_enc_key_new_generate(a_key_type, NULL, 0, NULL, 0, 0);
+    if ( l_enc_key ){
+        dap_cert_t * l_cert = dap_cert_new(a_cert_name);
+        l_cert->enc_key = l_enc_key;
+        log_it(L_DEBUG,"Certificate generated");
+        //dap_cert_item_t * l_cert_item = DAP_NEW_Z(dap_cert_item_t);
+        //snprintf(l_cert_item->name,sizeof(l_cert_item->name),"%s",a_cert_name);
+        //HASH_ADD_STR(s_certs,name,l_cert_item);
+        log_it(L_DEBUG,"Certificate name %s recorded", a_cert_name);
+        return l_cert;
+    } else {
+        log_it(L_ERROR,"Can't generate key in memory!");
+        //dap_cert_delete(l_cert);
+        return NULL;
+    }
+}
+
+/**
+ * @brief dap_cert_generate
+ * @param a_cert_name
+ * @param a_file_path
+ * @param a_key_type
+ * @return
+ */
+dap_cert_t * dap_cert_generate(const char * a_cert_name
+                                           , const char * a_file_path,dap_enc_key_type_t a_key_type )
+{
+    dap_cert_t * l_cert = dap_cert_generate_mem(a_cert_name,a_key_type);
+    if ( l_cert){
+        if ( dap_cert_file_save(l_cert, a_file_path) == 0 ){
+            return l_cert;
+        } else{
+            dap_cert_delete(l_cert);
+            log_it(L_ERROR, "Can't save certificate to the file!");
+            return NULL;
+        }
+    } else {
+        log_it(L_ERROR,"Can't generate certificat in memory!");
+    }
+    return NULL;
+}
+
+/**
+ * @brief dap_cert_delete_by_name
+ * @param a_cert_name
+ */
+void dap_cert_delete_by_name(const char * a_cert_name)
+{
+    dap_cert_t * l_cert = dap_cert_find_by_name(a_cert_name);
+    if ( l_cert )
+        dap_cert_delete( l_cert );
+    else
+        log_it(L_WARNING,"Can't find \"%s\" certificate to delete it",a_cert_name);
+}
+
+/**
+ * @brief dap_cert_find_by_name
+ * @param a_cert_name
+ * @return
+ */
+dap_cert_t * dap_cert_find_by_name(const char * a_cert_name)
+{
+    dap_cert_item_t * l_cert_item = NULL;
+    HASH_FIND_STR(s_certs,a_cert_name,l_cert_item);
+    if ( l_cert_item ){
+        return l_cert_item->cert ;
+    } else {
+            dap_cert_t *l_cert = NULL;
+            uint16_t l_ca_folders_size = 0;
+            char **l_ca_folders;
+            char *l_cert_path = NULL;
+            l_ca_folders = dap_config_get_array_str(g_config, "resources", "ca_folders", &l_ca_folders_size);
+            for (uint16_t i = 0; i < l_ca_folders_size; ++i) {
+#ifdef _WIN32
+                l_cert_path = dap_strjoin("", s_sys_dir_path, l_ca_folders[i], "/", a_cert_name, ".dcert", (char*)NULL);
+#else
+                l_cert_path = dap_strjoin("", l_ca_folders[i], "/", a_cert_name, ".dcert", (char*)NULL);
+#endif
+                l_cert = dap_cert_file_load(l_cert_path);
+                if (l_cert) {
+                    goto ret;
+                }
+            }
+    ret:
+            if (l_cert_path)
+                DAP_DELETE(l_cert_path);
+            return l_cert;
+        }
+}
+
+
+/**
+ * @brief dap_cert_new
+ * @param a_name
+ * @return
+ */
+dap_cert_t * dap_cert_new(const char * a_name)
+{
+    dap_cert_t * l_ret = DAP_NEW_Z(dap_cert_t);
+    l_ret->_pvt = DAP_NEW_Z(dap_cert_pvt_t);
+    dap_snprintf(l_ret->name,sizeof(l_ret->name),"%s",a_name);
+
+    dap_cert_item_t * l_cert_item = DAP_NEW_Z(dap_cert_item_t);
+    dap_snprintf(l_cert_item->name,sizeof(l_cert_item->name),"%s",a_name);
+    l_cert_item->cert = l_ret;
+    HASH_ADD_STR(s_certs,name,l_cert_item);
+
+    return l_ret;
+}
+
+/**
+ * @brief s_cert_delete
+ * @param a_cert
+ */
+void dap_cert_delete(dap_cert_t * a_cert)
+{
+    dap_cert_item_t * l_cert_item = NULL;
+    HASH_FIND_STR(s_certs, a_cert->name, l_cert_item);
+    if ( l_cert_item ){
+         HASH_DEL(s_certs,l_cert_item);
+         DAP_DELETE (l_cert_item);
+    }
+
+    if( a_cert->enc_key )
+        dap_enc_key_delete (a_cert->enc_key );
+    if( a_cert->metadata )
+        DAP_DELETE (a_cert->metadata );
+    if (a_cert->_pvt)
+        DAP_DELETE( a_cert->_pvt );
+    DAP_DELETE (a_cert );
+}
+
+/**
+ * @brief dap_cert_add_file
+ * @param a_cert_name
+ * @param a_folder_path
+ * @return
+ */
+dap_cert_t * dap_cert_add_file(const char * a_cert_name,const char *a_folder_path)
+{
+    size_t l_cert_path_length = strlen(a_cert_name)+8+strlen(a_folder_path);
+    char * l_cert_path = DAP_NEW_Z_SIZE(char,l_cert_path_length);
+    dap_snprintf(l_cert_path,l_cert_path_length,"%s/%s.dcert",a_folder_path,a_cert_name);
+    if( access( l_cert_path, F_OK ) == -1 ) {
+        log_it (L_ERROR, "File %s is not exists! ", l_cert_path);
+        DAP_DELETE(l_cert_path);
+        exit(-701);
+    }
+    dap_cert_t * l_cert;
+    l_cert = dap_cert_file_load(l_cert_path);
+    if (l_cert == NULL){
+        log_it (L_ERROR, "File %s is corrupted or wrong format ", l_cert_path);
+    }
+    DAP_DELETE(l_cert_path);
+    return l_cert;
+}
+
+/**
+ * @brief dap_cert_save_to_folder
+ * @param a_cert
+ * @param a_file_dir_path
+ */
+int dap_cert_save_to_folder(dap_cert_t * a_cert, const char *a_file_dir_path)
+{
+    int ret = 0;
+    const char * l_cert_name = a_cert->name;
+    size_t l_cert_path_length = strlen(l_cert_name)+8+strlen(a_file_dir_path);
+    char * l_cert_path = DAP_NEW_Z_SIZE(char,l_cert_path_length);
+    dap_snprintf(l_cert_path,l_cert_path_length,"%s/%s.dcert",a_file_dir_path,l_cert_name);
+    ret = dap_cert_file_save(a_cert,l_cert_path);
+    DAP_DELETE( l_cert_path);
+    return ret;
+}
+
+/**
+ * @brief dap_cert_to_pkey
+ * @param a_cert
+ * @return
+ */
+dap_pkey_t * dap_cert_to_pkey(dap_cert_t * a_cert)
+{
+    if ( a_cert )
+        return dap_pkey_from_enc_key( a_cert->enc_key );
+    else
+        return NULL;
+}
+
+/**
+ * @brief dap_cert_compare_with_sign
+ * @param a_cert
+ * @param a_sign
+ * @return
+ */
+int dap_cert_compare_with_sign (dap_cert_t * a_cert,dap_sign_t * a_sign)
+{
+    dap_return_val_if_fail(a_cert && a_cert->enc_key && a_sign, -1);
+    if ( dap_sign_type_from_key_type( a_cert->enc_key->type ).type == a_sign->header.type.type ){
+        int l_ret;
+        size_t l_pub_key_size = 0;
+        // serialize public key
+        uint8_t *l_pub_key = dap_enc_key_serealize_pub_key(a_cert->enc_key, &l_pub_key_size);
+        if ( l_pub_key_size == a_sign->header.sign_pkey_size){
+            l_ret = memcmp ( l_pub_key, a_sign->pkey_n_sign, a_sign->header.sign_pkey_size );
+        }else
+            l_ret = -2; // Wrong pkey size
+        DAP_DELETE(l_pub_key);
+        return l_ret;
+    }else
+        return -1; // Wrong sign type
+}
+
+
+
+/**
+ * @brief dap_cert_count_cert_sign
+ * @param a_cert
+ * @return
+ */
+size_t dap_cert_count_cert_sign(dap_cert_t * a_cert)
+{
+    size_t ret;
+    dap_sign_item_t * l_cert_item = NULL;
+    DL_COUNT(  PVT(a_cert)->signs,l_cert_item,ret);
+    return ret > 0 ? ret : 0 ;
+}
+
+
+/**
+ * @brief dap_cert_dump
+ * @param a_cert
+ */
+void dap_cert_dump(dap_cert_t * a_cert)
+{
+    printf ("Certificate name: %s\n",a_cert->name);
+    printf ("Signature type: %s\n", dap_sign_type_to_str( dap_sign_type_from_key_type(a_cert->enc_key->type) ) );
+    printf ("Private key size: %lu\n",a_cert->enc_key->priv_key_data_size);
+    printf ("Public key size: %lu\n", a_cert->enc_key->pub_key_data_size);
+    printf ("Metadata section size: %lu\n",a_cert->metadata?strlen(a_cert->metadata):0);
+    printf ("Certificates signatures chain size: %lu\n",dap_cert_count_cert_sign (a_cert));
+}
+
+
+/**
+ * @brief dap_cert_add_folder
+ * @param a_folder_path
+ */
+void dap_cert_add_folder(const char *a_folder_path)
+{
+    DIR * l_dir = opendir(a_folder_path);
+    if( l_dir ) {
+        struct dirent * l_dir_entry;
+        while((l_dir_entry=readdir(l_dir))!=NULL){
+            const char * l_filename = l_dir_entry->d_name;
+            size_t l_filename_len = strlen (l_filename);
+            // Check if its not special dir entries . or ..
+            if( strcmp(l_filename,".") && strcmp(l_filename,"..") ){
+                // If not check the file's suffix
+                const char l_suffix[]=".dcert";
+                size_t l_suffix_len = strlen(l_suffix);
+                if (strncmp(l_filename+ l_filename_len-l_suffix_len,l_suffix,l_suffix_len) == 0 ){
+                    char * l_cert_name = dap_strdup(l_filename);
+                    l_cert_name[l_filename_len-l_suffix_len] = '\0'; // Remove suffix
+                    // Load the cert file
+                    //log_it(L_DEBUG,"Trying to load %s",l_filename);
+                    dap_cert_add_file(l_cert_name,a_folder_path);
+                    DAP_DELETE(l_cert_name);
+                }
+            }
+
+        }
+        closedir(l_dir);
+        log_it(L_NOTICE, "Added folder %s",a_folder_path);
+    }else
+        log_it(L_WARNING, "Can't add folder %s to cert manager",a_folder_path);
+}
+
+/**
+ * @brief dap_cert_deinit
+ */
+void dap_cert_deinit()
+{
+
+}
diff --git a/src/dap_cert_file.c b/src/dap_cert_file.c
new file mode 100755
index 0000000000000000000000000000000000000000..f41e05eac7242b450d9b78a9deb744114f1f1009
--- /dev/null
+++ b/src/dap_cert_file.c
@@ -0,0 +1,230 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net    https:/gitlab.com/demlabs
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include "dap_common.h"
+#include "dap_enc.h"
+#include "dap_enc_key.h"
+#include "dap_cert_file.h"
+
+#define LOG_TAG "dap_cert_file"
+
+/**
+ * @brief dap_cert_file_save
+ * @param a_cert
+ * @param a_cert_file_path
+ * @return
+ */
+int dap_cert_file_save(dap_cert_t * a_cert, const char * a_cert_file_path)
+{
+    FILE * l_file = fopen(a_cert_file_path,"wb");
+    if( l_file ){
+        uint32_t l_data_size = 0;
+        void * l_data = dap_cert_mem_save(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");
+            fclose(l_file);
+            return -4;
+        }
+    }else{
+        log_it(L_ERROR, "Can't open file for write: %s", strerror(errno));
+        return -2;
+    }
+}
+
+/**
+ * @brief dap_cert_file_save_to_mem
+ * @param a_cert
+ * @param a_cert_size_out
+ * @return
+ */
+uint8_t* dap_cert_mem_save(dap_cert_t * a_cert, uint32_t *a_cert_size_out)
+{
+    dap_cert_file_hdr_t l_hdr={0};
+    uint32_t l_data_offset = 0;
+    dap_enc_key_t * l_key = a_cert->enc_key;
+    uint8_t *l_data = NULL;
+
+    size_t l_priv_key_data_size = a_cert->enc_key->priv_key_data_size;
+    size_t l_pub_key_data_size = a_cert->enc_key->pub_key_data_size;
+    uint8_t *l_pub_key_data = a_cert->enc_key->pub_key_data_size ?
+                dap_enc_key_serealize_pub_key(l_key, &l_pub_key_data_size) :
+                NULL;
+    uint8_t *l_priv_key_data = a_cert->enc_key->priv_key_data ?
+                dap_enc_key_serealize_priv_key(l_key, &l_priv_key_data_size) :
+                NULL;
+
+    l_hdr.sign = dap_cert_FILE_HDR_SIGN;
+    l_hdr.type = dap_cert_FILE_TYPE_PUBLIC;
+    if ( l_priv_key_data ){
+        l_hdr.type =  dap_cert_FILE_TYPE_PRIVATE;
+        log_it(L_DEBUG,"Private key size %u",l_priv_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");
+        goto lb_exit;
+    }
+    log_it(L_DEBUG,"Metadata size %u",l_key->_inheritor_size);
+
+    l_hdr.version = dap_cert_FILE_VERSION;
+    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_sign_type_from_key_type ( l_key->type );
+
+
+    l_data = DAP_NEW_SIZE(void, sizeof(l_hdr) + DAP_CERT_ITEM_NAME_MAX + 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, a_cert->name, DAP_CERT_ITEM_NAME_MAX );//save cert name
+    l_data_offset += DAP_CERT_ITEM_NAME_MAX;
+
+    memcpy(l_data +l_data_offset, l_pub_key_data ,l_pub_key_data_size );
+    l_data_offset += l_pub_key_data_size;
+
+    if ( l_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;
+    }
+
+    if ( l_key->_inheritor_size ) {
+        memcpy(l_data +l_data_offset, l_key->_inheritor ,l_key->_inheritor_size );
+        l_data_offset += l_key->_inheritor_size;
+    }
+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);
+    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;
+}
+
+/**
+ * @brief dap_cert_file_load
+ * @param a_cert_file_path
+ * @return
+ */
+
+dap_cert_t* dap_cert_file_load(const char * a_cert_file_path)
+{
+    dap_cert_t * l_ret = NULL;
+    FILE * l_file = fopen(a_cert_file_path,"rb");
+
+    if( l_file ){
+        fseek(l_file, 0L, SEEK_END);
+        uint64_t l_file_size = ftell(l_file);
+        rewind(l_file);
+        uint8_t * l_data = DAP_NEW_SIZE(uint8_t,l_file_size);
+        if ( fread(l_data,1,l_file_size,l_file ) != l_file_size ){
+            log_it(L_ERROR, "Can't read %u bytes from the disk!", l_file_size);
+            DAP_DELETE (l_data);
+            goto lb_exit;
+        }else{
+            l_ret = dap_cert_mem_load(l_data,l_file_size);
+        }
+        DAP_DELETE(l_data);
+    }
+lb_exit:
+    if( l_file )
+        fclose(l_file);
+    return l_ret;
+}
+
+
+/**
+ * @brief dap_cert_mem_load
+ * @param a_data
+ * @param a_data_size
+ * @return
+ */
+dap_cert_t* dap_cert_mem_load(void * a_data, size_t a_data_size)
+{
+    dap_cert_t * l_ret = NULL;
+    dap_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_cert_FILE_HDR_SIGN ){
+        log_it(L_ERROR, "Wrong cert signature, corrupted header!");
+        goto l_exit;
+    }
+    if (l_hdr.version >= 1 ){
+        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)",
+                    sizeof(l_hdr)+l_hdr.data_pvt_size+l_hdr.data_size+l_hdr.metadata_size, a_data_size);
+            goto l_exit;
+        }
+
+        char l_name[DAP_CERT_ITEM_NAME_MAX];
+        memcpy(l_name, l_data +l_data_offset, DAP_CERT_ITEM_NAME_MAX );//save cert name
+        l_data_offset += DAP_CERT_ITEM_NAME_MAX;
+
+        //l_ret = DAP_NEW_Z(dap_cert_t);
+        l_ret = dap_cert_new(l_name);
+        l_ret->enc_key = dap_enc_key_new( dap_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 ){
+
+            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;
+        }
+        if ( l_hdr.data_pvt_size > 0 ){
+
+            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 %s", l_ret->name);
+    }else
+        log_it(L_ERROR,"Unrecognizable certificate version, corrupted file or you have too old software");
+
+l_exit:
+    return l_ret;
+}
diff --git a/src/dap_hash.c b/src/dap_hash.c
new file mode 100755
index 0000000000000000000000000000000000000000..27db3c7b0c894fd3809f7a2b5db615292839d860
--- /dev/null
+++ b/src/dap_hash.c
@@ -0,0 +1,55 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "dap_common.h"
+#include "dap_hash.h"
+
+#include "KeccakHash.h"
+#include "SimpleFIPS202.h"
+
+#define LOG_TAG "dap_hash"
+
+/**
+ * @brief dap_chain_str_to_hash_fast_to_str
+ * @param a_hash_str
+ * @param a_hash
+ * @return
+ */
+int dap_chain_str_to_hash_fast( const char * a_hash_str, dap_chain_hash_fast_t * a_hash)
+{
+    const size_t c_hash_str_size = sizeof(*a_hash) * 2 + 1 /*trailing zero*/+ 2 /* heading 0x */;
+    size_t l_hash_str_len = strlen( a_hash_str);
+    if ( l_hash_str_len + 1 == c_hash_str_size ){
+        for (size_t l_offset = 2; l_offset < l_hash_str_len; l_offset+=2 ){
+            if ( ( sscanf(a_hash_str+l_offset,"%02hhx",a_hash->raw+l_offset/2-1) != 1) ||
+                 ( sscanf(a_hash_str+l_offset,"%02hhX",a_hash->raw+l_offset/2-1) != 1)
+                 )
+                log_it(L_ERROR,"dap_chain_str_to_hash_fast parse error: offset=%u, hash_str_len=%u, str=\"%2s\"",l_offset, l_hash_str_len, a_hash_str+l_offset);
+                return -10* ((int) l_offset); // Wrong char
+        }
+        return  0;
+    }else  // Wromg string len
+        return -1;
+}
diff --git a/src/dap_hash_fusion.c b/src/dap_hash_fusion.c
new file mode 100755
index 0000000000000000000000000000000000000000..a6e107f6fdbf9f52f2309bdcc0e88e0959ea258b
--- /dev/null
+++ b/src/dap_hash_fusion.c
@@ -0,0 +1,28 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "dap_common.h"
+#include "dap_hash_fusion.h"
+
+#define LOG_TAG "dap_hash_fusion"
diff --git a/src/dap_hash_keccak.c b/src/dap_hash_keccak.c
new file mode 100755
index 0000000000000000000000000000000000000000..03695a705ca482a0c39660726cc4ce0d7b4d4974
--- /dev/null
+++ b/src/dap_hash_keccak.c
@@ -0,0 +1,26 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "dap_hash_keccak.h"
+
diff --git a/src/dap_pkey.c b/src/dap_pkey.c
new file mode 100755
index 0000000000000000000000000000000000000000..4a62c3820887fc8789e959f59a57c8ee436f1bf2
--- /dev/null
+++ b/src/dap_pkey.c
@@ -0,0 +1,90 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net    https:/gitlab.com/demlabs
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <string.h>
+#include "dap_common.h"
+#include "dap_pkey.h"
+
+#define LOG_TAG "chain_key"
+//static dap_pkey_t m_dap_pkey_null={0}; // For sizeof nothing more
+
+
+/**
+ * @brief dap_pkey_from_enc_key
+ * @param a_key
+ * @return
+ */
+dap_pkey_t* dap_pkey_from_enc_key(dap_enc_key_t *a_key)
+{
+    if (a_key->pub_key_data_size > 0 ){
+        dap_pkey_t * l_ret = NULL;
+        l_ret = DAP_NEW_Z_SIZE(dap_pkey_t,dap_pkey_from_enc_key_output_calc(a_key));
+        if( dap_pkey_from_enc_key_output(a_key,l_ret) != 0 ) {
+            DAP_DELETE(l_ret);
+            return NULL;
+        }else
+            return l_ret;
+    }
+
+    return NULL;
+}
+
+/**
+ * @brief dap_pkey_from_enc_key_output
+ * @param a_key
+ * @param a_output
+ * @return
+ */
+int dap_pkey_from_enc_key_output(dap_enc_key_t *a_key, void * a_output)
+{
+    dap_pkey_t * l_output = (dap_pkey_t *) a_output;
+    if (a_key->pub_key_data_size > 0 ){
+        switch (a_key->type) {
+            case DAP_ENC_KEY_TYPE_SIG_BLISS:
+                l_output->header.type.type = PKEY_TYPE_SIGN_BLISS ;
+            break;
+            case DAP_ENC_KEY_TYPE_SIG_TESLA:
+                l_output->header.type.type = PKEY_TYPE_SIGN_TESLA ;
+            break;
+            case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+                l_output->header.type.type = PKEY_TYPE_SIGN_PICNIC ;
+            break;
+            case DAP_ENC_KEY_TYPE_SIG_DILITHIUM:
+                l_output->header.type.type = PKEY_TYPE_SIGN_DILITHIUM;
+            break;
+
+            default:
+                log_it(L_WARNING,"No serialization preset");
+                return -1;
+        }
+        l_output->header.size = a_key->pub_key_data_size;
+        memcpy(l_output->pkey,a_key->pub_key_data,a_key->pub_key_data_size);
+        return 0;
+    }else{
+        log_it(L_WARNING, "No public key in the input enc_key object");
+        return -2;
+    }
+    return -3;
+}
+
+
diff --git a/src/dap_sign.c b/src/dap_sign.c
new file mode 100755
index 0000000000000000000000000000000000000000..b7f436d9548fd49fbcd23cec5d5f4f71408222f8
--- /dev/null
+++ b/src/dap_sign.c
@@ -0,0 +1,350 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net    https:/gitlab.com/demlabs
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+
+#include "dap_common.h"
+#include "dap_hash.h"
+#include "dap_sign.h"
+#include "dap_enc_bliss.h"
+#include "dap_enc_tesla.h"
+#include "dap_enc_picnic.h"
+#include "dap_enc_dilithium.h"
+
+#define LOG_TAG "dap_sign"
+
+static dap_sign_t * s_sign_null = NULL;
+static bliss_signature_t s_sign_bliss_null = {0};
+
+// calc signature size
+size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t * a_key, size_t a_output_wish_size )
+{
+    size_t l_sign_size = 0;
+    switch (a_key->type){
+        case DAP_ENC_KEY_TYPE_SIG_BLISS: l_sign_size = sizeof(s_sign_bliss_null); break;
+        case DAP_ENC_KEY_TYPE_SIG_PICNIC: l_sign_size = dap_enc_picnic_calc_signature_size(a_key); break;
+        case DAP_ENC_KEY_TYPE_SIG_TESLA: l_sign_size = dap_enc_tesla_calc_signature_size(); break;
+        case DAP_ENC_KEY_TYPE_SIG_DILITHIUM: l_sign_size = dap_enc_dilithium_calc_signature_unserialized_size(); break;
+        default : return 0;
+
+    }
+    return l_sign_size;
+    //return sizeof(s_sign_null->header)+ a_key->pub_key_data_size + l_sign_size;
+}
+
+
+/**
+ * @brief dap_sign_type_from_key_type
+ * @param a_key_type
+ * @return
+ */
+dap_sign_type_t dap_sign_type_from_key_type( dap_enc_key_type_t a_key_type)
+{
+    dap_sign_type_t l_sign_type;
+    switch (a_key_type){
+        case DAP_ENC_KEY_TYPE_SIG_BLISS: l_sign_type.type = SIG_TYPE_BLISS; break;
+        case DAP_ENC_KEY_TYPE_SIG_PICNIC: l_sign_type.type = SIG_TYPE_PICNIC; break;
+        case DAP_ENC_KEY_TYPE_SIG_TESLA: l_sign_type.type = SIG_TYPE_TESLA; break;
+        case DAP_ENC_KEY_TYPE_SIG_DILITHIUM: l_sign_type.type = SIG_TYPE_DILITHIUM; break;
+        default: l_sign_type.raw = 0;
+    }
+    return l_sign_type;
+}
+
+/**
+ * @brief dap_sign_type_to_key_type
+ * @param a_chain_sign_type
+ * @return
+ */
+dap_enc_key_type_t  dap_sign_type_to_key_type(dap_sign_type_t  a_chain_sign_type)
+{
+    switch (a_chain_sign_type.type) {
+        case SIG_TYPE_BLISS: return DAP_ENC_KEY_TYPE_SIG_BLISS;
+        case SIG_TYPE_TESLA: return DAP_ENC_KEY_TYPE_SIG_TESLA;
+        case SIG_TYPE_PICNIC: return DAP_ENC_KEY_TYPE_SIG_PICNIC;
+        case SIG_TYPE_DILITHIUM: return DAP_ENC_KEY_TYPE_SIG_DILITHIUM;
+        default: return DAP_ENC_KEY_TYPE_NULL;
+    }
+}
+
+
+
+/**
+ * @brief dap_sign_type_to_str
+ * @param a_chain_sign_type
+ * @return
+ */
+const char * dap_sign_type_to_str(dap_sign_type_t a_chain_sign_type)
+{
+    switch (a_chain_sign_type.type) {
+        case SIG_TYPE_BLISS: return "sig_bliss";
+        case SIG_TYPE_TESLA: return "sig_tesla";
+        case SIG_TYPE_PICNIC: return "sig_picnic";
+        case SIG_TYPE_DILITHIUM: return "sig_dil";
+        default: return "UNDEFINED";//DAP_ENC_KEY_TYPE_NULL;
+    }
+
+}
+
+/**
+ * @brief dap_pkey_type_from_sign
+ * @param a_pkey_type
+ * @return
+ */
+dap_sign_type_t dap_pkey_type_from_sign( dap_pkey_type_t a_pkey_type)
+{
+    dap_sign_type_t l_sign_type={0};
+    switch (a_pkey_type.type){
+        case PKEY_TYPE_SIGN_BLISS: l_sign_type.type = SIG_TYPE_BLISS; break;
+        case PKEY_TYPE_SIGN_PICNIC: l_sign_type.type = SIG_TYPE_PICNIC; break;
+        case PKEY_TYPE_SIGN_TESLA: l_sign_type.type = SIG_TYPE_TESLA; break;
+        case PKEY_TYPE_SIGN_DILITHIUM : l_sign_type.type = SIG_TYPE_DILITHIUM; break;
+        case PKEY_TYPE_MULTI: l_sign_type.type = SIG_TYPE_MULTI; break;
+        case PKEY_TYPE_NULL: l_sign_type.type = SIG_TYPE_NULL; break;
+    }
+    return l_sign_type;
+}
+
+
+/**
+ * @brief dap_sign_type_from_str
+ * @param a_type_str
+ * @return
+ */
+dap_sign_type_t dap_sign_type_from_str(const char * a_type_str)
+{
+    dap_sign_type_t l_sign_type = {0};
+    if ( strcmp (a_type_str,"sig_bliss") == 0 ){
+        l_sign_type.type = SIG_TYPE_BLISS;
+    } else if ( strcmp (a_type_str,"sig_tesla") == 0){
+        l_sign_type.type = SIG_TYPE_TESLA;
+    } else if ( strcmp (a_type_str,"sig_picnic") == 0){
+        l_sign_type.type = SIG_TYPE_PICNIC;
+    }else if ( strcmp (a_type_str,"sig_dil") == 0){
+        l_sign_type.type = SIG_TYPE_DILITHIUM;
+    }else{
+       log_it (L_WARNING, "Wrong sign type string \"%s\"",a_type_str);
+    }
+    return l_sign_type;
+}
+
+/**
+ * @brief dap_sign_create_output
+ * @param a_key
+ * @param a_data
+ * @param a_data_size
+ * @param a_output [in/out]
+ * @return
+ */
+static 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)
+{
+    if(!a_key || !a_key->priv_key_data || !a_key->priv_key_data_size){
+        log_it (L_ERROR, "Can't find the private key to create signature");
+        return -1;
+    }
+    switch (a_key->type) {
+        case DAP_ENC_KEY_TYPE_SIG_TESLA:
+        case DAP_ENC_KEY_TYPE_SIG_PICNIC:
+        case DAP_ENC_KEY_TYPE_SIG_DILITHIUM:
+                // For PICNIC a_output_size should decrease
+            *a_output_size = dap_enc_sig_dilithium_get_sign(a_key,a_data,a_data_size,a_output,sizeof(dilithium_signature_t));
+             //       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_sign_create
+ * @param a_key
+ * @param a_data
+ * @param a_data_size
+ * @param a_output_wish_size
+ * @return
+ */
+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)
+{
+    // calculate max signature size
+    size_t l_sign_unserialized_size = dap_sign_create_output_unserialized_calc_size(a_key, a_output_wish_size);
+    if(l_sign_unserialized_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_unserialized = DAP_NEW_Z_SIZE(uint8_t, l_sign_unserialized_size);
+        // calc signature [sign_size may decrease slightly]
+        if( dap_sign_create_output(a_key, a_data, a_data_size,
+                                         l_sign_unserialized, &l_sign_unserialized_size) != 0) {
+            dap_enc_key_signature_delete(a_key->type, l_sign_unserialized);
+            DAP_DELETE(l_pub_key);
+            return NULL;
+        } else {
+            size_t l_sign_ser_size = l_sign_unserialized_size;
+            uint8_t *l_sign_ser = dap_enc_key_serealize_sign(a_key->type, l_sign_unserialized, &l_sign_ser_size);
+            if ( l_sign_ser ){
+                dap_sign_t * l_ret = DAP_NEW_Z_SIZE(dap_sign_t,
+                        sizeof(dap_sign_hdr_t) + l_sign_ser_size + l_pub_key_size);
+                // write serialized public key to dap_sign_t
+                memcpy(l_ret->pkey_n_sign, l_pub_key, l_pub_key_size);
+                l_ret->header.type = dap_sign_type_from_key_type(a_key->type);
+                // write serialized signature to dap_sign_t
+                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;
+                DAP_DELETE(l_sign_ser);
+                dap_enc_key_signature_delete(a_key->type, l_sign_unserialized);
+                DAP_DELETE(l_pub_key);
+                return l_ret;
+            }else {
+                log_it(L_WARNING,"Can't serialize signature: NULL returned");
+                return NULL;
+            }
+        }
+    }
+    return NULL;
+}
+
+/**
+ * @brief dap_sign_get_sign
+ * @param a_sign
+ * @param a_sign_out
+ * @return
+ */
+uint8_t* dap_sign_get_sign(dap_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;
+}
+
+/**
+ * @brief dap_sign_get_pkey
+ * @param a_sign
+ * @param a_pub_key_out
+ * @return
+ */
+uint8_t* dap_sign_get_pkey(dap_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_sign_get_pkey_hash
+ * @param a_sign
+ * @param a_sign_hash
+ * @return
+ */
+bool dap_sign_get_pkey_hash(dap_sign_t *a_sign, dap_chain_hash_fast_t * a_sign_hash)
+{
+    if(!a_sign){
+        log_it( L_WARNING, "Sign is NULL on enter");
+        return false;
+    }
+    if( ! a_sign->header.sign_pkey_size ){
+        log_it( L_WARNING, "Sign public key's size is 0");
+        return false;
+    }
+    return dap_hash_fast( a_sign->pkey_n_sign,a_sign->header.sign_pkey_size,a_sign_hash );
+}
+
+
+/**
+ * @brief dap_sign_to_enc_key
+ * @param a_chain_sign
+ * @return
+ */
+dap_enc_key_t *dap_sign_to_enc_key(dap_sign_t * a_chain_sign)
+{
+    dap_enc_key_t * l_ret =  dap_enc_key_new( dap_sign_type_to_key_type( a_chain_sign->header.type  ) );
+    size_t l_pkey_size = 0;
+    uint8_t *l_pkey = dap_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;
+}
+
+/**
+ * @brief dap_sign_verify
+ * @param a_chain_sign
+ * @param a_data
+ * @param a_data_size
+ * @return 1 valid signature, 0 invalid signature, -1 unsupported sign type
+ */
+int dap_sign_verify(dap_sign_t * a_chain_sign, const void * a_data, const size_t a_data_size)
+{
+    int l_ret;
+    dap_enc_key_t * l_key = dap_sign_to_enc_key(a_chain_sign);
+    size_t l_sign_size = a_chain_sign->header.sign_size;
+    size_t l_sign_ser_size;
+    uint8_t *l_sign_ser = dap_sign_get_sign(a_chain_sign, &l_sign_ser_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:
+    case DAP_ENC_KEY_TYPE_SIG_DILITHIUM:
+        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_enc_key_signature_delete(l_key->type, l_sign);
+    dap_enc_key_delete(l_key);
+    return l_ret;
+}
+
+/**
+ * Get size of struct dap_sign_t
+ */
+size_t dap_sign_get_size(dap_sign_t * a_chain_sign)
+{
+    if(!a_chain_sign)
+        return 0;
+    return (sizeof(dap_sign_t) + a_chain_sign->header.sign_size + a_chain_sign->header.sign_pkey_size);
+}
diff --git a/test/cert/CMakeLists.txt b/test/cert/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..0885e429f2a231cff1ae84cbefa3b2315aee4971
--- /dev/null
+++ b/test/cert/CMakeLists.txt
@@ -0,0 +1,18 @@
+if(TARGET crypto_cert_test)
+    return() # The project has already been built.
+endif()
+project(crypto_cert_test)
+
+add_subdirectory(libdap-test)
+
+file(GLOB SOURCES *.c)
+file(GLOB HEADERS *.h)
+
+add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
+
+target_link_libraries(${PROJECT_NAME} dap_crypto dap_core  dap_test)
+
+add_test(
+    NAME crypto_cert_test
+    COMMAND crypto_cert_test
+)
diff --git a/test/cert/dap_crypto_cert_save_tests.c b/test/cert/dap_crypto_cert_save_tests.c
new file mode 100755
index 0000000000000000000000000000000000000000..96a14206c3b08d30fccec9d42024a30eb6ec9ba4
--- /dev/null
+++ b/test/cert/dap_crypto_cert_save_tests.c
@@ -0,0 +1,66 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "dap_test.h"
+#include "dap_enc_key.h"
+#include "dap_cert.h"
+#include "dap_cert_file.h"
+
+#define CERT_FILE_PATH "cert_file_path.tmp"
+
+static void test_cert_memory_file(dap_enc_key_type_t a_key_type)
+{
+  uint32_t l_cert_buf_size = 0;
+
+  dap_cert_t *l_cert = dap_cert_generate_mem("name 1", a_key_type);
+  dap_assert_PIF(l_cert, "Fail create cert");
+
+  uint8_t * l_cert_buf = dap_cert_mem_save(l_cert, &l_cert_buf_size);
+  dap_assert_PIF(l_cert_buf, "Fail save cert to memory");
+  dap_cert_delete(l_cert);
+
+  dap_cert_t *l_cert2 = dap_cert_mem_load(l_cert_buf, l_cert_buf_size);
+  dap_assert_PIF(l_cert2, "Fail read cert from memory");
+  dap_cert_delete(l_cert2);
+  DAP_DELETE(l_cert_buf);
+
+  dap_pass_msg("Save and load cert in memory successfully");
+
+  dap_cert_t *l_certf = dap_cert_generate_mem("name 2", a_key_type);
+  int l_res = dap_cert_file_save(l_certf, CERT_FILE_PATH);
+  dap_assert_PIF(!l_res, "Fail save cert to file");
+  dap_cert_delete(l_certf);
+
+  dap_cert_t *l_certf2 = dap_cert_file_load(CERT_FILE_PATH);
+  dap_assert_PIF(l_certf2, "Fail load cert from file");
+  dap_cert_delete(l_certf2);
+
+  // delete temp file
+  unlink(CERT_FILE_PATH);
+
+  dap_pass_msg("Save and load cert in file successfully");
+}
+
+void init_test_case()
+{
+    dap_enc_key_init();
+}
+
+void cleanup_test_case()
+{
+    dap_enc_key_deinit();
+}
+
+void dap_crypto_cert_save_tests_run(void)
+{
+    dap_print_module_name("dap_cert_save");
+    init_test_case();
+
+    test_cert_memory_file(DAP_ENC_KEY_TYPE_SIG_BLISS);
+    test_cert_memory_file(DAP_ENC_KEY_TYPE_SIG_TESLA);
+    test_cert_memory_file(DAP_ENC_KEY_TYPE_SIG_PICNIC);
+    test_cert_memory_file(DAP_ENC_KEY_TYPE_SIG_DILITHIUM);
+
+    cleanup_test_case();
+}
diff --git a/test/cert/dap_crypto_cert_save_tests.h b/test/cert/dap_crypto_cert_save_tests.h
new file mode 100755
index 0000000000000000000000000000000000000000..a4002ef71a8c058cbdd602e3a8f4549f956ec7ca
--- /dev/null
+++ b/test/cert/dap_crypto_cert_save_tests.h
@@ -0,0 +1,4 @@
+#pragma once
+#include "dap_test.h"
+
+void dap_crypto_cert_save_tests_run(void);
diff --git a/test/cert/dap_sha3_tests.c b/test/cert/dap_sha3_tests.c
new file mode 100644
index 0000000000000000000000000000000000000000..7a58271861c6fb8eed36f2a291b0479e8d4df87d
--- /dev/null
+++ b/test/cert/dap_sha3_tests.c
@@ -0,0 +1,211 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <memory.h>
+#include <time.h>
+#include <stdbool.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include <pthread.h>
+
+#include "dap_test.h"
+
+#define BUFSIZE 512
+
+#ifdef _MSC_VER
+  #define DAP_STATIC_INLINE static __forceinline
+  #define DAP_INLINE __forceinline
+  #define DAP_ALIGNED(x) __declspec( align(x) )
+#else
+  #define DAP_STATIC_INLINE static __attribute__((always_inline)) inline
+  #define DAP_INLINE __attribute__((always_inline)) inline
+  #define DAP_ALIGNED(x) __attribute__ ((aligned (x)))
+#endif
+
+uint32_t xs30_seed[4] = { 0x3D696D09, 0xCD6BEB33, 0x9D1A0022, 0x9D1B0022 };
+
+static inline void zRAND_reset( void ) {
+
+  xs30_seed[0] = 0x3D696D09;
+  xs30_seed[1] = 0xCD6BEB33;
+  xs30_seed[2] = 0x9D1A0022;
+  xs30_seed[3] = 0x9D1B0022;
+}
+
+static inline uint32_t zRAND( void ) {          //period 2^96-1
+
+  uint32_t *zseed = &xs30_seed[0];
+
+  uint32_t  t;
+
+  zseed[0] ^= zseed[0] << 16;
+  zseed[0] ^= zseed[0] >> 5;
+  zseed[0] ^= zseed[0] << 1;
+
+  t = zseed[0];
+  zseed[0] = zseed[1];
+  zseed[1] = zseed[2];
+
+  zseed[2] = t ^ zseed[0] ^ zseed[1];
+
+  return zseed[0];
+}
+
+static inline uint64_t gettime64( void )
+{
+  uint64_t t64;
+  struct timespec now;
+
+  clock_gettime( CLOCK_MONOTONIC, &now );
+  t64 = now.tv_sec;
+  t64 *= 1000000000;
+  t64 += now.tv_nsec;
+
+  return t64;
+}
+
+static inline double gettimefloat( void )
+{
+  return (double)gettime64() / 1000000000.0;
+}
+
+#include "keccak.h"
+#include "XKCP/lib/high/Keccak/FIPS202/KeccakHash.h"
+#include "fips202.h"
+#include "SimpleFIPS202.h"
+
+#define DAP_CHAIN_HASH_FAST_SIZE    32
+
+typedef union dap_chain_hash_fast{
+    uint8_t raw[DAP_CHAIN_HASH_FAST_SIZE];
+} dap_chain_hash_fast_t;
+
+typedef enum dap_hash_type {
+    DAP_HASH_TYPE_KECCAK = 0,
+    DAP_HASH_TYPE_SLOW_0 = 1,
+} dap_hash_type_t;
+
+static inline void dap_hash_keccak( const void * a_in, size_t a_in_size, void *a_out, size_t a_out_size )
+{
+    keccak((const uint8_t*) a_in, a_in_size, (uint8_t *) a_out,(int)  a_out_size );
+}
+
+static inline void dap_hash(const void * a_data_in, size_t a_data_in_size,
+                     void * a_data_out, size_t a_data_out_size,
+                     dap_hash_type_t a_type ){
+    switch (a_type){
+        case DAP_HASH_TYPE_KECCAK:
+            dap_hash_keccak(a_data_in,a_data_in_size, a_data_out,a_data_out_size);
+        break;
+//        case DAP_HASH_TYPE_SLOW_0:
+//            if( a_data_out_size>= dap_hash_slow_size() ){
+//                dap_hash_slow(a_data_in,a_data_in_size,(char*) a_data_out);
+//            }
+//        break;
+    }
+}
+
+int dap_hash_fast( const 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;
+}
+
+#define DATA_SIZE 2048
+
+uint8_t data[8192];
+uint8_t data2[8192];
+
+Keccak_HashInstance ki0;
+
+#define print_hash( x )          \
+  printf( "  hash = " );         \
+  for( int g = 0; g < 32; ++g )  \
+    printf( "%02X", x[g] );      \
+  printf( "\n" );                \
+
+void dap_sha3_tests_run(void)
+{
+  dap_chain_hash_fast_t hash0;
+  uint64_t start;
+  double t;
+
+  uint8_t hash2[32];
+
+  dap_print_module_name("dap_sha3_tests_run( )");
+
+//  printf("dap_hash_fast( ) of %u data x %u ...\n", DATA_SIZE, 65536 );
+
+  for (int i = 0; i < DATA_SIZE; ++ i ) {
+    data[i] = zRAND( ) & 255;
+  }
+
+  zRAND_reset( );
+  start = gettime64( );
+
+  for (int h = 0; h < 65536; h ++ ) {
+    dap_hash_fast( &data[0], DATA_SIZE, &hash0 );
+  }
+
+  t = (double)(gettime64( ) - start) / 1000000000.0;
+  benchmark_mgs_rate( "dap_hash_fast_sha3(monero_crypto)(2048)", 65536.0 / t );
+  print_hash( hash0.raw );
+
+//  printf("Keccak_sha_256( ) of %u data x %u ...\n", DATA_SIZE,  65536 );
+  start = gettime64( );
+
+  for (int h = 0; h < 65536; h ++ ) {
+    SHA3_256( &hash2[0], &data[0], DATA_SIZE );
+  }
+  t = (double)(gettime64( ) - start) / 1000000000.0;
+  benchmark_mgs_rate( "SHA_256(XKCP)(2048)", 65536.0 / t );
+  print_hash( hash2 );
+
+//  printf("sha3_512(dap_crypto) of %u data x %u ...\n", DATA_SIZE,  65536 );
+  start = gettime64( );
+
+  for (int h = 0; h < 65536; h ++ ) {
+      sha3_256( &hash2[0], &data[0], DATA_SIZE );
+  }
+
+  t = (double)(gettime64( ) - start) / 1000000000.0;
+  benchmark_mgs_rate( "sha3_256(dap_crypto)(2048)", 65536.0 / t );
+
+  print_hash( hash2 );
+
+//  printf("shake256(dap_crypto) of %u data x %u ...\n", DATA_SIZE,  65536 );
+  start = gettime64( );
+
+  for (int h = 0; h < 65536; h ++ ) {
+      shake256( &hash2[0], 32, &data[0], DATA_SIZE );
+  }
+
+  t = (double)(gettime64( ) - start) / 1000000000.0;
+  benchmark_mgs_rate( "shake256(dap_crypto)(2048)", 65536.0 / t );
+  print_hash( hash2 );
+
+//  printf("SHAKE256 of %u data x %u ...\n", DATA_SIZE,  65536 );
+  start = gettime64( );
+
+  for (int h = 0; h < 65536; h ++ ) {
+      SHAKE256( &hash2[0], 32, &data[0], DATA_SIZE );
+  }
+
+  t = (double)(gettime64( ) - start) / 1000000000.0;
+  benchmark_mgs_rate( "SHAKE256(XKCP)(2048)", 65536.0 / t );
+
+  print_hash( hash2 );
+
+  dap_pass_msg("dap_sha3_tests_run( )");
+
+  return;
+}
\ No newline at end of file
diff --git a/test/cert/main.c b/test/cert/main.c
new file mode 100755
index 0000000000000000000000000000000000000000..0fc3c08f0f086e2faa3772f6589b0f2f5df8152a
--- /dev/null
+++ b/test/cert/main.c
@@ -0,0 +1,12 @@
+#include "dap_common.h"
+#include "dap_crypto_cert_save_tests.h"
+
+void dap_sha3_tests_run(void);
+
+int main(void) {
+    // switch off debug info from library
+    dap_log_level_set(L_CRITICAL);
+    dap_crypto_cert_save_tests_run();
+    dap_sha3_tests_run();
+    return 0;
+}