facil.io

#SHA-3

c
#define FIO_SHA3
#include "fio-stl.h"

The SHA-3 family (SHA3-224/256/384/512) and the SHAKE128/SHAKE256 extendable-output functions, built on Keccak-f[1600]. All variants share one streaming context type.

#Types

#fio_sha3_s

c
typedef struct {
  uint64_t state[25];
  uint8_t buf[200];
  size_t buflen;
  size_t rate;
  size_t outlen;
  uint8_t delim;
} fio_sha3_s;

Streaming context for every SHA-3 and SHAKE variant.

Members:

  • state - the 25-word Keccak-f[1600] state.
  • buf - partial-block input buffer.
  • buflen - bytes currently buffered.
  • rate - absorption/squeezing rate in bytes, set by the init function.
  • outlen - fixed output length in bytes for SHA-3; 0 for SHAKE.
  • delim - domain separator (0x06 for SHA-3, 0x1F for SHAKE).

Note: treat this as opaque. Always initialize it with one of the fio_sha3_*_init or fio_shake*_init functions.

#SHA-3 Fixed-Output Functions

#fio_sha3_224_init

c
fio_sha3_s fio_sha3_224_init(void);

Returns: a SHA3-224 context (28-byte output, rate 144).

#fio_sha3_256_init

c
fio_sha3_s fio_sha3_256_init(void);

Returns: a SHA3-256 context (32-byte output, rate 136).

#fio_sha3_384_init

c
fio_sha3_s fio_sha3_384_init(void);

Returns: a SHA3-384 context (48-byte output, rate 104).

#fio_sha3_512_init

c
fio_sha3_s fio_sha3_512_init(void);

Returns: a SHA3-512 context (64-byte output, rate 72).

#fio_sha3_consume

c
void fio_sha3_consume(fio_sha3_s *restrict h,
                      const void *restrict data,
                      size_t len);

Feeds len bytes into a SHA-3 context. May be called repeatedly.

Parameters:

  • h - pointer to the streaming context.
  • data - pointer to the data to absorb.
  • len - length of the data in bytes.

#fio_sha3_finalize

c
void fio_sha3_finalize(fio_sha3_s *restrict h, void *restrict out);

Pads, permutes, and writes h->outlen digest bytes to out.

Parameters:

  • h - pointer to the streaming context.
  • out - output buffer, must hold at least h->outlen bytes.

Note: do not call this on a SHAKE context. Use fio_shake_squeeze instead.

#fio_sha3_224

c
void fio_sha3_224(void *restrict out,
                  const void *restrict data,
                  size_t len);

One-shot SHA3-224.

Parameters:

  • out - output buffer (28 bytes).
  • data - pointer to the data to hash.
  • len - length of the data in bytes.

#fio_sha3_256

c
void fio_sha3_256(void *restrict out,
                  const void *restrict data,
                  size_t len);

One-shot SHA3-256.

Parameters:

  • out - output buffer (32 bytes).
  • data - pointer to the data to hash.
  • len - length of the data in bytes.

#fio_sha3_384

c
void fio_sha3_384(void *restrict out,
                  const void *restrict data,
                  size_t len);

One-shot SHA3-384.

Parameters:

  • out - output buffer (48 bytes).
  • data - pointer to the data to hash.
  • len - length of the data in bytes.

#fio_sha3_512

c
void fio_sha3_512(void *restrict out,
                  const void *restrict data,
                  size_t len);

One-shot SHA3-512.

Parameters:

  • out - output buffer (64 bytes).
  • data - pointer to the data to hash.
  • len - length of the data in bytes.

#SHAKE Extendable-Output Functions

#fio_shake128_init

c
fio_sha3_s fio_shake128_init(void);

Returns: a SHAKE128 context (variable output, rate 168).

#fio_shake256_init

c
fio_sha3_s fio_shake256_init(void);

Returns: a SHAKE256 context (variable output, rate 136).

#fio_shake_consume

c
#define fio_shake_consume fio_sha3_consume

Alias for fio_sha3_consume. Feeds data into a SHAKE context.

#fio_shake_squeeze

c
void fio_shake_squeeze(fio_sha3_s *restrict h,
                       void *restrict out,
                       size_t outlen);

Squeezes outlen bytes from a SHAKE context. On the first call it applies padding and runs the first permutation; later calls continue squeezing and re-permute as needed.

Parameters:

  • h - pointer to the SHAKE context.
  • out - output buffer, must hold at least outlen bytes.
  • outlen - number of bytes to squeeze.

#fio_shake128

c
void fio_shake128(void *restrict out,
                  size_t outlen,
                  const void *restrict data,
                  size_t len);

One-shot SHAKE128.

Parameters:

  • out - output buffer.
  • outlen - number of bytes to produce.
  • data - pointer to the data to hash.
  • len - length of the data in bytes.

#fio_shake256

c
void fio_shake256(void *restrict out,
                  size_t outlen,
                  const void *restrict data,
                  size_t len);

One-shot SHAKE256.

Parameters:

  • out - output buffer.
  • outlen - number of bytes to produce.
  • data - pointer to the data to hash.
  • len - length of the data in bytes.

#Examples

#One-shot SHA3-256

c
#define FIO_SHA3
#include "fio-stl.h"
#include <stdio.h>
#include <string.h>

int main(void) {
  const char *msg = "hello";
  uint8_t digest[32];
  fio_sha3_256(digest, msg, strlen(msg));
  for (size_t i = 0; i < sizeof(digest); ++i)
    printf("%02x", digest[i]);
  printf("\n");
  return 0;
}

#Streaming SHA3-512

c
fio_sha3_s h = fio_sha3_512_init();
fio_sha3_consume(&h, "hello, ", 7);
fio_sha3_consume(&h, "world", 5);
uint8_t digest[64];
fio_sha3_finalize(&h, digest);

#SHAKE256 extendable output

c
const char *seed = "hello";
uint8_t out[128];
fio_sha3_s h = fio_shake256_init();
fio_shake_consume(&h, seed, strlen(seed));
fio_shake_squeeze(&h, out, sizeof(out));

Note: state is caller-owned; no heap allocation occurs. Keep SHA-3 and SHAKE contexts separate at finalization time (fio_sha3_finalize vs. fio_shake_squeeze).