| #ifndef C_HIGHWAYHASH_H_ |
| #define C_HIGHWAYHASH_H_ |
| |
| #include <stdint.h> |
| #include <string.h> |
| |
| #if defined(__cplusplus) || defined(c_plusplus) |
| extern "C" { |
| #endif |
| |
| /*////////////////////////////////////////////////////////////////////////////*/ |
| /* Low-level API, use for implementing streams etc... */ |
| /*////////////////////////////////////////////////////////////////////////////*/ |
| |
| typedef struct { |
| uint64_t v0[4]; |
| uint64_t v1[4]; |
| uint64_t mul0[4]; |
| uint64_t mul1[4]; |
| } HighwayHashState; |
| |
| /* Initializes state with given key */ |
| static void HighwayHashReset(const uint64_t key[4], HighwayHashState* state); |
| /* Takes a packet of 32 bytes */ |
| void HighwayHashUpdatePacket(const uint8_t* packet, HighwayHashState* state); |
| /* Adds the final 1..31 bytes, do not use if 0 remain */ |
| void HighwayHashUpdateRemainder(const uint8_t* bytes, const size_t size_mod32, |
| HighwayHashState* state); |
| /* Compute final hash value. Makes state invalid. */ |
| static uint64_t HighwayHashFinalize64(HighwayHashState* state); |
| static void HighwayHashFinalize128(HighwayHashState* state, uint64_t hash[2]); |
| static void HighwayHashFinalize256(HighwayHashState* state, uint64_t hash[4]); |
| |
| /*////////////////////////////////////////////////////////////////////////////*/ |
| /* Non-cat API: single call on full data */ |
| /*////////////////////////////////////////////////////////////////////////////*/ |
| |
| uint64_t HighwayHash64(const uint8_t* data, size_t size, const uint64_t key[4]); |
| |
| void HighwayHash128(const uint8_t* data, size_t size, |
| const uint64_t key[4], uint64_t hash[2]); |
| |
| void HighwayHash256(const uint8_t* data, size_t size, |
| const uint64_t key[4], uint64_t hash[4]); |
| |
| /*////////////////////////////////////////////////////////////////////////////*/ |
| /* Cat API: allows appending with multiple calls */ |
| /*////////////////////////////////////////////////////////////////////////////*/ |
| |
| typedef struct { |
| HighwayHashState state; |
| uint8_t packet[32]; |
| int num; |
| } HighwayHashCat; |
| |
| /* Allocates new state for a new streaming hash computation */ |
| void HighwayHashCatStart(const uint64_t key[4], HighwayHashCat* state); |
| |
| void HighwayHashCatAppend(const uint8_t* bytes, size_t num, |
| HighwayHashCat* state); |
| |
| /* Computes final hash value */ |
| uint64_t HighwayHashCatFinish64(const HighwayHashCat* state); |
| void HighwayHashCatFinish128(const HighwayHashCat* state, uint64_t hash[2]); |
| void HighwayHashCatFinish256(const HighwayHashCat* state, uint64_t hash[4]); |
| |
| /* |
| Usage examples: |
| |
| #include <inttypes.h> |
| #include <stdio.h> |
| |
| void Example64() { |
| uint64_t key[4] = {1, 2, 3, 4}; |
| const char* text = "Hello world!"; |
| size_t size = strlen(text); |
| uint64_t hash = HighwayHash64((const uint8_t*)text, size, key); |
| printf("%016"PRIx64"\n", hash); |
| } |
| |
| void Example64Cat() { |
| uint64_t key[4] = {1, 2, 3, 4}; |
| HighwayHashCat state; |
| uint64_t hash; |
| |
| HighwayHashCatStart(key, &state); |
| |
| HighwayHashCatAppend((const uint8_t*)"Hello", 5, &state); |
| HighwayHashCatAppend((const uint8_t*)" world!", 7, &state); |
| |
| hash = HighwayHashCatFinish64(state); |
| printf("%016"PRIx64"\n", hash); |
| } |
| */ |
| |
| #if defined(__cplusplus) || defined(c_plusplus) |
| } /* extern "C" */ |
| #endif |
| |
| #endif // C_HIGHWAYHASH_H_ |