% limb manual
% hasher_hash(3)
% limb 0.1.0
% 2023-07-24
# NAME
hasher\_hash, hinit, hupdate, hfinal - compute a message digest using a given hasher
# SYNOPSIS
#include <limb/hasher.h>
```pre hl
const char * const algos[NB_ALGOS + 1]
hasher * const hashers[NB_ALGOS]
void hinit (hasher *<em>hasher</em>)
void hupdate (const void *<em>msg</em>, size_t <em>mlen</em>, hasher *<em>hasher</em>)
void hfinal (void *<em>digest</em>, hasher *<em>hasher</em>)
void hasher_hash(void *<em>digest</em>, const void *<em>msg</em>, size_t <em>mlen</em>, hasher *<em>hasher</em>)
```
# 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).
! NOTE:
! 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 :
```c
const 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)));
```
# SEE ALSO
[hmac](3), [pbkdf2](3), [blake3_init](3), [sha3_224_init](3)