From 5337a6cbf95753229313dee80abce2019b072e52 Mon Sep 17 00:00:00 2001
From: Roman Khlopkov <roman.khlopkov@demlabs.net>
Date: Sat, 2 May 2020 14:13:52 +0000
Subject: [PATCH] support-3409

---
 include/dap_sign.h                    |  19 +-
 src/dap_sign.c                        | 452 +++++++++++++++++---------
 test/crypto/dap_enc_sign_multi_test.c |  11 +-
 3 files changed, 317 insertions(+), 165 deletions(-)

diff --git a/include/dap_sign.h b/include/dap_sign.h
index ef4f027..b599e78 100755
--- a/include/dap_sign.h
+++ b/include/dap_sign.h
@@ -67,7 +67,7 @@ typedef struct dap_sign
 #define MULTI_SIGN_MAX_COUNT 255
 
 typedef struct _dap_multi_sign_params_t {
-    dap_sign_type_enum_t type;          // Multi-signature type
+    dap_sign_type_t type;               // Multi-signature type
     uint8_t total_count;                // Total key count
     uint8_t sign_count;                 // Signatures count
     uint8_t *key_seq;                   // Signing key sequence
@@ -82,11 +82,11 @@ typedef struct _dap_multi_sign_meta_t {
 typedef struct _dap_multi_sign_keys_t {
     uint8_t num;
     dap_sign_type_t type;
-} dap_multi_sign_keys_t;
+} DAP_ALIGN_PACKED dap_multi_sign_keys_t;
 
 typedef struct _dap_multi_sign_t {
 /*** Hashed metadata ***/
-    dap_sign_type_enum_t type;          // Multi-signature type
+    dap_sign_type_t type;               // Multi-signature type
     uint8_t total_count;                // Total key count
     uint8_t sign_count;                 // Signatures count
     dap_multi_sign_keys_t *key_seq;     // Signing key sequence
@@ -128,12 +128,13 @@ 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);
 
-
-dap_multi_sign_params_t *dap_multi_sign_params_make(dap_sign_type_enum_t type, uint8_t total_count, uint8_t sign_count, dap_enc_key_t *key1, ...);
-void dap_multi_sign_params_delete(dap_multi_sign_params_t *params);
-dap_multi_sign_t *dap_multi_sign_create(dap_multi_sign_params_t *params, const void *data, const size_t data_size);
-int dap_multi_sign_verify(dap_multi_sign_t *sign, const void *data, const size_t data_size);
-void dap_multi_sign_delete(dap_multi_sign_t *sign);
+uint8_t *dap_multi_sign_serialize(dap_multi_sign_t *a_sign, size_t *a_out_len);
+dap_multi_sign_t *dap_multi_sign_deserialize(dap_sign_type_enum_t a_type, uint8_t *a_sign, size_t a_sign_len);
+dap_multi_sign_params_t *dap_multi_sign_params_make(dap_sign_type_enum_t a_type, uint8_t a_total_count, uint8_t a_sign_count, dap_enc_key_t *a_key1, ...);
+void dap_multi_sign_params_delete(dap_multi_sign_params_t *a_params);
+dap_multi_sign_t *dap_multi_sign_create(dap_multi_sign_params_t *a_params, const void *a_data, const size_t a_data_size);
+int dap_multi_sign_verify(dap_multi_sign_t *a_sign, const void *a_data, const size_t a_data_size);
+void dap_multi_sign_delete(dap_multi_sign_t *a_sign);
 
 #ifdef __cplusplus
 }
diff --git a/src/dap_sign.c b/src/dap_sign.c
index 6db1f54..35119c6 100755
--- a/src/dap_sign.c
+++ b/src/dap_sign.c
@@ -377,263 +377,405 @@ size_t dap_sign_get_size(dap_sign_t * a_chain_sign)
     return (sizeof(dap_sign_t) + a_chain_sign->header.sign_size + a_chain_sign->header.sign_pkey_size);
 }
 
