libsodium

View Source

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

ModuleDescriptionFunctions
libsodium_crypto_aead_aegis128lAEGIS-128L14
libsodium_crypto_aead_aegis256AEGIS-25614
libsodium_crypto_aead_aes256gcmAES256-GCM25
libsodium_crypto_aead_chacha20poly1305ChaCha20-Poly130528
libsodium_crypto_aead_xchacha20poly1305XChaCha20-Poly130514
libsodium_crypto_authSecret-key authentication6
libsodium_crypto_auth_hmacsha256HMAC-SHA-2569
libsodium_crypto_auth_hmacsha512HMAC-SHA-5129
libsodium_crypto_auth_hmacsha512256HMAC-SHA-512-2569
libsodium_crypto_ipcryptIP address encryption26
libsodium_crypto_secretboxSecret-key authenticated encryption14
libsodium_crypto_secretbox_xchacha20poly1305XChaCha20-Poly1305 secret box8
libsodium_crypto_secretbox_xsalsa20poly1305XSalsa20-Poly1305 secret box9
libsodium_crypto_secretstream_xchacha20poly1305Encrypted streams15

Public-key cryptography

ModuleDescriptionFunctions
libsodium_crypto_boxPublic-key authenticated encryption28
libsodium_crypto_box_curve25519xchacha20poly1305X25519-XChaCha20-Poly1305 box21
libsodium_crypto_box_curve25519xsalsa20poly1305X25519-XSalsa20-Poly1305 box16
libsodium_crypto_kemKey encapsulation10
libsodium_crypto_kem_mlkem768ML-KEM-768 key encapsulation10
libsodium_crypto_kem_xwingX-Wing key encapsulation10
libsodium_crypto_kxKey exchange9
libsodium_crypto_signPublic-key signatures17
libsodium_crypto_sign_ed25519Ed25519 signatures20
libsodium_crypto_sign_ed25519phEd25519ph signatures5

Hashing

ModuleDescriptionFunctions
libsodium_crypto_generichashGeneric hashing18
libsodium_crypto_generichash_blake2bBLAKE2b25
libsodium_crypto_hashHashing (SHA-512)3
libsodium_crypto_hash_sha256SHA-2566
libsodium_crypto_hash_sha3256SHA3-2566
libsodium_crypto_hash_sha3512SHA3-5126
libsodium_crypto_hash_sha512SHA-5126
libsodium_crypto_shorthashShort-input hashing5
libsodium_crypto_shorthash_siphash24SipHash-2-43
libsodium_crypto_shorthash_siphashx24SipHash-2-4 (128-bit)3
libsodium_crypto_xof_shake128SHAKE128 extendable-output function8
libsodium_crypto_xof_shake256SHAKE256 extendable-output function8
libsodium_crypto_xof_turboshake128TurboSHAKE128 extendable-output function8
libsodium_crypto_xof_turboshake256TurboSHAKE256 extendable-output function8

Password hashing

ModuleDescriptionFunctions
libsodium_crypto_pwhashPassword hashing26
libsodium_crypto_pwhash_argon2iArgon2i password hashing22
libsodium_crypto_pwhash_argon2idArgon2id password hashing22
libsodium_crypto_pwhash_scryptsalsa208sha256Scrypt password hashing20

Key derivation

ModuleDescriptionFunctions
libsodium_crypto_kdfKey derivation7
libsodium_crypto_kdf_blake2bBLAKE2b key derivation5
libsodium_crypto_kdf_hkdf_sha256HKDF-SHA-25613
libsodium_crypto_kdf_hkdf_sha512HKDF-SHA-51213

Advanced

ModuleDescriptionFunctions
libsodium_crypto_core_ed25519Edwards25519 arithmetic19
libsodium_crypto_core_hchacha20HChaCha20 core5
libsodium_crypto_core_hsalsa20HSalsa20 core5
libsodium_crypto_core_keccak1600Keccak-f[1600] permutation6
libsodium_crypto_core_ristretto255Ristretto255 arithmetic17
libsodium_crypto_core_salsa20Salsa20 core5
libsodium_crypto_core_salsa2012Salsa20/12 core5
libsodium_crypto_onetimeauthOne-time authentication10
libsodium_crypto_onetimeauth_poly1305Poly13059
libsodium_crypto_scalarmultPoint multiplication5
libsodium_crypto_scalarmult_curve25519X25519 point multiplication4
libsodium_crypto_scalarmult_ed25519Ed25519 point multiplication6
libsodium_crypto_scalarmult_ristretto255Ristretto255 point multiplication4
libsodium_crypto_streamStream cipher7
libsodium_crypto_stream_chacha20ChaCha20 stream cipher14
libsodium_crypto_stream_salsa20Salsa20 stream cipher7
libsodium_crypto_stream_salsa2012Salsa20/12 stream cipher6
libsodium_crypto_stream_xchacha20XChaCha20 stream cipher7
libsodium_crypto_stream_xsalsa20XSalsa20 stream cipher7
libsodium_crypto_verify_1616-byte comparison2
libsodium_crypto_verify_3232-byte comparison2
libsodium_crypto_verify_6464-byte comparison2

Helpers

ModuleDescriptionFunctions
libsodium_randombytesRandom data10
libsodium_runtimeCPU features12
libsodium_utilsHelpers20
libsodium_versionLibrary version4

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.