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

The FF3-1 format-preserving encryption mode.

> #### No longer NIST-approved {: .warning}
>
> NIST **removed the entire FF3 family (FF3 and FF3-1)** in
> [SP 800-38Gr1 2pd](https://csrc.nist.gov/pubs/sp/800/38/g/r1/2pd)
> (Second Public Draft, February 2025): Beyne's linear cryptanalysis
> ([CRYPTO 2021](https://doi.org/10.1007/978-3-030-84242-0_3)) found a weakness
> in the tweak schedule that affects both FF3 and FF3-1 but **not** FF1. FF1 is
> now the only approved FPE mode.
>
> FF3-1 is retained here for interoperability with existing data, but new
> applications should prefer `ExFPE.FF1` (the `:ff1` mode, which is the default).

Use it through the `ExFPE` facade: `ExFPE.new(key, :ff3_1, radix_or_alphabet)`,
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 FF3-1: its fixed **7-byte tweak** and its **length constraints**.

This implementation conforms, as best as possible, to
[Draft SP 800-38G Rev. 1](https://csrc.nist.gov/pubs/sp/800/38/g/r1/ipd)
(the first draft, in which FF3-1 was still specified), as published by NIST in
their Cryptographic Standards.

No official test vectors for FF3-1 exist as of the time of writing;
many of the ones used in this library's test suite were copied almost verbatim
from [ubiq-fpe-go](https://gitlab.com/ubiqsecurity/ubiq-fpe-go), an implementation
of the FF1 and FF3-1 algorithms in Go.

## Length constraints

Numerical strings under FF3-1 are subject to minimum and maximum lengths.
These constraints depend on the radix.

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

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

    iex> key = :crypto.strong_rand_bytes(32)
    iex> {:ok, ctx} = ExFPE.new(key, :ff3_1,_radix = 2)
    iex> %{min_length: 20, max_length: 192} = ExFPE.FF3_1.constraints(ctx.algorithm)

`min_length` is required because, for any given radix, short enough numerical
strings encompass too few possible values, rendering encryption ineffective
under adversarial conditions. In other words: their domain is too small.

`max_length` may be there - pure layman speculation - as an incentive for people
to use regular crypto when working with large enough numbers. I didn't find
the exact reasoning for it.

## Tweak

FF3-1 uses a fixed **7-byte (56-bit)** tweak. See `ExFPE` for the general role
of tweaks in FPE, and Appendix C (page 20) of
[the reference
document](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38Gr1-draft.pdf)
for the specifics.

    iex> byte_size(<<0::56>>)
    7

# `radix`

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

# `tweak`

```elixir
@type tweak() :: &lt;&lt;_::56&gt;&gt;
```

---

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