# `MetamorphicCrypto.Keys`
[🔗](https://github.com/moss-piglet/metamorphic_crypto/blob/main/lib/metamorphic_crypto/keys.ex#L1)

Key generation and private key management.

## Key types

| Type | Size | Use |
|------|------|-----|
| Symmetric key | 32 bytes | SecretBox encryption |
| X25519 keypair | 32 + 32 bytes | BoxSeal / Seal public-key encryption |
| Salt | 16 bytes | Argon2id KDF input |

## Usage

    # Symmetric key for SecretBox
    key = MetamorphicCrypto.Keys.generate_key()

    # X25519 keypair for BoxSeal
    {public_key, private_key} = MetamorphicCrypto.Keys.generate_keypair()

    # Salt for KDF
    salt = MetamorphicCrypto.Keys.generate_salt()

# `decrypt_private_key`

```elixir
@spec decrypt_private_key(ciphertext_b64 :: String.t(), session_key_b64 :: String.t()) ::
  {:ok, String.t()} | {:error, String.t()}
```

Decrypt an encrypted private key with a session key.

Returns `{:ok, private_key_b64}` or `{:error, reason}`.

## Example

    {:ok, private_key} = MetamorphicCrypto.Keys.decrypt_private_key(encrypted_sk, session_key)

# `encrypt_private_key`

```elixir
@spec encrypt_private_key(
  private_key_b64 :: String.t(),
  session_key_b64 :: String.t()
) ::
  {:ok, String.t()} | {:error, String.t()}
```

Encrypt a private key (base64) with a session key for storage.

The private key is treated as a UTF-8 string (its base64 representation)
and encrypted with XSalsa20-Poly1305.

## Example

    {_pk, sk} = MetamorphicCrypto.Keys.generate_keypair()
    session_key = MetamorphicCrypto.Keys.generate_key()
    {:ok, encrypted_sk} = MetamorphicCrypto.Keys.encrypt_private_key(sk, session_key)

# `generate_key`

```elixir
@spec generate_key() :: String.t()
```

Generate a random 32-byte symmetric key (base64-encoded).

## Example

    key = MetamorphicCrypto.Keys.generate_key()

# `generate_keypair`

```elixir
@spec generate_keypair() :: {String.t(), String.t()}
```

Generate a random X25519 keypair.

Returns `{public_key_b64, private_key_b64}`.

## Example

    {public_key, private_key} = MetamorphicCrypto.Keys.generate_keypair()

# `generate_salt`

```elixir
@spec generate_salt() :: String.t()
```

Generate a random 16-byte Argon2id salt (base64-encoded).

## Example

    salt = MetamorphicCrypto.Keys.generate_salt()

---

*Consult [api-reference.md](api-reference.md) for complete listing*
