hash_test.c (3030B)
1 /* hash_test — public <kit/hash.h> surface: one-shot kit_hash against known 2 * vectors (SHA-256 empty/"abc", CRC-32 of "123456789", BLAKE2b-256 "abc") and 3 * streaming/one-shot equivalence (two kit_hasher_update chunks == one shot) 4 * for all three algorithms. 5 * 6 * Run by: make test-hash 7 */ 8 9 #include <kit/core.h> 10 #include <kit/hash.h> 11 #include <stddef.h> 12 #include <stdint.h> 13 #include <string.h> 14 15 #include "lib/kit_unit.h" 16 17 static KitUnit g_u; 18 #define EXPECT(c, ...) CU_EXPECT(&g_u, c, __VA_ARGS__) 19 20 static int hexval(char c) { 21 if (c >= '0' && c <= '9') return c - '0'; 22 if (c >= 'a' && c <= 'f') return c - 'a' + 10; 23 if (c >= 'A' && c <= 'F') return c - 'A' + 10; 24 return -1; 25 } 26 27 static void parse_hex(const char* hex, uint8_t* out, size_t n) { 28 size_t i; 29 for (i = 0; i < n; ++i) 30 out[i] = (uint8_t)((hexval(hex[2 * i]) << 4) | hexval(hex[2 * i + 1])); 31 } 32 33 static void check_oneshot(KitHashAlgo algo, const char* name, const char* msg, 34 size_t len, const char* exphex) { 35 uint8_t digest[KIT_HASH_MAX_LEN]; 36 uint8_t want[KIT_HASH_MAX_LEN]; 37 size_t dlen = 0; 38 size_t wn = strlen(exphex) / 2; 39 EXPECT(kit_hash(algo, (const uint8_t*)msg, len, digest, &dlen) == KIT_OK, 40 "%s: kit_hash returned OK", name); 41 EXPECT(dlen == kit_hash_len(algo) && dlen == wn, 42 "%s: digest length %zu == %zu", name, dlen, wn); 43 parse_hex(exphex, want, wn); 44 EXPECT(memcmp(digest, want, wn) == 0, "%s: digest matches %s", name, exphex); 45 } 46 47 /* Hashing "abc"+"def" in two streamed chunks must equal a one-shot of 48 * "abcdef". */ 49 static void check_stream_equiv(KitHashAlgo algo, const char* name) { 50 uint8_t one[KIT_HASH_MAX_LEN]; 51 uint8_t two[KIT_HASH_MAX_LEN]; 52 size_t l1 = 0, l2 = 0; 53 KitHasher* h = NULL; 54 EXPECT(kit_hash(algo, (const uint8_t*)"abcdef", 6, one, &l1) == KIT_OK, 55 "%s: one-shot OK", name); 56 EXPECT(kit_hasher_new(&g_u.ctx, algo, &h) == KIT_OK, "%s: hasher_new", name); 57 kit_hasher_update(h, (const uint8_t*)"abc", 3); 58 kit_hasher_update(h, (const uint8_t*)"def", 3); 59 EXPECT(kit_hasher_final(h, two, &l2) == KIT_OK, "%s: hasher_final", name); 60 kit_hasher_free(h); 61 EXPECT(l1 == l2 && memcmp(one, two, l1) == 0, 62 "%s: streamed digest == one-shot", name); 63 } 64 65 int main(void) { 66 kit_unit_init(&g_u); 67 68 check_oneshot( 69 KIT_HASH_SHA256, "sha256(\"\")", "", 0, 70 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); 71 check_oneshot( 72 KIT_HASH_SHA256, "sha256(\"abc\")", "abc", 3, 73 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); 74 check_oneshot(KIT_HASH_CRC32, "crc32(\"123456789\")", "123456789", 9, 75 "cbf43926"); 76 check_oneshot( 77 KIT_HASH_BLAKE2B, "blake2b(\"abc\")", "abc", 3, 78 "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319"); 79 80 check_stream_equiv(KIT_HASH_SHA256, "sha256"); 81 check_stream_equiv(KIT_HASH_BLAKE2B, "blake2b"); 82 check_stream_equiv(KIT_HASH_CRC32, "crc32"); 83 84 kit_unit_summary(&g_u, "hash_test"); 85 return kit_unit_status(&g_u); 86 }