Welcome to little lamb

Code » limb » release » tree

[release] / src / doc / hasher.h / hasher_hash.3.md

% 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)