change how hashes are defined from enum to define

this way the mapping between hashcodes and hash definitions isn't needed
also it simplfies handling, testing  and allows to return error with
the hash code
This commit is contained in:
Jakub Sztandera 2016-07-31 15:42:29 +01:00
parent 7aa01e57d6
commit 171bddef0a
7 changed files with 122 additions and 31 deletions

View file

@ -47,7 +47,7 @@ test: $(TEST_BINS)
"./$$t" || ERROR=1; \
done; \
echo; \
[ "$${ERROR-0}" -eq "1" ] && exit 1
exit $$ERROR
tests/c/test_%.o: tests/c/test_%.c tests/c/minunit.h
$(CC) $(CFLAGS) -c -I include $< -o $@

6
include/mh/assert.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef MH_ASSERT
#define MH_ASSERT
#define mh_assert_static(isTrue) void mh_assert_static(char x[1 - (!(isTrue))])
#endif /* end of include guard */

View file

@ -1,7 +1,21 @@
#include "errors.h"
// definitions of hash functions
#define MH_H_SHA1 0x11
#define MH_H_SHA2_256 0x12
#define MH_H_SHA2_512 0x13
#define MH_H_SHA3_512 0x14
#define MH_H_SHA3_384 0x15
#define MH_H_SHA3_256 0x16
#define MH_H_SHA3_224 0x17
#define MH_H_SHAKE_128 0x18
#define MH_H_SHAKE_256 0x19
#define MH_H_BLAKE2B 0x40
#define MH_H_BLAKE2S 0x41
// list of avaliable hash functions.
typedef enum {
static const int mh_all_hashes[] = {
MH_H_SHA1,
MH_H_SHA2_256,
MH_H_SHA2_512,
@ -13,16 +27,18 @@ typedef enum {
MH_H_SHAKE_256,
MH_H_BLAKE2B,
MH_H_BLAKE2S,
};
MH_H_COUNT // number of hash functions
} mh_hash;
#define MH_H_COUNT (int)(sizeof(mh_all_hashes) / sizeof(mh_all_hashes[0]))
const char *mh_hash_name(int hash);
// returns length in bytes or if returns is < 0 it is an error
int mh_hash_default_length(mh_hash hash);
int mh_hash_default_length(int hash);
int mh_hash_length(const unsigned char multihash[], int len, int *hash_length);
int mh_hash_function(const unsigned char multihash[], int len, mh_hash *hash);
int mh_hash_function(const unsigned char multihash[], int len, int *hash);

View file

@ -1,5 +1,39 @@
#include <stdlib.h>
#include "mh/hashes.h"
#include "mh/errors.h"
#include "mh/assert.h"
static const struct hash_name {
int hash;
const char *name;
} hash_names[] = {
{ MH_H_SHA1, "sha1" },
{ MH_H_SHA2_256, "sha2-256" },
{ MH_H_SHA2_512, "sha2-512" },
{ MH_H_SHA3_512, "sha3-512" },
{ MH_H_SHA3_384, "sha3-384" },
{ MH_H_SHA3_256, "sha3-256" },
{ MH_H_SHA3_224, "sha3-224" },
{ MH_H_SHAKE_128, "shake-128" },
{ MH_H_SHAKE_256, "shake-256" },
{ MH_H_BLAKE2B, "blake2b" },
{ MH_H_BLAKE2S, "blake2s" }
};
mh_assert_static(sizeof(hash_names) / sizeof(hash_names[0]) == MH_H_COUNT);
const char *mh_hash_name(int hash) {
unsigned int i = 0;
for (; i < sizeof(mh_all_hashes) / sizeof(mh_all_hashes[0]); i++) {
if (hash_names[i].hash == hash)
return hash_names[i].name;
}
return NULL;
}
static const int hash_lengths[] = {
@ -16,31 +50,16 @@ static const int hash_lengths[] = {
32, // blake2s
};
mh_assert_static(sizeof(hash_lengths)/sizeof(hash_lengths[0]) == MH_H_COUNT);
int mh_hash_default_length(mh_hash hash) {
int mh_hash_default_length(int hash) {
if (hash < 0 || hash >= MH_H_COUNT)
return MH_;
return MH_E_UNKNOWN_CODE;
return hash_lengths[hash];
}
int mh_hash_length(const unsigned char multihash[], int len, int *hash_length);
/*
MH_H_SHA1,
MH_H_SHA2_256,
MH_H_SHA2_512,
MH_H_SHA3_512,
MH_H_SHA3_384,
MH_H_SHA3_256,
MH_H_SHA3_224,
MH_H_SHAKE_128,
MH_H_SHAKE_256,
MH_H_BLAKE2B,
MH_H_BLAKE2S,
HM_H_COUNT // number of hash functions
*/
int mh_hash_function(const unsigned char multihash[], int len, int *hash);

View file

@ -0,0 +1,30 @@
#include <string.h>
#include "minunit.h"
#include "mh/errors.h"
#include "mh/hashes.h"
char error_buf[256];
static char *test_all_hashes_have_names(void) {
int i = 0;
for (; i < MH_H_COUNT; i++) {
sprintf(error_buf, "hash code %d does not have name mapping",
i);
mu_assert(error_buf, mh_hash_name(mh_all_hashes[i]) != NULL);
}
return NULL;
}
static char *test_name_is_null_when_out_of_bands(void) {
mu_assert("hash code out of range does not have name",
mh_hash_name(0) == NULL);
return NULL;
}
static char *mu_all_tests(void) {
mu_run_test(test_name_is_null_when_out_of_bands);
mu_run_test(test_all_hashes_have_names);
return NULL;
}

View file

@ -1,26 +1,46 @@
#include <string.h>
#include "minunit.h"
#include "mh/errors.h"
#include "mh/hashes.h"
char error_buf[256];
static char *test_all_hashes_have_lengths(void) {
int i = 0;
//int length = 0;
int length = 0;
for (; i < MH_H_COUNT; i++) {
/* length = mh_hash_default_length((mh_hash) i);
length = mh_hash_default_length(i);
sprintf(error_buf, "mh_hash_default_length: hash %d"
" returned invalid (%d) default length",
i, length);
mu_assert(error_buf, length > 0);
*/
}
return NULL;
}
static char *mu_all_tests(void) {
mu_run_test(test_all_hashes_have_lengths);
static char *test_error_when_out_of_bands(void) {
mu_assert("out of bands index should give error",
mh_hash_default_length(1 << 20) == MH_E_UNKNOWN_CODE);
return NULL;
}
static char *test_lengths_are_correct_for_known_codes(void) {
#define hlen mh_hash_default_length
mu_assert("sha1 has valid length", hlen(MH_H_SHA1) == 20);
mu_assert("sha3-512 has valid length", hlen(MH_H_SHA3_256) == 32);
mu_assert("shake-128 has valid length", hlen(MH_H_SHAKE_128) == 16);
#undef hlen
return NULL;
}
static char *mu_all_tests(void) {
mu_run_test(test_all_hashes_have_lengths);
mu_run_test(test_error_when_out_of_bands);
mu_run_test(test_lengths_are_correct_for_known_codes);
return NULL;
}