---
name: "mhash"
section: "3"
platform: "linux"
package: "mhash"
version: "0.9.9.9-7"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/mhash"
---

# mhash(3)

Hash Library

## NAME

**mhash - Hash Library**

## VERSION

mhash .9.2

## SYNOPSIS

```
 #include "mhash.h"
```

 **Informative Functions**

```
 size_t   mhash_count(void);
 size_t   mhash_get_block_size(hashid type);
 char    *mhash_get_hash_name(hashid type);
 size_t   mhash_get_hash_pblock(hashid type);
 hashid   mhash_get_mhash_algo( MHASH);
```

 **Key Generation Functions**

```
 int      mhash_keygen_ext(keygenid algorithm, KEYGEN algorithm_data,
                void* keyword, int keysize,
                unsigned char* password, int passwordlen);
```

 **Initializing Functions**

```
 MHASH    mhash_init(hashid type);
 MHASH    mhash_hmac_init(const hashid type, void *key, int keysize, int block);
 MHASH    mhash_cp( MHASH);
```

 **Update Functions**

```
 int      mhash(MHASH thread, const void *plaintext, size_t size);
```

 **Save/Restore Functions**

```
 int      mhash_save_state_mem(MHASH thread, void *mem, int* mem_size );
 MHASH    mhash_restore_state_mem(void* mem);
```

 **Finalizing Functions**

```
 void    mhash_deinit(MHASH thread, void *result);
 void    *mhash_end(MHASH thread);
 void    *mhash_end_m(MHASH thread, void* (*hash_malloc)(size_t));
```

```
 void    *mhash_hmac_end(MHASH thread);
 void    *mhash_hmac_end_m(MHASH thread, void* (*hash_malloc)(size_t));
 int     mhash_hmac_deinit(MHASH thread, void *result);
```

 **Available Hashes**

*CRC32*: The crc32 algorithm is used to compute checksums. The two variants used in mhash are: **MHASH\_CRC32** (like the one used in ethernet) and **MHASH\_CRC32B** (like the one used in ZIP programs).

*ADLER32*: The adler32 algorithm is used to compute checksums. It is faster than CRC32 and it is considered to be as reliable as CRC32. This algorithm is defined as **MHASH\_ADLER32**.

*MD5*: The MD5 algorithm by Ron Rivest and RSA. In mhash this algorithm is defined as **MHASH\_MD5**.

*MD4*: The MD4 algorithm by Ron Rivest and RSA. This algorithm is considered broken, so don't use it. In mhash this algorithm is defined as **MHASH\_MD4**.

