MetamorphicCrypto.KDF (metamorphic_crypto v0.1.0)

Copy Markdown View Source

Argon2id key derivation.

Derives a 32-byte session key from a password and 16-byte salt using Argon2id with libsodium's OPSLIMIT_INTERACTIVE / MEMLIMIT_INTERACTIVE parameters:

  • Time cost: 2 iterations
  • Memory cost: 64 MiB
  • Output: 32 bytes

This is typically used to derive a session key from a user's password, which then decrypts their private key stored on the server.

Usage

salt = MetamorphicCrypto.Keys.generate_salt()
{:ok, session_key} = MetamorphicCrypto.KDF.derive_session_key("my password", salt)

Note: This function is intentionally expensive (64 MiB memory, ~200ms). It runs on a dirty CPU scheduler to avoid blocking the BEAM.

Summary

Functions

Derive a 32-byte session key from a password and base64-encoded 16-byte salt.

Derive a session key, raising on failure.

Parse the salt portion from a key_hash string.

Functions

derive_session_key(password, salt_b64)

@spec derive_session_key(password :: String.t(), salt_b64 :: String.t()) ::
  {:ok, String.t()} | {:error, String.t()}

Derive a 32-byte session key from a password and base64-encoded 16-byte salt.

Returns {:ok, key_b64} or {:error, reason}.

Example

salt = MetamorphicCrypto.Keys.generate_salt()
{:ok, key} = MetamorphicCrypto.KDF.derive_session_key("correct horse battery staple", salt)

derive_session_key!(password, salt_b64)

@spec derive_session_key!(password :: String.t(), salt_b64 :: String.t()) ::
  String.t()

Derive a session key, raising on failure.

Example

key = MetamorphicCrypto.KDF.derive_session_key!("password", salt)

parse_salt_from_key_hash(key_hash)

@spec parse_salt_from_key_hash(key_hash :: String.t()) ::
  {:ok, String.t()} | {:error, String.t()}

Parse the salt portion from a key_hash string.

Key hashes are stored as {salt_b64}$argon2id. This extracts the salt.

Example

{:ok, salt} = MetamorphicCrypto.KDF.parse_salt_from_key_hash("c2FsdA==$argon2id")
#=> {:ok, "c2FsdA=="}