From 171bddef0af84c8bdc5d6f67a54984811b9d92e4 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Sun, 31 Jul 2016 15:42:29 +0100 Subject: [PATCH] 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 --- Makefile | 2 +- include/mh/assert.h | 6 ++ include/mh/hashes.h | 26 ++++++-- src/hashes.c | 59 ++++++++++++------- ...st_error_string.c => test_errors_string.c} | 0 tests/c/test_hashes_code.c | 30 ++++++++++ tests/c/test_hashes_length.c | 30 ++++++++-- 7 files changed, 122 insertions(+), 31 deletions(-) create mode 100644 include/mh/assert.h rename tests/c/{test_error_string.c => test_errors_string.c} (100%) create mode 100644 tests/c/test_hashes_code.c diff --git a/Makefile b/Makefile index 1318066..d60f433 100644 --- a/Makefile +++ b/Makefile @@ -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 $@ diff --git a/include/mh/assert.h b/include/mh/assert.h new file mode 100644 index 0000000..022b73c --- /dev/null +++ b/include/mh/assert.h @@ -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 */ diff --git a/include/mh/hashes.h b/include/mh/hashes.h index f7a249a..5d35cf5 100644 --- a/include/mh/hashes.h +++ b/include/mh/hashes.h @@ -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); diff --git a/src/hashes.c b/src/hashes.c index b3f991f..a0caf80 100644 --- a/src/hashes.c +++ b/src/hashes.c @@ -1,5 +1,39 @@ +#include #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); diff --git a/tests/c/test_error_string.c b/tests/c/test_errors_string.c similarity index 100% rename from tests/c/test_error_string.c rename to tests/c/test_errors_string.c diff --git a/tests/c/test_hashes_code.c b/tests/c/test_hashes_code.c new file mode 100644 index 0000000..19df9cb --- /dev/null +++ b/tests/c/test_hashes_code.c @@ -0,0 +1,30 @@ +#include +#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; +} + diff --git a/tests/c/test_hashes_length.c b/tests/c/test_hashes_length.c index 17871af..7dd8afb 100644 --- a/tests/c/test_hashes_length.c +++ b/tests/c/test_hashes_length.c @@ -1,26 +1,46 @@ #include #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; }