ExFPE.FF1 (ex_fpe v0.1.0)

Copy Markdown View Source

The FF1 format-preserving encryption mode.

FF1 is the only FPE mode approved by NIST as of SP 800-38Gr1 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.

Summary

Types

radix()

@type radix() :: 2..65536

tweak()

@type tweak() :: binary()