libsodium
libsodium 1.0.22 bindings for Erlang and Elixir, implemented as a NIF.
Every libsodium namespace has its own module, named after its C prefix:
crypto_secretbox_easy() is libsodium_crypto_secretbox:easy/3. Functions
take and return binaries and integers, raise badarg for arguments of the wrong
type or length, and return libsodium's status code (-1) when decryption or
verification fails. Streaming hashes, MACs, signatures, and encrypted streams
use opaque native states: each operation returns a new state and leaves its
argument unchanged.
Work that processes more than 64 KiB runs on a dirty CPU scheduler,
password hashing always does, and streaming updates (update/2 on hash, MAC, and
signature states) yield whenever their timeslice is exhausted.
API reference · Migrating to 3.0 · Development · Changelog
Installation
Add libsodium to your project's dependencies in mix.exs:
defp deps do
[
{:libsodium, "~> 3.0"}
]
end
Or in rebar.config:
{deps, [
{libsodium, "~> 3.0"}
]}.
Building requires a C compiler, make, and Erlang/OTP 27 or later. The
vendored libsodium sources are compiled into the NIF; no system library is
needed.
Examples
Keys and nonces below are fixed so the outputs are reproducible; real
applications should use each module's keygen/0 or keypair/0 and
libsodium_randombytes:buf/1 for nonces.
Secret-key authenticated encryption
Key = binary:copy(<<1>>, libsodium_crypto_secretbox:keybytes()),
Nonce = binary:copy(<<2>>, libsodium_crypto_secretbox:noncebytes()),
Ciphertext = libsodium_crypto_secretbox:easy(<<"hello">>, Nonce, Key),
<<"691178A0A6E933CF40579C1446303BC59500B29111">> = binary:encode_hex(Ciphertext),
<<"hello">> = libsodium_crypto_secretbox:open_easy(Ciphertext, Nonce, Key),
-1 = libsodium_crypto_secretbox:open_easy(<<Ciphertext/binary, 0>>, Nonce, Key).
Authenticated encryption with additional data
Key = binary:copy(<<3>>, libsodium_crypto_aead_xchacha20poly1305:ietf_keybytes()),
Nonce = binary:copy(<<4>>, libsodium_crypto_aead_xchacha20poly1305:ietf_npubbytes()),
Ciphertext = libsodium_crypto_aead_xchacha20poly1305:ietf_encrypt(<<"hello">>, <<"header">>, Nonce, Key),
<<"hello">> = libsodium_crypto_aead_xchacha20poly1305:ietf_decrypt(Ciphertext, <<"header">>, Nonce, Key).
Public-key authenticated encryption
{AlicePK, AliceSK} = libsodium_crypto_box:seed_keypair(binary:copy(<<5>>, 32)),
{BobPK, BobSK} = libsodium_crypto_box:seed_keypair(binary:copy(<<6>>, 32)),
Nonce = binary:copy(<<7>>, libsodium_crypto_box:noncebytes()),
Ciphertext = libsodium_crypto_box:easy(<<"hello">>, Nonce, BobPK, AliceSK),
<<"hello">> = libsodium_crypto_box:open_easy(Ciphertext, Nonce, AlicePK, BobSK),
Sealed = libsodium_crypto_box:seal(<<"anonymous">>, BobPK),
<<"anonymous">> = libsodium_crypto_box:seal_open(Sealed, BobPK, BobSK).
Post-quantum key encapsulation
libsodium_crypto_kem uses the xwing primitive (X-Wing), a hybrid of
ML-KEM-768 and X25519 that stays secure if either one is broken.
{PK, SK} = libsodium_crypto_kem:keypair(),
{Ciphertext, SharedSecret} = libsodium_crypto_kem:enc(PK),
SharedSecret = libsodium_crypto_kem:dec(Ciphertext, SK).
Signatures
{PK, SK} = libsodium_crypto_sign_ed25519:seed_keypair(binary:copy(<<8>>, 32)),
<<"1398F62C6D1A457C51BA6A4B5F3DBD2F69FCA93216218DC8997E416BD17D93CA">> = binary:encode_hex(PK),
Signature = libsodium_crypto_sign_ed25519:detached(<<"message">>, SK),
0 = libsodium_crypto_sign_ed25519:verify_detached(Signature, <<"message">>, PK),
-1 = libsodium_crypto_sign_ed25519:verify_detached(Signature, <<"forged">>, PK).
Hashing
<<"BDDD813C634239723171EF3FEE98579B94964E3BB1CB3E427262C8C068D52319">> =
binary:encode_hex(libsodium_crypto_generichash:crypto_generichash(<<"abc">>)),
State0 = libsodium_crypto_generichash:init(),
State1 = libsodium_crypto_generichash:update(State0, <<"a">>),
State2 = libsodium_crypto_generichash:update(State1, <<"bc">>),
Digest = libsodium_crypto_generichash:final(State2),
Digest = libsodium_crypto_generichash:crypto_generichash(<<"abc">>).
Extendable output
<<"483366601360A8771C6863080CC4114D">> =
binary:encode_hex(libsodium_crypto_xof_shake256:crypto_xof_shake256(16, <<"abc">>)),
State0 = libsodium_crypto_xof_shake256:update(libsodium_crypto_xof_shake256:init(), <<"abc">>),
{State1, First} = libsodium_crypto_xof_shake256:squeeze(State0, 8),
{_State2, Second} = libsodium_crypto_xof_shake256:squeeze(State1, 8),
Output = libsodium_crypto_xof_shake256:crypto_xof_shake256(16, <<"abc">>),
Output = <<First/binary, Second/binary>>.
Password hashing
Hash = libsodium_crypto_pwhash:str(
<<"correct horse battery staple">>,
libsodium_crypto_pwhash:opslimit_interactive(),
libsodium_crypto_pwhash:memlimit_interactive()
),
0 = libsodium_crypto_pwhash:str_verify(Hash, <<"correct horse battery staple">>),
-1 = libsodium_crypto_pwhash:str_verify(Hash, <<"wrong">>).
Key derivation and exchange
MasterKey = binary:copy(<<9>>, libsodium_crypto_kdf:keybytes()),
SubKey1 = libsodium_crypto_kdf:derive_from_key(32, 1, <<"Examples">>, MasterKey),
SubKey2 = libsodium_crypto_kdf:derive_from_key(32, 2, <<"Examples">>, MasterKey),
true = SubKey1 =/= SubKey2,
{ClientPK, ClientSK} = libsodium_crypto_kx:seed_keypair(binary:copy(<<10>>, 32)),
{ServerPK, ServerSK} = libsodium_crypto_kx:seed_keypair(binary:copy(<<11>>, 32)),
{ClientRx, ClientTx} = libsodium_crypto_kx:client_session_keys(ClientPK, ClientSK, ServerPK),
{ServerRx, ServerTx} = libsodium_crypto_kx:server_session_keys(ServerPK, ServerSK, ClientPK),
{ClientRx, ClientTx} = {ServerTx, ServerRx}.
Modules
Secret-key cryptography
| Module | Description | Functions |
|---|---|---|
libsodium_crypto_aead_aegis128l |
AEGIS-128L | 14 |
libsodium_crypto_aead_aegis256 |
AEGIS-256 | 14 |
libsodium_crypto_aead_aes256gcm |
AES256-GCM | 25 |
libsodium_crypto_aead_chacha20poly1305 |
ChaCha20-Poly1305 | 28 |
libsodium_crypto_aead_xchacha20poly1305 |
XChaCha20-Poly1305 | 14 |
libsodium_crypto_auth |
Secret-key authentication | 6 |
libsodium_crypto_auth_hmacsha256 |
HMAC-SHA-256 | 9 |
libsodium_crypto_auth_hmacsha512 |
HMAC-SHA-512 | 9 |
libsodium_crypto_auth_hmacsha512256 |
HMAC-SHA-512-256 | 9 |
libsodium_crypto_ipcrypt |
IP address encryption | 26 |
libsodium_crypto_secretbox |
Secret-key authenticated encryption | 14 |
libsodium_crypto_secretbox_xchacha20poly1305 |
XChaCha20-Poly1305 secret box | 8 |
libsodium_crypto_secretbox_xsalsa20poly1305 |
XSalsa20-Poly1305 secret box | 9 |
libsodium_crypto_secretstream_xchacha20poly1305 |
Encrypted streams | 15 |
Public-key cryptography
| Module | Description | Functions |
|---|---|---|
libsodium_crypto_box |
Public-key authenticated encryption | 28 |
libsodium_crypto_box_curve25519xchacha20poly1305 |
X25519-XChaCha20-Poly1305 box | 21 |
libsodium_crypto_box_curve25519xsalsa20poly1305 |
X25519-XSalsa20-Poly1305 box | 16 |
libsodium_crypto_kem |
Key encapsulation | 10 |
libsodium_crypto_kem_mlkem768 |
ML-KEM-768 key encapsulation | 10 |
libsodium_crypto_kem_xwing |
X-Wing key encapsulation | 10 |
libsodium_crypto_kx |
Key exchange | 9 |
libsodium_crypto_sign |
Public-key signatures | 17 |
libsodium_crypto_sign_ed25519 |
Ed25519 signatures | 20 |
libsodium_crypto_sign_ed25519ph |
Ed25519ph signatures | 5 |
Hashing
| Module | Description | Functions |
|---|---|---|
libsodium_crypto_generichash |
Generic hashing | 18 |
libsodium_crypto_generichash_blake2b |
BLAKE2b | 25 |
libsodium_crypto_hash |
Hashing (SHA-512) | 3 |
libsodium_crypto_hash_sha256 |
SHA-256 | 6 |
libsodium_crypto_hash_sha3256 |
SHA3-256 | 6 |
libsodium_crypto_hash_sha3512 |
SHA3-512 | 6 |
libsodium_crypto_hash_sha512 |
SHA-512 | 6 |
libsodium_crypto_shorthash |
Short-input hashing | 5 |
libsodium_crypto_shorthash_siphash24 |
SipHash-2-4 | 3 |
libsodium_crypto_shorthash_siphashx24 |
SipHash-2-4 (128-bit) | 3 |
libsodium_crypto_xof_shake128 |
SHAKE128 extendable-output function | 8 |
libsodium_crypto_xof_shake256 |
SHAKE256 extendable-output function | 8 |
libsodium_crypto_xof_turboshake128 |
TurboSHAKE128 extendable-output function | 8 |
libsodium_crypto_xof_turboshake256 |
TurboSHAKE256 extendable-output function | 8 |
Password hashing
| Module | Description | Functions |
|---|---|---|
libsodium_crypto_pwhash |
Password hashing | 26 |
libsodium_crypto_pwhash_argon2i |
Argon2i password hashing | 22 |
libsodium_crypto_pwhash_argon2id |
Argon2id password hashing | 22 |
libsodium_crypto_pwhash_scryptsalsa208sha256 |
Scrypt password hashing | 20 |
Key derivation
| Module | Description | Functions |
|---|---|---|
libsodium_crypto_kdf |
Key derivation | 7 |
libsodium_crypto_kdf_blake2b |
BLAKE2b key derivation | 5 |
libsodium_crypto_kdf_hkdf_sha256 |
HKDF-SHA-256 | 13 |
libsodium_crypto_kdf_hkdf_sha512 |
HKDF-SHA-512 | 13 |
Advanced
Helpers
| Module | Description | Functions |
|---|---|---|
libsodium_randombytes |
Random data | 10 |
libsodium_runtime |
CPU features | 12 |
libsodium_utils |
Helpers | 20 |
libsodium_version |
Library version | 4 |
libsodium_nif exposes all 732 native functions directly, named
<namespace>_<function>.
Development
The native sources, the Erlang modules, the generated tests, and this README
are generated from the YAML definitions in codegen/:
just codegen # or `just docker-codegen` to run in a Linux container
gmake tests # Common Test suites
gmake lint # formatting, Dialyzer, Eqwalizer, and xref
just bench # Benchee comparisons with OTP crypto; see bench/README.md
Generated files carry a signature; edit the definitions or templates and regenerate rather than changing them by hand.
License
MIT. libsodium is distributed under the ISC license.