dazibao/src/hash.c
2020-05-06 13:47:57 +02:00

87 lines
2.4 KiB
C

#include "hash.h"
#include "debug.h"
// Hash a single data
void hash_data(pub_data *data, unsigned char *buf) {
// All three fields are concatenated into a single buffer
int totlen = data->length + 10;
unsigned char concat[totlen];
concat_data(data, concat);
// The resulting buf is hashed and put into a buffer
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, concat, totlen);
SHA256_Final(hash, &sha256);
// Put truncated hash into buf
hash_trunc(hash, buf);
}
// Hash every data contained in data_list then return a network hash
void hash_network(list *data_list, unsigned char *buf) {
// Get list length to initialize concat buffer
int concat_len = len_list(data_list) * 16;
unsigned char *concat = (unsigned char*) malloc(concat_len);
unsigned char hash[SHA256_DIGEST_LENGTH];
int totlen = 0;
list *tmp = data_list;
// Hash every known data and concatenate it to buffer concat
while(tmp != NULL) {
hash_data((pub_data*) tmp->data, hash);
concat_hash(concat, hash, totlen);
totlen += 16;
tmp = tmp->next;
}
// Hash all of concat to obtain the network hash
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, concat, concat_len);
SHA256_Final(hash, &sha256);
// Put truncated hash into buf
hash_trunc(hash, buf);
// Get rid of concat
free(concat);
}
// Truncate 32 octet hash to 16 octets
void hash_trunc(unsigned char *hash32oct, unsigned char *buf) {
// Copy the first 16 octets from hash32oct
if (memcpy(buf, hash32oct, 16) == NULL) {
print_debug(">> Truncating the hashs didn't work !");
}
}
// Concat all fields of data and put them in buf
void concat_data(pub_data *data, unsigned char *buf) {
// Turn seqno to big endian
uint16_t seqno = htobe16(data->seqno);
uint64_t id = htobe64(data->id);
if (memcpy(buf, (char*) &id, 8) == NULL) {
print_debug(">> Concat the data (id) didn't work !");
}
if (memcpy(buf+8, (char*) &seqno, 2) == NULL) {
print_debug(">> concat the data (seqno) didn't work !");
}
if (memcpy(buf+10, data->data, data->length) == NULL) {
print_debug(">> Contact the data (data) didn't work !");
}
}
// Concat hash2 to hash1 (hash1 is modified)
void concat_hash(unsigned char *hash1, unsigned char *hash2, size_t size) {
if(memcpy(hash1+size, hash2, 16) == NULL){
print_debug(">> Concat the hash didn't work !");
}
}