facil.io

#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. Lyra2 is a different memory-hard tool.