Skip to content
Snippets Groups Projects
Commit 7b0a9d65 authored by dmitriy.gerasimov's avatar dmitriy.gerasimov
Browse files

Merge branch 'support-3409' into 'master'

support-3409

See merge request !32
parents e012b3aa 5337a6cb
No related branches found
No related tags found
1 merge request!32support-3409
......@@ -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
}
......
......@@ -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);
}
......@@ -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]);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment