#SHA-2
#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
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
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
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
fio_sha256_s fio_sha256_init(void);Returns: a freshly initialized SHA-256 streaming state.
#fio_sha256_consume
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
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
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
fio_sha512_s fio_sha512_init(void);Returns: a freshly initialized SHA-512 streaming state.
#fio_sha512_consume
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
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
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
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
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
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
#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
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
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.