libsodium

CI Hex.pm HexDocs

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

Module Description Functions
libsodium_crypto_core_ed25519 Edwards25519 arithmetic 19
libsodium_crypto_core_hchacha20 HChaCha20 core 5
libsodium_crypto_core_hsalsa20 HSalsa20 core 5
libsodium_crypto_core_keccak1600 Keccak-f[1600] permutation 6
libsodium_crypto_core_ristretto255 Ristretto255 arithmetic 17
libsodium_crypto_core_salsa20 Salsa20 core 5
libsodium_crypto_core_salsa2012 Salsa20/12 core 5
libsodium_crypto_onetimeauth One-time authentication 10
libsodium_crypto_onetimeauth_poly1305 Poly1305 9
libsodium_crypto_scalarmult Point multiplication 5
libsodium_crypto_scalarmult_curve25519 X25519 point multiplication 4
libsodium_crypto_scalarmult_ed25519 Ed25519 point multiplication 6
libsodium_crypto_scalarmult_ristretto255 Ristretto255 point multiplication 4
libsodium_crypto_stream Stream cipher 7
libsodium_crypto_stream_chacha20 ChaCha20 stream cipher 14
libsodium_crypto_stream_salsa20 Salsa20 stream cipher 7
libsodium_crypto_stream_salsa2012 Salsa20/12 stream cipher 6
libsodium_crypto_stream_xchacha20 XChaCha20 stream cipher 7
libsodium_crypto_stream_xsalsa20 XSalsa20 stream cipher 7
libsodium_crypto_verify_16 16-byte comparison 2
libsodium_crypto_verify_32 32-byte comparison 2
libsodium_crypto_verify_64 64-byte comparison 2

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.