# Introduction

Sodium is a modern, easy-to-use software library for encryption, decryption, signatures, password hashing, and more.

It is a portable, cross-compilable, installable, and packageable fork of [NaCl](http://nacl.cr.yp.to/), with a compatible but extended API to improve usability even further.

Its goal is to provide all of the core operations needed to build higher-level cryptographic tools.

Sodium is cross-platform and cross-language. It runs on many compilers and operating systems, including Windows (with MinGW or Visual Studio, x86, x86\_64 and arm64), iOS, and Android. JavaScript and WebAssembly versions are also available and fully supported. Furthermore, bindings for all common programming languages are available and well-supported.

The design choices emphasize security and ease of use. But despite the emphasis on high security, primitives are faster across-the-board than most implementations.

## Downloading libsodium

[libsodium 1.0.22-stable](https://download.libsodium.org/libsodium/releases/) is the latest version.

* [Tarballs and pre-compiled binaries](https://download.libsodium.org/libsodium/releases/)
* [GitHub repository](https://github.com/jedisct1/libsodium)
* [Documentation](https://doc.libsodium.org)

## Mailing list

A mailing list is available to discuss libsodium.

To join, just send a random email to `sodium-subscribe` {at} `pureftpd`{dot}`org`.

## License

[ISC license](https://en.wikipedia.org/wiki/ISC_license).

See the `LICENSE` file for details.

## Thanks!

Sodium is developed by volunteers. We would like to especially thank the following companies and organizations for their contribution:

* [Paragonie Initiative Enterprise](https://paragonie.com/), who donated a Raspberry Pi to ensure that the library works perfectly on this hardware. Thanks!
* [Private Internet Access](https://www.privateinternetaccess.com), who sponsored a [complete security audit](https://www.privateinternetaccess.com/blog/libsodium-audit-results/). This is amazing, thanks!
* [Maximilian Blochberger](https://github.com/blochberger) and Joshua Small, who both generously donated $100. This will help cover the infrastructure costs a lot. Thanks again, Max and Joshua!

People who designed the primitives and wrote implementations the library is based on can be found in the [AUTHORS](https://raw.githubusercontent.com/jedisct1/libsodium/master/AUTHORS) file. This project wouldn’t exist without them.

Also, a huge “thank you” to people and companies who contributed bindings for their favorite programming languages. A list can be found in the [THANKS](https://raw.githubusercontent.com/jedisct1/libsodium/master/THANKS) file.

Another huge “thank you” to package maintainers who have been doing an amazing job at building packages for many distributions and operating systems.

Finally, thanks to **you** for reading this documentation and for the awesome projects you are going to build with this library!


# Installation

## Versioning

Libsodium uses a two-tier release system:

**Point releases** (e.g., 1.0.20, 1.0.21, 1.0.22) are tagged from time to time, typically when new features are added or significant changes are made.

**Stable releases** are frequent updates to the current point release. They address compilation issues, documentation problems, and performance improvements while remaining fully compatible with their parent point release. No new features, no breaking changes.

If your application depends on a specific point release, stable releases provide continuous updates that are always safe to apply. This is particularly valuable for enterprises that need ongoing support without surprises between point releases.

If a security issue is discovered, it gets fixed in the stable branch of all supported versions, and a new point release follows shortly after.

You can choose to only use point releases if you prefer. But stable releases mean your dependencies stay maintained and secure even when a new point release hasn’t been tagged yet.

## Compilation on Unix-like systems

Sodium is a shared library with a machine-independent set of headers, so it can easily be used by 3rd party projects.

The library is built using Autotools, making it easy to package.

Installation is trivial, and both compilation and testing can take advantage of multiple CPU cores.

Download a [tarball of libsodium](https://download.libsodium.org/libsodium/releases/), preferably the latest `stable` version, then follow the ritual:

```sh
./configure
make && make check
sudo make install
```

On `aarch64`, with some compilers, you may currently have to define `-march=armv8-a+crypto+aes`:

```sh
env CFLAGS="$CFLAGS -march=armv8-a+crypto+aes" ./configure
make && make check
sudo make install
```

Since different files are compiled for different CPU classes, and to prevent unwanted optimizations, link-time optimization (LTO) should not be used.

Also, do not enable sanitizers (such as `-fsanitize=signed-integer-overflow`). These can introduce side channels.

On Linux, if the process hangs at the `make check` step, your system RNG may not have been properly seeded. Please refer to the notes in the `Usage` section for ways to address this.

Also, on Linux, like any manually installed library, running the `ldconfig` command is required to make the dynamic linker aware of the new library.

## Compilation on Windows

Compilation on Windows is usually not required, as pre-built libraries for MinGW and Visual Studio are available (see below).

However, if you want to compile it yourself, start by cloning the [stable branch](https://github.com/jedisct1/libsodium/archive/stable.zip) from the Git repository.

Visual Studio solutions can then be found in the `builds/msvc` directory.

In order to compile with MinGW, run either `./dist-build/msys2-win32.sh` or `./dist-build/msys2-win64.sh` for Win32 or x64 targets.

Alternatively, you can build and install libsodium using [vcpkg](https://github.com/microsoft/vcpkg/) dependency manager:

```batch
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.bat
./vcpkg install libsodium
./vcpkg integrate install
```

The libsodium port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.

## Pre-built libraries

[Pre-built x86 and x86\_64 libraries for Visual Studio 2017, 2019, 2022, and 2026](https://download.libsodium.org/libsodium/releases/) with `stable` additions (see below) are available, as well as pre-built libraries for MinGW32 and MinGW64. Note that pre-built libraries are built with the run-time Multi-threaded (/MT) and not with Multi-threaded DLL (/MD).

They include header files as well as static (`.LIB`) and shared (`.DLL`) libraries for all the supported compiler versions.

### Note for Visual Studio

Projects willing to statically link Sodium must define a macro named `SODIUM_STATIC`. This will prevent symbol definitions from being referenced with `__declspec(dllexport)`.

## Cross-compiling to Android

After unpacking the source distribution (`stable` is recommended), set `ANDROID_NDK_HOME` to the path to the Android NDK. Note that compilation is only tested on CI with the LTS version of the NDK.

Then, run the `android-aar.sh` script:

```sh
./dist-build/android-aar.sh
```

This will compile libsodium (full builds and minimal builds) for all Android architectures. The resulting libraries are in `libsodium-android-<architecture>` folders.

In addition, this creates AAR files, that can be directly included in projects using `gradle` or `cmake`. After compilation, the script outputs the instructions to do so.

## Cross-compiling to Apple devices

The `apple-xcframework.sh` script creates an `xcframework` package containing `libsodium` for iOS, macOS, Catalyst, watchOS, tvOS, visionOS and their respective emulators:

```sh
./dist-build/apple-xcframework.sh
```

## Cross-compiling to ARM microcontrollers

Here is an example of cross-compiling to ARM using the GNU tools for ARM embedded processors:

```sh
export PATH=/path/to/gcc-arm-none-eabi/bin:$PATH
export LDFLAGS='--specs=nosys.specs'
export CFLAGS='-Os'
./configure --host=arm-none-eabi --prefix=/install/path
make install
```

`make check` can also build the test apps, but these have to be run on the native platform.

Note: `--specs=nosys.specs` is only required for the ARM compilation toolchain.

Please note that using libsodium on ARM Cortex M0, M3, and M4 CPUs is untested and not recommended if side-channels are a concern.

## Compiling with CompCert

Releases can be compiled using the CompCert compiler.

A typical command to compile Sodium on a little-endian system with CompCert is:

```sh
$ env CC=ccomp CFLAGS="-O2 -fstruct-passing" ./configure --disable-shared && \
make && sudo make install
```

## Compiling and cross-compiling with Zig

[Zig](https://ziglang.org) can be used to compile or cross-compile to any supported target:

Compilation for the current target:

```sh
$ zig build -Doptimize=ReleaseFast
```

Size-optimized builds:

```sh
$ zig build -Doptimize=ReleaseSmall
```

Cross-compilation:

```sh
$ zig build -Doptimize=ReleaseFast -Dtarget=aarch64-windows
$ zig build -Doptimize=ReleaseFast -Dtarget=riscv64-linux
$ zig build -Doptimize=ReleaseFast -Dtarget=wasm32-wasi
```

## Stable branch

We recommend using distribution tarballs over cloning the [libsodium Git repository](https://github.com/jedisct1/libsodium), especially since tarballs do not require dependencies, such as Libtool and Autotools.

If cloning a Git repository is more convenient, the [stable](https://github.com/jedisct1/libsodium/tree/stable) branch always contains the latest stable release. As described in the [Versioning](#versioning) section, stable releases are frequent updates to the current point release, fixing bugs and improving performance without introducing new features or breaking changes. This branch also receives critical security fixes while new packages are being prepared.

Code in the `stable` branch includes generated files and does not require autotools (Libtool, Autoconf, and Automake) to be present.

To check out the stable branch:

```sh
git clone https://github.com/jedisct1/libsodium --branch stable
```

Tarballs of the `stable` code are also available for download and recommended if you are compiling libsodium from source.

## Getting started

See the [quickstart](https://libsodium.gitbook.io/doc/quickstart) and [usage](https://libsodium.gitbook.io/doc/usage) sections to get started!

## Integrity checking

Distribution files can be verified with [Minisign](https://jedisct1.github.io/minisign/) using the following Ed25519 key:

`RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3`

The `.minisig` file should be present in the same directory as the main file. The typical command to verify a file is:

```sh
minisign -VP RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3 -m <file>
```

Or with GnuPG and the following RSA key:

```
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1 (OpenBSD)

mQINBFTZ0A8BEAD2/BeYhJpEJDADNuOz5EO8E0SIj5VeQdb9WLh6tBe37KrJJy7+
FBFnsd/ahfsqoLmr/IUE3+ZejNJ6QVozUKUAbds1LnKh8ejX/QegMrtgb+F2Zs83
8ju4k6GtWquW5OmiG7+b5t8R/oHlPs/1nHbk7jkQqLkYAYswRmKld1rqrrLFV8fH
SAsnTkgeNxpX8W4MJR22yEwxb/k9grQTxnKHHkjJInoP6VnGRR+wmXL/7xeyUg6r
EVmTaqEoZA2LiSaxaJ1c8+5c7oJ3zSBUveJA587KsCp56xUKcwm2IFJnC34WiBDn
KOLB7lNxIT3BnnzabF2m+5602qWRbyMME2YZmcISQzjiVKt8O62qmKfFr5u9B8Tx
iYpSOal9HvZqih8C7u/SKeGzbONfbmmJgFuA15LVwt7I5Xx7565+kWeoDgKPlfrL
7zPrCQqS1a75MB+W/fOHhCRJ3IqFc+dT1F4hb8AAKWrERVq27LEJzmxXH36kMbB+
eQg336JlS6TmqelVFb15PgtcFh972jJK8u/vpHY0EBPij5chjYQ2nCBmFLT5O4UZ
Y4Gm8Z3QLFG1EeOiz+uRdNfchxwfLkjng1UhKXSq5yuOAAeMaNoYFtCf1hAHG6tx
vWyIijRxUd5c8cDZsKMuLQ34O6DuvPZyeCy6q8BTfW18miMMhIH0QTS9MwARAQAB
tC5GcmFuayBEZW5pcyAoSmVkaS9TZWN0b3IgT25lKSA8akBwdXJlZnRwZC5vcmc+
iQI2BBMBCAAgAhsDAh4BAheABQJU2dF6BAsJCAcFFQoJCAsFFgIDAQAACgkQIQYn
qrpwn+GpOBAAkJu5yZhLPBIznDZMr0oJ/pJiSea7GUCY4fVuFUKLpLlSjIaSxC4E
2oWG8cJoMdMhwW1x166rRZPdXFpW8eC5r+h8m25HBJ649FjMUPDi2r9uQgPdBy80
I+gFlrsinSy7xbdlUSpjrcYYCx9jYjjTwH6L1QZa+YCMFya8dob/NcdzQ0o7cNRu
5NG988cScsscXYXzI6SMouSwPGCMrQHAsM31Yb8YFbJLuDxFRCZY5+qiR8DXDzW4
Lp68fJq0X/UGW9Q+i29LMTvZZWDGBQ9bwQNtvDrPZ8SYp249cMOsR4W7FK4Y0Oea
YRTBFcXaeXEKAP1ZqYrY22BDiHJO5IGY72D3j3vPATAYigwjr/qNFOt/DaERFpQ4
L7RD+E6WLHATFWxZHH/APck6q8bY4EHr8GJWA77sIqN/Ctvap759QKB8nrerT6lA
0cojhS5Ie8Lro6YsMAXDqwjzsv+VgnTgql8oAFmuU+o+6cmHUwGNHgEs+xe2UDQi
kxu685gOCHfHmBwue391glHufQdveChy5eikif6q6Ndg7VH9mR335o8VJ9I+Vp/k
3W8XZBA9OEuwrxjy1EzWvcb2WGXrUHVZ32w+E9CICvFFV7JiTntG3t1Ch4/bbFwr
wdkc5EZTh0c6B7YfIkEWnOnBovWBPEBkSGve371MsqBuKuBr1W4jecyIRgQQEQgA
BgUCVNnRHAAKCRCSa8UXHN6kOWXzAKCGlk6DvVCqExkBd6OEsaEoOBgH5ACfcVQa
z/FEgCdRsJeLi7xNwZXZ22O0IUZyYW5rIERlbmlzIDxnaXRodWJAcHVyZWZ0cGQu
b3JnPokCNgQTAQgAIAIbAwIeAQIXgAUCVNnRaQQLCQgHBRUKCQgLBRYCAwEAAAoJ
ECEGJ6q6cJ/hslIQAI2l+uRlwmofiSHo/H2cUDNO2Nn7uRfcVIw9EItTmdU6KKx9
nkgFP3Y3lUwkLQFP6aQhQJyHBU5QGqn9n8k8+jEPciTL7hcbTuY0YRuz0mp9bJ8r
ruqGxTrZuogvIVntwnn1HvgAbu13HKu+3KOLYDmWqosVNf0a8GjHj10ZDuNDPQVb
X6NWDes+jLdeUsxVKUZHlOC3CiRCSHJzZ3G1gO9QU78LQAFCIIDO7GO7xPjqbvEX
nsys5f12OLXB4NqBlIamEdyztV+CwIZBM9Ni6ytPnEhWzTHzHwi95oNa+AtpUlgG
RYjYtMR9pxCqVkrplwrwhA4dbSO7HLiXQIrA57F1/5LwKRR4e7IGhnTpZoW8hr8y
qg4AAVCZqr5aB82LOJAMP6ZlC7kQb9/YxGYw4Vwf6qCY8Iw74MvIL5wW0zSv/orB
eNtHeP0Z/Ozx3UXKA2chNElEWbZ9e0IZBXgcj/JDfK8e0VTqv1ItHLm2ZkvCbyhV
fER8I8AHPnfzwkXvWFeDKeMO8rakqDeNQ3h4BeiCBCVHpEsUdIWSG3oCO1guy9/h
xMJR2yAWiK+35sCcZbrgTTN0oQepRMuZ34niIBK0jUh7t1M5sBMNgxEAIeKjJf64
DEudNz+xUgek5N+BXx7hryuVC3s1y6H42ztOjPtpHPVUw98gWpv5V7QRLBs0iEYE
EBEIAAYFAlTZ0RwACgkQkmvFFxzepDn8sACdF51BycwRvMpkFPea1Yi3/B1EOs0A
oJT9afe3zQnOlcIuBFBzpdOTsecUtCZGcmFuayBEZW5pcyA8ZnJhbmsuZGVuaXNA
Y29ycC5vdmguY29tPokCNgQTAQgAIAIbAwIeAQIXgAUCVNnRegQLCQgHBRUKCQgL
BRYCAwEAAAoJECEGJ6q6cJ/h0LgP+wfCw2SCFvD7sFlnmd6oJNP+ddtt+qbxDGXo
UbhrS1N88k6YiFRZQ+Z84ge9RgQXA74xuWlx8g1YBEsqO1rYCGQ4C+Ph+oUO+a3X
k+wmEzINnjCF8CQzZQ3vdXvWmshKzqC2yyeR235WC/BSHsqsr+TRFEmGa68ju8s7
UF8ZQaBzbM0ttUtrc0UqhnS16xV5lH9gBkVbMWIN1pAeJcFRL6MB92Vv5tWjayua
w76vxmwPhu6quUlwxNYNvYBgG5kpBjqMOLHaX1x+SA5F6aI6E3kqxeyurwV6Ty+/
FIns+Awl+IFPey5ctwSOXkizhtqxpMNHAu9resNRjneIjNVTLON1uaxvmPJttMd/
CdTXh+guxDBfH6Vr9nmExy2qbihDJ06Sm874UYtnBZdB7Fi0cNF1DlEZKaZyYaLw
RA/TelI2IaIdkRFLsaFdo144nfceZ2fra2QO83Ow6uShNZzAHU0ZVEKLVt/VJqCL
6hts7vhKuCBcNlpoNOZptRPJf8RMLh4qwtniZadDcM16TpvkyTQUAWH+GvTML0UR
5sLHOtZ7MUaHO/c5UWQWJOmuaWOKgdKLi3iXztGbNNDc9F7wRoObUH7Om/0s5IRy
noO58ofDCmurPDP+10eOQaWtgVz2nFXcFF0qTw4H6L/sXlzbm27HuqEHuYrzpTl/
Njn0chjBiEYEEBEIAAYFAlTZ0RwACgkQkmvFFxzepDnrmQCfdaiJcQsAZaSfEfO1
VxZaY0kEVf0An1xVULYvo5M4sta0tILFu3UthzBGtDdGcmFuayBEZW5pcyAoSmVk
aS9TZWN0b3IgT25lKSA8MGRheWRpZ2VzdEBwdXJlZnRwZC5vcmc+iQI2BBMBCAAg
BQJU2dKRAhsDBAsJCAcFFQoJCAsFFgIDAQACHgECF4AACgkQIQYnqrpwn+FqRxAA
wWm+f6mo9nCoGRD4r4jrSLuJ5ApyIxRQ3L5DL/MeITRMPNDps0OpvKIIGmGv19n5
Ani7ufOcnQLkTVj1179U5BTnahk2fDS0CxlFyslpR9A7tX6qQMtIyBE4cdPhjVue
ZOwI+PfJSleFFmPQ3ESlbKzeNGJqBQiNSbpo9qMhhyYRZy/Fk4kOQzAdXpa63kPX
1KVoTsvz19O2frLim7QY8oTI8Vbij0CB+HfhHuLmolc039/S47hF+5ygERK5Fwjo
mSx+Q2fKx9P35TZqQ9Zw73e3gS9YUErT4LU7ZwdmulftfCaVLmIuX4GUDPasmNbA
WLpKHEwLln0YJO0kIzD+2q2zclzUmGgdgGcEUwLb6vpWLJ41MsmHknZg0zm/yG6/
sasA0jU1wKxeRlHeSxnh3PYb+v36kHXsRViqPlwxe9PGmLK9p9wD0yS/dk2LsJbE
1hnUZfw7l14VdivrL567My/0sG3SbIUb/DxHuVkgHU9LHHlca4z5VmFc7v2+sc0+
6IczFW86FKI8m+q8zLhHcquKgZpumxvwjEoAbjl9123bqZKm1e8pHL3bTQa6bSv9
isNsW3T9eHeEB7frbBlYOZjvMQuYLf82t2tu+E4xbUYZZrmlRYGwBGFUBRprtJ0e
XeUvxFgAnazyNNXxXhO3PMiCxpCp0e7+x64fKVPMfFu5Ag0EVNnQDwEQAMnv/UG9
7vAtIyeG+lPalmhn10NQ07I4Rz+vigZHAxO8t7QYhOYOYLZFj1mO11f8lc5X1oxV
7dKwh+sHMJQ3fkOmQbG6VGRLmRTAPk45GsaRcAnczNzCZWw0s4f92ybc9Th4dNR8
dUk90t+tFItPGnFHGHmjwUYMc7u8BNl9l/SNiJipxuHjUR1hXQE+RXrlgkoW9S8I
bisHytd5IcOXGz337coYkdJLzx1AdpOMGN4n5qymlrhjBIvV2a/R+mweUAD7Il8I
Ynj58lalrp2kLmnoJacL0R9R2ZbSjDBevKpitmy3kqHS59vChw80asBRWr10++Ea
V0LnWDKKbc1U809RP1Ac0l66KjKj3mmiQQKDpb2oHHD0uJsx84kqCOkoWdqF12wR
stygYsAc8CJXnsAKThdDvsQTkMX6WKg4wtSJw0ELRtNCQZzH8iE6eq9MXZijvG6H
j9WyZ2L2eeO0bKn0uEDGvpPMLWcFfOjCxL32x/Jr95sqAt2p0DcBFH5d4jK7tqHQ
YzNwt8ibbbGlwzRFTgq/5igV+n9q9P/h8bWQhUJyqbjyJuwt4l/oTSTKZ5bZ0IAr
KS/+Y/Y9b/BBXRzRP/D1LhaOndH43E6HmEWGS2PhUUPn3V6TQzOq5npaTXKhq/f8
XMYEqvbQ3qjfREa+LLgmFLAwD7rc8h2WYVp7ABEBAAGJAh8EGAEIAAkFAlTZ0A8C
GwwACgkQIQYnqrpwn+GCVhAAscO0pYCRzcgDwDWOrT3g5yi8dt3NmDGL9c6/ohKV
waWSIDlwFtbZNiZ/fr91VCdDfhUSohtn6E7XvKYdVNO4NRLIbSgRc7Y/C4P+9lEh
k+6mlXYlEil/GN6YXBsQvDSz1xw+Csz3Y6kq2m1xiSHFuZrP0PS75x+vIAKbIspa
uu5IyEh/wAW1vY/pnzs7TJtY2r8Qsv/5xt+zUdlGB0ZJq7IZ/1GveltRMJrfhcCT
KPQRWdMv0aEioeBwYAM8sc9UrrePM9jSpT3uCYwuJlld4M94+tqt7tqvkR6dluXF
+4WWeuPXo65jSBl094BEfT5dVbt0TqmG6eTgnPghh1j7PpIghyqUU0v8YPl5DUnZ
UuHzi4CEcQWNUEq+xK9N2/nflaq8R4LPDJjupSWIw5tZv8NWj+EA/zyxggX+q2pr
3qlD+IUnO8cR/RT1LvZ9L5t1fvTqjpgDqXJIremihObLOGEV0+0xWEaN085OVzyU
QTt2EBhzSxHkC0CEd6CgR8l48YGsKJrHCjuOvQ+lgVtAkgYBeVFefhrKa242TmVB
NlZCkS25wUhGhWbLv334p+KTG4d79J+iKYbh8n0C/gBK0YzDX3gLbL+6wes0xYia
WSRBfx9hfPCfFLDGG5sY7yViH8YcOGig6IV9+DWBCSyOZ0d0IXWNvTLF+3d1BFD4
dlG5Ag0EVNnQNwEQANZNoFI4cM9TYFCMOYIiH1UaXoibNE7kZ1qDM/O6y5HTUOSn
m2koCYMTqtVaigAq/tXiUJLBzoHwh17CzDx5L3/IShMHdqwAFCcUZII2NW/XEEH7
knwnqn5tki2CZCzfE+GXtUm7M7fBW2pgPvVt/Ord+DhmEKP0A+fdKHS3x/EUn8Vs
vJoYEkxg9fT14eqYk+oALFxm6vW9UAFO0VZ/JOXzeDTux0+6p6NQjcykKeG5GiXA
dHpRopfeksLQx3sZqfFBEhuiIX7PllAQxHpPqKcPG82aVqT5x9tvZ2RVdk/55hcK
gNhdcbDGWqkNENbOvTmom2a/gDNgb7pf12jJa9t2RRVC8oyYh+zVftLhf2GlwMVv
vwuXO1U2A0/lUQ7K33t6lQ2mEmbudyeFJCso3kIJ598efTw2ZPkeEkZ+adsIBQbd
CSEm0B/S+DS8CDTLTfS5nN5T3rGnO7lzPf983uP9CLbODyt05dqF1Hl+4XicMT3P
Qtz1T+P7X7nPQL9FUwOWUBHqfhYhNsnV17m6M/ODoKsyjdl92njOxvyD6zVaffcx
2zX+SYEaIIiDFhxVFprhwTuruKOfax3nNTLd1JeiraUejSNCnP60VxTsp203Y0H8
quLtvsWF6V5lr57WQxGQxQmS5JQV9wreYzuA339ApUqukfWmhiPDHbQVWAe3ABEB
AAGJBD4EGAEIAAkFAlTZ0DcCGwICKQkQIQYnqrpwn+HBXSAEGQEIAAYFAlTZ0DcA
CgkQYvJbWStvdtq1jg/8Dm6BicjEbcNphWpsjj0uoPB49I0fKFxSM2uUh6PI+wtc
LtikJsNyGvXDm7oGE/uXIki5S++91pZ5oTV931HVzp8e4vip5IRCcWFk6NisRmiZ
nN/xMejLnK3s51pmK5UJhoYymrETGiUKj1uu5BqewRXZ4wWH2kzIusBzIc537shR
Gqk+LgwY7/x4aKY+5Z46VpAGSlO4a6WdWtlRLZzOz0x+tPIrAYo0f72hdHg2enZE
rqkhi90dy/5hCsaJRl+raEZVDSggOtO0hmhTnLSWAX3YPINp1qSqvn5EQk8FhZuh
RaonpXg0wZLc82oIYEZ0KnhJ7HBgV/jF78lI5ZPdk9m22GbASWkIjwNmfzAhGEPu
/NX3iweDPfU4ULbOvejs3ivQTEOrF47u3ps/6SOrBXS7f23ZBw7nwYryezCeQUV8
RCKkk+xUPv5YU0DpGtViDrfxeucXW8W05VOBsCfpa2PTXvj4VjP6UGRUcX3SVTcA
VnvKAmfsDa/4+4AOEvfgQFRzuex8tthFbPW2pLJEQPpVFuxAK0foUHw78HFL7NRV
TFx3jUWgGAM7PA9FI9h1rrU5dXyi8uXwBjaXcEaIts7WE0NGjFzEbub6kJldryhl
5ZCMkmOcBU7SkSmI95bOJwvYdGGiEcO4eh7ci4pOFH0ZNqKfpjyfpTgtFgS5Ldne
pBAA8ubnR6+b7gGaOQk/rROTYHoSq9GXVAqhhmY69lfsXQ9EXoiAzNZnhJLtj1J7
86Z3Bgd9X+MXrrPoJLVGmBTT8yT337KY/+rbk16E5oL1eItnsJ0xgprD1gkWUNaa
pRXLKdA86ogoU8sE/9Wr2CN6dCdPCmjmc0mWvGHY5V6lMf3NPIAQbS4izuU/w+IE
gPnBo45BPkxP2HyvhoOek+pxpsqL8uLQzuIjtwgWvMOocVQrpBNr6kQ99hvr8feY
6kOI5MoGsagW3R65m7DAfz/x1oO3QmWT/kg2dcWqiEbzL3phX1QpQtdJkO5+JTYQ
F0WP5sPzQ7DaIP7Mo2NjhqvnO5NR9/kEzX1yEQck3BI4vKNHSiAQ1/J94uiu9Aze
W6ddPO4Ax7LycK0WOeNVNAT6a3tFJbQrve3ZoDDSNXAa70VKmpdrsrwnX+/4+rly
Z7lj7rnMWCe9jllfZ2Mi+nIYXCrvhVh0t7OHVGwpSq28B/e2AFsQZxXcT4Y+6po7
aJADVdb+LlOAuF6xB3sylE1Im0iADCW9UAWub1oiOr9jv0+mHEYc3kaF0kPU5zKO
I9cg891jcOBV/qRv89ubSHifw9hTZB0dDjXzBjNwNjBHqkYDaLsf1izeYHEG4gEO
sjoMDQMqgw6KyZ++6FgAUGX5I1dBOYLJoonhOH/lNmxjQvc= =Hkmu
-----END PGP PUBLIC KEY BLOCK-----
```

## Reporting vulnerabilities

We encourage users and researchers to use PGP encrypted emails to transmit confidential details regarding possible vulnerabilities in the Sodium library.

Details should be sent to j \[at] pureftpd \[dot] org using the PGP key above.


# Quickstart and FAQ

## Boilerplate

A project using libsodium should include the `sodium.h` header. Including individual headers is neither required nor recommended.

The `sodium_init()` function must be called before any other function. It is safe to call `sodium_init()` multiple times or from different threads; it will immediately return `1` without doing anything if the library has already been initialized.

```c
#include <sodium.h>

int main(void)
{
    if (sodium_init() < 0) {
        /* panic! the library couldn't be initialized; it is not safe to use */
    }
    return 0;
}
```

## What is the difference between point releases and stable releases?

Libsodium uses a two-tier versioning system.

**Point releases** (like 1.0.20, 1.0.21, 1.0.22) are tagged when new features are added or significant changes are made.

**Stable releases** happen more frequently between point releases. They fix compilation issues, improve documentation, and enhance performance while remaining fully compatible with their parent point release. They never introduce new features or breaking changes.

If your application depends on a specific point release, you can safely apply stable updates without worrying about compatibility. This is valuable for enterprises that need continuous support without surprises. Of course, you can also choose to use only point releases if you prefer.

If a security issue is discovered, it gets fixed in the stable branch of all supported versions, and a new point release follows shortly after.

See the [Installation guide](https://libsodium.gitbook.io/doc/installation#versioning) for more details.

## Is libsodium cross-platform?

Yes, a message can be encrypted in Python on a MIPS CPU, decrypted in JavaScript using Chrome on Windows, and its signature can then be verified by an iPhone app written in Swift.

The available algorithms are the same on all supported platforms, input and output formats are also identical on all platforms, and bindings for various programming languages tend to leverage the original algorithms and formats.

## How do I generate random numbers that are safe to use for cryptography?

Use the [`randombytes` API](https://libsodium.gitbook.io/doc/generating_random_data).

## How do I compute a hash?

Use the [`crypto_generichash` API](https://libsodium.gitbook.io/doc/hashing/generic_hashing).

## What is the difference between a secret key and a password?

A password has a couple of requirements to fulfill:

* It has to be reasonably short.
* It must be easy to type on any keyboard.
* Users may have to remember it.

As a result, the number of possible passwords of a given size is fairly small. For the same size, the number of distinct passwords actually used is much smaller, and their distribution is skewed. Even if mitigations exist, guessing (brute-forcing) a password is often practical.

A secret key, on the other hand, is a sequence of bits that can be of any size, doesn’t have any restrictions, and is generated by software or specialized hardware. A 32-byte key represents 256 bits, none of them being predictable by observing other bits from that key or previous keys.

Secret keys are not designed to be typed on a keyboard. They are binary data stored as files, kept in secure memory, or sent over the network. They can be unique and offer far more security than passwords.

Libsodium almost exclusively uses secret keys.

If an application must use a password as a secret key, it should call the `crypto_pwhash()` function first. This computes a secret key from a password using an intentionally CPU-intensive and memory-hard function to slow down brute-force attacks.

Native secret keys using the `*_keygen()` function should always be preferred.

## How do I initialize the library from another library?

If the other library doesn’t have any initialization function, it can use a [`DllMain()`](https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain) function (Windows) or `__attribute__((constructor))` (GCC, Clang, icc on macOS and ELF-based systems) to call `sodium_init()` on load.

However, explicitly calling initialization functions is recommended as automatic initialization makes it difficult to safely recover from errors.

## How do I check if a function call succeeded?

Functions returning an `int` return `0` on success and `-1` to indicate an error.

Functions returning a pointer return a valid address on success and `NULL` on error.

Some operations include variants with slightly different algorithms. For example, authenticated encryption can be done with XChaCha20-Poly1305 or AES-GCM. For consistency and to make high-level wrappers using dynamic dispatch easier to implement, all the variants of a function share the same prototype.

In the above example, AES-GCM can fail due to message size limits, but XChaCha20 cannot; its limits are only theoretical, so checking the return value for that variant would not be strictly necessary. However, it is best to check unconditionally in applications because it is cheap, good hygiene, and functions can easily be replaced later if necessary.

Some returned values must be checked. For example, the outcome of the verification of an authentication token. These functions are tagged with the `warn_unused_result` attribute and will cause a compiler warning if ignored. Such warnings must not be ignored.

## How do I encrypt data?

### One-shot encryption where everything fits in memory

1. Create a secret key using `crypto_secretbox_keygen()`.
2. Create a nonce using `randombytes_buf(nonce, sizeof nonce)`.
3. Use `crypto_secretbox_easy()` to encrypt the message and send/store the resulting ciphertext along with the nonce. Unlike the key, the nonce doesn’t have to be secret.
4. Use `crypto_secretbox_open_easy()` to decrypt the ciphertext using the same key and nonce.

### If everything doesn’t fit in memory or is not available as a single chunk

* With libsodium 1.0.14 and beyond, use the [`crypto_secretstream` API](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretstream).
* Otherwise, read the guidance on [encrypting a set of messages](https://libsodium.gitbook.io/doc/secret-key_cryptography/encrypted-messages).

## How do I safely store and later verify a password?

* Use the `crypto_pwhash_str()` and `crypto_pwhash_str_verify()` functions described in the [`password hashing guide`](https://libsodium.gitbook.io/doc/password_hashing).

## How do I encrypt a file using a password?

1. Derive an encryption key from the password using [`crypto_pwhash()`](https://libsodium.gitbook.io/doc/password_hashing/default_phf).
2. Use that key with the [`crypto_secretstream` API](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretstream).

Secret file metadata should be part of the encrypted data, and non-secret metadata can be included as additional data.

## How can `A` and `B` securely communicate without a pre-shared secret key?

Use the [key exchange API](https://libsodium.gitbook.io/doc/key_exchange):

1. `A` and `B` both call `crypto_kx_keypair()` to create their own key pair. Secret keys must remain secret, but `A` can send their public key to `B` or make it available to everyone. The same applies to `B`.
2. `A` uses `crypto_kx_client_session_keys()` along with `B`’s public key and their own key pair to create a set of shared keys to communicate with `B`.
3. `B` uses `crypto_kx_server_session_keys()` along with `A`’s public key and their own key pair to create a set of shared keys to communicate with `A`.

The shared keys computed by `A` and `B` will be identical. There are two of them, so one can be used to encrypt and decrypt messages in one direction (from `A` to `B`), and the other can be used to encrypt and decrypt messages in the other direction (from `B` to `A`).

To encrypt and decrypt data using one of these shared secret keys, use one of `crypto_secretbox_*()`, `crypto_secretstream_*()`, or `crypto_aead_*()`.

## How can I derive multiple keys from a single master key like what HKDF does?

Use the [key derivation API](https://libsodium.gitbook.io/doc/key_derivation).

## Do I need to add a signature to encrypted messages to detect if they have been tampered with?

No, signatures are designed to allow non-secret data to be verified by many parties using a public key. For example, a signature can be used to verify the authenticity of a firmware update.

When `A` encrypts a message for `B` using a shared secret key using `crypto_box()`, `crypto_secretbox()`, `crypto_seal()`, `crypto_secretstream()`, or `crypto_aead()`, an authentication tag is also computed and should be sent to `B` along with the encrypted payload.

During the decryption process, the secret key is used to check that the authentication tag is valid for the given encrypted message. If that message has been modified, the tag will not be valid and decryption functions will return an error code. Knowing the secret key is required to create a valid tag, and therefore only `A` and `B` can create such a tag.

Also, if shared keys are computed using the key exchange API (`crypto_kx`), a valid tag for a message can only be created by the sender.

## How can I sign and encrypt using the same key pair?

First, read the previous section. In most cases, signing a message in addition to encrypting it is not required.

If you need to sign and encrypt a message, possibly for signatures to be publicly verified, consider using [signcryption](https://github.com/jedisct1/libsodium-signcryption).

Alternatively, signing key pairs can be [converted to X25519 key exchange key pairs](https://libsodium.gitbook.io/doc/advanced/ed25519-curve25519). This can be used to encrypt and sign independently.

However, this is not recommended and is usually not necessary. Prefer using distinct key pairs instead as this will always be safer.

Remember that public keys for both operations are very small (only 32 bytes). Concatenating both produces an aggregate public key that is only 64 bytes long. For most applications, the overhead is negligible, and conversions are no longer required.

On the sender side, `crypto_sign_seed_keypair()` and `crypto_kx_seed_keypair()` can derive specialized key pairs from the same 32-byte seed.

If you really need to use the same key pair for both operations, Diffie-Hellman key exchange can be made over Edwards25519, the same group as the one used for signatures. Libsodium provides the `crypto_scalarmult_ed25519()` and `crypto_scalarmult_ed25519_base()` functions for scalar multiplication over edwards25519.

The following code illustrates how to do it:

```c
unsigned char ed25519_pk[crypto_sign_PUBLICKEYBYTES];
unsigned char ed25519_sk[crypto_sign_SECRETKEYBYTES];
unsigned char ed25519_seed[crypto_sign_SEEDBYTES];
unsigned char edwards25519_pk[crypto_scalarmult_ed25519_BYTES];
unsigned char edwards25519_sk[crypto_scalarmult_ed25519_SCALARBYTES];
unsigned char h[crypto_hash_sha512_BYTES];

// create an Ed25519 keypair
crypto_sign_keypair(ed25519_pk, ed25519_sk);

// Extract the seed from the Ed25519 secret key
crypto_sign_ed25519_sk_to_seed(ed25519_seed, ed25519_sk);

// Ed25519 internally derives two values from the seed; this is how it does it.
crypto_hash_sha512(h, ed25519_seed, sizeof ed25519_seed);

// The first half of the output corresponds to the scalar.
memcpy(edwards25519_sk, h, sizeof edwards25519_sk);

// The Ed25519 public key is the Edwards25519 base point multiplied
// by the scalar. We can copy ed25519_pk, or recompute it as follows:
crypto_scalarmult_ed25519_base(edwards25519_pk, edwards25519_sk);

// (edwards25519_pk, edwards25519_sk) can be used for Diffie-Hellman
// using crypto_scalarmult_ed25519() if you like to. Do not forget to
// hash the result in order to get a key suitable for encryption.
```

Finally, if, for some reason, you want to implement your own signcryption scheme:

* If public verifiability is not required, sign `(encryption_key || message)` first then encrypt `(recipient_id || signature || message)`.
* If public verifiability is required, encrypt `(sender_id || message)` then sign the ciphertext.
* If public verifiability is required, and the same message can be decrypted by multiple recipients, encrypt `(H(sender_id || message) || message)`, then sign the ciphertext.

`sender_id` and `recipient_id` are public data that uniquely identifies a party.

Verify the metadata when opening a signed plus encrypted message.

If this section looks complicated, ignore it, and use distinct keys for encryption and signing. This is easier and more secure. Furthermore, signing and encryption keys don’t necessarily have the same lifetime. It is common to frequently rotate encryption keys, while signing keys are long-term.

Also keep in mind that with post-quantum schemes, key pairs for signature and encryption systems are completely different and incompatible. So, if only for future-proofing your applications and protocols, do not assume that a single key pair can be used for both operations.

## How do I hide the length of a message?

Use [padding](https://libsodium.gitbook.io/doc/padding).

## Should I call `crypto_generichash_blake2b` or just `crypto_generichash`?

Always use the high-level API if one is available. The low-level API it is based on is guaranteed not to change before a major revision of the library. If a high-level API needs to use a different construction, it will expose a different set of functions.

This is true for all APIs provided by this library.

## Why is `crypto_stream()` barely documented and not even present in some bindings?

The `crypto_stream()` API generates a deterministic sequence of bytes from a seed and optionally applies the XOR operation between that sequence and some input sequence.

Performing the XOR operation once produces content that resembles random data, and performing the same operation twice restores the initial input sequence.

This can be seen as a form of encryption. However,

* If an adversary replaces the ciphertext with null bytes, the original, complete sequence derived from the seed will be decrypted. This can have catastrophic implications with some (badly designed) protocols.
* More generally, anyone can modify the ciphertext without this being detected. Since a stream cipher is XOR’d with a message, targeted bits can be flipped. Knowing the secret key is not required.

If a deterministic sequence must be derived from a seed (e.g. for unit testing), libsodium provides the `randombytes_buf_deterministic()` function.

For actual encryption, other options such as `crypto_secretbox`, `crypto_aead`, and `crypto_secretstream` should be used over `crypto_stream` as they will add and verify an authentication tag to detect data that has been corrupted or tampered with.

`crypto_stream()` is only useful as a building block to design custom constructions. As-is, it is completely insecure.

## Is encryption without nonces possible?

The encryption schemes implemented in libsodium are fast but require a unique `(key, nonce)` tuple for every message.

Nonces don’t have to be secret, but they must not be reused. Reusing a nonce would destroy the confidentiality of messages sharing the same nonce and allow an attacker to craft additional valid ciphertexts.

On a platform where counters cannot be maintained and no trusted source of randomness exists, deterministic encryption can be used as a last resort.

[XChaCha20-SIV](https://github.com/jedisct1/libsodium-xchacha20-siv) is such a construction, which can also be used for key wrapping.

On such systems, [libhydrogen](https://libhydrogen.org) may also be a better option.

## I want to write bindings for my favorite language, where should I start?

Start with the `crypto_generichash` and `crypto_secretstream` APIs. These are the trickiest to implement bindings for and will provide good insights about how to design your bindings.


# Projects using libsodium

## Applications using libsodium

Here are some applications using libsodium. Send a [pull request](https://libsodium.gitbook.io/doc/libsodium_users) to add yours to the list.

* [Abot](https://abot.app): Anonymous messaging for Slack.
* [Aspia Remote Desktop](https://github.com/aspia-org/remote-desktop): A remote desktop implementation (client and server) for Windows systems.
* [Apache Tuweni](https://tuweni.apache.org/): A set of libraries and other tools to aid development of blockchain and other decentralized software in Java and other JVM languages.
* [Astroport.ONE](https://github.com/papiche/Astroport.ONE): A spherical planetary blockchain built on IPFS run by cooperative hosts swarms based on trust level. Exclusively using libsodium through keygen and duniterpy as seed as generator for PGG, SSH, IPFS, Bitcoin, Duniter Ğ1, and more…
* [Babble Browser Extension](https://github.com/XCF-Babble/babble): A platform agnostic browser extension that allows for easy encryption and decryption of text data across the web.
* [Cloaker](https://github.com/spieglt/Cloaker): Very simple cross-platform file encryption.
* [Cyph](https://cyph.im/): End-to-end encrypted, authenticated, and ephemeral chat with voice, video, and file transfers.
* [DAT](https://datproject.org): Nonprofit-backed data sharing protocol for applications of the future.
* [Detsign](https://github.com/simonfxr/detsign): Use passphrases to generate deterministic Ed25519 signing keys.
* [Discord](https://discord.com): All-in-one voice and text chat for gamers that’s free, secure, and works on both your desktop and phone.
* [Dircifrar](https://github.com/ctchou/dircifrar): A directory synchronization and encryption tool.
* [Dovecot](https://dovecot.org): Dovecot is an open source IMAP and POP3 email server for Linux/Unix-like systems, written with security primarily in mind.
* [Duniter](https://duniter.org): Duniter is an open source Relative Money Theory distributed forged blockchain, and the clients (silkaj, duniterpy, cesium, …) use libsodium.
* [emberclear](https://emberclear.io): An open source, privacy-first, encrypted chat app using progressive web app technologies. Built with [Ember](http://emberjs.com) using all of the latest experimental features.
* [ente](https://ente.io): A simple, end-to-end encrypted backup solution for photos and videos.
* [EQEmu](http://www.eqemulator.org): An open source project committed to providing custom EverQuest servers.
* [Evernym Plenum](http://evernym.com/): A byzantine fault tolerant protocol.
* [Fastd](https://fastd.readthedocs.io/): A fast and secure tunnelling daemon.
* [FeCl](https://github.com/jhwgh1968/FeCl): A secure message-passing server based on libsodium.
* [Flocksy](https://github.com/alex-dot/syncbox): An anonymous file synchronisation tool.
* [Glorytun](https://github.com/angt/glorytun): A small, simple and very fast VPN.
* [Habitat](https://www.habitat.sh/): Habitat, by Chef, is automation that travels with the app.
* [Hat-Backup](https://github.com/google/hat-backup): A backend-agnostic snapshotting backup system.
* [Husarnet](https://husarnet.com): Open source P2P VPN to connect your laptops, servers and microcontrollers over the Internet with zero configuration.
* [KadNode](https://github.com/mwarning/KadNode): A small P2P DNS resolution daemon based on a Distributed Hash Table.
* [Keystone Enclave](https://github.com/keystone-enclave): An open source secure enclave for RISC-V processors.
* [KeepassXC](https://keepassxc.org/): KeePass Cross-Platform Community Edition. KeePassXC stores your passwords safely and auto-types them into your everyday websites and applications.
* [Kickpass](https://github.com/paulfariello/kickpass): A stupid simple password manager.
* [Krypton akr](https://github.com/akamai/akr): FIDO2 SSH agent for iOS and Android (successor to Kryptonite, now part of Akamai MFA).
* [Kryptor](https://kryptor.co.uk/): Free and open source file encryption software.
* [Lageant](https://github.com/bitbeans/lageant): Libsodium Authentication Agent.
* [Lawncipher](https://github.com/LockateMe/Lawncipher): An embedded, encrypted, multi-purpose document store.
* [libagentcrypt](https://github.com/ndilieto/libagentcrypt): Library for symmetric encryption using SSH Agent. It includes a command line utility able to encrypt/decrypt files and/or passwords securely with your SSH keys.
* [Lumimaja](https://github.com/Safari77/lumimaja): PasswordSafe with Argon2 KDF, data encrypted with ChaCha20-Poly1305, and YubiKey support.
* [MLVPN](http://zehome.github.io/MLVPN/): A multi-link VPN (ADSL/SDSL/xDSL/Network aggregator)
* [Magic Wormhole](https://github.com/warner/magic-wormhole): Get things from one computer to another, safely.
* [MaidSafe](http://maidsafe.net/): A new secure way to access a world of existing apps where the security of your data is put above all else.
* [Metastream](https://github.com/samuelmaddock/metastream): Watch streaming media with friends.
* [Minisign](https://jedisct1.github.io/minisign/): A dead simple tool to sign files and verify signatures.
* [Molch](https://github.com/FSMaxB/molch): An implementation of the Axolotl ratchet.
* [Muon](https://github.com/puxxustc/muon): A fast stateless VPN with obfuscation to escape traffic monitoring.
* [Nahoft](https://nahoftapp.com): An offline encryption tool for mobile phones designed to let people communicate during Internet shutdowns in Iran.
* [NTPsec](https://github.com/ntpsec/ntpsec): A security-hardened implementation of Network Time Protocol Version 4.
* [NanoChat](https://github.com/hamidreza-s/NanoChat): A P2P, E2E encrypted and discoverable chat application on top of nanomsg library.
* [Network Next](https://networknext.com): A real-time CDN for game traffic. *You* control the network!
* [OpenGKS](https://arpa.ph/opengks/): An RFID gate keeper solution that automatically tracks, records data and sends text messages (SMS) and email notifications to parents upon a student’s entrance and exit in school.
* [OpenR](https://github.com/facebook/openr): Facebook’s internally designed and developed routing protocol/platform.
* [PAVE](https://pave.software/): The password manager. Easy password sharing for teams. No cloud.
* [PCP](https://codeberg.org/scip/pcp/): Pretty Curved Privacy (pcp1) is a command line utility that can be used to encrypt files.
* [Phase](https://github.com/phasehq/console): An all-in-one platform for developers to securely create, manage and deploy application secrets across local development 💻, CI tools 🔨, and cloud ☁️ infrastructure.
* [Petmail](https://github.com/warner/petmail): A secure communication and file-sharing system.
* [Pichi](https://github.com/pichi-router/pichi): An Application Layer Proxy controlled via RESTful APIs.
* [PowerDNS](https://www.powerdns.com/): PowerDNS has been designed to serve both the needs of small installations by being easy to set up as well as for serving very large query volumes on large numbers of domains. Additionally, PowerDNS offers very high domain resolution performance.
* [QtCrypt](https://github.com/trashctor/QtCrypt): Lightweight, portable application that encrypts files and directories using a symmetric-key algorithm.
* [Quick Crypt](https://quickcrypt.org): A small-batch text-focused online cipher tool designed to be easy to use, trustworthy, and convenient.
* [RavenDB](https://ravendb.net/): A LINQ-enabled document database for .NET.
* [Rebel Backup](https://www.svsware.com/rebelbackup): Encrypted backups of important files to Dropbox and Google Drive.
* [Reop](http://www.tedunangst.com/flak/post/reop): Reasonable expectation of privacy.
* [rtty-soda](https://github.com/theosaveliev/rtty-soda): A PyNaCl frontend with custom encodings, compression, and key derivation.
* [Rubinius](http://rubinius.com/): Rubinius is a platform for building programming language technology.
* [SODA](https://github.com/vong-xiv/SODA): The SODA project aims to investigate the relationship between server components and server performance.
* [SaltStack](http://saltstack.com/): SaltStack software orchestrates the build and ongoing management of any modern infrastructure.
* [Sandstorm](https://sandstorm.io/): An open source operating system for personal and private clouds.
* [Secrets](https://outercorner.com/secrets): Easily and securely store passwords, credit card numbers, bank details, and confidential information. Available for Mac and iOS.
* [ShadowSocks](https://shadowsocks.org/): A secure SOCKS5 proxy designed to protect your Internet traffic.
* [Sharekey](https://sharekey.com/): Encrypted data storage.
* [Simple DnsCrypt](https://github.com/bitbeans/SimpleDnsCrypt): A simple management tool for dnscrypt-proxy.
* [SPAKE2+EE](https://github.com/jedisct1/spake2-ee): A SPAKE2+ Elligator Edition implementation for libsodium.
* [Splonebox](https://splone.com/splonebox/): An open source network assessment tool with a focus on modularity.
* [Stellar](https://www.stellar.org/): An open platform for building financial products that connect people everywhere.
* [TREES](https://0xacab.org/riseuplabs/trees): A Dovecot email storage encryption plugin.
* [Tbak](https://github.com/tux3/tbak): Encrypted, compressed, distributed backups.
* [Telehash](https://github.com/telehash): An embeddable private network stack for mobile, web, and devices.
* [Tezos](https://www.tezos.com): A new decentralized blockchain that governs itself by establishing a true digital commonwealth.
* [Tinfoil Chat](https://github.com/maqp/tfc): An onion-routed, endpoint secure messaging system.
* [Toluca Store Desktop](https://go.toluca.app): Multiplatform ERP system with unlimited sales and no fees. E-commerce, APP, Sales Robot, POS, Comanda, Sales Receipts and Artificial Intelligence. The power of UNIX® for robust business management.
* [Tox](https://tox.chat/): A new kind of instant messaging.
* [Vim](http://github.com/vim/vim): Vim is a greatly improved version of the good old UNIX editor Vi. Libsodium is used for reading and writing encrypted files.
* [VOLTTRON](https://volttron.org/): VOLTTRON is an innovative distributed control and sensing software platform. Its source code has been released, making it possible for researchers and others to use this tool to build applications for more efficiently managing energy use among appliances and devices, including heating, ventilation and air conditioning (HVAC) systems, lighting, electric vehicles and others.
* [Wifibroadcast](https://github.com/svpcom/wifibroadcast): Transmitter and receiver of UDP packets using raw Wi-Fi radio.
* [Wire](https://wire.com/): Modern, private communications. Crystal clear voice, video and group chats. No advertising. Your data, always encrypted.
* [Wireguard-rs](https://git.zx2c4.com/wireguard-rs): Rust implementation of WireGuard.
* [Zbox](https://github.com/zboxfs/zbox): Zero-details, privacy-focused embeddable file system.
* [Zcash](https://z.cash/): Zcash is a decentralized and open source cryptocurrency that aims to set a new standard for privacy through the use of groundbreaking cryptography.
* [OpenZiti](https://openziti.io/): Ziti is an open-source SDK and platform for agentless, embedded zero trust networking (mTLS+E2EE everywhere).
* [libsodium for Universal Windows Platform](https://github.com/charlesportwoodii/libsodium-uwp): a C++ Windows Runtime Component for UWP applications.
* [libsodium password hashing schemes for Dovecot](https://github.com/LuckyFellow/dovecot-libsodium-plugin): Dovecot plugin to support scrypt and Argon2 for password hashing.
* [Wordpress](https://wordpress.com): Uses libsodium for verified updates.
* [C-lightning](https://github.com/ElementsProject/lightning/): A [Lightning Network](https://github.com/lightningnetwork/lightning-rfc) implementation in C that uses libsodium.
* [SilentDragon](https://github.com/MyHush/SilentDragon) + [SilentDragonLite](https://github.com/MyHush/SilentDragonLite): GUI full node and lite wallets for the [Hush](https://hush.is/) cryptocoin, which is focused on secure communications.

## Libraries using libsodium

Here are some libraries and frameworks using libsodium. Send a [pull request](https://libsodium.gitbook.io/doc/libsodium_users) to add yours to that list.

* [Asio Sodium Socket](https://github.com/mikezackles/asio_sodium_socket): A header-only C++14 library implementing custom transport encryption using libsodium and Asio’s stackless coroutines.
* [Blobcrypt](https://github.com/jedisct1/blobcrypt): Authenticated encryption for streams and arbitrary large files.
* [Cordova Minisodium](https://npmdaily.com/pkg/cordova-plugin-minisodium): A minimal sodium plugin for Cordova - for iOS and Android.
* [@deliberative/crypto](https://github.com/deliberative/crypto): Typescript/WebAssembly library for public key cryptography, secret boxes, Shamir secret sharing and random shuffling. Runs on Nodejs, ESM, CommonJS and the browser.
* [drasyl](https://drasyl.org/): drasyl is a high-performance framework for rapid development of distributed applications.
* [EdCert](https://docs.rs/edcert/): A Rust crate to sign and verify content using Ed25519.
* [esp\_husarnet](https://github.com/husarnet/esp_husarnet): ESP-IDF port of the Husarnet VPN client library.
* [Etebase](https://www.etebase.com/): An open source SDK and backend to build end-to-end encrypted applications.
* [Folly](https://github.com/facebook/folly): An open-source C++ library developed and used at Facebook.
* [Halite](https://github.com/paragonie/halite): High-level cryptography interface for PHP.
* [Hyperledger Indy](https://github.com/hyperledger/indy-sdk): Everything needed to build applications that interact with an Indy distributed identity ledger.
* [Innovault](https://innovault.io): A toolkit to store sensitive data from web forms in an encrypted database.
* [libopaque](https://github.com/stef/libopaque): An implementation of the OPAQUE protocol.
* [liboprf](https://github.com/stef/liboprf): A library providing OPRF and Threshold OPRF based on libsodium.
* [libSQRL](https://github.com/Novators/libsqrl): SQRL authentication library.
* [MEGA SDK](https://github.com/meganz/sdk): SDK by mega.nz, a secure cloud storage provider that protects your data, thanks to end-to-end encryption.
* [Macaroons](https://github.com/rescrv/libmacaroons): Macaroons are flexible authorization credentials that support decentralized delegation, attenuation, and verification.
* [MatrixSSL](https://github.com/matrixssl/matrixssl): Lightweight embedded SSL/TLS implementation that can use libsodium as a crypto provider.
* [MySQL-Sodium](https://github.com/mashthekeys/mysql-sodium): MySQL UDF bindings for libsodium.
* [NaclKeys](https://github.com/bitbeans/NaclKeys): Library to generate libsodium-net compatible KeyPairs.
* [Netcode.io](http://netcode.io): A simple protocol for creating secure client/server connections over UDP.
* [Noise-C](http://rweather.github.io/noise-c/): Noise-C is a plain C implementation of the Noise Protocol, intended as a reference implementation.
* [OAuthSDK](https://github.com/ramki1979/OAuthSDK): OAuth 1 and OAuth 2 framework in Swift for iOS.
* [Posh-Sodium](https://github.com/jamessantiago/PoSH-Sodium): A PowerShell module.
* [Pull-box-stream](https://github.com/dominictarr/pull-box-stream): One-way streaming encryption for JavaScript.
* [react-native-get-random-values](https://github.com/kore-koi/react-native-get-random-values): A fast implementation of crypto.getRandomValues for React Native.
* [@s77rt/react-native-sodium](https://github.com/s77rt/react-native-sodium): A fast cryptography module for React Native using libsodium.
* [Sodium native](https://github.com/sodium-friends/sodium-native): Low-level NodeJS bindings for libsodium.
* [Stream Cryptor](https://github.com/bitbeans/StreamCryptor): Stream encryption and decryption with libsodium and protobuf for .NET.
* [Tanker SDK](https://github.com/TankerHQ/sdk-js): An encryption SDK for JavaScript.
* [The Update Framework](https://github.com/theupdateframework/tuf): A plug-and-play library for securing a software updater.
* [Yojimbo](https://github.com/networkprotocol/yojimbo): A network library for client/server games with dedicated servers.
* [ZeroMQ](http://zeromq.org/): Connect your code in any language, on any platform.
* [OpenZiti SDK](https://github.com/openziti/ziti-sdk-c): The C-SDK for [the OpenZiti project](https://ziti.dev).
* [libotrv4](https://github.com/otrv4/libotrv4): An OTR version 4 implementation.
* [libsaxolotl](https://github.com/stef/libsaxolotl): An Axolotol implementation in C using libsodium.
* [libsodium-Laravel](https://github.com/scrothers/libsodium-laravel): Laravel integration.
* [libsodium-UE4](https://github.com/maxenko/libsodium-ue4): An easy to use cryptography plugin for Unreal Engine 4 based on libsodium.
* [UnrealSodium](https://github.com/Helium-Labs/UnrealSodium): A user-friendly & portable Unreal Engine 5 cryptography plugin based on libsodium.
* [minisign-net](https://github.com/bitbeans/minisign-net): .NET library to handle and create Minisign signatures.
* [neuropil](https://www.neuropil.org/): An IoT secure messaging library with end-to-end encryption written in C and using libsodium.
* [pgsodium](https://github.com/michelp/pgsodium): Postgres extension wrapper around libsodium.
* [spake2+ee](https://github.com/jedisct1/spake2-ee): A SPAKE2+ implementation.
* [iota.c](https://github.com/iotaledger/iota.c): An IOTA Client library in C.

## Companies using libsodium

Here are some companies using libsodium, possibly in closed source products. Send a [pull request](https://libsodium.gitbook.io/doc/libsodium_users) to add yours to that list.

* [Arpa Information Technology Solutions](https://arpa.ph/)
* [Assa Abloy](https://www.assaabloy.com)
* [Auth0](https://auth0.com)
* [Digital Ocean](https://www.digitalocean.com/)
* [Espressif Systems](http://espressif.com/)
* [Facebook](https://facebook.com)
* [Gamuza Technologies](https://www.gamuza.com.br/)
* [GitHub](https://github.com)
* [Infoblox](https://www.infoblox.com)
* [Informatica](https://www.informatica.com/)
* [Innovis Solutions KG](https://www.innovis-solutions.de/)
* [Keybase](https://keybase.io/)
* [Krypt.co](https://krypt.co)
* [Magento (Adobe)](https://business.adobe.com/products/magento/magento-commerce.html)
* [Malwarebytes](https://www.malwarebytes.com/)
* [MongoDB](https://www.mongodb.com)
* [Mullvad VPN](https://mullvad.net)
* [NetFoundry](https://netfoundry.io) (maintainers of [the OpenZiti project](https://ziti.dev))
* [OVHcloud](https://www.ovhcloud.com)
* [Paragon Initiative Enterprises](https://paragonie.com)
* [Pi-lar](http://www.pi-lar.net)
* [Private Internet Access](https://www.privateinternetaccess.com)
* [Q-Leap Networks](http://www.q-leap.com/)
* [Riseup](https://riseup.net)
* [Splunk](https://splunk.com)
* [Supercell](http://supercell.com)
* [Valve](https://www.valvesoftware.com)
* [Wire](https://wire.com)
* [Wordpress](https://wordpress.com)
* [Yandex](https://www.yandex.com)


# Commercial support

The following companies offer professional support services for libsodium and applications using libsodium:

## Frank Denis

Libsodium’s primary maintainer services include:

* Expert assistance with configuring, installing, integrating, and optimizing libsodium and libhydrogen for your systems and applications.
* Porting to new platforms.
* Custom packages tailored to your specific needs.
* Long-term support, including backporting of security fixes to ensure continued protection.
* Development of bindings for currently unsupported languages.
* Security review of constructions, protocols, and applications involving cryptography.
* Implementation of new cryptographic primitives in various programming languages.
* Consulting and mentoring services.

Email `consulting` `[at]` `libsodium`.`org` for inquiries.

## Edge Security (<https://www.edgesecurity.com>)

Libsodium-specific services include:

* Cryptographic and implementation auditing of libsodium usage.
* Security review of constructions, protocols, and applications using libsodium.
* Consulting on libsodium usage in applications – web apps, backends, mobile, embedded, kernel, etc.
* General consulting and review of cryptography inquiries.
* Implementation security and helping to work toward a vulnerability-free codebase.
* Reverse engineering of complicated binaries.
* General consulting, advising, mentoring, and development.

## Paragon Initiative Enterprises (<https://paragonie.com>)

Libsodium-specific services include:

* Library integration, with a focus on web applications (PHP, .NET, Python).
* Bespoke or standard high-level protocol design and implementation (e.g. Noise).
* Security audits for in-house library integrations and/or high-level protocols.
* Custom application development that requires cryptography.
* Consulting and mentoring services.

***

(Please submit a pull request if you want your company added to that list)


# Bindings for other languages

## Programming languages whose standard library includes support for libsodium

* PHP >= 7.2
* HHVM >= 3.20
* [Citrine](https://citrine-lang.org/)
* [Factor](https://factorcode.org/) >= 0.98

## Bindings for programming languages

* .NET: [BetterCallSodium](https://github.com/BetterCallSodium/BetterCallSodium)
* .NET: [NSec](https://github.com/ektrah/nsec)
* .NET: [Geralt](https://github.com/samuel-lucas6/Geralt)
* .NET: [libsodium-core](https://github.com/tabrath/libsodium-core) (maintenance mode)
* .NET: [ASodium](https://github.com/Chewhern/ASodium)
* .NET: [SpaceWizards.Sodium](https://github.com/space-wizards/SpaceWizards.Sodium)
* .NET (Blazor): [BlazorSodium](https://github.com/Jack-Edwards/BlazorSodium)
* Ada: [libsodium-ada](https://github.com/jrmarino/libsodium-ada)
* Ada: [sodiumada](https://gitlab.com/ada23/sodiumada)
* Clojure: [caesium](https://github.com/lvh/caesium)
* Crystal: [Sodium](https://github.com/didactic-drunk/sodium.cr)
* D: [LibsodiumD](https://github.com/Geod24/libsodiumd) (based on libsodium 1.0.18)
* Dart: [libsodium\_dart\_bindings](https://github.com/Skycoder42/libsodium_dart_bindings)
* Delphi: [Delphi-NaCl](https://github.com/zedalaye/Delphi-NaCl)
* Erlang: [ENaCl](https://github.com/jlouis/enacl)
* Erlang: [Erlang-libsodium](https://github.com/potatosalad/erlang-libsodium) (work in progress)
* Fortran: [Sodium](https://github.com/freevryheid/sodium)
* Go: [Sodium](https://github.com/jamesruan/sodium)
* Haskell: [Saltine](https://github.com/tel/saltine)
* Haskell: [hs-sodium](https://github.com/k0001/hs-libsodium)
* Haskell: [haskell-crypto](https://github.com/serokell/haskell-crypto) (experimental)
* Haskell: [cryptography-libsodium](https://github.com/haskell-cryptography/cryptography-libsodium-bindings)
* Java (Java Native Access): [libsodium-jna](https://github.com/muquit/libsodium-jna)
* Java (Android): [Lazysodium for Android](https://github.com/terl/lazysodium-android)
* Java: [Lazysodium for Java](https://github.com/terl/lazysodium-java)
* JavaScript (compiled to pure JavaScript): [libsodium.js](https://github.com/jedisct1/libsodium.js)
* JavaScript (libsodium.js wrapper for browsers): [Natrium Browser](https://github.com/wilhelmmatilainen/natrium-browser)
* JavaScript (NodeJS): [sodium-native](https://github.com/mafintosh/sodium-native)
* Kotlin Multiplatform: [kotlin-multiplatform-libsodium](https://github.com/ionspin/kotlin-multiplatform-libsodium)
* Lean 4: [Sodium](https://github.com/rj-calvin/sodium)
* Lua: [luasodium](https://github.com/jprjr/luasodium)
* Nim: [nim-libsodium](https://github.com/BundleFeed/nim-libsodium) (experimental)
* Perl: [Crypt::Sodium::XS](https://metacpan.org/dist/Crypt-Sodium-XS)
* PHP: [libsodium-php](https://github.com/jedisct1/libsodium-php)
* PHP: [dhole-cryptography](https://github.com/soatok/dhole-cryptography)
* Pharo 7/8: [Crypto-Nacl](https://github.com/objectguild/Crypto-Nacl)
* Pony: [Pony-Sodium](https://github.com/jemc/pony-sodium)
* Python: [LibNaCl](https://github.com/saltstack/libnacl)
* Python: [PyNaCl](https://github.com/pyca/pynacl)
* Python: [PySodium](https://github.com/stef/pysodium)
* R: [Cyphr](https://github.com/richfitz/cyphr)
* R: [Sodium](https://github.com/jeroenooms/sodium)
* REALbasic and Xojo: [RB-libsodium](https://github.com/charonn0/RB-libsodium)
* Ruby: [RbNaCl](https://github.com/cryptosphere/rbnacl)
* Rust: [libsodium-sys-stable](https://github.com/jedisct1/libsodium-sys-stable)
* Rust: [tablesalt](https://github.com/JacoMalan1/tablesalt)
* Rust: [sodoken](https://github.com/holochain/sodoken)
* Rust: [alkali](https://github.com/tom25519/alkali)
* Swift: [Swift-Sodium](https://github.com/jedisct1/swift-sodium)
* V: [vlang/libsodium](https://github.com/vlang/libsodium)


# Usage

```c
#include <sodium.h>

int main(void)
{
    if (sodium_init() == -1) {
        return 1;
    }
    ...
}
```

`sodium.h` is the only header that has to be included.

The library is called `sodium` (use `-lsodium` to link it), and proper compilation/linker flags can be obtained using `pkg-config` on systems where it is available:

```sh
CFLAGS += $(pkg-config --cflags libsodium)
LDFLAGS += $$(pkg-config --libs-only-L libsodium)
LDLIBS += $$(pkg-config --libs-only-l libsodium)
```

For static linking, Visual Studio users should define `SODIUM_STATIC=1` and `SODIUM_EXPORT=`. This is not required on other platforms.

Projects using CMake can include the [Findsodium.cmake](https://github.com/facebookincubator/fizz/blob/master/build/fbcode_builder/CMake/FindSodium.cmake) file from the Facebook Fizz project to detect and link the library.

`sodium_init()` initializes the library and should be called before any other function provided by Sodium. It is safe to call this function more than once and from different threads – subsequent calls won’t have any effects.

After this function returns, all of the other functions provided by Sodium will be thread-safe.

`sodium_init()` doesn’t perform any memory allocations. However, on Unix systems, it may open `/dev/urandom` and keep the descriptor open so that the device remains accessible after a `chroot()` call.

Multiple calls to `sodium_init()` do not cause additional descriptors to be opened.

`sodium_init()` returns `0` on success, `-1` on failure, and `1` if the library had already been initialized.

Before returning, the function ensures that the system’s random number generator has been properly seeded.

## sodium\_init() stalling on Linux

On some Linux systems, this may take some time, especially when called right after a reboot of the system. This issue has been reported on Digital Ocean virtual machines, Scaleway ARM instances, and AWS Nitro Enclaves.

This can be confirmed with the following command:

```sh
cat /proc/sys/kernel/random/entropy_avail
```

If the command returns `0` or a very low number (< `160`), and you are not running an obsolete kernel, this is very likely to be the case.

In a virtualized environment, make sure that the `virtio-rng` interface is available. If this is a cloud service and the hypervisor settings are out of your reach, consider switching to a different service.

Current Linux kernels (>= 5.4) include the `haveged` algorithm in order to mitigate that problem. So, before trying the last-resort solutions below, try using a recent kernel.

If you have to use a kernel before version 5.4, a possible workaround is to install `haveged`:

```sh
apt-get install haveged
```

An alternative is `rng-tools`:

```sh
apt-get install rng-tools
```

In some environments, setting the `-O jitter:timeout` option to `20` [might be necessary](https://github.com/nhorman/rng-tools/issues/195#issuecomment-1519222464).

[Jitterentropy](https://github.com/smuellerDD/jitterentropy-rngd) is a better alternative, but most Linux distributions don’t offer it as an installable package yet.

After installing these tools, check the value of `/proc/sys/kernel/random/entropy_avail` again.

On AWS Nitro Enclaves, workarounds include:

* Calling the `aws_nitro_enclaves_library_seed_entropy()` function before `sodium_init()`, and occasionally afterwards.
* Using the `RDSEED` CPU instruction to seed the kernel RNG (not recommended as a unique entropy source).
* Setting `random.trust_cpu=on` in the kernel command line (requires Linux kernel > 4.19).

Applications can warn users about the Linux RNG not being seeded before calling `sodium_init()` using code similar to the following:

```c
#if defined(__linux__)
# include <fcntl.h>
# include <unistd.h>
# include <sys/ioctl.h>
# include <linux/random.h>
#endif
// ...
#if defined(__linux__) && defined(RNDGETENTCNT)
int fd;
int c;

if ((fd = open("/dev/random", O_RDONLY)) != -1) {
    if (ioctl(fd, RNDGETENTCNT, &c) == 0 && c < 160) {
        fputs("This system doesn't provide enough entropy to quickly generate high-quality random numbers.\n"
              "Upgrading the kernel, installing the rng-utils/rng-tools, jitterentropy-rngd or haveged packages may help.\n"
              "On virtualized Linux environments, also consider using virtio-rng.\n"
              "The service will not start until enough entropy has been collected.\n", stderr);
    }
    (void) close(fd);
}
#endif
```

Congrats, you’re all set up!

A good documentation page to read next might be [Quickstart and FAQ](https://libsodium.gitbook.io/doc/quickstart).


# Helpers

## Constant-time test for equality

```c
int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len);
```

When a comparison involves secret data (e.g. a key, an authentication tag, etc.), it is critical to use a constant-time comparison function. This property does not relate to computational complexity: it means the time needed to perform the comparison is the same for all data of the same size. The goal is to mitigate side-channel attacks.

The `sodium_memcmp()` function can be used for this purpose.

The function returns `0` if the `len` bytes pointed to by `b1_` match the `len` bytes pointed to by `b2_`. Otherwise, it returns `-1`.

**Note:** `sodium_memcmp()` is not a lexicographic comparator and is not a generic replacement for `memcmp()`.

## Hexadecimal encoding/decoding

```c
char *sodium_bin2hex(char * const hex, const size_t hex_maxlen,
                     const unsigned char * const bin, const size_t bin_len);
```

The `sodium_bin2hex()` function converts `bin_len` bytes stored at `bin` into a hexadecimal string.

The string is stored into `hex` and includes a null byte (`\0`) terminator.

`hex_maxlen` is the maximum number of bytes that the function is allowed to write starting at `hex`. It must be at least `bin_len * 2 + 1` bytes.

The function always returns `hex`. It evaluates in constant time for a given size.

```c
int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen,
                   const char * const hex, const size_t hex_len,
                   const char * const ignore, size_t * const bin_len,
                   const char ** const hex_end);
```

The `sodium_hex2bin()` function parses a hexadecimal string `hex` and converts it to a byte sequence.

`hex` does not have to be null terminated, as the number of characters to parse is supplied via the `hex_len` parameter.

`ignore` is a string of characters to skip. For example, the string `": "` allows colons and spaces to be present at any location in the hexadecimal string. These characters will just be ignored. As a result, `"69:FC"`, `"69 FC"`, `"69 : FC"` and `"69FC"` will be valid inputs and produce the same output.

`ignore` can be set to `NULL` to disallow any non-hexadecimal character.

`bin_maxlen` is the maximum number of bytes to put into `bin`.

The parser stops when a non-hexadecimal, non-ignored character is found or when `bin_maxlen` bytes have been written.

If `hex_end` is not `NULL`, it will be set to the address of the first byte after the last valid parsed character.

The function returns `0` on success.

It returns `-1` if more than `bin_maxlen` bytes would be required to store the parsed string or the string couldn’t be fully parsed, but a valid pointer for `hex_end` was not provided.

It evaluates in constant time for a given length and format.

## Base64 encoding/decoding

```c
char *sodium_bin2base64(char * const b64, const size_t b64_maxlen,
                        const unsigned char * const bin, const size_t bin_len,
                        const int variant);
```

The `sodium_bin2base64()` function encodes `bin` as a Base64 string. `variant` must be one of:

* `sodium_base64_VARIANT_ORIGINAL`
* `sodium_base64_VARIANT_ORIGINAL_NO_PADDING`
* `sodium_base64_VARIANT_URLSAFE`
* `sodium_base64_VARIANT_URLSAFE_NO_PADDING`

None of these Base64 variants provides any form of encryption; just like hex encoding, anyone can decode them.

Computing a correct size for `b64_maxlen` is not straightforward and depends on the chosen variant.

The `sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT)` macro returns the minimum number of bytes required to encode `BIN_LEN` bytes using the Base64 variant `VARIANT`. The returned length includes a trailing `\0` byte.

The `sodium_base64_encoded_len(size_t bin_len, int variant)` function is also available for the same purpose.

```c
int sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen,
                      const char * const b64, const size_t b64_len,
                      const char * const ignore, size_t * const bin_len,
                      const char ** const b64_end, const int variant);
```

The `sodium_base642bin()` function decodes a Base64 string using the given variant and an optional set of characters to ignore (typically: whitespaces and newlines).

If `b64_end` is not `NULL`, it will be set to the address of the first byte after the last valid parsed character.

Base64 encodes 3 bytes as 4 characters, so the result of decoding a `b64_len` string will always be at most `b64_len / 4 * 3` bytes long.

The function returns `0` on success.

It returns `-1` if more than `bin_maxlen` bytes would be required to store the parsed string or the string couldn’t be fully parsed, but a valid pointer for `b64_end` was not provided.

## Incrementing large numbers

```c
void sodium_increment(unsigned char *n, const size_t nlen);
```

The `sodium_increment()` function takes a pointer to an arbitrary-long unsigned number and increments it.

It runs in constant time for a given length and considers the number to be encoded in a little-endian format.

`sodium_increment()` can be used to increment nonces in constant time.

## Adding large numbers

```c
void sodium_add(unsigned char *a, const unsigned char *b, const size_t len);
```

The `sodium_add()` function accepts two pointers to unsigned numbers encoded in little-endian format, `a` and `b`, both of size `len` bytes.

It computes `(a + b) mod 2^(8*len)` in constant time for a given length and overwrites `a` with the result.

## Subtracting large numbers

```c
void sodium_sub(unsigned char *a, const unsigned char *b, const size_t len);
```

The `sodium_sub()` function accepts two pointers to unsigned numbers encoded in little-endian format, `a` and `b`, both of size `len` bytes.

It computes `(a - b) mod 2^(8*len)` in constant time for a given length and overwrites `a` with the result.

This function was introduced in libsodium 1.0.17.

## Comparing large numbers

```c
int sodium_compare(const void * const b1_, const void * const b2_, size_t len);
```

Given `b1_` and `b2_`, two `len` bytes numbers encoded in little-endian format, this function returns:

* `-1` if `b1_` is less than `b2_`
* `0` if `b1_` equals `b2_`
* `1` if `b1_` is greater than `b2_`

The comparison is done in constant time for a given length.

This function can be used with nonces to prevent replay attacks.

## Testing for all zeros

```c
int sodium_is_zero(const unsigned char *n, const size_t nlen);
```

This function returns `1` if the `nlen` bytes vector pointed by `n` contains only zeros. It returns `0` if non-zero bits are found.

Its execution time is constant for a given length.

## Clearing the stack

```c
void sodium_stackzero(const size_t len);
```

The `sodium_stackzero()` function clears `len` bytes above the current stack pointer, to overwrite sensitive values that may have been temporarily stored on the stack.

Note that these values can still be present in registers.

This function was introduced in libsodium 1.0.16.

## Notes

The `sodium_base64_VARIANT_*()` macros don’t have associated symbols. Bindings are encouraged to define specialized encoding/decoding functions instead.


# Padding

Most modern cryptographic constructions disclose message lengths. The ciphertext for a given message will always have the same length or a constant number of bytes added to it.

For most applications, this is not an issue. But in some specific situations, such as interactive remote shells, hiding the length may be desirable. Padding can be used for that purpose.

This API was introduced in libsodium 1.0.14.

## Example

```c
unsigned char buf[100];
size_t        buf_unpadded_len = 10;
size_t        buf_padded_len;
size_t        block_size = 16;

/* round the length of the buffer to a multiple of `block_size` by appending
 * padding data and put the new, total length into `buf_padded_len` */
if (sodium_pad(&buf_padded_len, buf, buf_unpadded_len, block_size, sizeof buf) != 0) {
    /* overflow! buf[] is not large enough */
}

/* compute the original, unpadded length */
if (sodium_unpad(&buf_unpadded_len, buf, buf_padded_len, block_size) != 0) {
    /* incorrect padding */
}
```

## Usage

```c
int sodium_pad(size_t *padded_buflen_p, unsigned char *buf,
               size_t unpadded_buflen, size_t blocksize, size_t max_buflen);
```

The `sodium_pad()` function adds padding data to a buffer `buf` whose original size is `unpadded_buflen` in order to extend its total length to a multiple of `blocksize`.

The new length is put into `padded_buflen_p`.

The function returns `-1` if the padded buffer length would exceed `max_buflen`, or if the block size is `0`. It returns `0` on success.

```c
int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf,
                 size_t padded_buflen, size_t blocksize);
```

The `sodium_unpad()` function computes the original, unpadded length of a message previously padded using `sodium_pad()`. The original length is put into `unpadded_buflen_p`.

## Algorithm

These functions use the ISO/IEC 7816-4 padding algorithm. It supports arbitrary block sizes, ensures that the padding data are checked for computing the unpadded length, and is more resistant to some classes of attacks than other standard padding algorithms.

## Notes

Padding should be applied before encryption and removed after decryption.

Usage of padding to hide the length of a password is not recommended. A client willing to send a password to a server should hash it instead, even with a single iteration of the hash function.

This ensures that the length of the transmitted data is constant and that the server doesn’t effortlessly get a copy of the password.

Applications may eventually leak the unpadded length via side channels, but the `sodium_pad()` and `sodium_unpad()` functions themselves try to minimize side channels for a given `length & <block size mask>` value.


# Secure memory

## Zeroing memory

```c
void sodium_memzero(void * const pnt, const size_t len);
```

After use, sensitive data should be overwritten, but `memset()` and hand-written code can be silently stripped out by an optimizing compiler or the linker.

The `sodium_memzero()` function tries to effectively zero `len` bytes starting at `pnt`, even if optimizations are being applied to the code.

## Locking memory

```c
int sodium_mlock(void * const addr, const size_t len);
```

The `sodium_mlock()` function locks at least `len` bytes of memory starting at `addr`. This can help avoid swapping sensitive data to disk.

In addition, it is recommended to disable swap partitions on machines processing sensitive data or, as a second choice, use encrypted swap partitions.

For similar reasons, on Unix systems, one should also disable core dumps when running crypto code outside a development environment. This can be achieved using a shell built-in such as `ulimit` or programmatically using `setrlimit(RLIMIT_CORE, &(struct rlimit) {0, 0})`. On operating systems where this feature is implemented, kernel crash dumps should also be disabled.

`sodium_mlock()` wraps `mlock()` and `VirtualLock()`. **Note:** Many systems place limits on the amount of memory that may be locked by a process. Care should be taken to raise those limits (e.g. Unix ulimits) where necessary. `sodium_mlock()` will return `-1` when any limit is reached.

```c
int sodium_munlock(void * const addr, const size_t len);
```

The `sodium_munlock()` function should be called after locked memory is not being used anymore. It will zero `len` bytes starting at `addr` before flagging the pages as swappable again. Calling `sodium_memzero()` prior to `sodium_munlock()` is thus not required.

On systems where it is supported, `sodium_mlock()` also wraps `madvise()` and advises the kernel not to include the locked memory in core dumps. `sodium_munlock()` also undoes this additional protection.

## Guarded heap allocations

Sodium provides heap allocation functions for storing sensitive data.

These are not general-purpose allocation functions. In particular, they are slower than `malloc()` and friends and require 3 or 4 extra pages of virtual memory.

`sodium_init()` must be called before using any of the guarded heap allocation functions.

```c
void *sodium_malloc(size_t size);
```

The `sodium_malloc()` function returns a pointer from which exactly `size` contiguous bytes of memory can be accessed. Like normal `malloc`, `NULL` may be returned and `errno` set if it is not possible to allocate enough memory.

The allocated region is placed at the end of a page boundary, immediately followed by a guard page (or an emulation, if unsupported by the platform). As a result, accessing memory past the end of the region will immediately terminate the application.

A canary is also placed right before the returned pointer. Modifications of this canary are detected when trying to free the allocated region with `sodium_free()` and cause the application to immediately terminate.

If supported by the platform, an additional guard page is placed before this canary to make it less likely for sensitive data to be accessible when reading past the end of an unrelated region.

The allocated region is filled with `0xdb` bytes to help catch bugs due to uninitialized data.

In addition, `mlock()` is called on the region to help avoid it being swapped to disk. Note however that `mlock()` may not be supported, may fail or may be a no-op, in which case `sodium_malloc()` will return the memory regardless, but it will not be locked. If you specifically need to rely on memory locking, consider calling `sodium_mlock()` and checking its return value.

On operating systems supporting `MAP_NOCORE` or `MADV_DONTDUMP`, memory allocated this way will also not be part of core dumps.

The returned address will not be aligned if the allocation size is not a multiple of the required alignment.

For this reason, `sodium_malloc()` should not be used with packed or variable-length structures unless the size given to `sodium_malloc()` is rounded up to ensure proper alignment.

All the structures used by libsodium can safely be allocated using `sodium_malloc()`.

Allocating `0` bytes is a valid operation. It returns a pointer that can be successfully passed to `sodium_free()`.

```c
void *sodium_allocarray(size_t count, size_t size);
```

The `sodium_allocarray()` function returns a pointer from which `count` objects that are `size` bytes of memory each can be accessed.

It provides the same guarantees as `sodium_malloc()` but also protects against arithmetic overflows when `count * size` exceeds `SIZE_MAX`.

```c
void sodium_free(void *ptr);
```

The `sodium_free()` function unlocks and deallocates memory allocated using `sodium_malloc()` or `sodium_allocarray()`.

Before this, the canary is checked to detect possible buffer underflows and terminate the process if required.

`sodium_free()` also fills the memory region with zeros before the deallocation.

This function can be called even if the region was previously protected using `sodium_mprotect_readonly()`; the protection will automatically be changed as needed.

`ptr` can be `NULL`, in which case no operation is performed.

```c
int sodium_mprotect_noaccess(void *ptr);
```

The `sodium_mprotect_noaccess()` function makes a region allocated using `sodium_malloc()` or `sodium_allocarray()` inaccessible. It cannot be read or written, but the data are preserved.

This function can be used to make confidential data inaccessible except when needed for a specific operation.

```c
int sodium_mprotect_readonly(void *ptr);
```

The `sodium_mprotect_readonly()` function marks a region allocated using `sodium_malloc()` or `sodium_allocarray()` as read-only.

Attempting to modify the data will cause the process to terminate.

```c
int sodium_mprotect_readwrite(void *ptr);
```

The `sodium_mprotect_readwrite()` function marks a region allocated using `sodium_malloc()` or `sodium_allocarray()` as readable and writable after having been protected using `sodium_mprotect_readonly()` or `sodium_mprotect_noaccess()`.

## Notes on memory locking

While `mlock()` and `sodium_mlock()` are useful for preventing heap-allocated data from being swapped to disk, they have important limitations that developers should understand.

First, `mlock()` only protects heap-allocated data, not data on the stack or in CPU registers. Even when sensitive data is stored in locked heap pages, it will be copied to registers and potentially the stack when actually used.

The stack cannot be reliably locked with `mlock()` because it only locks existing pages at the time of the call—if the stack later grows, new pages will not be locked.

Protecting CPU registers from being swapped is fundamentally impossible with current operating system interfaces, as they may be saved to the stack during context switches, interrupt handling, or when the kernel pages out a process.

As a mitigation, `sodium_stackzero()` can be called after a batch of sensitive operations to wipe the stack and remove any sensitive data that may have been temporarily stored there.

Second, memory locking is constrained by the `RLIMIT_MEMLOCK` resource limit, which restricts the amount of memory a process can lock. On some systems, raising this limit requires the `CAP_IPC_LOCK` capability.

If a process exceeds this limit, `mlock()` will fail and return `ENOMEM`. Applications that need to lock substantial amounts of memory must ensure the limit is appropriately configured.

For applications that require comprehensive protection of the stack, one approach is to lock all memory in the process using `mlockall(MCL_CURRENT | MCL_FUTURE)`. The `MCL_CURRENT` flag locks all currently mapped pages, while `MCL_FUTURE` ensures that all pages mapped in the future are also locked.

However, this approach increases memory pressure, may require elevated resource limits, and can impact application performance.

Therefore, if cold boot attacks or at-rest data protection are serious concerns for your threat model, the most effective defense is to encrypt the entire disk volume and encrypt the swap partition (or disable swap entirely).

Additionally, hibernation should be completely disabled on systems running sensitive applications, as it writes the entire contents of RAM to disk and completely bypasses all memory locking protections.

Encryption at rest ensures that even if memory contents are written to disk, they remain protected. Memory locking should be viewed as a defense-in-depth measure, not a complete solution for preventing sensitive data from ever reaching persistent storage.


# Generating random data

The library provides a set of functions to generate unpredictable data, suitable for creating secret keys.

* On Windows systems, the `RtlGenRandom()` function is used.
* On OpenBSD, the `arc4random()` function is used.
* On recent FreeBSD and Linux kernels, the `getrandom` system call is used.
* On other Unices, the `/dev/urandom` device is used.
* If none of these options can safely be used, custom implementations can easily be hooked.

## Usage

```c
uint32_t randombytes_random(void);
```

The `randombytes_random()` function returns an unpredictable value between `0` and `0xffffffff` (included).

```c
uint32_t randombytes_uniform(const uint32_t upper_bound);
```

The `randombytes_uniform()` function returns an unpredictable value between `0` and `upper_bound` (excluded). Unlike `randombytes_random() % upper_bound`, it guarantees a uniform distribution of the possible output values even when `upper_bound` is not a power of 2. Note that an `upper_bound < 2` leaves only a single element to be chosen, namely `0`.

```c
void randombytes_buf(void * const buf, const size_t size);
```

The `randombytes_buf()` function fills `size` bytes starting at `buf` with an unpredictable sequence of bytes.

```c
void randombytes_buf_deterministic(void * const buf, const size_t size,
                                   const unsigned char seed[randombytes_SEEDBYTES]);
```

The `randombytes_buf_deterministic` function stores `size` bytes into `buf` indistinguishable from random bytes without knowing `seed`.

For a given `seed`, this function will always output the same sequence. `size` can be up to 2^38 (256 GB).

`seed` is `randombytes_SEEDBYTES` bytes long.

This function is mainly useful for writing tests and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher.

Up to 256 GB can be produced with a single seed.

```c
int randombytes_close(void);
```

This deallocates the global resources used by the pseudo-random number generator. More specifically, when the `/dev/urandom` device is used, it closes the descriptor. Explicitly calling this function is almost never required.

```c
void randombytes_stir(void);
```

The `randombytes_stir()` function reseeds the pseudo-random number generator if it supports this operation. Calling this function is not required with the default generator, even after a `fork()` call, unless the descriptor for `/dev/urandom` was closed using `randombytes_close()`.

If a non-default implementation is being used (see `randombytes_set_implementation()`), `randombytes_stir()` must be called by the child after a `fork()` call.

## Note

If this is used in an application inside a VM, and the VM is snapshotted and restored, then the above functions may produce the same output.


# Secret-key cryptography


# Authenticated encryption

## Example

```c
#define MESSAGE ((const unsigned char *) "test")
#define MESSAGE_LEN 4
#define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN)

unsigned char key[crypto_secretbox_KEYBYTES];
unsigned char nonce[crypto_secretbox_NONCEBYTES];
unsigned char ciphertext[CIPHERTEXT_LEN];

crypto_secretbox_keygen(key);
randombytes_buf(nonce, sizeof nonce);
crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key);

unsigned char decrypted[MESSAGE_LEN];
if (crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, key) != 0) {
    /* message forged! */
}
```

## Purpose

This operation:

* Encrypts a message with a key and a nonce to keep it confidential
* Computes an authentication tag. This tag is used to make sure that the message hasn’t been tampered with before decrypting it.

A single key is used both to encrypt/authenticate and verify/decrypt messages. For this reason, it is critical to keep the key confidential.

The nonce doesn’t have to be confidential, but it should never ever be reused with the same key. The easiest way to generate a nonce is to use `randombytes_buf()`.

Messages encrypted are assumed to be independent. If multiple messages are sent using this API and random nonces, there will be no way to detect if a message has been received twice, or if messages have been reordered. If this is a requirement, see the [encrypting a sequence of a set of related messages](https://libsodium.gitbook.io/doc/secret-key_cryptography/encrypted-messages) section.

## Combined mode

In combined mode, the authentication tag and the encrypted message are stored together. This is usually what you want.

```c
int crypto_secretbox_easy(unsigned char *c, const unsigned char *m,
                          unsigned long long mlen, const unsigned char *n,
                          const unsigned char *k);
```

The `crypto_secretbox_easy()` function encrypts a message `m` whose length is `mlen` bytes, with a key `k` and a nonce `n`.

`k` should be `crypto_secretbox_KEYBYTES` bytes and `n` should be `crypto_secretbox_NONCEBYTES` bytes.

`c` should be at least `crypto_secretbox_MACBYTES + mlen` bytes long.

This function writes the authentication tag, whose length is `crypto_secretbox_MACBYTES` bytes, in `c`, immediately followed by the encrypted message, whose length is the same as the plaintext: `mlen`.

`c` and `m` can overlap, making in-place encryption possible. However do not forget that `crypto_secretbox_MACBYTES` extra bytes are required to prepend the tag.

```c
int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c,
                               unsigned long long clen, const unsigned char *n,
                               const unsigned char *k);
```

The `crypto_secretbox_open_easy()` function verifies and decrypts a ciphertext produced by `crypto_secretbox_easy()`.

`c` is a pointer to an authentication tag + encrypted message combination, as produced by `crypto_secretbox_easy()`. `clen` is the length of this authentication tag + encrypted message combination. Put differently, `clen` is the number of bytes written by `crypto_secretbox_easy()`, which is `crypto_secretbox_MACBYTES` + the length of the message.

The nonce `n` and the key `k` have to match those used to encrypt and authenticate the message.

The function returns `-1` if the verification fails, and `0` on success. On success, the decrypted message is stored into `m`.

`m` and `c` can overlap, making in-place decryption possible.

## Detached mode

Some applications may need to store the authentication tag and the encrypted message at different locations.

For this specific use case, “detached” variants of the functions above are available.

```c
int crypto_secretbox_detached(unsigned char *c, unsigned char *mac,
                              const unsigned char *m,
                              unsigned long long mlen,
                              const unsigned char *n,
                              const unsigned char *k);
```

This function encrypts a message `m` of length `mlen` with a key `k` and a nonce `n`, and puts the encrypted message into `c`. Exactly `mlen` bytes will be put into `c`, since this function does not prepend the authentication tag. The tag, whose size is `crypto_secretbox_MACBYTES` bytes, will be put into `mac`.

```c
int crypto_secretbox_open_detached(unsigned char *m,
                                   const unsigned char *c,
                                   const unsigned char *mac,
                                   unsigned long long clen,
                                   const unsigned char *n,
                                   const unsigned char *k);
```

The `crypto_secretbox_open_detached()` function verifies and decrypts an encrypted message `c` whose length is `clen`. `clen` doesn’t include the tag, so this length is the same as the plaintext.

The plaintext is put into `m` after verifying that `mac` is a valid authentication tag for this ciphertext, with the given nonce `n` and key `k`.

The function returns `-1` if the verification fails, or `0` on success.

```c
void crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_secretbox_KEYBYTES`
* `crypto_secretbox_MACBYTES`
* `crypto_secretbox_NONCEBYTES`

## Algorithm details

* Encryption: XSalsa20 stream cipher
* Authentication: Poly1305 MAC

## Notes

Internally, `crypto_secretbox` calls `crypto_stream_xor()` to encrypt the message. As a result, a secret key used with the former should not be reused with the later. But as a general rule, a key should not be reused for different purposes.

The original NaCl `crypto_secretbox` API is also supported, albeit not recommended.

`crypto_secretbox()` takes a pointer to 32 bytes before the message, and stores the ciphertext 16 bytes after the destination pointer, the first 16 bytes being overwritten with zeros. `crypto_secretbox_open()` takes a pointer to 16 bytes before the ciphertext and stores the message 32 bytes after the destination pointer, overwriting the first 32 bytes with zeros.

The `_easy` and `_detached` APIs are faster and improve usability by not requiring padding, copying or tricky pointer arithmetic.


# Encrypted streams and file encryption

This high-level API encrypts a sequence of messages, or a single message split into an arbitrary number of chunks, using a secret key, with the following properties:

* Messages cannot be truncated, removed, reordered, duplicated or modified without this being detected by the decryption functions.
* The same sequence encrypted twice will produce different ciphertexts.
* An authentication tag is added to each encrypted message: stream corruption will be detected early, without having to read the stream until the end.
* Each message can include additional data (ex: timestamp, protocol version) in the computation of the authentication tag.
* Messages can have different sizes.
* There are no practical limits to the total length of the stream, or to the total number of individual messages.
* Ratcheting: at any point in the stream, it is possible to “forget” the key used to encrypt the previous messages, and switch to a new key.

This API can be used to securely send an ordered sequence of messages to a peer. Since the length of the stream is not limited, it can also be used to encrypt files regardless of their size.

It transparently generates nonces and automatically handles key rotation.

The `crypto_secretstream_*()` API was introduced in libsodium 1.0.14.

## Example (stream encryption)

```c
#define MESSAGE_PART1 (const unsigned char *) "Arbitrary data to encrypt"
#define MESSAGE_PART1_LEN    25
#define CIPHERTEXT_PART1_LEN MESSAGE_PART1_LEN + crypto_secretstream_xchacha20poly1305_ABYTES

#define MESSAGE_PART2 (const unsigned char *) "split into"
#define MESSAGE_PART2_LEN    10
#define CIPHERTEXT_PART2_LEN MESSAGE_PART2_LEN + crypto_secretstream_xchacha20poly1305_ABYTES

#define MESSAGE_PART3 (const unsigned char *) "three messages"
#define MESSAGE_PART3_LEN    14
#define CIPHERTEXT_PART3_LEN MESSAGE_PART3_LEN + crypto_secretstream_xchacha20poly1305_ABYTES

crypto_secretstream_xchacha20poly1305_state state;
unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
unsigned char c1[CIPHERTEXT_PART1_LEN],
              c2[CIPHERTEXT_PART2_LEN],
              c3[CIPHERTEXT_PART3_LEN];

/* Shared secret key required to encrypt/decrypt the stream */
crypto_secretstream_xchacha20poly1305_keygen(key);

/* Set up a new stream: initialize the state and create the header */
crypto_secretstream_xchacha20poly1305_init_push(&state, header, key);

/* Now, encrypt the first chunk. `c1` will contain an encrypted,
 * authenticated representation of `MESSAGE_PART1`. */
crypto_secretstream_xchacha20poly1305_push
 (&state, c1, NULL, MESSAGE_PART1, MESSAGE_PART1_LEN, NULL, 0, 0);

/* Encrypt the second chunk. `c2` will contain an encrypted, authenticated
 * representation of `MESSAGE_PART2`. */
crypto_secretstream_xchacha20poly1305_push
 (&state, c2, NULL, MESSAGE_PART2, MESSAGE_PART2_LEN, NULL, 0, 0);

/* Encrypt the last chunk, and store the ciphertext into `c3`.
 * Note the `TAG_FINAL` tag to indicate that this is the final chunk. */
crypto_secretstream_xchacha20poly1305_push
 (&state, c3, NULL, MESSAGE_PART3, MESSAGE_PART3_LEN, NULL, 0,
  crypto_secretstream_xchacha20poly1305_TAG_FINAL);
```

## Example (stream decryption)

```c
unsigned char tag;
unsigned char m1[MESSAGE_PART1_LEN],
              m2[MESSAGE_PART2_LEN],
              m3[MESSAGE_PART3_LEN];

/* Decrypt the stream: initializes the state, using the key and a header */
if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, key) != 0) {
    /* Invalid header, no need to go any further */
}

/* Decrypt the first chunk. A real application would probably use
 * a loop, that reads data from the network or from disk, and exits after
 * an error, or after the last chunk (with a `TAG_FINAL` tag) has been
 * decrypted. */
if (crypto_secretstream_xchacha20poly1305_pull
    (&state, m1, NULL, &tag, c1, CIPHERTEXT_PART1_LEN, NULL, 0) != 0) {
   /* Invalid/incomplete/corrupted ciphertext - abort */
}
assert(tag == 0); /* The tag is the one we attached to this chunk: 0 */

/* Decrypt the second chunk, store the result into `m2` */
if (crypto_secretstream_xchacha20poly1305_pull
    (&state, m2, NULL, &tag, c2, CIPHERTEXT_PART2_LEN, NULL, 0) != 0) {
    /* Invalid/incomplete/corrupted ciphertext - abort */
}
assert(tag == 0); /* Not the end of the stream yet */

/* Decrypt the last chunk, store the result into `m3` */
if (crypto_secretstream_xchacha20poly1305_pull
    (&state, m3, NULL, &tag, c3, CIPHERTEXT_PART3_LEN, NULL, 0) != 0) {
    /* Invalid/incomplete/corrupted ciphertext - abort */
}
/* The tag indicates that this is the final chunk, no need to read and decrypt more */
assert(tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL);
```

See down below for a complete example of file encryption/decryption using the secretstream API.

## Usage

The `crypto_secretstream_*_push()` function set creates an encrypted stream. The `crypto_secretstream_*_pull()` function set is the decryption counterpart.

An encrypted stream starts with a short header, whose size is `crypto_secretstream_xchacha20poly1305_HEADERBYTES` bytes. That header must be sent/stored before the sequence of encrypted messages, as it is required to decrypt the stream. The header content doesn’t have to be secret and decryption with a different header would fail.

A tag is attached to each message. That tag can be any of:

* `0`, or `crypto_secretstream_xchacha20poly1305_TAG_MESSAGE`: the most common tag, that doesn’t add any information about the nature of the message.
* `crypto_secretstream_xchacha20poly1305_TAG_FINAL`: indicates that the message marks the end of the stream, and erases the secret key used to encrypt the previous sequence.
* `crypto_secretstream_xchacha20poly1305_TAG_PUSH`: indicates that the message marks the end of a set of messages, but not the end of the stream. For example, a huge JSON string sent as multiple chunks can use this tag to indicate to the application that the string is complete and that it can be decoded. But the stream itself is not closed, and more data may follow.
* `crypto_secretstream_xchacha20poly1305_TAG_REKEY`: “forget” the key used to encrypt this message and the previous ones, and derive a new secret key.

A typical encrypted stream simply attaches `0` as a tag to all messages, except the last one which is tagged as `TAG_FINAL`.

Note that tags are encrypted; encrypted streams do not reveal any information about sequence boundaries (`PUSH` and `REKEY` tags).

For each message, additional data can be included in the computation of the authentication tag. With this API, additional data is rarely required, and most applications can just use `NULL` and a length of `0` instead.

### Encryption

```c
void crypto_secretstream_xchacha20poly1305_keygen
   (unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]);
```

Creates a random, secret key to encrypt a stream, and stores it into `k`.

Note that using this function is not required to obtain a suitable key: the `secretstream` API can use any secret key whose size is `crypto_secretstream_xchacha20poly1305_KEYBYTES` bytes.

Network protocols can leverage the key exchange API in order to get a shared key that can be used to encrypt streams. Similarly, file encryption applications can use the password hashing API to get a key that can be used with the functions below.

```c
int crypto_secretstream_xchacha20poly1305_init_push
   (crypto_secretstream_xchacha20poly1305_state *state,
    unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES],
    const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]);
```

The `crypto_secretstream_xchacha20poly1305_init_push()` function initializes a state `state` using the key `k` and an internal, automatically generated initialization vector. It then stores the stream header into `header` (`crypto_secretstream_xchacha20poly1305_HEADERBYTES` bytes).

This is the first function to call in order to create an encrypted stream. The key `k` will not be required any more for subsequent operations.

```c
int crypto_secretstream_xchacha20poly1305_push
   (crypto_secretstream_xchacha20poly1305_state *state,
    unsigned char *c, unsigned long long *clen_p,
    const unsigned char *m, unsigned long long mlen,
    const unsigned char *ad, unsigned long long adlen, unsigned char tag);
```

The `crypto_secretstream_xchacha20poly1305_push()` function encrypts a message `m` of length `mlen` bytes using the state `state` and the tag `tag`.

Additional data `ad` of length `adlen` can be included in the computation of the authentication tag. If no additional data is required, `ad` can be `NULL` and `adlen` set to `0`.

The ciphertext is put into `c`.

If `clen_p` is not `NULL`, the ciphertext length will be stored at that address. But with this particular construction, the ciphertext length is guaranteed to always be `mlen + crypto_secretstream_xchacha20poly1305_ABYTES`.

The maximum length of an individual message is `crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX` bytes (\~ 256 GB).

### Decryption

```c
int crypto_secretstream_xchacha20poly1305_init_pull
   (crypto_secretstream_xchacha20poly1305_state *state,
    const unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES],
    const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]);
```

The `crypto_secretstream_xchacha20poly1305_init_pull()` function initializes a state given a secret key `k` and a header `header`. The key `k` will not be required any more for subsequent operations.

It returns `0` on success, or `-1` if the header is invalid.

```c
int crypto_secretstream_xchacha20poly1305_pull
   (crypto_secretstream_xchacha20poly1305_state *state,
    unsigned char *m, unsigned long long *mlen_p, unsigned char *tag_p,
    const unsigned char *c, unsigned long long clen,
    const unsigned char *ad, unsigned long long adlen);
```

The `crypto_secretstream_xchacha20poly1305_pull()` function verifies that `c` (a sequence of `clen` bytes) contains a valid ciphertext and authentication tag for the given state `state` and optional authenticated data `ad` of length `adlen` bytes.

If the ciphertext appears to be invalid, the function returns `-1`.

If the authentication tag appears to be correct, the decrypted message is put into `m`.

If `tag_p` is not `NULL`, the tag attached to the message is stored at that address.

If `mlen_p` is not `NULL`, the message length is stored at that address. But with this particular construction, it is guaranteed to always be `clen - crypto_secretstream_xchacha20poly1305_ABYTES` bytes.

Applications will typically call this function in a loop, until a message with the `crypto_secretstream_xchacha20poly1305_TAG_FINAL` tag is found.

### Rekeying

Rekeying happens automatically and transparently, before the internal counter of the underlying cipher wraps. Therefore, streams can be arbitrary large.

Optionally, applications for which forward secrecy is critical can attach the `crypto_secretstream_xchacha20poly1305_TAG_REKEY` tag to a message in order to trigger an explicit rekeying. The decryption API will automatically update the key if this tag is found attached to a message.

Explicit rekeying can also be performed without adding a tag, by calling the `crypto_secretstream_xchacha20poly1305_rekey()` function:

```c
void crypto_secretstream_xchacha20poly1305_rekey
    (crypto_secretstream_xchacha20poly1305_state *state);
```

This updates the state, but doesn’t add any information about the key change to the stream. If this function is used to create an encrypted stream, the decryption process must call that function at the exact same stream location.

## Constants

* `crypto_secretstream_xchacha20poly1305_ABYTES`
* `crypto_secretstream_xchacha20poly1305_HEADERBYTES`
* `crypto_secretstream_xchacha20poly1305_KEYBYTES`
* `crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX`
* `crypto_secretstream_xchacha20poly1305_TAG_MESSAGE`
* `crypto_secretstream_xchacha20poly1305_TAG_PUSH`
* `crypto_secretstream_xchacha20poly1305_TAG_REKEY`
* `crypto_secretstream_xchacha20poly1305_TAG_FINAL`

## Algorithm

Initialization (`secretstream_init`): a subkey `k` and a 64-bit nonce `n` are derived from a key `K` and a 192-bit random nonce `N`, using the same algorithm as XChaCha20. `i` is a 32-bit counter.

```
k <- HChaCha20(K, N[0..16])
n <- N[16..24]
i <- 1
```

`secretstream_init_push()` outputs `N`.

Encryption:

For every message `M` with a tag `T`:

```
c, mac <- ChaCha20Poly1305-IETF(key = k, nonce = i || n, msg = T || {0} * 63 || M)
n <- n ^ mac[0..8]
i <- (i + 1) & 0xffffffff
if i = 0:
  rekey()
```

`secretstream_push()` outputs `c` with the first block truncated to the tag size: `c[0] || c[64..] || mac`

Encrypting a unique message using `secretstream` is equivalent to `ChaCha20Poly1305-IETF(key = k, nonce = 1 || n, T || {0} * 63 || M)`.

Rekeying:

```
k || n <- ChaCha20-IETF(key = k, nonce = i || n, msg = k || n)
i <- 1
```

A `FINAL` tag performs an implicit rekeying.

## File encryption example code

```c
#include <stdio.h>
#include <sodium.h>

#define CHUNK_SIZE 4096

static int
encrypt(const char *target_file, const char *source_file,
        const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES])
{
    unsigned char  buf_in[CHUNK_SIZE];
    unsigned char  buf_out[CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES];
    unsigned char  header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
    crypto_secretstream_xchacha20poly1305_state st;
    FILE          *fp_t, *fp_s;
    unsigned long long out_len;
    size_t         rlen;
    int            eof;
    unsigned char  tag;

    fp_s = fopen(source_file, "rb");
    fp_t = fopen(target_file, "wb");
    crypto_secretstream_xchacha20poly1305_init_push(&st, header, key);
    fwrite(header, 1, sizeof header, fp_t);
    do {
        rlen = fread(buf_in, 1, sizeof buf_in, fp_s);
        eof = feof(fp_s);
        tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0;
        crypto_secretstream_xchacha20poly1305_push(&st, buf_out, &out_len, buf_in, rlen,
                                                   NULL, 0, tag);
        fwrite(buf_out, 1, (size_t) out_len, fp_t);
    } while (! eof);
    fclose(fp_t);
    fclose(fp_s);
    return 0;
}

static int
decrypt(const char *target_file, const char *source_file,
        const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES])
{
    unsigned char  buf_in[CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES];
    unsigned char  buf_out[CHUNK_SIZE];
    unsigned char  header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
    crypto_secretstream_xchacha20poly1305_state st;
    FILE          *fp_t, *fp_s;
    unsigned long long out_len;
    size_t         rlen;
    int            eof;
    int            ret = -1;
    unsigned char  tag;

    fp_s = fopen(source_file, "rb");
    fp_t = fopen(target_file, "wb");
    fread(header, 1, sizeof header, fp_s);
    if (crypto_secretstream_xchacha20poly1305_init_pull(&st, header, key) != 0) {
        goto ret; /* incomplete header */
    }
    do {
        rlen = fread(buf_in, 1, sizeof buf_in, fp_s);
        eof = feof(fp_s);
        if (crypto_secretstream_xchacha20poly1305_pull(&st, buf_out, &out_len, &tag,
                                                       buf_in, rlen, NULL, 0) != 0) {
            goto ret; /* corrupted chunk */
        }
        if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
            if (! eof) {
                goto ret; /* end of stream reached before the end of the file */
            }
        } else { /* not the final chunk yet */
            if (eof) {
                goto ret; /* end of file reached before the end of the stream */
            }
        }
        fwrite(buf_out, 1, (size_t) out_len, fp_t);
    } while (! eof);

    ret = 0;
ret:
    fclose(fp_t);
    fclose(fp_s);
    return ret;
}

int
main(void)
{
    unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES];

    if (sodium_init() != 0) {
        return 1;
    }
    crypto_secretstream_xchacha20poly1305_keygen(key);
    if (encrypt("/tmp/encrypted", "/tmp/original", key) != 0) {
        return 1;
    }
    if (decrypt("/tmp/decrypted", "/tmp/encrypted", key) != 0) {
        return 1;
    }
    return 0;
}
```


# Encrypting a set of related messages

The `crypto_secretbox`, `crypto_box` and `crypto_seal` APIs are designed to encrypt **independent** messages.

However, applications may wish to encrypt a set of messages with the following constraints:

* If a sequence of messages is encrypted, the decryption system must ensure that the complete, unmodified sequence has been properly received. In particular, it must guarantee that messages haven’t been added, removed, duplicated, truncated or reordered.
* If an unordered set of encrypted messages is transmitted (for example when using a protocol such as UDP), the decryption system must be able to reorder the messages.

Simply encrypting individual messages with a random nonce doesn’t respect these constraints.

For sequences of messages, libsodium 1.0.14 and beyond implement the [`crypto_secretstream` API](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretstream) that satisfies the above constraints. This API is recommended to encrypt files or for secure communications over a reliable protocol with ordering guarantees, such as TCP.

On older versions of the library, and with transport protocols featuring weaker ordering and reliability guarantees, these constraints can be satisfied using AEAD (Authenticated Encryption with Additional Data) constructions.

Recommended API: [`crypto_aead_xchacha20poly1305_ietf_*()`](https://libsodium.gitbook.io/doc/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction).

## Initialization vector

The same key will be used to encrypt a set of messages. This is perfectly acceptable as long as that key is combined with a unique nonce for each message.

The easiest way to achieve this is to choose a random initial nonce, and to increment it after each message:

```c
unsigned char nonce[NPUBBYTES];

randombytes_buf(nonce, sizeof nonce);

encrypt(c1, m1, key, nonce);
sodium_increment(nonce, sizeof nonce);
encrypt(c2, m2, key, nonce);
sodium_increment(nonce, sizeof nonce);
...
```

Although the terms “nonce” and “initialization vector” are frequently used interchangeably, in this documentation, we use the term “initialization vector” to describe the first nonce used to encrypt a set of messages.

A random initialization vector ensures that even if the key is reused to encrypt a different set of messages, two messages will not be encrypted using the same nonce, which, for most constructions, is critical for security.

This assumes that the size of the nonce is big enough that the probability of a nonce reuse is negligible. With a 192-bit nonce size, the XChaCha20 and XSalsa20 ciphers fit in this category. The AES and ChaCha20 (not XChaCha20) ciphers do *not* fit in this category. Please refer to the “short nonces” section below for recommendations about using such ciphers, if you really have to use these.

In order for the set of messages to be decrypted, the initialization vector must be transmitted. Unlike the key, it doesn’t have to be secret, so it can be prepended to the ciphertext, before the first message.

## Authentication tags

AEAD constructions encrypt messages and append an authentication tag. That authentication tag is computed using the following data:

* The secret key
* The nonce
* The message, before or after encryption
* Optionally, some additional data

During the decryption process, the authentication tag is computed using the same data, and compared with the one that was attached to the ciphertext. If the tag is large enough, a valid authentication tag for a given ciphertext cannot be computed without knowing the secret key.

If these authentication tags differ, it means that the ciphertext has been corrupted, tampered with, or created without the correct secret key. In such a situation, decryption functions return an error code, and applications must discard the invalid received data.

Note that the nonce is included in the computation of the tag. A valid tag for a given ciphertext and nonce will not verify with the same ciphertext, but a different nonce.

## Additional data

As described above, the computation of an authentication tag can include additional data. This is completely optional, and most applications don’t need to include any.

For a given key, nonce and message, the authentication tag will be different if the additional data differs. The ciphertext will be the same, though. Additional data are usually non-secret data.

How additional data are used is specific to every application and protocol, but here are two sample use cases for them:

* **version identifiers:** using a version identifier as additional data allows the recipient of an encrypted message to check that the expected protocol version was used. If a valid secret key is used, but the version is not the one expected by the recipient, decryption will fail.
* **timestamps:** when using a datagram-based transport protocol such as UDP, a timestamp can be included in every datagram, so that the recipient can ignore datagrams that are too old or in the future. A timestamp is not secret data and doesn’t have to be encrypted. Using the timestamp as additional data allows the recipient to confirm that a timestamp that appears to be valid hasn’t been tampered with.

## Ordered and unordered messages

As described above, a simple way to ensure that a sequence of received messages matches what the originator sent is to set the initial nonce to a given value, and increment it after every message.

The originator only sends the initialization vector. Individual messages do not contain a copy of the nonce used to encrypt them. They don’t have to, since the recipient can perform the same operation as the sender, namely increment the nonce after every received encrypted message, in order to decrypt the stream.

If the stream being decrypted doesn’t match the original stream, because messages have been altered, removed, added, duplicated or reordered, the authentication tag will not match the one computed by the recipient using the expected nonce. This issue will be immediately detected by the decryption function.

When using a transport protocol such as UDP, encrypted messages are not guaranteed to be received in order. Some datagrams may also be missing or duplicated. Applications must reorder them and handle retransmission.

In that situation, a copy of the nonce, or value representing the difference with the initial nonce, can be added to every encrypted message. Since a message is encrypted and authenticated using a unique nonce in addition to the key, the decryption process will immediately detect an encrypted message whose attached nonce has been tampered with.

## Shared keys and repeated nonces

As previously stated, it is important to avoid using the same nonce to encrypt different messages.

If two or more parties share the same secret key, increment the nonce after each message, but use the same initialization vector, different messages may end up being encrypted with the same nonce.

Each party can start with a different initialization vector and send it to its peers, but a better approach is to simply use different keys. Even if `kAB` and `kBA` are known by both parties, messages sent by `A` to `B` are encrypted using the secret key `kAB`, whereas messages sent by `B` to `A` will be encrypted using `kBA`.

The key exchange API (`crypto_kx()` functions) creates two different keys for that purpose.

## Short nonces

Ciphers such as `AES` do not feature nonces large enough to be randomly chosen without taking the risk of repeating a nonce.

More accurately, a single nonce shouldn’t be used to encrypt different messages with the same key. Using the same nonce to encrypt different messages with different keys is perfectly safe.

Therefore, ciphers with short nonces can be safely used, but require keys to be frequently rotated, in addition to generating a new key for every stream. This requires support from application-level protocols, and can be tricky to implement.

An alternative is to use a nonce extension mechanism. A large (160 bits or more) nonce `N` is used by the protocol. Its initial value can be randomly chosen.

The actual encryption is done as follows:

* Using a pseudorandom function, a subkey and a shorter nonce are derived from the key and the large nonce
* The cipher is used with this subkey and short nonce to encrypt or decrypt a message

The following code snippet derives a 256-bit subkey and a 96-bit subnonce (these parameters can be used with AES-256) from a 256-bit key and an arbitrarily long nonce:

```c
unsigned char  out[32 + 12];
unsigned char *subkey   = out;
unsigned char *subnonce = out + 32;
crypto_generichash(out, sizeof out, nonce, sizeof nonce, key, sizeof key);
```

Note that the security of the cipher is reduced to the one of the hash function. This operation also implies a small performance hit, that becomes negligible as the message size increases.

Unless a cipher such as `AES` is a requirement, using a cipher with a longer nonce is easier and safer.

## Note

Please refer to the [main page on AEAD constructions](https://libsodium.gitbook.io/doc/secret-key_cryptography/aead) for detailed information about the limitations of each construction.


# Authentication

## Example

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4

unsigned char key[crypto_auth_KEYBYTES];
unsigned char mac[crypto_auth_BYTES];

crypto_auth_keygen(key);
crypto_auth(mac, MESSAGE, MESSAGE_LEN, key);

if (crypto_auth_verify(mac, MESSAGE, MESSAGE_LEN, key) != 0) {
    /* message forged! */
}
```

## Purpose

This operation computes an authentication tag for a message and a secret key, and provides a way to verify that a given tag is valid for a given message and a key.

The function computing the tag is deterministic: the same (message, key) tuple will always produce the same output.

However, even if the message is public, knowing the key is required in order to be able to compute a valid tag. Therefore, the key should remain confidential. The tag, however, can be public.

A typical use case is:

* `A` prepares a message, adds an authentication tag, and sends it to `B`
* `A` doesn’t store the message
* Later on, `B` sends the message and the authentication tag to `A`
* `A` uses the authentication tag to verify that it created this message.

This operation does *not* encrypt the message. It only computes and verifies an authentication tag.

## Usage

```c
int crypto_auth(unsigned char *out, const unsigned char *in,
                unsigned long long inlen, const unsigned char *k);
```

The `crypto_auth()` function computes a tag for the message `in`, whose length is `inlen` bytes, and the key `k`. `k` should be `crypto_auth_KEYBYTES` bytes. The function puts the tag into `out`. The tag is `crypto_auth_BYTES` bytes long.

```c
int crypto_auth_verify(const unsigned char *h, const unsigned char *in,
                       unsigned long long inlen, const unsigned char *k);
```

The `crypto_auth_verify()` function verifies that the tag stored at `h` is a valid tag for the message `in` whose length is `inlen` bytes, and the key `k`.

It returns `-1` if the verification fails, and `0` if it passes.

```c
void crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_auth_BYTES`
* `crypto_auth_KEYBYTES`

## Algorithm details

* HMAC-SHA512-256


# AEAD constructions

This operation:

* Encrypts a message with a key and a nonce to keep it confidential
* Computes an authentication tag. This tag is used to make sure that the message, as well as optional, non-confidential (non-encrypted) data, haven’t been tampered with.

A typical use case for additional data is to authenticate protocol-specific metadata about the message, such as its length and encoding.

## Supported constructions

libsodium supports two popular constructions: AES256-GCM and ChaCha20-Poly1305 (original version and IETF version), as well as a variant of the latter with an extended nonce: XChaCha20-Poly1305.

The “combined mode” API of each construction appends the authentication tag to the ciphertext. The “detached mode” API stores the authentication tag in a separate location.

### Availability and interoperability

| Construction            | Key size | Nonce size | Block size | MAC size | Availability                                                                                               |
| ----------------------- | -------- | ---------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| AEGIS-128L              | 128 bits | 128 bits   | 256 bits   | 256 bits | libsodium >= 1.0.19. On the standard track.                                                                |
| AEGIS-256               | 256 bits | 256 bits   | 128 bits   | 256 bits | libsodium >= 1.0.19. On the standard track.                                                                |
| AES256-GCM              | 256 bits | 96 bits    | 128 bits   | 128 bits | libsodium >= 1.0.4 but requires hardware support. IETF standard; also implemented in many other libraries. |
| ChaCha20-Poly1305       | 256 bits | 64 bits    | 512 bits   | 128 bits | libsodium >= 0.6.0. Also implemented in {Libre,Open,Boring}SSL.                                            |
| ChaCha20-Poly1305-IETF  | 256 bits | 96 bits    | 512 bits   | 128 bits | libsodium >= 1.0.4. IETF standard; also implemented in Ring, {Libre,Open,Boring}SSL and other libraries.   |
| XChaCha20-Poly1305-IETF | 256 bits | 192 bits   | 512 bits   | 128 bits | libsodium >= 1.0.12. Not standardized but widely implemented.                                              |

## Limitations

| Construction            | Max bytes for a single (key,nonce)  |
| ----------------------- | ----------------------------------- |
| AEGIS-256               | No practical limits                 |
| AEGIS-128L              | No practical limits                 |
| XChaCha20-Poly1305-IETF | No practical limits (\~ 2^64 bytes) |
| ChaCha20-Poly1305       | No practical limits (\~ 2^64 bytes) |
| ChaCha20-Poly1305-IETF  | 256 GB                              |
| AES256-GCM              | \~ 64 GB                            |

| Construction            | Max messages with random nonces |
| ----------------------- | ------------------------------- |
| AEGIS-256               | No practical limits             |
| XChaCha20-Poly1305-IETF | No practical limits             |
| AEGIS-128L              | 2^48                            |
| AES256-GCM              | 2^32                            |
| ChaCha20-Poly1305-IETF  | 2^32                            |
| ChaCha20-Poly1305       | 2^16                            |

These figures assume an untruncated (128-bit or 256-bit) authentication tag.

Although periodic rekeying remains highly recommended, online protocols leveraging additional data to discard old messages don’t have practical limitations on the total number of messages.

In spite of these limits, applications must enforce a limit on the maximum size of a ciphertext to decrypt. Very large messages should be split in multiple chunks instead of being encrypted as a single ciphertext:

* This keeps memory usage in control,
* A corrupted chunk can be immediately detected before the whole ciphertext is received,
* Large messages provide more wiggle room for attacks.

Applications are also encouraged to limit the number of attempts an adversary can make, for example by closing a session after a large number of decryption failures.

Assuming a 2^-32 attack success probability, and nonces safely chosen (cf. the `Nonces` section below) the following tables summarize how many messages should be encrypted with a single key before switching to a new key, as well as how many brute force decryption attempts an attacker should be allowed to make to prevent forgery.

Note that the latter is not a practical concern due to application limits, noisiness, storage and bandwidth requirements. The maximum number of encryptions is the most important criteria for selecting a secure primitive.

* For 16 KB long messages:

| Construction                   | Max number of encryptions | Max number of decryption attempts/message |
| ------------------------------ | ------------------------- | ----------------------------------------- |
| AEGIS-256                      | No practical limits       | > 2^128 (with 256-bit tags)               |
| AEGIS-128L                     | No practical limits       | > 2^128 (with 256-bit tags)               |
| AES256-GCM                     | 2^38                      | 2^85                                      |
| All ChaCha20-Poly1305 variants | 2^63                      | 2^61 (but requires at least 2^77 bytes)   |

* For 1 MB long messages:

| Construction                   | Max number of encryptions | Max number of decryption attempts/message |
| ------------------------------ | ------------------------- | ----------------------------------------- |
| AEGIS-256                      | No practical limits       | > 2^128 (with 256-bit tags)               |
| AEGIS-128L                     | No practical limits       | > 2^128 (with 256-bit tags)               |
| AES256-GCM                     | 2^32                      | 2^79                                      |
| All ChaCha20-Poly1305 variants | 2^57                      | 2^55 (but requires at least 2^77 bytes)   |

* For 1 GB long messages:

| Construction                   | Max number of encryptions | Max number of decryption attempts/message |
| ------------------------------ | ------------------------- | ----------------------------------------- |
| AEGIS-256                      | No practical limits       | > 2^128 (with 256-bit tags)               |
| AEGIS-128L                     | No practical limits       | > 2^128 (with 256-bit tags)               |
| AES256-GCM                     | 2^22                      | 2^69                                      |
| All ChaCha20-Poly1305 variants | 2^47                      | 2^45 (but requires at least 2^77 bytes)   |

* For 64 GB long messages:

| Construction                   | Max number of encryptions | Max number of decryption attempts/message |
| ------------------------------ | ------------------------- | ----------------------------------------- |
| AEGIS-256                      | No practical limits       | > 2^128 (with 256-bit tags)               |
| AEGIS-128L                     | No practical limits       | > 2^128 (with 256-bit tags)               |
| AES256-GCM                     | 2^16                      | 2^63                                      |
| All ChaCha20-Poly1305 variants | 2^41                      | 2^39 (but requires at least 2^77 bytes)   |

### Nonces

| Construction            | Safe options to choose a nonce    |
| ----------------------- | --------------------------------- |
| XChaCha20-Poly1305-IETF | Counter, permutation, random      |
| AEGIS-256               | Counter, permutation, random      |
| AEGIS-128L              | Counter, permutation, random (\*) |
| AES256-GCM              | Counter, permutation              |
| ChaCha20-Poly1305       | Counter, permutation              |
| ChaCha20-Poly1305-IETF  | Counter, permutation              |

\*: for a collision probability below 2^-32, random nonces are safe up to 2^48 messages.

### TL;DR: which one should I use?

If the target CPU has hardware AES acceleration (modern Intel or ARM CPU), `AEGIS-256` is the safest choice.

If not, use `XChaCha20-Poly1305-IETF`.

Other choices are only present for interoperability with other libraries that don’t implement these ciphers yet.

### AES256-GCM

The current implementation of this construction is hardware-accelerated and requires the Intel AES-NI extensions, or the ARM Crypto extensions.

Intel Westmere processors (introduced in 2010) and newer, as well as the vast majority of 64-bit ARM processors meet the requirements.

There are no plans to support non hardware-accelerated implementations of AES-GCM, as correctly mitigating side-channels in a software implementation comes with major speed tradeoffs, that defeat the whole point of AES-GCM over ChaCha20-Poly1305.

### ChaCha20-Poly1305

While AES is very fast on dedicated hardware, its performance on platforms that lack such hardware is considerably lower. Another problem is that many software AES implementations are vulnerable to cache-collision timing attacks.

ChaCha20 is considerably faster than AES in software-only implementations, making it around three times as fast on platforms that lack specialized AES hardware. ChaCha20 is also not sensitive to timing attacks.

Poly1305 is a high-speed message authentication code.

The combination of the ChaCha20 stream cipher with the Poly1305 authenticator was proposed in January 2014 as an alternative to the Salsa20-Poly1305 construction. ChaCha20-Poly1305 was implemented in major operating systems, web browsers and crypto libraries shortly after. It eventually became an official IETF standard in May 2015.

The ChaCha20-Poly1305 implementation in libsodium is portable across all supported architectures.

### XChaCha20-Poly1305

XChaCha20-Poly1305 applies the construction described in Daniel Bernstein’s [Extending the Salsa20 nonce](https://cr.yp.to/snuffle/xsalsa-20081128.pdf) paper to the ChaCha20 cipher in order to extend the nonce size to 192-bit.

This extended nonce size allows random nonces to be safely used, and also facilitates the construction of misuse-resistant schemes.

The XChaCha20-Poly1305 implementation in libsodium is portable across all supported architectures.

## Additional data

These functions accept an optional, arbitrarily long “additional data” parameter. These data are not present in the ciphertext, but are mixed in the computation of the authentication tag.

A typical use for these data is to authenticate version numbers, timestamps or monotonically increasing counters in order to discard previous messages and prevent replay attacks.

## Robustness

Ciphertexts are expected to be decrypted and verified using the same key as the key initially used for encryption.

However, when using AES-GCM and ChaCha20-Poly1305, multiple keys that would cause a (ciphertext, tag) pair to verify can be efficiently computed.

Decryption using a key that differs from the one used for encryption would produce a different message, and would not compromise the security of the original message.

Still, it may be an issue if an attacker has the ability to force a recipient to use a different key than the one used for encryption.

If that turns out to be a concern, the following can be done:

* Use the AEGIS ciphers, that, under common scenarios, are assumed to be safe against these attacks.

or with other ciphers:

* Prepend `H(key, nonce || ciphertext_tag)` to the ciphertext
* Verify this prior to decryption. This can be done with `crypto_auth()` and `crypto_auth_verify()`.

This assumes that attackers don’t have control over associated data. If they do, associated data `ad` must be included in the input of the hash function as well: `H(key, nonce || ciphertext_tag || ad)`. In that case, as an optimization, `ad` can be left empty in the encryption and decryption functions.

## References

* [Limits on Authenticated Encryption Use in TLS](https://eprint.iacr.org/2024/051.pdf) (Atul Luykx, Kenneth G. Paterson).
* [Usage Limits on AEAD Algorithms](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aead-limits/)
* [Collision Attacks on Galois/Counter Mode (GCM)](https://eprint.iacr.org/2024/1111.pdf)


# ChaCha20-Poly1305

## Purpose

This operation:

* Encrypts a message with a key and a nonce to keep it confidential
* Computes an authentication tag. This tag is used to make sure that the message, as well as optional, non-confidential (non-encrypted) data, haven’t been tampered with.

A typical use case for additional data is to store protocol-specific metadata about the message, such as its length and encoding.

The chosen construction uses encrypt-then-MAC and decryption will never be performed, even partially, before verification.

## Variants

libsodium implements three versions of the ChaCha20-Poly1305 construction:

* The original construction can safely encrypt up to 2^64 messages with the same key (even more with most protocols), without any practical limit to the size of a message (up to 2^64 bytes for a 128-bit tag).
* The IETF variant. It can safely encrypt a practically unlimited number of messages, but individual messages cannot exceed 64\*(2^32)-64 bytes (approximately 256 GB).
* The XChaCha20 variant, introduced in libsodium 1.0.12. It can safely encrypt a practically unlimited number of messages of any sizes, and random nonces are safe to use.

The first two variants are fully interoperable with other crypto libraries. The XChaCha20 variant is currently only implemented in libsodium, but is the recommended option if interoperability is not a concern.

They all share the same security properties when used properly, and are accessible via a similar API.

The `crypto_aead_chacha20poly1305_*()` set of functions implements the original construction, the `crypto_aead_chacha20poly1305_ietf_*()` functions implement the IETF version, and the `crypto_aead_xchacha20poly1305_ietf_*()` functions implement the XChaCha20 variant.

The constants are the same, except for the nonce size.


# Original ChaCha20-Poly1305 construction

The original ChaCha20-Poly1305 construction can safely encrypt a practically unlimited number of messages with the same key, without any practical limit to the size of a message (up to \~ 2^64 bytes).

## Example (combined mode)

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4
#define ADDITIONAL_DATA (const unsigned char *) "123456"
#define ADDITIONAL_DATA_LEN 6

unsigned char nonce[crypto_aead_chacha20poly1305_NPUBBYTES];
unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES];
unsigned char ciphertext[MESSAGE_LEN + crypto_aead_chacha20poly1305_ABYTES];
unsigned long long ciphertext_len;

crypto_aead_chacha20poly1305_keygen(key);
randombytes_buf(nonce, sizeof nonce);

crypto_aead_chacha20poly1305_encrypt(ciphertext, &ciphertext_len,
                                     MESSAGE, MESSAGE_LEN,
                                     ADDITIONAL_DATA, ADDITIONAL_DATA_LEN,
                                     NULL, nonce, key);

unsigned char decrypted[MESSAGE_LEN];
unsigned long long decrypted_len;
if (crypto_aead_chacha20poly1305_decrypt(decrypted, &decrypted_len,
                                         NULL,
                                         ciphertext, ciphertext_len,
                                         ADDITIONAL_DATA,
                                         ADDITIONAL_DATA_LEN,
                                         nonce, key) != 0) {
    /* message forged! */
}
```

## Combined mode

In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want.

```c
int crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
                                         unsigned long long *clen_p,
                                         const unsigned char *m,
                                         unsigned long long mlen,
                                         const unsigned char *ad,
                                         unsigned long long adlen,
                                         const unsigned char *nsec,
                                         const unsigned char *npub,
                                         const unsigned char *k);
```

The `crypto_aead_chacha20poly1305_encrypt()` function encrypts a message `m` whose length is `mlen` bytes using a secret key `k` (`crypto_aead_chacha20poly1305_KEYBYTES` bytes) and public nonce `npub` (`crypto_aead_chacha20poly1305_NPUBBYTES` bytes).

The encrypted message, as well as a tag authenticating both the confidential message `m` and `adlen` bytes of non-confidential data `ad`, are put into `c`.

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

At most `mlen + crypto_aead_chacha20poly1305_ABYTES` bytes are put into `c`, and the actual number of bytes is stored into `clen` unless `clen` is a `NULL` pointer.

`nsec` is not used by this particular construction and should always be `NULL`.

The public nonce `npub` should never ever be reused with the same key. The recommended way to generate it is to use `randombytes_buf()` for the first message, and increment it for each subsequent message using the same key.

```c
int crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
                                         unsigned long long *mlen_p,
                                         unsigned char *nsec,
                                         const unsigned char *c,
                                         unsigned long long clen,
                                         const unsigned char *ad,
                                         unsigned long long adlen,
                                         const unsigned char *npub,
                                         const unsigned char *k);
```

The `crypto_aead_chacha20poly1305_decrypt()` function verifies that the ciphertext `c` (as produced by `crypto_aead_chacha20poly1305_encrypt()`) includes a valid tag using a secret key `k`, a public nonce `npub`, and additional data `ad` (`adlen` bytes).

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

`nsec` is not used by this particular construction and should always be `NULL`.

The function returns `-1` if the verification fails.

If the verification succeeds, the function returns `0`, puts the decrypted message into `m` and stores its actual number of bytes into `mlen` if `mlen` is not a `NULL` pointer.

At most `clen - crypto_aead_chacha20poly1305_ABYTES` bytes will be put into `m`.

## Detached mode

Some applications may need to store the authentication tag and the encrypted message at different locations.

For this specific use case, “detached” variants of the functions above are available.

```c
int crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c,
                                                  unsigned char *mac,
                                                  unsigned long long *maclen_p,
                                                  const unsigned char *m,
                                                  unsigned long long mlen,
                                                  const unsigned char *ad,
                                                  unsigned long long adlen,
                                                  const unsigned char *nsec,
                                                  const unsigned char *npub,
                                                  const unsigned char *k);
```

The `crypto_aead_chacha20poly1305_encrypt_detached()` function encrypts a message `m` with a key `k` and a nonce `npub`. It puts the resulting ciphertext, whose length is equal to the message, into `c`.

It also computes a tag that authenticates the ciphertext as well as optional, additional data `ad` of length `adlen`. This tag is put into `mac`, and its length is `crypto_aead_chacha20poly1305_ABYTES` bytes.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
int crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m,
                                                  unsigned char *nsec,
                                                  const unsigned char *c,
                                                  unsigned long long clen,
                                                  const unsigned char *mac,
                                                  const unsigned char *ad,
                                                  unsigned long long adlen,
                                                  const unsigned char *npub,
                                                  const unsigned char *k);
```

The `crypto_aead_chacha20poly1305_decrypt_detached()` function verifies that the authentication tag `mac` is valid for the ciphertext `c` of length `clen` bytes, the key `k` , the nonce `npub` and optional, additional data `ad` of length `adlen` bytes.

If the tag is not valid, the function returns `-1` and doesn’t do any further processing.

If the tag is valid, the ciphertext is decrypted and the plaintext is put into `m`. The length is equal to the length of the ciphertext.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
void crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_aead_chacha20poly1305_KEYBYTES`
* `crypto_aead_chacha20poly1305_NPUBBYTES`
* `crypto_aead_chacha20poly1305_ABYTES`

## Algorithm details

* Encryption: ChaCha20 stream cipher
* Authentication: Poly1305 MAC

## Notes

In order to prevent nonce reuse, if a key is being reused, it is recommended to increment the previous nonce instead of generating a random nonce for each message.

To prevent nonce reuse in a client-server protocol, either use different keys for each direction, or make sure that a bit is masked in one direction, and set in the other.

## See also

* [ChaCha20 and Poly1305 based Cipher Suites for TLS](https://datatracker.ietf.org/doc/html/draft-agl-tls-chacha20poly1305-04) - Specification of the original construction


# IETF ChaCha20-Poly1305 construction

The IETF variant of the ChaCha20-Poly1305 construction can safely encrypt a practically unlimited number of messages, but individual messages cannot exceed 64\*(2^32)-64 bytes (approximately 256 GiB).

## Example (combined mode)

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4
#define ADDITIONAL_DATA (const unsigned char *) "123456"
#define ADDITIONAL_DATA_LEN 6

unsigned char nonce[crypto_aead_chacha20poly1305_IETF_NPUBBYTES];
unsigned char key[crypto_aead_chacha20poly1305_IETF_KEYBYTES];
unsigned char ciphertext[MESSAGE_LEN + crypto_aead_chacha20poly1305_IETF_ABYTES];
unsigned long long ciphertext_len;

crypto_aead_chacha20poly1305_ietf_keygen(key);
randombytes_buf(nonce, sizeof nonce);

crypto_aead_chacha20poly1305_ietf_encrypt(ciphertext, &ciphertext_len,
                                          MESSAGE, MESSAGE_LEN,
                                          ADDITIONAL_DATA, ADDITIONAL_DATA_LEN,
                                          NULL, nonce, key);

unsigned char decrypted[MESSAGE_LEN];
unsigned long long decrypted_len;
if (crypto_aead_chacha20poly1305_ietf_decrypt(decrypted, &decrypted_len,
                                              NULL,
                                              ciphertext, ciphertext_len,
                                              ADDITIONAL_DATA,
                                              ADDITIONAL_DATA_LEN,
                                              nonce, key) != 0) {
    /* message forged! */
}
```

## Combined mode

In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want.

```c
int crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c,
                                              unsigned long long *clen_p,
                                              const unsigned char *m,
                                              unsigned long long mlen,
                                              const unsigned char *ad,
                                              unsigned long long adlen,
                                              const unsigned char *nsec,
                                              const unsigned char *npub,
                                              const unsigned char *k);
```

The `crypto_aead_chacha20poly1305_ietf_encrypt()` function encrypts a message `m` whose length is `mlen` bytes using a secret key `k` (`crypto_aead_chacha20poly1305_IETF_KEYBYTES` bytes) and public nonce `npub` (`crypto_aead_chacha20poly1305_IETF_NPUBBYTES` bytes).

The encrypted message, as well as a tag authenticating both the confidential message `m` and `adlen` bytes of non-confidential data `ad`, are put into `c`.

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

At most `mlen + crypto_aead_chacha20poly1305_IETF_ABYTES` bytes are put into `c`, and the actual number of bytes is stored into `clen` unless `clen` is a `NULL` pointer.

`nsec` is not used by this particular construction and should always be `NULL`.

The public nonce `npub` should never ever be reused with the same key. The recommended way to generate it is to use `randombytes_buf()` for the first message, and increment it for each subsequent message using the same key.

```c
int crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m,
                                              unsigned long long *mlen_p,
                                              unsigned char *nsec,
                                              const unsigned char *c,
                                              unsigned long long clen,
                                              const unsigned char *ad,
                                              unsigned long long adlen,
                                              const unsigned char *npub,
                                              const unsigned char *k);
```

The `crypto_aead_chacha20poly1305_ietf_decrypt()` function verifies that the ciphertext `c` (as produced by `crypto_aead_chacha20poly1305_ietf_encrypt()`) includes a valid tag using a secret key `k`, a public nonce `npub`, and additional data `ad` (`adlen` bytes).

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

`nsec` is not used by this particular construction and should always be `NULL`.

The function returns `-1` if the verification fails.

If the verification succeeds, the function returns `0`, puts the decrypted message into `m` and stores its actual number of bytes into `mlen` if `mlen` is not a `NULL` pointer.

At most `clen - crypto_aead_chacha20poly1305_IETF_ABYTES` bytes will be put into `m`.

## Detached mode

Some applications may need to store the authentication tag and the encrypted message at different locations.

For this specific use case, “detached” variants of the functions above are available.

```c
int crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c,
                                                       unsigned char *mac,
                                                       unsigned long long *maclen_p,
                                                       const unsigned char *m,
                                                       unsigned long long mlen,
                                                       const unsigned char *ad,
                                                       unsigned long long adlen,
                                                       const unsigned char *nsec,
                                                       const unsigned char *npub,
                                                       const unsigned char *k);
```

The `crypto_aead_chacha20poly1305_ietf_encrypt_detached()` function encrypts a message `m` with a key `k` and a nonce `npub`. It puts the resulting ciphertext, whose length is equal to the message, into `c`.

It also computes a tag that authenticates the ciphertext as well as optional, additional data `ad` of length `adlen`. This tag is put into `mac`, and its length is `crypto_aead_chacha20poly1305_IETF_ABYTES` bytes.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
int crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m,
                                                       unsigned char *nsec,
                                                       const unsigned char *c,
                                                       unsigned long long clen,
                                                       const unsigned char *mac,
                                                       const unsigned char *ad,
                                                       unsigned long long adlen,
                                                       const unsigned char *npub,
                                                       const unsigned char *k);
```

The `crypto_aead_chacha20poly1305_ietf_decrypt_detached()` function verifies that the authentication tag `mac` is valid for the ciphertext `c` of length `clen` bytes, the key `k` , the nonce `npub` and optional, additional data `ad` of length `adlen` bytes.

If the tag is not valid, the function returns `-1` and doesn’t do any further processing.

If the tag is valid, the ciphertext is decrypted and the plaintext is put into `m`. The length is equal to the length of the ciphertext.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
void crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_aead_chacha20poly1305_IETF_ABYTES`
* `crypto_aead_chacha20poly1305_IETF_KEYBYTES`
* `crypto_aead_chacha20poly1305_IETF_NPUBBYTES`

On earlier versions, use `crypto_aead_chacha20poly1305_KEYBYTES` and `crypto_aead_chacha20poly1305_NPUBBYTES` - The nonce size is the only constant that differs between the original variant and the IETF variant.

## Algorithm details

* Encryption: ChaCha20 stream cipher
* Authentication: Poly1305 MAC

## Notes

In order to prevent nonce reuse, if a key is being reused, it is recommended to increment the previous nonce instead of generating a random nonce for each message.

To prevent nonce reuse in a client-server protocol, either use different keys for each direction, or make sure that a bit is masked in one direction, and set in the other.

## See also

* [ChaCha20 and Poly1305 for IETF protocols](https://datatracker.ietf.org/doc/html/rfc7539) - Specification of the IETF variant


# XChaCha20-Poly1305 construction

The XChaCha20-Poly1305 construction can safely encrypt a practically unlimited number of messages with the same key, without any practical limit to the size of a message (up to \~ 2^64 bytes).

As an alternative to counters, its large nonce size (192-bit) allows random nonces to be safely used.

For this reason, and if interoperability with other libraries is not a concern, this is the recommended AEAD construction.

## Example (combined mode)

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4
#define ADDITIONAL_DATA (const unsigned char *) "123456"
#define ADDITIONAL_DATA_LEN 6

unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES];
unsigned char key[crypto_aead_xchacha20poly1305_ietf_KEYBYTES];
unsigned char ciphertext[MESSAGE_LEN + crypto_aead_xchacha20poly1305_ietf_ABYTES];
unsigned long long ciphertext_len;

crypto_aead_xchacha20poly1305_ietf_keygen(key);
randombytes_buf(nonce, sizeof nonce);

crypto_aead_xchacha20poly1305_ietf_encrypt(ciphertext, &ciphertext_len,
                                           MESSAGE, MESSAGE_LEN,
                                           ADDITIONAL_DATA, ADDITIONAL_DATA_LEN,
                                           NULL, nonce, key);

unsigned char decrypted[MESSAGE_LEN];
unsigned long long decrypted_len;
if (crypto_aead_xchacha20poly1305_ietf_decrypt(decrypted, &decrypted_len,
                                               NULL,
                                               ciphertext, ciphertext_len,
                                               ADDITIONAL_DATA,
                                               ADDITIONAL_DATA_LEN,
                                               nonce, key) != 0) {
    /* message forged! */
}
```

## Combined mode

In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want.

```c
int crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c,
                                               unsigned long long *clen_p,
                                               const unsigned char *m,
                                               unsigned long long mlen,
                                               const unsigned char *ad,
                                               unsigned long long adlen,
                                               const unsigned char *nsec,
                                               const unsigned char *npub,
                                               const unsigned char *k);
```

The `crypto_aead_xchacha20poly1305_ietf_encrypt()` function encrypts a message `m` whose length is `mlen` bytes using a secret key `k` (`crypto_aead_xchacha20poly1305_ietf_KEYBYTES` bytes) and public nonce `npub` (`crypto_aead_xchacha20poly1305_ietf_NPUBBYTES` bytes).

The encrypted message, as well as a tag authenticating both the confidential message `m` and `adlen` bytes of non-confidential data `ad`, are put into `c`.

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

At most `mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES` bytes are put into `c`, and the actual number of bytes is stored into `clen` unless `clen` is a `NULL` pointer.

`nsec` is not used by this particular construction and should always be `NULL`.

The public nonce `npub` should never ever be reused with the same key. Nonces can be generated using `randombytes_buf()` for every message. XChaCha20 uses 192-bit nonces, so the probability of a collision is negligible. Using a counter is also perfectly fine: nonces have to be unique for a given key, but they don’t have to be unpredictable.

```c
int crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m,
                                               unsigned long long *mlen_p,
                                               unsigned char *nsec,
                                               const unsigned char *c,
                                               unsigned long long clen,
                                               const unsigned char *ad,
                                               unsigned long long adlen,
                                               const unsigned char *npub,
                                               const unsigned char *k);
```

The `crypto_aead_xchacha20poly1305_ietf_decrypt()` function verifies that the ciphertext `c` (as produced by `crypto_aead_xchacha20poly1305_ietf_encrypt()`) includes a valid tag using a secret key `k`, a public nonce `npub`, and additional data `ad` (`adlen` bytes).

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

`nsec` is not used by this particular construction and should always be `NULL`.

The function returns `-1` if the verification fails.

If the verification succeeds, the function returns `0`, puts the decrypted message into `m` and stores its actual number of bytes into `mlen` if `mlen` is not a `NULL` pointer.

At most `clen - crypto_aead_xchacha20poly1305_ietf_ABYTES` bytes will be put into `m`.

## Detached mode

Some applications may need to store the authentication tag and the encrypted message at different locations.

For this specific use case, “detached” variants of the functions above are available.

```c
int crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c,
                                                        unsigned char *mac,
                                                        unsigned long long *maclen_p,
                                                        const unsigned char *m,
                                                        unsigned long long mlen,
                                                        const unsigned char *ad,
                                                        unsigned long long adlen,
                                                        const unsigned char *nsec,
                                                        const unsigned char *npub,
                                                        const unsigned char *k);
```

The `crypto_aead_xchacha20poly1305_ietf_encrypt_detached()` function encrypts a message `m` with a key `k` and a nonce `npub`. It puts the resulting ciphertext, whose length is equal to the message, into `c`.

It also computes a tag that authenticates the ciphertext as well as optional, additional data `ad` of length `adlen`. This tag is put into `mac`, and its length is `crypto_aead_xchacha20poly1305_ietf_ABYTES` bytes.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m,
                                                        unsigned char *nsec,
                                                        const unsigned char *c,
                                                        unsigned long long clen,
                                                        const unsigned char *mac,
                                                        const unsigned char *ad,
                                                        unsigned long long adlen,
                                                        const unsigned char *npub,
                                                        const unsigned char *k);
```

The `crypto_aead_xchacha20poly1305_ietf_decrypt_detached()` function verifies that the authentication tag `mac` is valid for the ciphertext `c` of length `clen` bytes, the key `k` , the nonce `npub` and optional, additional data `ad` of length `adlen` bytes.

If the tag is not valid, the function returns `-1` and doesn’t do any further processing.

If the tag is valid, the ciphertext is decrypted and the plaintext is put into `m`. The length is equal to the length of the ciphertext.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_aead_xchacha20poly1305_ietf_KEYBYTES`
* `crypto_aead_xchacha20poly1305_ietf_NPUBBYTES`
* `crypto_aead_xchacha20poly1305_ietf_ABYTES`

## Algorithm details

* Encryption: XChaCha20 stream cipher
* Authentication: Poly1305 MAC

## Notes

XChaCha20-Poly1305 was introduced in libsodium 1.0.12.

Unlike other variants directly using the ChaCha20 cipher, generating a random nonce for each message is acceptable with this XChaCha20-based construction, provided that the output of the PRNG is indistinguishable from random data.


# AEGIS-256

AEGIS-256 is a modern AES-based cipher with unique properties making it easier and safer to use than common alternatives:

* targets 256 bit confidentiality
* 256-bit authentication tags, ensuring collision resistance within a given key; a tag can thus be used as a unique identifier for a message.
* It can safely encrypt a practically unlimited number of messages, without any practical limits on their lengths.
* It has a very large nonce size (256 bits), allowing random nonces to be used without any practical limits either.
* It has a better security margin than AES-GCM
* Leaking the state doesn’t leak the key
* It is assumed to be key-committing, preventing partitioning attacks affecting other ciphers when used with low-entropy keys such as passwords. Namely, it is difficult to find distinct keys and/or nonces that successfully verify the same `(ad, ciphertext, tag)` tuple.

AEGIS-256 is also extremely fast on recent CPUs with AES pipelines, with lower memory usage than AES-GCM.

However, on platforms without hardware AES support, it is slow and not guaranteed to be protected against side channels. In that scenario, XChaCha20-Poly1305 is a better choice.

## Example (combined mode)

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4
#define ADDITIONAL_DATA (const unsigned char *) "123456"
#define ADDITIONAL_DATA_LEN 6

unsigned char nonce[crypto_aead_aegis256_NPUBBYTES];
unsigned char key[crypto_aead_aegis256_KEYBYTES];
unsigned char ciphertext[MESSAGE_LEN + crypto_aead_aegis256_ABYTES];
unsigned long long ciphertext_len;

crypto_aead_aegis256_keygen(key);
randombytes_buf(nonce, sizeof nonce);

crypto_aead_aegis256_encrypt(ciphertext, &ciphertext_len,
                             MESSAGE, MESSAGE_LEN,
                             ADDITIONAL_DATA, ADDITIONAL_DATA_LEN,
                             NULL, nonce, key);

unsigned char decrypted[MESSAGE_LEN];
unsigned long long decrypted_len;
if (crypto_aead_aegis256_decrypt(decrypted, &decrypted_len,
                                 NULL,
                                 ciphertext, ciphertext_len,
                                 ADDITIONAL_DATA,
                                 ADDITIONAL_DATA_LEN,
                                 nonce, key) != 0) {
    /* message forged! */
}
```

## Combined mode

In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want.

```c
int crypto_aead_aegis256_encrypt(unsigned char *c,
                                 unsigned long long *clen_p,
                                 const unsigned char *m,
                                 unsigned long long mlen,
                                 const unsigned char *ad,
                                 unsigned long long adlen,
                                 const unsigned char *nsec,
                                 const unsigned char *npub,
                                 const unsigned char *k);
```

The `crypto_aead_aegis256_encrypt()` function encrypts a message `m` whose length is `mlen` bytes using a secret key `k` (`crypto_aead_aegis256_KEYBYTES` bytes) and public nonce `npub` (`crypto_aead_aegis256_NPUBBYTES` bytes).

The encrypted message, as well as a tag authenticating both the confidential message `m` and `adlen` bytes of non-confidential data `ad`, are put into `c`.

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

At most `mlen + crypto_aead_aegis256_ABYTES` bytes are put into `c`, and the actual number of bytes is stored into `clen` unless `clen` is a `NULL` pointer.

`nsec` is not used by this particular construction and should always be `NULL`.

The public nonce `npub` should never ever be reused with the same key. The recommended way to generate it is to use `randombytes_buf()` for the first message, and increment it for each subsequent message using the same key.

```c
int crypto_aead_aegis256_decrypt(unsigned char *m,
                                 unsigned long long *mlen_p,
                                 unsigned char *nsec,
                                 const unsigned char *c,
                                 unsigned long long clen,
                                 const unsigned char *ad,
                                 unsigned long long adlen,
                                 const unsigned char *npub,
                                 const unsigned char *k);
```

The `crypto_aead_aegis256_decrypt()` function verifies that the ciphertext `c` (as produced by `crypto_aead_aegis256_encrypt()`) includes a valid tag using a secret key `k`, a public nonce `npub`, and additional data `ad` (`adlen` bytes).

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

`nsec` is not used by this particular construction and should always be `NULL`.

The function returns `-1` if the verification fails.

If the verification succeeds, the function returns `0`, puts the decrypted message into `m` and stores its actual number of bytes into `mlen` if `mlen` is not a `NULL` pointer.

At most `clen - crypto_aead_aegis256_ABYTES` bytes will be put into `m`.

## Detached mode

Some applications may need to store the authentication tag and the encrypted message at different locations.

For this specific use case, “detached” variants of the functions above are available.

```c
int crypto_aead_aegis256_encrypt_detached(unsigned char *c,
                                          unsigned char *mac,
                                          unsigned long long *maclen_p,
                                          const unsigned char *m,
                                          unsigned long long mlen,
                                          const unsigned char *ad,
                                          unsigned long long adlen,
                                          const unsigned char *nsec,
                                          const unsigned char *npub,
                                          const unsigned char *k);
```

The `crypto_aead_aegis256_encrypt_detached()` function encrypts a message `m` with a key `k` and a nonce `npub`. It puts the resulting ciphertext, whose length is equal to the message, into `c`.

It also computes a tag that authenticates the ciphertext as well as optional, additional data `ad` of length `adlen`. This tag is put into `mac`, and its length is `crypto_aead_aegis256_ABYTES` bytes.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
int crypto_aead_aegis256_decrypt_detached(unsigned char *m,
                                          unsigned char *nsec,
                                          const unsigned char *c,
                                          unsigned long long clen,
                                          const unsigned char *mac,
                                          const unsigned char *ad,
                                          unsigned long long adlen,
                                          const unsigned char *npub,
                                          const unsigned char *k);
```

The `crypto_aead_aegis256_decrypt_detached()` function verifies that the authentication tag `mac` is valid for the ciphertext `c` of length `clen` bytes, the key `k` , the nonce `npub` and optional, additional data `ad` of length `adlen` bytes.

If the tag is not valid, the function returns `-1` and doesn’t do any further processing.

If the tag is valid, the ciphertext is decrypted and the plaintext is put into `m`. The length is equal to the length of the ciphertext.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
void crypto_aead_aegis256_keygen(unsigned char k[crypto_aead_aegis256_KEYBYTES]);
```

This is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_aead_aegis256_ABYTES`
* `crypto_aead_aegis256_KEYBYTES`
* `crypto_aead_aegis256_NPUBBYTES`

## Notes

* Unique nonces are required for each message.
* However, the nonce space is very large (256 bits). It can thus be randomly chosen with no risks of collision.
* It is also safe to only use a subset of the nonce space, for example by filling only 160 bits (20 bytes) with random data, and padding the rest with zeros. A 160 bit nonce already provides enough collision resistance for virtually all practical needs.
* AEGIS can also be used as a very fast MAC, by encrypting an empty message, and putting the actual message to be authenticated in the `ad` parameter, which can be up to 2^61 bytes long.
* However, it should *NOT* be used as a hash function. If the key is known, state collisions can be crafted.
* Unlike AES-GCM and Salsa/ChaChaPoly1305, it is believed to be impractical to find multiple AEGIS keys that successfully decrypt a given `(ad, ciphertext, tag)` tuple (*receiver-binding* game). However, this security property doesn’t hold true any more if the associated data inputs can be freely chosen in addition to the keys (*FROB* security). If commitment to the associated data is necessary, set the `ad` parameter to the hash of the associated data, using a collision-resistant and preimage-resistant hash function.
* AEGIS was added in libsodium version 1.0.19.

## See also

* [The AEGIS Family Of Authenticated Encryption Algorithms](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aegis-aead) - AEGIS specification
* [Reference implementations](https://github.com/cfrg/draft-irtf-cfrg-aegis-aead/tree/main/reference-implementations)
* [libaegis](https://github.com/jedisct1/libaegis) - A more extensive C library for AEGIS variants


# AEGIS-128L

AEGIS-128L is a modern AES-based cipher with unique properties making it easier and safer to use than common alternatives:

* 256-bit authentication tags, ensuring collision resistance within a given key; a tag can thus be used as a unique identifier for a message.
* It can safely encrypt a practically unlimited number of messages, without any practical limits on their lengths.
* It has a 128 bit nonce size, allowing random nonces to be safely used up to 2^48 messages for a single key.
* It has a better security margin than AES-GCM
* Leaking the state doesn’t leak the key
* It is assumed to be key-committing, preventing partitioning attacks affecting other ciphers when used with low-entropy keys such as passwords. Namely, it is difficult to find distinct keys and/or nonces that successfully verify the same `(ad, ciphertext, tag)` tuple.

AEGIS-128L is also extremely fast on recent CPUs with AES pipelines, with lower memory usage than AES-GCM.

However, on platforms without hardware AES support, it is slow and not guaranteed to be protected against side channels. In that scenario, XChaCha20-Poly1305 is a better choice.

Unlike all other ciphers in libsodium, AEGIS-128L uses a 128 bit key.

## Example (combined mode)

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4
#define ADDITIONAL_DATA (const unsigned char *) "123456"
#define ADDITIONAL_DATA_LEN 6

unsigned char nonce[crypto_aead_aegis128l_NPUBBYTES];
unsigned char key[crypto_aead_aegis128l_KEYBYTES];
unsigned char ciphertext[MESSAGE_LEN + crypto_aead_aegis128l_ABYTES];
unsigned long long ciphertext_len;

crypto_aead_aegis128l_keygen(key);
randombytes_buf(nonce, sizeof nonce);

crypto_aead_aegis128l_encrypt(ciphertext, &ciphertext_len,
                              MESSAGE, MESSAGE_LEN,
                              ADDITIONAL_DATA, ADDITIONAL_DATA_LEN,
                              NULL, nonce, key);

unsigned char decrypted[MESSAGE_LEN];
unsigned long long decrypted_len;
if (crypto_aead_aegis128l_decrypt(decrypted, &decrypted_len,
                                  NULL,
                                  ciphertext, ciphertext_len,
                                  ADDITIONAL_DATA,
                                  ADDITIONAL_DATA_LEN,
                                  nonce, key) != 0) {
    /* message forged! */
}
```

## Combined mode

In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want.

```c
int crypto_aead_aegis128l_encrypt(unsigned char *c,
                                  unsigned long long *clen_p,
                                  const unsigned char *m,
                                  unsigned long long mlen,
                                  const unsigned char *ad,
                                  unsigned long long adlen,
                                  const unsigned char *nsec,
                                  const unsigned char *npub,
                                  const unsigned char *k);
```

The `crypto_aead_aegis128l_encrypt()` function encrypts a message `m` whose length is `mlen` bytes using a secret key `k` (`crypto_aead_aegis128l_KEYBYTES` bytes) and public nonce `npub` (`crypto_aead_aegis128l_NPUBBYTES` bytes).

The encrypted message, as well as a tag authenticating both the confidential message `m` and `adlen` bytes of non-confidential data `ad`, are put into `c`.

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

At most `mlen + crypto_aead_aegis128l_ABYTES` bytes are put into `c`, and the actual number of bytes is stored into `clen` unless `clen` is a `NULL` pointer.

`nsec` is not used by this particular construction and should always be `NULL`.

The public nonce `npub` should never ever be reused with the same key. The recommended way to generate it is to use `randombytes_buf()` for the first message, and increment it for each subsequent message using the same key.

```c
int crypto_aead_aegis128l_decrypt(unsigned char *m,
                                  unsigned long long *mlen_p,
                                  unsigned char *nsec,
                                  const unsigned char *c,
                                  unsigned long long clen,
                                  const unsigned char *ad,
                                  unsigned long long adlen,
                                  const unsigned char *npub,
                                  const unsigned char *k);
```

The `crypto_aead_aegis128l_decrypt()` function verifies that the ciphertext `c` (as produced by `crypto_aead_aegis128l_encrypt()`) includes a valid tag using a secret key `k`, a public nonce `npub`, and additional data `ad` (`adlen` bytes).

`ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required.

`nsec` is not used by this particular construction and should always be `NULL`.

The function returns `-1` if the verification fails.

If the verification succeeds, the function returns `0`, puts the decrypted message into `m` and stores its actual number of bytes into `mlen` if `mlen` is not a `NULL` pointer.

At most `clen - crypto_aead_aegis128l_ABYTES` bytes will be put into `m`.

## Detached mode

Some applications may need to store the authentication tag and the encrypted message at different locations.

For this specific use case, “detached” variants of the functions above are available.

```c
int crypto_aead_aegis128l_encrypt_detached(unsigned char *c,
                                           unsigned char *mac,
                                           unsigned long long *maclen_p,
                                           const unsigned char *m,
                                           unsigned long long mlen,
                                           const unsigned char *ad,
                                           unsigned long long adlen,
                                           const unsigned char *nsec,
                                           const unsigned char *npub,
                                           const unsigned char *k);
```

The `crypto_aead_aegis128l_encrypt_detached()` function encrypts a message `m` with a key `k` and a nonce `npub`. It puts the resulting ciphertext, whose length is equal to the message, into `c`.

It also computes a tag that authenticates the ciphertext as well as optional, additional data `ad` of length `adlen`. This tag is put into `mac`, and its length is `crypto_aead_aegis128l_ABYTES` bytes.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
int crypto_aead_aegis128l_decrypt_detached(unsigned char *m,
                                           unsigned char *nsec,
                                           const unsigned char *c,
                                           unsigned long long clen,
                                           const unsigned char *mac,
                                           const unsigned char *ad,
                                           unsigned long long adlen,
                                           const unsigned char *npub,
                                           const unsigned char *k);
```

The `crypto_aead_aegis128l_decrypt_detached()` function verifies that the authentication tag `mac` is valid for the ciphertext `c` of length `clen` bytes, the key `k` , the nonce `npub` and optional, additional data `ad` of length `adlen` bytes.

If the tag is not valid, the function returns `-1` and doesn’t do any further processing.

If the tag is valid, the ciphertext is decrypted and the plaintext is put into `m`. The length is equal to the length of the ciphertext.

`nsec` is not used by this particular construction and should always be `NULL`.

```c
void crypto_aead_aegis128l_keygen(unsigned char k[crypto_aead_aegis128l_KEYBYTES]);
```

This is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_aead_aegis128l_ABYTES`
* `crypto_aead_aegis128l_KEYBYTES`
* `crypto_aead_aegis128l_NPUBBYTES`

## Notes

* The key size is 128 bits (16 bytes), unlike all other ciphers in this library.
* Unique nonces are required for each message.
* AEGIS can also be used as a very fast MAC, by encrypting an empty message, and putting the actual message to be authenticated in the `ad` parameter, which can be up to 2^61 bytes long.
* However, it should *NOT* be used as a hash function. If the key is known, state collisions can be crafted.
* Unlike AES-GCM and Salsa/ChaChaPoly1305, it is believed to be impractical to find multiple AEGIS keys that successfully decrypt a given `(ad, ciphertext, tag)` tuple (*receiver-binding* game). However, this security property doesn’t hold true any more if the associated data inputs can be freely chosen in addition to the keys (*FROB* security). If commitment to the associated data is necessary, set the `ad` parameter to the hash of the associated data, using a collision-resistant and preimage-resistant hash function.
* AEGIS was added in libsodium version 1.0.19.

## See also

* [The AEGIS Family Of Authenticated Encryption Algorithms](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aegis-aead) - AEGIS specification
* [Reference implementations](https://github.com/cfrg/draft-irtf-cfrg-aegis-aead/tree/main/reference-implementations)
* [libaegis](https://github.com/jedisct1/libaegis) - A more extensive C library for AEGIS variants


# AES256-GCM

## Warning

WARNING: Despite being the most popular AEAD construction due to its use in TLS, safely using AES-GCM in a different context is tricky.

No more than \~ 350 GB of input data should be encrypted with a given key. This is for \~ 16 KB messages – Actual figures vary according to message sizes.

In addition, nonces are short and repeated nonces would totally destroy the security of this scheme. Nonces should thus come from atomic counters, which can be difficult to set up in a distributed environment.

Unless you absolutely need AES-GCM, use AEGIS-256 (`crypto_aead_aegis256_*()`) instead. It doesn’t have any of these limitations.

Or, if you don’t need to authenticate additional data, just stick to `crypto_secretbox()`.

## Example (combined mode)

```c
#include <sodium.h>

#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4
#define ADDITIONAL_DATA (const unsigned char *) "123456"
#define ADDITIONAL_DATA_LEN 6

unsigned char nonce[crypto_aead_aes256gcm_NPUBBYTES];
unsigned char key[crypto_aead_aes256gcm_KEYBYTES];
unsigned char ciphertext[MESSAGE_LEN + crypto_aead_aes256gcm_ABYTES];
unsigned long long ciphertext_len;

sodium_init();
if (crypto_aead_aes256gcm_is_available() == 0) {
    abort(); /* Not available on this CPU */
}

crypto_aead_aes256gcm_keygen(key);
randombytes_buf(nonce, sizeof nonce);

crypto_aead_aes256gcm_encrypt(ciphertext, &ciphertext_len,
                              MESSAGE, MESSAGE_LEN,
                              ADDITIONAL_DATA, ADDITIONAL_DATA_LEN,
                              NULL, nonce, key);

unsigned char decrypted[MESSAGE_LEN];
unsigned long long decrypted_len;
if (ciphertext_len < crypto_aead_aes256gcm_ABYTES ||
    crypto_aead_aes256gcm_decrypt(decrypted, &decrypted_len,
                                  NULL,
                                  ciphertext, ciphertext_len,
                                  ADDITIONAL_DATA,
                                  ADDITIONAL_DATA_LEN,
                                  nonce, key) != 0) {
    /* message forged! */
}
```

## Purpose

This operation:

* Encrypts a message with a key and a nonce to keep it confidential
* Computes an authentication tag. This tag is used to make sure that the message, as well as optional, non-confidential (non-encrypted) data, haven’t been tampered with.

A typical use case for additional data is to store protocol-specific metadata about the message, such as its length and encoding.

It can also be used as a MAC, with an empty message.

Decryption will never be performed, even partially, before verification.

When supported by the CPU, AES-GCM is the fastest AEAD cipher available in this library.

## Limitations

The current implementation of this construction is hardware-accelerated and requires the Intel AES-NI extensions, or the ARM Crypto extensions.

Intel Westmere processors (introduced in 2010) and newer, as well as the vast majority of 64-bit ARM processors meet the requirements.

There are no plans to support non hardware-accelerated implementations of AES-GCM. This includes JavaScript and WebAssembly, where it can’t be implemented efficiently and securely. If portability is a concern, use ChaCha20-Poly1305 instead.

Before using the functions below, hardware support for AES can be checked with:

```c
int crypto_aead_aes256gcm_is_available(void);
```

The function returns `1` if the current CPU supports the AES256-GCM implementation, and `0` if it doesn’t.

The library must have been initialized with `sodium_init()` prior to calling this function.

## Combined mode

In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want.

```c
int crypto_aead_aes256gcm_encrypt(unsigned char *c,
                                  unsigned long long *clen_p,
                                  const unsigned char *m,
                                  unsigned long long mlen,
                                  const unsigned char *ad,
                                  unsigned long long adlen,
                                  const unsigned char *nsec,
                                  const unsigned char *npub,
                                  const unsigned char *k);
```

The function `crypto_aead_aes256gcm_encrypt()` encrypts a message `m` whose length is `mlen` bytes using a secret key `k` (`crypto_aead_aes256gcm_KEYBYTES` bytes) and a public nonce `npub` (`crypto_aead_aes256gcm_NPUBBYTES` bytes).

The encrypted message, as well as a tag authenticating both the confidential message `m` and `adlen` bytes of non-confidential data `ad`, are put into `c`.

`ad` can also be a `NULL` pointer if no additional data are required.

At most `mlen + crypto_aead_aes256gcm_ABYTES` bytes are put into `c`, and the actual number of bytes is stored into `clen` if `clen` is not a `NULL` pointer.

`nsec` is not used by this particular construction and should always be `NULL`.

The function always returns `0`.

The public nonce `npub` should never ever be reused with the same key. The recommended way to generate it is to use `randombytes_buf()` for the first message, and then to increment it for each subsequent message using the same key.

```c
int crypto_aead_aes256gcm_decrypt(unsigned char *m,
                                  unsigned long long *mlen_p,
                                  unsigned char *nsec,
                                  const unsigned char *c,
                                  unsigned long long clen,
                                  const unsigned char *ad,
                                  unsigned long long adlen,
                                  const unsigned char *npub,
                                  const unsigned char *k);
```

The function `crypto_aead_aes256gcm_decrypt()` verifies that the ciphertext `c` (as produced by `crypto_aead_aes256gcm_encrypt()`), includes a valid tag using a secret key `k`, a public nonce `npub`, and additional data `ad` (`adlen` bytes). `clen` is the ciphertext length in bytes with the authenticator, so it has to be at least `aead_aes256gcm_ABYTES`.

`ad` can be a `NULL` pointer if no additional data are required.

`nsec` is not used by this particular construction and should always be `NULL`.

The function returns `-1` if the verification fails.

If the verification succeeds, the function returns `0`, puts the decrypted message into `m` and stores its actual number of bytes into `mlen` if `mlen` is not a `NULL` pointer.

At most `clen - crypto_aead_aes256gcm_ABYTES` bytes will be put into `m`.

## Detached mode

Some applications may need to store the authentication tag and the encrypted message at different locations.

For this specific use case, “detached” variants of the functions above are available.

```c
int crypto_aead_aes256gcm_encrypt_detached(unsigned char *c,
                                           unsigned char *mac,
                                           unsigned long long *maclen_p,
                                           const unsigned char *m,
                                           unsigned long long mlen,
                                           const unsigned char *ad,
                                           unsigned long long adlen,
                                           const unsigned char *nsec,
                                           const unsigned char *npub,
                                           const unsigned char *k);
```

`crypto_aead_aes256gcm_encrypt_detached()` encrypts a message `m` whose length is `mlen` bytes using a secret key `k` (`crypto_aead_aes256gcm_KEYBYTES` bytes) and a public nonce `npub` (`crypto_aead_aes256gcm_NPUBBYTES` bytes).

The encrypted message in put into `c`. A tag authenticating both the confidential message `m` and `adlen` bytes of non-confidential data `ad` is put into `mac`.

`ad` can also be a `NULL` pointer if no additional data are required.

`crypto_aead_aes256gcm_ABYTES` bytes are put into `mac`, and the actual number of bytes required for verification is stored into `maclen_p`, unless `maclen_p` is `NULL` pointer.

`nsec` is not used by this particular construction and should always be `NULL`.

The function always returns `0`.

```c
int crypto_aead_aes256gcm_decrypt_detached(unsigned char *m,
                                           unsigned char *nsec,
                                           const unsigned char *c,
                                           unsigned long long clen,
                                           const unsigned char *mac,
                                           const unsigned char *ad,
                                           unsigned long long adlen,
                                           const unsigned char *npub,
                                           const unsigned char *k);
```

The function `crypto_aead_aes256gcm_decrypt_detached()` verifies that the tag `mac` is valid for the ciphertext `c` using a secret key `k`, a public nonce `npub`, and additional data `ad` (`adlen` bytes).

`clen` is the ciphertext length in bytes.

`ad` can be a `NULL` pointer if no additional data are required.

`nsec` is not used by this particular construction and should always be `NULL`.

The function returns `-1` if the verification fails.

If the verification succeeds, the function returns `0`, and puts the decrypted message into `m`, whose length is equal to the length of the ciphertext.

```c
void crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_aead_aes256gcm_KEYBYTES`
* `crypto_aead_aes256gcm_NPUBBYTES`
* `crypto_aead_aes256gcm_ABYTES`

## Notes

The nonce is 96 bits long. In order to prevent nonce reuse, if a key is being reused, it is recommended to increment the previous nonce instead of generating a random nonce for each message.

To prevent nonce reuse in a client-server protocol, either use different keys for each direction, or make sure that a bit is masked in one direction, and set in the other. The `crypto_kx_*()` API can be used to do so.

When using AES-GCM, it is also recommended to switch to a new key before reaching \~ 350 GB encrypted with the same key. If frequent rekeying is not an option, use (X)ChaCha20-Poly1305 instead.


# AES256-GCM with precomputation

Applications that encrypt several messages using the same key can gain a little speed by expanding the AES key only once, via the precalculation interface.

```c
int crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_,
                                   const unsigned char *k);
```

The `crypto_aead_aes256gcm_beforenm()` function initializes a context `ctx` by expanding the key `k` and always returns `0`.

A 16 bytes alignment is required for the address of `ctx`. The size of this value can be obtained using `sizeof(crypto_aead_aes256gcm_state)`, or `crypto_aead_aes256gcm_statebytes()`.

## Combined mode with precalculation

```c
int crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c,
                                          unsigned long long *clen_p,
                                          const unsigned char *m,
                                          unsigned long long mlen,
                                          const unsigned char *ad,
                                          unsigned long long adlen,
                                          const unsigned char *nsec,
                                          const unsigned char *npub,
                                          const crypto_aead_aes256gcm_state *ctx_);
```

```c
int crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m,
                                          unsigned long long *mlen_p,
                                          unsigned char *nsec,
                                          const unsigned char *c,
                                          unsigned long long clen,
                                          const unsigned char *ad,
                                          unsigned long long adlen,
                                          const unsigned char *npub,
                                          const crypto_aead_aes256gcm_state *ctx_);
```

The `crypto_aead_aes256gcm_encrypt_afternm()` and `crypto_aead_aes256gcm_decrypt_afternm()` functions are identical to `crypto_aead_aes256gcm_encrypt()` and `crypto_aead_aes256gcm_decrypt()`, but accept a previously initialized context `ctx` instead of a key.

## Detached mode with precalculation

```c
int crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c,
                                                   unsigned char *mac,
                                                   unsigned long long *maclen_p,
                                                   const unsigned char *m,
                                                   unsigned long long mlen,
                                                   const unsigned char *ad,
                                                   unsigned long long adlen,
                                                   const unsigned char *nsec,
                                                   const unsigned char *npub,
                                                   const crypto_aead_aes256gcm_state *ctx_);
```

```c
int crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m,
                                                   unsigned char *nsec,
                                                   const unsigned char *c,
                                                   unsigned long long clen,
                                                   const unsigned char *mac,
                                                   const unsigned char *ad,
                                                   unsigned long long adlen,
                                                   const unsigned char *npub,
                                                   const crypto_aead_aes256gcm_state *ctx_)
```

The `crypto_aead_aes256gcm_encrypt_detached_afternm()` and `crypto_aead_aes256gcm_decrypt_detached_afternm()` functions are identical to `crypto_aead_aes256gcm_encrypt_detached()` and `crypto_aead_aes256gcm_decrypt_detached()`, but accept a previously initialized context `ctx` instead of a key.

## Constants

* `crypto_aead_aes256gcm_KEYBYTES`
* `crypto_aead_aes256gcm_NPUBBYTES`
* `crypto_aead_aes256gcm_ABYTES`

## Data types

* `crypto_aead_aes256gcm_state`

## Notes

The nonce is 96 bits long. In order to prevent nonce reuse, if a key is being reused, it is recommended to increment the previous nonce instead of generating a random nonce for each message. To prevent nonce reuse in a client-server protocol, either use different keys for each direction, or make sure that a bit is masked in one direction, and set in the other.

When using AES-GCM, it is also recommended to switch to a new key before reaching \~350 GB encrypted with the same key. If frequent rekeying is not an option, use (X)ChaCha20-Poly1305 instead.


# IP address encryption

The `crypto_ipcrypt` API provides efficient, secure encryption of IP addresses (IPv4 and IPv6) for privacy-preserving storage, logging, and analytics.

Unlike truncation (which irreversibly destroys data) or hashing (which prevents decryption), ipcrypt provides reversible encryption with well-defined security properties while maintaining operational utility.

## Use cases

* Privacy-preserving logs: Encrypt IP addresses in web server access logs, DNS query logs, or application logs while retaining the ability to decrypt when needed.
* Rate limiting and abuse detection: Count requests per client, detect brute-force attempts, or implement request throttling using deterministic encryption.
* Analytics without exposure: Count unique visitors, analyze geographic traffic patterns, or build user behavior analytics without revealing actual addresses.
* Data sharing: Share network data with security researchers, cloud providers, or partner organizations without exposing actual client addresses.
* Database storage: Store encrypted IP addresses in databases with indexes on the encrypted values (deterministic mode). Query, group, and sort by client without exposing actual addresses.

## Variants

ipcrypt provides four variants with different security and format trade-offs:

| Variant                          | Key      | Output   | Properties                                                |
| -------------------------------- | -------- | -------- | --------------------------------------------------------- |
| Deterministic                    | 16 bytes | 16 bytes | Same input always produces same output; format-preserving |
| ND (non-deterministic)           | 16 bytes | 24 bytes | Different output each time; 8-byte random tweak           |
| NDX (extended non-deterministic) | 32 bytes | 32 bytes | Different output each time; 16-byte random tweak          |
| PFX (prefix-preserving)          | 32 bytes | 16 bytes | Preserves network prefix relationships                    |

### Choosing the right variant

Use deterministic mode for rate limiting, deduplication, unique visitor counting, database indexing, or anywhere you need to identify the same address across multiple observations. Fastest option. Trade-off: identical inputs produce identical outputs.

Use ND mode when sharing data externally or when preventing correlation across observations matters. Each encryption produces a different ciphertext, so an observer cannot tell if two records came from the same address. Good for log archival, third-party analytics, or data exports.

Use NDX mode for maximum security when you need the non-deterministic property and will perform very large numbers of encryptions (billions) with the same key. The larger tweak space provides a higher birthday bound.

Use PFX mode for network analysis applications: DDoS research, traffic studies, packet trace anonymization, or any scenario where understanding which addresses belong to the same network matters more than hiding that relationship.

## IP address representation

All variants operate on 16-byte values. IPv4 addresses are represented as IPv4-mapped IPv6 addresses:

* IPv6: Used directly (16 bytes in network byte order)
* IPv4: Encoded as `::ffff:a.b.c.d` (10 zero bytes, `0xff 0xff`, then 4 IPv4 bytes)

For example, `192.0.2.1` is represented as:

```
00 00 00 00 00 00 00 00 00 00 ff ff c0 00 02 01
```

## Converting IP addresses

The `sodium_ip2bin()` and `sodium_bin2ip()` functions convert between string and binary representations.

```c
int sodium_ip2bin(unsigned char bin[16], const char *ip, size_t ip_len);
```

The `sodium_ip2bin()` function parses the IP address string `ip` of length `ip_len` and writes the 16-byte binary representation to `bin`.

It accepts both IPv4 (e.g., `"192.0.2.1"`) and IPv6 (e.g., `"2001:db8::1"`) addresses. IPv4 addresses are automatically converted to IPv4-mapped format. IPv6 addresses with zone identifiers (e.g., `"fe80::1%eth0"`) are also supported.

Returns `0` on success, `-1` on error.

```c
char *sodium_bin2ip(char *ip, size_t ip_maxlen, const unsigned char bin[16]);
```

The `sodium_bin2ip()` function converts the 16-byte binary address `bin` to a string and writes it to `ip`.

The buffer `ip` must be at least 16 bytes for IPv4 addresses or 46 bytes for IPv6 addresses. IPv4-mapped addresses are automatically converted to dotted-decimal notation.

Returns a pointer to `ip` on success, `NULL` on error.

## Deterministic encryption

The simplest variant encrypts an IP address to a 16-byte ciphertext. The same address with the same key always produces the same ciphertext.

```c
void crypto_ipcrypt_encrypt(unsigned char *out,
                            const unsigned char *in,
                            const unsigned char *k);
```

```c
void crypto_ipcrypt_decrypt(unsigned char *out,
                            const unsigned char *in,
                            const unsigned char *k);
```

The `crypto_ipcrypt_encrypt()` function encrypts a 16-byte address `in` using the key `k` and writes the result to `out`.

The `crypto_ipcrypt_decrypt()` function reverses the encryption.

```c
void crypto_ipcrypt_keygen(unsigned char *k);
```

The `crypto_ipcrypt_keygen()` function generates a random 16-byte key.

### Example (deterministic)

```c
#include <sodium.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    unsigned char key[crypto_ipcrypt_KEYBYTES];
    unsigned char addr[crypto_ipcrypt_BYTES];
    unsigned char encrypted[crypto_ipcrypt_BYTES];
    unsigned char decrypted[crypto_ipcrypt_BYTES];
    char ip_str[46];

    if (sodium_init() < 0) {
        return 1;
    }

    /* Generate a random key */
    crypto_ipcrypt_keygen(key);

    /* Parse an IP address */
    if (sodium_ip2bin(addr, "192.0.2.1", strlen("192.0.2.1")) != 0) {
        return 1;
    }

    /* Encrypt */
    crypto_ipcrypt_encrypt(encrypted, addr, key);

    /* The encrypted address can be displayed as an IP */
    sodium_bin2ip(ip_str, sizeof ip_str, encrypted);
    printf("Encrypted: %s\n", ip_str);

    /* Decrypt */
    crypto_ipcrypt_decrypt(decrypted, encrypted, key);

    /* Convert back to string */
    sodium_bin2ip(ip_str, sizeof ip_str, decrypted);
    printf("Decrypted: %s\n", ip_str);  /* "192.0.2.1" */

    return 0;
}
```

### When to use deterministic mode

Use deterministic encryption when:

* You need to identify duplicate addresses (rate limiting, deduplication)
* Format preservation matters (output is also a valid IP representation)
* Storage space is constrained

The trade-off is that identical addresses produce identical ciphertexts, allowing correlation analysis. An attacker who knows a specific address was encrypted can verify this by encrypting it with a guessed key.

## Non-deterministic encryption (ND)

The ND variant uses a random 8-byte tweak, ensuring the same address produces different ciphertexts each time.

```c
void crypto_ipcrypt_nd_encrypt(unsigned char *out,
                               const unsigned char *in,
                               const unsigned char *t,
                               const unsigned char *k);
```

```c
void crypto_ipcrypt_nd_decrypt(unsigned char *out,
                               const unsigned char *in,
                               const unsigned char *k);
```

```c
void crypto_ipcrypt_nd_keygen(unsigned char *k);
```

The `crypto_ipcrypt_nd_encrypt()` function encrypts a 16-byte address `in` using the key `k` and tweak `t`, writing the 24-byte result (tweak prepended to ciphertext) to `out`.

The `crypto_ipcrypt_nd_decrypt()` function decrypts a 24-byte ciphertext `in` (which includes the tweak) and writes the 16-byte address to `out`. No separate tweak parameter is needed because the tweak is extracted from the ciphertext.

The `crypto_ipcrypt_nd_keygen()` function generates a random 16-byte key.

### Example (ND)

```c
unsigned char key[crypto_ipcrypt_ND_KEYBYTES];
unsigned char tweak[crypto_ipcrypt_ND_TWEAKBYTES];
unsigned char addr[crypto_ipcrypt_ND_INPUTBYTES];
unsigned char encrypted[crypto_ipcrypt_ND_OUTPUTBYTES];
unsigned char decrypted[crypto_ipcrypt_ND_INPUTBYTES];
char ip_str[46];

crypto_ipcrypt_nd_keygen(key);
randombytes_buf(tweak, sizeof tweak);

if (sodium_ip2bin(addr, "192.0.2.1", strlen("192.0.2.1")) != 0) {
    /* handle error */
}

crypto_ipcrypt_nd_encrypt(encrypted, addr, tweak, key);
crypto_ipcrypt_nd_decrypt(decrypted, encrypted, key);

sodium_bin2ip(ip_str, sizeof ip_str, decrypted);  /* "192.0.2.1" */
```

### When to use ND mode

Use ND encryption when:

* Preventing correlation analysis is important
* 24-byte output is acceptable
* You’ll perform fewer than \~4 billion encryptions with the same key (birthday bound on 64-bit tweaks)

## Extended non-deterministic encryption (NDX)

The NDX variant provides larger tweaks and a larger key for higher security margins.

```c
void crypto_ipcrypt_ndx_encrypt(unsigned char *out,
                                const unsigned char *in,
                                const unsigned char *t,
                                const unsigned char *k);
```

```c
void crypto_ipcrypt_ndx_decrypt(unsigned char *out,
                                const unsigned char *in,
                                const unsigned char *k);
```

The `crypto_ipcrypt_ndx_encrypt()` function encrypts a 16-byte address `in` using the 32-byte key `k` and 16-byte tweak `t`, writing the 32-byte result to `out`.

The `crypto_ipcrypt_ndx_decrypt()` function decrypts a 32-byte ciphertext.

```c
void crypto_ipcrypt_ndx_keygen(unsigned char *k);
```

The `crypto_ipcrypt_ndx_keygen()` function generates a random 32-byte key.

### Example (NDX)

```c
unsigned char key[crypto_ipcrypt_NDX_KEYBYTES];
unsigned char tweak[crypto_ipcrypt_NDX_TWEAKBYTES];
unsigned char addr[crypto_ipcrypt_NDX_INPUTBYTES];
unsigned char encrypted[crypto_ipcrypt_NDX_OUTPUTBYTES];
unsigned char decrypted[crypto_ipcrypt_NDX_INPUTBYTES];
char ip_str[46];

crypto_ipcrypt_ndx_keygen(key);
randombytes_buf(tweak, sizeof tweak);

if (sodium_ip2bin(addr, "2001:db8::1", strlen("2001:db8::1")) != 0) {
    /* handle error */
}

crypto_ipcrypt_ndx_encrypt(encrypted, addr, tweak, key);
crypto_ipcrypt_ndx_decrypt(decrypted, encrypted, key);

sodium_bin2ip(ip_str, sizeof ip_str, decrypted);  /* "2001:db8::1" */
```

### When to use NDX mode

Use NDX encryption when:

* Maximum security is required
* 32-byte output is acceptable
* You want practically unlimited encryptions per key (\~2^64 birthday bound)

## Prefix-preserving encryption (PFX)

The PFX variant preserves network prefix relationships: addresses sharing a common prefix will have ciphertexts sharing a corresponding (different) prefix.

```c
void crypto_ipcrypt_pfx_encrypt(unsigned char *out,
                                const unsigned char *in,
                                const unsigned char *k);
```

```c
void crypto_ipcrypt_pfx_decrypt(unsigned char *out,
                                const unsigned char *in,
                                const unsigned char *k);
```

The `crypto_ipcrypt_pfx_encrypt()` function encrypts a 16-byte address `in` using the 32-byte key `k` and writes the 16-byte result to `out`.

The address family is preserved: IPv4 addresses encrypt to IPv4 addresses.

```c
void crypto_ipcrypt_pfx_keygen(unsigned char *k);
```

The `crypto_ipcrypt_pfx_keygen()` function generates a random 32-byte key.

### Example (PFX)

```c
unsigned char key[crypto_ipcrypt_PFX_KEYBYTES];
unsigned char addr1[crypto_ipcrypt_PFX_BYTES];
unsigned char addr2[crypto_ipcrypt_PFX_BYTES];
unsigned char enc1[crypto_ipcrypt_PFX_BYTES];
unsigned char enc2[crypto_ipcrypt_PFX_BYTES];
char ip_str[46];

crypto_ipcrypt_pfx_keygen(key);

/* Encrypt two addresses in the same /24 */
if (sodium_ip2bin(addr1, "10.0.0.1", strlen("10.0.0.1")) != 0) {
    /* handle error */
}
if (sodium_ip2bin(addr2, "10.0.0.100", strlen("10.0.0.100")) != 0) {
    /* handle error */
}

crypto_ipcrypt_pfx_encrypt(enc1, addr1, key);
crypto_ipcrypt_pfx_encrypt(enc2, addr2, key);

sodium_bin2ip(ip_str, sizeof ip_str, enc1);
printf("10.0.0.1   -> %s\n", ip_str);  /* e.g., "79.55.98.17" */

sodium_bin2ip(ip_str, sizeof ip_str, enc2);
printf("10.0.0.100 -> %s\n", ip_str);  /* e.g., "79.55.98.127" - same /24 */
```

### When to use PFX mode

Use PFX encryption when you need to preserve network relationships for analysis while protecting individual addresses:

* Network research: Share measurement data with collaborators while preserving routing paths, AS relationships, and network topology. Researchers can study BGP behavior or CDN architectures without exposing actual network identities.
* DDoS attack analysis: Identify whether attacks originate from the same /24 or /16 block, spot botnet clustering patterns, and share attack data with other organizations for collaborative defense.
* PCAP and NetFlow anonymization: Anonymize packet captures and flow records while enabling analysis of traffic patterns between subnets.
* Traffic analysis: Analyze customer traffic patterns, peering relationships, and routing efficiency without exposing actual networks.
* Multi-organization threat intelligence: Share network-level threat indicators with industry partners using the same key, enabling correlation across collective infrastructure.

### Example: Analyzing attack origins by subnet

```c
#include <sodium.h>
#include <stdio.h>

/* Anonymize attack source IPs while preserving subnet relationships */
void analyze_attack_sources(const char source_ips, size_t count,
                             const unsigned char *key)
{
    unsigned char addr[crypto_ipcrypt_PFX_BYTES];
    unsigned char encrypted[crypto_ipcrypt_PFX_BYTES];
    char enc_str[46];

    printf("Attack sources (encrypted, preserving /24 prefixes):\n");
    for (size_t i = 0; i < count; i++) {
        if (sodium_ip2bin(addr, source_ips[i], strlen(source_ips[i])) != 0) continue;

        crypto_ipcrypt_pfx_encrypt(encrypted, addr, key);
        sodium_bin2ip(enc_str, sizeof enc_str, encrypted);

        /* Analysts can see which attacks come from the same subnet */
        printf("  %s\n", enc_str);
    }
}
```

### Trade-offs

PFX mode reveals network topology: addresses in the same subnet produce ciphertexts in a corresponding (encrypted) subnet. This is intentional and useful for the above applications, but means an observer can learn:

* Which addresses share a common prefix (are in the same network)
* The hierarchical relationship between addresses
* Approximate network sizes

If hiding network relationships is required, use deterministic or non-deterministic modes instead.

## Algorithm details

* Deterministic: Single-block AES-128
* ND: KIASU-BC (tweakable AES-128 with 64-bit tweak)
* NDX: AES-XTS (IEEE 1619-2007) with 128-bit tweak
* PFX: Bit-by-bit format-preserving encryption using XOR of two AES-128 permutations

All implementations use hardware acceleration when available (AES-NI on x86-64, ARM Crypto extensions on ARM).

## Security considerations

What ipcrypt protects against:

* Unauthorized parties learning original addresses without the key
* Statistical analysis revealing traffic patterns (non-deterministic modes)
* Brute-force attacks on the address space (128-bit AES security)

What ipcrypt does not protect against:

* Active attackers modifying, reordering, or removing encrypted addresses
* Correlation of identical addresses (deterministic mode)
* Traffic analysis based on volume and timing metadata

Key management:

* Generate keys using `crypto_ipcrypt_keygen()`, `crypto_ipcrypt_nd_keygen()`, `crypto_ipcrypt_ndx_keygen()`, or `crypto_ipcrypt_pfx_keygen()`
* Never reuse keys across different variants; use HKDF to derive separate keys if needed
* Rotate keys based on usage volume and security requirements

Tweak generation (ND/NDX modes):

* Tweaks can be randomly generated using `randombytes_buf`.

## Why encryption instead of truncation?

Truncating IP addresses (zeroing out the last octet or bits) is a common but flawed approach to anonymization.

Truncation doesn’t provide meaningful anonymity: subnet size doesn’t correlate with user anonymity. A `/24` network might serve only one small company with a handful of employees, making individual identification trivial through WHOIS queries. Even after truncation, the retained prefix reveals the Internet Service Provider, geographic location (often down to city level), and organization.

IPv6 makes truncation nearly useless: unlike IPv4, IPv6 has no standardized truncation boundaries. A household might receive an entire `/48` allocation, trillions of addresses going to one router. There’s no consistent “last octet” to remove.

Truncated IPs remain personal data: under GDPR and similar regulations, truncated addresses combined with timestamps, user agents, and request paths often create unique fingerprints that identify individuals.

Truncation is irreversible: once truncated, legitimate needs cannot be satisfied. Encryption preserves the ability to recover the original address when needed. When irreversibility is desired, simply wipe the key. This provides the same outcome as truncation while allowing you to choose when that transition happens. Keys can also be rotated on a schedule so that older data becomes permanently unrecoverable after the retention period.

## Constants

* `crypto_ipcrypt_BYTES`
* `crypto_ipcrypt_KEYBYTES`
* `crypto_ipcrypt_ND_KEYBYTES`
* `crypto_ipcrypt_ND_TWEAKBYTES`
* `crypto_ipcrypt_ND_INPUTBYTES`
* `crypto_ipcrypt_ND_OUTPUTBYTES`
* `crypto_ipcrypt_NDX_KEYBYTES`
* `crypto_ipcrypt_NDX_TWEAKBYTES`
* `crypto_ipcrypt_NDX_INPUTBYTES`
* `crypto_ipcrypt_NDX_OUTPUTBYTES`
* `crypto_ipcrypt_PFX_KEYBYTES`
* `crypto_ipcrypt_PFX_BYTES`

## Notes

This API was introduced in libsodium 1.0.21.

## See also

* [ipcrypt specification](https://ipcrypt-std.github.io/)
* [IETF draft](https://datatracker.ietf.org/doc/draft-denis-ipcrypt/)


# Public-key cryptography

*Public-key cryptography* refers to cryptographic systems that require two different keys, linked together by some one-way mathematical relationship, which depends on the algorithm used. The private key cannot be recovered from the public key.


# Authenticated encryption

## Example

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4
#define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN)

unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES];
unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(alice_publickey, alice_secretkey);

unsigned char bob_publickey[crypto_box_PUBLICKEYBYTES];
unsigned char bob_secretkey[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(bob_publickey, bob_secretkey);

unsigned char nonce[crypto_box_NONCEBYTES];
unsigned char ciphertext[CIPHERTEXT_LEN];
randombytes_buf(nonce, sizeof nonce);
if (crypto_box_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce,
                    bob_publickey, alice_secretkey) != 0) {
    /* error */
}

unsigned char decrypted[MESSAGE_LEN];
if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce,
                         alice_publickey, bob_secretkey) != 0) {
    /* message for Bob pretending to be from Alice has been forged! */
}
```

## Purpose

Using public-key authenticated encryption, Alice can encrypt a confidential message specifically for Bob, using Bob’s public key.

Based on Bob’s public key, Alice can compute a shared secret key. Using Alice’s public key and his secret key, Bob can compute the same shared secret key. That shared secret key can be used to verify that the encrypted message was not tampered with before decryption.

To send messages to Bob, Alice only needs Bob’s public key. Bob should never share his secret key, even with Alice.

For verification and decryption, Bob only needs Alice’s public key, the nonce, and the ciphertext. Alice should never share her secret key either, even with Bob.

Bob can reply to Alice using the same system without needing to generate a distinct key pair.

The nonce doesn’t have to be confidential, but it should be used with just one invocation of `crypto_box_easy()` for a particular pair of public and secret keys.

One easy way to generate a nonce is to use `randombytes_buf()`. Considering the size of the nonce, the risk of a random collision is negligible.

For some applications, if you wish to use nonces to detect missing messages or to ignore replayed messages, it is also acceptable to use a simple incrementing counter as a nonce. However, you must ensure that the same value is never reused. Be careful as you may have multiple threads or even hosts generating messages using the same key pairs. A better alternative is to use the `crypto_secretstream()` API.

As stated above, senders can decrypt their own messages and compute a valid authentication tag for any messages encrypted with a given shared secret key. This is generally not an issue for online protocols. If this is not acceptable, then check out the Sealed Boxes and [Key encapsulation](https://github.com/jedisct1/libsodium-doc/blob/master/public-key_cryptography/key_encapsulation.md) sections of the documentation.

## Key pair generation

```c
int crypto_box_keypair(unsigned char *pk, unsigned char *sk);
```

The `crypto_box_keypair()` function randomly generates a secret key and the corresponding public key. The public key is put into `pk` (`crypto_box_PUBLICKEYBYTES` bytes) and the secret key into `sk` (`crypto_box_SECRETKEYBYTES` bytes).

```c
int crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk,
                            const unsigned char *seed);
```

Using `crypto_box_seed_keypair()`, the key pair can also be deterministically derived from a single key `seed` (`crypto_box_SEEDBYTES` bytes).

```c
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
```

In addition, `crypto_scalarmult_base()` can be used to compute the public key given a secret key previously generated with `crypto_box_keypair()`:

```c
unsigned char pk[crypto_box_PUBLICKEYBYTES];
crypto_scalarmult_base(pk, sk);
```

## Combined mode

In combined mode, the authentication tag and encrypted message are stored together. This is usually what you want.

```c
int crypto_box_easy(unsigned char *c, const unsigned char *m,
                    unsigned long long mlen, const unsigned char *n,
                    const unsigned char *pk, const unsigned char *sk);
```

The `crypto_box_easy()` function encrypts a message `m`, whose length is `mlen` bytes, using the recipient’s public key `pk`, the sender’s secret key `sk`, and a nonce `n`.

`n` should be `crypto_box_NONCEBYTES` bytes.

`c` should be at least `crypto_box_MACBYTES + mlen` bytes long.

This function writes the authentication tag, whose length is `crypto_box_MACBYTES` bytes, in `c`, immediately followed by the encrypted message, whose length is the same as the plaintext `mlen`.

`c` and `m` can overlap, making in-place encryption possible. However, do not forget that `crypto_box_MACBYTES` extra bytes are required to prepend the tag.

```c
int crypto_box_open_easy(unsigned char *m, const unsigned char *c,
                         unsigned long long clen, const unsigned char *n,
                         const unsigned char *pk, const unsigned char *sk);
```

The `crypto_box_open_easy()` function verifies and decrypts a ciphertext produced by `crypto_box_easy()`.

`c` is a pointer to an authentication tag and encrypted message combination, as produced by `crypto_box_easy()`. `clen` is the length of this authentication tag and encrypted message combination. Put differently, `clen` is the number of bytes written by `crypto_box_easy()`, which is `crypto_box_MACBYTES` + the length of the message.

The nonce `n` must match the nonce used to encrypt and authenticate the message.

`pk` is the public key of the sender that encrypted the message. `sk` is the secret key of the recipient that is willing to verify and decrypt it.

The function returns `-1` if the verification fails and `0` on success. On success, the decrypted message is stored into `m`.

`m` and `c` can overlap, making in-place decryption possible.

## Detached mode

Some applications may need to store the authentication tag and encrypted message at different locations.

For this use case, “detached” variants of the functions above are available.

```c
int crypto_box_detached(unsigned char *c, unsigned char *mac,
                        const unsigned char *m,
                        unsigned long long mlen,
                        const unsigned char *n,
                        const unsigned char *pk,
                        const unsigned char *sk);
```

This function encrypts a message `m` of length `mlen` using a nonce `n` and a secret key `sk` for a recipient whose public key is `pk`. The encrypted message is put into `c`.

Exactly `mlen` bytes will be put into `c` since this function does not prepend the authentication tag.

The tag, whose size is `crypto_box_MACBYTES` bytes, will be put into `mac`.

```c
int crypto_box_open_detached(unsigned char *m,
                             const unsigned char *c,
                             const unsigned char *mac,
                             unsigned long long clen,
                             const unsigned char *n,
                             const unsigned char *pk,
                             const unsigned char *sk);
```

The `crypto_box_open_detached()` function verifies and decrypts an encrypted message `c`, whose length is `clen`, using the recipient’s secret key `sk` and the sender’s public key `pk`.

`clen` doesn’t include the tag, so this length is the same as the plaintext.

The plaintext is put into `m` after verifying that `mac` is a valid authentication tag for this ciphertext with the given nonce `n` and key `k`.

The function returns `-1` if the verification fails and `0` on success.

## Precalculation interface

Applications that send several messages to the same recipient or receive several messages from the same sender can improve performance by calculating the shared key only once and reusing it in subsequent operations.

```c
int crypto_box_beforenm(unsigned char *k, const unsigned char *pk,
                        const unsigned char *sk);
```

The `crypto_box_beforenm()` function computes a shared secret key given a public key `pk` and a secret key `sk` and puts it into `k` (`crypto_box_BEFORENMBYTES` bytes).

```c
int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m,
                            unsigned long long mlen, const unsigned char *n,
                            const unsigned char *k);

int crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c,
                                 unsigned long long clen, const unsigned char *n,
                                 const unsigned char *k);

int crypto_box_detached_afternm(unsigned char *c, unsigned char *mac,
                                const unsigned char *m, unsigned long long mlen,
                                const unsigned char *n, const unsigned char *k);

int crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c,
                                     const unsigned char *mac,
                                     unsigned long long clen, const unsigned char *n,
                                     const unsigned char *k);
```

The `_afternm` variants of the previously described functions accept a precalculated shared secret key `k` instead of a key pair.

Like any secret key, a precalculated shared key should be wiped from memory (for example, using `sodium_memzero()`) as soon as it is not needed anymore.

`c` and `m` can overlap, making in-place encryption possible. However, do not forget that `crypto_box_MACBYTES` extra bytes are required to prepend the tag.

## Constants

* `crypto_box_PUBLICKEYBYTES`
* `crypto_box_SECRETKEYBYTES`
* `crypto_box_MACBYTES`
* `crypto_box_NONCEBYTES`
* `crypto_box_SEEDBYTES`
* `crypto_box_BEFORENMBYTES`

## Algorithm details

* Key exchange: X25519
* Encryption: XSalsa20
* Authentication: Poly1305

## Notes

The original NaCl `crypto_box` API is also supported, albeit not recommended.

`crypto_box()` takes a pointer to 32 bytes before the message and stores the ciphertext 16 bytes after the destination pointer, with the first 16 bytes being overwritten with zeros. `crypto_box_open()` takes a pointer to 16 bytes before the ciphertext and stores the message 32 bytes after the destination pointer, overwriting the first 32 bytes with zeros.

The `_easy` and `_detached` APIs are faster and improve usability by not requiring padding, copying, or tricky pointer arithmetic.


# Public-key signatures

## Example (combined mode)

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4

unsigned char pk[crypto_sign_PUBLICKEYBYTES];
unsigned char sk[crypto_sign_SECRETKEYBYTES];
crypto_sign_keypair(pk, sk);

unsigned char signed_message[crypto_sign_BYTES + MESSAGE_LEN];
unsigned long long signed_message_len;

crypto_sign(signed_message, &signed_message_len,
            MESSAGE, MESSAGE_LEN, sk);

unsigned char unsigned_message[MESSAGE_LEN];
unsigned long long unsigned_message_len;
if (crypto_sign_open(unsigned_message, &unsigned_message_len,
                     signed_message, signed_message_len, pk) != 0) {
    /* incorrect signature! */
}
```

### Example (detached mode)

```c
#define MESSAGE (const unsigned char *) "test"
#define MESSAGE_LEN 4

unsigned char pk[crypto_sign_PUBLICKEYBYTES];
unsigned char sk[crypto_sign_SECRETKEYBYTES];
crypto_sign_keypair(pk, sk);

unsigned char sig[crypto_sign_BYTES];

crypto_sign_detached(sig, NULL, MESSAGE, MESSAGE_LEN, sk);

if (crypto_sign_verify_detached(sig, MESSAGE, MESSAGE_LEN, pk) != 0) {
    /* incorrect signature! */
}
```

### Example (multi-part message)

```c
#define MESSAGE_PART1 \
    ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_PART1_LEN 22

#define MESSAGE_PART2 \
    ((const unsigned char *) "is longer than expected")
#define MESSAGE_PART2_LEN 23

unsigned char pk[crypto_sign_PUBLICKEYBYTES];
unsigned char sk[crypto_sign_SECRETKEYBYTES];
crypto_sign_keypair(pk, sk);

crypto_sign_state state;
unsigned char sig[crypto_sign_BYTES];

/* signature creation */

crypto_sign_init(&state)
crypto_sign_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN);
crypto_sign_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN);
crypto_sign_final_create(&state, sig, NULL, sk);

/* signature verification */

crypto_sign_init(&state)
crypto_sign_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN);
crypto_sign_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN);
if (crypto_sign_final_verify(&state, sig, pk) != 0) {
    /* message forged! */
}
```

## Purpose

In this system, a signer generates a key pair consisting of:

* A secret key, which you can use to append a signature to any number of messages.
* A public key, which anybody can use to verify that the signature appended to a message was issued by the creator of the public key.

Verifiers need to already know and ultimately trust a public key before messages signed using it can be verified.

*Warning:* this is different from authenticated encryption. Appending a signature does not change the representation of the message itself.

## Key pair generation

```c
int crypto_sign_keypair(unsigned char *pk, unsigned char *sk);
```

The `crypto_sign_keypair()` function randomly generates a secret key and a corresponding public key. The public key is put into `pk` (`crypto_sign_PUBLICKEYBYTES` bytes) and the secret key into `sk` (`crypto_sign_SECRETKEYBYTES` bytes).

```c
int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk,
                             const unsigned char *seed);
```

Using `crypto_sign_seed_keypair()`, the key pair can also be deterministically derived from a single key `seed` (`crypto_sign_SEEDBYTES` bytes).

## Combined mode

```c
int crypto_sign(unsigned char *sm, unsigned long long *smlen_p,
                const unsigned char *m, unsigned long long mlen,
                const unsigned char *sk);
```

The `crypto_sign()` function prepends a signature to a message `m`, whose length is `mlen` bytes, using the secret key `sk`.

The signed message, which includes the signature plus an unaltered copy of the message, is put into `sm` and is `crypto_sign_BYTES + mlen` bytes long.

If `smlen` is not a `NULL` pointer, then the actual length of the signed message is stored in `smlen`.

```c
int crypto_sign_open(unsigned char *m, unsigned long long *mlen_p,
                     const unsigned char *sm, unsigned long long smlen,
                     const unsigned char *pk);
```

The `crypto_sign_open()` function checks that the signed message `sm`, whose length is `smlen` bytes, has a valid signature for the public key `pk`.

If the signature isn’t valid, then the function returns `-1`.

On success, it puts the message without the signature into `m`, stores its length in `mlen` if `mlen` is not a `NULL` pointer, and returns `0`.

## Detached mode

In detached mode, the signature is stored without attaching a copy of the original message to it.

```c
int crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p,
                         const unsigned char *m, unsigned long long mlen,
                         const unsigned char *sk);
```

The `crypto_sign_detached()` function signs the message `m`, whose length is `mlen` bytes, using the secret key `sk` and puts the signature into `sig`, which can be up to `crypto_sign_BYTES` bytes long.

The actual length of the signature is put into `siglen` if `siglen` is not `NULL`.

It is safe to ignore `siglen` and always consider a signature as `crypto_sign_BYTES` bytes long; shorter signatures will be transparently padded with zeros if necessary.

```c
int crypto_sign_verify_detached(const unsigned char *sig,
                                const unsigned char *m,
                                unsigned long long mlen,
                                const unsigned char *pk);
```

The `crypto_sign_verify_detached()` function verifies that `sig` is a valid signature for the message `m`, whose length is `mlen` bytes, using the signer’s public key `pk`.

It returns `-1` if signature verification fails and `0` on success.

## Multi-part messages

If the message doesn’t fit in memory, then it can be provided as a sequence of arbitrarily-sized chunks.

This uses the Ed25519ph signature system, which pre-hashes the message. In other words, what gets signed is not the message itself but its image through a hash function.

If the message *can* fit in memory and be supplied as a single chunk, then the single-part API should be preferred.

Note: `Ed25519ph(m)` is intentionally not equivalent to `Ed25519(SHA512(m))`.

If, for some reason, you need to pre-hash the message yourself, then use the multi-part `crypto_generichash_*()` APIs and sign the 512-bit output, preferably prefixed by your protocol name (or anything that will make the hash unique for a given use case).

```c
int crypto_sign_init(crypto_sign_state *state);
```

The `crypto_sign_init()` function initializes the state `state`. This function must be called before the first `crypto_sign_update()` call.

```c
int crypto_sign_update(crypto_sign_state *state,
                       const unsigned char *m, unsigned long long mlen);
```

Add a new chunk `m` of length `mlen` bytes to the message that will eventually be signed.

After all parts have been supplied, one of the following functions can be called:

```c
int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig,
                             unsigned long long *siglen_p,
                             const unsigned char *sk);
```

The `crypto_sign_final_create()` function computes a signature for the previously supplied message using the secret key `sk` and puts it into `sig`.

If `siglen_p` is not `NULL`, then the length of the signature is stored at this address.

It is safe to ignore `siglen` and always consider a signature as `crypto_sign_BYTES` bytes long; shorter signatures will be transparently padded with zeros if necessary.

```c
int crypto_sign_final_verify(crypto_sign_state *state, const unsigned char *sig,
                             const unsigned char *pk);
```

The `crypto_sign_final_verify()` function verifies that `sig` is a valid signature using the public key `pk` for the message whose content has been previously supplied using `crypto_update()`.

## Extracting the seed and the public key from the secret key

The secret key includes the seed (either a random seed or the one given to `crypto_sign_seed_keypair()`) and public key.

While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing.

If required, Sodium provides two functions to extract the seed and public key from the secret key:

```c
int crypto_sign_ed25519_sk_to_seed(unsigned char *seed,
                                   const unsigned char *sk);

int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk);
```

The `crypto_sign_ed25519_sk_to_seed()` function extracts the seed from the secret key `sk` and copies it into `seed` (`crypto_sign_SEEDBYTES` bytes).

The `crypto_sign_ed25519_sk_to_pk()` function extracts the public key from the secret key `sk` and copies it into `pk` (`crypto_sign_PUBLICKEYBYTES` bytes).

## Data structures

* `crypto_sign_state`, whose size can be retrieved using `crypto_sign_statebytes()`

## Constants

* `crypto_sign_PUBLICKEYBYTES`
* `crypto_sign_SECRETKEYBYTES`
* `crypto_sign_BYTES`
* `crypto_sign_SEEDBYTES`

## Algorithm details

* Single-part signature: Ed25519
* Multi-part signature: Ed25519ph

## References

* [Edwards-Curve Digital Signature Algorithm (EdDSA)](https://datatracker.ietf.org/doc/html/rfc8032)
* [The Provable Security of Ed25519: Theory and Practice](https://eprint.iacr.org/2020/823.pdf)
* [Seems Legit: Automated Analysis of Subtle Attacks on Protocols that Use Signatures](https://eprint.iacr.org/2019/779.pdf)
* [Taming the many EdDSAs](https://eprint.iacr.org/2020/1244.pdf)

## Notes

`crypto_sign_verify()` and `crypto_sign_verify_detached()` are only designed to verify signatures computed using `crypto_sign()` and `crypto_sign_detached()`.

The original NaCl `crypto_sign_open()` implementation overwrote 64 bytes after the message, whereas the libsodium implementation doesn’t write past the end of the message.

Ed25519ph (used by the multi-part API) was implemented in libsodium 1.0.12.

The Ed25519 system was designed to compute deterministic signatures.

Non-deterministic (but also non-standard) signatures can be produced by compiling libsodium with the `ED25519_NONDETERMINISTIC` macro defined.

Computing an Ed25519 signature requires an Edwards25519 secret and a hashing prefix. But applications do not directly supply them: they are both internally derived from the seed.

One of these secrets is the scalar the Edwards25519 base point is multiplied with. That scalar is computed by calling `crypto_hash_sha512(seed)` and truncating the output to the first 32 bytes. There’s nothing specific to libsodium here, this is how Ed25519 signatures work and have been standardized.


# Sealed boxes

## Example

```c
#define MESSAGE (const unsigned char *) "Message"
#define MESSAGE_LEN 7
#define CIPHERTEXT_LEN (crypto_box_SEALBYTES + MESSAGE_LEN)

/* Recipient creates a long-term key pair */
unsigned char recipient_pk[crypto_box_PUBLICKEYBYTES];
unsigned char recipient_sk[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(recipient_pk, recipient_sk);

/* Anonymous sender encrypts a message using an ephemeral key pair
 * and the recipient's public key */
unsigned char ciphertext[CIPHERTEXT_LEN];
crypto_box_seal(ciphertext, MESSAGE, MESSAGE_LEN, recipient_pk);

/* Recipient decrypts the ciphertext */
unsigned char decrypted[MESSAGE_LEN];
if (crypto_box_seal_open(decrypted, ciphertext, CIPHERTEXT_LEN,
                         recipient_pk, recipient_sk) != 0) {
    /* message corrupted or not intended for this recipient */
}
```

## Purpose

Sealed boxes are designed to anonymously send messages to a recipient given their public key.

Only the recipient can decrypt these messages using their private key. While the recipient can verify the integrity of the message, they cannot verify the identity of the sender.

A message is encrypted using an ephemeral key pair, with the secret key being erased right after the encryption process.

Without knowing the secret key used for a given message, the sender cannot decrypt the message later. Furthermore, without additional data, a message cannot be correlated with the identity of its sender.

## Usage

```c
int crypto_box_seal(unsigned char *c, const unsigned char *m,
                    unsigned long long mlen, const unsigned char *pk);
```

The `crypto_box_seal()` function encrypts a message `m` of length `mlen` for a recipient whose public key is `pk`. It puts the ciphertext, whose length is `crypto_box_SEALBYTES + mlen`, into `c`.

The function creates a new key pair for each message and attaches the public key to the ciphertext. The secret key is overwritten and is not accessible after this function returns.

```c
int crypto_box_seal_open(unsigned char *m, const unsigned char *c,
                         unsigned long long clen,
                         const unsigned char *pk, const unsigned char *sk);
```

The `crypto_box_seal_open()` function decrypts the ciphertext `c`, whose length is `clen`, using the key pair (`pk`, `sk`) and puts the decrypted message into `m` (`clen - crypto_box_SEALBYTES` bytes).

Key pairs are compatible with other `crypto_box_*` operations and can be created using `crypto_box_keypair()` or `crypto_box_seed_keypair()`.

This function doesn’t require passing the public key of the sender as the ciphertext already includes this information.

## Constants

* `crypto_box_SEALBYTES`

## Algorithm details

Sealed boxes leverage the `crypto_box` construction, which uses X25519 and XSalsa20-Poly1305.

The format of a sealed box is

```
ephemeral_pk ‖ box(m, recipient_pk, ephemeral_sk, nonce=blake2b(ephemeral_pk ‖ recipient_pk))
```


# Key encapsulation

## Example

```c
unsigned char pk[crypto_kem_PUBLICKEYBYTES];
unsigned char sk[crypto_kem_SECRETKEYBYTES];
unsigned char ciphertext[crypto_kem_CIPHERTEXTBYTES];
unsigned char client_key[crypto_kem_SHAREDSECRETBYTES];
unsigned char server_key[crypto_kem_SHAREDSECRETBYTES];

crypto_kem_keypair(pk, sk);

if (crypto_kem_enc(ciphertext, client_key, pk) != 0) {
    /* error */
}
if (crypto_kem_dec(server_key, ciphertext, sk) != 0) {
    /* error */
}
```

## Purpose

A key encapsulation mechanism creates a shared secret for a recipient using the public key of that recipient.

The sender obtains the shared secret directly during encapsulation. The recipient obtains the same shared secret by decapsulating the ciphertext with the secret key.

This is useful for bootstrapping session keys or building hybrid encryption schemes.

For most applications, the high-level `crypto_kem_*()` API should be preferred. In libsodium, it uses X-Wing, a hybrid post-quantum KEM combining ML-KEM768 and X25519.

## Usage

```c
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk);
```

The `crypto_kem_keypair()` function creates a new key pair. It puts the public key into `pk` and the secret key into `sk`.

```c
int crypto_kem_seed_keypair(unsigned char *pk, unsigned char *sk,
                            const unsigned char *seed);
```

The `crypto_kem_seed_keypair()` function computes a deterministic key pair from `seed` (`crypto_kem_SEEDBYTES` bytes).

```c
int crypto_kem_enc(unsigned char *ct, unsigned char *ss,
                   const unsigned char *pk);
```

The `crypto_kem_enc()` function creates a ciphertext `ct` for the recipient public key `pk` and stores the shared secret into `ss`.

It returns `0` on success and `-1` on failure.

```c
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct,
                   const unsigned char *sk);
```

The `crypto_kem_dec()` function verifies and decapsulates the ciphertext `ct` using the recipient secret key `sk`, and stores the shared secret into `ss`.

It returns `0` on success and `-1` on failure.

## Using the shared secret

The shared secret is `crypto_kem_SHAREDSECRETBYTES` bytes long.

In many protocols, the shared secret is immediately fed to a KDF in order to derive multiple context-specific keys. [HKDF](https://libsodium.gitbook.io/doc/key_derivation/hkdf) is a good fit for this.

## Algorithm details

The high-level `crypto_kem_*()` API uses X-Wing and reports `"xwing"` via `crypto_kem_PRIMITIVE`.

X-Wing combines ML-KEM768 with X25519 in order to provide protection against both classical and quantum adversaries.

For libsodium applications, it should be the default choice.

## Constants

* `crypto_kem_PUBLICKEYBYTES`
* `crypto_kem_SECRETKEYBYTES`
* `crypto_kem_CIPHERTEXTBYTES`
* `crypto_kem_SHAREDSECRETBYTES`
* `crypto_kem_SEEDBYTES`
* `crypto_kem_PRIMITIVE`

## Notes

Unlike traditional Diffie-Hellman style key exchange, encapsulation is asymmetric: only the recipient needs a long-term key pair, and the sender does not need to publish a public key in order to create a shared secret.

If the application needs sender authentication in addition to confidentiality, combine key encapsulation with a signature scheme or an authenticated key exchange.

This API was introduced in libsodium 1.0.22.


# Hashing

This page is a work in progress. Feel free to contribute a nice intro to hash functions!


# Generic hashing

## Single-part example without a key

```c
#define MESSAGE ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_LEN 22

unsigned char hash[crypto_generichash_BYTES];

crypto_generichash(hash, sizeof hash,
                   MESSAGE, MESSAGE_LEN,
                   NULL, 0);
```

## Single-part example with a key

```c
#define MESSAGE ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_LEN 22

unsigned char hash[crypto_generichash_BYTES];
unsigned char key[crypto_generichash_KEYBYTES];

randombytes_buf(key, sizeof key);

crypto_generichash(hash, sizeof hash,
                   MESSAGE, MESSAGE_LEN,
                   key, sizeof key);
```

## Multi-part example with a key

```c
#define MESSAGE_PART1 \
    ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_PART1_LEN 22

#define MESSAGE_PART2 \
    ((const unsigned char *) "is longer than expected")
#define MESSAGE_PART2_LEN 23

unsigned char hash[crypto_generichash_BYTES];
unsigned char key[crypto_generichash_KEYBYTES];
crypto_generichash_state state;

randombytes_buf(key, sizeof key);

crypto_generichash_init(&state, key, sizeof key, sizeof hash);

crypto_generichash_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN);
crypto_generichash_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN);

crypto_generichash_final(&state, hash, sizeof hash);
```

## Purpose

This API computes a fixed-length fingerprint for an arbitrarily long message.

Sample use cases:

* File integrity checking
* Creating unique identifiers to index arbitrarily long data

## Usage

```c
int crypto_generichash(unsigned char *out, size_t outlen,
                       const unsigned char *in, unsigned long long inlen,
                       const unsigned char *key, size_t keylen);
```

The `crypto_generichash()` function puts a fingerprint of the message `in` whose length is `inlen` bytes into `out`. The output size can be chosen by the application.

The minimum recommended output size is `crypto_generichash_BYTES`. This size makes it practically impossible for two messages to produce the same fingerprint.

However, for specific use cases, the size can be any value between `crypto_generichash_BYTES_MIN` (included) and `crypto_generichash_BYTES_MAX` (included).

`key` can be `NULL` and `keylen` can be `0`. In this case, a message will always have the same fingerprint, like the `MD5` or `SHA-1` functions for which `crypto_generichash()` is a faster and more secure alternative.

But a key can also be specified. A message will always have the same fingerprint for a given key, but different keys used to hash the same message are very likely to produce distinct fingerprints.

In particular, the key can be used to make sure that different applications generate different fingerprints even if they process the same data.

The recommended key size is `crypto_generichash_KEYBYTES` bytes.

However, the key size can be any value between `0` (included) and `crypto_generichash_KEYBYTES_MAX` (included). If the key is meant to be secret, the recommended minimum length is `crypto_generichash_KEYBYTES_MIN`.

```c
int crypto_generichash_init(crypto_generichash_state *state,
                            const unsigned char *key,
                            const size_t keylen, const size_t outlen);

int crypto_generichash_update(crypto_generichash_state *state,
                              const unsigned char *in,
                              unsigned long long inlen);

int crypto_generichash_final(crypto_generichash_state *state,
                             unsigned char *out, const size_t outlen);
```

The message doesn’t have to be provided as a single chunk. The `generichash` operation also supports a streaming API.

The `crypto_generichash_init()` function initializes a state `state` with a key `key` (that can be `NULL`) of length `keylen` bytes to eventually produce `outlen` bytes of output.

Each chunk of the complete message can then be sequentially processed by calling `crypto_generichash_update()`, providing the previously initialized state `state`, a pointer to the chunk `in`, and the length of the chunk in bytes, `inlen`.

The `crypto_generichash_final()` function completes the operation and puts the final fingerprint into `out` as `outlen` bytes.

After `crypto_generichash_final()` returns, the state should not be used any more, unless it is reinitialized using `crypto_generichash_init()`.

This alternative API is especially useful to process very large files and data streams.

```c
void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]);
```

The `crypto_generichash_keygen()` function creates a key `k` of the recommended length `crypto_generichash_KEYBYTES`.

## Constants

* `crypto_generichash_BYTES`
* `crypto_generichash_BYTES_MIN`
* `crypto_generichash_BYTES_MAX`
* `crypto_generichash_KEYBYTES`
* `crypto_generichash_KEYBYTES_MIN`
* `crypto_generichash_KEYBYTES_MAX`

## Data types

* `crypto_generichash_state`

## Algorithm details

BLAKE2b

## Notes

The `crypto_generichash_*` function set is implemented using BLAKE2b, a simple, standardized ([RFC 7693](https://www.rfc-editor.org/rfc/rfc7693.txt)), and secure hash function that is as strong as SHA-3 but faster than MD5 and SHA-1.

Unlike MD5, SHA-1, and SHA-256, this function is safe against hash length extension attacks.

With a key, the function can be used as a PRF.

BLAKE2b’s salt and personalization parameters are accessible through the lower-level functions whose prototypes are defined in `crypto_generichash_blake2b.h`.

BLAKE2b is not suitable for hashing passwords. For this purpose, use the `crypto_pwhash` API documented in the Password Hashing section.


# Short-input hashing

## Example

```c
#define SHORT_DATA ((const unsigned char *) "Sparkling water")
#define SHORT_DATA_LEN 15

unsigned char hash[crypto_shorthash_BYTES];
unsigned char key[crypto_shorthash_KEYBYTES];

crypto_shorthash_keygen(key);
crypto_shorthash(hash, SHORT_DATA, SHORT_DATA_LEN, key);
```

## Purpose

Many applications and programming language implementations were recently found to be vulnerable to denial-of-service (DoS) attacks when a hash function with weak security guarantees, such as MurmurHash3, was used to construct a hash table.

To address this, Sodium provides the `crypto_shorthash()` function, which outputs short but unpredictable (without knowing the secret key) values suitable for picking a list in a hash table for a given key.

This function is optimized for short inputs.

The output of this function is only 64 bits. Therefore, it should *not* be considered collision-resistant.

Use cases:

* Hash tables
* Probabilistic data structures, such as Bloom filters
* Integrity checking in interactive protocols

## Usage

```c
int crypto_shorthash(unsigned char *out, const unsigned char *in,
                     unsigned long long inlen, const unsigned char *k);
```

Compute a fixed-size (`crypto_shorthash_BYTES` bytes) fingerprint for the message `in` whose length is `inlen` bytes, using the key `k`.

The `k` is `crypto_shorthash_KEYBYTES` bytes and can be created using `crypto_shorthash_keygen()`.

The same message hashed with the same key will always produce the same output.

## Constants

* `crypto_shorthash_BYTES`
* `crypto_shorthash_KEYBYTES`

## Algorithm details

SipHash-2-4

## Notes

* The key must remain secret. This function will not provide any mitigations against DoS attacks if the key is known from attackers.
* When building hash tables, it is recommended to use a prime number for the table size. This ensures that all bits from the output of the hash function are being used. Mapping the range of the hash function to `[0..N)` can be done efficiently [without modulo reduction](http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/).
* libsodium >= 1.0.12 also implements a variant of SipHash with the same key size but a 128-bit output, accessible as `crypto_shorthash_siphashx24()`.


# Extendable output functions

An extendable output function (XOF) is similar to a hash function, but its output can be extended to any desired length.

Unlike a hash function where the output size is fixed, a XOF can produce output of arbitrary length from the same input, making it useful for key derivation, stream generation, and applications where variable-length output is needed.

libsodium provides two families of XOFs:

* SHAKE: NIST-standardized XOFs from [FIPS 202](https://csrc.nist.gov/pubs/fips/202/final)
* TurboSHAKE: Faster variants using reduced-round Keccak, standardized in [RFC 9861](https://www.rfc-editor.org/rfc/rfc9861.html)

## Single-part example

```c
#define MESSAGE ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_LEN 22

unsigned char out[32];

crypto_xof_turboshake128(out, sizeof out, MESSAGE, MESSAGE_LEN);
```

## Multi-part example

```c
#define MESSAGE_PART1 \
    ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_PART1_LEN 22

#define MESSAGE_PART2 \
    ((const unsigned char *) "is longer than expected")
#define MESSAGE_PART2_LEN 23

unsigned char out[32];
crypto_xof_turboshake128_state state;

crypto_xof_turboshake128_init(&state);

crypto_xof_turboshake128_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN);
crypto_xof_turboshake128_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN);

crypto_xof_turboshake128_squeeze(&state, out, sizeof out);
```

## Incremental output

Unlike regular hash functions, XOFs can be squeezed multiple times to produce additional output. The concatenation of all squeezed outputs is identical to squeezing the total length at once.

```c
unsigned char seed[32];
randombytes_buf(seed, sizeof seed);

crypto_xof_turboshake128_state state;
crypto_xof_turboshake128_init(&state);
crypto_xof_turboshake128_update(&state, seed, sizeof seed);

unsigned char key1[32], key2[32], key3[32];
crypto_xof_turboshake128_squeeze(&state, key1, sizeof key1);
crypto_xof_turboshake128_squeeze(&state, key2, sizeof key2);
crypto_xof_turboshake128_squeeze(&state, key3, sizeof key3);
```

## Purpose

XOFs can be used as:

* Hash functions: producing fixed-length digests
* Key derivation functions: deriving multiple keys from a seed
* Deterministic random generators: expanding a seed into arbitrary-length output
* Domain-separated hashing: using custom domain separators

## Real-world use cases

### Deriving multiple keys from a master secret

XOFs naturally support deriving multiple independent keys by squeezing repeatedly:

```c
unsigned char master_key[32];
/* ... master_key is established via key exchange or similar ... */

crypto_xof_turboshake128_state state;
crypto_xof_turboshake128_init(&state);
crypto_xof_turboshake128_update(&state, master_key, sizeof master_key);

/* Derive independent keys for different purposes */
unsigned char encryption_key[32];
unsigned char mac_key[32];
unsigned char iv[16];

crypto_xof_turboshake128_squeeze(&state, encryption_key, sizeof encryption_key);
crypto_xof_turboshake128_squeeze(&state, mac_key, sizeof mac_key);
crypto_xof_turboshake128_squeeze(&state, iv, sizeof iv);
```

### Generating deterministic test vectors

Expand a short seed into reproducible test data:

```c
unsigned char seed[16] = "test_vector_seed";
unsigned char test_data[10000];

crypto_xof_turboshake128(test_data, sizeof test_data, seed, sizeof seed);
```

### Hashing with context/domain separation

Use domain separators to create independent hash functions from the same primitive:

```c
#define DOMAIN_FILE_ID    0x01
#define DOMAIN_SESSION_ID 0x02

/* Hash a file with domain separation */
unsigned char file_hash[32];
crypto_xof_turboshake128_state state;
crypto_xof_turboshake128_init_with_domain(&state, DOMAIN_FILE_ID);
crypto_xof_turboshake128_update(&state, file_contents, file_len);
crypto_xof_turboshake128_squeeze(&state, file_hash, sizeof file_hash);

/* Hash session data - independent from file hashing even with same input */
unsigned char session_id[16];
crypto_xof_turboshake128_init_with_domain(&state, DOMAIN_SESSION_ID);
crypto_xof_turboshake128_update(&state, session_data, session_len);
crypto_xof_turboshake128_squeeze(&state, session_id, sizeof session_id);
```

### Hash-to-curve or hash-to-field

XOFs simplify protocols that need to hash into mathematical structures by providing arbitrary-length output without awkward padding or multiple hash calls:

```c
/* Generate enough random bytes to reduce bias when mapping to a field */
unsigned char uniform_bytes[64];
crypto_xof_turboshake128(uniform_bytes, sizeof uniform_bytes,
                          input, input_len);
/* ... use uniform_bytes to derive a field element ... */
```

### Replacing HKDF-Expand

When you have a uniformly random key and need to derive multiple outputs, a XOF is simpler than HKDF:

```c
/* Instead of multiple HKDF-Expand calls with different info strings,
   just squeeze the outputs you need */
unsigned char prk[32]; /* pseudorandom key from key exchange */

crypto_xof_turboshake128_state state;
crypto_xof_turboshake128_init(&state);
crypto_xof_turboshake128_update(&state, prk, sizeof prk);
crypto_xof_turboshake128_update(&state, context, context_len);

unsigned char derived[96]; /* 3 x 32-byte keys */
crypto_xof_turboshake128_squeeze(&state, derived, sizeof derived);
```

## SHAKE

SHAKE128 and SHAKE256 are XOFs defined in FIPS 202, based on the Keccak permutation with 24 rounds.

### Single-part API

```c
int crypto_xof_shake256(unsigned char *out, size_t outlen,
                        const unsigned char *in, unsigned long long inlen);

int crypto_xof_shake128(unsigned char *out, size_t outlen,
                        const unsigned char *in, unsigned long long inlen);
```

The `crypto_xof_shake256()` function hashes `inlen` bytes from `in` and writes `outlen` bytes into `out`.

The output length can be any value. Common choices are 32 or 64 bytes, but the output can be much longer when the XOF is used for key derivation or as a deterministic random generator.

### Multi-part API

```c
int crypto_xof_shake256_init(crypto_xof_shake256_state *state);

int crypto_xof_shake256_update(crypto_xof_shake256_state *state,
                               const unsigned char *in,
                               unsigned long long inlen);

int crypto_xof_shake256_squeeze(crypto_xof_shake256_state *state,
                                unsigned char *out, size_t outlen);
```

The multi-part API allows hashing data provided in chunks, and squeezing output incrementally.

After calling `crypto_xof_shake256_init()`, `crypto_xof_shake256_update()` can be called repeatedly to absorb data. Once all data has been absorbed, `crypto_xof_shake256_squeeze()` can be called repeatedly to produce output.

After squeezing begins, no more data can be absorbed into the state.

SHAKE128 has equivalent functions with `shake128` instead of `shake256` in the names.

### Custom domain separation

```c
int crypto_xof_shake256_init_with_domain(crypto_xof_shake256_state *state,
                                         unsigned char domain);
```

The `crypto_xof_shake256_init_with_domain()` function initializes the state with a custom domain separator instead of the standard one. This produces outputs unrelated to the standard variant, allowing different applications to use the same underlying XOF without risk of collisions.

The domain separator must be between `0x01` and `0x7F`.

Calling `crypto_xof_shake256_init()` is equivalent to calling `crypto_xof_shake256_init_with_domain()` with `crypto_xof_shake256_DOMAIN_STANDARD`.

### Constants

* `crypto_xof_shake256_BLOCKBYTES` (136)
* `crypto_xof_shake256_STATEBYTES` (256)
* `crypto_xof_shake256_DOMAIN_STANDARD` (0x1F): the domain separator used by `crypto_xof_shake256_init()`
* `crypto_xof_shake128_BLOCKBYTES` (168)
* `crypto_xof_shake128_STATEBYTES` (256)
* `crypto_xof_shake128_DOMAIN_STANDARD` (0x1F): the domain separator used by `crypto_xof_shake128_init()`

### Data types

* `crypto_xof_shake256_state`
* `crypto_xof_shake128_state`

## TurboSHAKE

TurboSHAKE128 and TurboSHAKE256 are faster variants of SHAKE that use 12 rounds of the Keccak permutation instead of 24. They are roughly twice as fast as SHAKE while maintaining the same security claims.

TurboSHAKE is the underlying function of KangarooTwelve. Both are standardized in RFC 9861.

### Single-part API

```c
int crypto_xof_turboshake256(unsigned char *out, size_t outlen,
                             const unsigned char *in, unsigned long long inlen);

int crypto_xof_turboshake128(unsigned char *out, size_t outlen,
                             const unsigned char *in, unsigned long long inlen);
```

### Multi-part API

```c
int crypto_xof_turboshake256_init(crypto_xof_turboshake256_state *state);

int crypto_xof_turboshake256_update(crypto_xof_turboshake256_state *state,
                                    const unsigned char *in,
                                    unsigned long long inlen);

int crypto_xof_turboshake256_squeeze(crypto_xof_turboshake256_state *state,
                                     unsigned char *out, size_t outlen);
```

TurboSHAKE128 has equivalent functions with `turboshake128` instead of `turboshake256` in the names.

### Custom domain separation

```c
int crypto_xof_turboshake256_init_with_domain(crypto_xof_turboshake256_state *state,
                                              unsigned char domain);
```

Domain-separated hashing is useful for deriving independent functions from the same primitive:

```c
#define DOMAIN_KEY_DERIVATION 0x01
#define DOMAIN_COMMITMENT     0x02

unsigned char master_secret[32];
/* ... */

/* Derive an encryption key */
unsigned char enc_key[32];
crypto_xof_turboshake256_state state;
crypto_xof_turboshake256_init_with_domain(&state, DOMAIN_KEY_DERIVATION);
crypto_xof_turboshake256_update(&state, master_secret, sizeof master_secret);
crypto_xof_turboshake256_squeeze(&state, enc_key, sizeof enc_key);

/* Compute a commitment (independent from the key derivation) */
unsigned char commitment[32];
crypto_xof_turboshake256_init_with_domain(&state, DOMAIN_COMMITMENT);
crypto_xof_turboshake256_update(&state, master_secret, sizeof master_secret);
crypto_xof_turboshake256_squeeze(&state, commitment, sizeof commitment);
```

The domain separator must be between `0x01` and `0x7F`.

Calling `crypto_xof_turboshake256_init()` is equivalent to calling `crypto_xof_turboshake256_init_with_domain()` with `crypto_xof_turboshake256_DOMAIN_STANDARD`.

### Constants

* `crypto_xof_turboshake256_BLOCKBYTES` (136)
* `crypto_xof_turboshake256_STATEBYTES` (256)
* `crypto_xof_turboshake256_DOMAIN_STANDARD` (0x1F): the domain separator used by `crypto_xof_turboshake256_init()`
* `crypto_xof_turboshake128_BLOCKBYTES` (168)
* `crypto_xof_turboshake128_STATEBYTES` (256)
* `crypto_xof_turboshake128_DOMAIN_STANDARD` (0x1F): the domain separator used by `crypto_xof_turboshake128_init()`

### Data types

* `crypto_xof_turboshake256_state`
* `crypto_xof_turboshake128_state`

## Which variant to use

TurboSHAKE128 is the recommended choice for most applications. It offers:

* Great performance (\~2x faster than SHAKE)
* 128-bit security, which is more than sufficient for virtually all use cases
* Built-in domain separation support
* Standardized in RFC 9861

Use a different variant only if you have specific requirements:

* SHAKE256 or TurboSHAKE256: When you need 256-bit collision resistance
* SHAKE128/SHAKE256: When NIST FIPS 202 compliance is mandated

The “128” and “256” in the names refer to security levels, not output sizes. All variants can produce output of any length.

Security considerations:

When using a XOF as a hash function (collision resistance matters), the output should be at least twice the security level. TurboSHAKE128 with a 32-byte output provides full 128-bit collision resistance. Shorter outputs reduce collision resistance proportionally: a 16-byte output only provides 64-bit collision resistance.

When using a XOF for key derivation or as a PRF (preimage resistance matters), the output length doesn’t affect security as long as you’re using it correctly. TurboSHAKE128 provides 128-bit preimage resistance regardless of output length.

```c
/* TurboSHAKE128 producing a 256-bit hash - full 128-bit security */
unsigned char hash[32];
crypto_xof_turboshake128(hash, 32, message, message_len);

/* TurboSHAKE128 deriving a 256-bit key - full 128-bit security */
unsigned char key[32];
crypto_xof_turboshake128(key, 32, seed, seed_len);

/* TurboSHAKE128 generating 1KB of deterministic randomness */
unsigned char random_data[1024];
crypto_xof_turboshake128(random_data, 1024, seed, seed_len);
```

## Algorithm details

All four XOFs are based on the Keccak-p (SHA-3) permutation:

| Function      | Security | Block size | Rounds |
| ------------- | -------- | ---------- | ------ |
| SHAKE128      | 128-bit  | 168 bytes  | 24     |
| SHAKE256      | 256-bit  | 136 bytes  | 24     |
| TurboSHAKE128 | 128-bit  | 168 bytes  | 12     |
| TurboSHAKE256 | 256-bit  | 136 bytes  | 12     |

The security level indicates resistance to generic attacks:

* 128-bit security: collision resistance up to 2^64 work, preimage resistance up to 2^128 work
* 256-bit security: collision resistance up to 2^128 work, preimage resistance up to 2^256 work

## Notes

XOFs differ from hash functions in an important way: for the same input, requesting different output lengths produces related outputs. Specifically, shorter outputs are prefixes of longer outputs. If this property is undesirable for your application, include the intended output length in the input.

The state should not be used after the object has been squeezed unless it is reinitialized using the `init` function.

These functions are deterministic: the same input always produces the same output. They are not suitable for password hashing. For that purpose, use the [password hashing](https://libsodium.gitbook.io/doc/password_hashing) API.

These functions were introduced in libsodium 1.0.21.


# Password hashing

Secret keys used to encrypt or sign confidential data have to be chosen from a very large keyspace.

However, passwords are usually short, human-generated strings, making dictionary attacks practical.

Password hashing functions derive a secret key of any size from a password and salt.

* The generated key has the size defined by the application, no matter what the password length is.
* The same password hashed with the same parameters will always produce the same output.
* The same password hashed with different salts will produce different outputs.
* The function deriving a key from a password and salt is CPU intensive and intentionally requires a fair amount of memory. Therefore, it mitigates brute-force attacks by requiring a significant effort to verify each password.

Common use cases:

* Password storage, or rather storing what it takes to verify a password without having to store the actual password.
* Deriving a secret key from a password; for example, for disk encryption.

Sodium’s high-level `crypto_pwhash_*` API currently leverages the Argon2id function on all platforms. This can change at any point in time, but it is guaranteed that a given version of libsodium can verify all hashes produced by all previous versions from any platform. Applications don’t have to worry about backward compatibility.

The more specific `crypto_pwhash_scryptsalsa208sha256_*` API uses the more conservative and widely deployed scrypt function.

## Argon2

Argon2 is optimized for the x86 architecture and exploits the cache and memory organization of the recent Intel and AMD processors, but its implementation remains portable and fast on other architectures, except for JavaScript.

Argon2 has three variants: Argon2d, Argon2i, and Argon2id. Libsodium supports Argon2i and Argon2id.

## Scrypt

Scrypt was also designed to make it costly to perform large-scale custom hardware attacks by requiring large amounts of memory.

Even though its memory hardness can be significantly reduced at the cost of extra computations, this function remains an excellent choice today, provided that its parameters are properly chosen.

## Server relief

If multiple clients can simultaneously log in on a shared server, then the memory and computation requirements can exhaust the server’s resources.

To mitigate this, passwords can be pre-hashed on the client (e.g. using libsodium.js in a web application):

* On user account creation, the server sends a random seed to the client. The client computes `ph = password_hash(password, seed)` and sends `ph` to the server. `password_hash` is a password hashing function tuned for the maximum memory and CPU usage the client can handle. The server stores the seed and `password_hash'(ph, seed)` for this user account. `password_hash'` is a password hashing function, whose parameters can be tuned for low memory and CPU usage.
* On a login attempt, the server sends the seed, or, for a non-existent user, a pseudorandom seed that must always be the same for a given username (for example, using `crypto_generichash()` with a key on the username as the message). The client computes `ph = password_hash(password, seed)` and sends it to the server. The server computes `password_hash'(ph, seed)` and compares it against what was stored in the database.


# The pwhash\* API

Sodium provides an API that can be used both for key derivation using a low-entropy input and password storage.

## Example 1: key derivation

```c
#define PASSWORD "Correct Horse Battery Staple"
#define KEY_LEN crypto_box_SEEDBYTES

unsigned char salt[crypto_pwhash_SALTBYTES];
unsigned char key[KEY_LEN];

randombytes_buf(salt, sizeof salt);

if (crypto_pwhash
    (key, sizeof key, PASSWORD, strlen(PASSWORD), salt,
     crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE,
     crypto_pwhash_ALG_DEFAULT) != 0) {
    /* out of memory */
}
```

## Example 2: password storage

```c
#define PASSWORD "Correct Horse Battery Staple"

char hashed_password[crypto_pwhash_STRBYTES];

if (crypto_pwhash_str
    (hashed_password, PASSWORD, strlen(PASSWORD),
     crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE) != 0) {
    /* out of memory */
}

if (crypto_pwhash_str_verify
    (hashed_password, PASSWORD, strlen(PASSWORD)) != 0) {
    /* wrong password */
}
```

## Key derivation

```c
int crypto_pwhash(unsigned char * const out,
                  unsigned long long outlen,
                  const char * const passwd,
                  unsigned long long passwdlen,
                  const unsigned char * const salt,
                  unsigned long long opslimit,
                  size_t memlimit, int alg);
```

The `crypto_pwhash()` function derives an `outlen` bytes long key from a password `passwd` whose length is `passwdlen` and a salt `salt` whose fixed length is `crypto_pwhash_SALTBYTES` bytes. `passwdlen` should be at least `crypto_pwhash_PASSWD_MIN` and `crypto_pwhash_PASSWD_MAX`. `outlen` should be at least `crypto_pwhash_BYTES_MIN` = `16` (128 bits) and at most `crypto_pwhash_BYTES_MAX`.

The computed key is stored into `out`, representing the address of a dedicated storage area of `outlen` bytes.

`opslimit` represents the maximum amount of computations to perform. Raising this number will make the function require more CPU cycles to compute a key. This number must be between `crypto_pwhash_OPSLIMIT_MIN` and `crypto_pwhash_OPSLIMIT_MAX`.

`memlimit` is the maximum amount of RAM in bytes that the function will use. This number must be between `crypto_pwhash_MEMLIMIT_MIN` and `crypto_pwhash_MEMLIMIT_MAX`.

`alg` is an identifier for the algorithm to use and should be set to one of the following values:

* `crypto_pwhash_ALG_DEFAULT`: the currently recommended algorithm, which can change from one version of libsodium to another.
* `crypto_pwhash_ALG_ARGON2I13`: version 1.3 of the Argon2i algorithm.
* `crypto_pwhash_ALG_ARGON2ID13`: version 1.3 of the Argon2id algorithm, available since libsodium 1.0.13.

For interactive, online operations, `crypto_pwhash_OPSLIMIT_INTERACTIVE` and `crypto_pwhash_MEMLIMIT_INTERACTIVE` provide a baseline for these two parameters. This currently requires 64 MiB of dedicated RAM. Higher values may improve security (see below).

Alternatively, `crypto_pwhash_OPSLIMIT_MODERATE` and `crypto_pwhash_MEMLIMIT_MODERATE` can be used. This requires 256 MiB of dedicated RAM and takes about 0.7 seconds on a 2.8 GHz Core i7 CPU.

For highly sensitive data and non-interactive operations, `crypto_pwhash_OPSLIMIT_SENSITIVE` and `crypto_pwhash_MEMLIMIT_SENSITIVE` can be used. With these parameters, deriving a key takes about 3.5 seconds on a 2.8 GHz Core i7 CPU and requires 1024 MiB of dedicated RAM.

The `salt` should be unpredictable. `randombytes_buf()` is the easiest way to fill the `crypto_pwhash_SALTBYTES` bytes of the salt.

Keep in mind that to produce the same key from the same password, the same algorithm, the same salt, and the same values for `opslimit` and `memlimit` must be used. Therefore, these parameters must be stored for each user.

The function returns `0` on success and `-1` if the computation didn’t complete, usually because the operating system refused to allocate the amount of requested memory.

## Password storage

```c
int crypto_pwhash_str(char out[crypto_pwhash_STRBYTES],
                      const char * const passwd,
                      unsigned long long passwdlen,
                      unsigned long long opslimit,
                      size_t memlimit);
```

The `crypto_pwhash_str()` function puts an ASCII encoded string into `out`, which includes:

* the result of a memory-hard, CPU-intensive hash function applied to the password `passwd` of length `passwdlen`;
* the automatically generated salt used for the previous computation;
* the other parameters required to verify the password, including the algorithm identifier, its version, `opslimit`, and `memlimit`.

`out` must be a dedicated storage area that’s large enough to hold `crypto_pwhash_STRBYTES` bytes, but the actual output string may be shorter.

The output string is zero-terminated, includes only ASCII characters, and can be safely stored in SQL databases and other data stores. No extra information has to be stored to verify the password.

The function returns `0` on success and `-1` if it didn’t complete successfully.

```c
int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES],
                             const char * const passwd,
                             unsigned long long passwdlen);
```

This function verifies that `str` is a valid password verification string (as generated by `crypto_pwhash_str()`) for `passwd` whose length is `passwdlen`.

`str` must be zero-terminated.

It returns `0` if the verification succeeds and `-1` on error.

```c
int crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES],
                                   unsigned long long opslimit, size_t memlimit);
```

Check if a password verification string `str` matches the parameters `opslimit`, `memlimit`, and the current default algorithm.

The function returns `1` if the string appears to be correct but doesn’t match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in.

The function returns `0` if the parameters already match the given ones.

It returns `-1` on error. If this happens, applications may want to compute a correct hash the next time the user logs in.

## Guidelines for choosing the parameters

Start by determining how much memory the function can use. What will be the highest number of threads/processes evaluating the function simultaneously (ideally, no more than 1 per CPU core)? How much physical memory is guaranteed to be available?

Set `memlimit` to the amount of memory you want to reserve for password hashing.

Then set `opslimit` to `3` and measure the time it takes to hash a password.

If this is way too long for your application, reduce `memlimit`, but keep `opslimit` set to `3`.

If the function is so fast that you can afford it to be more computationally intensive without any usability issues, then increase `opslimit`.

For online use (e.g. logging in on a website), a 1 second computation is likely to be the acceptable maximum.

For interactive use (e.g. a desktop application), a 5 second pause after having entered a password is acceptable if the password doesn’t need to be entered more than once per session.

For non-interactive and infrequent use (e.g. restoring an encrypted backup), an even slower computation can be an option.

However, the best defense against brute-force password cracking is to use strong passwords. Libraries such as [passwdqc](http://www.openwall.com/passwdqc/) can help enforce this.

## Constants

* `crypto_pwhash_ALG_ARGON2I13`
* `crypto_pwhash_ALG_ARGON2ID13`
* `crypto_pwhash_ALG_DEFAULT`
* `crypto_pwhash_BYTES_MAX`
* `crypto_pwhash_BYTES_MIN`
* `crypto_pwhash_MEMLIMIT_INTERACTIVE`
* `crypto_pwhash_MEMLIMIT_MAX`
* `crypto_pwhash_MEMLIMIT_MIN`
* `crypto_pwhash_MEMLIMIT_MODERATE`
* `crypto_pwhash_MEMLIMIT_SENSITIVE`
* `crypto_pwhash_OPSLIMIT_INTERACTIVE`
* `crypto_pwhash_OPSLIMIT_MAX`
* `crypto_pwhash_OPSLIMIT_MIN`
* `crypto_pwhash_OPSLIMIT_MODERATE`
* `crypto_pwhash_OPSLIMIT_SENSITIVE`
* `crypto_pwhash_PASSWD_MAX`
* `crypto_pwhash_PASSWD_MIN`
* `crypto_pwhash_SALTBYTES`
* `crypto_pwhash_STRBYTES`
* `crypto_pwhash_STRPREFIX`

## Notes

`opslimit`, the number of passes, must be at least `3` when using Argon2i.`crypto_pwhash()` and `crypto_pwhash_str()` will fail with a `-1` return code for lower values.

There is no “insecure” value for `memlimit`, though the more memory, the better.

Do not forget to initialize the library with `sodium_init()`. `crypto_pwhash_*` will still work without doing so but possibly way slower.

Do not use constants (including `crypto_pwhash_OPSLIMIT_*` and `crypto_pwhash_MEMLIMIT_*`) to verify a password or produce a deterministic output. Save the parameters, including the algorithm identifier, alongside the hash instead.

By doing so, passwords can be rehashed using different parameters if required later on.

For password verification, the recommended interface is `crypto_pwhash_str()` and `crypto_pwhash_str_verify()`. The string produced by `crypto_pwhash_str()` already includes an algorithm identifier and all the parameters, including the automatically generated salt, that were used to hash the password. Subsequently, `crypto_pwhash_str_verify()` automatically decodes these parameters

Plaintext passwords should not stay in memory longer than needed.

It is highly recommended to use `sodium_mlock()` to lock memory regions storing plaintext passwords and to call `sodium_munlock()` right after `crypto_pwhash_str()` and `crypto_pwhash_str_verify()` return.

`sodium_munlock()` overwrites the region with zeros before unlocking it, so it must not be done before calling this function; otherwise, zeroes, instead of the password, would be hashed.

Since version 1.0.15, libsodium’s default algorithm is Argon2id.

Passwords should generally not be used for encryption. If that must be done, then read the AEADs section first.

## Algorithm details

* [Argon2 v1.3](https://github.com/P-H-C/phc-winner-argon2/raw/master/argon2-specs.pdf)


# Key derivation

## Deriving a key from a password

Secret keys used to encrypt or sign confidential data have to be chosen from a very large keyspace. However, passwords are usually short, human-generated strings, making dictionary attacks practical.

The [`pwhash`](https://libsodium.gitbook.io/doc/password_hashing) operation derives a secret key of any size from a password and salt.

Refer to the [Password hashing](https://libsodium.gitbook.io/doc/password_hashing) section for more information and code examples.

## Deriving keys from a single high-entropy key

Multiple secret subkeys can be derived from a single master key.

Given the master key and a key identifier, a subkey can be deterministically computed. However, given a subkey, an attacker cannot compute the master key nor any other subkeys.

The `crypto_kdf` API can derive up to 2^64 keys from a single master key and context, and individual subkeys can have an arbitrary length between 128 (16 bytes) and 512 bits (64 bytes).

Example:

```c
#define CONTEXT "Examples"

uint8_t master_key[crypto_kdf_KEYBYTES];
uint8_t subkey1[32];
uint8_t subkey2[32];
uint8_t subkey3[64];

crypto_kdf_keygen(master_key);

crypto_kdf_derive_from_key(subkey1, sizeof subkey1, 1, CONTEXT, master_key);
crypto_kdf_derive_from_key(subkey2, sizeof subkey2, 2, CONTEXT, master_key);
crypto_kdf_derive_from_key(subkey3, sizeof subkey3, 3, CONTEXT, master_key);
```

Usage:

```c
void crypto_kdf_keygen(uint8_t key[crypto_kdf_KEYBYTES]);
```

The `crypto_kdf_keygen()` function creates a master key.

```c
int crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len,
                               uint64_t subkey_id,
                               const char ctx[crypto_kdf_CONTEXTBYTES],
                               const unsigned char key[crypto_kdf_KEYBYTES]);
```

The `crypto_kdf_derive_from_key()` function derives a `subkey_id`-th subkey `subkey` of length `subkey_len` bytes using the master key `key` and the context `ctx`.

`subkey_id` can be any value up to `(2^64)-1`. However, with 128-bit subkeys, it is not safe to derive more than `2^48` subkeys from the same key. With subkeys that are at 160 bits or more, `2^64` subkeys can be safely derived.

`subkey_len` must be between `crypto_kdf_BYTES_MIN` (inclusive) and `crypto_kdf_BYTES_MAX` (inclusive).

Similar to a type, the context `ctx` is an 8 character string describing what the key is going to be used for.

Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but in two distinct contexts is likely to generate two different outputs.

Contexts don’t have to be secret and can have a low entropy.

Examples of contexts include `UserName`, `__auth__`, `pictures`, and `userdata`.

They must be `crypto_kdf_CONTEXTBYTES` bytes long.

If more convenient, it is also fine to use a single global context for a whole application. This will still prevent the same keys from being mistakenly used by another application.

Constants:

* `crypto_kdf_PRIMITIVE`
* `crypto_kdf_BYTES_MIN`
* `crypto_kdf_BYTES_MAX`
* `crypto_kdf_CONTEXTBYTES`
* `crypto_kdf_KEYBYTES`

Algorithm details:

`BLAKE2B-subkeylen(key=key, message={}, salt=subkey_id || {0}, personal=ctx || {0})`

## Nonce extension

Unlike AEGIS-256, XSalsa20 (used by `crypto_box_*` and `crypto_secretbox_*`) and XChaCha20, ciphers such as AES-GCM and ChaCha20 require a nonce too short to be chosen randomly (64 or 96 bits). With 96-bit random nonces, 2^32 encryptions is the limit before the probability of duplicate nonces becomes too high.

Using a counter instead of random nonces prevents this. However, keeping a state is not always an option, especially with offline protocols.

As an alternative, the nonce can be extended: a key and part of a long nonce are used as inputs to a pseudorandom function to compute a new key. This subkey and the remaining bits of the long nonce can then be used as parameters for the cipher.

For example, this allows using a 192-bit nonce with a cipher requiring a 64-bit nonce:

```
k = <key>
n = <192-bit nonce>
k' = PRF(k, n[0..127])
c = E(k', n[128..191], m)
```

Sodium also provides the `crypto_core_hchacha20()` function, which can be used as a PRF for that purpose:

```c
int crypto_core_hchacha20(unsigned char *out, const unsigned char *in,
                          const unsigned char *k, const unsigned char *c);
```

This function accepts a 32-byte (`crypto_core_hchacha20_KEYBYTES`) secret key `k` as well as a 16-byte (`crypto_core_hchacha20_INPUTBYTES`) input `in` and outputs a 32-byte (`crypto_core_hchacha20_OUTPUTBYTES`) value indistinguishable from random data without knowing `k`.

Optionally, a 16-byte (`crypto_core_hchacha20_CONSTBYTES`) constant `c` can be specified to personalize the function to an application. `c` can be left to `NULL` to use the default constant.

The following code snippet illustrates how XChaCha20, the variant of ChaCha20-Poly1305 with a 192-bit nonce, is built:

```c
#define MESSAGE (const unsigned char *) "message"
#define MESSAGE_LEN 7

unsigned char c[crypto_aead_chacha20poly1305_ABYTES + MESSAGE_LEN];
unsigned char k[crypto_core_hchacha20_KEYBYTES];
unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES];
unsigned char n[crypto_core_hchacha20_INPUTBYTES +
                crypto_aead_chacha20poly1305_NPUBBYTES];

randombytes_buf(k, sizeof k);
randombytes_buf(n, sizeof n); /* 192-bits nonce */

crypto_core_hchacha20(k2, n, k, NULL);

assert(crypto_aead_chacha20poly1305_KEYBYTES <= sizeof k2);
assert(crypto_aead_chacha20poly1305_NPUBBYTES ==
       (sizeof n) - crypto_core_hchacha20_INPUTBYTES);

crypto_aead_chacha20poly1305_encrypt(c, NULL, MESSAGE, MESSAGE_LEN,
                                     NULL, 0, NULL,
                                     n + crypto_core_hchacha20_INPUTBYTES,
                                     k2);
```


# HKDF

HKDF (HMAC-based Extract-and-Expand Key Derivation Function) is a key derivation function used by many standard protocols.

It actually includes two operations:

* **extract:** this operation absorbs an arbitrary-long sequence of bytes and outputs a fixed-size master key (also known as `PRK`), suitable for use with the second function (*expand*).
* **expand:** this operation generates an variable size subkey given a master key (also known as `PRK`) and a description of a key (or “context”) to derive from it. That operation can be repeated with different descriptions in order to derive as many keys as necessary.

The latter can be used without the former, if a randomly sampled key of the right size is already available.

## Deriving keys from a master key

Example:

```c
unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES];
unsigned char subkey1[32];
unsigned char subkey2[32];
unsigned char subkey3[64];

crypto_kdf_hkdf_sha256_keygen(prk);

crypto_kdf_hkdf_sha256_expand(subkey1, sizeof subkey1,
                              "key for encryption",
                              (sizeof "key for encryption") - 1,
                              prk);
crypto_kdf_hkdf_sha256_expand(subkey2, sizeof subkey2,
                              "key for signatures",
                              (sizeof "key for signatures") - 1,
                              prk);
crypto_kdf_hkdf_sha256_expand(subkey3, sizeof subkey3,
                              "key for something else",
                              (sizeof "key for something else") - 1,
                              prk);
```

Usage:

```c
int crypto_kdf_hkdf_sha256_expand(
    unsigned char *out, size_t out_len,
    const char *ctx, size_t ctx_len,
    const unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]);
```

The `crypto_kdf_hkdf_sha256_expand()` function derives a subkey from a context/description `ctx` of length `ctx_len` bytes and a master key `prk` of length `crypto_kdf_hkdf_sha256_KEYBYTES` bytes.

The key is stored into `out` whose length is `out_len` bytes.

Up to `crypto_kdf_hkdf_sha256_BYTES_MAX` bytes can be produced.

The generated keys satisfy the typical requirements of keys used for symmetric cryptography. In particular, they appear to be sampled from a uniform distribution over the entire range of possible keys.

Contexts don’t have to be secret. They just need to be distinct in order to produce distinct keys from the same master key.

Any `crypto_kdf_hkdf_sha256_KEYBYTES` bytes key that appears to be sampled from a uniform distribution can be used for the `prk`. For example, the output of a key exchange mechanism (such as `crypto_kx_*`) can be used as a master key.

For convenience, the `crypto_kdf_hkdf_sha256_keygen()` function creates a random `prk`.

The master key should remain secret.

`crypto_kdf_hkdf_sha256_expand()` is effectively a standard alternative to `crypto_kdf_derive_from_key()`. It is slower, but the context can be of any size.

## Creating a master key from input keying material

Example:

```c
#define APPLICATION_UUID "6723D3AA-C6CA-4F3C-8F24-94B550C5F10A"
#define IKM "John Doe - 951a 6158 4fe0 8a0b ad7c b57b 7687 09b6"

crypto_kdf_hkdf_sha256_extract(prk,
                               (const unsigned char *) APPLICATION_UUID,
                               (sizeof APPLICATION_UUID) - 1,
                               (const unsigned char *) IKM,
                               (sizeof IKM) - 1);
```

Usage:

```c
int crypto_kdf_hkdf_sha256_extract(unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES],
                                   const unsigned char *salt, size_t salt_len,
                                   const unsigned char *ikm, size_t ikm_len);
```

The `crypto_kdf_hkdf_sha256_extract()` function creates a master key (`prk`) given an optional salt `salt` (which can be `NULL`, or `salt_len` bytes), and input keying material `ikm` of size `ikm_len` bytes.

`salt` is optional. It can be a public, unique identifier for a protocol or application. Its purpose is to ensure that distinct keys will be created even if the input keying material is accidentally reused across protocols.

A UUID is a decent example of a `salt`. There is no minimum length.

If input keying material cannot be accidentally reused, using an empty (`NULL`) salt is perfectly acceptable.

`ikm` (Input Keying Material) is an arbitrary-long byte sequence. The bytes don’t have to be sampled from a uniform distribution. It can be any combination of text and binary data.

But the overall sequence needs to include some entropy.

The resulting PRK will roughly have the same entropy. The “extract” operation effectively extracts the entropy and packs it into a fixed-size key, but it doesn’t *add* any entropy.

## Incremental entropy extraction

Example:

```c
#define IKM1 "John Doe - "
#define IKM2 "951a 6158 4fe0 8a0b ad7c b57b 7687 09b6"

crypto_kdf_hkdf_sha256_extract_init(&st, NULL, 0);
crypto_kdf_hkdf_sha256_extract_update(&st,
                                      (const unsigned char *) IKM1,
                                      (sizeof IKM1) - 1);
crypto_kdf_hkdf_sha256_extract_update(&st,
                                      (const unsigned char *) IKM2,
                                      (sizeof IKM2) - 1);
crypto_kdf_hkdf_sha256_extract_final(&st, prk);
```

Usage:

```c
int crypto_kdf_hkdf_sha256_extract_init(
    crypto_kdf_hkdf_sha256_state *state,
    const unsigned char *salt, size_t salt_len);

int crypto_kdf_hkdf_sha256_extract_update(
    crypto_kdf_hkdf_sha256_state *state,
    const unsigned char *ikm, size_t ikm_len);

int crypto_kdf_hkdf_sha256_extract_final(
    crypto_kdf_hkdf_sha256_state *state,
    unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]);
```

Instead of a one-shot call to `crypto_kdf_hkdf_sha256_extract()`, it is possible to feed the input keying material incrementally.

In order to do so, initialize a state with `crypto_kdf_hkdf_sha256_extract_init()`, then call `crypto_kdf_hkdf_sha256_extract_update()` as many times as required, and finally generate the key with `crypto_kdf_hkdf_sha256_extract_final()`.

## HKDF-SHA256 and HKDF-SHA512

Both the `SHA256` and the `SHA512` instantiations are supported.

The functions documented above use `HKDF-SHA256`, but the `HKDF-SHA512` can be used simply by replacing the `crypto_kdf_hkdf_sha256` prefix with `crypto_kdf_hkdf_sha512`.

`HKDF-SHA512` is present for consistency and compatibility with existing protocols, but it doesn’t have practical security benefits over `HKDF-SHA256`.

Therefore, the `SHA256` instantiation is generally recommended.

## Constants

* `crypto_kdf_hkdf_sha256_KEYBYTES`
* `crypto_kdf_hkdf_sha256_BYTES_MIN`
* `crypto_kdf_hkdf_sha256_BYTES_MAX`
* `crypto_kdf_hkdf_sha512_KEYBYTES`
* `crypto_kdf_hkdf_sha512_BYTES_MIN`
* `crypto_kdf_hkdf_sha512_BYTES_MAX`

## Algorithm details

* [RFC5869 - HMAC-based Extract-and-Expand Key Derivation Function](https://www.rfc-editor.org/rfc/rfc5869.html)

## Notes

HKDF was added in libsodium version 1.0.19.


# Key exchange

## Example (client-side)

```c
unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], client_sk[crypto_kx_SECRETKEYBYTES];
unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES];

/* Generate the client's key pair */
crypto_kx_keypair(client_pk, client_sk);

/* Prerequisite after this point: the server's public key must be known by the client */

/* Compute two shared keys using the server's public key and the client's secret key.
   client_rx will be used by the client to receive data from the server,
   client_tx will be used by the client to send data to the server. */
if (crypto_kx_client_session_keys(client_rx, client_tx,
                                  client_pk, client_sk, server_pk) != 0) {
    /* Suspicious server public key, bail out */
}
```

## Example (server-side)

```c
unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], server_sk[crypto_kx_SECRETKEYBYTES];
unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES];

/* Generate the server's key pair */
crypto_kx_keypair(server_pk, server_sk);

/* Prerequisite after this point: the client's public key must be known by the server */

/* Compute two shared keys using the client's public key and the server's secret key.
   server_rx will be used by the server to receive data from the client,
   server_tx will be used by the server to send data to the client. */
if (crypto_kx_server_session_keys(server_rx, server_tx,
                                  server_pk, server_sk, client_pk) != 0) {
    /* Suspicious client public key, bail out */
}
```

## Purpose

Using the key exchange API, two parties can securely compute a set of shared keys using their peer’s public key and their own secret key.

This API was introduced in libsodium 1.0.12.

## Usage

```c
int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
                      unsigned char sk[crypto_kx_SECRETKEYBYTES]);
```

The `crypto_kx_keypair()` function creates a new key pair. It puts the public key into `pk` and the secret key into `sk`.

```c
int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
                           unsigned char sk[crypto_kx_SECRETKEYBYTES],
                           const unsigned char seed[crypto_kx_SEEDBYTES]);
```

The `crypto_kx_seed_keypair()` function computes a deterministic key pair from the seed `seed` (`crypto_kx_SEEDBYTES` bytes).

```c
int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
                                  unsigned char tx[crypto_kx_SESSIONKEYBYTES],
                                  const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
                                  const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
                                  const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]);
```

The `crypto_kx_client_session_keys()` function computes a pair of shared keys (`rx` and `tx`) using the client’s public key `client_pk`, the client’s secret key `client_sk`, and the server’s public key `server_pk`.

It returns `0` on success and `-1` if the server’s public key is not acceptable.

These keys can be used by any functions requiring secret keys up to `crypto_kx_SESSIONKEYBYTES` bytes, including `crypto_secretbox_*()` and `crypto_aead_*()`.

The shared secret key `rx` should be used by the client to receive data from the server, whereas `tx` should be used for data flowing in the opposite direction.

`rx` and `tx` are both `crypto_kx_SESSIONKEYBYTES` bytes long. If only one session key is required, either `rx` or `tx` can be set to `NULL`.

```c
int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
                                  unsigned char tx[crypto_kx_SESSIONKEYBYTES],
                                  const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],
                                  const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],
                                  const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]);
```

The `crypto_kx_server_session_keys()` function computes a pair of shared keys (`rx` and `tx`) using the server’s public key `server_pk`, the server’s secret key `server_sk`, and the client’s public key `client_pk`.

It returns `0` on success and `-1` if the client’s public key is not acceptable.

The shared secret key `rx` should be used by the server to receive data from the client, whereas `tx` should be used for data flowing in the opposite direction.

`rx` and `tx` are both `crypto_kx_SESSIONKEYBYTES` bytes long. If only one session key is required, either `rx` or `tx` can be set to `NULL`.

## Constants

* `crypto_kx_PUBLICKEYBYTES`
* `crypto_kx_SECRETKEYBYTES`
* `crypto_kx_SEEDBYTES`
* `crypto_kx_SESSIONKEYBYTES`
* `crypto_kx_PRIMITIVE`

## Algorithm details

Let `p.n` be the `crypto_scalarmult_curve25519_BYTES` byte output of the X25519 key exchange operation. The 512-bit output of `BLAKE2B-512` is split into two 256-bit keys `client_rx` and `client_tx`.

`client_rx = server_tx` and `client_tx = server_rx`.

`client_rx || client_tx = BLAKE2B-512(p.n || client_pk || server_pk)`

## Notes

For earlier versions of the library that didn’t implement this API, the X25519 function is accessible directly using the `crypto_scalarmult_*()` API.

Having different keys for each direction allows counters to be safely used as nonces without having to wait for an acknowledgment after every message.


# Advanced

The functions outlined in this section are low-level and implement specific algorithms.

They are only designed to be used as building blocks for custom constructions or interoperability with other libraries and applications.

As a result, using these functions directly may not be secure if not done correctly.

The behavior and/or interface of these functions can change at any point in time.

Low-level functions that are not required by high-level APIs are also not present in libsodium when compiled in minimal mode.

Unless you need these specific algorithms, use the high-level APIs when possible.

Bindings for third-party languages are encouraged to use the high-level APIs as well. The underlying functions they depend on are guaranteed to never change without a major version bump of the library.


# SHA-2

The SHA-256 and SHA-512 functions are provided for interoperability with other applications. If you are looking for a generic hash function and not specifically SHA-2, using [`crypto_generichash()`](https://libsodium.gitbook.io/doc/hashing/generic_hashing) (BLAKE2b) might be a better choice.

These functions are also not suitable for hashing passwords or deriving keys from passwords. Use one of the [password hashing](https://libsodium.gitbook.io/doc/password_hashing) APIs instead.

These functions are not keyed and are thus deterministic. In addition, the untruncated versions are vulnerable to length extension attacks.

A message can be hashed in a single pass, but a streaming API is also available to process a message as a sequence of multiple chunks.

## Single-part SHA-256 example

```c
#define MESSAGE ((const unsigned char *) "test")
#define MESSAGE_LEN 4

unsigned char out[crypto_hash_sha256_BYTES];

crypto_hash_sha256(out, MESSAGE, MESSAGE_LEN);
```

## Multi-part SHA-256 example

```c
#define MESSAGE_PART1 \
    ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_PART1_LEN 22

#define MESSAGE_PART2 \
    ((const unsigned char *) "is longer than expected")
#define MESSAGE_PART2_LEN 23

unsigned char out[crypto_hash_sha256_BYTES];
crypto_hash_sha256_state state;

crypto_hash_sha256_init(&state);

crypto_hash_sha256_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN);
crypto_hash_sha256_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN);

crypto_hash_sha256_final(&state, out);
```

## Usage

### SHA-256

Single-part:

```c
int crypto_hash_sha256(unsigned char *out, const unsigned char *in,
                       unsigned long long inlen);
```

Multi-part:

```c
int crypto_hash_sha256_init(crypto_hash_sha256_state *state);

int crypto_hash_sha256_update(crypto_hash_sha256_state *state,
                              const unsigned char *in,
                              unsigned long long inlen);

int crypto_hash_sha256_final(crypto_hash_sha256_state *state,
                             unsigned char *out);
```

### SHA-512

Single-part:

```c
int crypto_hash_sha512(unsigned char *out, const unsigned char *in,
                       unsigned long long inlen);
```

Multi-part:

```c
int crypto_hash_sha512_init(crypto_hash_sha512_state *state);

int crypto_hash_sha512_update(crypto_hash_sha512_state *state,
                              const unsigned char *in,
                              unsigned long long inlen);

int crypto_hash_sha512_final(crypto_hash_sha512_state *state,
                             unsigned char *out);
```

## Notes

The state must be initialized with `crypto_hash_sha*_init()` before updating or finalizing it.

After `crypto_hash_sha*_final()`, the state should not be used any more, unless it is reinitialized using `crypto_hash_sha*_init()`.

SHA-512-256 is also available via the higher-level interface `crypto_hash()`.

As an alternative to `crypto_auth_hmac*()` or `crypto_generichash()`, the SHA-256 and SHA-512 hash functions [can be keyed](https://tosc.iacr.org/index.php/ToSC/article/view/12072/11913), but the key must be placed after the message, after having padded the message to the block size (64 bytes for SHA-256, 128 bytes for SHA-512). Using the key as a prefix, rather than a suffix would allow for length extension attacks.

## Constants

* `crypto_hash_sha256_BYTES`
* `crypto_hash_sha512_BYTES`

## Data types

* `crypto_hash_sha256_state`
* `crypto_hash_sha512_state`


# SHA-3

The SHA3-256 and SHA3-512 functions are provided for interoperability with other applications and protocols. If you are looking for a general-purpose hash function and not specifically SHA-3, using [`crypto_generichash()`](https://libsodium.gitbook.io/doc/hashing/generic_hashing) (BLAKE2b) is usually a better choice.

These functions are also not suitable for hashing passwords or deriving keys from passwords. Use one of the [password hashing](https://libsodium.gitbook.io/doc/password_hashing) APIs instead.

These functions are not keyed and are thus deterministic.

A message can be hashed in a single pass, but a streaming API is also available to process a message as a sequence of multiple chunks.

All these functions return `0` on success.

## Single-part SHA3-256 example

```c
#define MESSAGE ((const unsigned char *) "test")
#define MESSAGE_LEN 4

unsigned char out[crypto_hash_sha3256_BYTES];

crypto_hash_sha3256(out, MESSAGE, MESSAGE_LEN);
```

## Single-part SHA3-512 example

```c
#define MESSAGE ((const unsigned char *) "test")
#define MESSAGE_LEN 4

unsigned char out[crypto_hash_sha3512_BYTES];

crypto_hash_sha3512(out, MESSAGE, MESSAGE_LEN);
```

## Multi-part SHA3-256 example

```c
#define MESSAGE_PART1 \
    ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_PART1_LEN 22

#define MESSAGE_PART2 \
    ((const unsigned char *) "is longer than expected")
#define MESSAGE_PART2_LEN 23

unsigned char out[crypto_hash_sha3256_BYTES];
crypto_hash_sha3256_state state;

crypto_hash_sha3256_init(&state);

crypto_hash_sha3256_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN);
crypto_hash_sha3256_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN);

crypto_hash_sha3256_final(&state, out);
```

## Usage

### SHA3-256

Single-part:

```c
int crypto_hash_sha3256(unsigned char *out, const unsigned char *in,
                        unsigned long long inlen);
```

Multi-part:

```c
int crypto_hash_sha3256_init(crypto_hash_sha3256_state *state);

int crypto_hash_sha3256_update(crypto_hash_sha3256_state *state,
                               const unsigned char *in,
                               unsigned long long inlen);

int crypto_hash_sha3256_final(crypto_hash_sha3256_state *state,
                              unsigned char *out);
```

### SHA3-512

Single-part:

```c
int crypto_hash_sha3512(unsigned char *out, const unsigned char *in,
                        unsigned long long inlen);
```

Multi-part:

```c
int crypto_hash_sha3512_init(crypto_hash_sha3512_state *state);

int crypto_hash_sha3512_update(crypto_hash_sha3512_state *state,
                               const unsigned char *in,
                               unsigned long long inlen);

int crypto_hash_sha3512_final(crypto_hash_sha3512_state *state,
                              unsigned char *out);
```

## Notes

The state must be initialized with `crypto_hash_sha3*_init()` before updating or finalizing it.

After `crypto_hash_sha3*_final()`, the state should not be used any more, unless it is reinitialized using `crypto_hash_sha3*_init()`.

The `crypto_hash_sha3256_statebytes()` and `crypto_hash_sha3512_statebytes()` helper functions return the size of the corresponding state structures and are useful when state objects need to be allocated dynamically.

These functions were introduced in libsodium 1.0.22.

## Constants

* `crypto_hash_sha3256_BYTES`
* `crypto_hash_sha3512_BYTES`

## Data types

* `crypto_hash_sha3256_state`
* `crypto_hash_sha3512_state`


# ML-KEM768

The `crypto_kem_mlkem768_*()` functions expose the ML-KEM768 key encapsulation primitive.

This is a low-level API. For most applications, use the high-level [`crypto_kem_*()`](https://libsodium.gitbook.io/doc/public-key_cryptography/key_encapsulation) API instead.

## Example

```c
unsigned char pk[crypto_kem_mlkem768_PUBLICKEYBYTES];
unsigned char sk[crypto_kem_mlkem768_SECRETKEYBYTES];
unsigned char ciphertext[crypto_kem_mlkem768_CIPHERTEXTBYTES];
unsigned char client_key[crypto_kem_mlkem768_SHAREDSECRETBYTES];
unsigned char server_key[crypto_kem_mlkem768_SHAREDSECRETBYTES];

crypto_kem_mlkem768_keypair(pk, sk);

if (crypto_kem_mlkem768_enc(ciphertext, client_key, pk) != 0) {
    /* error */
}
if (crypto_kem_mlkem768_dec(server_key, ciphertext, sk) != 0) {
    /* error */
}
```

## Purpose

ML-KEM768 is a post-quantum key encapsulation mechanism standardized by NIST.

It can be used to create a shared secret for a recipient using only the public key of that recipient.

For libsodium applications, the high-level `crypto_kem_*()` API is usually a better choice because it uses X-Wing, which combines ML-KEM768 with X25519.

## Usage

```c
int crypto_kem_mlkem768_keypair(unsigned char *pk, unsigned char *sk);
```

The `crypto_kem_mlkem768_keypair()` function creates a new key pair. It puts the public key into `pk` and the secret key into `sk`.

```c
int crypto_kem_mlkem768_seed_keypair(unsigned char *pk, unsigned char *sk,
                                     const unsigned char *seed);
```

The `crypto_kem_mlkem768_seed_keypair()` function computes a deterministic key pair from `seed` (`crypto_kem_mlkem768_SEEDBYTES` bytes).

```c
int crypto_kem_mlkem768_enc(unsigned char *ct, unsigned char *ss,
                            const unsigned char *pk);
```

The `crypto_kem_mlkem768_enc()` function creates a ciphertext `ct` for the recipient public key `pk` and stores the shared secret into `ss`.

It returns `0` on success and `-1` on failure.

```c
int crypto_kem_mlkem768_enc_deterministic(unsigned char *ct,
                                          unsigned char *ss,
                                          const unsigned char *pk,
                                          const unsigned char *seed);
```

The `crypto_kem_mlkem768_enc_deterministic()` function is similar to `crypto_kem_mlkem768_enc()`, but takes an explicit 32-byte seed instead of using internal randomness.

This is mainly useful for reproducible test vectors.

It returns `0` on success and `-1` on failure.

```c
int crypto_kem_mlkem768_dec(unsigned char *ss, const unsigned char *ct,
                            const unsigned char *sk);
```

The `crypto_kem_mlkem768_dec()` function verifies and decapsulates the ciphertext `ct` using the recipient secret key `sk`, and stores the shared secret into `ss`.

It returns `0` on success and `-1` on failure.

## Constants

* `crypto_kem_mlkem768_PUBLICKEYBYTES`
* `crypto_kem_mlkem768_SECRETKEYBYTES`
* `crypto_kem_mlkem768_CIPHERTEXTBYTES`
* `crypto_kem_mlkem768_SHAREDSECRETBYTES`
* `crypto_kem_mlkem768_SEEDBYTES`

## Notes

Unlike the high-level `crypto_kem_*()` API, this primitive does not combine ML-KEM768 with a classical key exchange algorithm.

If long-term interoperability is not required, prefer the high-level `crypto_kem_*()` API.

These functions were introduced in libsodium 1.0.22.


# HMAC-SHA-2

The keyed message authentication codes HMAC-SHA-256, HMAC-SHA-512 and HMAC-SHA512-256 (truncated HMAC-SHA-512) are provided.

The [`crypto_auth`](https://libsodium.gitbook.io/doc/secret-key_cryptography/secret-key_authentication) API provides a simplified interface for message authentication.

If required, a streaming API is available to process a message as a sequence of multiple chunks.

## Single-part example

```c
#define MESSAGE ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_LEN 22

unsigned char hash[crypto_auth_hmacsha512_BYTES];
unsigned char key[crypto_auth_hmacsha512_KEYBYTES];

crypto_auth_hmacsha512_keygen(key);
crypto_auth_hmacsha512(hash, MESSAGE, MESSAGE_LEN, key);
```

## Multi-part example

```c
#define MESSAGE_PART1 \
    ((const unsigned char *) "Arbitrary data to hash")
#define MESSAGE_PART1_LEN 22

#define MESSAGE_PART2 \
    ((const unsigned char *) "is longer than expected")
#define MESSAGE_PART2_LEN 23

unsigned char hash[crypto_auth_hmacsha512_BYTES];
unsigned char key[crypto_auth_hmacsha512_KEYBYTES];
crypto_auth_hmacsha512_state state;

crypto_auth_hmacsha512_keygen(key);

crypto_auth_hmacsha512_init(&state, key, sizeof key);

crypto_auth_hmacsha512_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN);
crypto_auth_hmacsha512_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN);

crypto_auth_hmacsha512_final(&state, hash);
```

## Usage

### HMAC-SHA-256

```c
int crypto_auth_hmacsha256(unsigned char *out,
                           const unsigned char *in,
                           unsigned long long inlen,
                           const unsigned char *k);
```

The `crypto_auth_hmacsha256()` function authenticates a message `in` whose length is `inlen` using the secret key `k` whose length is `crypto_auth_hmacsha256_KEYBYTES`, and puts the authenticator into `out` (`crypto_auth_hmacsha256_BYTES` bytes).

```c
int crypto_auth_hmacsha256_verify(const unsigned char *h,
                                  const unsigned char *in,
                                  unsigned long long inlen,
                                  const unsigned char *k);
```

The `crypto_auth_hmacsha256_verify()` function verifies in constant time that `h` is a correct authenticator for the message `in` whose length is `inlen` under a secret key `k` (`crypto_auth_hmacsha256_KEYBYTES` bytes).

It returns `-1` if the verification fails, and `0` on success.

A multi-part (streaming) API can be used instead of `crypto_auth_hmacsha256()`:

```c
int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
                                const unsigned char *key,
                                size_t keylen);
```

```c
int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
                                  const unsigned char *in,
                                  unsigned long long inlen);
```

```c
int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
                                 unsigned char *out);
```

This alternative API supports a key of arbitrary length `keylen`.

If `keylen` is `0`, `key` can be `NULL`.

However, please note that in the HMAC construction, a key larger than the block size gets reduced to `h(key)`.

```c
void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

### HMAC-SHA-512

Similarly to the `crypto_auth_hmacsha256_*()` set of functions, the `crypto_auth_hmacsha512_*()` set of functions implements HMAC-SHA512:

```c
int crypto_auth_hmacsha512(unsigned char *out,
                           const unsigned char *in,
                           unsigned long long inlen,
                           const unsigned char *k);
```

```c
int crypto_auth_hmacsha512_verify(const unsigned char *h,
                                  const unsigned char *in,
                                  unsigned long long inlen,
                                  const unsigned char *k);
```

```c
int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state,
                                const unsigned char *key,
                                size_t keylen);
```

If `keylen` is `0`, `key` can be `NULL`.

```c
int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state,
                                  const unsigned char *in,
                                  unsigned long long inlen);
```

```c
int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state,
                                 unsigned char *out);
```

```c
void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]);
```

### HMAC-SHA-512-256

HMAC-SHA-512-256 is implemented as HMAC-SHA-512 with the output truncated to 256 bits. This is slightly faster than HMAC-SHA-256. Note that this construction is not the same as HMAC-SHA-512/256, which is HMAC using the SHA-512/256 function.

```c
int crypto_auth_hmacsha512256(unsigned char *out,
                              const unsigned char *in,
                              unsigned long long inlen,
                              const unsigned char *k);
```

```c
int crypto_auth_hmacsha512256_verify(const unsigned char *h,
                                     const unsigned char *in,
                                     unsigned long long inlen,
                                     const unsigned char *k);
```

```c
int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state,
                                   const unsigned char *key,
                                   size_t keylen);
```

```c
int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state,
                                     const unsigned char *in,
                                     unsigned long long inlen);
```

```c
int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state,
                                    unsigned char *out);
```

```c
void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]);
```

## Constants

* `crypto_auth_hmacsha256_BYTES`
* `crypto_auth_hmacsha256_KEYBYTES`
* `crypto_auth_hmacsha512_BYTES`
* `crypto_auth_hmacsha512_KEYBYTES`
* `crypto_auth_hmacsha512256_BYTES`
* `crypto_auth_hmacsha512256_KEYBYTES`

## Data types

* `crypto_auth_hmacsha256_state`
* `crypto_auth_hmacsha512_state`
* `crypto_auth_hmacsha512256_state`

## Notes

* The state must be initialized with `crypto_auth_hmacsha*_init()` before updating or finalizing it. After `crypto_auth_hmacsha*_final()` returns, the state should not be used any more, unless it is reinitialized using `crypto_auth_hmacsha*_init()`.
* Arbitrary key lengths are supported using the multi-part interface. However, keys larger than 32 bytes are generally useless, even with SHA-512. It has been proven that HMAC offers PRF security with *any* sufficiently large key length.
* `crypto_auth_hmacsha256_*()` can be used to create AWS HMAC-SHA256 request signatures.
* `crypto_auth_hmacsha512_*()` is only provided for compatibility with legacy protocols specifically requiring that construction. The 32-byte authenticator offered by other functions is more than enough to guarantee that collisions will never occur.
* Only use these functions for interoperability with 3rd party services. For everything else, you should probably use `crypto_auth()`/`crypto_auth_verify()` or `crypto_generichash_*()` instead.

## References

* [When Messages are Keys: Is HMAC a dual-PRF?](https://eprint.iacr.org/2023/861.pdf) - M. Backendal, M. Bellare, Fl. Günther, M. Scarlata.


# The Scrypt function

Sodium provides an implementation of the scrypt password hashing function.

However, unless you have specific reasons to use scrypt, you should instead consider the default function, [Argon2](https://libsodium.gitbook.io/doc/password_hashing/default_phf).

## Example 1: key derivation

```c
#define PASSWORD "Correct Horse Battery Staple"
#define KEY_LEN crypto_box_SEEDBYTES

unsigned char salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
unsigned char key[KEY_LEN];

randombytes_buf(salt, sizeof salt);

if (crypto_pwhash_scryptsalsa208sha256
    (key, sizeof key, PASSWORD, strlen(PASSWORD), salt,
     crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE,
     crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
    /* out of memory */
}
```

## Example 2: password storage

```c
#define PASSWORD "Correct Horse Battery Staple"

char hashed_password[crypto_pwhash_scryptsalsa208sha256_STRBYTES];

if (crypto_pwhash_scryptsalsa208sha256_str
    (hashed_password, PASSWORD, strlen(PASSWORD),
     crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE,
     crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE) != 0) {
    /* out of memory */
}

if (crypto_pwhash_scryptsalsa208sha256_str_verify
    (hashed_password, PASSWORD, strlen(PASSWORD)) != 0) {
    /* wrong password */
}
```

## Key derivation

```c
int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out,
                                       unsigned long long outlen,
                                       const char * const passwd,
                                       unsigned long long passwdlen,
                                       const unsigned char * const salt,
                                       unsigned long long opslimit,
                                       size_t memlimit);
```

The `crypto_pwhash_scryptsalsa208sha256()` function derives an `outlen` bytes long key from a password `passwd` whose length is `passwdlen` and a salt `salt` whose fixed length is `crypto_pwhash_scryptsalsa208sha256_SALTBYTES` bytes.

The computed key is stored into `out`. `out` (and hence `outlen`) should be at least `crypto_pwhash_scryptsalsa208sha256_BYTES_MIN` and at most `crypto_pwhash_scryptsalsa208sha256_BYTES_MAX` (\~127 GB).

`passwd` (and hence `passwdlen`) should be at least `crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN` and at most `crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX`.

`opslimit` represents the maximum amount of computations to perform. Raising this number will make the function require more CPU cycles to compute a key. This number must be between `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN` and `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX`.

`memlimit` is the maximum amount of RAM in bytes that the function will use. It is highly recommended to allow the function to use at least 16 MiB. This number must be between `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN` and `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX`.

For interactive, online operations, `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE` and `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE` provide a safe baseline for these two parameters. However, using higher values may improve security.

For highly sensitive data, `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE` and `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE` can be used as an alternative. However, with these parameters, deriving a key takes about 2 seconds on a 2.8 GHz Core i7 CPU and requires up to 1 GiB of dedicated RAM.

The `salt` should be unpredictable. `randombytes_buf()` is the easiest way to fill the `crypto_pwhash_scryptsalsa208sha256_SALTBYTES` bytes of the salt.

Keep in mind that to produce the same key from the same password, the same salt, `opslimit`, and `memlimit` values must be used. Therefore, these parameters must be stored for each user.

The function returns `0` on success and `-1` if the computation didn’t complete, usually because the operating system refused to allocate the amount of requested memory.

## Password storage

```c
int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
                                           const char * const passwd,
                                           unsigned long long passwdlen,
                                           unsigned long long opslimit,
                                           size_t memlimit);
```

The `crypto_pwhash_scryptsalsa208sha256_str()` function puts an ASCII encoded string into `out`, which includes:

* the result of a memory-hard, CPU-intensive hash function applied to the password `passwd` of length `passwdlen`;
* the automatically generated salt used for the previous computation;
* the other parameters required to verify the password: `opslimit` and `memlimit`.

`crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE` and `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE` are safe baseline values to use for `opslimit` and `memlimit`.

The output string is zero-terminated, includes only ASCII characters, and can be safely stored in SQL databases and other data stores. No extra information has to be stored to verify the password.

The function returns `0` on success and `-1` if it didn’t complete successfully.

```c
int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
                                                  const char * const passwd,
                                                  unsigned long long passwdlen);
```

This function verifies that the password `str` is a valid password verification string (as generated by `crypto_pwhash_scryptsalsa208sha256_str()`) for `passwd` whose length is `passwdlen`.

`str` must be zero-terminated.

It returns `0` if the verification succeeds and `-1` on error.

## Guidelines for choosing scrypt parameters

Start by determining how much memory the scrypt function can use. What will be the highest number of threads/processes evaluating the function simultaneously (ideally, no more than 1 per CPU core)? How much physical memory is guaranteed to be available?

`memlimit` should be a power of 2. Do not use anything less than 16 MiB, even for interactive use.

Then a reasonable starting point for `opslimit` is `memlimit / 32`.

Measure how long the scrypt function needs to hash a password. If this is way too long for your application, reduce `memlimit` and adjust `opslimit` using the above formula.

If the function is so fast that you can afford it to be more computationally intensive without any usability issues, increase `opslimit`.

For online use (e.g. logging in on a website), a 1 second computation is likely to be the acceptable maximum.

For interactive use (e.g. a desktop application), a 5 second pause after having entered a password is acceptable if the password doesn’t need to be entered more than once per session.

For non-interactive and infrequent use (e.g. restoring an encrypted backup), an even slower computation can be an option.

However, the best defense against brute-force password cracking is to use strong passwords. Libraries such as [passwdqc](http://www.openwall.com/passwdqc/) can help enforce this.

## Low-level scrypt API

The traditional, low-level scrypt API is also available:

```c
int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen,
                                          const uint8_t * salt, size_t saltlen,
                                          uint64_t N, uint32_t r, uint32_t p,
                                          uint8_t * buf, size_t buflen);
```

Please note that `r` is specified in kilobytes, not in bytes as in the Sodium API.

## Constants

* `crypto_pwhash_scryptsalsa208sha256_BYTES_MIN`
* `crypto_pwhash_scryptsalsa208sha256_BYTES_MAX`
* `crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN`
* `crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX`
* `crypto_pwhash_scryptsalsa208sha256_SALTBYTES`
* `crypto_pwhash_scryptsalsa208sha256_STRBYTES`
* `crypto_pwhash_scryptsalsa208sha256_STRPREFIX`
* `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN`
* `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX`
* `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN`
* `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX`
* `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE`
* `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE`
* `crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE`
* `crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE`

## Notes

Do not forget to initialize the library with `sodium_init()`. `crypto_pwhash_scryptsalsa208sha256_*` will still work without doing so but possibly way slower.

Do not use constants (including `crypto_pwhash_cryptsalsa208sha256_OPSLIMIT_*` and `crypto_pwhash_cryptsalsa208sha256_MEMLIMIT_*`) to verify a password or produce a deterministic output. Save the parameters alongside the hash instead.

By doing so, passwords can be rehashed using different parameters if required later on.

For password verification, the recommended interface is `crypto_pwhash_cryptsalsa208sha256_str()` and `crypto_pwhash_cryptsalsa208sha256_str_verify()`. The string produced by `crypto_pwhash_cryptsalsa208sha256_str()` already includes an algorithm identifier and all the parameters, including the automatically generated salt, that were used to hash the password. Subsequently, `crypto_pwhash_cryptsalsa208sha256_str_verify()` automatically decodes these parameters.

Plaintext passwords should not stay in memory longer than needed.

It is highly recommended to use `sodium_mlock()` to lock memory regions storing plaintext passwords and to call `sodium_munlock()` right after `crypto_pwhash_scryptsalsa208sha256_str()` and `crypto_pwhash_scryptsalsa208sha256_str_verify()` return.

`sodium_munlock()` overwrites the region with zeros before unlocking it, so it doesn’t have to be done before calling this function.

By design, a password whose length is 65 bytes or more is reduced to `SHA-256(password)`. This can have security implications if the password is present in another password database using raw, unsalted SHA-256 or when upgrading passwords previously hashed with unsalted SHA-256 to scrypt.

If this is a concern, then passwords should be pre-hashed before being hashed using scrypt:

```c
char prehashed_password[56];
crypto_generichash((unsigned char *) prehashed_password, 56,
    (const unsigned char *) password, strlen(password), NULL, 0);
crypto_pwhash_scryptsalsa208sha256_str(out, prehashed_password, 56, ...);
...
crypto_pwhash_scryptsalsa208sha256_str_verify(str, prehashed_password, 56);
```

## Algorithm details

* [The scrypt Password-Based Key Derivation Function](https://www.rfc-editor.org/rfc/rfc7914.txt)


# Point\*scalar multiplication

Sodium provides an API for X25519, the Diffie-Hellman function over Curve25519 defined in [RFC 7748](https://www.rfc-editor.org/rfc/rfc7748.txt). It performs clamped scalar multiplication on the u-coordinate of points, and is specifically designed for key exchange. It can be used to compute a shared secret from two parties’ keys, or to derive an X25519 public key from a secret key.

On current libsodium versions, you generally want to use the [`crypto_kx`](https://libsodium.gitbook.io/doc/key_exchange) API for key exchange instead.

## Usage

```c
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
```

Given a user’s secret key `n` (`crypto_scalarmult_SCALARBYTES` bytes), the `crypto_scalarmult_base()` function computes the corresponding X25519 public key and puts it into `q` (`crypto_scalarmult_BYTES` bytes). Internally, this clamps the scalar and multiplies it by the Curve25519 base point.

`crypto_scalarmult_BYTES` and `crypto_scalarmult_SCALARBYTES` are provided for consistency, but it is safe to assume that `crypto_scalarmult_BYTES == crypto_scalarmult_SCALARBYTES`.

```c
int crypto_scalarmult(unsigned char *q, const unsigned char *n,
                      const unsigned char *p);
```

This function can be used to compute a shared secret `q` given a user’s secret key and another user’s public key.

`n` is `crypto_scalarmult_SCALARBYTES` bytes long, `p` and the output are `crypto_scalarmult_BYTES` bytes long.

`q` represents the X coordinate of a point on the curve. As a result, the number of possible keys is limited to the group size (≈2^252), which is smaller than the key space.

For this reason, and to mitigate subtle attacks due to the fact many (`p`, `n`) pairs produce the same result, using the output of the multiplication `q` directly as a shared key is not recommended.

A better way to compute a shared key is `h(q ‖ pk1 ‖ pk2)`, with `pk1` and `pk2` being the public keys.

By doing so, each party can prove what exact public key they intended to perform a key exchange with (for a given public key, 11 other public keys producing the same shared secret can be trivially computed).

This can be achieved with the following code snippet:

```c
unsigned char client_publickey[crypto_box_PUBLICKEYBYTES];
unsigned char client_secretkey[crypto_box_SECRETKEYBYTES];
unsigned char server_publickey[crypto_box_PUBLICKEYBYTES];
unsigned char server_secretkey[crypto_box_SECRETKEYBYTES];
unsigned char scalarmult_q_by_client[crypto_scalarmult_BYTES];
unsigned char scalarmult_q_by_server[crypto_scalarmult_BYTES];
unsigned char sharedkey_by_client[crypto_generichash_BYTES];
unsigned char sharedkey_by_server[crypto_generichash_BYTES];
crypto_generichash_state h;

/* Create client's secret and public keys */
randombytes_buf(client_secretkey, sizeof client_secretkey);
crypto_scalarmult_base(client_publickey, client_secretkey);

/* Create server's secret and public keys */
randombytes_buf(server_secretkey, sizeof server_secretkey);
crypto_scalarmult_base(server_publickey, server_secretkey);
```

```c
/* The client derives a shared key from its secret key and the server's public key */
/* shared key = h(q ‖ client_publickey ‖ server_publickey) */
if (crypto_scalarmult(scalarmult_q_by_client, client_secretkey, server_publickey) != 0) {
    /* Error */
}
crypto_generichash_init(&h, NULL, 0U, sizeof sharedkey_by_client);
crypto_generichash_update(&h, scalarmult_q_by_client, sizeof scalarmult_q_by_client);
crypto_generichash_update(&h, client_publickey, sizeof client_publickey);
crypto_generichash_update(&h, server_publickey, sizeof server_publickey);
crypto_generichash_final(&h, sharedkey_by_client, sizeof sharedkey_by_client);
```

```c
/* The server derives a shared key from its secret key and the client's public key */
/* shared key = h(q ‖ client_publickey ‖ server_publickey) */
if (crypto_scalarmult(scalarmult_q_by_server, server_secretkey, client_publickey) != 0) {
    /* Error */
}
crypto_generichash_init(&h, NULL, 0U, sizeof sharedkey_by_server);
crypto_generichash_update(&h, scalarmult_q_by_server, sizeof scalarmult_q_by_server);
crypto_generichash_update(&h, client_publickey, sizeof client_publickey);
crypto_generichash_update(&h, server_publickey, sizeof server_publickey);
crypto_generichash_final(&h, sharedkey_by_server, sizeof sharedkey_by_server);

/* sharedkey_by_client and sharedkey_by_server are identical */
```

If the intent is to create 256-bit keys (or less) for encryption, the final hash can also be set to output 512 bits: the first half can be used as a key to encrypt in one direction (for example from the server to the client), and the other half can be used in the other direction.

When using counters as nonces, having distinct keys allows the client and the server to safely send multiple messages without having to wait for an acknowledgment after each message.

```c
typedef struct kx_session_keypair {
    unsigned char rx[32];
    unsigned char tx[32];
} kx_session_keypair;

kx_session_keypair kp;

if (crypto_scalarmult(scalarmult_q_by_client, client_secretkey, server_publickey) != 0) {
    /* Error */
}
crypto_generichash_init(&h, NULL, 0U, sizeof session_keypair_by_client);
crypto_generichash_update(&h, scalarmult_q_by_client, sizeof scalarmult_q_by_client);
crypto_generichash_update(&h, client_publickey, sizeof client_publickey);
crypto_generichash_update(&h, server_publickey, sizeof server_publickey);
crypto_generichash_final(&h, session_keypair_by_client, sizeof session_keypair_by_client);
```

`kp->tx` is a key that the server can use in order to encrypt data sent to the client, and `kp->rx` is a key that can be used in the opposite direction.

## Constants

* `crypto_scalarmult_BYTES`
* `crypto_scalarmult_SCALARBYTES`

## Notes

X25519 is not a generic scalar multiplication over the Curve25519 group. The scalar is clamped (the three lowest bits are cleared, and bit 254 is set), which ensures the result is always in the prime-order subgroup and avoids small-subgroup attacks. As a consequence, not every scalar can be represented, and the function is not suitable for protocols that require unclamped operations.

As X25519 encodes a field element that is always smaller than 2^255, the top bit is not used.

## Algorithm

* X25519 (ECDH over Curve25519) - [RFC 7748](https://www.rfc-editor.org/rfc/rfc7748.txt)


# One-time authentication

One-time authentication in Sodium uses Poly1305, a Wegman-Carter authenticator designed by D. J. Bernstein.

Poly1305 takes a 32-byte, one-time key and a message and produces a 16-byte tag that authenticates the message such that an attacker has a negligible chance of producing a valid tag for an inauthentic message.

Poly1305 keys have to be:

* secret. An attacker can compute a valid authentication tag for any message, for any given key. The security of Poly1305 relies on the fact that attackers don’t know the key being used to compute the tag. This implies that they have to be:
* unpredictable. Do not use timestamps or counters.
* unique. Never reuse a key. A new key is required for every single message. The key can be recovered if two messages are authenticated with the same key.

The standard way to use Poly1305 is to derive a dedicated subkey from a `(key, nonce)` tuple, for example by taking the first bytes generated by a stream cipher.

Due to its output size, Poly1305 is recommended for online protocols, exchanging many small messages, rather than for authenticating very large files.

Finally, Poly1305 is not a replacement for a hash function.

## Single-part example

```c
#define MESSAGE ((const unsigned char *) "Data to authenticate")
#define MESSAGE_LEN 20

unsigned char out[crypto_onetimeauth_BYTES];
unsigned char key[crypto_onetimeauth_KEYBYTES];

crypto_onetimeauth_keygen(key);
crypto_onetimeauth(out, MESSAGE, MESSAGE_LEN, key);

if (crypto_onetimeauth_verify(out, MESSAGE, MESSAGE_LEN, key) != 0) {
    /* message forged! */
}
```

## Multi-part example

```c
#define MESSAGE1 ((const unsigned char *) "Multi-part")
#define MESSAGE1_LEN 10
#define MESSAGE2 ((const unsigned char *) "data")
#define MESSAGE2_LEN 4

unsigned char out[crypto_onetimeauth_BYTES];
unsigned char key[crypto_onetimeauth_KEYBYTES];
crypto_onetimeauth_state state;

crypto_onetimeauth_keygen(key);

crypto_onetimeauth_init(&state, key);
crypto_onetimeauth_update(&state, MESSAGE1, MESSAGE1_LEN);
crypto_onetimeauth_update(&state, MESSAGE2, MESSAGE2_LEN);
crypto_onetimeauth_final(&state, out);
```

## Usage

### Single-part interface

```c
int crypto_onetimeauth(unsigned char *out, const unsigned char *in,
                       unsigned long long inlen, const unsigned char *k);
```

The `crypto_onetimeauth()` function authenticates a message `in` whose length is `inlen` using a secret key `k` (`crypto_onetimeauth_KEYBYTES` bytes) and puts the authenticator into `out` (`crypto_onetimeauth_BYTES` bytes).

```c
int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in,
                              unsigned long long inlen, const unsigned char *k);
```

The `crypto_onetimeauth_verify()` function verifies, in constant time, that `h` is a correct authenticator for the message `in` whose length is `inlen` bytes, using the secret key `k`.

It returns `-1` if the verification fails, or `0` on success.

### Multi-part (streaming) interface

```c
int crypto_onetimeauth_init(crypto_onetimeauth_state *state,
                            const unsigned char *key);
```

```c
int crypto_onetimeauth_update(crypto_onetimeauth_state *state,
                              const unsigned char *in,
                              unsigned long long inlen);
```

```c
int crypto_onetimeauth_final(crypto_onetimeauth_state *state,
                             unsigned char *out);
```

The `crypto_onetimeauth_init()` function initializes a structure pointed by `state` using a key `key`.

A 16 bytes alignment is required for the address of `state`. The size of this value can be obtained using `sizeof(crypto_onetimeauth_state)`, or `crypto_onetimeauth_statebytes()`.

`crypto_onetimeauth_update()` can then be called more than one in order to compute the authenticator from sequential chunks of the message.

Finally, `crypto_onetimeauth_final()` puts the authenticator into `out`.

The state must be initialized with `crypto_onetimeauth_init()` before updating or finalizing it.

After `crypto_onetimeauth_final()` returns, the state should not be used any more, unless it is reinitialized using `crypto_onetimeauth_init()`.

```c
void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]);
```

The `crypto_onetimeauth_keygen()` function fills `k` with a random key. This convenience function was introduced in libsodium 1.0.12.

## Constants

* `crypto_onetimeauth_BYTES`
* `crypto_onetimeauth_KEYBYTES`

## Data types

* `crypto_onetimeauth_state`

## Algorithm details

* Poly1305


# Stream ciphers

Sodium includes implementations of the Salsa20, XSalsa20, ChaCha20 and XChaCha20 stream ciphers.

These functions are stream ciphers. They do not provide authenticated encryption.

They can be used to generate pseudo-random data from a key, or as building blocks for implementing custom constructions, but they are not alternatives to `crypto_secretbox_*()`.


# ChaCha20

ChaCha20 is a stream cipher developed by Daniel J. Bernstein. Its original design expands a 256-bit key into 2^64 randomly accessible streams, each containing 2^64 randomly accessible 64-byte (512 bits) blocks. It is a variant of Salsa20 with better diffusion.

ChaCha20 doesn’t require any lookup tables and avoids the possibility of timing attacks.

Internally, ChaCha20 works like a block cipher used in counter mode. It includes an internal block counter to avoid incrementing the nonce after each block.

Two variants of the ChaCha20 cipher are implemented in libsodium:

* The original ChaCha20 cipher with a 64-bit nonce and a 64-bit counter, allowing a practically unlimited amount of data to be encrypted with the same `(key, nonce)` pair.
* The IETF variant increases the nonce size to 96 bits, but reduces the counter size down to 32 bits, allowing only up to 256 GB of data to be safely encrypted with a given `(key, nonce)` pair.

These primitives should only be used to implement protocols that specifically require them. For all other applications, it is recommended to use the high-level `crypto_stream` API (XSalsa20) or the ChaCha20-based construction with an extended nonce, XChaCha20 (`crypto_stream_xchacha20`).

## Usage (original construction)

```c
int crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
                           const unsigned char *n, const unsigned char *k);
```

The `crypto_stream_chacha20()` function stores `clen` pseudo random bytes into `c` using a nonce `n` (`crypto_stream_chacha20_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_chacha20_KEYBYTES` bytes).

```c
int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m,
                               unsigned long long mlen, const unsigned char *n,
                               const unsigned char *k);
```

The `crypto_stream_chacha20_xor()` function encrypts a message `m` of length `mlen` using a nonce `n` (`crypto_stream_chacha20_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_chacha20_KEYBYTES` bytes).

The ciphertext is put into `c`. The ciphertext is the message combined with the output of the stream cipher using the XOR operation, and doesn’t include any authentication tag.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

```c
int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
                                  unsigned long long mlen,
                                  const unsigned char *n, uint64_t ic,
                                  const unsigned char *k);
```

The `crypto_stream_chacha20_xor_ic()` function is similar to `crypto_stream_chacha20_xor()` but adds the ability to set the initial value of the block counter to a non-zero value, `ic`.

This permits direct access to any block without having to compute the previous ones.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

## Usage (IETF variant, message length limited to 256 GB)

```c
int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen,
                               const unsigned char *n, const unsigned char *k);
```

The `crypto_stream_chacha20_ietf()` function stores `clen` pseudo random bytes into `c` using a nonce `n` (`crypto_stream_chacha20_ietf_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_chacha20_ietf_KEYBYTES` bytes).

```c
int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m,
                                    unsigned long long mlen, const unsigned char *n,
                                    const unsigned char *k);
```

The `crypto_stream_chacha20_ietf_xor()` function encrypts a message `m` of length `mlen` using a nonce `n` (`crypto_stream_chacha20_ietf_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_chacha20_ietf_KEYBYTES` bytes).

The ciphertext is put into `c`. The ciphertext is the message combined with the output of the stream cipher using the XOR operation, and doesn’t include any authentication tag.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

```c
int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m,
                                       unsigned long long mlen,
                                       const unsigned char *n, uint32_t ic,
                                       const unsigned char *k);
```

The `crypto_stream_chacha20_ietf_xor_ic()` function is similar to `crypto_stream_chacha20_ietf_xor()` but adds the ability to set the initial value of the block counter to a non-zero value, `ic`.

This permits direct access to any block without having to compute the previous ones.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

## Constants

* `crypto_stream_chacha20_KEYBYTES`
* `crypto_stream_chacha20_NONCEBYTES`
* `crypto_stream_chacha20_ietf_KEYBYTES`
* `crypto_stream_chacha20_ietf_NONCEBYTES`

## Notes

The nonce is short. In order to prevent nonce reuse, if a key is being reused, it is recommended to increment the previous nonce instead of generating a random nonce every time a new stream is required.

With the IETF variant, up to 256 GB can be produced from the a (`key`, `nonce`) pair. The original design doesn’t have this limitation.


# XChaCha20

XChaCha20 is a variant of ChaCha20 with an extended nonce, allowing random nonces to be safe.

XChaCha20 doesn’t require any lookup tables and avoids the possibility of timing attacks.

Internally, XChaCha20 works like a block cipher used in counter mode. It uses the HChaCha20 hash function to derive a subkey and a subnonce from the original key and extended nonce, and a dedicated 64-bit block counter to avoid incrementing the nonce after each block.

XChaCha20 is generally recommended over plain ChaCha20 due to its extended nonce size, and its comparable performance. However, XChaCha20 is currently not widely implemented outside the libsodium library, due to the absence of formal specification.

## Usage

```c
int crypto_stream_xchacha20(unsigned char *c, unsigned long long clen,
                            const unsigned char *n, const unsigned char *k);
```

The `crypto_stream_xchacha20()` function stores `clen` pseudo random bytes into `c` using a nonce `n` (`crypto_stream_xchacha20_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_xchacha20_KEYBYTES` bytes).

```c
int crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m,
                                unsigned long long mlen, const unsigned char *n,
                                const unsigned char *k);
```

The `crypto_stream_xchacha20_xor()` function encrypts a message `m` of length `mlen` using a nonce `n` (`crypto_stream_xchacha20_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_xchacha20_KEYBYTES` bytes).

The ciphertext is put into `c`. The ciphertext is the message combined with the output of the stream cipher using the XOR operation, and doesn’t include any authentication tag.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

```c
int crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m,
                                   unsigned long long mlen,
                                   const unsigned char *n, uint64_t ic,
                                   const unsigned char *k);
```

The `crypto_stream_xchacha20_xor_ic()` function is similar to `crypto_stream_xchacha20_xor()` but adds the ability to set the initial value of the block counter to a non-zero value, `ic`.

This permits direct access to any block without having to compute the previous ones.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

```c
void crypto_stream_xchacha20_keygen(unsigned char k[crypto_stream_xchacha20_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_stream_xchacha20_KEYBYTES`
* `crypto_stream_xchacha20_NONCEBYTES`

## Notes

Unlike plain ChaCha20, the nonce is 192 bits long, so that generating a random nonce for every message is safe. If the output of the PRNG is indistinguishable from random data, the probability for a collision to happen is negligible.

XChaCha20 was implemented in libsodium 1.0.12.


# Salsa20

Salsa20 is a stream cipher developed by Daniel J. Bernstein that expands a 256-bit key into 2^64 randomly accessible streams, each containing 2^64 randomly accessible 64-byte (512 bits) blocks.

Salsa20 doesn’t require any lookup tables and avoids the possibility of timing attacks.

Internally, Salsa20 works like a block cipher used in counter mode. It uses a dedicated 64-bit block counter to avoid incrementing the nonce after each block.

The extended-nonce construction XSalsa20 is generally recommended over raw Salsa20, as it makes it easier to safely generate nonces.

## Usage

```c
int crypto_stream_salsa20(unsigned char *c, unsigned long long clen,
                          const unsigned char *n, const unsigned char *k);
```

The `crypto_stream_salsa20()` function stores `clen` pseudo random bytes into `c` using a nonce `n` (`crypto_stream_salsa20_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_salsa20_KEYBYTES` bytes).

```c
int crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m,
                              unsigned long long mlen, const unsigned char *n,
                              const unsigned char *k);
```

The `crypto_stream_salsa20_xor()` function encrypts a message `m` of length `mlen` using a nonce `n` (`crypto_stream_salsa20_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_salsa20_KEYBYTES` bytes).

The ciphertext is put into `c`. The ciphertext is the message combined with the output of the stream cipher using the XOR operation, and doesn’t include any authentication tag.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

```c
int crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m,
                                 unsigned long long mlen,
                                 const unsigned char *n, uint64_t ic,
                                 const unsigned char *k);
```

The `crypto_stream_salsa20_xor_ic()` function is similar to `crypto_stream_salsa20_xor()` but adds the ability to set the initial value of the block counter to a non-zero value, `ic`.

This permits direct access to any block without having to compute the previous ones.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

```c
void crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_stream_salsa20_KEYBYTES`
* `crypto_stream_salsa20_NONCEBYTES`

## Notes

The nonce is 64 bits long. In order to prevent nonce reuse, if a key is being reused, it is recommended to increment the previous nonce instead of generating a random nonce every time a new stream is required.

Alternatively, XSalsa20, a variant of Salsa20 with a longer nonce, can be used.

The functions described above perform 20 rounds of Salsa20.

Faster, reduced-rounds versions are also available:

### Salsa20 reduced to 12 rounds

```c
int crypto_stream_salsa2012(unsigned char *c, unsigned long long clen,
                            const unsigned char *n, const unsigned char *k);

int crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m,
                                unsigned long long mlen, const unsigned char *n,
                                const unsigned char *k);

void crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES]);
```

### Salsa20 reduced to 8 rounds

```c
int crypto_stream_salsa208(unsigned char *c, unsigned long long clen,
                           const unsigned char *n, const unsigned char *k);

int crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m,
                               unsigned long long mlen, const unsigned char *n,
                               const unsigned char *k);

void crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES]);
```

Although the best known attack against Salsa20-8 is not practical, the full-round version provides a highest security margin while still being fast enough for most purposes.


# XSalsa20

XSalsa20 is a stream cipher based upon Salsa20 but with a much longer nonce: 192 bits instead of 64 bits.

XSalsa20 uses a 256-bit key as well as the first 128 bits of the nonce in order to compute a subkey. This subkey, as well as the remaining 64 bits of the nonce, are the parameters of the Salsa20 function used to actually generate the stream.

Like Salsa20, XSalsa20 is immune to timing attacks and provides its own 64-bit block counter to avoid incrementing the nonce after each block.

But with XSalsa20’s longer nonce, it is safe to generate nonces using `randombytes_buf()` for every message encrypted with the same key without having to worry about a collision.

Sodium exposes XSalsa20 with 20 rounds as the `crypto_stream` operation.

## Usage

```c
int crypto_stream(unsigned char *c, unsigned long long clen,
                  const unsigned char *n, const unsigned char *k);
```

The `crypto_stream()` function stores `clen` pseudo random bytes into `c` using a nonce `n` (`crypto_stream_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_KEYBYTES` bytes).

```c
int crypto_stream_xor(unsigned char *c, const unsigned char *m,
                      unsigned long long mlen, const unsigned char *n,
                      const unsigned char *k);
```

The `crypto_stream_xor()` function encrypts a message `m` of length `mlen` using a nonce `n` (`crypto_stream_NONCEBYTES` bytes) and a secret key `k` (`crypto_stream_KEYBYTES` bytes).

The ciphertext is put into `c`. The ciphertext is the message combined with the output of the stream cipher using the XOR operation, and doesn’t include any authentication tag.

`m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap.

```c
void crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES]);
```

This helper function introduced in libsodium 1.0.12 creates a random key `k`.

It is equivalent to calling `randombytes_buf()` but improves code clarity and can prevent misuse by ensuring that the provided key length is always be correct.

## Constants

* `crypto_stream_KEYBYTES`
* `crypto_stream_NONCEBYTES`
* `crypto_stream_PRIMITIVE`


# Ed25519 to Curve25519

Ed25519 keys can be converted to X25519 keys, so that the same key pair can be used both for authenticated encryption (`crypto_box`) and for signatures (`crypto_sign`).

Before considering this operation, please read these relevant paragraphs from the FAQ:

* [Do I need to add a signature to encrypted messages to detect if they have been tampered with?](https://libsodium.gitbook.io/doc/quickstart#do-i-need-to-add-a-signature-to-encrypted-messages-to-detect-if-they-have-been-tampered-with)
* [How can I sign and encrypt using the same key pair?](https://libsodium.gitbook.io/doc/quickstart#how-can-i-sign-and-encrypt-using-the-same-key-pair)

## Example

```c
unsigned char ed25519_pk[crypto_sign_ed25519_PUBLICKEYBYTES];
unsigned char ed25519_skpk[crypto_sign_ed25519_SECRETKEYBYTES];
unsigned char x25519_pk[crypto_scalarmult_curve25519_BYTES];
unsigned char x25519_sk[crypto_scalarmult_curve25519_BYTES];

crypto_sign_ed25519_keypair(ed25519_pk, ed25519_skpk);

crypto_sign_ed25519_pk_to_curve25519(x25519_pk, ed25519_pk);
crypto_sign_ed25519_sk_to_curve25519(x25519_sk, ed25519_skpk);
```

## Usage

```c
int crypto_sign_ed25519_pk_to_curve25519(unsigned char *x25519_pk,
                                         const unsigned char *ed25519_pk);
```

The `crypto_sign_ed25519_pk_to_curve25519()` function converts an Ed25519 public key `ed25519_pk` to an X25519 public key and stores it into `x25519_pk`.

```c
int crypto_sign_ed25519_sk_to_curve25519(unsigned char *x25519_sk,
                                         const unsigned char *ed25519_sk);
```

The `crypto_sign_ed25519_sk_to_curve25519()` function converts an Ed25519 secret key `ed25519_sk` to an X25519 secret key and stores it into `x25519_sk`.

In order to save CPU cycles and prevent key mismatches, the `crypto_sign_open()` and `crypto_sign_verify_detached()` functions expect Ed25519 secret keys generated by `crypto_sign_keypair()` or `crypto_sign_seed_keypair()`. These keys are 64 byte long.

However, the `crypto_sign_ed25519_sk_to_curve25519()` function only reads the first 32 bytes (the 32 byte seed returned by `crypto_sign_ed25519_sk_to_seed()`) and ignores the 32 remaining bytes.

## Notes

If you can afford it, using distinct keys for signing and for encryption is still highly recommended. Signing keys are usually long-term keys, while keys used for key exchange should rather be ephemeral.

An alternative is to do the ECDH operation over the Edwards curve, avoiding the conversion altogether.

In order to do this, the `crypto_scalarmult_ed25519()` function is available.

However, that still requires computing the Edwards25519 secret key from the Ed25519 seed. See the Quickstart/FAQ page for guidance on how to do it.

## References

* [On using the same key pair for Ed25519 and an X25519 based KEM](https://eprint.iacr.org/2021/509.pdf) - E. Thormarker


# Finite field arithmetic

A set of low-level APIs to perform computations over the edwards25519 curve, only useful to implement custom constructions.

Points are represented as their Y coordinate.

## Example

Perform a secure two-party computation of `f(x) = p(x)^k`. `x` is the input sent to the second party by the first party after blinding it using a random invertible scalar `r`, and `k` is a secret key only known by the second party. `p(x)` is a hash-to-curve function.

```c
// -------- First party -------- Send blinded p(x)
unsigned char x[crypto_core_ed25519_UNIFORMBYTES];
randombytes_buf(x, sizeof x);

// Compute px = p(x), an EC point representative for x
unsigned char px[crypto_core_ed25519_BYTES];
crypto_core_ed25519_from_uniform(px, x);

// Compute a = p(x) * g^r
unsigned char r[crypto_core_ed25519_SCALARBYTES];
unsigned char gr[crypto_core_ed25519_BYTES];
unsigned char a[crypto_core_ed25519_BYTES];
crypto_core_ed25519_scalar_random(r);
crypto_scalarmult_ed25519_base_noclamp(gr, r);
crypto_core_ed25519_add(a, px, gr);

// -------- Second party -------- Send g^k and a^k
unsigned char k[crypto_core_ed25519_SCALARBYTES];
randombytes_buf(k, sizeof k);

// Compute v = g^k
unsigned char v[crypto_core_ed25519_BYTES];
crypto_scalarmult_ed25519_base(v, k);

// Compute b = a^k
unsigned char b[crypto_core_ed25519_BYTES];
if (crypto_scalarmult_ed25519(b, k, a) != 0) {
    return -1;
}

// -------- First party -------- Unblind f(x)
// Compute vir = v^(-r)
unsigned char ir[crypto_core_ed25519_SCALARBYTES];
unsigned char vir[crypto_core_ed25519_BYTES];
crypto_core_ed25519_scalar_negate(ir, r);
crypto_scalarmult_ed25519_noclamp(vir, ir, v);

// Compute f(x) = b * v^(-r) = (p(x) * g^r)^k * (g^k)^(-r)
//              = (p(x) * g)^k * g^(-k) = p(x)^k
unsigned char fx[crypto_core_ed25519_BYTES];
crypto_core_ed25519_add(fx, b, vir);
```

## Point validation

```c
int crypto_core_ed25519_is_valid_point(const unsigned char *p);
```

The `crypto_core_ed25519_is_valid_point()` function checks that `p` represents a point on the edwards25519 curve, in canonical form, on the main subgroup, and that the point doesn’t have a small order.

It returns `1` on success, and `0` if the checks didn’t pass.

In versions <= 1.0.20, this function incorrectly accepted some points not on the main subgroup (points in mixed-order subgroups like 2L, 4L, 8L). Consider using [Ristretto255](https://libsodium.gitbook.io/doc/advanced/point-arithmetic/ristretto) instead, which eliminates cofactor-related issues entirely: if a point decodes, it’s safe.

If you can’t upgrade or switch to Ristretto255, use this workaround:

```c
int is_on_main_subgroup(const unsigned char p[crypto_core_ed25519_BYTES])
{
    static const unsigned char L_1[crypto_core_ed25519_SCALARBYTES] = {
        0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
        0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
    };
    static const unsigned char ID[crypto_core_ed25519_BYTES] = {
        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    unsigned char t[crypto_core_ed25519_BYTES];
    unsigned char r[crypto_core_ed25519_BYTES];
    if (crypto_scalarmult_ed25519_noclamp(t, L_1, p) != 0 ||
        crypto_core_ed25519_add(r, t, p) != 0) {
        return 0;
    }
    return sodium_memcmp(r, ID, sizeof ID) == 0;
}
```

## Random group element

```c
void crypto_core_ed25519_random(unsigned char *p);
```

Fills `p` with the representation of a random group element.

## Elligator 2 map

```c
int crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r);
```

The `crypto_core_ed25519_from_uniform()` function maps a 32 bytes vector `r` to a point, and stores its compressed representation into `p`.

The point is guaranteed to be on the main subgroup.

This function directly exposes the Elligator 2 map, uses the high bit to set the sign of the X coordinate, and the resulting point is multiplied by the cofactor.

## Scalar multiplication

```c
int crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n,
                              const unsigned char *p);
```

The `crypto_scalarmult_ed25519()` function multiplies a point `p` by a scalar `n` and puts the Y coordinate of the resulting point into `q`.

`q` should not be used as a shared key prior to hashing.

The function returns `0` on success, or `-1` if `n` is `0` or if `p` is not on the curve, not on the main subgroup, is a point of small order, or is not provided in canonical form.

Note that `n` is “clamped” (the 3 low bits are cleared to make it a multiple of the cofactor, bit 254 is set and bit 255 is cleared to respect the original design).

```c
int crypto_scalarmult_ed25519_base(unsigned char *q, const unsigned char *n);
```

The `crypto_scalarmult_ed25519_base()` function multiplies the base point `(x, 4/5)` by a scalar `n` (clamped) and puts the Y coordinate of the resulting point into `q`.

The function returns `-1` if `n` is `0`, and `0` otherwise.

## Scalar multiplication without clamping

In order to prevent attacks using small subgroups, the `scalarmult` functions above clear lower bits of the scalar. This may be undesirable to build protocols that require `n` to be invertible.

The `noclamp` variants of these functions do not clear these bits, and do not set the high bit either. These variants expect a scalar in the `]0..L[` range.

```c
int crypto_scalarmult_ed25519_noclamp(unsigned char *q, const unsigned char *n,
                                      const unsigned char *p);
```

The function verifies that `p` is on the prime-order subgroup before performing the multiplication, and return `-1` if this is not the case or `n` is `0`. It returns `0` on success.

```c
int crypto_scalarmult_ed25519_base_noclamp(unsigned char *q, const unsigned char *n);
```

The function returns `0` on success, or `-1` if `n` is `0`.

## Point addition/subtraction

```c
int crypto_core_ed25519_add(unsigned char *r,
                            const unsigned char *p, const unsigned char *q);
```

The `crypto_core_ed25519_add()` function adds the point `p` to the point `q` and stores the resulting point into `r`.

The function returns `0` on success, or `-1` if `p` and/or `q` are not valid points.

```c
int crypto_core_ed25519_sub(unsigned char *r,
                            const unsigned char *p, const unsigned char *q);
```

The `crypto_core_ed25519_sub()` function subtracts the point `q` from the point `p` and stores the resulting point into `r`.

The function returns `0` on success, or `-1` if `p` and/or `q` are not valid points.

## Scalar arithmetic over L

The `crypto_core_ed25519_scalar_*()` function set operates over scalars in the `[0..L[` interval, `L` being the order of the main subgroup (2^252 + 27742317777372353535851937790883648493).

Non-reduced inputs are expected to be within that interval.

A random scalar can be obtained using the `crypto_core_ed25519_scalar_random()` function introduced in libsodium 1.0.17:

```c
void crypto_core_ed25519_scalar_random(unsigned char *r);
```

`crypto_core_ed25519_scalar_random()` fills `r` with a `crypto_core_ed25519_SCALARBYTES` bytes representation of the scalar in the `]0..L[` interval.

A scalar in the `[0..L[` interval can also be obtained by reducing a possibly larger value:

```c
void crypto_core_ed25519_scalar_reduce(unsigned char *r, const unsigned char *s);
```

The `crypto_core_ed25519_scalar_reduce()` function reduces `s` to `s mod L` and puts the `crypto_core_ed25519_SCALARBYTES` integer into `r`.

Note that `s` is much larger than `r` (64 bytes vs 32 bytes). Bits of `s` can be left to `0`, but the interval `s` is sampled from should be at least 317 bits to ensure almost uniformity of `r` over `L`.

```c
int crypto_core_ed25519_scalar_invert(unsigned char *recip, const unsigned char *s);
```

The `crypto_core_ed25519_scalar_invert()` function computes the multiplicative inverse of `s` over `L`, and puts it into `recip`.

```c
void crypto_core_ed25519_scalar_negate(unsigned char *neg, const unsigned char *s);
```

The `crypto_core_ed25519_scalar_negate()` function returns `neg` so that `s + neg = 0 (mod L)`.

```c
void crypto_core_ed25519_scalar_complement(unsigned char *comp, const unsigned char *s);
```

The `crypto_core_ed25519_scalar_complement()` function returns `comp` so that `s + comp = 1 (mod L)`.

```c
void crypto_core_ed25519_scalar_add(unsigned char *z,
                                    const unsigned char *x, const unsigned char *y);
```

The `crypto_core_ed25519_scalar_add()` function stores `x + y (mod L)` into `z`.

```c
void crypto_core_ed25519_scalar_sub(unsigned char *z,
                                    const unsigned char *x, const unsigned char *y);
```

The `crypto_core_ed25519_scalar_sub()` function stores `x - y (mod L)` into `z`.

```c
void crypto_core_ed25519_scalar_mul(unsigned char *z,
                                    const unsigned char *x, const unsigned char *y);
```

The `crypto_core_ed25519_scalar_mul()` function stores `x * y (mod L)` into `z`.

## Constants

* `crypto_scalarmult_ed25519_BYTES`
* `crypto_scalarmult_ed25519_SCALARBYTES`
* `crypto_core_ed25519_BYTES`
* `crypto_core_ed25519_UNIFORMBYTES`
* `crypto_core_ed25519_SCALARBYTES`
* `crypto_core_ed25519_NONREDUCEDSCALARBYTES`

## Note

These functions were introduced in libsodium 1.0.16, 1.0.17 and 1.0.18.

For a complete example using these functions, see the [SPAKE2+EE implementation](https://github.com/jedisct1/spake2-ee) for libsodium.

`crypto_core_ed25519_from_uniform()` exposes the Elligator 2 map, using the high bit for the sign of the X coordinate.


# Ristretto

[Ristretto](https://ristretto.group) is a new unified point compression format for curves over large-characteristic fields, which divides the curve’s cofactor by 4 or 8 at very little cost of performance, efficiently implementing a prime-order group.

libsodium 1.0.18+ implements ristreto255: ristretto on top of the Curve25519 curve.

Compared to Curve25519 points encoded as their coordinates, ristretto makes it easier to safely implement protocols originally designed for prime-order groups.

## Example

Perform a secure two-party computation of `f(x) = p(x)^k`. `x` is the input sent to the second party by the first party after blinding it using a random invertible scalar `r`, and `k` is a secret key only known by the second party. `p(x)` is a hash-to-group function.

```c
// -------- First party -------- Send blinded p(x)
unsigned char x[crypto_core_ristretto255_HASHBYTES];
randombytes_buf(x, sizeof x);

// Compute px = p(x), a group element derived from x
unsigned char px[crypto_core_ristretto255_BYTES];
crypto_core_ristretto255_from_hash(px, x);

// Compute a = p(x) * g^r
unsigned char r[crypto_core_ristretto255_SCALARBYTES];
unsigned char gr[crypto_core_ristretto255_BYTES];
unsigned char a[crypto_core_ristretto255_BYTES];
crypto_core_ristretto255_scalar_random(r);
crypto_scalarmult_ristretto255_base(gr, r);
crypto_core_ristretto255_add(a, px, gr);

// -------- Second party -------- Send g^k and a^k
unsigned char k[crypto_core_ristretto255_SCALARBYTES];
crypto_core_ristretto255_scalar_random(k);

// Compute v = g^k
unsigned char v[crypto_core_ristretto255_BYTES];
crypto_scalarmult_ristretto255_base(v, k);

// Compute b = a^k
unsigned char b[crypto_core_ristretto255_BYTES];
if (crypto_scalarmult_ristretto255(b, k, a) != 0) {
    return -1;
}

// -------- First party -------- Unblind f(x)
// Compute vir = v^(-r)
unsigned char ir[crypto_core_ristretto255_SCALARBYTES];
unsigned char vir[crypto_core_ristretto255_BYTES];
crypto_core_ristretto255_scalar_negate(ir, r);
crypto_scalarmult_ristretto255(vir, ir, v);

// Compute f(x) = b * v^(-r) = (p(x) * g^r)^k * (g^k)^(-r)
//              = (p(x) * g)^k * g^(-k) = p(x)^k
unsigned char fx[crypto_core_ristretto255_BYTES];
crypto_core_ristretto255_add(fx, b, vir);
```

## Encoded element validation

```c
int crypto_core_ristretto255_is_valid_point(const unsigned char *p);
```

The `crypto_core_ristretto255_is_valid_point()` function checks that `p` is a valid ristretto255-encoded element.

This operation only checks that `p` is in canonical form.

The function returns `1` on success, and `0` if the checks didn’t pass.

## Random group element

```c
void crypto_core_ristretto255_random(unsigned char *p);
```

Fills `p` with the representation of a random group element.

## Hash-to-group

```c
int crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r);
```

The `crypto_core_ristretto255_from_hash()` function maps a 64 bytes vector `r` (usually the output of a hash function) to a group element, and stores its representation into `p`.

## Scalar multiplication

```c
int crypto_scalarmult_ristretto255(unsigned char *q, const unsigned char *n,
                                   const unsigned char *p);
```

The `crypto_scalarmult_ristretto255()` function multiplies an element represented by `p` by a scalar `n` (in the `[0..L[` range) and puts the resulting element into `q`.

`q` should not be used as a shared key prior to hashing.

The function returns `0` on success, or `-1` if `q` is the identity element.

```c
int crypto_scalarmult_ristretto255_base(unsigned char *q, const unsigned char *n);
```

The `crypto_scalarmult_ristretto255_base()` function multiplies the generator by a scalar `n` (`[0..L[` range) and puts the resulting element into `q`.

The function returns `-1` if `n` is `0`, and `0` otherwise.

## Element addition/subtraction

```c
int crypto_core_ristretto255_add(unsigned char *r,
                                 const unsigned char *p, const unsigned char *q);
```

The `crypto_core_ristretto255_add()` function adds the element represented by `p` to the element `q` and stores the resulting element into `r`.

The function returns `0` on success, or `-1` if `p` and/or `q` are not valid encoded elements.

```c
int crypto_core_ristretto255_sub(unsigned char *r,
                                 const unsigned char *p, const unsigned char *q);
```

The `crypto_core_ristretto255_sub()` function subtracts the element represented by `p` to the element `q` and stores the resulting element into `r`.

The function returns `0` on success, or `-1` if `p` and/or `q` are not valid encoded elements.

## Scalar arithmetic over L

The `crypto_core_ristretto255_scalar_*()` function set operates over scalars in the `[0..L[` interval, `L` being the order of the ristretto255 group: (2^252 + 27742317777372353535851937790883648493).

Non-reduced inputs are expected to be within that interval.

A random scalar can be obtained using the `crypto_core_ristretto255_scalar_random()` function:

```c
void crypto_core_ristretto255_scalar_random(unsigned char *r);
```

`crypto_core_ristretto255_scalar_random()` fills `r` with a `crypto_core_ristretto255_SCALARBYTES` bytes representation of the scalar in the `]0..L[` interval.

A scalar in the `[0..L[` interval can also be obtained by reducing a possibly larger value:

```c
void crypto_core_ristretto255_scalar_reduce(unsigned char *r, const unsigned char *s);
```

The `crypto_core_ristretto255_scalar_reduce()` function reduces `s` to `s mod L` and puts the `crypto_core_ristretto255_SCALARBYTES` integer into `r`.

Note that `s` is much larger than `r` (64 bytes vs 32 bytes). Bits of `s` can be left to `0`, but the interval `s` is sampled from should be at least 317 bits to ensure almost uniformity of `r` over `L`.

```c
int crypto_core_ristretto255_scalar_invert(unsigned char *recip, const unsigned char *s);
```

The `crypto_core_ristretto255_scalar_invert()` function computes the multiplicative inverse of `s` over `L`, and puts it into `recip`.

```c
void crypto_core_ristretto255_scalar_negate(unsigned char *neg, const unsigned char *s);
```

The `crypto_core_ristretto255_scalar_negate()` function returns `neg` so that `s + neg = 0 (mod L)`.

```c
void crypto_core_ristretto255_scalar_complement(unsigned char *comp, const unsigned char *s);
```

The `crypto_core_ristretto255_scalar_complement()` function returns `comp` so that `s + comp = 1 (mod L)`.

```c
void crypto_core_ristretto255_scalar_add(unsigned char *z,
                                         const unsigned char *x, const unsigned char *y);
```

The `crypto_core_ristretto255_scalar_add()` function stores `x + y (mod L)` into `z`.

```c
void crypto_core_ristretto255_scalar_sub(unsigned char *z,
                                         const unsigned char *x, const unsigned char *y);
```

The `crypto_core_ristretto255_scalar_sub()` function stores `x - y (mod L)` into `z`.

```c
void crypto_core_ristretto255_scalar_mul(unsigned char *z,
                                         const unsigned char *x, const unsigned char *y);
```

The `crypto_core_ristretto255_scalar_mul()` function stores `x * y (mod L)` into `z`.

## Constants

* `crypto_scalarmult_ristretto255_BYTES`
* `crypto_scalarmult_ristretto255_SCALARBYTES`
* `crypto_core_ristretto255_BYTES`
* `crypto_core_ristretto255_HASHBYTES`
* `crypto_core_ristretto255_SCALARBYTES`
* `crypto_core_ristretto255_NONREDUCEDSCALARBYTES`

## Notes

As Ristretto encodes a field element that is always smaller than 2^255, the top bit is not used.

It can be thus used by applications to encode additional data.

Forcing the top bit to zero in order to ignore it:

```c
s[31] &= 0x7f;
```

Rejecting a key that has the top bit set:

```c
if ((s[31] & 0x80) != 0) {
    return;
}
```

## Algorithms

* `ristretto255`

## References

* [Ristretto](https://ristretto.group)
* [Decaf: Eliminating cofactors through point compression](https://eprint.iacr.org/2015/673.pdf)


# Keccak-f\[1600]

The `crypto_core_keccak1600` functions provide direct access to the Keccak-f\[1600] permutation, the core building block of SHA-3, SHAKE, and TurboSHAKE.

This is a low-level API. For most applications, use the high-level [XOF API](https://libsodium.gitbook.io/doc/hashing/xof) (SHAKE128, SHAKE256, TurboSHAKE128, TurboSHAKE256) instead.

## Usage

The API follows the sponge construction pattern:

1. Initialize the state
2. Absorb data by XORing it into the state, applying the permutation between blocks
3. Squeeze output by extracting bytes from the state, applying the permutation between blocks

```c
crypto_core_keccak1600_state state;

/* Initialize */
crypto_core_keccak1600_init(&state);

/* Absorb: XOR data into state and permute */
crypto_core_keccak1600_xor_bytes(&state, input, 0, input_len);
crypto_core_keccak1600_permute_24(&state);

/* Squeeze: extract output from state */
crypto_core_keccak1600_extract_bytes(&state, output, 0, output_len);
```

## State

```c
typedef struct crypto_core_keccak1600_state {
    unsigned char opaque[224];
} crypto_core_keccak1600_state;
```

The state is an opaque 224-byte structure with 16-byte alignment. The internal Keccak state is 200 bytes (1600 bits), with additional bytes reserved for metadata and alignment.

The state size can be queried at runtime:

```c
size_t crypto_core_keccak1600_statebytes(void);
```

Returns `224`.

## Initialization

```c
void crypto_core_keccak1600_init(crypto_core_keccak1600_state *state);
```

Initializes the state to all zeros. Must be called before any other operation on a fresh state.

## Absorbing data

```c
void crypto_core_keccak1600_xor_bytes(crypto_core_keccak1600_state *state,
                                      const unsigned char *bytes,
                                      size_t offset, size_t length);
```

XORs `length` bytes from `bytes` into the state starting at byte position `offset`.

Parameters:

* `state`: pointer to the state
* `bytes`: input data to absorb
* `offset`: byte offset within the state (0-199)
* `length`: number of bytes to XOR

The offset and length must satisfy `offset + length <= 200`. This function does not apply the permutation; call `permute_24()` or `permute_12()` after absorbing a block.

## Extracting output

```c
void crypto_core_keccak1600_extract_bytes(const crypto_core_keccak1600_state *state,
                                          unsigned char *bytes,
                                          size_t offset, size_t length);
```

Extracts `length` bytes from the state starting at byte position `offset` into `bytes`.

Parameters:

* `state`: pointer to the state (not modified)
* `bytes`: output buffer
* `offset`: byte offset within the state (0-199)
* `length`: number of bytes to extract

The offset and length must satisfy `offset + length <= 200`. This function does not apply the permutation; call `permute_24()` or `permute_12()` to generate additional output.

## Permutations

```c
void crypto_core_keccak1600_permute_24(crypto_core_keccak1600_state *state);
```

Applies the Keccak-f\[1600] permutation with 24 rounds. This is the full-strength permutation used by SHAKE128 and SHAKE256.

```c
void crypto_core_keccak1600_permute_12(crypto_core_keccak1600_state *state);
```

Applies the Keccak-p\[1600,12] permutation with 12 rounds. This reduced-round variant is used by TurboSHAKE128 and TurboSHAKE256 for approximately 2x better performance while maintaining the same security claims.

## Building a sponge

To implement a sponge-based construction:

```c
#define RATE 136  /* For a 256-bit capacity (like SHAKE256/TurboSHAKE256) */

void absorb_block(crypto_core_keccak1600_state *state,
                  const unsigned char *block) {
    crypto_core_keccak1600_xor_bytes(state, block, 0, RATE);
    crypto_core_keccak1600_permute_24(state);  /* or permute_12 for TurboSHAKE */
}

void squeeze_block(crypto_core_keccak1600_state *state,
                   unsigned char *block) {
    crypto_core_keccak1600_extract_bytes(state, block, 0, RATE);
    crypto_core_keccak1600_permute_24(state);  /* or permute_12 for TurboSHAKE */
}
```

The rate depends on the desired security level:

* 168 bytes for 128-bit security (SHAKE128, TurboSHAKE128)
* 136 bytes for 256-bit security (SHAKE256, TurboSHAKE256)

## Notes

This is a low-level primitive with no built-in padding or domain separation. Applications must implement proper padding (typically pad10\*1) and domain separation to build secure constructions.

For standard XOF functionality with proper padding and domain separation, use the high-level API:

* `crypto_xof_shake128()` / `crypto_xof_shake256()`
* `crypto_xof_turboshake128()` / `crypto_xof_turboshake256()`

The state type uses an opaque structure to provide type safety. The state must be declared as `crypto_core_keccak1600_state`, not allocated manually using the size from `crypto_core_keccak1600_statebytes()`.

These functions are constant-time and safe for use with secret data.


# Custom RNG

On Unix-based systems and on Windows, Sodium uses the facilities provided by the operating system when generating random numbers is required.

Other operating systems do not support `/dev/urandom` or it might not be suitable for cryptographic applications. These systems might provide a different way to gather random numbers.

And, on embedded operating systems, even if the system may not have such a facility, a hardware-based random number generator might be available.

In addition, reproducible results instead of unpredictable ones may be required in a testing environment.

For all these scenarios, Sodium provides a way to replace the default implementations generating random numbers.

## Usage

```c
typedef struct randombytes_implementation {
    const char *(*implementation_name)(void);
    uint32_t    (*random)(void);
    void        (*stir)(void);
    uint32_t    (*uniform)(const uint32_t upper_bound);
    void        (*buf)(void * const buf, const size_t size);
    int         (*close)(void);
} randombytes_implementation;

int randombytes_set_implementation(randombytes_implementation *impl);
```

The `randombytes_set_implementation()` function defines the set of functions required by the `randombytes_*` interface.

**This function should only be called once, before `sodium_init()`.**

## Example

Sodium ships with a sample alternative `randombytes` implementation based on the ChaCha20 stream cipher in `randombytes_internal_random.c` file.

This implementation only requires access to `/dev/urandom` or `/dev/random` (or to `RtlGenRandom()` on Windows) once, during `sodium_init()`.

It might be used instead of the default implementations in order to avoid system calls when random numbers are required.

It might also be used if a non-blocking random device is not available or not safe, but blocking would only be acceptable at initialization time.

It can be enabled with:

```c
randombytes_set_implementation(&randombytes_internal_implementation);
```

Before calling `sodium_init()`.

It does fast key erasure. However, it is not thread-safe (locks must be added if this is a requirement), and was designed to be just a boilerplate for writing implementations for embedded operating systems. `randombytes_stir()` also has to be called to rekey the generator after fork()ing.

If you are using Windows or a modern Unix-based system, you should stick to the default implementations.

## Notes

Internally, all the functions requiring random numbers use the `randombytes_*` interface.

Replacing the default implementations will affect explicit calls to `randombytes_*` functions as well as functions generating keys and nonces.

Since version 1.0.3, custom RNGs don’t need to provide `randombytes_stir()` nor `randombytes_close()` if they are not required (for example if the data comes from a system call). These can be `NULL` pointers instead. `randombytes_uniform()` doesn’t have to be defined either: a default implementation will be used if a `NULL` pointer is given.


# Internals

## Naming conventions

Sodium follows the NaCl naming conventions.

Each operation defines functions and macros in a dedicated `crypto_operation` namespace. For example, the “hash” operation defines:

* A description of the underlying primitive: `crypto_hash_PRIMITIVE`.
* Constants, such as key and output lengths: `crypto_hash_BYTES`.
* For each constant, a function returning the same value. The name is identical to the constant but all lowercase: `crypto_hash_bytes(void)`.
* A set of functions with the same prefix or identical to the prefix: `crypto_hash()`.

Low-level APIs are defined in the `crypto_operation_primitivename` namespace. For example, specific hash functions and their related macros are defined in the `crypto_hash_sha256`, `crypto_hash_sha512`, and `crypto_hash_sha512256` namespaces.

To guarantee forward compatibility, specific implementations are intentionally not directly accessible. The library is responsible for choosing the best working implementation at runtime.

For compatibility with NaCl, the size of messages and ciphertexts are given as `unsigned long long` values. Other values representing the size of an object in memory use the standard `size_t` type.

## Avoiding type confusion

An object type has only one public representation.

Points and scalars are always accepted and returned as a fixed-size, compressed, portable, and serializable bit string.

This simplifies usage and mitigates type confusion in languages that don’t enforce strict type safety.

## Thread safety

Initializing the random number generator is the only operation that requires an internal lock.

`sodium_init()` must be called before any other function. It picks the best implementations for the current platform, initializes the random number generator, and generates the canary for guarded heap allocations.

On POSIX systems, everything in libsodium is guaranteed to be thread-safe.

## Heap allocations

Cryptographic operations in Sodium never allocate memory on the heap (`malloc`, `calloc`, etc), except for `crypto_pwhash` and `sodium_malloc`.

## Prepended zeros

For some operations, the traditional NaCl API requires extra zero bytes (`*_ZEROBYTES`, `*_BOXZEROBYTES`) before messages and ciphertexts.

However, this proved to be error-prone. Therefore, functions whose input requires transformations before they can be used are discouraged in Sodium.

When NaCl API compatibility is required, alternative functions that do not require extra steps are available and recommended.

## Branches

Secrets are always compared in constant time using `sodium_memcmp()` or `crypto_verify_(16|32|64)()`.

## Alignment and endianness

All operations work on big-endian and little-endian systems and do not require pointers to be aligned.

## C macros

C header files cannot be used in other programming languages.

For this reason, none of the documented functions are macros hiding the actual symbols.

## Security first

When a balance is required, extra safety measures have a higher priority than speed. Examples include:

* Sensitive data is wiped from memory when the cost remains reasonable compared to the cost of the actual computations.
* Signatures use different code paths for verification to mitigate fault attacks and check for small order nonces.
* X25519 checks for weak public keys.
* Heap memory allocations ensure that pages are not swapped and cannot be shared with other processes.
* The code is optimized for clarity, not for the number of lines of code. Except for trivial inlined functions (e.g. helpers for unaligned memory access), implementations are self-contained.
* The default compiler flags use a conservative optimization level, with extra code to check for stack overflows and some potentially dangerous optimizations disabled. The `--enable-opt` switch remains available for more aggressive optimizations.
* A complete, safe, and consistent API is favored over compact code. Redundancy of trivial functions is acceptable to improve clarity and prevent potential bugs in applications. For example, every operation gets a dedicated `_keygen()` function.
* The default PRG doesn’t implement something complicated and potentially insecure in userland to save CPU cycles. It is fast enough for most applications while being guaranteed to be thread-safe and fork-safe in all cases. If thread safety is not required, a faster, simple, and provably secure userland implementation is provided.
* The code includes many internal consistency checks and will defensively `abort()` if something unusual is detected. This requires a few extra checks but is useful for spotting internal and application-specific bugs that tests don’t catch.

## Testing

### Unit testing

The test suite covers all the functions, symbols, and macros of the library built with `--enable-minimal`.

In addition to fixed test vectors, all functions include non-deterministic tests using variable-length, random data.

Non-scalar parameters are stored into a region allocated with `sodium_malloc()` whenever possible. This immediately detects out-of-bounds accesses, including reads. The base address is also not guaranteed to be aligned, which helps detect mishandling of unaligned data.

The Makefile for the test suite also includes a `check-valgrind` target, which checks that the whole suite passes with the Valgrind’s Memcheck, Helgrind, DRD, and SGCheck modules.

### Static analysis

Continuous static analysis of the Sodium source code is performed using Coverity and GitHub’s CodeQL scanner.

On Windows, static analysis is done using Visual Studio and Viva64 PVS-Studio.

The Clang static analyzer is also used on macOS and Linux.

Releases are never shipped until all these tools report zero defects.

### Dynamic analysis

Continuous Integration is provided by [Azure Pipelines](https://jedisct1.visualstudio.com/Libsodium), [GitHub Actions](https://github.com/jedisct1/libsodium/actions), and [AppVeyor](https://ci.appveyor.com/project/jedisct1/libsodium).

In addition, the test suite must pass on the following environments. Libsodium is manually validated on all of these before every release and before merging a new change to the `stable` branch.

* asmjs/V8 (node + in-browser), asmjs/SpiderMonkey, asmjs/JavaScriptCore
* WebAssembly/V8, WebAssembly/Firefox, WebAssembly/WASI using zig cc
* OpenBSD-current/x86\_64
* Ubuntu/x86\_64 using GCC 15, `-fsanitize=address,undefined` and Valgrind (Memcheck, Helgrind, DRD, and SGCheck)
* Ubuntu/x86\_64 using Clang 21, `-fsanitize=address,undefined` and Valgrind (Memcheck, Helgrind, DRD, and SGCheck)
* Ubuntu/x86\_64 using TCC
* Ubuntu/x86\_64 using CompCert
* Ubuntu/x86\_64 using Fil-C
* macOS using Xcode 26
* macOS using zig cc
* Windows 11 using Visual Studio 2019, 2022 and 2026 (x86 and x86\_64)
* MSYS2 using MinGW32 and MinGW64
* Arch Linux/x86\_64
* Arch Linux/ARMv6
* Debian/x86
* Debian/SPARC
* Debian/ppc
* Raspbian/Cortex-A53
* Alpine/RiscV64 - Courtesy of the GCC Compile Farm project
* Ubuntu/AArch64 - Courtesy of the GCC Compile Farm project
* Fedora/ppc64 - Courtesy of the GCC Compile Farm project
* AIX 7.1/ppc64 - Courtesy of the GCC Compile Farm project
* Debian/MIPS64 - Courtesy of the GCC Compile Farm project

### Cross-implementation testing

[crypto test vectors](https://github.com/jedisct1/crypto-test-vectors) aims to generate large collections of test vectors for cryptographic primitives using different implementations.

[libsodium validation](https://github.com/jedisct1/libsodium-validation) verifies that the output of libsodium’s implementations match the test vectors. Each release must pass all these tests on the platforms listed above.

## Bindings for other languages

Bindings are essential to the libsodium ecosystem. It is expected that:

* New versions of libsodium will be installed along with bindings written before these libsodium versions were available.
* Recent versions of these bindings will be installed along with older versions of libsodium (e.g. a stock package from a Linux distribution).

For these reasons, ABI stability is critical:

* Symbols must not be removed from non-minimal builds without changing the major version of the library. Symbols must not be replaced with macros either.
* However, symbols that will eventually be removed can be tagged with GCC’s `deprecated` attribute. They can also be removed from minimal builds.
* A data structure must be considered opaque from an application perspective, and a structure size cannot change if that size was previously exposed as a constant. Structures whose size are subject to change must only expose their size through a function.

Any major change to the library should be tested for compatibility with popular bindings, especially those recompiling a copy of the library.


# Roadmap

libsodium’s roadmap is driven by its user community, and new ideas are always welcome.

New features will gladly be implemented if they are not redundant and solve common problems.

## pre-1.0.0 roadmap

* AEAD construction (ChaCha20-Poly1305)
* API to set initial counter value in ChaCha20/Salsa20
* Big-endian compatibility
* BLAKE2
* ChaCha20
* Constant-time comparison
* Cross-compilation support
* Detached authentication for `crypto_box()` and `crypto_secretbox()`
* Detached signatures
* Deterministic key generation for `crypto_box()`
* Deterministic key generation for `crypto_sign()`
* Documentation
* Ed25519 signatures
* Emscripten support
* FP rounding mode independent Poly1305 implementation
* Faster portable Curve25519 implementation
* Fix undefined behaviors for C99
* Guarded memory
* HMAC-SHA512, HMAC-SHA256
* Hex codec
* Hide specific implementations, expose wrappers
* Higher-level API for crypto\_box
* Higher-level API for crypto\_secretbox
* Lift `ZEROBYTES` requirements
* Make all constants accessible via public functions
* MinGW port
* Minimal build mode
* NuGet packages
* Password hashing
* Pluggable random number generator
* Portable memory locking
* Position-independent code
* Replace the build system with Autotools/Libtool
* Runtime CPU features detection
* Secure memory zeroing
* Seed and public key extraction from an Ed25519 secret key
* SipHash
* Streaming support for hashing and authentication
* Streaming support for one-time authentication
* Support for arbitrary HMAC key lengths
* Support for architectures requiring strict alignment
* Visual Studio port
* 100% code coverage, static and dynamic analysis
* `arc4random*()` compatible API
* Ed25519 to X25519 keys conversion
* iOS/Android compatibility

## 1.0.x roadmap

* Constant-time bin2hex() \[DONE] and hex2bin() \[DONE]
* Constant-time base64 codecs \[DONE]
* Improve consistency and clarity of function prototypes
* Improve the documentation
* Consider `getrandom(2)` \[DONE]
* Complete the sodium-validation project
* Optimized implementations for ARM w/NEON
* AVX optimized Curve25119 \[DONE]
* Precomputed interface for crypto\_box\_easy() \[DONE]
* First-class support for JavaScript \[DONE]
* ChaCha20 and ChaCha20-Poly1305 with a 96-bit nonce and a 32-bit counter \[DONE]
* IETF-compatible ChaCha20-Poly1305 implementation \[DONE]
* SSE-optimized BLAKE2b implementation \[DONE]
* AES-GCM \[DONE]
* AES-GCM detached mode \[DONE]
* Use Montgomery reduction for GHASH
* ChaCha20-Poly1305 detached mode \[DONE]
* Argon2i as crypto\_pwhash \[DONE]
* Argon2id as crypto\_pwhash \[DONE]
* Multithreaded crypto\_pwhash \[on hold]
* Generic subkey derivation API \[DONE]
* Nonce misuse-resistant scheme
* BLAKE2 AVX2 implementations \[DONE]
* Keyed (Hash-then-Encrypt) crypto\_pwhash
* Consider yescrypt
* Argon2id \[DONE]
* Port libhydrogen’s key exchange API
* SSSE3 ChaCha20 implementation \[DONE]
* SSSE3 Salsa20 implementation \[DONE]
* SSSE3 Poly1305 implementation \[DONE]
* AVX2 Salsa20 implementation \[DONE]
* AVX2 ChaCha20 implementation \[DONE]
* AVX2 Poly1305 implementation
* AVX512 implementations \[done for Argon2, withhold for other operations due to throttling concerns]
* Key generation API \[DONE]
* Nonce/subkey generation API
* WebAssembly support \[DONE]
* Stream encryption using a CHAIN-like construction \[DONE]
* Security audit by a 3rd party \[DONE]
* Formally-verified implementations \[on hold]
* Padding API \[DONE]
* `secretstream_inject()` for nonce misuse-resistance \[on hold]
* Point addition, subtraction \[DONE]
* Point validation \[DONE]
* Hash-to-point (Elligator) \[DONE]
* SPAKE2+ \[DONE]
* Support server relief in the password hashing API
* Ristretto \[DONE]
* Consider a streaming interface for `crypto_shorthash_*()`
* AEGIS-256 \[DONE]
* AEGIS-128L \[DONE]
* AEGIS-based `secretstream` API \[PoC exists]
* HKDF/SHA-512 and HKDF/SHA-256 \[DONE]
* Standard hash-to-curve \[in progress]
* Consider [signcryption](https://github.com/jedisct1/libsodium-signcryption)
* High-level AEAD and `secretstream` APIs
* Consider ECVRF \[in progress]
* Consider FROST
* Consider using TIMECOP2
* Consider [bscrypt](https://github.com/Sc00bz/bscrypt)
* Check/mitigate the implications of the [DIT](https://developer.arm.com/documentation/ddi0601/2020-12/AArch64-Registers/DIT--Data-Independent-Timing) and [DOITM](https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/data-operand-independent-timing-isa-guidance.html) flags.
* Add SHAKE/TurboSHAKE \[Done]
* SHA-3 \[DONE]
* Add parallel Keccak/SHAKE/TurboSHAKE
* Add KT128/KT256
* AEGIS-128X and 256X
* Add more ARM optimized implementations
* Add AEGISMAC
* Consider AES-GCM-SIV
* Parallel Argon2
* Consider a streaming interface to Ed25519 signatures
* Batch signatures
* HPKE
* ML-KEM \[DONE]
* X-Wing \[DONE]
* IPCrypt \[DONE]
* CHERI support for the allocation functions
* See if `wasm32-freestanding` can be supported
* Consider BLS signatures
* Consider AES-SIV or another deterministic AE

## 2.0.0 roadmap

* Switch to a new API (closer to libhydrogen)
* Session support