*SHA1*/*SHA256*: The SHA algorithm by US. NIST/NSA. This algorithm is specified for use in the NIST's Digital Signature Standard. In mhash these algorithm are defined as **MHASH\_SHA1** and **MHASH\_SHA256**.

*HAVAL*: HAVAL is a one-way hashing algorithm with variable length of output. HAVAL is a modification of MD5.  Defined in mhash as: **MHASH\_HAVAL256, MHASH\_HAVAL192, MHASH\_HAVAL160, MHASH\_HAVAL128**.

*RIPEMD160*:  RIPEMD-160 is a 160-bit cryptographic hash function, designed by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel. It is intended to be used as a secure replacement for the 128-bit hash functions MD4, MD5, and RIPEMD. MD4 and MD5 were developed by Ron Rivest for RSA Data Security, while RIPEMD was developed in the framework of the EU project RIPE (RACE Integrity Primitives Evaluation, 1988-1992). In mhash this algorithm is defined as **MHASH\_RIPEMD160**.

*TIGER*: Tiger is a fast hash function, by Eli Biham and Ross Anderson. Tiger was designed to be very fast on modern computers, and in particular on the state-of-the-art 64-bit computers, while it is still not slower than other suggested hash functions on 32-bit machines.  In mhash this algorithm is defined as: **MHASH\_TIGER, MHASH\_TIGER160, MHASH\_TIGER128**.

*GOST*: GOST algorithm is a russian standard and it uses the GOST encryption algorithm to produce a 256 bit hash value. This algorithm is specified for use in the Russian Digital Signature Standard. In mhash this algorithm is defined as **MHASH\_GOST**.

 **Available Key Generation algorithms**

*KEYGEN\_MCRYPT*: The key generator used in mcrypt.

*KEYGEN\_ASIS*: Just returns the password as binary key.

*KEYGEN\_HEX*: Just converts a hex key into a binary one.

*KEYGEN\_PKDES*: The transformation used in Phil Karn's DES encryption program.

*KEYGEN\_S2K\_SIMPLE*: The OpenPGP (rfc2440) Simple S2K.

*KEYGEN\_S2K\_SALTED*: The OpenPGP Salted S2K.

*KEYGEN\_S2K\_ISALTED*: The OpenPGP Iterated Salted S2K.

## DESCRIPTION

The **mhash** library provides an easy to use C interface for several *hash* *algorithms* (also known as "one-way" algorithms). These can be used to create checksums, message digests and more. Currently, MD5, SHA1, GOST, TIGER, RIPE-MD160, HAVAL and several other algorithms are supported. **mhash** support *HMAC generation* (a mechanism for message authentication using cryptographic hash functions, and is described in rfc2104). HMAC can be used to create message digests using a secret key, so that these message digests cannot be regenerated (or replaced) by someone else. A key generation mechanism was added to **mhash** since *key generation* algorithms usually involve hash algorithms.

## API FUNCTIONS

We will describe the API of **mhash** in detail now. The order follows the one in the SYNOPSIS directly.

- size\_t **mhash\_count**(void);

  This returns the `"hashid"` of the last available hash. Hashes are numbered from 0 to `"mhash_count()"`.

- size\_t **mhash\_get\_block\_size**(hashid *type*);

  If *type* exists, this returns the used blocksize of the hash *type* in bytes. Otherwise, it returns 0.

- char \***mhash\_get\_hash\_name**(hashid *type*);

  If *type* exists, this returns the name of the hash *type*. Otherwise, a `"NULL"` pointer is returned. The string is allocated with [*malloc*(3)](/malloc/3.md) seperately, so do not forget to [*free*(3)](/free/3.md) it.

- const char \***mhash\_get\_hash\_name\_static**(hashid *type*);

  If *type* exists, this returns the name of the hash *type*. Otherwise, a `"NULL"` pointer is returned.

- size\_t **mhash\_get\_hash\_pblock**(hashid *type*);

  It returns the block size that the algorithm operates. This is used in mhash\_hmac\_init. If the return value is 0 you shouldn't use that algorithm in HMAC.

- hashid **mhash\_get\_mhash\_algo**(MHASH *src*);

  Returns the algorithm used in the state of *src*.

- MHASH **mhash\_init**(hashid *type*);

  This setups a context to begin hashing using the algorithm *type*. It returns a descriptor to that context which will result in leaking memory, if you do not call *mhash\_deinit*(3) later. Returns `"MHASH_FAILED"` on failure.

- MHASH **mhash\_hmac\_init**(const hashid *type*, void \**key*, int *keysize*, int *block*);

  This setups a context to begin hashing using the algorithm type in HMAC mode. *key* should be a pointer to the key and *keysize* its len. The *block* is the block size (in bytes) that the algorithm operates. It should be obtained by *mhash\_get\_hash\_pblock()*. If its 0 it defaults to 64. After calling it you should use *mhash()* to update the context. It returns a descriptor to that context which will result in leaking memory, if you do not call *mhash\_hmac\_deinit*(3) later. Returns `"MHASH_FAILED"` on failure.

- MHASH **mhash\_cp**(MHASH *src*);

  This setups a new context using the state of *src*.

- int **mhash**(MHASH *thread*, const void \**plaintext*, size\_t *size*);

  This updates the context described by *thread* with *plaintext*. *size* is the length of *plaintext* which may be binary data.

- int **mhash\_save\_state\_mem**( MHASH *thread*, void \**mem*, int\* *mem\_size*);

  Saves the state of a hashing algorithm such that it can be restored at  some later point in time using **mhash\_restore\_state\_mem**(). *mem\_size* should  contain the size of the given *mem* pointer. If it is not enough to hold the buffer the required value will be copied there.

- MHASH **mhash\_restore\_state\_mem**(void\* *mem*);

  Restores the state of a hashing algorithm that was saved using  **mhash\_save\_state\_mem**(). Use like **mhash\_init**().

- void \***mhash\_end**(MHASH *thread*);

  This frees all resources associated with *thread* and returns the result of the whole hashing operation (the \`\`*digest*'').

- void **mhash\_deinit**(MHASH *thread*, void\* digest);

  This frees all resources associated with *thread* and stores the result of the whole hashing operation in memory pointed by *digest*. *digest* may be null.

- void \***mhash\_hmac\_end**(MHASH *thread*);

  This frees all resources associated with thread and returns the result of the whole hashing operation (the \`\`*mac*'').

- int **mhash\_hmac\_deinit**(MHASH *thread*, void\* digest);

  This frees all resources associated with *thread* and stores the result of the whole hashing operation in memory pointed by digest. Digest may be null. Returns non-zero in case of an error.

- void \***mhash\_end\_m**(MHASH *thread*, void\* (\*hash\_malloc)(size\_t));

  This frees all resources associated with *thread* and returns the result of the whole hashing operation (the \`\`*digest*''). The result will be allocated by using the *hash\_malloc()* function provided.

- void \***mhash\_hmac\_end**(MHASH *thread*, void\* (\*hash\_malloc)(size\_t));

  This frees all resources associated with thread and returns the result of the whole hashing operation (the \`\`*mac*''). The result will be allocated by using the *hash\_malloc()* function provided.

## KEYGEN API FUNCTIONS

We will now describe the Key Generation API of **mhash** in detail.

- int **mhash\_keygen\_ext**(keygenid *algorithm*, KEYGEN *algorithm\_data*, void\* *keyword*, int *keysize*, unsigned char\* *password*, int *passwordlen*);

  This function, generates a key from a password. The password is read from *password* and it's len should be in *passwordlen*.  The key generation algorithm is specified in *algorithm*, and that algorithm may (internally)  use the KEYGEN structure. The KEYGEN structure consists of:\
    typedef struct keygen {\
           hashid          hash\_algorithm\[2\];\
           unsigned int    count;\
           void\*           salt;\
           int             salt\_size;\
    } KEYGEN;

  The algorithm(s) specified in *algorithm\_data.hash\_algorithm*, should be hash  algorithms and may be used by the key generation algorithm. Some key generation algorithms may use more than one hash algorithms (view also *mhash\_keygen\_uses\_hash\_algorithm()*). If it is desirable (and supported by the algorithm, eg. KEYGEN\_S2K\_SALTED)  a salt may be specified in *algorithm\_data.salt* of size *algorithm\_data.salt\_size* or may be NULL.

  The algorithm may use the *algorithm\_data.count* internally (eg. KEYGEN\_S2K\_ISALTED). The generated keyword is stored in *keyword*, which should be (at least) *keysize* bytes long. The generated keyword is a binary one. Returns a negative number on failure.

- int **mhash\_keygen\_uses\_salt**( keygenid *algorithm*);

  This function returns 1 if the specified key generation algorithm needs a salt to be specified.

- int **mhash\_keygen\_uses\_count**( keygenid *algorithm*);

  This function returns 1 if the specified key generation algorithm needs the algorithm\_data.count field in *mhash\_keygen\_ext()*. The count field tells the algorithm to hash repeatedly the password and to stop when **count** bytes have been processed.

- int **mhash\_get\_keygen\_salt\_size**( keygenid *algorithm*);

  This function returns the size of the salt size, that the specific *algorithm* will use. If it returns 0, then there is no limitation in the size.

- int **mhash\_get\_keygen\_max\_key\_size**( keygenid *algorithm*);

  This function returns the maximum size of the key, that the key generation  algorithm may produce. If it returns 0, then there is no limitation in the size.

- int **mhash\_keygen\_uses\_hash\_algorithm**( keygenid *algorithm*);

  This function returns the number of the hash algorithms the key generation algorithm will use. If it is 0 then no hash algorithm is used by the key generation algorithm. This is for the *algorithm\_data.hash\_algorithm* field in *mhash\_keygen\_ext()*. If

- size\_t **mhash\_keygen\_count**(void);

  This returns the `"keygenid"` of the last available key generation algorithm. Algorithms are numbered from 0 to `"mhash_keygen_count()"`.

- char \***mhash\_get\_keygen\_name**(keygenid *type*);

  If *type* exists, this returns the name of the keygen *type*. Otherwise, a `"NULL"` pointer is returned. The string is allocated with [*malloc*(3)](/malloc/3.md) seperately, so do not forget to [*free*(3)](/free/3.md) it.

- const char \***mhash\_get\_keygen\_name\_static**(keygenid *type*);

  If *type* exists, this returns the name of the keygen *type*. Otherwise, a `"NULL"` pointer is returned.

## EXAMPLE

Hashing STDIN until EOF.

```
 #include <mhash.h>
 #include <stdio.h>
 #include <stdlib.h>
```

```
 int main(void)
 {
        int i;
        MHASH td;
        unsigned char buffer;
        unsigned char hash[16]; /* enough size for MD5 */
