Skip to content

nqhash(3)

nqhash, nqhini, nqhupd, nqhfin, nqhlen, nqhmac — SHA-2, SHA-3, SHAKE and HMAC

libnoqtis, -lnoqtis

#include <noqtis.h>

size_t
nqhlen(nqhalg alg);

int
nqhash(nqhalg alg, const uint8_t *in, size_t inlen, uint8_t *out, size_t outlen);

int
nqhini(nqhctx *ctx, nqhalg alg);

int
nqhupd(nqhctx *ctx, const uint8_t *in, size_t inlen);

int
nqhfin(nqhctx *ctx, uint8_t *out, size_t outlen);

int
nqhmac(nqhalg alg, const uint8_t *key, size_t keylen, const uint8_t *in, size_t inlen, uint8_t *out, size_t outlen);

nqhalg names a hash of FIPS 180-4 or FIPS 202:

SHA-224 28
SHA-256 32
SHA-384 48
SHA-512 64
SHA-512/224 28
SHA-512/256 32
SHA3-224 28
SHA3-256 32
SHA3-384 48
SHA3-512 64
SHAKE128 any (32)
SHAKE256 any (64)

() returns the digest size in bytes; for SHAKE, the output length the pre-hash signatures use (32 for SHAKE128, 64 for SHAKE256). It returns 0 for a value that is not an nqhalg.

() hashes the inlen bytes at in into out. For the fixed-length hashes outlen must be exactly nqhlen(alg); for SHAKE it may be any length, including 0.

(), () and () hash a message given in pieces. nqhctx is opaque but sized in the header, so it can live on the stack; it needs no cleanup function. nqhini() starts ctx for alg; nqhupd() absorbs more input and may be called any number of times; nqhfin() writes the digest (the same length rule as nqhash()). For a fixed-length hash, nqhfin() ends the context, which must be started again with nqhini() before reuse. For SHAKE, nqhfin() may be called again to squeeze more output; after the first nqhfin(), nqhupd() fails. nqhupd() and nqhfin() check the fields of the context and return NQESTATE for one nqhini() did not make (copied in from elsewhere and changed), rather than follow a position out of its buffer.

() computes HMAC (FIPS 198-1, RFC 2104) with any of the ten fixed-length hashes, writing the first outlen bytes of the tag (1 to nqhlen(alg)) to out. Compare tags with nqcteq(3), never memcmp(3).

nqhlen() returns a size. The other functions return NQOK (0) or a negative error code:

[NQEARG]
alg is not an nqhalg; ctx is NULL; a pointer is NULL with a nonzero length; outlen is larger than a fixed-length digest; or, for nqhmac(), out is NULL or outlen is 0 or over the digest size.
[NQEBUF]
outlen is smaller than a fixed-length digest.
[NQESTATE]
nqhupd() or nqhfin() on a context that was not started, or was finished.
[NQENOSUP]
nqhmac() with SHAKE128 or SHAKE256.

Adapted from docs/examples/hash.c of the source tree:

const uint8_t abc[] = "abc";
uint8_t d[32], x[64];
nqhctx c;
int rc = nqhash(NQS256, abc, 3, d, sizeof d);
/* SHAKE256: 32 bytes, then 32 more from the same context */
if (rc == NQOK)
  rc = nqhini(&c, NQSHK256);
if (rc == NQOK)
  rc = nqhupd(&c, abc, 3);
if (rc == NQOK)
  rc = nqhfin(&c, x, 32);
if (rc == NQOK)
  rc = nqhfin(&c, x + 32, 32);

noqtis-hash(1), noqtis(3), nqcteq(3), nqsign(3)

FIPS 180-4 (SHA-2), FIPS 202 (SHA-3, SHAKE), FIPS 198-1 (HMAC).