NuHash is a fast, portable and secure hashing library, released under the CC0 license.
The “core” library (libnuhash) is written in pure C99, but a high-level wrapper for C++ is also provided.
Supported platforms include Linux, Windows, *BSD, Illumos, Haiku OS, GNU Hurd and MacOS X.
The following example shows how to use the libnuhash “stream” API in C99 code:
#include <nuhash.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
/* state variables */
;
nuhash_t contextuint8_t buffer[BUFSIZ], digest[NUHASH_BYTES];
char hexstr[NUHASH_CHARS];
/* initialization */
(&context);
nuhash_init
/* input data processing */
while(more_data())
{
const size_t len = read_data(buffer, BUFSIZ);
(&context, buffer, len);
nuhash_update}
/* finalization */
(&context, digest);
nuhash_final
/* print the result */
(nuhash_tohex(digest, 0, hexstr));
puts}
If all input data is available at once, the libnuhash “simple” API can be used instead:
#include <nuhash.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
/* state variables */
uint8_t digest[NUHASH_BYTES];
char hexstr[NUHASH_CHARS];
/* compute hash */
(get_data(), length(), digest);
nuhash_compute
/* print the result */
(nuhash_tohex(digest, 0, hexstr));
puts}
The nuhash
command-line tool provides
an interface similar to sha256sum
and friends:
Usage:
nuhash.exe [options] [<file_1> [... <file_n>]]
Options:
-b --binary Output digest as binary, default is hex-string.
-h --help Print the help screen and exit.
-i --ignore Ignore interrupt signals.
-l --line-mode Process the input file(s) as text, line by line.
-p --progress Print progress, while computing the hash.
-s --stop Stop on all errors, default is to keep going.
-t --self-test Run the built-in self-test.
-u --uppercase Print digest as uppercase, default is lowercase.
-v --version Print version information and exit.
abe9d2f9f55d62951540397875f1104d0374a7ce3ca9e21cfde6efd638b75765885f186477669b79d78d13b6d1abe0a2 foo
06573eaba880f77db3a9e6a085e3a4f8c1bf6f2997d6789bc38439d1f581e0907b21200aff43df37de27d241dc64d19e bar
e26b0338b7a3d662397cbc1ff9f81ac8885ee71f861f5897fc3a7b113ea314994f749caf7618a4bfc1ac90727ef64f94 baz
d113572666421a1e2cf6e17481f1f94b2b006e8c48504fea03e4b24d04930db4302368dc0e7bf44b104f7118bdd62f2d qux
The C99 API defines the following constants:
NUHASH_WORDS
: The size of the “raw”
hash value (digest), in uint64_t
words.
NUHASH_BYTES
: The size of the “raw”
hash value (digest), in bytes.
NUHASH_CHARS
: The size of the hash
value (digest) encoded as a null-terminated “hex” string, in characters.
This is twice the size of a “raw” hash value plus an additional
slot for the terminating \0
character.
The simple API can be used to compute a hash value in an “all at once” fashion.
Use this API, if all input data is available at once. It can compute the hash value with as single function call.
nuhash_compute()
Compute the hash value from the given input data and return the resulting hash value (digest).
Syntax:
uint8_t *nuhash_compute(const uint8_t *const src, const size_t len, uint8_t *const out);
Parameters:
src
: Pointer to the source array
containing all input data to be processed (sequence of bytes).len
: The length of the input data, in
bytes.out
: Pointer to the destination array
where the hash value is stored, must be
NUHASH_BYTES
in size.Return value:
out
pointer.nuhash_compute_with_key()
Compute the hash value from the given input data and a user-defined key; returns the hash value (digest).
Syntax:
uint8_t *nuhash_compute_with_key(const uint8_t *const key, const size_t key_len,
const uint8_t *const src, const size_t in_len, uint8_t *const out);
Parameters:
key
: Pointer to the source array
containing a user-defined key (sequence of bytes).key_len
: The length of the
user-defined key, in bytes.src
: Pointer to the source array
containing all input data to be processed (sequence of bytes).in_len
: The length of the input data,
in bytes.out
: Pointer to the destination array
where the hash value is stored, must be
NUHASH_BYTES
in size.Return value:
out
pointer.The stream API can be used to compute a hash value in a “step by step” fashion.
Use this API, if not all input data is available at once. The input data can be processed in chunks of arbitrary size.
nuhash_t
An object containing the state of an ongoing hash computation.
The application shall treat this type as an opaque data structure; it is not meant to be accessed directly!
nuhash_init()
Initialize or reset the state for a new hash computation.
This function is supposed to be called exactly once at the beginning of a new hash computation!
Syntax:
void nuhash_init(nuhash_t *const ctx);
Parameters:
ctx
: Pointer to the
nuhash_t
instance to be initialized.nuhash_init_with_key()
Initialize or reset the state for a new hash computation with a user-defined key.
This function is supposed to be called exactly once at the beginning of a new hash computation!
Syntax:
void nuhash_init_with_key(nuhash_t *const ctx, const uint8_t *const key, const size_t len);
Parameters:
ctx
: Pointer to the
nuhash_t
instance to be initialized.key
: Pointer to the source array
containing the user-defined key (sequence of bytes).len
: The length of the user-defined
key, in bytes.nuhash_update()
Process the next chunk of input data and update the state.
This function is supposed to be called repeatedly until all the input data has been processed!
Syntax:
void nuhash_update(nuhash_t *const ctx, const uint8_t *const src, const size_t len);
Parameters:
ctx
: Pointer to the
nuhash_t
instance to be updated.src
: Pointer to the source array
containing the next chunk of input data (sequence of bytes).len
: The length of the input data, in
bytes.nuhash_final()
Finish the hash computation and return the resulting hash value (digest).
This function is supposed to be called exactly once after
all the input data has been processed! After calling this function, the
nuhash_t
instance is invalidated; it must
be reset in order to start a new
hash computation.
Syntax:
uint8_t *nuhash_final(nuhash_t *const ctx, uint8_t *const out);
Parameters:
ctx
: Pointer to the
nuhash_t
instance to be updated.out
: Pointer to the destination array
where the hash value is stored, must be
NUHASH_BYTES
in size.Return value:
out
pointer.The C99 API also provides a few additional utility functions that may be helpful.
nuhash_tohex()
Converts a “raw” hash value (digest) into a null-terminated “hex” string.
Syntax:
char *nuhash_tohex(const uint8_t *const hash, const int upper, char *const out);
Parameters:
hash
: Pointer to the source array
containing the “raw” hash value, must be
NUHASH_BYTES
in size.upper
: If non-zero, generate
upper-case characters; otherwise generate lower-case characters.out
: Pointer to the destination array
where the “hex” string is stored, must be
NUHASH_CHARS
in size.Return value:
out
pointer.nuhash_version()
Returns the version number and the build date of the current libnuhash library.
Syntax:
char *nuhash_version(uint16_t version[3U], char *const build);
Parameters:
version
: Pointer to the destination
array where the major, minor and patch
version are stored.build
: Pointer to the destination
array where the build date is stored, must be 12
characters in size.Return value:
build
pointer.All functions provided by libnuhash are
thread-safe and reentrant, in the sense that there is
no implicitly shared “global” state; the functions
operate strictly on the given input parameters. Specifically, the
functions of the “stream” API maintain all state of the
hash computation within the given nuhash_t
instance. This
means that these functions are thread-safe and
reentrant as long as each “concurrent” invocation uses its own
separate nuhash_t
instance; no
synchronization is required in that case. However, libnuhash
makes no attempt to coordinate the access to the
same nuhash_t
instance between concurrent threads.
If the same nuhash_t
instance needs to be accessed
by multiple concurrent threads (which generally is
not advised), then the application is responsible for
serializing all access to that “shared” instance, e.g. by using
a mutex
lock! Reentrancy can not be achieved with a single
“shared” nuhash_t
.
The source code is available from these Git mirrors:
git clone https://github.com/lordmulder/NuHash.git
(Browse)git clone https://bitbucket.org/muldersoft/nuhash.git
(Browse)git clone https://gitlab.com/lord_mulder/nuhash.git
(Browse)git clone https://repo.or.cz/nuhash.git
(Browse)git clone https://punkindrublic.mooo.com:3000/Muldersoft/NuHash.git
(Browse)This work has been released under the CC0 1.0 Universal license.
For details, please refer to:
https://creativecommons.org/publicdomain/zero/1.0/legalcode
Licenses for third-party components used by NuHash:
▮