```

```
        td = mhash_init(MHASH_MD5);
```

```
        if (td == MHASH_FAILED) exit(1);
```

```
        while (fread(&buffer, 1, 1, stdin) == 1) {
                mhash(td, &buffer, 1);
        }
```

```
        mhash_deinit(td, hash);
```

```
        printf("Hash:");
        for (i = 0; i < mhash_get_block_size(MHASH_MD5); i++) {
                printf("%.2x", hash[i]);
        }
        printf("\n");
```

```
        exit(0);
 }
```

## EXAMPLE

An example program using HMAC:

```
 #include <mhash.h>
 #include <stdio.h>
```

```
 int main()
 {
```

```
        char password[] = "Jefe";
        int keylen = 4;
        char data[] = "what do ya want for nothing?";
        int datalen = 28;
        MHASH td;
        unsigned char mac[16];
        int j;
```

```
        td = mhash_hmac_init(MHASH_MD5, password, keylen,
                            mhash_get_hash_pblock(MHASH_MD5));
```

```
        mhash(td, data, datalen);
        mhash_hmac_deinit(td, mac);
```

```
 /*
  * The output should be 0x750c783e6ab0b503eaa86e310a5db738
  * according to RFC 2104.
  */
```

```
        printf("0x");
        for (j = 0; j < mhash_get_block_size(MHASH_MD5); j++) {
                printf("%.2x", mac[j]);
        }
        printf("\n");
```

```
        exit(0);
 }
```

## HISTORY

This library was originally written by *Nikos Mavroyanopoulos* \<nmav@hellug.gr\> who passed the project over to *Sascha Schumann* \<sascha@schumann.cx\> in May 1999. Sascha maintained it until March 2000. The library is now maintained by *Nikos Mavroyanopoulos*.

## BUGS

If you find any, please send a bug report (preferrably together with a patch) to the maintainer with a detailed description on how to reproduce the bug.

## AUTHORS

Sascha Schumann \<sascha@schumann.cx\> Nikos Mavroyanopoulos \<nmav@hellug.gr\>
