NAME
hasher_hash, hinit, hupdate, hfinal - compute a message digest using a given hasher
SYNOPSIS
#include <limb/hasher.h>
const char * const algos[NB_ALGOS + 1] hasher * const hashers[NB_ALGOS] void hinit (hasher *hasher) void hupdate (const void *msg, size_t mlen, hasher *hasher) void hfinal (void *digest, hasher *hasher) void hasher_hash(void *digest, const void *msg, size_t mlen, hasher *hasher)
DESCRIPTION
A hasher is a structure containing all required information to compute a message digest with a given algorithm. It is defined as such :
typedef void (*hasher_init) (void *ctx); typedef void (*hasher_update) (const void *msg, size_t mlen, void *ctx); typedef void (*hasher_final) (void *digest, void *ctx); struct hasher { size_t hlen; size_t blen; hasher_init init; hasher_update update; hasher_final final; void *ctx; };
The meanings of different members are :
hlen
Length (in bytes) of the generated hash/message digest.
blen
Length (in bytes) of the internal block size for the algorithm.
init
Function to call to initialize the hasher's context.
update
Function to call to feed data into the hasher.
final
Function to call to obtain the hash/message digest from the hasher.
ctx
The hasher's (opaque) context.
Though it is possible to call the previously mentioned functions directly, some macros are available to make things easier.
The hinit
() macro initializes the hasher hasher
to calculate a new message
digest.
The hupdate
() macro feeds the specified chunk of data pointed by msg
of
length mlen
to be hashed into the given hasher
. You can call this function
repeatedly as many times as needed.
The hfinal
() macro stores the calculated hash from hasher
in binary form
into digest
, which must be able to store as many bytes as needed, available
through hasher->hlen
.
Finally, the hasher_hash
() function is there for convenience, allowing to
compute into digest
the message digest for message msg
of length mlen
using hasher
all in a single call, when the entire message is available in
a single continuous memory area.
AVAILABLE HASHERS
A few hashers are available, each define in their own header. In order to use a hasher, all you need is to include its header, which includes hasher.h(0), and you can any of the functions described above.
A constant NB_ALGOS is defined with the number of available hashers. Two pointers are defined :
algos
which points to a NULL-terminated array of strings, naming each of the available hashers/algorithms.hashers
which points to an array of pointers to the available hashers.
Obviously, indices in each array are referring to the same hasher/algorithm. In addition, constants are defined for each of the indices.
The following hashers are available :
blake3
Index ALGO_BLAKE3. Requires hasher_blake3.h(0).
sha1
Index ALGO_SHA1. Requires hasher_sha1.h(0).
sha256
Index ALGO_SHA256. Requires hasher_sha256.h(0).
sha512
Index ALGO_SHA512. Requires hasher_sha512.h(0).
sha3_224
Index ALGO_SHA3_224. Requires hasher_sha3_224.h(0).
sha3_256
Index ALGO_SHA3_256. Requires hasher_sha3_256.h(0).
sha3_384
Index ALGO_SHA3_384. Requires hasher_sha3_384.h(0).
sha3_512
Index ALGO_SHA3_512. Requires hasher_sha3_512.h(0).
The hashers for SHA1, SHA256 and SHA512 are wrappers around functions from
skalibs. If you want to use said functions directly, you'll need to include
the appropriate headers from skalibs - skalibs/sha1.h
, skalibs/sha256.h
and skalibs/sha512.h
respectively.
Note that they do not follow the same conventions as functions in limb, meaning they take the context argument first instead of last, and some of the arguments' types differ.
EXAMPLE
To compute the SHA1 of a given message, and show it on stdout, one could do :
1 2 3 4 5
cconst char *msg = "The quick brown fox jumps over the lazy dog";
char digest[sha1->hlen];
hasher_hash(digest, msg, strlen(msg), sha1);
out("The SHA1 of ", ESC, msg, ESC, " is ", HEX(digest, sizeof(digest)));