Newer
Older
/*
* Authors:
* Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* 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_enc_base58.h"
/**
* @brief dap_chain_hash_to_str
* @param a_hash
* @param a_str
* @param a_str_max
* @return
*/
size_t dap_chain_hash_slow_to_str(dap_chain_hash_slow_t * a_hash, char * a_str, size_t a_str_max)
const size_t c_hash_str_size = sizeof(*a_hash) * 2 + 1 /*trailing zero*/+ 2 /* heading 0x */;
if(a_str_max < c_hash_str_size) {
log_it(L_ERROR, "String for hash too small, need %u but have only %u", c_hash_str_size, a_str_max);
snprintf(a_str, 3, "0x");
for(i = 0; i < sizeof(a_hash->raw); ++i)
snprintf(a_str + i * 2 + 2, 3, "%02x", a_hash->raw[i]);
a_str[c_hash_str_size] = '\0';
return strlen(a_str);
}
/**
* @brief dap_chain_hash_fast_to_str
* @param a_hash
* @param a_str
* @param a_str_max
* @return
*/
size_t dap_chain_hash_fast_to_str(dap_chain_hash_fast_t * a_hash, char * a_str, size_t a_str_max)
{
const size_t c_hash_str_size = sizeof(*a_hash) * 2 + 1 /*trailing zero*/+ 2 /* heading 0x */;
if(a_str_max < c_hash_str_size) {
log_it(L_ERROR, "String for hash too small, need %u but have only %u", c_hash_str_size, a_str_max);
}
size_t i;
snprintf(a_str, 3, "0x");
for(i = 0; i < sizeof(a_hash->raw); ++i)
snprintf(a_str + i * 2 + 2, 3, "%02x", a_hash->raw[i]);
a_str[c_hash_str_size] = '\0';
return strlen(a_str);
/**
* @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 == c_hash_str_size ){
for (size_t l_offset = 2; l_offset < c_hash_str_size ; l_offset+=2 ){
if ( ( sscanf(a_hash_str+l_offset,"%02hhx",a_hash->raw+l_offset-2) != 1) ||
( sscanf(a_hash_str+l_offset,"%02hhX",a_hash->raw+l_offset-2) != 1)
)
return -10* ((int) l_offset); // Wrong char
}
return 0;
}else // Wromg string len
return -1;
}
/**
Aleksandr Lysikov
committed
* @brief dap_chain_addr_to_str
* @param a_addr
* @return
*/
char* dap_chain_addr_to_str(const dap_chain_addr_t *a_addr)
{
size_t l_ret_size = DAP_ENC_BASE58_ENCODE_SIZE(sizeof(dap_chain_addr_t));
char * l_ret = DAP_NEW_SIZE(char, l_ret_size);
if(dap_enc_base58_encode(a_addr, sizeof(dap_chain_addr_t), l_ret) > 0)
return l_ret;
DAP_DELETE(l_ret);
return NULL;
}
}
Aleksandr Lysikov
committed
/**
* @brief dap_chain_str_to_addr
* @param a_addr
* @return
*/
dap_chain_addr_t* dap_chain_str_to_addr(const char *a_str)
Aleksandr Lysikov
committed
{
size_t l_str_len = (a_str) ? strlen(a_str) : 0;
if(l_str_len <= 0)
Aleksandr Lysikov
committed
return NULL;
size_t l_ret_size = DAP_ENC_BASE58_DECODE_SIZE(l_str_len);
dap_chain_addr_t * l_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, l_ret_size);
if(dap_enc_base58_decode(a_str, l_addr) == sizeof(dap_chain_addr_t) &&
dap_chain_addr_check_sum(l_addr)==1)
Aleksandr Lysikov
committed
else
Aleksandr Lysikov
committed
return NULL;
}
/**
* @brief dap_chain_addr_fill
* @param a_addr
* @param a_key
* @param a_net_id
* @return
*/
void dap_chain_addr_fill(dap_chain_addr_t *a_addr, dap_enc_key_t *a_key, dap_chain_net_id_t *a_net_id)
{
if(!a_addr || !a_key || !a_net_id)
return;
a_addr->addr_ver = DAP_CHAIN_ADDR_VERSION_CURRENT;
a_addr->net_id.uint64 = a_net_id->uint64;
a_addr->sig_type.raw = dap_chain_sign_type_from_key_type(a_key->type).raw;
// key -> serialized key
dap_chain_hash_fast_t l_hash_public_key;
size_t l_pub_key_data_size;
uint8_t *l_pub_key_data = dap_enc_key_serealize_pub_key(a_key, &l_pub_key_data_size);
// serialized key -> key hash
if(dap_hash_fast(l_pub_key_data, l_pub_key_data_size, &l_hash_public_key)==1)
memcpy(a_addr->data.hash, l_hash_public_key.raw, sizeof(l_hash_public_key.raw));
// calc checksum
dap_hash_fast(a_addr, sizeof(dap_chain_addr_t) - sizeof(dap_chain_hash_fast_t), &a_addr->checksum);
}
/**
* @brief dap_chain_addr_check_sum
* @param a_addr
* @return 1 Ok, -1 Invalid a_addr or checksum
*/
int dap_chain_addr_check_sum(const dap_chain_addr_t *a_addr)
{
if(!a_addr)
return -1;
dap_chain_hash_fast_t l_checksum;
// calc checksum
dap_hash_fast(a_addr, sizeof(dap_chain_addr_t) - sizeof(dap_chain_hash_fast_t), &l_checksum);
if(!memcmp(a_addr->checksum.raw, l_checksum.raw, sizeof(l_checksum.raw)))
return 1;
return -1;
}