tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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