My Project
sha3

Embeddable, dependency-free C11 implementation of the SHA-3 cryptographic hash functions, eXtendable Output Functions (XOF), and Hash-based Message Authentication Code functions (HMAC) defined in FIPS 202, SP 800-185, and the draft KangarooTwelve and TurboSHAKE specification.

Includes AVX-512 acceleration, Doxygen-friendly API documentation, and a full test suite with sanitizers enabled and test vectors from the NIST CSRC "Examples With Intermediate Values" site and the Test Vectors section of the draft KangarooTwelve and TurboSHAKE specification.

The following algorithms are implemented:

Use make to build a shared library and minimal sample application, make doc to generate HTML-formatted API documentation, and make test to run the test suite.

Examples

Calculate the SHA3-256 hash of a test string and print the result to standard output:

// sha3-256-example: print sha3-256 hash of data to standard output.
#include <stdint.h>
#include <stdio.h>
#include "hex.h"
#include "sha3.h"
// test data
static const uint8_t DATA[] = "this is some test data";
int main(void) {
// hash `DATA` into `buf`
uint8_t buf[32] = { 0 };
sha3_256(DATA, sizeof(DATA), buf);
// print result to stdout
printf("SHA3-256: ");
hex_write(stdout, buf, sizeof(buf));
printf("\n");
return 0;
}
void sha3_256(const uint8_t *src, size_t len, uint8_t dst[static 32])
Calculate SHA3-256 hash of input data.

Calculate the SHAKE128 hash of a test string and print the first 200 bytes to standard output:

//
// shake128-example: hash contents of DATA with SHAKE128 and print first
// 200 bytes of SHAKE128 hash of data to standard output.
//
#include <stdint.h>
#include <stdio.h>
#include "hex.h"
#include "sha3.h"
// test data
static const uint8_t DATA[] = "this is some test data";
int main(void) {
// hash data
uint8_t buf[200] = { 0 };
shake128_xof_once(DATA, sizeof(DATA), buf, sizeof(buf));
// print result to stdout
printf("SHAKE128 (200 bytes): ");
hex_write(stdout, buf, sizeof(buf));
printf("\n");
return 0;
}
void shake128_xof_once(const uint8_t *src, const size_t src_len, uint8_t *dst, const size_t dst_len)
Absorb data into SHAKE128 XOF, then squeeze bytes out.

TurboSHAKE128 example, using the iterative API:

//
// turboshake128-example: Absorb 4096 bytes of data from /dev/urandom in
// 1024 byte chunks, hash it with TurboShake128, then print 128 bytes of
// result in 32 byte chunks (hex-encoded) to standard output.
// output.
//
#include <stdint.h>
#include <stdio.h>
#include <err.h>
#include "hex.h"
#include "sha3.h"
int main() {
// init turboshake
// open source
FILE *fh = fopen("/dev/urandom", "rb");
if (!fh) {
err(-1, "fopen()");
}
{
// read and absorb
uint8_t buf[1024] = { 0 };
for (size_t i = 0; i < 4096/sizeof(buf); i++) {
// read data
if (!fread(buf, sizeof(buf), 1, fh)) {
err(-1, "fread()");
}
// absorb
turboshake128_absorb(&ts, buf, sizeof(buf));
}
}
// close source
if (!fclose(fh)) {
warn("fclose()");
}
printf("TurboShake128 output:\n");
{
// squeeze in 32 byte chunks, write to stdout
uint8_t buf[32] = { 0 };
for (size_t ofs = 0; ofs < 128; ofs += sizeof(buf)) {
turboshake128_squeeze(&ts, buf, sizeof(buf));
hex_write(stdout, buf, sizeof(buf));
}
}
printf("\n");
return 0;
}
void turboshake128_init(turboshake_t *ts)
Initialize TurboSHAKE128 context.
_Bool turboshake128_absorb(turboshake_t *ts, const uint8_t *src, const size_t len)
Absorb data into TurboSHAKE128 context.
void turboshake128_squeeze(turboshake_t *ts, uint8_t *dst, const size_t len)
Squeeze bytes from TurboSHAKE128 context.
TurboShake XOF context.
Definition: sha3.h:1563

See the examples/ directory for more examples.

Documentation

Full API documentation is available in the comments of sha3.h. If you have Doxygen installed, you can generate HTML-formatted API documentation by typeing make doc.

References