11 KiB
Introduction
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.
Getting Started
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 context;
uint8_t buffer[BUFSIZ], digest[NUHASH_BYTES];
char hexstr[NUHASH_CHARS];
/* initialization */
nuhash_init(&context);
/* input data processing */
while(more_data())
{
const size_t len = read_data(buffer, BUFSIZ);
nuhash_update(&context, buffer, len);
}
/* finalization */
nuhash_final(&context, digest);
/* print the result */
puts(nuhash_tohex(digest, 0, hexstr));
}
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 */
nuhash_compute(get_data(), length(), digest);
/* print the result */
puts(nuhash_tohex(digest, 0, hexstr));
}
Command-line Usage
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.
Example output:
abe9d2f9f55d62951540397875f1104d0374a7ce3ca9e21cfde6efd638b75765885f186477669b79d78d13b6d1abe0a2 foo
06573eaba880f77db3a9e6a085e3a4f8c1bf6f2997d6789bc38439d1f581e0907b21200aff43df37de27d241dc64d19e bar
e26b0338b7a3d662397cbc1ff9f81ac8885ee71f861f5897fc3a7b113ea314994f749caf7618a4bfc1ac90727ef64f94 baz
d113572666421a1e2cf6e17481f1f94b2b006e8c48504fea03e4b24d04930db4302368dc0e7bf44b104f7118bdd62f2d qux
Application Programming Interface (API)
C99 API
Constants
The C99 API defines the following constants:
-
NUHASH_WORDS
: The size of the “raw” hash value (digest), inuint64_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.
Simple
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 beNUHASH_BYTES
in size.
-
Return value:
- This function returns the given
out
pointer.
- This function returns the given
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 beNUHASH_BYTES
in size.
-
Return value:
- This function returns the given
out
pointer.
- This function returns the given
Stream API
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 thenuhash_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 thenuhash_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 thenuhash_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 thenuhash_t
instance to be updated.out
: Pointer to the destination array where the hash value is stored, must beNUHASH_BYTES
in size.
-
Return value:
- This function returns the given
out
pointer.
- This function returns the given
Utilities
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 beNUHASH_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 beNUHASH_CHARS
in size.
-
Return value:
- This function returns the given
out
pointer.
- This function returns the given
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:
- This function returns the given
build
pointer.
- This function returns the given
Thread-safety
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
.
Source Code
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)
License
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
Acknowledgment
Licenses for third-party components used by NuHash:
- Hash icons
Created by Vectors Market – Flaticon. Free for personal and commercial use with attribution.
▮