# 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.

------------------------------------------------------------
