sodium.h
header. Including individual headers is neither required nor recommended.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.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.*_keygen()
function should always be preferred.DllMain()
function (Windows) or __attribute__((constructor))
(GCC, Clang, icc on macOS and ELF-based systems) to call sodium_init()
on load.int
return 0
on success and -1
to indicate an error.NULL
on error.warn_unused_result
attribute and will cause a compiler warning if ignored. Such warnings must not be ignored.crypto_secretbox_keygen()
.randombytes_buf(nonce, sizeof nonce)
.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.crypto_secretbox_open_easy()
to decrypt the ciphertext using the same key and nonce.crypto_pwhash_str()
and crypto_pwhash_str_verify()
functions described in the password hashing guide
.A
and B
securely communicate without a pre-shared secret key?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
.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
.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
.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
).crypto_secretbox_*()
, crypto_secretstream_*()
, or crypto_aead_*()
.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.A
and B
can create such a tag.crypto_kx
), a valid tag for a message can only be created by the sender.crypto_sign_seed_keypair()
and crypto_kx_seed_keypair()
can derive specialized key pairs from the same 32-byte seed.crypto_scalarmult_ed25519()
and crypto_scalarmult_ed25519_base()
functions for scalar multiplication over edwards25519.(encryption_key || message)
first then encrypt (recipient_id || signature || message)
.(sender_id || message)
then sign the ciphertext.(H(sender_id || message) || message)
(if using AES-GCM or Salsa20/ChaCha20-Poly1305) then sign the ciphertext.sender_id
and recipient_id
are public data that uniquely identifies a party.crypto_generichash_blake2b
or just crypto_generichash
?crypto_stream()
barely documented and not even present in some bindings?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.randombytes_buf_deterministic()
function.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.(key, nonce)
tuple for every message.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.