+
+/**
+ * @brief dap_multi_sign_calc_size Auxiliary function to calculate multi-signature strucrutre size
+ * @param a_sign The multi-signature
+ * @return Multi-signature size
+ */
+size_t dap_multi_sign_calc_size(dap_multi_sign_t *a_sign)
+{
+    if (!a_sign)
+        return 0;
+    size_t l_meta_data_size = sizeof(dap_sign_type_t) + 2 * sizeof(uint8_t) +
+            a_sign->sign_count * (sizeof(dap_multi_sign_keys_t) + sizeof(dap_multi_sign_meta_t));
+    size_t l_pkeys_hashes_size = a_sign->total_count * sizeof(dap_chain_hash_fast_t);
+    size_t l_pkeys_size = 0, l_signes_size = 0;
+    for (int i = 0; i < a_sign->sign_count; i++) {
+        l_pkeys_size += a_sign->meta[i].pkey_size;
+        l_signes_size += a_sign->meta[i].sign_size;
+    }
+    return l_meta_data_size + l_pkeys_hashes_size + l_pkeys_size + l_signes_size;
+}
+
+/**
+ * @brief dap_multi_sign_serialize Makes a serialization for multi-signature structure
+ * @param a_sign Pointer to multi-signature
+ * @param a_out_len OUT Output data lenght
+ * @return Pointer to serialized data
+ */
+uint8_t *dap_multi_sign_serialize(dap_multi_sign_t *a_sign, size_t *a_out_len)
+{
+    if (a_sign->type.type != SIG_TYPE_MULTI_CHAINED) {
+        log_it(L_ERROR, "Unsupported multi-signature type");
+        return NULL;
+    }
+    *a_out_len = dap_multi_sign_calc_size(a_sign) + sizeof(size_t);
+    uint8_t *l_ret = DAP_NEW_SIZE(uint8_t, *a_out_len);
+    size_t l_mem_shift = 0;
+    memcpy(l_ret, a_out_len, sizeof(size_t));
+    l_mem_shift += sizeof(size_t);
+    memcpy(&l_ret[l_mem_shift], &a_sign->type, sizeof(dap_sign_type_t));
+    l_mem_shift += sizeof(dap_sign_type_t);
+    memcpy(&l_ret[l_mem_shift], &a_sign->total_count, 1);
+    l_mem_shift++;
+    memcpy(&l_ret[l_mem_shift], &a_sign->sign_count, 1);
+    l_mem_shift++;
+    for (int i = 0; i < a_sign->sign_count; i++) {
+        memcpy(&l_ret[l_mem_shift], &a_sign->key_seq[i].num, 1);
+        l_mem_shift++;
+        memcpy(&l_ret[l_mem_shift], &a_sign->key_seq[i].type, sizeof(dap_sign_type_t));
+        l_mem_shift += sizeof(dap_sign_type_t);
+    }
+    for (int i = 0; i < a_sign->sign_count; i++) {
+        memcpy(&l_ret[l_mem_shift], &a_sign->meta[i].pkey_size, sizeof(uint32_t));
+        l_mem_shift += sizeof(uint32_t);
+        memcpy(&l_ret[l_mem_shift], &a_sign->meta[i].sign_size, sizeof(uint32_t));
+        l_mem_shift += sizeof(uint32_t);
+    }
+    for (int i = 0; i < a_sign->total_count; i++) {
+        memcpy(&l_ret[l_mem_shift], &a_sign->key_hashes[i], sizeof(dap_chain_hash_fast_t));
+        l_mem_shift += sizeof(dap_chain_hash_fast_t);
+    }
+    uint32_t l_data_shift = 0, l_data_size = 0;
+    for (int i = 0; i < a_sign->sign_count; i++) {
+        l_data_size = a_sign->meta[i].pkey_size;
+        memcpy(&l_ret[l_mem_shift], &a_sign->pub_keys[l_data_shift], l_data_size);
+        l_mem_shift += l_data_size;
+        l_data_shift += l_data_size;
+    }
+    l_data_shift = l_data_size = 0;
+    for (int i = 0; i < a_sign->sign_count; i++) {
+        l_data_size = a_sign->meta[i].sign_size;
+        memcpy(&l_ret[l_mem_shift], &a_sign->sign_data[l_data_shift], l_data_size);
+        l_mem_shift += l_data_size;
+        l_data_shift += l_data_size;
+    }
+    return l_ret;
+}
+
+/**
+ * @brief dap_multi_sign_deserialize Makes a deserialization for multi-signature structure
+ * @param a_sign Pointer to serialized data
+ * @param a_sign_len Input data lenght
+ * @return Pointer to multi-signature
+ */
+dap_multi_sign_t *dap_multi_sign_deserialize(dap_sign_type_enum_t a_type, uint8_t *a_sign, size_t a_sign_len)
+{
+    if (a_type != SIG_TYPE_MULTI_CHAINED) {
+        log_it(L_ERROR, "Unsupported multi-signature type");
+        return NULL;
+    }
+    size_t l_sign_len = *(size_t *)a_sign;
+    if (l_sign_len != a_sign_len) {
+        return NULL;
+    }
+    dap_multi_sign_t *l_sign = DAP_NEW(dap_multi_sign_t);
+    size_t l_mem_shift = sizeof(size_t);
+    memcpy(&l_sign->type, &a_sign[l_mem_shift], sizeof(dap_sign_type_t));
+    l_mem_shift += sizeof(dap_sign_type_t);
+    memcpy(&l_sign->total_count, &a_sign[l_mem_shift], 1);
+    l_mem_shift++;
+    memcpy(&l_sign->sign_count, &a_sign[l_mem_shift], 1);
+    l_mem_shift++;
+    l_sign->key_seq = DAP_NEW_SIZE(dap_multi_sign_keys_t, l_sign->sign_count * sizeof(dap_multi_sign_keys_t));
+    for (int i = 0; i < l_sign->sign_count; i++) {
+        memcpy(&l_sign->key_seq[i].num, &a_sign[l_mem_shift], 1);
+        l_mem_shift++;
+        memcpy(&l_sign->key_seq[i].type, &a_sign[l_mem_shift], sizeof(dap_sign_type_t));
+        l_mem_shift += sizeof(dap_sign_type_t);
+    }
+    l_sign->meta = DAP_NEW_SIZE(dap_multi_sign_meta_t, l_sign->sign_count * sizeof(dap_multi_sign_meta_t));
+    size_t l_pkeys_size = 0, l_signes_size = 0;
+    for (int i = 0; i < l_sign->sign_count; i++) {
+        memcpy(&l_sign->meta[i].pkey_size, &a_sign[l_mem_shift], sizeof(uint32_t));
+        l_mem_shift += sizeof(uint32_t);
+        l_pkeys_size += l_sign->meta[i].pkey_size;
+        memcpy(&l_sign->meta[i].sign_size, &a_sign[l_mem_shift], sizeof(uint32_t));
+        l_mem_shift += sizeof(uint32_t);
+        l_signes_size += l_sign->meta[i].sign_size;
+    }
+    l_sign->key_hashes = DAP_NEW_SIZE(dap_chain_hash_fast_t, l_sign->total_count * sizeof(dap_chain_hash_fast_t));
+    for (int i = 0; i < l_sign->total_count; i++) {
+        memcpy(&l_sign->key_hashes[i], &a_sign[l_mem_shift], sizeof(dap_chain_hash_fast_t));
+        l_mem_shift += sizeof(dap_chain_hash_fast_t);
+    }
+    uint32_t l_data_shift = 0, l_data_size = 0;
+    l_sign->pub_keys = DAP_NEW_SIZE(uint8_t, l_pkeys_size);
+    for (int i = 0; i < l_sign->sign_count; i++) {
+        l_data_size = l_sign->meta[i].pkey_size;
+        memcpy( &l_sign->pub_keys[l_data_shift], &a_sign[l_mem_shift],l_data_size);
+        l_mem_shift += l_data_size;
+        l_data_shift += l_data_size;
+    }
+    l_data_shift = l_data_size = 0;
+    l_sign->sign_data = DAP_NEW_SIZE(uint8_t, l_signes_size);
+    for (int i = 0; i < l_sign->sign_count; i++) {
+        l_data_size = l_sign->meta[i].sign_size;
+        memcpy(&l_sign->sign_data[l_data_shift], &a_sign[l_mem_shift], l_data_size);
+        l_mem_shift += l_data_size;
+        l_data_shift += l_data_size;
+    }
+    return l_sign;
+}
+
 /**
  * @brief dap_multi_sign_params_make Auxiliary function which helps fill multi-signature params structure
- * @param type Type of multi-signature
- * @param total_count Number of total key count
- * @param sign_count Number of keys participating in multi-signing algorithm
- * @param key[1 .. total_count] Set of keys
- * @param num[1 .. sign_count] Signing keys sequence
+ * @param a_type Type of multi-signature
+ * @param a_total_count Number of total key count
+ * @param a_sign_count Number of keys participating in multi-signing algorithm
+ * @param a_key[1 .. total_count] Set of keys
+ * @param a_num[1 .. sign_count] Signing keys sequence
  * @return Pointer to multi-signature params structure
  */
