# Lyra2

```c
#define FIO_LYRA2
#include "fio-stl.h"
```

Lyra2 is a memory-hard password hashing scheme built around a BLAKE2b sponge. It lets you tune time cost and memory matrix size so password checks are cheap for you and annoying for attackers. A fair trade.

This implementation matches the reference C setup with `nPARALLEL == 1`, `SPONGE == 0`, and `RHO == 1`. It is single-threaded.

When comparing Lyra2 outputs, use `fio_ct_is_eq` or another constant-time comparison.

## Arguments

```c
typedef struct {
  fio_buf_info_s password;
  fio_buf_info_s salt;
  uint64_t t_cost;
  uint64_t m_cost;
  size_t outlen;
  size_t n_cols;
} fio_lyra2_args_s;
```

| Field | Meaning |
| --- | --- |
| `password` | Password to hash. |
| `salt` | Salt for the hash; use a unique random salt. |
| `t_cost` | Time cost / number of rounds, minimum `1`. |
| `m_cost` | Memory cost / number of matrix rows, minimum `3`. |
| `outlen` | Output length in bytes; default `32` when `0`. |
| `n_cols` | Matrix column count; default `256` when `0`. |

## API

### `fio_lyra2`

```c
SFUNC fio_u512 fio_lyra2(fio_lyra2_args_s args);
#define fio_lyra2(...) fio_lyra2((fio_lyra2_args_s){__VA_ARGS__})
```

Computes a Lyra2 hash and returns up to 64 bytes in `fio_u512`. Use the first `outlen` bytes; when `outlen` is `0`, use the default 32 bytes.

For outputs longer than 64 bytes, use `fio_lyra2_hash`.

### `fio_lyra2_hash`

```c
SFUNC int fio_lyra2_hash(void *out, fio_lyra2_args_s args);
#define fio_lyra2_hash(out, ...)                                               \
  fio_lyra2_hash(out, (fio_lyra2_args_s){__VA_ARGS__})
```

Writes the Lyra2 output into a caller-provided buffer. Supports arbitrary output lengths.

Returns `0` on success, `-1` on error.

## Example

```c
#define FIO_LYRA2
#include "fio-stl.h"

int check_password(const char *password,
                   size_t password_len,
                   const void *salt,
                   size_t salt_len,
                   const uint8_t expected[32]) {
  fio_u512 hash = fio_lyra2(
      .password = FIO_BUF_INFO2((void *)password, password_len),
      .salt = FIO_BUF_INFO2((void *)salt, salt_len),
      .t_cost = 3,
      .m_cost = 1024,
      .outlen = 32);

  return fio_ct_is_eq(hash.u8, expected, 32) ? 0 : -1;
}
```

## Practical Notes

- Store the salt, `t_cost`, `m_cost`, `n_cols`, and `outlen` next to the hash.
- Increase `m_cost` first when you want more memory pressure.
- Use constant-time comparison for verification.
- If you need the standardized RFC 9106 family, see [Argon2](https://facil.io/0.8.x/argon2/). Lyra2 is a different memory-hard tool.

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