Tor 0.4.9.2-alpha-dev
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
hashx.h
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 */
58typedef struct hashx_ctx hashx_ctx;
59
60/* Type of hash context / type of compiled function */
61typedef 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 */
68typedef 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
100extern "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 */
111HASHX_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 */
129HASHX_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*/
146HASHX_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 */
160HASHX_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*/
170HASHX_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 */
186HASHX_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