-dap_multi_sign_params_t *dap_multi_sign_params_make(dap_sign_type_enum_t type, uint8_t total_count, uint8_t sign_count, dap_enc_key_t *key1, ...)
+dap_multi_sign_params_t *dap_multi_sign_params_make(dap_sign_type_enum_t a_type, uint8_t a_total_count, uint8_t a_sign_count, dap_enc_key_t *a_key1, ...)
 {
-    dap_multi_sign_params_t *params = DAP_NEW(dap_multi_sign_params_t);
-    params->type = type;
-    params->total_count = total_count;
-    params->keys = DAP_NEW_SIZE(dap_enc_key_t *, total_count * sizeof(dap_enc_key_t *));
-    params->sign_count = sign_count;
-    params->key_seq = DAP_NEW_SIZE(uint8_t, sign_count);
-    params->keys[0] = key1;
+    dap_multi_sign_params_t *l_params = DAP_NEW(dap_multi_sign_params_t);
+    l_params->type.type = a_type;
+    l_params->total_count = a_total_count;
+    l_params->keys = DAP_NEW_SIZE(dap_enc_key_t *, a_total_count * sizeof(dap_enc_key_t *));
+    l_params->sign_count = a_sign_count;
+    l_params->key_seq = DAP_NEW_SIZE(uint8_t, a_sign_count);
+    l_params->keys[0] = a_key1;
     va_list list;
-    va_start(list, key1);
-    for (int i = 1; i < total_count; i++) {
-        params->keys[i] = va_arg(list, dap_enc_key_t *);
+    va_start(list, a_key1);
+    for (int i = 1; i < a_total_count; i++) {
+        l_params->keys[i] = va_arg(list, dap_enc_key_t *);
     }
-    for (int i = 0; i < sign_count; i++) {
-        params->key_seq[i] = va_arg(list, int) - 1;
+    for (int i = 0; i < a_sign_count; i++) {
+        l_params->key_seq[i] = va_arg(list, int) - 1;
     }
     va_end(list);
-    return params;
+    return l_params;
 }
 
 /**
  * @brief dap_multi_sign_delete Destroy multi-signature params structure
- * @param sign Pointer to multi-signature params structure to destroy
+ * @param a_sign Pointer to multi-signature params structure to destroy
  * @return None
  */
-void dap_multi_sign_params_delete(dap_multi_sign_params_t *params)
+void dap_multi_sign_params_delete(dap_multi_sign_params_t *a_params)
 {
-    if (!params)
+    if (!a_params)
         return;
-    if (params->key_seq) {
-        DAP_DELETE(params->key_seq);
+    if (a_params->key_seq) {
+        DAP_DELETE(a_params->key_seq);
     }
-    if (params->keys) {
-        DAP_DELETE(params->keys);
+    if (a_params->keys) {
+        DAP_DELETE(a_params->keys);
     }
-    DAP_DELETE(params);
+    DAP_DELETE(a_params);
 }
 
 /**
  * @brief dap_multi_sign_hash_data Make multi-signature hash for specified message
- * @param sign Pointer to multi-signature structure
- * @param data Pointer to message to be signed with this multi-signature
- * @param data_size Message size
- * @param hash OUT Pointer to calculated hash
+ * @param a_sign Pointer to multi-signature structure
+ * @param a_data Pointer to message to be signed with this multi-signature
+ * @param a_data_size Message size
+ * @param a_hash OUT Pointer to calculated hash
  * @return True if success, overwise return false
  */
-bool dap_multi_sign_hash_data(dap_multi_sign_t *sign, const void *data, const size_t data_size, dap_chain_hash_fast_t *hash)
+bool dap_multi_sign_hash_data(dap_multi_sign_t *a_sign, const void *a_data, const size_t a_data_size, dap_chain_hash_fast_t *a_hash)
 {
-    uint8_t *concatenated_hash = DAP_NEW_SIZE(uint8_t, 3 * sizeof(dap_chain_hash_fast_t));
-    if (!dap_hash_fast(data, data_size, hash)) {
-        DAP_DELETE(concatenated_hash);
+    uint8_t *l_concatenated_hash = DAP_NEW_SIZE(uint8_t, 3 * sizeof(dap_chain_hash_fast_t));
+    if (!dap_hash_fast(a_data, a_data_size, a_hash)) {
+        DAP_DELETE(l_concatenated_hash);
         return false;
     }
-    memcpy(concatenated_hash, hash, sizeof(dap_chain_hash_fast_t));
-    uint32_t meta_data_size = sizeof(dap_sign_type_enum_t) + 2 * sizeof(uint8_t) + sign->sign_count * sizeof(dap_multi_sign_keys_t);
-    uint8_t *meta_data = DAP_NEW_SIZE(uint8_t, meta_data_size);
-    int meta_data_mem_shift = 0;
-    memcpy(meta_data, &sign->type, sizeof(dap_sign_type_enum_t));
-    meta_data_mem_shift += sizeof(dap_sign_type_enum_t);
-    meta_data[meta_data_mem_shift++] = sign->total_count;
-    meta_data[meta_data_mem_shift++] = sign->sign_count;
-    memcpy(&meta_data[meta_data_mem_shift], sign->key_seq, sign->sign_count * sizeof(dap_multi_sign_keys_t));
-    if (!dap_hash_fast(meta_data, meta_data_size, hash)) {
-        DAP_DELETE(meta_data);
-        DAP_DELETE(concatenated_hash);
+    memcpy(l_concatenated_hash, a_hash, sizeof(dap_chain_hash_fast_t));
+    uint32_t l_meta_data_size = sizeof(dap_sign_type_t) + 2 * sizeof(uint8_t) + a_sign->sign_count * sizeof(dap_multi_sign_keys_t);
+    uint8_t *l_meta_data = DAP_NEW_SIZE(uint8_t, l_meta_data_size);
+    int l_meta_data_mem_shift = 0;
+    memcpy(l_meta_data, &a_sign->type, sizeof(dap_sign_type_t));
+    l_meta_data_mem_shift += sizeof(dap_sign_type_t);
+    l_meta_data[l_meta_data_mem_shift++] = a_sign->total_count;
+    l_meta_data[l_meta_data_mem_shift++] = a_sign->sign_count;
+    memcpy(&l_meta_data[l_meta_data_mem_shift], a_sign->key_seq, a_sign->sign_count * sizeof(dap_multi_sign_keys_t));
+    if (!dap_hash_fast(l_meta_data, l_meta_data_size, a_hash)) {
+        DAP_DELETE(l_meta_data);
+        DAP_DELETE(l_concatenated_hash);
         return false;
     }
-    DAP_DELETE(meta_data);
-    memcpy(concatenated_hash + sizeof(dap_chain_hash_fast_t), hash, sizeof(dap_chain_hash_fast_t));
-    if (!dap_hash_fast(sign->key_hashes, sign->total_count * sizeof(dap_chain_hash_fast_t), hash)) {
-        DAP_DELETE(concatenated_hash);
+    DAP_DELETE(l_meta_data);
+    memcpy(l_concatenated_hash + sizeof(dap_chain_hash_fast_t), a_hash, sizeof(dap_chain_hash_fast_t));
+    if (!dap_hash_fast(a_sign->key_hashes, a_sign->total_count * sizeof(dap_chain_hash_fast_t), a_hash)) {
+        DAP_DELETE(l_concatenated_hash);
         return false;
     }
-    memcpy(concatenated_hash + 2 * sizeof(dap_chain_hash_fast_t), hash, sizeof(dap_chain_hash_fast_t));
-    if (!dap_hash_fast(concatenated_hash, 3 * sizeof(dap_chain_hash_fast_t), hash)) {
-        DAP_DELETE(concatenated_hash);
+    memcpy(l_concatenated_hash + 2 * sizeof(dap_chain_hash_fast_t), a_hash, sizeof(dap_chain_hash_fast_t));
+    if (!dap_hash_fast(l_concatenated_hash, 3 * sizeof(dap_chain_hash_fast_t), a_hash)) {
+        DAP_DELETE(l_concatenated_hash);
         return false;
     }
-    DAP_DELETE(concatenated_hash);
+    DAP_DELETE(l_concatenated_hash);
     return true;
 }
 
 /**
  * @brief dap_multi_sign_create Make multi-signature for specified message
- * @param params Pointer to multi-signature params structure
- * @param data Pointer to message to be signed with this multi-signature
- * @param data_size Message size
+ * @param a_params Pointer to multi-signature params structure
+ * @param a_data Pointer to message to be signed with this multi-signature
+ * @param a_data_size Message size
  * @return Pointer to multi-signature structure for specified message
  */
-dap_multi_sign_t *dap_multi_sign_create(dap_multi_sign_params_t *params, const void *data, const size_t data_size)
+dap_multi_sign_t *dap_multi_sign_create(dap_multi_sign_params_t *a_params, const void *a_data, const size_t a_data_size)
 {
-    if (params->type != SIG_TYPE_MULTI_CHAINED) {
+    if (a_params->type.type != SIG_TYPE_MULTI_CHAINED) {
         log_it (L_ERROR, "Unsupported multi-signature type");
         return NULL;
     }
-    if (!params || !params->total_count) {
-        log_it (L_ERROR, "Can't create multi-signature");
+    if (!a_params || !a_params->total_count) {
+        log_it (L_ERROR, "Wrong parameters of multi-signature");
         return NULL;
     }
-    dap_multi_sign_t *sign = DAP_NEW_Z(dap_multi_sign_t);
-    sign->type = params->type;
-    sign->total_count = params->total_count;
-    sign->key_hashes = DAP_NEW_SIZE(dap_chain_hash_fast_t, params->total_count * sizeof(dap_chain_hash_fast_t));
-    for (int i = 0; i < params->total_count; i++) {
-        if (!dap_hash_fast(params->keys[i]->pub_key_data, params->keys[i]->pub_key_data_size, &sign->key_hashes[i])) {
+    dap_multi_sign_t *l_sign = DAP_NEW_Z(dap_multi_sign_t);
+    l_sign->type = a_params->type;
+    l_sign->total_count = a_params->total_count;
+    l_sign->key_hashes = DAP_NEW_SIZE(dap_chain_hash_fast_t, a_params->total_count * sizeof(dap_chain_hash_fast_t));
+    for (int i = 0; i < a_params->total_count; i++) {
+        if (!dap_hash_fast(a_params->keys[i]->pub_key_data, a_params->keys[i]->pub_key_data_size, &l_sign->key_hashes[i])) {
             log_it (L_ERROR, "Can't create multi-signature hash");
-            dap_multi_sign_delete(sign);
+            dap_multi_sign_delete(l_sign);
             return NULL;
         }
     }
-    sign->sign_count = params->sign_count;
-    sign->key_seq = DAP_NEW_SIZE(dap_multi_sign_keys_t, params->sign_count * sizeof(dap_multi_sign_keys_t));
-    sign->meta = DAP_NEW_SIZE(dap_multi_sign_meta_t, params->sign_count * sizeof(dap_multi_sign_meta_t));
-    for (int i = 0; i < sign->sign_count; i++) {
-        uint8_t num = params->key_seq[i];
-        sign->key_seq[i].num = num;
-        sign->key_seq[i].type = dap_sign_type_from_key_type(params->keys[num]->type);
-    }
-    uint32_t pkeys_mem_shift = 0, signs_mem_shift = 0;
-    size_t pkey_size, sign_size;
-    dap_chain_hash_fast_t data_hash;
-    bool hashed;
-    for (int i = 0; i < sign->sign_count; i++) {
+    l_sign->sign_count = a_params->sign_count;
+    l_sign->key_seq = DAP_NEW_SIZE(dap_multi_sign_keys_t, a_params->sign_count * sizeof(dap_multi_sign_keys_t));
+    l_sign->meta = DAP_NEW_SIZE(dap_multi_sign_meta_t, a_params->sign_count * sizeof(dap_multi_sign_meta_t));
+    for (int i = 0; i < l_sign->sign_count; i++) {
+        uint8_t l_num = a_params->key_seq[i];
+        l_sign->key_seq[i].num = l_num;
+        l_sign->key_seq[i].type = dap_sign_type_from_key_type(a_params->keys[l_num]->type);
+    }
+    uint32_t l_pkeys_mem_shift = 0, l_signs_mem_shift = 0;
+    size_t l_pkey_size, l_sign_size;
+    dap_chain_hash_fast_t l_data_hash;
+    bool l_hashed;
+    for (int i = 0; i < l_sign->sign_count; i++) {
         if (i == 0) {
-             hashed = dap_multi_sign_hash_data(sign, data, data_size, &data_hash);
+             l_hashed = dap_multi_sign_hash_data(l_sign, a_data, a_data_size, &l_data_hash);
         } else {
-             hashed = dap_hash_fast(&sign->sign_data[signs_mem_shift], sign_size, &data_hash);
-             signs_mem_shift += sign_size;
+             l_hashed = dap_hash_fast(&l_sign->sign_data[l_signs_mem_shift], l_sign_size, &l_data_hash);
+             l_signs_mem_shift += l_sign_size;
         }
-        if (!hashed) {
+        if (!l_hashed) {
             log_it (L_ERROR, "Can't create multi-signature hash");
-            dap_multi_sign_delete(sign);
+            dap_multi_sign_delete(l_sign);
             return NULL;
         }
-        int num = sign->key_seq[i].num;
-        dap_sign_t *dap_sign_step = dap_sign_create(params->keys[num], &data_hash, sizeof(dap_chain_hash_fast_t), 0);
-        if (!dap_sign_step) {
+        int l_num = l_sign->key_seq[i].num;
+        dap_sign_t *l_dap_sign_step = dap_sign_create(a_params->keys[l_num], &l_data_hash, sizeof(dap_chain_hash_fast_t), 0);
+        if (!l_dap_sign_step) {
             log_it (L_ERROR, "Can't create multi-signature step signature");
-            dap_multi_sign_delete(sign);
+            dap_multi_sign_delete(l_sign);
             return NULL;
         }
-        uint8_t *pkey = dap_sign_get_pkey(dap_sign_step, &pkey_size);
-        sign->meta[i].pkey_size = pkey_size;
-        if (pkeys_mem_shift == 0) {
-            sign->pub_keys = DAP_NEW_SIZE(uint8_t, pkey_size);
+        uint8_t *l_pkey = dap_sign_get_pkey(l_dap_sign_step, &l_pkey_size);
+        l_sign->meta[i].pkey_size = l_pkey_size;
+        if (l_pkeys_mem_shift == 0) {
+            l_sign->pub_keys = DAP_NEW_SIZE(uint8_t, l_pkey_size);
         } else {
-            sign->pub_keys = DAP_REALLOC(sign->pub_keys, pkeys_mem_shift + pkey_size);
+            l_sign->pub_keys = DAP_REALLOC(l_sign->pub_keys, l_pkeys_mem_shift + l_pkey_size);
         }
-        memcpy(&sign->pub_keys[pkeys_mem_shift], pkey, pkey_size);
-        pkeys_mem_shift += pkey_size;
-        uint8_t *sign_step = dap_sign_get_sign(dap_sign_step, &sign_size);
-        sign->meta[i].sign_size = sign_size;
-        if (signs_mem_shift == 0) {
-            sign->sign_data = DAP_NEW_SIZE(uint8_t, sign_size);
+        memcpy(&l_sign->pub_keys[l_pkeys_mem_shift], l_pkey, l_pkey_size);
+        l_pkeys_mem_shift += l_pkey_size;
+        uint8_t *l_sign_step = dap_sign_get_sign(l_dap_sign_step, &l_sign_size);
+        l_sign->meta[i].sign_size = l_sign_size;
+        if (l_signs_mem_shift == 0) {
+            l_sign->sign_data = DAP_NEW_SIZE(uint8_t, l_sign_size);
         } else {
-            sign->sign_data = DAP_REALLOC(sign->sign_data, signs_mem_shift + sign_size);
+            l_sign->sign_data = DAP_REALLOC(l_sign->sign_data, l_signs_mem_shift + l_sign_size);
         }
-        memcpy(&sign->sign_data[signs_mem_shift], sign_step, sign_size);
-        DAP_DELETE(dap_sign_step);
+        memcpy(&l_sign->sign_data[l_signs_mem_shift], l_sign_step, l_sign_size);
+        DAP_DELETE(l_dap_sign_step);
     }
-    return sign;
+    return l_sign;
 }
 
 /**
  * @brief dap_multi_sign_verify Make verification test for multi-signed message
- * @param sign Pointer to multi-signature structure
- * @param data Pointer to message signed with this multi-signature
- * @param data_size Signed message size
+ * @param a_sign Pointer to multi-signature structure
+ * @param a_data Pointer to message signed with this multi-signature
+ * @param a_data_size Signed message size
  * @return 1 valid signature, 0 invalid signature, -1 verification error
  */
-int dap_multi_sign_verify(dap_multi_sign_t *sign, const void *data, const size_t data_size)
+int dap_multi_sign_verify(dap_multi_sign_t *a_sign, const void *a_data, const size_t a_data_size)
 {
-    if (!sign || !data)
+    if (!a_sign || !a_data)
         return -1;
-    if (sign->type != SIG_TYPE_MULTI_CHAINED) {
+    if (a_sign->type.type != SIG_TYPE_MULTI_CHAINED) {
         log_it (L_ERROR, "Unsupported multi-signature type");
         return -1;
     }
-    if (!sign->pub_keys || !sign->sign_data || !sign->key_hashes || !sign->meta || !sign->key_seq) {
+    if (!a_sign->pub_keys || !a_sign->sign_data || !a_sign->key_hashes || !a_sign->meta || !a_sign->key_seq) {
         log_it (L_ERROR, "Invalid multi-signature format");
         return -1;
     }
-    uint32_t pkeys_mem_shift = 0, signs_mem_shift = 0;
-    for (int i = 0; i < sign->sign_count - 1; i++) {
-        pkeys_mem_shift += sign->meta[i].pkey_size;
-        signs_mem_shift += sign->meta[i].sign_size;
-    }
-    dap_chain_hash_fast_t data_hash;
-    bool hashed;
-    int verified = 0;
-    for (int i = sign->sign_count - 1; i >= 0; i--) {
-        size_t pkey_size = sign->meta[i].pkey_size;
-        size_t sign_size = sign->meta[i].sign_size;
-        dap_sign_t *step_sign = DAP_NEW_Z_SIZE(dap_sign_t,
-                sizeof(dap_sign_hdr_t) + pkey_size + sign_size);
-        step_sign->header.type = sign->key_seq[i].type;
-        step_sign->header.sign_pkey_size = pkey_size;
-        step_sign->header.sign_size = sign_size;
-        memcpy(step_sign->pkey_n_sign, &sign->pub_keys[pkeys_mem_shift], pkey_size);
+    uint32_t l_pkeys_mem_shift = 0, l_signs_mem_shift = 0;
+    for (int i = 0; i < a_sign->sign_count - 1; i++) {
+        l_pkeys_mem_shift += a_sign->meta[i].pkey_size;
+        l_signs_mem_shift += a_sign->meta[i].sign_size;
+    }
+    dap_chain_hash_fast_t l_data_hash;
+    bool l_hashed;
+    int l_verified = 0;
+    for (int i = a_sign->sign_count - 1; i >= 0; i--) {
+        size_t l_pkey_size = a_sign->meta[i].pkey_size;
+        size_t l_sign_size = a_sign->meta[i].sign_size;
+        dap_sign_t *l_step_sign = DAP_NEW_Z_SIZE(dap_sign_t,
+                sizeof(dap_sign_hdr_t) + l_pkey_size + l_sign_size);
+        l_step_sign->header.type = a_sign->key_seq[i].type;
+        l_step_sign->header.sign_pkey_size = l_pkey_size;
+        l_step_sign->header.sign_size = l_sign_size;
+        memcpy(l_step_sign->pkey_n_sign, &a_sign->pub_keys[l_pkeys_mem_shift], l_pkey_size);
         if (i > 0) {
-            pkeys_mem_shift -= sign->meta[i - 1].pkey_size;
+            l_pkeys_mem_shift -= a_sign->meta[i - 1].pkey_size;
         }
-        memcpy(&step_sign->pkey_n_sign[pkey_size], &sign->sign_data[signs_mem_shift], sign_size);
+        memcpy(&l_step_sign->pkey_n_sign[l_pkey_size], &a_sign->sign_data[l_signs_mem_shift], l_sign_size);
         if (i > 0) {
-            signs_mem_shift -= sign->meta[i - 1].sign_size;
+            l_signs_mem_shift -= a_sign->meta[i - 1].sign_size;
         }
         if (i ==0) {
-            hashed = dap_multi_sign_hash_data(sign, data, data_size, &data_hash);
+            l_hashed = dap_multi_sign_hash_data(a_sign, a_data, a_data_size, &l_data_hash);
         } else {
-            hashed = dap_hash_fast(&sign->sign_data[signs_mem_shift], sign->meta[i - 1].sign_size, &data_hash);
+            l_hashed = dap_hash_fast(&a_sign->sign_data[l_signs_mem_shift], a_sign->meta[i - 1].sign_size, &l_data_hash);
         }
-        if (!hashed) {
+        if (!l_hashed) {
             log_it (L_ERROR, "Can't create multi-signature hash");
             return -1;
         }
-        verified = dap_sign_verify(step_sign, &data_hash, sizeof(dap_chain_hash_fast_t));
-        DAP_DELETE(step_sign);
-        if (verified != 1) {
-            return verified;
+        l_verified = dap_sign_verify(l_step_sign, &l_data_hash, sizeof(dap_chain_hash_fast_t));
+        DAP_DELETE(l_step_sign);
+        if (l_verified != 1) {
+            return l_verified;
         }
     }
-    return verified;
+    return l_verified;
 }
 
 /**
  * @brief dap_multi_sign_delete Destroy multi-signature structure
- * @param sign Pointer to multi-signature structure to destroy
+ * @param a_sign Pointer to multi-signature structure to destroy
  * @return None
  */
-void dap_multi_sign_delete(dap_multi_sign_t *sign)
+void dap_multi_sign_delete(dap_multi_sign_t *a_sign)
 {
-    if (!sign)
+    if (!a_sign)
         return;
-    if (sign->sign_data) {
-        DAP_DELETE(sign->sign_data);
+    if (a_sign->sign_data) {
+        DAP_DELETE(a_sign->sign_data);
     }
-    if (sign->pub_keys) {
-        DAP_DELETE(sign->pub_keys);
+    if (a_sign->pub_keys) {
+        DAP_DELETE(a_sign->pub_keys);
     }
-    if (sign->key_hashes) {
-        DAP_DELETE(sign->key_hashes);
+    if (a_sign->key_hashes) {
+        DAP_DELETE(a_sign->key_hashes);
     }
-    if (sign->meta) {
-        DAP_DELETE(sign->meta);
+    if (a_sign->meta) {
+        DAP_DELETE(a_sign->meta);
     }
-    if (sign->key_seq) {
-        DAP_DELETE(sign->key_seq);
+    if (a_sign->key_seq) {
+        DAP_DELETE(a_sign->key_seq);
     }
-    DAP_DELETE(sign);
+    DAP_DELETE(a_sign);
 }
diff --git a/test/crypto/dap_enc_sign_multi_test.c b/test/crypto/dap_enc_sign_multi_test.c
index 9d1f238..2a7a47b 100755
--- a/test/crypto/dap_enc_sign_multi_test.c
+++ b/test/crypto/dap_enc_sign_multi_test.c
@@ -38,11 +38,20 @@ static void test_signing_verifying(void)
     dap_multi_sign_t *sign = dap_multi_sign_create(params, source, source_size);
     dap_assert_PIF(sign, "Signing message");
 
-    int verify = dap_multi_sign_verify(sign, source, source_size);
+    size_t serialized_size = 0;
+    uint8_t *serialized_sign = dap_multi_sign_serialize(sign, &serialized_size);
+    dap_assert_PIF(serialized_sign, "Serializing signature");
+
+    dap_multi_sign_t *deserialized_sign = dap_multi_sign_deserialize(SIG_TYPE_MULTI_CHAINED, serialized_sign, serialized_size);
+    dap_assert_PIF(deserialized_sign, "Deserializing signature");
+
+    int verify = dap_multi_sign_verify(deserialized_sign, source, source_size);
     dap_assert_PIF(verify == 1, "Verifying signature");
 
+    dap_multi_sign_delete(deserialized_sign);
     dap_multi_sign_delete(sign);
     dap_multi_sign_params_delete(params);
+    DAP_DELETE(serialized_sign);
     DAP_DELETE(source);
     for (int i = 0; i < KEYS_TOTAL_COUNT; i++) {
         dap_enc_key_delete(key[i]);
-- 
GitLab