hashx.h (6329B)
1 /* Copyright (c) 2020 tevador <tevador@gmail.com> */ 2 /* See LICENSE for licensing information */ 3 4 /* 5 * HashX is an algorithm designed for client puzzles and proof-of-work schemes. 6 * While traditional cryptographic hash functions use a fixed one-way 7 * compression function, each HashX instance represents a unique pseudorandomly 8 * generated one-way function. 9 * 10 * Example of usage: 11 * 12 #include <hashx.h> 13 #include <stdio.h> 14 15 int main() { 16 char seed[] = "this is a seed that will generate a hash function"; 17 char hash[HASHX_SIZE]; 18 hashx_ctx* ctx = hashx_alloc(HASHX_TRY_COMPILE); 19 if (ctx == NULL) 20 return 1; 21 if (hashx_make(ctx, seed, sizeof(seed)) != EQUIX_OK) 22 return 1; 23 if (hashx_exec(ctx, 123456789, hash) != EQUIX_OK) 24 return 1; 25 hashx_free(ctx); 26 for (unsigned i = 0; i < HASHX_SIZE; ++i) 27 printf("%02x", hash[i] & 0xff); 28 printf("\n"); 29 return 0; 30 } 31 * 32 */ 33 34 #ifndef HASHX_H 35 #define HASHX_H 36 37 #include <stdint.h> 38 #include <stddef.h> 39 40 /* 41 * Input of the hash function. 42 * 43 * Counter mode (default): a 64-bit unsigned integer 44 * Block mode: pointer to a buffer and the number of bytes to be hashed 45 */ 46 #ifndef HASHX_BLOCK_MODE 47 #define HASHX_INPUT uint64_t input 48 #else 49 #define HASHX_INPUT const void* input, size_t size 50 #endif 51 52 /* The default (and maximum) hash size is 32 bytes */ 53 #ifndef HASHX_SIZE 54 #define HASHX_SIZE 32 55 #endif 56 57 /* Opaque struct representing a HashX instance */ 58 typedef struct hashx_ctx hashx_ctx; 59 60 /* Type of hash context / type of compiled function */ 61 typedef enum hashx_type { 62 HASHX_TYPE_INTERPRETED = 1, /* Only the interpreted implementation */ 63 HASHX_TYPE_COMPILED, /* Require the compiler, fail if unavailable */ 64 HASHX_TRY_COMPILE, /* (hashx_alloc) Try compiler, don't require */ 65 } hashx_type; 66 67 /* Result code for hashx_make and hashx_exec */ 68 typedef enum hashx_result { 69 HASHX_OK = 0, 70 HASHX_FAIL_UNPREPARED, /* Trying to run an unmade hash funciton */ 71 HASHX_FAIL_UNDEFINED, /* Unrecognized hashx_type enum value */ 72 HASHX_FAIL_SEED, /* Can't construct a hash function from this seed */ 73 HASHX_FAIL_COMPILE, /* Can't compile, and no fallback is enabled. */ 74 } hashx_result; 75 76 #if defined(_WIN32) || defined(__CYGWIN__) 77 #define HASHX_WIN 78 #endif 79 80 /* Shared/static library definitions */ 81 #ifdef HASHX_WIN 82 #ifdef HASHX_SHARED 83 #define HASHX_API __declspec(dllexport) 84 #elif !defined(HASHX_STATIC) 85 #define HASHX_API __declspec(dllimport) 86 #else 87 #define HASHX_API 88 #endif 89 #define HASHX_PRIVATE 90 #else 91 #ifdef HASHX_SHARED 92 #define HASHX_API __attribute__ ((visibility ("default"))) 93 #else 94 #define HASHX_API __attribute__ ((visibility ("hidden"))) 95 #endif 96 #define HASHX_PRIVATE __attribute__ ((visibility ("hidden"))) 97 #endif 98 99 #ifdef __cplusplus 100 extern "C" { 101 #endif 102 103 /* 104 * Allocate a HashX instance. 105 * 106 * @param type is the type of instance to be created. 107 * 108 * @return pointer to a new HashX instance. Returns NULL on memory allocation 109 * failures only. Other failures are reported in hashx_make. 110 */ 111 HASHX_API hashx_ctx* hashx_alloc(hashx_type type); 112 113 /* 114 * Create a new HashX function from a variable-length seed value. 115 * 116 * The seed value will be hashed internally in order to initialize the state 117 * of the HashX program generator and create a new unique hash function. 118 * 119 * @param ctx is pointer to a HashX instance. 120 * @param seed is a pointer to the seed value. 121 * @param size is the size of the seed. 122 * 123 * @return HASHX_OK on success, HASHX_FAIL_SEED if the specific seed is 124 * not associated with a valid hash program, and HASHX_FAIL_COMPILE 125 * if the compiler failed for OS-specific reasons and the interpreter 126 * fallback was disabled by allocating the context with 127 * HASHX_TYPE_COMPILED rather than HASHX_TRY_COMPILE. 128 */ 129 HASHX_API hashx_result hashx_make(hashx_ctx* ctx, 130 const void* seed, size_t size); 131 132 /* 133 * Asks the specific implementation of a function created with hashx_make. 134 * 135 * This will equal the parameter to hashx_alloc() if a specific type was 136 * chosen there, but a context allocated with HASHX_TRY_COMPILE will allow 137 * the implementation to vary dynamically during hashx_make. 138 * 139 * @param ctx is pointer to a HashX instance. 140 * @param type_out is a pointer to which, on success, we write 141 * a HASHX_TYPE_* value. 142 * 143 * @return HASHX_OK on success, or HASHX_FAIL_UNPREPARED if hashx_make has not 144 * been invoked successfully on this context. 145 */ 146 HASHX_API hashx_result hashx_query_type(hashx_ctx* ctx, hashx_type *type_out); 147 148 /* 149 * Execute the HashX function. 150 * 151 * @param ctx is pointer to a HashX instance. A HashX function must have 152 * been previously created by invoking hashx_make successfully. 153 * @param HASHX_INPUT is the input to be hashed (see definition above). 154 * @param output is a pointer to the result buffer. HASHX_SIZE bytes will be 155 * written. 156 * 157 * @return HASHX_OK on success, or HASHX_FAIL_UNPREPARED if hashx_make has not 158 * been invoked successfully on this context. 159 */ 160 HASHX_API hashx_result hashx_exec(const hashx_ctx* ctx, 161 HASHX_INPUT, void* output); 162 163 /* 164 * Free a HashX instance. 165 * 166 * Has no effect if ctx is NULL. 167 * 168 * @param ctx is pointer to a HashX instance. 169 */ 170 HASHX_API void hashx_free(hashx_ctx* ctx); 171 172 #ifdef HASHX_RNG_CALLBACK 173 /* 174 * Set a callback for inspecting or modifying the HashX random number stream. 175 * 176 * The callback and its user pointer are associated with the provided context 177 * even if it's re-used for another hash program. A callback value of NULL 178 * disables the callback. 179 * 180 * @param ctx is pointer to a HashX instance. 181 * @param callback is invoked after each new 64-bit pseudorandom value 182 * is generated in a buffer. The callback may record it and/or replace 183 * it. A NULL pointer here disables the callback. 184 * @param user_data is an opaque parameter given to the callback 185 */ 186 HASHX_API void hashx_rng_callback(hashx_ctx* ctx, 187 void (*callback)(uint64_t*, void*), 188 void* user_data); 189 #endif 190 191 #ifdef __cplusplus 192 } 193 #endif 194 195 #endif