facil.io

#SHA-2

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

SHA-256 and SHA-512 hashing, with both one-shot and streaming APIs plus HMAC. These are the workhorse hashes for checksums, signatures, and anything that needs a collision-resistant digest.

#Types

#fio_sha256_s

c
typedef struct {
  fio_u256 hash;
  fio_u512 cache;
  uint64_t total_len;
} fio_sha256_s;

Streaming SHA-256 state. Initialize with fio_sha256_init, feed with fio_sha256_consume, and finish with fio_sha256_finalize.

#fio_sha512_s

c
typedef struct {
  fio_u512 hash;
  fio_u1024 cache;
  uint64_t total_len;
} fio_sha512_s;

Streaming SHA-512 state. Initialize with fio_sha512_init, feed with fio_sha512_consume, and finish with fio_sha512_finalize.

#SHA-256 Functions

#fio_sha256

c
fio_u256 fio_sha256(const void *data, uint64_t len);

One-shot SHA-256 of len bytes at data.

Parameters:

  • data - pointer to the data to hash.
  • len - length of the data in bytes.

Returns: a fio_u256 containing the 32-byte digest.

#fio_sha256_init

c
fio_sha256_s fio_sha256_init(void);

Returns: a freshly initialized SHA-256 streaming state.

#fio_sha256_consume

c
void fio_sha256_consume(fio_sha256_s *h, const void *data, uint64_t len);

Feeds more data into a streaming SHA-256 hash. May be called repeatedly.

Parameters:

  • h - pointer to the streaming state.
  • data - pointer to the data to add.
  • len - length of the data in bytes.

#fio_sha256_finalize

c
fio_u256 fio_sha256_finalize(fio_sha256_s *h);

Finalizes the hash and returns the 32-byte digest.

Parameters:

  • h - pointer to the streaming state.

Returns: a fio_u256 containing the digest.

Note: after finalization, h should not be reused without re-initialization.

#SHA-512 Functions

#fio_sha512

c
fio_u512 fio_sha512(const void *data, uint64_t len);

One-shot SHA-512 of len bytes at data.

Parameters:

  • data - pointer to the data to hash.
  • len - length of the data in bytes.

Returns: a fio_u512 containing the 64-byte digest.

#fio_sha512_init

c
fio_sha512_s fio_sha512_init(void);

Returns: a freshly initialized SHA-512 streaming state.

#fio_sha512_consume

c
void fio_sha512_consume(fio_sha512_s *h, const void *data, uint64_t len);

Feeds more data into a streaming SHA-512 hash. May be called repeatedly.

Parameters:

  • h - pointer to the streaming state.
  • data - pointer to the data to add.
  • len - length of the data in bytes.

#fio_sha512_finalize

c
fio_u512 fio_sha512_finalize(fio_sha512_s *h);

Finalizes the hash and returns the 64-byte digest.

Parameters:

  • h - pointer to the streaming state.

Returns: a fio_u512 containing the digest.

Note: after finalization, h should not be reused without re-initialization.

#SHA-384 Functions

SHA-384 is SHA-512 with different initial values, truncated to 48 bytes (truncating a SHA-512 result is NOT the same as SHA-384).

#fio_sha384

c
fio_u512 fio_sha384(const void *data, uint64_t len);

Computes SHA-384 in a single call.

Returns: a fio_u512 whose first 48 bytes hold the digest.

#fio_sha384_init / fio_sha384_consume / fio_sha384_finalize

c
fio_sha512_s fio_sha384_init(void);
void fio_sha384_consume(fio_sha512_s *h, const void *data, uint64_t len);
fio_u512 fio_sha384_finalize(fio_sha512_s *h);

Streaming SHA-384: same state type as SHA-512; fio_sha384_init seeds the SHA-384 initial values, consume/finalize alias the SHA-512 operations.

#HMAC Functions

#fio_sha256_hmac

c
fio_u256 fio_sha256_hmac(const void *key,
                         uint64_t key_len,
                         const void *msg,
                         uint64_t msg_len);

Computes HMAC-SHA256, producing a 32-byte authentication code.

Parameters:

  • key - pointer to the secret key.
  • key_len - length of the key in bytes.
  • msg - pointer to the message to authenticate.
  • msg_len - length of the message in bytes.

Returns: a fio_u256 containing the 32-byte HMAC.

Note: keys longer than 64 bytes are hashed first.

#fio_sha512_hmac

c
fio_u512 fio_sha512_hmac(const void *key,
                         uint64_t key_len,
                         const void *msg,
                         uint64_t msg_len);

Computes HMAC-SHA512, producing a 64-byte authentication code.

Parameters:

  • key - pointer to the secret key.
  • key_len - length of the key in bytes.
  • msg - pointer to the message to authenticate.
  • msg_len - length of the message in bytes.

Returns: a fio_u512 containing the 64-byte HMAC.

Note: keys longer than 128 bytes are hashed first.

#Examples

#One-shot SHA-256

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

int main(void) {
  const char *msg = "hello";
  fio_u256 r = fio_sha256(msg, strlen(msg));
  for (size_t i = 0; i < sizeof(r.u8); ++i)
    printf("%02x", r.u8[i]);
  printf("\n");
  return 0;
}

#Streaming SHA-256

c
fio_sha256_s h = fio_sha256_init();
fio_sha256_consume(&h, "hello, ", 7);
fio_sha256_consume(&h, "world", 5);
fio_u256 r = fio_sha256_finalize(&h);

#HMAC-SHA256

c
fio_u256 mac = fio_sha256_hmac("secret", 6, "hello", 5);

Note: all state lives in caller-owned variables. The functions do not allocate heap memory and are thread-safe as long as each thread uses its own state.