# `ExFPE.FF1`
[🔗](https://github.com/g-andrade/ex_fpe/blob/v0.1.0/lib/ex_fpe/ff1.ex#L3)

The FF1 format-preserving encryption mode.

FF1 is the **only FPE mode approved by NIST** as of
[SP 800-38Gr1 2pd](https://csrc.nist.gov/pubs/sp/800/38/g/r1/2pd)
(Second Public Draft, February 2025), and this library's **default** mode.

Use it through the `ExFPE` facade: since FF1 is the default, `ExFPE.new(key,
radix_or_alphabet)` already selects it (no mode argument needed); then
`ExFPE.encrypt!/3` / `ExFPE.decrypt!/3`. See `ExFPE` for the full how-to-use guide
(contexts, alphabets, tweaks). This module documents what is specific to FF1:
its **variable-length tweak** and its **length constraints**.

## Length constraints

Numerical strings under FF1 are subject to minimum and maximum lengths that
depend on the radix.

    iex> key = :crypto.strong_rand_bytes(32)
    iex> {:ok, ctx} = ExFPE.new(key, _radix = 10)
    iex> %{min_length: 6, max_length: 4_294_967_295} = ExFPE.FF1.constraints(ctx.algorithm)

    iex> key = :crypto.strong_rand_bytes(32)
    iex> {:ok, ctx} = ExFPE.new(key, _radix = 16)
    iex> %{min_length: 5, max_length: 4_294_967_295} = ExFPE.FF1.constraints(ctx.algorithm)

`min_length` exists because, for a given radix, short numerical strings
encompass too few possible values, rendering encryption ineffective under
adversarial conditions. The 2pd requires the domain `radix ** min_length` to
be at least **1 000 000** (strengthened from 100 in the first version, to
mitigate FF1's small-domain vulnerabilities).

## Tweak

FF1 accepts a **variable-length** tweak: any byte string, from the empty
string up to the maximum tweak length. See `ExFPE` for the general role of
tweaks, and the reference document below for the specifics.

# `radix`

```elixir
@type radix() :: 2..65536
```

# `tweak`

```elixir
@type tweak() :: binary()
```

---

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