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; }