├── secret-key_cryptography ├── README.md ├── aegis │ ├── README.md │ └── aegis-128l.md ├── chacha20-poly1305.md ├── secret-key_authentication.md ├── aes-gcm_with_precomputation.md ├── secretbox.md ├── original_chacha20-poly1305_construction.md ├── encrypted-messages.md ├── xchacha20-poly1305_construction.md └── ietf_chacha20-poly1305_construction.md ├── cover.jpg ├── cover_small.jpg ├── hashing ├── README.md ├── short-input_hashing.md └── generic_hashing.md ├── public-key_cryptography ├── README.md └── sealed_boxes.md ├── format.sh ├── advanced ├── stream_ciphers.md ├── README.md ├── xsalsa20.md ├── ed25519-curve25519.md ├── custom_rng.md ├── xchacha20.md ├── sha-2_hash_function.md ├── salsa20.md ├── poly1305.md ├── chacha20.md ├── scalar_multiplication.md ├── hmac-sha2.md ├── ristretto.md └── point-arithmetic.md ├── book.json ├── LICENSE ├── commercial_support └── README.md ├── helpers ├── padding.md ├── memory_management.md └── README.md ├── generating_random_data └── README.md ├── README.md ├── SUMMARY.md ├── password_hashing └── README.md ├── bindings_for_other_languages └── README.md ├── usage └── README.md ├── key_exchange └── README.md ├── internals ├── roadmap.md └── README.md ├── key_derivation ├── README.md └── hkdf.md └── quickstart └── multiple_recipients.md /secret-key_cryptography/README.md: -------------------------------------------------------------------------------- 1 | # Secret-key cryptography 2 | -------------------------------------------------------------------------------- /cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tniessen/libsodium-doc/HEAD/cover.jpg -------------------------------------------------------------------------------- /cover_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tniessen/libsodium-doc/HEAD/cover_small.jpg -------------------------------------------------------------------------------- /secret-key_cryptography/aegis/README.md: -------------------------------------------------------------------------------- 1 | # The AEGIS family of authenticated ciphers 2 | -------------------------------------------------------------------------------- /hashing/README.md: -------------------------------------------------------------------------------- 1 | # Hashing 2 | 3 | This page is a work in progress. Feel free to contribute a nice intro to hash functions\! 4 | -------------------------------------------------------------------------------- /public-key_cryptography/README.md: -------------------------------------------------------------------------------- 1 | # Public-key cryptography 2 | 3 | *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. 4 | -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | cmark-gfm --to commonmark --nobreaks --smart --validate-utf8 \ 4 | --extension table \ 5 | --extension strikethrough \ 6 | --extension autolink \ 7 | --extension tagfilter \ 8 | "$1" \ 9 | > "${1}.tmp" && mv -f "${1}.tmp" "$1" 10 | -------------------------------------------------------------------------------- /advanced/stream_ciphers.md: -------------------------------------------------------------------------------- 1 | # Stream ciphers 2 | 3 | Sodium includes implementations of the Salsa20, XSalsa20, ChaCha20 and XChaCha20 stream ciphers. 4 | 5 | These functions are stream ciphers. They do not provide authenticated encryption. 6 | 7 | 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_*()`. 8 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [], 3 | "pluginsConfig": { 4 | "fontSettings": { 5 | "theme": "white", 6 | "family": "sans", 7 | "size": 1 8 | } 9 | }, 10 | "links": { 11 | "home": null, 12 | "about": false, 13 | "issues": null, 14 | "contribute": null, 15 | "sharing": { 16 | "google": null, 17 | "facebook": null, 18 | "twitter": null 19 | } 20 | }, 21 | "pdf": { 22 | "toc": true, 23 | "pageNumbers": true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2023, Frank Denis 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /advanced/README.md: -------------------------------------------------------------------------------- 1 | # Advanced 2 | 3 | The functions outlined in this section are low-level and implement specific algorithms. 4 | 5 | They are only designed to be used as building blocks for custom constructions or interoperability with other libraries and applications. 6 | 7 | As a result, using these functions directly may not be secure if not done correctly. 8 | 9 | The behavior and/or interface of these functions can change at any point in time. 10 | 11 | Low-level functions that are not required by high-level APIs are also not present in libsodium when compiled in minimal mode. 12 | 13 | Unless you need these specific algorithms, use the high-level APIs when possible. 14 | 15 | 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. 16 | -------------------------------------------------------------------------------- /commercial_support/README.md: -------------------------------------------------------------------------------- 1 | # Commercial support for libsodium 2 | 3 | The following companies offer professional support services for libsodium and applications using libsodium: 4 | 5 | ## Edge Security () 6 | 7 | Libsodium-specific services include: 8 | 9 | - Cryptographic and implementation auditing of libsodium usage. 10 | - Security review of constructions, protocols, and applications using libsodium. 11 | - Consulting on libsodium usage in applications – web apps, backends, mobile, embedded, kernel, etc. 12 | - General consulting and review of cryptography inquiries. 13 | - Implementation security and helping to work toward a vulnerability-free codebase. 14 | - Reverse engineering of complicated binaries. 15 | - General consulting, advising, mentoring, and development. 16 | 17 | ## Paragon Initiative Enterprises () 18 | 19 | Libsodium-specific services include: 20 | 21 | - Library integration, with a focus on web applications (PHP, .NET, Python). 22 | - Bespoke or standard high-level protocol design and implementation (e.g. Noise). 23 | - Security audits for in-house library integrations and/or high-level protocols. 24 | - Custom application development that requires cryptography. 25 | - Consulting and mentoring services. 26 | 27 | ----- 28 | 29 | (Please submit a pull request if you want your company added to that list) 30 | -------------------------------------------------------------------------------- /secret-key_cryptography/chacha20-poly1305.md: -------------------------------------------------------------------------------- 1 | # Authenticated Encryption with Additional Data using ChaCha20-Poly1305 2 | 3 | ## Purpose 4 | 5 | This operation: 6 | 7 | - Encrypts a message with a key and a nonce to keep it confidential 8 | - 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. 9 | 10 | A typical use case for additional data is to store protocol-specific metadata about the message, such as its length and encoding. 11 | 12 | The chosen construction uses encrypt-then-MAC and decryption will never be performed, even partially, before verification. 13 | 14 | ## Variants 15 | 16 | libsodium implements three versions of the ChaCha20-Poly1305 construction: 17 | 18 | - 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). 19 | - The IETF variant. It can safely encrypt a practically unlimited number of messages, but individual messages cannot exceed 64\*(2^32)-64 bytes (approximatively 256 GB). 20 | - 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. 21 | 22 | The first two variants are fully interoperable with other crypto libaries. The XChaCha20 variant is currently only implemented in libsodium, but is the recommended option if interoperability is not a concern. 23 | 24 | They all share the same security properties when used properly, and are accessible via a similar API. 25 | 26 | 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. 27 | 28 | The constants are the same, except for the nonce size. 29 | -------------------------------------------------------------------------------- /advanced/xsalsa20.md: -------------------------------------------------------------------------------- 1 | # XSalsa20 2 | 3 | XSalsa20 is a stream cipher based upon Salsa20 but with a much longer nonce: 192 bits instead of 64 bits. 4 | 5 | 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. 6 | 7 | Like Salsa20, XSalsa20 is immune to timing attacks and provides its own 64-bit block counter to avoid incrementing the nonce after each block. 8 | 9 | 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. 10 | 11 | Sodium exposes XSalsa20 with 20 rounds as the `crypto_stream` operation. 12 | 13 | ## Usage 14 | 15 | ``` c 16 | int crypto_stream(unsigned char *c, unsigned long long clen, 17 | const unsigned char *n, const unsigned char *k); 18 | ``` 19 | 20 | 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). 21 | 22 | ``` c 23 | int crypto_stream_xor(unsigned char *c, const unsigned char *m, 24 | unsigned long long mlen, const unsigned char *n, 25 | const unsigned char *k); 26 | ``` 27 | 28 | 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). 29 | 30 | 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. 31 | 32 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 33 | 34 | ``` c 35 | void crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES]); 36 | ``` 37 | 38 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 39 | 40 | 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. 41 | 42 | ## Constants 43 | 44 | - `crypto_stream_KEYBYTES` 45 | - `crypto_stream_NONCEBYTES` 46 | - `crypto_stream_PRIMITIVE` 47 | -------------------------------------------------------------------------------- /hashing/short-input_hashing.md: -------------------------------------------------------------------------------- 1 | # Short-input hashing 2 | 3 | ## Example 4 | 5 | ``` c 6 | #define SHORT_DATA ((const unsigned char *) "Sparkling water") 7 | #define SHORT_DATA_LEN 15 8 | 9 | unsigned char hash[crypto_shorthash_BYTES]; 10 | unsigned char key[crypto_shorthash_KEYBYTES]; 11 | 12 | crypto_shorthash_keygen(key); 13 | crypto_shorthash(hash, SHORT_DATA, SHORT_DATA_LEN, key); 14 | ``` 15 | 16 | ## Purpose 17 | 18 | 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. 19 | 20 | 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. 21 | 22 | This function is optimized for short inputs. 23 | 24 | The output of this function is only 64 bits. Therefore, it should *not* be considered collision-resistant. 25 | 26 | Use cases: 27 | 28 | - Hash tables 29 | - Probabilistic data structures, such as Bloom filters 30 | - Integrity checking in interactive protocols 31 | 32 | ## Usage 33 | 34 | ``` c 35 | int crypto_shorthash(unsigned char *out, const unsigned char *in, 36 | unsigned long long inlen, const unsigned char *k); 37 | ``` 38 | 39 | Compute a fixed-size (`crypto_shorthash_BYTES` bytes) fingerprint for the message `in` whose length is `inlen` bytes, using the key `k`. 40 | 41 | The `k` is `crypto_shorthash_KEYBYTES` bytes and can be created using `crypto_shorthash_keygen()`. 42 | 43 | The same message hashed with the same key will always produce the same output. 44 | 45 | ## Constants 46 | 47 | - `crypto_shorthash_BYTES` 48 | - `crypto_shorthash_KEYBYTES` 49 | 50 | ## Algorithm details 51 | 52 | SipHash-2-4 53 | 54 | ## Notes 55 | 56 | - The key must remain secret. This function will not provide any mitigations against DoS attacks if the key is known from attackers. 57 | - 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/). 58 | - 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()`. 59 | -------------------------------------------------------------------------------- /secret-key_cryptography/secret-key_authentication.md: -------------------------------------------------------------------------------- 1 | # Secret-key authentication 2 | 3 | ## Example 4 | 5 | ``` c 6 | #define MESSAGE (const unsigned char *) "test" 7 | #define MESSAGE_LEN 4 8 | 9 | unsigned char key[crypto_auth_KEYBYTES]; 10 | unsigned char mac[crypto_auth_BYTES]; 11 | 12 | crypto_auth_keygen(key); 13 | crypto_auth(mac, MESSAGE, MESSAGE_LEN, key); 14 | 15 | if (crypto_auth_verify(mac, MESSAGE, MESSAGE_LEN, key) != 0) { 16 | /* message forged! */ 17 | } 18 | ``` 19 | 20 | ## Purpose 21 | 22 | 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. 23 | 24 | The function computing the tag deterministic: the same (message, key) tuple will always produce the same output. 25 | 26 | 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. 27 | 28 | A typical use case is: 29 | 30 | - `A` prepares a message, add an authentication tag, sends it to `B` 31 | - `A` doesn’t store the message 32 | - Later on, `B` sends the message and the authentication tag to `A` 33 | - `A` uses the authentication tag to verify that it created this message. 34 | 35 | This operation does *not* encrypt the message. It only computes and verifies an authentication tag. 36 | 37 | ## Usage 38 | 39 | ``` c 40 | int crypto_auth(unsigned char *out, const unsigned char *in, 41 | unsigned long long inlen, const unsigned char *k); 42 | ``` 43 | 44 | 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. 45 | 46 | ``` c 47 | int crypto_auth_verify(const unsigned char *h, const unsigned char *in, 48 | unsigned long long inlen, const unsigned char *k); 49 | ``` 50 | 51 | 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`. 52 | 53 | It returns `-1` if the verification fails, and `0` if it passes. 54 | 55 | ``` c 56 | void crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]); 57 | ``` 58 | 59 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 60 | 61 | 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. 62 | 63 | ## Constants 64 | 65 | - `crypto_auth_BYTES` 66 | - `crypto_auth_KEYBYTES` 67 | 68 | ## Algorithm details 69 | 70 | - HMAC-SHA512-256 71 | -------------------------------------------------------------------------------- /helpers/padding.md: -------------------------------------------------------------------------------- 1 | # Padding 2 | 3 | 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. 4 | 5 | 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. 6 | 7 | This API was introduced in libsodium 1.0.14. 8 | 9 | ## Example 10 | 11 | ``` c 12 | unsigned char buf[100]; 13 | size_t buf_unpadded_len = 10; 14 | size_t buf_padded_len; 15 | size_t block_size = 16; 16 | 17 | /* round the length of the buffer to a multiple of `block_size` by appending 18 | * padding data and put the new, total length into `buf_padded_len` */ 19 | if (sodium_pad(&buf_padded_len, buf, buf_unpadded_len, block_size, sizeof buf) != 0) { 20 | /* overflow! buf[] is not large enough */ 21 | } 22 | 23 | /* compute the original, unpadded length */ 24 | if (sodium_unpad(&buf_unpadded_len, buf, buf_padded_len, block_size) != 0) { 25 | /* incorrect padding */ 26 | } 27 | ``` 28 | 29 | ## Usage 30 | 31 | ``` c 32 | int sodium_pad(size_t *padded_buflen_p, unsigned char *buf, 33 | size_t unpadded_buflen, size_t blocksize, size_t max_buflen); 34 | ``` 35 | 36 | 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`. 37 | 38 | The new length is put into `padded_buflen_p`. 39 | 40 | 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. 41 | 42 | ``` c 43 | int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf, 44 | size_t padded_buflen, size_t blocksize); 45 | ``` 46 | 47 | 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`. 48 | 49 | ## Algorithm 50 | 51 | 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. 52 | 53 | ## Notes 54 | 55 | Padding should be applied before encryption and removed after decryption. 56 | 57 | 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. 58 | 59 | This ensures that the length of the transmitted data is constant and that the server doesn’t effortlessly get a copy of the password. 60 | 61 | 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 & ` value. 62 | -------------------------------------------------------------------------------- /advanced/ed25519-curve25519.md: -------------------------------------------------------------------------------- 1 | # Ed25519 to X25519 keys conversion 2 | 3 | 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`). 4 | 5 | Before considering this operation, please read these relevant paragraphs from the FAQ: 6 | 7 | - [Do I need to add a signature to encrypted messages to detect if they have been tampered with?](../quickstart#do-i-need-to-add-a-signature-to-encrypted-messages-to-detect-if-they-have-been-tampered-with) 8 | - [How can I sign and encrypt using the same key pair?](../quickstart#how-can-i-sign-and-encrypt-using-the-same-key-pair) 9 | 10 | ## Example 11 | 12 | ``` c 13 | unsigned char ed25519_pk[crypto_sign_ed25519_PUBLICKEYBYTES]; 14 | unsigned char ed25519_skpk[crypto_sign_ed25519_SECRETKEYBYTES]; 15 | unsigned char x25519_pk[crypto_scalarmult_curve25519_BYTES]; 16 | unsigned char x25519_sk[crypto_scalarmult_curve25519_BYTES]; 17 | 18 | crypto_sign_ed25519_keypair(ed25519_pk, ed25519_skpk); 19 | 20 | crypto_sign_ed25519_pk_to_curve25519(x25519_pk, ed25519_pk); 21 | crypto_sign_ed25519_sk_to_curve25519(x25519_sk, ed25519_skpk); 22 | ``` 23 | 24 | ## Usage 25 | 26 | ``` c 27 | int crypto_sign_ed25519_pk_to_curve25519(unsigned char *x25519_pk, 28 | const unsigned char *ed25519_pk); 29 | ``` 30 | 31 | 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`. 32 | 33 | ``` c 34 | int crypto_sign_ed25519_sk_to_curve25519(unsigned char *x25519_sk, 35 | const unsigned char *ed25519_sk); 36 | ``` 37 | 38 | 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`. 39 | 40 | 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. 41 | 42 | However, the `crypto_sign_ed25519_sk_to_curve25519()` function accepts both these 64 byte keys, and the 32 byte seed returned by `crypto_sign_ed25519_sk_to_seed()`. 43 | 44 | ## Notes 45 | 46 | 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. 47 | 48 | An alternative is do the ECDH operation over the Edwards curve, avoiding the conversion altogether. 49 | 50 | In order to do this, the `crypto_scalarmult_ed25519()` function is available. 51 | 52 | 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. 53 | 54 | ## References 55 | 56 | - [On using the same key pair for Ed25519 and an X25519 based KEM](https://eprint.iacr.org/2021/509.pdf) - E. Thormarker 57 | -------------------------------------------------------------------------------- /generating_random_data/README.md: -------------------------------------------------------------------------------- 1 | # Generating random data 2 | 3 | The library provides a set of functions to generate unpredictable data, suitable for creating secret keys. 4 | 5 | - On Windows systems, the `RtlGenRandom()` function is used. 6 | - On OpenBSD and Bitrig, the `arc4random()` function is used. 7 | - On recent FreeBSD and Linux kernels, the `getrandom` system call is used. 8 | - On other Unices, the `/dev/urandom` device is used. 9 | - If none of these options can safely be used, custom implementations can easily be hooked. 10 | 11 | ## Usage 12 | 13 | ``` c 14 | uint32_t randombytes_random(void); 15 | ``` 16 | 17 | The `randombytes_random()` function returns an unpredictable value between `0` and `0xffffffff` (included). 18 | 19 | ``` c 20 | uint32_t randombytes_uniform(const uint32_t upper_bound); 21 | ``` 22 | 23 | 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` 24 | 25 | ``` c 26 | void randombytes_buf(void * const buf, const size_t size); 27 | ``` 28 | 29 | The `randombytes_buf()` function fills `size` bytes starting at `buf` with an unpredictable sequence of bytes. 30 | 31 | ``` c 32 | void randombytes_buf_deterministic(void * const buf, const size_t size, 33 | const unsigned char seed[randombytes_SEEDBYTES]); 34 | ``` 35 | 36 | The `randombytes_buf_deterministic` function stores `size` bytes into `buf` indistinguishable from random bytes without knowing `seed`. 37 | 38 | For a given `seed`, this function will always output the same sequence. `size` can be up to 2^38 (256 GB). 39 | 40 | `seed` is `randombytes_SEEDBYTES` bytes long. 41 | 42 | 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. 43 | 44 | Up to 256 GB can be produced with a single seed. 45 | 46 | ``` c 47 | int randombytes_close(void); 48 | ``` 49 | 50 | 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. 51 | 52 | ``` c 53 | void randombytes_stir(void); 54 | ``` 55 | 56 | 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()`. 57 | 58 | If a non-default implementation is being used (see `randombytes_set_implementation()`), `randombytes_stir()` must be called by the child after a `fork()` call. 59 | 60 | ## Note 61 | 62 | 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. 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Sodium crypto library (libsodium) 2 | 3 | Sodium is a modern, easy-to-use software library for encryption, decryption, signatures, password hashing, and more. 4 | 5 | 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. 6 | 7 | Its goal is to provide all of the core operations needed to build higher-level cryptographic tools. 8 | 9 | Sodium is cross-platform and cross-language. It runs on many compilers and operating systems, including Windows (with MinGW or Visual Studio, x86 and x86\_64), 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. 10 | 11 | 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. 12 | 13 | ## Downloading libsodium 14 | 15 | [libsodium 1.0.19-stable](https://download.libsodium.org/libsodium/releases/) is the latest version. 16 | 17 | - [Tarballs and pre-compiled binaries](https://download.libsodium.org/libsodium/releases/) 18 | - [GitHub repository](https://github.com/jedisct1/libsodium) 19 | - [Documentation](https://doc.libsodium.org) 20 | 21 | ## Mailing list 22 | 23 | A mailing list is available to discuss libsodium. 24 | 25 | To join, just send a random email to `sodium-subscribe` {at} `pureftpd`{dot}`org`. 26 | 27 | ## License 28 | 29 | [ISC license](https://en.wikipedia.org/wiki/ISC_license). 30 | 31 | See the `LICENSE` file for details. 32 | 33 | ## Thanks\! 34 | 35 | Sodium is developed by volunteers. We would like to especially thank the following companies and organizations for their contribution: 36 | 37 | - [Paragonie Initiative Enterprise](https://paragonie.com/), who donated a Raspberry Pi to ensure that the library works perfectly on this hardware. Thanks\! 38 | - [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\! 39 | - [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\! 40 | 41 | 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. 42 | 43 | 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. 44 | 45 | Another huge “thank you” to package maintainers who have been doing an amazing job at building packages for many distributions and operating systems. 46 | 47 | Finally, thanks to **you** for reading this documentation and for the awesome projects you are going to build with this library\! 48 | -------------------------------------------------------------------------------- /advanced/custom_rng.md: -------------------------------------------------------------------------------- 1 | # Defining a custom random number generator 2 | 3 | On Unix-based systems and on Windows, Sodium uses the facilities provided by the operating system when generating random numbers is required. 4 | 5 | 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. 6 | 7 | And, on embedded operating systems, even if the system may not have such a facility, a hardware-based random number generator might be available. 8 | 9 | In addition, reproducible results instead of unpredictable ones may be required in a testing environment. 10 | 11 | For all these scenarios, Sodium provides a way to replace the default implementations generating random numbers. 12 | 13 | ## Usage 14 | 15 | ``` c 16 | typedef struct randombytes_implementation { 17 | const char *(*implementation_name)(void); 18 | uint32_t (*random)(void); 19 | void (*stir)(void); 20 | uint32_t (*uniform)(const uint32_t upper_bound); 21 | void (*buf)(void * const buf, const size_t size); 22 | int (*close)(void); 23 | } randombytes_implementation; 24 | 25 | int randombytes_set_implementation(randombytes_implementation *impl); 26 | ``` 27 | 28 | The `randombytes_set_implementation()` function defines the set of functions required by the `randombytes_*` interface. 29 | 30 | **This function should only be called once, before `sodium_init()`.** 31 | 32 | ## Example 33 | 34 | Sodium ships with a sample alternative `randombytes` implementation based on the ChaCha20 stream cipher in `randombytes_internal_random.c` file. 35 | 36 | This implementation only requires access to `/dev/urandom` or `/dev/random` (or to `RtlGenRandom()` on Windows) once, during `sodium_init()`. 37 | 38 | It might be used instead of the default implementations in order to avoid system calls when random numbers are required. 39 | 40 | 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. 41 | 42 | It can be enabled with: 43 | 44 | ``` c 45 | randombytes_set_implementation(&randombytes_internal_implementation); 46 | ``` 47 | 48 | Before calling `sodium_init()`. 49 | 50 | 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. 51 | 52 | If you are using Windows or a modern Unix-based system, you should stick to the default implementations. 53 | 54 | ## Notes 55 | 56 | Internally, all the functions requiring random numbers use the `randombytes_*` interface. 57 | 58 | Replacing the default implementations will affect explicit calls to `randombytes_*` functions as well as functions generating keys and nonces. 59 | 60 | 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. 61 | -------------------------------------------------------------------------------- /public-key_cryptography/sealed_boxes.md: -------------------------------------------------------------------------------- 1 | # Sealed boxes 2 | 3 | ## Example 4 | 5 | ``` c 6 | #define MESSAGE (const unsigned char *) "Message" 7 | #define MESSAGE_LEN 7 8 | #define CIPHERTEXT_LEN (crypto_box_SEALBYTES + MESSAGE_LEN) 9 | 10 | /* Recipient creates a long-term key pair */ 11 | unsigned char recipient_pk[crypto_box_PUBLICKEYBYTES]; 12 | unsigned char recipient_sk[crypto_box_SECRETKEYBYTES]; 13 | crypto_box_keypair(recipient_pk, recipient_sk); 14 | 15 | /* Anonymous sender encrypts a message using an ephemeral key pair 16 | * and the recipient's public key */ 17 | unsigned char ciphertext[CIPHERTEXT_LEN]; 18 | crypto_box_seal(ciphertext, MESSAGE, MESSAGE_LEN, recipient_pk); 19 | 20 | /* Recipient decrypts the ciphertext */ 21 | unsigned char decrypted[MESSAGE_LEN]; 22 | if (crypto_box_seal_open(decrypted, ciphertext, CIPHERTEXT_LEN, 23 | recipient_pk, recipient_sk) != 0) { 24 | /* message corrupted or not intended for this recipient */ 25 | } 26 | ``` 27 | 28 | ## Purpose 29 | 30 | Sealed boxes are designed to anonymously send messages to a recipient given their public key. 31 | 32 | 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. 33 | 34 | A message is encrypted using an ephemeral key pair, with the secret key being erased right after the encryption process. 35 | 36 | 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. 37 | 38 | ## Usage 39 | 40 | ``` c 41 | int crypto_box_seal(unsigned char *c, const unsigned char *m, 42 | unsigned long long mlen, const unsigned char *pk); 43 | ``` 44 | 45 | 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`. 46 | 47 | 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. 48 | 49 | ``` c 50 | int crypto_box_seal_open(unsigned char *m, const unsigned char *c, 51 | unsigned long long clen, 52 | const unsigned char *pk, const unsigned char *sk); 53 | ``` 54 | 55 | 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). 56 | 57 | Key pairs are compatible with other `crypto_box_*` operations and can be created using `crypto_box_keypair()` or `crypto_box_seed_keypair()`. 58 | 59 | This function doesn’t require passing the public key of the sender as the ciphertext already includes this information. 60 | 61 | ## Constants 62 | 63 | - `crypto_box_SEALBYTES` 64 | 65 | ## Algorithm details 66 | 67 | Sealed boxes leverage the `crypto_box` construction, which uses X25519 and XSalsa20-Poly1305. 68 | 69 | The format of a sealed box is 70 | 71 | ``` text 72 | ephemeral_pk ‖ box(m, recipient_pk, ephemeral_sk, nonce=blake2b(ephemeral_pk ‖ recipient_pk)) 73 | ``` 74 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Introduction](README.md) 4 | - [Installation](installation/README.md) 5 | - [Quickstart and FAQ](quickstart/README.md) 6 | - [Projects using libsodium](libsodium_users/README.md) 7 | - [Commercial support](commercial_support/README.md) 8 | - [Bindings for other languages](bindings_for_other_languages/README.md) 9 | - [Usage](usage/README.md) 10 | - [Helpers](helpers/README.md) 11 | - [Padding](helpers/padding.md) 12 | - [Secure memory](helpers/memory_management.md) 13 | - [Generating random data](generating_random_data/README.md) 14 | - [Secret-key cryptography](secret-key_cryptography/README.md) 15 | - [Authenticated encryption](secret-key_cryptography/secretbox.md) 16 | - [Encrypted streams and file encryption](secret-key_cryptography/secretstream.md) 17 | - [Encrypting a set of related messages](secret-key_cryptography/encrypted-messages.md) 18 | - [Authentication](secret-key_cryptography/secret-key_authentication.md) 19 | - [AEAD constructions](secret-key_cryptography/aead.md) 20 | - [ChaCha20-Poly1305](secret-key_cryptography/chacha20-poly1305.md) 21 | - [Original ChaCha20-Poly1305 construction](secret-key_cryptography/original_chacha20-poly1305_construction.md) 22 | - [IETF ChaCha20-Poly1305 construction](secret-key_cryptography/ietf_chacha20-poly1305_construction.md) 23 | - [XChaCha20-Poly1305 construction](secret-key_cryptography/xchacha20-poly1305_construction.md) 24 | - [AEGIS-256](secret-key_cryptography/aegis/aegis-256.md) 25 | - [AEGIS-128L](secret-key_cryptography/aegis/aegis-128l.md) 26 | - [AES256-GCM](secret-key_cryptography/aes-256-gcm.md) 27 | - [AES256-GCM with precomputation](secret-key_cryptography/aes-gcm_with_precomputation.md) 28 | - [Public-key cryptography](public-key_cryptography/README.md) 29 | - [Authenticated encryption](public-key_cryptography/authenticated_encryption.md) 30 | - [Public-key signatures](public-key_cryptography/public-key_signatures.md) 31 | - [Sealed boxes](public-key_cryptography/sealed_boxes.md) 32 | - [Hashing](hashing/README.md) 33 | - [Generic hashing](hashing/generic_hashing.md) 34 | - [Short-input hashing](hashing/short-input_hashing.md) 35 | - [Password hashing](password_hashing/README.md) 36 | - [The pwhash\* API](password_hashing/default_phf.md) 37 | - [Key derivation](key_derivation/README.md) 38 | - [HKDF](key_derivation/hkdf.md) 39 | - [Key exchange](key_exchange/README.md) 40 | - [Advanced](advanced/README.md) 41 | - [SHA-2](advanced/sha-2_hash_function.md) 42 | - [HMAC-SHA-2](advanced/hmac-sha2.md) 43 | - [The Scrypt function](password_hashing/scrypt.md) 44 | - [Point\*scalar multiplication](advanced/scalar_multiplication.md) 45 | - [One-time authentication](advanced/poly1305.md) 46 | - [Stream ciphers](advanced/stream_ciphers.md) 47 | - [ChaCha20](advanced/chacha20.md) 48 | - [XChaCha20](advanced/xchacha20.md) 49 | - [Salsa20](advanced/salsa20.md) 50 | - [XSalsa20](advanced/xsalsa20.md) 51 | - [Ed25519 to Curve25519](advanced/ed25519-curve25519.md) 52 | - [Finite field arithmetic](advanced/point-arithmetic.md) 53 | - [Ristretto](advanced/ristretto.md) 54 | - [Custom RNG](advanced/custom_rng.md) 55 | - [Internals](internals/README.md) 56 | - [Roadmap](internals/roadmap.md) 57 | -------------------------------------------------------------------------------- /password_hashing/README.md: -------------------------------------------------------------------------------- 1 | # Password hashing 2 | 3 | Secret keys used to encrypt or sign confidential data have to be chosen from a very large keyspace. 4 | 5 | However, passwords are usually short, human-generated strings, making dictionary attacks practical. 6 | 7 | Password hashing functions derive a secret key of any size from a password and salt. 8 | 9 | - The generated key has the size defined by the application, no matter what the password length is. 10 | - The same password hashed with the same parameters will always produce the same output. 11 | - The same password hashed with different salts will produce different outputs. 12 | - 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. 13 | 14 | Common use cases: 15 | 16 | - Password storage, or rather storing what it takes to verify a password without having to store the actual password. 17 | - Deriving a secret key from a password; for example, for disk encryption. 18 | 19 | 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. 20 | 21 | The more specific `crypto_pwhash_scryptsalsa208sha256_*` API uses the more conservative and widely deployed scrypt function. 22 | 23 | ## Argon2 24 | 25 | 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. 26 | 27 | Argon2 has three variants: Argon2d, Argon2i, and Argon2id. Libsodium supports Argon2i and Argon2id. 28 | 29 | ## Scrypt 30 | 31 | Scrypt was also designed to make it costly to perform large-scale custom hardware attacks by requiring large amounts of memory. 32 | 33 | 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. 34 | 35 | ## Server relief 36 | 37 | If multiple clients can simultaneously log in on a shared server, then the memory and computation requirements can exhaust the server’s resources. 38 | 39 | To mitigate this, passwords can be pre-hashed on the client (e.g. using libsodium.js in a web application): 40 | 41 | - 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. 42 | - 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. 43 | -------------------------------------------------------------------------------- /advanced/xchacha20.md: -------------------------------------------------------------------------------- 1 | # XChaCha20 2 | 3 | XChaCha20 is a variant of ChaCha20 with an extended nonce, allowing random nonces to be safe. 4 | 5 | XChaCha20 doesn’t require any lookup tables and avoids the possibility of timing attacks. 6 | 7 | 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. 8 | 9 | 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. 10 | 11 | ## Usage 12 | 13 | ``` c 14 | int crypto_stream_xchacha20(unsigned char *c, unsigned long long clen, 15 | const unsigned char *n, const unsigned char *k); 16 | ``` 17 | 18 | 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). 19 | 20 | ``` c 21 | int crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, 22 | unsigned long long mlen, const unsigned char *n, 23 | const unsigned char *k); 24 | ``` 25 | 26 | 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). 27 | 28 | 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. 29 | 30 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 31 | 32 | ``` c 33 | int crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m, 34 | unsigned long long mlen, 35 | const unsigned char *n, uint64_t ic, 36 | const unsigned char *k); 37 | ``` 38 | 39 | 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`. 40 | 41 | This permits direct access to any block without having to compute the previous ones. 42 | 43 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 44 | 45 | ``` c 46 | void crypto_stream_xchacha20_keygen(unsigned char k[crypto_stream_xchacha20_KEYBYTES]); 47 | ``` 48 | 49 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 50 | 51 | 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. 52 | 53 | ## Constants 54 | 55 | - `crypto_stream_xchacha20_KEYBYTES` 56 | - `crypto_stream_xchacha20_NONCEBYTES` 57 | 58 | ## Notes 59 | 60 | 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. 61 | 62 | XChaCha20 was implemented in libsodium 1.0.12. 63 | -------------------------------------------------------------------------------- /advanced/sha-2_hash_function.md: -------------------------------------------------------------------------------- 1 | # The SHA-2 hash functions family 2 | 3 | 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()`](../hashing/generic_hashing.md) (BLAKE2b) might be a better choice. 4 | 5 | These functions are also not suitable for hashing passwords or deriving keys from passwords. Use one of the [password hashing](../password_hashing/README.md) APIs instead. 6 | 7 | These functions are not keyed and are thus deterministic. In addition, the untruncated versions are vulnerable to length extension attacks. 8 | 9 | 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. 10 | 11 | ## Single-part SHA-256 example 12 | 13 | ``` c 14 | #define MESSAGE ((const unsigned char *) "test") 15 | #define MESSAGE_LEN 4 16 | 17 | unsigned char out[crypto_hash_sha256_BYTES]; 18 | 19 | crypto_hash_sha256(out, MESSAGE, MESSAGE_LEN); 20 | ``` 21 | 22 | ## Multi-part SHA-256 example 23 | 24 | ``` c 25 | #define MESSAGE_PART1 \ 26 | ((const unsigned char *) "Arbitrary data to hash") 27 | #define MESSAGE_PART1_LEN 22 28 | 29 | #define MESSAGE_PART2 \ 30 | ((const unsigned char *) "is longer than expected") 31 | #define MESSAGE_PART2_LEN 23 32 | 33 | unsigned char out[crypto_hash_sha256_BYTES]; 34 | crypto_hash_sha256_state state; 35 | 36 | crypto_hash_sha256_init(&state); 37 | 38 | crypto_hash_sha256_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN); 39 | crypto_hash_sha256_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN); 40 | 41 | crypto_hash_sha256_final(&state, out); 42 | ``` 43 | 44 | ## Usage 45 | 46 | ### SHA-256 47 | 48 | Single-part: 49 | 50 | ``` c 51 | int crypto_hash_sha256(unsigned char *out, const unsigned char *in, 52 | unsigned long long inlen); 53 | ``` 54 | 55 | Multi-part: 56 | 57 | ``` c 58 | int crypto_hash_sha256_init(crypto_hash_sha256_state *state); 59 | 60 | int crypto_hash_sha256_update(crypto_hash_sha256_state *state, 61 | const unsigned char *in, 62 | unsigned long long inlen); 63 | 64 | int crypto_hash_sha256_final(crypto_hash_sha256_state *state, 65 | unsigned char *out); 66 | ``` 67 | 68 | ### SHA-512 69 | 70 | Single-part: 71 | 72 | ``` c 73 | int crypto_hash_sha512(unsigned char *out, const unsigned char *in, 74 | unsigned long long inlen); 75 | ``` 76 | 77 | Multi-part: 78 | 79 | ``` c 80 | int crypto_hash_sha512_init(crypto_hash_sha512_state *state); 81 | 82 | int crypto_hash_sha512_update(crypto_hash_sha512_state *state, 83 | const unsigned char *in, 84 | unsigned long long inlen); 85 | 86 | int crypto_hash_sha512_final(crypto_hash_sha512_state *state, 87 | unsigned char *out); 88 | ``` 89 | 90 | ## Notes 91 | 92 | The state must be initialized with `crypto_hash_sha*_init()` before updating or finalizing it. 93 | 94 | After `crypto_hash_sha*_final()`, the state should not be used any more, unless it is reinitialized using `crypto_hash_sha*_init()`. 95 | 96 | SHA-512-256 is also available via the higher-level interface `crypto_hash()`. 97 | 98 | ## Constants 99 | 100 | - `crypto_hash_sha256_BYTES` 101 | - `crypto_hash_sha512_BYTES` 102 | 103 | ## Data types 104 | 105 | - `crypto_hash_sha256_state` 106 | - `crypto_hash_sha512_state` 107 | -------------------------------------------------------------------------------- /bindings_for_other_languages/README.md: -------------------------------------------------------------------------------- 1 | # Libsodium and programming languages 2 | 3 | ## Programming languages whose standard library includes support for libsodium 4 | 5 | - PHP \>= 7.2 6 | - HHVM \>= 3.20 7 | - [Citrine](https://citrine-lang.org/) 8 | - [Factor](https://factorcode.org/) \>= 0.98 9 | 10 | ## Bindings programming languages 11 | 12 | - .NET: [BetterCallSodium](https://github.com/BetterCallSodium/BetterCallSodium) 13 | - .NET: [NSec](https://github.com/ektrah/nsec) 14 | - .NET: [Geralt](https://github.com/samuel-lucas6/Geralt) 15 | - .NET: [libsodium-core](https://github.com/tabrath/libsodium-core) (maintenance mode) 16 | - .NET: [ASodium](https://github.com/Chewhern/ASodium) 17 | - .NET: [SpaceWizards.Sodium](https://github.com/space-wizards/SpaceWizards.Sodium) 18 | - .NET (Blazor): [BlazorSodium](https://github.com/Jack-Edwards/BlazorSodium) 19 | - Ada: [libsodium-ada](https://github.com/jrmarino/libsodium-ada) 20 | - Ada: [sodiumada](https://gitlab.com/ada23/sodiumada) 21 | - Clojure: [caesium](https://github.com/lvh/caesium) 22 | - Crystal: [Sodium](https://github.com/didactic-drunk/sodium.cr) 23 | - D: [LibsodiumD](https://github.com/Geod24/libsodiumd) 24 | - Dart (Flutter): [Flutter-Sodium](https://github.com/firstfloorsoftware/flutter_sodium) 25 | - Dart: [libsodium\_dart\_bindings](https://github.com/Skycoder42/libsodium_dart_bindings) 26 | - Delphi: [Delphi-NaCl](https://github.com/zedalaye/Delphi-NaCl) 27 | - Erlang: [ENaCl](https://github.com/jlouis/enacl) 28 | - Erlang: [Erlang-libsodium](https://github.com/potatosalad/erlang-libsodium) 29 | - Fortran: [Sodium](https://github.com/freevryheid/sodium) 30 | - Go: [Sodium](https://github.com/jamesruan/sodium) 31 | - Hack: [Nuxed Crypto](https://github.com/nuxed/crypto) 32 | - Haskell: [Saltine](https://github.com/tel/saltine) 33 | - Haskell: [hs-sodium](https://github.com/k0001/hs-libsodium) 34 | - Haskell: [haskell-crypto](https://github.com/serokell/haskell-crypto) 35 | - Haskell: [cryptography-libsodium](https://github.com/haskell-cryptography/cryptography-libsodium-bindings) 36 | - Java (Java Native Access): [libsodium-jna](https://github.com/muquit/libsodium-jna) 37 | - Java (Android): [Lazysodium for Android](https://github.com/terl/lazysodium-android) 38 | - Java: [Apache Tuweni](https://github.com/apache/incubator-tuweni) ([crypto module](https://github.com/apache/incubator-tuweni/tree/master/crypto/src)) 39 | - Java: [Lazysodium for Java](https://github.com/terl/lazysodium-java) 40 | - JavaScript (compiled to pure JavaScript): [libsodium.js](https://github.com/jedisct1/libsodium.js) 41 | - JavaScript (compiled to pure JavaScript): [js-nacl](https://github.com/tonyg/js-nacl) 42 | - JavaScript (libsodium.js wrapper for browsers): [Natrium Browser](https://github.com/wilhelmmatilainen/natrium-browser) 43 | - JavaScript (NodeJS): [sodium-native](https://github.com/mafintosh/sodium-native) 44 | - JavaScript (NodeJS): [sodium](https://github.com/devtomio/sodium) 45 | - Kotlin Multiplatform: [kotlin-multiplatform-libsodium](https://github.com/ionspin/kotlin-multiplatform-libsodium) 46 | - Lua: [luasodium](https://github.com/jprjr/luasodium) 47 | - Nim: [nim-libsodium](https://github.com/BundleFeed/nim-libsodium) 48 | - PHP: [libsodium-php](https://github.com/jedisct1/libsodium-php) 49 | - PHP: [dhole-cryptography](https://github.com/soatok/dhole-cryptography) 50 | - Pharo 7/8: [Crypto-Nacl](https://github.com/objectguild/Crypto-Nacl) 51 | - Pony: [Pony-Sodium](https://github.com/jemc/pony-sodium) 52 | - Python: [LibNaCl](https://github.com/saltstack/libnacl) 53 | - Python: [PyNaCl](https://github.com/pyca/pynacl) 54 | - Python: [PySodium](https://github.com/stef/pysodium) 55 | - R: [Cyphr](https://github.com/richfitz/cyphr) 56 | - R: [Sodium](https://github.com/jeroenooms/sodium) 57 | - REALbasic and Xojo: [RB-libsodium](https://github.com/charonn0/RB-libsodium) 58 | - Ruby: [RbNaCl](https://github.com/cryptosphere/rbnacl) 59 | - Rust: [libsodium-sys-stable](https://github.com/jedisct1/libsodium-sys-stable) 60 | - Rust: [tablesalt](https://github.com/JacoMalan1/tablesalt) 61 | - Rust: [sodoken](https://github.com/holochain/sodoken) 62 | - Rust: [alkali](https://github.com/tom25519/alkali) 63 | - Swift: [Swift-Sodium](https://github.com/jedisct1/swift-sodium) 64 | - V: [vlang/libsodium](https://github.com/vlang/libsodium) 65 | -------------------------------------------------------------------------------- /advanced/salsa20.md: -------------------------------------------------------------------------------- 1 | # Salsa20 2 | 3 | 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. 4 | 5 | Salsa20 doesn’t require any lookup tables and avoids the possibility of timing attacks. 6 | 7 | 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. 8 | 9 | The extended-nonce construction XSalsa20 is generally recommended over raw Salsa20, as it makes it easier to safely generate nonces. 10 | 11 | ## Usage 12 | 13 | ``` c 14 | int crypto_stream_salsa20(unsigned char *c, unsigned long long clen, 15 | const unsigned char *n, const unsigned char *k); 16 | ``` 17 | 18 | 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). 19 | 20 | ``` c 21 | int crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m, 22 | unsigned long long mlen, const unsigned char *n, 23 | const unsigned char *k); 24 | ``` 25 | 26 | 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). 27 | 28 | 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. 29 | 30 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 31 | 32 | ``` c 33 | int crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m, 34 | unsigned long long mlen, 35 | const unsigned char *n, uint64_t ic, 36 | const unsigned char *k); 37 | ``` 38 | 39 | 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`. 40 | 41 | This permits direct access to any block without having to compute the previous ones. 42 | 43 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 44 | 45 | ``` c 46 | void crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES]); 47 | ``` 48 | 49 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 50 | 51 | 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. 52 | 53 | ## Constants 54 | 55 | - `crypto_stream_salsa20_KEYBYTES` 56 | - `crypto_stream_salsa20_NONCEBYTES` 57 | 58 | ## Notes 59 | 60 | 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. 61 | 62 | Alternatively, XSalsa20, a variant of Salsa20 with a longer nonce, can be used. 63 | 64 | The functions described above perform 20 rounds of Salsa20. 65 | 66 | Faster, reduced-rounds versions are also available: 67 | 68 | ### Salsa20 reduced to 12 rounds 69 | 70 | ``` c 71 | int crypto_stream_salsa2012(unsigned char *c, unsigned long long clen, 72 | const unsigned char *n, const unsigned char *k); 73 | 74 | int crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m, 75 | unsigned long long mlen, const unsigned char *n, 76 | const unsigned char *k); 77 | 78 | void crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES]); 79 | ``` 80 | 81 | ### Salsa20 reduced to 8 rounds 82 | 83 | ``` c 84 | int crypto_stream_salsa208(unsigned char *c, unsigned long long clen, 85 | const unsigned char *n, const unsigned char *k); 86 | 87 | int crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m, 88 | unsigned long long mlen, const unsigned char *n, 89 | const unsigned char *k); 90 | 91 | void crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES]); 92 | ``` 93 | 94 | 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. 95 | -------------------------------------------------------------------------------- /usage/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | ``` c 4 | #include 5 | 6 | int main(void) 7 | { 8 | if (sodium_init() == -1) { 9 | return 1; 10 | } 11 | ... 12 | } 13 | ``` 14 | 15 | `sodium.h` is the only header that has to be included. 16 | 17 | 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: 18 | 19 | ``` bash 20 | CFLAGS=$(pkg-config --cflags libsodium) 21 | LDFLAGS=$(pkg-config --libs libsodium) 22 | ``` 23 | 24 | For static linking, Visual Studio users should define `SODIUM_STATIC=1` and `SODIUM_EXPORT=`. This is not required on other platforms. 25 | 26 | 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. 27 | 28 | `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. 29 | 30 | After this function returns, all of the other functions provided by Sodium will be thread-safe. 31 | 32 | `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. 33 | 34 | Multiple calls to `sodium_init()` do not cause additional descriptors to be opened. 35 | 36 | `sodium_init()` returns `0` on success, `-1` on failure, and `1` if the library had already been initialized. 37 | 38 | Before returning, the function ensures that the system’s random number generator has been properly seeded. 39 | 40 | ## sodium\_init() stalling on Linux 41 | 42 | 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. 43 | 44 | This can be confirmed with the following command: 45 | 46 | ``` sh 47 | cat /proc/sys/kernel/random/entropy_avail 48 | ``` 49 | 50 | 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. 51 | 52 | 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. 53 | 54 | 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. 55 | 56 | If you have to use a kernel before version 5.4, a possible workaround is to install `haveged`: 57 | 58 | ``` sh 59 | apt-get install haveged 60 | ``` 61 | 62 | An alternative is `rng-tools`: 63 | 64 | ``` sh 65 | apt-get install rng-tools 66 | ``` 67 | 68 | In some environments, setting the `-O jitter:timeout` option to `20` [might be necessary](https://github.com/nhorman/rng-tools/issues/195#issuecomment-1519222464). 69 | 70 | [Jitterentropy](https://github.com/smuellerDD/jitterentropy-rngd) is a better alternative, but most Linux distributions don’t offer it as an installable package yet. 71 | 72 | After installating these tools, check the value of `/proc/sys/kernel/random/entropy_avail` again. 73 | 74 | On AWS Nitro Enclaves, workarounds include: 75 | 76 | - Calling the `aws_nitro_enclaves_library_seed_entropy()` function before `sodium_init()`, and occasionally afterwards. 77 | - Using the `RDSEED` CPU instruction to seed the kernel RNG (not recommended as a unique entropy source). 78 | - Setting `random.trust_cpu=on` in the kernel command line (requires Linux kernel \> 4.19). 79 | 80 | Applications can warn users about the Linux RNG not being seeded before calling `sodium_init()` using code similar to the following: 81 | 82 | ``` c 83 | #if defined(__linux__) 84 | # include 85 | # include 86 | # include 87 | # include 88 | #endif 89 | // ... 90 | #if defined(__linux__) && defined(RNDGETENTCNT) 91 | int fd; 92 | int c; 93 | 94 | if ((fd = open("/dev/random", O_RDONLY)) != -1) { 95 | if (ioctl(fd, RNDGETENTCNT, &c) == 0 && c < 160) { 96 | fputs("This system doesn't provide enough entropy to quickly generate high-quality random numbers.\n" 97 | "Upgrading the kernel, installing the rng-utils/rng-tools, jitterentropy-rngd or haveged packages may help.\n" 98 | "On virtualized Linux environments, also consider using virtio-rng.\n" 99 | "The service will not start until enough entropy has been collected.\n", stderr); 100 | } 101 | (void) close(fd); 102 | } 103 | #endif 104 | ``` 105 | 106 | Congrats, you’re all set up\! 107 | 108 | A good documentation page to read next might be [Quickstart and FAQ](../quickstart/README.md). 109 | -------------------------------------------------------------------------------- /secret-key_cryptography/aes-gcm_with_precomputation.md: -------------------------------------------------------------------------------- 1 | # AES256-GCM with precomputation 2 | 3 | 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. 4 | 5 | ``` c 6 | int crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, 7 | const unsigned char *k); 8 | ``` 9 | 10 | The `crypto_aead_aes256gcm_beforenm()` function initializes a context `ctx` by expanding the key `k` and always returns `0`. 11 | 12 | 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()`. 13 | 14 | ## Combined mode with precalculation 15 | 16 | ``` c 17 | int crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, 18 | unsigned long long *clen_p, 19 | const unsigned char *m, 20 | unsigned long long mlen, 21 | const unsigned char *ad, 22 | unsigned long long adlen, 23 | const unsigned char *nsec, 24 | const unsigned char *npub, 25 | const crypto_aead_aes256gcm_state *ctx_); 26 | ``` 27 | 28 | ``` c 29 | int crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, 30 | unsigned long long *mlen_p, 31 | unsigned char *nsec, 32 | const unsigned char *c, 33 | unsigned long long clen, 34 | const unsigned char *ad, 35 | unsigned long long adlen, 36 | const unsigned char *npub, 37 | const crypto_aead_aes256gcm_state *ctx_); 38 | ``` 39 | 40 | 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. 41 | 42 | ## Detached mode with precalculation 43 | 44 | ``` c 45 | int crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, 46 | unsigned char *mac, 47 | unsigned long long *maclen_p, 48 | const unsigned char *m, 49 | unsigned long long mlen, 50 | const unsigned char *ad, 51 | unsigned long long adlen, 52 | const unsigned char *nsec, 53 | const unsigned char *npub, 54 | const crypto_aead_aes256gcm_state *ctx_); 55 | ``` 56 | 57 | ``` c 58 | int crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, 59 | unsigned char *nsec, 60 | const unsigned char *c, 61 | unsigned long long clen, 62 | const unsigned char *mac, 63 | const unsigned char *ad, 64 | unsigned long long adlen, 65 | const unsigned char *npub, 66 | const crypto_aead_aes256gcm_state *ctx_) 67 | ``` 68 | 69 | 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. 70 | 71 | ## Constants 72 | 73 | - `crypto_aead_aes256gcm_KEYBYTES` 74 | - `crypto_aead_aes256gcm_NPUBBYTES` 75 | - `crypto_aead_aes256gcm_ABYTES` 76 | 77 | ## Data types 78 | 79 | - `crypto_aead_aes256gcm_state` 80 | 81 | ## Notes 82 | 83 | 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. 84 | 85 | 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. 86 | -------------------------------------------------------------------------------- /advanced/poly1305.md: -------------------------------------------------------------------------------- 1 | # Secret-key single-message authentication using Poly1305 2 | 3 | One-time authentication in Sodium uses Poly1305, a Wegman-Carter authenticator designed by D. J. Bernstein. 4 | 5 | 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 a inauthentic message. 6 | 7 | Poly1305 keys have to be: 8 | 9 | - 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: 10 | - unpredictable. Do not use timestamps or counters. 11 | - 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. 12 | 13 | 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. 14 | 15 | Due to its output size, Poly1305 is recommended for online protocols, exchanging many small messages, rather than for authenticating very large files. 16 | 17 | Finally, Poly1305 is not a replacement for a hash function. 18 | 19 | ## Single-part example 20 | 21 | ``` c 22 | #define MESSAGE ((const unsigned char *) "Data to authenticate") 23 | #define MESSAGE_LEN 20 24 | 25 | unsigned char out[crypto_onetimeauth_BYTES]; 26 | unsigned char key[crypto_onetimeauth_KEYBYTES]; 27 | 28 | crypto_onetimeauth_keygen(key); 29 | crypto_onetimeauth(out, MESSAGE, MESSAGE_LEN, key); 30 | 31 | if (crypto_onetimeauth_verify(out, MESSAGE, MESSAGE_LEN, key) != 0) { 32 | /* message forged! */ 33 | } 34 | ``` 35 | 36 | ## Multi-part example 37 | 38 | ``` c 39 | #define MESSAGE1 ((const unsigned char *) "Multi-part") 40 | #define MESSAGE1_LEN 10 41 | #define MESSAGE2 ((const unsigned char *) "data") 42 | #define MESSAGE2_LEN 4 43 | 44 | unsigned char out[crypto_onetimeauth_BYTES]; 45 | unsigned char key[crypto_onetimeauth_KEYBYTES]; 46 | crypto_onetimeauth_state state; 47 | 48 | crypto_onetimeauth_keygen(key); 49 | 50 | crypto_onetimeauth_init(&state, key); 51 | crypto_onetimeauth_update(&state, MESSAGE1, MESSAGE1_LEN); 52 | crypto_onetimeauth_update(&state, MESSAGE2, MESSAGE2_LEN); 53 | crypto_onetimeauth_final(&state, out); 54 | ``` 55 | 56 | ## Usage 57 | 58 | ### Single-part interface 59 | 60 | ``` c 61 | int crypto_onetimeauth(unsigned char *out, const unsigned char *in, 62 | unsigned long long inlen, const unsigned char *k); 63 | ``` 64 | 65 | 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). 66 | 67 | ``` c 68 | int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in, 69 | unsigned long long inlen, const unsigned char *k); 70 | ``` 71 | 72 | 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`. 73 | 74 | It returns `-1` if the verification fails, or `0` on success. 75 | 76 | ### Multi-part (streaming) interface 77 | 78 | ``` c 79 | int crypto_onetimeauth_init(crypto_onetimeauth_state *state, 80 | const unsigned char *key); 81 | ``` 82 | 83 | ``` c 84 | int crypto_onetimeauth_update(crypto_onetimeauth_state *state, 85 | const unsigned char *in, 86 | unsigned long long inlen); 87 | ``` 88 | 89 | ``` c 90 | int crypto_onetimeauth_final(crypto_onetimeauth_state *state, 91 | unsigned char *out); 92 | ``` 93 | 94 | The `crypto_onetimeauth_init()` function initializes a structure pointed by `state` using a key `key`. 95 | 96 | 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()`. 97 | 98 | `crypto_onetimeauth_update()` can then be called more than one in order to compute the authenticator from sequential chunks of the message. 99 | 100 | Finally, `crypto_onetimeauth_final()` puts the authenticator into `out`. 101 | 102 | The state must be initialized with `crypto_onetimeauth_init()` before updating or finalizing it. 103 | 104 | After `crypto_onetimeauth_final()` returns, the state should not be used any more, unless it is reinitialized using `crypto_onetimeauth_init()`. 105 | 106 | ``` c 107 | void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]); 108 | ``` 109 | 110 | The `crypto_onetimeauth_keygen()` function fills `k` with a random key. This convenience function was introduced in libsodium 1.0.12. 111 | 112 | ## Constants 113 | 114 | - `crypto_onetimeauth_BYTES` 115 | - `crypto_onetimeauth_KEYBYTES` 116 | 117 | ## Data types 118 | 119 | - `crypto_onetimeauth_state` 120 | 121 | ## Algorithm details 122 | 123 | - Poly1305 124 | -------------------------------------------------------------------------------- /advanced/chacha20.md: -------------------------------------------------------------------------------- 1 | # ChaCha20 2 | 3 | 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. 4 | 5 | ChaCha20 doesn’t require any lookup tables and avoids the possibility of timing attacks. 6 | 7 | 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. 8 | 9 | Two variants of the ChaCha20 cipher are implemented in libsodium: 10 | 11 | - 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. 12 | - 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. 13 | 14 | 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`). 15 | 16 | ## Usage (original construction) 17 | 18 | ``` c 19 | int crypto_stream_chacha20(unsigned char *c, unsigned long long clen, 20 | const unsigned char *n, const unsigned char *k); 21 | ``` 22 | 23 | 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). 24 | 25 | ``` c 26 | int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m, 27 | unsigned long long mlen, const unsigned char *n, 28 | const unsigned char *k); 29 | ``` 30 | 31 | 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). 32 | 33 | 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. 34 | 35 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 36 | 37 | ``` c 38 | int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m, 39 | unsigned long long mlen, 40 | const unsigned char *n, uint64_t ic, 41 | const unsigned char *k); 42 | ``` 43 | 44 | 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`. 45 | 46 | This permits direct access to any block without having to compute the previous ones. 47 | 48 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 49 | 50 | ## Usage (IETF variant, message length limited to 256 GB) 51 | 52 | ``` c 53 | int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen, 54 | const unsigned char *n, const unsigned char *k); 55 | ``` 56 | 57 | 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). 58 | 59 | ``` c 60 | int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m, 61 | unsigned long long mlen, const unsigned char *n, 62 | const unsigned char *k); 63 | ``` 64 | 65 | 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). 66 | 67 | 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. 68 | 69 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 70 | 71 | ``` c 72 | int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, 73 | unsigned long long mlen, 74 | const unsigned char *n, uint32_t ic, 75 | const unsigned char *k); 76 | ``` 77 | 78 | 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`. 79 | 80 | This permits direct access to any block without having to compute the previous ones. 81 | 82 | `m` and `c` can point to the same address (in-place encryption/decryption). If they don’t, the regions should not overlap. 83 | 84 | ## Constants 85 | 86 | - `crypto_stream_chacha20_KEYBYTES` 87 | - `crypto_stream_chacha20_NONCEBYTES` 88 | - `crypto_stream_chacha20_ietf_KEYBYTES` 89 | - `crypto_stream_chacha20_ietf_NONCEBYTES` 90 | 91 | ## Notes 92 | 93 | 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. 94 | 95 | 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. 96 | -------------------------------------------------------------------------------- /key_exchange/README.md: -------------------------------------------------------------------------------- 1 | # Key exchange 2 | 3 | ## Example (client-side) 4 | 5 | ``` c 6 | unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], client_sk[crypto_kx_SECRETKEYBYTES]; 7 | unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES]; 8 | 9 | /* Generate the client's key pair */ 10 | crypto_kx_keypair(client_pk, client_sk); 11 | 12 | /* Prerequisite after this point: the server's public key must be known by the client */ 13 | 14 | /* Compute two shared keys using the server's public key and the client's secret key. 15 | client_rx will be used by the client to receive data from the server, 16 | client_tx will be used by the client to send data to the server. */ 17 | if (crypto_kx_client_session_keys(client_rx, client_tx, 18 | client_pk, client_sk, server_pk) != 0) { 19 | /* Suspicious server public key, bail out */ 20 | } 21 | ``` 22 | 23 | ## Example (server-side) 24 | 25 | ``` c 26 | unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], server_sk[crypto_kx_SECRETKEYBYTES]; 27 | unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES]; 28 | 29 | /* Generate the server's key pair */ 30 | crypto_kx_keypair(server_pk, server_sk); 31 | 32 | /* Prerequisite after this point: the client's public key must be known by the server */ 33 | 34 | /* Compute two shared keys using the client's public key and the server's secret key. 35 | server_rx will be used by the server to receive data from the client, 36 | server_tx will be used by the server to send data to the client. */ 37 | if (crypto_kx_server_session_keys(server_rx, server_tx, 38 | server_pk, server_sk, client_pk) != 0) { 39 | /* Suspicious client public key, bail out */ 40 | } 41 | ``` 42 | 43 | ## Purpose 44 | 45 | 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. 46 | 47 | This API was introduced in libsodium 1.0.12. 48 | 49 | ## Usage 50 | 51 | ``` c 52 | int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], 53 | unsigned char sk[crypto_kx_SECRETKEYBYTES]); 54 | ``` 55 | 56 | The `crypto_kx_keypair()` function creates a new key pair. It puts the public key into `pk` and the secret key into `sk`. 57 | 58 | ``` c 59 | int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], 60 | unsigned char sk[crypto_kx_SECRETKEYBYTES], 61 | const unsigned char seed[crypto_kx_SEEDBYTES]); 62 | ``` 63 | 64 | The `crypto_kx_seed_keypair()` function computes a deterministic key pair from the seed `seed` (`crypto_kx_SEEDBYTES` bytes). 65 | 66 | ``` c 67 | int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], 68 | unsigned char tx[crypto_kx_SESSIONKEYBYTES], 69 | const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], 70 | const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], 71 | const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]); 72 | ``` 73 | 74 | 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`. 75 | 76 | It returns `0` on success and `-1` if the server’s public key is not acceptable. 77 | 78 | These keys can be used by any functions requiring secret keys up to `crypto_kx_SESSIONKEYBYTES` bytes, including `crypto_secretbox_*()` and `crypto_aead_*()`. 79 | 80 | 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. 81 | 82 | `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`. 83 | 84 | ``` c 85 | int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], 86 | unsigned char tx[crypto_kx_SESSIONKEYBYTES], 87 | const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], 88 | const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], 89 | const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]); 90 | ``` 91 | 92 | 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`. 93 | 94 | It returns `0` on success and `-1` if the client’s public key is not acceptable. 95 | 96 | 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. 97 | 98 | `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`. 99 | 100 | ## Constants 101 | 102 | - `crypto_kx_PUBLICKEYBYTES` 103 | - `crypto_kx_SECRETKEYBYTES` 104 | - `crypto_kx_SEEDBYTES` 105 | - `crypto_kx_SESSIONKEYBYTES` 106 | - `crypto_kx_PRIMITIVE` 107 | 108 | ## Algorithm details 109 | 110 | 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 `rx` and `tx`. 111 | 112 | `rx || tx = BLAKE2B-512(p.n || client_pk || server_pk)` 113 | 114 | ## Notes 115 | 116 | For earlier versions of the library that didn’t implement this API, the X25519 function is accessible directly using the `crypto_scalarmult_*()` API. 117 | 118 | Having different keys for each direction allows counters to be safely used as nonces without having to wait for an acknowledgment after every message. 119 | -------------------------------------------------------------------------------- /internals/roadmap.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | libsodium’s roadmap is driven by its user community, and new ideas are always welcome. 4 | 5 | New features will gladly be implemented if they are not redundant and solve common problems. 6 | 7 | ## pre-1.0.0 roadmap 8 | 9 | - AEAD construction (ChaCha20-Poly1305) 10 | - API to set initial counter value in ChaCha20/Salsa20 11 | - Big-endian compatibility 12 | - BLAKE2 13 | - ChaCha20 14 | - Constant-time comparison 15 | - Cross-compilation support 16 | - Detached authentication for `crypto_box()` and `crypto_secretbox()` 17 | - Detached signatures 18 | - Deterministic key generation for `crypto_box()` 19 | - Deterministic key generation for `crypto_sign()` 20 | - Documentation 21 | - Ed25519 signatures 22 | - Emscripten support 23 | - FP rounding mode independent Poly1305 implementation 24 | - Faster portable Curve25519 implementation 25 | - Fix undefined behaviors for C99 26 | - Guarded memory 27 | - HMAC-SHA512, HMAC-SHA256 28 | - Hex codec 29 | - Hide specific implementations, expose wrappers 30 | - Higher-level API for crypto\_box 31 | - Higher-level API for crypto\_secretbox 32 | - Lift `ZEROBYTES` requirements 33 | - Make all constants accessible via public functions 34 | - MinGW port 35 | - Minimal build mode 36 | - NuGet packages 37 | - Password hashing 38 | - Pluggable random number generator 39 | - Portable memory locking 40 | - Position-independent code 41 | - Replace the build system with Autotools/Libtool 42 | - Runtime CPU features detection 43 | - Secure memory zeroing 44 | - Seed and public key extraction from an Ed25519 secret key 45 | - SipHash 46 | - Streaming support for hashing and authentication 47 | - Streaming support for one-time authentication 48 | - Support for arbitrary HMAC key lengths 49 | - Support for architectures requiring strict alignment 50 | - Visual Studio port 51 | - 100% code coverage, static and dynamic analysis 52 | - `arc4random*()` compatible API 53 | - Ed25519 to X25519 keys conversion 54 | - iOS/Android compatibility 55 | 56 | ## 1.0.x roadmap 57 | 58 | - Constant-time bin2hex() \[DONE\] and hex2bin() \[DONE\] 59 | - Constant-time base64 codecs \[DONE\] 60 | - Improve consistency and clarity of function prototypes 61 | - Improve the documentation 62 | - Consider `getrandom(2)` \[DONE\] 63 | - Consider [Gitian](https://gitian.org/) 64 | - Complete the sodium-validation project 65 | - Optimized implementations for ARM w/NEON 66 | - AVX optimized Curve25119 \[DONE\] 67 | - Precomputed interface for crypto\_box\_easy() \[DONE\] 68 | - First-class support for JavaScript \[DONE\] 69 | - ChaCha20 and ChaCha20-Poly1305 with a 96-bit nonce and a 32-bit counter \[DONE\] 70 | - IETF-compatible ChaCha20-Poly1305 implementation \[DONE\] 71 | - SSE-optimized BLAKE2b implementation \[DONE\] 72 | - AES-GCM \[DONE\] 73 | - AES-GCM detached mode \[DONE\] 74 | - Use Montgomery reduction for GHASH 75 | - ChaCha20-Poly1305 detached mode \[DONE\] 76 | - Argon2i as crypto\_pwhash \[DONE\] 77 | - Argon2id as crypto\_pwhash \[DONE\] 78 | - Multithreaded crypto\_pwhash \[on hold\] 79 | - Generic subkey derivation API \[DONE\] 80 | - Nonce misuse-resistant scheme 81 | - BLAKE2 AVX2 implementations \[DONE\] 82 | - Keyed (Hash-then-Encrypt) crypto\_pwhash 83 | - Consider yescrypt 84 | - Argon2id \[DONE\] 85 | - Port libhydrogen’s key exchange API 86 | - SSSE3 ChaCha20 implementation \[DONE\] 87 | - SSSE3 Salsa20 implementation \[DONE\] 88 | - SSSE3 Poly1305 implementation \[DONE\] 89 | - AVX2 Salsa20 implementation \[DONE\] 90 | - AVX2 ChaCha20 implementation \[DONE\] 91 | - AVX2 Poly1305 implementation 92 | - AVX512 implementations \[done for Argon2, withhold for other operations due to throttling concerns\] 93 | - Key generation API \[DONE\] 94 | - Nonce/subkey generation API 95 | - WebAssembly support \[DONE\] 96 | - Stream encryption using a CHAIN-like construction \[DONE\] 97 | - Security audit by a 3rd party \[DONE\] 98 | - Formally-verified implementations \[on hold\] 99 | - Padding API \[DONE\] 100 | - `secretstream_inject()` for nonce misuse-resistance \[on hold\] 101 | - Point addition, subtraction \[DONE\] 102 | - Point validation \[DONE\] 103 | - Hash-to-point (Elligator) \[DONE\] 104 | - SPAKE2+ \[DONE\] 105 | - Support server relief in the password hashing API 106 | - Ristretto \[DONE\] 107 | - Consider a streaming interface for `crypto_shorthash_*()` 108 | - AEGIS-256 \[DONE\] 109 | - AEGIS-128L \[DONE\] 110 | - AEGIS-based `secretstream` API 111 | - HKDF/SHA-512 and HKDF/SHA-256 \[DONE\] 112 | - Standard hash-to-curve \[DONE\] 113 | - Consider [signcryption](https://github.com/jedisct1/libsodium-signcryption) 114 | - High-level AEAD and `secretstream` APIs 115 | - Consider ECVRF \[in progress\] 116 | - Consider FROST 117 | - Consider using [TIMECOP](https://www.post-apocalyptic-crypto.org/timecop) 118 | - Keep an eye on jq255 119 | - Consider [bscrypt](https://github.com/Sc00bz/bscrypt) 120 | - 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. 121 | - Consider SHAKE/TurboSHAKE/KangarooTwelve 122 | - AEGIS-128X and 256X 123 | - Add more ARM optimized implementations 124 | - Add AEGIS-based `crypto_auth` APIs 125 | - Consider AES-GCM-SIV 126 | - Parallel Argon2 127 | - Consider a streaming interface to Ed25519 signatures 128 | - Batch signatures 129 | - HPKE 130 | - Kyber 131 | - CHERI support for the allocation functions 132 | - See if `wasm32-freestanding` can be supported 133 | 134 | ## 2.0.0 roadmap 135 | 136 | - Switch to a new API (libhydrogen/WASI-crypto) 137 | - Session support 138 | -------------------------------------------------------------------------------- /advanced/scalar_multiplication.md: -------------------------------------------------------------------------------- 1 | # Point\*scalar multiplication (X25519) 2 | 3 | Sodium provides an API to multiply a point on the Curve25519 curve. 4 | 5 | This can be used as a building block to construct key exchange mechanisms, or more generally to compute a public key from a secret key. 6 | 7 | On current libsodium versions, you generally want to use the [`crypto_kx`](../key_exchange/README.md) API for key exchange instead. 8 | 9 | ## Usage 10 | 11 | ``` c 12 | int crypto_scalarmult_base(unsigned char *q, const unsigned char *n); 13 | ``` 14 | 15 | Given a user’s secret key `n` (`crypto_scalarmult_SCALARBYTES` bytes), the `crypto_scalarmult_base()` function computes the user’s public key and puts it into `q` (`crypto_scalarmult_BYTES` bytes). 16 | 17 | `crypto_scalarmult_BYTES` and `crypto_scalarmult_SCALARBYTES` are provided for consistency, but it is safe to assume that `crypto_scalarmult_BYTES == crypto_scalarmult_SCALARBYTES`. 18 | 19 | ``` c 20 | int crypto_scalarmult(unsigned char *q, const unsigned char *n, 21 | const unsigned char *p); 22 | ``` 23 | 24 | This function can be used to compute a shared secret `q` given a user’s secret key and another user’s public key. 25 | 26 | `n` is `crypto_scalarmult_SCALARBYTES` bytes long, `p` and the output are `crypto_scalarmult_BYTES` bytes long. 27 | 28 | `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. 29 | 30 | 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. 31 | 32 | A better way to compute a shared key is `h(q ‖ pk1 ‖ pk2)`, with `pk1` and `pk2` being the public keys. 33 | 34 | 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). 35 | 36 | This can be achieved with the following code snippet: 37 | 38 | ``` c 39 | unsigned char client_publickey[crypto_box_PUBLICKEYBYTES]; 40 | unsigned char client_secretkey[crypto_box_SECRETKEYBYTES]; 41 | unsigned char server_publickey[crypto_box_PUBLICKEYBYTES]; 42 | unsigned char server_secretkey[crypto_box_SECRETKEYBYTES]; 43 | unsigned char scalarmult_q_by_client[crypto_scalarmult_BYTES]; 44 | unsigned char scalarmult_q_by_server[crypto_scalarmult_BYTES]; 45 | unsigned char sharedkey_by_client[crypto_generichash_BYTES]; 46 | unsigned char sharedkey_by_server[crypto_generichash_BYTES]; 47 | crypto_generichash_state h; 48 | 49 | /* Create client's secret and public keys */ 50 | randombytes_buf(client_secretkey, sizeof client_secretkey); 51 | crypto_scalarmult_base(client_publickey, client_secretkey); 52 | 53 | /* Create server's secret and public keys */ 54 | randombytes_buf(server_secretkey, sizeof server_secretkey); 55 | crypto_scalarmult_base(server_publickey, server_secretkey); 56 | ``` 57 | 58 | ``` c 59 | /* The client derives a shared key from its secret key and the server's public key */ 60 | /* shared key = h(q ‖ client_publickey ‖ server_publickey) */ 61 | if (crypto_scalarmult(scalarmult_q_by_client, client_secretkey, server_publickey) != 0) { 62 | /* Error */ 63 | } 64 | crypto_generichash_init(&h, NULL, 0U, sizeof sharedkey_by_client); 65 | crypto_generichash_update(&h, scalarmult_q_by_client, sizeof scalarmult_q_by_client); 66 | crypto_generichash_update(&h, client_publickey, sizeof client_publickey); 67 | crypto_generichash_update(&h, server_publickey, sizeof server_publickey); 68 | crypto_generichash_final(&h, sharedkey_by_client, sizeof sharedkey_by_client); 69 | ``` 70 | 71 | ``` c 72 | /* The server derives a shared key from its secret key and the client's public key */ 73 | /* shared key = h(q ‖ client_publickey ‖ server_publickey) */ 74 | if (crypto_scalarmult(scalarmult_q_by_server, server_secretkey, client_publickey) != 0) { 75 | /* Error */ 76 | } 77 | crypto_generichash_init(&h, NULL, 0U, sizeof sharedkey_by_server); 78 | crypto_generichash_update(&h, scalarmult_q_by_server, sizeof scalarmult_q_by_server); 79 | crypto_generichash_update(&h, client_publickey, sizeof client_publickey); 80 | crypto_generichash_update(&h, server_publickey, sizeof server_publickey); 81 | crypto_generichash_final(&h, sharedkey_by_server, sizeof sharedkey_by_server); 82 | 83 | /* sharedkey_by_client and sharedkey_by_server are identical */ 84 | ``` 85 | 86 | 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. 87 | 88 | When using counters as nonces, having distinct keys allows the client and the server to safely send multiple messages without having to wait from an acknowledgment after each message. 89 | 90 | ``` c 91 | typedef struct kx_session_keypair { 92 | unsigned char rx[32]; 93 | unsigned char tx[32]; 94 | } kx_session_keypair; 95 | 96 | kx_session_keypair kp; 97 | 98 | if (crypto_scalarmult(scalarmult_q_by_client, client_secretkey, server_publickey) != 0) { 99 | /* Error */ 100 | } 101 | crypto_generichash_init(&h, NULL, 0U, sizeof session_keypair_by_client); 102 | crypto_generichash_update(&h, scalarmult_q_by_client, sizeof scalarmult_q_by_client); 103 | crypto_generichash_update(&h, client_publickey, sizeof client_publickey); 104 | crypto_generichash_update(&h, server_publickey, sizeof server_publickey); 105 | crypto_generichash_final(&h, session_keypair_by_client, sizeof session_keypair_by_client); 106 | ``` 107 | 108 | `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. 109 | 110 | ## Constants 111 | 112 | - `crypto_scalarmult_BYTES` 113 | - `crypto_scalarmult_SCALARBYTES` 114 | 115 | ## Notes 116 | 117 | As X25519 encodes a field element that is always smaller than 2^255, the top bit is not used. 118 | 119 | ## Algorithm 120 | 121 | - X25519 (ECDH over Curve25519) - [RFC 7748](https://www.rfc-editor.org/rfc/rfc7748.txt) 122 | -------------------------------------------------------------------------------- /key_derivation/README.md: -------------------------------------------------------------------------------- 1 | # Key derivation 2 | 3 | ## Deriving a key from a password 4 | 5 | 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. 6 | 7 | The [`pwhash`](../password_hashing/README.md) operation derives a secret key of any size from a password and salt. 8 | 9 | Refer to the [Password hashing](../password_hashing/README.md) section for more information and code examples. 10 | 11 | ## Deriving keys from a single high-entropy key 12 | 13 | Multiple secret subkeys can be derived from a single master key. 14 | 15 | 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. 16 | 17 | 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). 18 | 19 | Example: 20 | 21 | ``` c 22 | #define CONTEXT "Examples" 23 | 24 | uint8_t master_key[crypto_kdf_KEYBYTES]; 25 | uint8_t subkey1[32]; 26 | uint8_t subkey2[32]; 27 | uint8_t subkey3[64]; 28 | 29 | crypto_kdf_keygen(master_key); 30 | 31 | crypto_kdf_derive_from_key(subkey1, sizeof subkey1, 1, CONTEXT, master_key); 32 | crypto_kdf_derive_from_key(subkey2, sizeof subkey2, 2, CONTEXT, master_key); 33 | crypto_kdf_derive_from_key(subkey3, sizeof subkey3, 3, CONTEXT, master_key); 34 | ``` 35 | 36 | Usage: 37 | 38 | ``` c 39 | void crypto_kdf_keygen(uint8_t key[crypto_kdf_KEYBYTES]); 40 | ``` 41 | 42 | The `crypto_kdf_keygen()` function creates a master key. 43 | 44 | ``` c 45 | int crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len, 46 | uint64_t subkey_id, 47 | const char ctx[crypto_kdf_CONTEXTBYTES], 48 | const unsigned char key[crypto_kdf_KEYBYTES]); 49 | ``` 50 | 51 | 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`. 52 | 53 | `subkey_id` can be any value up to `(2^64)-1`. 54 | 55 | `subkey_len` must be between `crypto_kdf_BYTES_MIN` (inclusive) and `crypto_kdf_BYTES_MAX` (inclusive). 56 | 57 | Similar to a type, the context `ctx` is an 8 character string describing what the key is going to be used for. 58 | 59 | 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. 60 | 61 | Contexts don’t have to be secret and can have a low entropy. 62 | 63 | Examples of contexts include `UserName`, `__auth__`, `pictures`, and `userdata`. 64 | 65 | They must be `crypto_kdf_CONTEXTBYTES` bytes long. 66 | 67 | 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. 68 | 69 | Constants: 70 | 71 | - `crypto_kdf_PRIMITIVE` 72 | - `crypto_kdf_BYTES_MIN` 73 | - `crypto_kdf_BYTES_MAX` 74 | - `crypto_kdf_CONTEXTBYTES` 75 | - `crypto_kdf_KEYBYTES` 76 | 77 | Algorithm details: 78 | 79 | `BLAKE2B-subkeylen(key=key, message={}, salt=subkey_id || {0}, personal=ctx || {0})` 80 | 81 | ## Nonce extension 82 | 83 | Unlike 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. 84 | 85 | Using a counter instead of random nonces prevents this. However, keeping a state is not always an option, especially with offline protocols. 86 | 87 | 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. 88 | 89 | For example, this allows using a 192-bit nonce with a cipher requiring a 64-bit nonce: 90 | 91 | ``` text 92 | k = 93 | n = <192-bit nonce> 94 | k' = PRF(k, n[0..127]) 95 | c = E(k', n[128..191], m) 96 | ``` 97 | 98 | Sodium also provides the `crypto_core_hchacha20()` function, which can be used as a PRF for that purpose: 99 | 100 | ``` c 101 | int crypto_core_hchacha20(unsigned char *out, const unsigned char *in, 102 | const unsigned char *k, const unsigned char *c); 103 | ``` 104 | 105 | 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`. 106 | 107 | 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. 108 | 109 | The following code snippet can be used to construct a ChaCha20-Poly1305 variant with a 192-bit nonce (XChaCha20) on libsodium \< 1.0.12 (versions \>= 1.0.12 already include this construction). 110 | 111 | ``` c 112 | #define MESSAGE (const unsigned char *) "message" 113 | #define MESSAGE_LEN 7 114 | 115 | unsigned char c[crypto_aead_chacha20poly1305_ABYTES + MESSAGE_LEN]; 116 | unsigned char k[crypto_core_hchacha20_KEYBYTES]; 117 | unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; 118 | unsigned char n[crypto_core_hchacha20_INPUTBYTES + 119 | crypto_aead_chacha20poly1305_NPUBBYTES]; 120 | 121 | randombytes_buf(k, sizeof k); 122 | randombytes_buf(n, sizeof n); /* 192-bits nonce */ 123 | 124 | crypto_core_hchacha20(k2, n, k, NULL); 125 | 126 | assert(crypto_aead_chacha20poly1305_KEYBYTES <= sizeof k2); 127 | assert(crypto_aead_chacha20poly1305_NPUBBYTES == 128 | (sizeof n) - crypto_core_hchacha20_INPUTBYTES); 129 | 130 | crypto_aead_chacha20poly1305_encrypt(c, NULL, MESSAGE, MESSAGE_LEN, 131 | NULL, 0, NULL, 132 | n + crypto_core_hchacha20_INPUTBYTES, 133 | k2); 134 | ``` 135 | -------------------------------------------------------------------------------- /hashing/generic_hashing.md: -------------------------------------------------------------------------------- 1 | # Generic hashing 2 | 3 | ## Single-part example without a key 4 | 5 | ``` c 6 | #define MESSAGE ((const unsigned char *) "Arbitrary data to hash") 7 | #define MESSAGE_LEN 22 8 | 9 | unsigned char hash[crypto_generichash_BYTES]; 10 | 11 | crypto_generichash(hash, sizeof hash, 12 | MESSAGE, MESSAGE_LEN, 13 | NULL, 0); 14 | ``` 15 | 16 | ## Single-part example with a key 17 | 18 | ``` c 19 | #define MESSAGE ((const unsigned char *) "Arbitrary data to hash") 20 | #define MESSAGE_LEN 22 21 | 22 | unsigned char hash[crypto_generichash_BYTES]; 23 | unsigned char key[crypto_generichash_KEYBYTES]; 24 | 25 | randombytes_buf(key, sizeof key); 26 | 27 | crypto_generichash(hash, sizeof hash, 28 | MESSAGE, MESSAGE_LEN, 29 | key, sizeof key); 30 | ``` 31 | 32 | ## Multi-part example with a key 33 | 34 | ``` c 35 | #define MESSAGE_PART1 \ 36 | ((const unsigned char *) "Arbitrary data to hash") 37 | #define MESSAGE_PART1_LEN 22 38 | 39 | #define MESSAGE_PART2 \ 40 | ((const unsigned char *) "is longer than expected") 41 | #define MESSAGE_PART2_LEN 23 42 | 43 | unsigned char hash[crypto_generichash_BYTES]; 44 | unsigned char key[crypto_generichash_KEYBYTES]; 45 | crypto_generichash_state state; 46 | 47 | randombytes_buf(key, sizeof key); 48 | 49 | crypto_generichash_init(&state, key, sizeof key, sizeof hash); 50 | 51 | crypto_generichash_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN); 52 | crypto_generichash_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN); 53 | 54 | crypto_generichash_final(&state, hash, sizeof hash); 55 | ``` 56 | 57 | ## Purpose 58 | 59 | This API computes a fixed-length fingerprint for an arbitrarily long message. 60 | 61 | Sample use cases: 62 | 63 | - File integrity checking 64 | - Creating unique identifiers to index arbitrarily long data 65 | 66 | ## Usage 67 | 68 | ``` c 69 | int crypto_generichash(unsigned char *out, size_t outlen, 70 | const unsigned char *in, unsigned long long inlen, 71 | const unsigned char *key, size_t keylen); 72 | ``` 73 | 74 | 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. 75 | 76 | The minimum recommended output size is `crypto_generichash_BYTES`. This size makes it practically impossible for two messages to produce the same fingerprint. 77 | 78 | However, for specific use cases, the size can be any value between `crypto_generichash_BYTES_MIN` (included) and `crypto_generichash_BYTES_MAX` (included). 79 | 80 | `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. 81 | 82 | 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. 83 | 84 | In particular, the key can be used to make sure that different applications generate different fingerprints even if they process the same data. 85 | 86 | The recommended key size is `crypto_generichash_KEYBYTES` bytes. 87 | 88 | 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`. 89 | 90 | ``` c 91 | int crypto_generichash_init(crypto_generichash_state *state, 92 | const unsigned char *key, 93 | const size_t keylen, const size_t outlen); 94 | 95 | int crypto_generichash_update(crypto_generichash_state *state, 96 | const unsigned char *in, 97 | unsigned long long inlen); 98 | 99 | int crypto_generichash_final(crypto_generichash_state *state, 100 | unsigned char *out, const size_t outlen); 101 | ``` 102 | 103 | The message doesn’t have to be provided as a single chunk. The `generichash` operation also supports a streaming API. 104 | 105 | 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. 106 | 107 | 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`. 108 | 109 | The `crypto_generichash_final()` function completes the operation and puts the final fingerprint into `out` as `outlen` bytes. 110 | 111 | After `crypto_generichash_final()` returns, the state should not be used any more, unless it is reinitialized using `crypto_generichash_init()`. 112 | 113 | This alternative API is especially useful to process very large files and data streams. 114 | 115 | ``` c 116 | void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]); 117 | ``` 118 | 119 | The `crypto_generichash_keygen()` function creates a key `k` of the recommended length `crypto_generichash_KEYBYTES`. 120 | 121 | ## Constants 122 | 123 | - `crypto_generichash_BYTES` 124 | - `crypto_generichash_BYTES_MIN` 125 | - `crypto_generichash_BYTES_MAX` 126 | - `crypto_generichash_KEYBYTES` 127 | - `crypto_generichash_KEYBYTES_MIN` 128 | - `crypto_generichash_KEYBYTES_MAX` 129 | 130 | ## Data types 131 | 132 | - `crypto_generichash_state` 133 | 134 | ## Algorithm details 135 | 136 | BLAKE2b 137 | 138 | ## Notes 139 | 140 | 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. 141 | 142 | Unlike MD5, SHA-1, and SHA-256, this function is safe against hash length extension attacks. 143 | 144 | With a key, the function can be used as a PRF. 145 | 146 | BLAKE2b’s salt and personalization parameters are accessible through the lower-level functions whose prototypes are defined in `crypto_generichash_blake2b.h`. 147 | 148 | BLAKE2b is not suitable for hashing passwords. For this purpose, use the `crypto_pwhash` API documented in the Password Hashing section. 149 | -------------------------------------------------------------------------------- /helpers/memory_management.md: -------------------------------------------------------------------------------- 1 | # Securing memory allocations 2 | 3 | ## Zeroing memory 4 | 5 | ``` c 6 | void sodium_memzero(void * const pnt, const size_t len); 7 | ``` 8 | 9 | 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. 10 | 11 | The `sodium_memzero()` function tries to effectively zero `len` bytes starting at `pnt`, even if optimizations are being applied to the code. 12 | 13 | ## Locking memory 14 | 15 | ``` c 16 | int sodium_mlock(void * const addr, const size_t len); 17 | ``` 18 | 19 | The `sodium_mlock()` function locks at least `len` bytes of memory starting at `addr`. This can help avoid swapping sensitive data to disk. 20 | 21 | In addition, it is recommended to disable swap partitions on machines processing sensitive data or, as a second choice, use encrypted swap partitions. 22 | 23 | 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. 24 | 25 | `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. 26 | 27 | ``` c 28 | int sodium_munlock(void * const addr, const size_t len); 29 | ``` 30 | 31 | 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. 32 | 33 | 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. 34 | 35 | ## Guarded heap allocations 36 | 37 | Sodium provides heap allocation functions for storing sensitive data. 38 | 39 | 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. 40 | 41 | `sodium_init()` must be called before using any of the guarded heap allocation functions. 42 | 43 | ``` c 44 | void *sodium_malloc(size_t size); 45 | ``` 46 | 47 | 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. 48 | 49 | 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. 50 | 51 | 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. 52 | 53 | 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. 54 | 55 | The allocated region is filled with `0xdb` bytes to help catch bugs due to uninitialized data. 56 | 57 | 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. 58 | 59 | On operating systems supporting `MAP_NOCORE` or `MADV_DONTDUMP`, memory allocated this way will also not be part of core dumps. 60 | 61 | The returned address will not be aligned if the allocation size is not a multiple of the required alignment. 62 | 63 | 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. 64 | 65 | All the structures used by libsodium can safely be allocated using `sodium_malloc()`. 66 | 67 | Allocating `0` bytes is a valid operation. It returns a pointer that can be successfully passed to `sodium_free()`. 68 | 69 | ``` c 70 | void *sodium_allocarray(size_t count, size_t size); 71 | ``` 72 | 73 | The `sodium_allocarray()` function returns a pointer from which `count` objects that are `size` bytes of memory each can be accessed. 74 | 75 | It provides the same guarantees as `sodium_malloc()` but also protects against arithmetic overflows when `count * size` exceeds `SIZE_MAX`. 76 | 77 | ``` c 78 | void sodium_free(void *ptr); 79 | ``` 80 | 81 | The `sodium_free()` function unlocks and deallocates memory allocated using `sodium_malloc()` or `sodium_allocarray()`. 82 | 83 | Before this, the canary is checked to detect possible buffer underflows and terminate the process if required. 84 | 85 | `sodium_free()` also fills the memory region with zeros before the deallocation. 86 | 87 | This function can be called even if the region was previously protected using `sodium_mprotect_readonly()`; the protection will automatically be changed as needed. 88 | 89 | `ptr` can be `NULL`, in which case no operation is performed. 90 | 91 | ``` c 92 | int sodium_mprotect_noaccess(void *ptr); 93 | ``` 94 | 95 | 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. 96 | 97 | This function can be used to make confidential data inaccessible except when needed for a specific operation. 98 | 99 | ``` c 100 | int sodium_mprotect_readonly(void *ptr); 101 | ``` 102 | 103 | The `sodium_mprotect_readonly()` function marks a region allocated using `sodium_malloc()` or `sodium_allocarray()` as read-only. 104 | 105 | Attempting to modify the data will cause the process to terminate. 106 | 107 | ``` c 108 | int sodium_mprotect_readwrite(void *ptr); 109 | ``` 110 | 111 | 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()`. 112 | -------------------------------------------------------------------------------- /quickstart/multiple_recipients.md: -------------------------------------------------------------------------------- 1 | # Multiple recipients 2 | 3 | A message encrypted using a shared secret doesn’t authenticate the sender: anyone with a key can pretend to be the author of any message encrypted using that key. 4 | 5 | This is usually not an issue when only two parties are involved. 6 | 7 | However, it can become a concern for group communications, where a single key is shared by multiple recipients:. 8 | 9 | Signatures can prove the identity of a sender. In order to prove the identity of a sender for messages encrypted using shared secrets, signatures can thus be combined with encryption. 10 | 11 | The recommended approach is to: 12 | 13 | - Sign the message, as well as the context of the message: the identity of the sender, the identity of the recipient, and a message identifier (ex: uid, timestamp). 14 | - Encrypt and authenticate the message and its signature. 15 | 16 | While, under some circumstances, a single key pair could be used both for signing and encryption, this is neither recommended nor usually necessary. In libsodium, signature and encryption public keys are only 32 bytes long, and these two kind of public keys can be encoded as a compound 64 byte key. 17 | 18 | - `sender_kx.pk`: the sender’s public key used to compute a shared secret 19 | - `sender_kx.sk`: the sender’s secret key used to compute a shared secret 20 | - `recipient_kx.pk`: the recipient’s public key for signature verification 21 | - `recipient_kx.sk`: the recipient’s secret key for signing 22 | 23 | 24 | 25 | ``` c 26 | static int crypto_sign_with_id(unsigned char *signed_msg, const unsigned char *msg, size_t msg_len, 27 | const unsigned char *sender_info, size_t sender_info_len, 28 | const unsigned char *recipient_info, size_t recipient_info_len, 29 | const unsigned char *info, size_t info_len, 30 | const unsigned char client_sign_sk[crypto_sign_SECRETKEYBYTES]) 31 | { 32 | crypto_sign_state st; 33 | 34 | if (msg != signed_msg && msg_len > 0) { 35 | memmove(signed_msg, msg, msg_len); 36 | } 37 | crypto_sign_init(&st); 38 | crypto_sign_update(&st, sender_info, sender_info_len); 39 | crypto_sign_update(&st, recipient_info, recipient_info_len); 40 | crypto_sign_update(&st, info, info_len); 41 | crypto_sign_update(&st, msg, msg_len); 42 | 43 | return crypto_sign_final_create(&st, &signed_msg[msg_len], NULL, client_sign_sk); 44 | } 45 | 46 | static int 47 | crypto_sign_verify_with_id(const unsigned char *signed_msg, size_t signed_msg_len, 48 | const unsigned char *sender_info, size_t sender_info_len, 49 | const unsigned char *recipient_info, size_t recipient_info_len, 50 | const unsigned char *info, size_t info_len, 51 | const unsigned char client_sign_pk[crypto_sign_PUBLICKEYBYTES]) 52 | { 53 | crypto_sign_state st; 54 | 55 | if (signed_msg_len < crypto_sign_BYTES) { 56 | return -1; 57 | } 58 | crypto_sign_init(&st); 59 | crypto_sign_update(&st, sender_info, sender_info_len); 60 | crypto_sign_update(&st, recipient_info, recipient_info_len); 61 | crypto_sign_update(&st, info, info_len); 62 | crypto_sign_update(&st, signed_msg, signed_msg_len - crypto_sign_BYTES); 63 | 64 | return crypto_sign_final_verify(&st, &signed_msg[signed_msg_len - crypto_sign_BYTES], 65 | client_sign_pk); 66 | } 67 | ``` 68 | 69 | ``` c 70 | 71 | typedef struct KXKeyPair_ { 72 | unsigned char pk[crypto_kx_PUBLICKEYBYTES], sk[crypto_kx_SECRETKEYBYTES]; 73 | } KXKeyPair; 74 | 75 | typedef struct SignKeyPair_ { 76 | unsigned char pk[crypto_sign_PUBLICKEYBYTES], sk[crypto_sign_SECRETKEYBYTES]; 77 | } SignKeyPair; 78 | 79 | #define MSG (const unsigned char *) "test" 80 | #define MSG_LEN (sizeof "test" - 1) 81 | 82 | static void create_key_pairs(KXKeyPair *sender_kx, KXKeyPair *recipient_kx, 83 | SignKeyPair *sender_sign, SignKeyPair *recipient_sign) 84 | { 85 | crypto_kx_keypair(sender_kx->pk, sender_kx->sk); 86 | crypto_kx_keypair(recipient_kx->pk, recipient_kx->sk); 87 | crypto_sign_keypair(sender_sign->pk, sender_sign->sk); 88 | crypto_sign_keypair(recipient_sign->pk, recipient_sign->sk); 89 | } 90 | 91 | int main(void) 92 | { 93 | KXKeyPair sender_kx, recipient_kx; 94 | SignKeyPair sender_sign, recipient_sign; 95 | unsigned char sender_encrypt_k[crypto_kx_SESSIONKEYBYTES]; 96 | unsigned char signed_encrypted_msg[MSG_LEN + crypto_sign_BYTES + crypto_box_MACBYTES]; 97 | unsigned char signed_decrypted_msg[MSG_LEN + crypto_sign_BYTES]; 98 | unsigned char nonce[crypto_box_NONCEBYTES]; 99 | 100 | if (sodium_init() != 0) { 101 | return 1; 102 | } 103 | create_key_pairs(&sender_kx, &recipient_kx, &sender_sign, &recipient_sign); 104 | 105 | /* sender-side */ 106 | 107 | if (crypto_kx_client_session_keys(sender_encrypt_k, NULL, sender_kx.pk, sender_kx.sk, 108 | recipient_kx.pk) != 0) { 109 | return 1; 110 | } 111 | /* sign then encrypt */ 112 | if (crypto_sign_with_id(signed_encrypted_msg, MSG, MSG_LEN, sender_kx.pk, sizeof sender_kx.pk, 113 | recipient_kx.pk, sizeof recipient_kx.pk, nonce, sizeof nonce, 114 | sender_sign.sk) != 0 || 115 | crypto_secretbox_easy(signed_encrypted_msg, signed_encrypted_msg, 116 | MSG_LEN + crypto_sign_BYTES, nonce, sender_encrypt_k) != 0) { 117 | return 1; 118 | } 119 | 120 | /* recipient-side */ 121 | 122 | if (crypto_kx_server_session_keys(NULL, sender_encrypt_k, recipient_kx.pk, recipient_kx.sk, 123 | sender_kx.pk) != 0) { 124 | return 1; 125 | } 126 | /* decrypt then verify the signature */ 127 | if (crypto_secretbox_open_easy(signed_decrypted_msg, signed_encrypted_msg, 128 | MSG_LEN + crypto_sign_BYTES + crypto_box_MACBYTES, nonce, 129 | sender_encrypt_k) != 0 || 130 | crypto_sign_verify_with_id(signed_decrypted_msg, MSG_LEN + crypto_sign_BYTES, sender_kx.pk, 131 | sizeof sender_kx.pk, recipient_kx.pk, sizeof recipient_kx.pk, 132 | nonce, sizeof nonce, sender_sign.pk) != 0) { 133 | return 1; 134 | } 135 | return 0; 136 | } 137 | ``` 138 | 139 | But group messaging is a complex topic. [RFC9420](https://datatracker.ietf.org/doc/rfc9420/) is a proper approach. 140 | -------------------------------------------------------------------------------- /secret-key_cryptography/secretbox.md: -------------------------------------------------------------------------------- 1 | # Secret-key authenticated encryption 2 | 3 | ## Example 4 | 5 | ``` c 6 | #define MESSAGE ((const unsigned char *) "test") 7 | #define MESSAGE_LEN 4 8 | #define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN) 9 | 10 | unsigned char key[crypto_secretbox_KEYBYTES]; 11 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; 12 | unsigned char ciphertext[CIPHERTEXT_LEN]; 13 | 14 | crypto_secretbox_keygen(key); 15 | randombytes_buf(nonce, sizeof nonce); 16 | crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key); 17 | 18 | unsigned char decrypted[MESSAGE_LEN]; 19 | if (crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, key) != 0) { 20 | /* message forged! */ 21 | } 22 | ``` 23 | 24 | ## Purpose 25 | 26 | This operation: 27 | 28 | - Encrypts a message with a key and a nonce to keep it confidential 29 | - Computes an authentication tag. This tag is used to make sure that the message hasn’t been tampered with before decrypting it. 30 | 31 | A single key is used both to encrypt/authenticate and verify/decrypt messages. For this reason, it is critical to keep the key confidential. 32 | 33 | 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()`. 34 | 35 | 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](encrypted-messages.md) section. 36 | 37 | ## Combined mode 38 | 39 | In combined mode, the authentication tag and the encrypted message are stored together. This is usually what you want. 40 | 41 | ``` c 42 | int crypto_secretbox_easy(unsigned char *c, const unsigned char *m, 43 | unsigned long long mlen, const unsigned char *n, 44 | const unsigned char *k); 45 | ``` 46 | 47 | The `crypto_secretbox_easy()` function encrypts a message `m` whose length is `mlen` bytes, with a key `k` and a nonce `n`. 48 | 49 | `k` should be `crypto_secretbox_KEYBYTES` bytes and `n` should be `crypto_secretbox_NONCEBYTES` bytes. 50 | 51 | `c` should be at least `crypto_secretbox_MACBYTES + mlen` bytes long. 52 | 53 | 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`. 54 | 55 | `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. 56 | 57 | ``` c 58 | int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, 59 | unsigned long long clen, const unsigned char *n, 60 | const unsigned char *k); 61 | ``` 62 | 63 | The `crypto_secretbox_open_easy()` function verifies and decrypts a ciphertext produced by `crypto_secretbox_easy()`. 64 | 65 | `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. 66 | 67 | The nonce `n` and the key `k` have to match those used to encrypt and authenticate the message. 68 | 69 | The function returns `-1` if the verification fails, and `0` on success. On success, the decrypted message is stored into `m`. 70 | 71 | `m` and `c` can overlap, making in-place decryption possible. 72 | 73 | ## Detached mode 74 | 75 | Some applications may need to store the authentication tag and the encrypted message at different locations. 76 | 77 | For this specific use case, “detached” variants of the functions above are available. 78 | 79 | ``` c 80 | int crypto_secretbox_detached(unsigned char *c, unsigned char *mac, 81 | const unsigned char *m, 82 | unsigned long long mlen, 83 | const unsigned char *n, 84 | const unsigned char *k); 85 | ``` 86 | 87 | 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`. 88 | 89 | ``` c 90 | int crypto_secretbox_open_detached(unsigned char *m, 91 | const unsigned char *c, 92 | const unsigned char *mac, 93 | unsigned long long clen, 94 | const unsigned char *n, 95 | const unsigned char *k); 96 | ``` 97 | 98 | 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. 99 | 100 | 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`. 101 | 102 | The function returns `-1` if the verification fails, or `0` on success. 103 | 104 | ``` c 105 | void crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]); 106 | ``` 107 | 108 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 109 | 110 | 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. 111 | 112 | ## Constants 113 | 114 | - `crypto_secretbox_KEYBYTES` 115 | - `crypto_secretbox_MACBYTES` 116 | - `crypto_secretbox_NONCEBYTES` 117 | 118 | ## Algorithm details 119 | 120 | - Encryption: XSalsa20 stream cipher 121 | - Authentication: Poly1305 MAC 122 | 123 | ## Notes 124 | 125 | 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. 126 | 127 | The original NaCl `crypto_secretbox` API is also supported, albeit not recommended. 128 | 129 | `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. 130 | 131 | The `_easy` and `_detached` APIs are faster and improve usability by not requiring padding, copying or tricky pointer arithmetic. 132 | -------------------------------------------------------------------------------- /key_derivation/hkdf.md: -------------------------------------------------------------------------------- 1 | # HKDF key derivation function 2 | 3 | HKDF (HMAC-based Extract-and-Expand Key Derivation Function) is a key derivation function used by many standard protocols. 4 | 5 | It actually includes two operations: 6 | 7 | - **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*). 8 | - **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. 9 | 10 | The latter can be used without the former, if a randomly sampled key of the right size is already available. 11 | 12 | ## Deriving keys from a master key 13 | 14 | Example: 15 | 16 | ``` c 17 | unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]; 18 | unsigned char subkey1[32]; 19 | unsigned char subkey2[32]; 20 | unsigned char subkey3[64]; 21 | 22 | crypto_kdf_hkdf_sha256_keygen(prk); 23 | 24 | crypto_kdf_hkdf_sha256_expand(subkey1, sizeof subkey1, 25 | "key for encryption", 26 | (sizeof "key for encryption") - 1, 27 | prk); 28 | crypto_kdf_hkdf_sha256_expand(subkey2, sizeof subkey2, 29 | "key for signatures", 30 | (sizeof "key for signatures") - 1, 31 | prk); 32 | crypto_kdf_hkdf_sha256_expand(subkey3, sizeof subkey3, 33 | "key for something else", 34 | (sizeof "key for something else") - 1, 35 | prk); 36 | ``` 37 | 38 | Usage: 39 | 40 | ``` c 41 | int crypto_kdf_hkdf_sha256_expand( 42 | unsigned char *out, size_t out_len, 43 | const char *ctx, size_t ctx_len, 44 | const unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]); 45 | ``` 46 | 47 | 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. 48 | 49 | The key is stored into `out` whose length is `out_len` bytes. 50 | 51 | Up to `crypto_kdf_hkdf_sha256_BYTES_MAX` bytes can be produced. 52 | 53 | The generated keys satifsy 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. 54 | 55 | Contexts don’t have to secret. They just need to be distinct in order to produce distinct keys from the same master key. 56 | 57 | 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. 58 | 59 | For convenience, the `crypto_kdf_hkdf_sha256_keygen()` function creates a random `prk`. 60 | 61 | The master key should remain secret. 62 | 63 | `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. 64 | 65 | ## Creating a master key from input keying material 66 | 67 | Example: 68 | 69 | ``` c 70 | #define APPLICATION_UUID "6723D3AA-C6CA-4F3C-8F24-94B550C5F10A" 71 | #define IKM "John Doe - 951a 6158 4fe0 8a0b ad7c b57b 7687 09b6" 72 | 73 | crypto_kdf_hkdf_sha256_extract(prk, 74 | (const unsigned char *) APPLICATION_UUID, 75 | (sizeof APPLICATION_UUID) - 1, 76 | (const unsigned char *) IKM, 77 | (sizeof IKM) - 1); 78 | ``` 79 | 80 | Usage: 81 | 82 | ``` c 83 | int crypto_kdf_hkdf_sha256_extract(unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES], 84 | const unsigned char *salt, size_t salt_len, 85 | const unsigned char *ikm, size_t ikm_len); 86 | ``` 87 | 88 | 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. 89 | 90 | `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. 91 | 92 | A UUID is a decent example of a `salt`. There is no minimum length. 93 | 94 | If input keying material cannot be accidentally reused, using an empty (`NULL`) salt is perfectly acceptable. 95 | 96 | `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. 97 | 98 | But the overall sequence needs to include some entropy. 99 | 100 | 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. 101 | 102 | ## Incremental entropy extraction 103 | 104 | Example: 105 | 106 | ``` c 107 | #define IKM1 "John Doe - " 108 | #define IKM2 "951a 6158 4fe0 8a0b ad7c b57b 7687 09b6" 109 | 110 | crypto_kdf_hkdf_sha256_extract_init(&st, NULL, 0); 111 | crypto_kdf_hkdf_sha256_extract_update(&st, 112 | (const unsigned char *) IKM1, 113 | (sizeof IKM1) - 1); 114 | crypto_kdf_hkdf_sha256_extract_update(&st, 115 | (const unsigned char *) IKM2, 116 | (sizeof IKM2) - 1); 117 | crypto_kdf_hkdf_sha256_extract_final(&st, prk); 118 | ``` 119 | 120 | Usage: 121 | 122 | ``` c 123 | int crypto_kdf_hkdf_sha256_extract_init( 124 | crypto_kdf_hkdf_sha256_state *state, 125 | const unsigned char *salt, size_t salt_len); 126 | 127 | int crypto_kdf_hkdf_sha256_extract_update( 128 | crypto_kdf_hkdf_sha256_state *state, 129 | const unsigned char *ikm, size_t ikm_len); 130 | 131 | int crypto_kdf_hkdf_sha256_extract_final( 132 | crypto_kdf_hkdf_sha256_state *state, 133 | unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]); 134 | ``` 135 | 136 | Instead of a one-shot call to `crypto_kdf_hkdf_sha256_extract()`, it is possible to feed the input keying material incrementally. 137 | 138 | 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()`. 139 | 140 | ## HKDF-SHA256 and HKDF-SHA512 141 | 142 | Both the `SHA256` and the `SHA512` instantiations are supported. 143 | 144 | 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`. 145 | 146 | `HKDF-SHA512` is present for consistency and compatibility with existing protocols, but it doesn’t have practical security benefits over `HKDF-SHA256`. 147 | 148 | Therefore, the `SHA256` instantiation is generally recommended. 149 | 150 | ## Constants 151 | 152 | - `crypto_kdf_hkdf_sha256_KEYBYTES` 153 | - `crypto_kdf_hkdf_sha256_BYTES_MIN` 154 | - `crypto_kdf_hkdf_sha256_BYTES_MAX` 155 | - `crypto_kdf_hkdf_sha512_KEYBYTES` 156 | - `crypto_kdf_hkdf_sha512_BYTES_MIN` 157 | - `crypto_kdf_hkdf_sha512_BYTES_MAX` 158 | 159 | ## Algorithm details 160 | 161 | - [RFC5869 - HMAC-based Extract-and-Expand Key Derivation Function](https://www.rfc-editor.org/rfc/rfc5869.html) 162 | 163 | ## Notes 164 | 165 | HKDF was added in libsodium version 1.0.19. 166 | -------------------------------------------------------------------------------- /helpers/README.md: -------------------------------------------------------------------------------- 1 | # Helpers 2 | 3 | ## Constant-time test for equality 4 | 5 | ``` c 6 | int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len); 7 | ``` 8 | 9 | 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. 10 | 11 | The `sodium_memcmp()` function can be used for this purpose. 12 | 13 | The function returns `0` if the `len` bytes pointed to by `b1_` match the `len` bytes pointed to by `b2_`. Otherwise, it returns `-1`. 14 | 15 | **Note:** `sodium_memcmp()` is not a lexicographic comparator and is not a generic replacement for `memcmp()`. 16 | 17 | ## Hexadecimal encoding/decoding 18 | 19 | ``` c 20 | char *sodium_bin2hex(char * const hex, const size_t hex_maxlen, 21 | const unsigned char * const bin, const size_t bin_len); 22 | ``` 23 | 24 | The `sodium_bin2hex()` function converts `bin_len` bytes stored at `bin` into a hexadecimal string. 25 | 26 | The string is stored into `hex` and includes a nul byte (`\0`) terminator. 27 | 28 | `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. 29 | 30 | The function always returns `hex`. It evaluates in constant time for a given size. 31 | 32 | ``` c 33 | int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen, 34 | const char * const hex, const size_t hex_len, 35 | const char * const ignore, size_t * const bin_len, 36 | const char ** const hex_end); 37 | ``` 38 | 39 | The `sodium_hex2bin()` function parses a hexadecimal string `hex` and converts it to a byte sequence. 40 | 41 | `hex` does not have to be nul terminated, as the number of characters to parse is supplied via the `hex_len` parameter. 42 | 43 | `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. 44 | 45 | `ignore` can be set to `NULL` to disallow any non-hexadecimal character. 46 | 47 | `bin_maxlen` is the maximum number of bytes to put into `bin`. 48 | 49 | The parser stops when a non-hexadecimal, non-ignored character is found or when `bin_maxlen` bytes have been written. 50 | 51 | If `hex_end` is not `NULL`, it will be set to the address of the first byte after the last valid parsed character. 52 | 53 | The function returns `0` on success. 54 | 55 | 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. 56 | 57 | It evaluates in constant time for a given length and format. 58 | 59 | ## Base64 encoding/decoding 60 | 61 | ``` c 62 | char *sodium_bin2base64(char * const b64, const size_t b64_maxlen, 63 | const unsigned char * const bin, const size_t bin_len, 64 | const int variant); 65 | ``` 66 | 67 | The `sodium_bin2base64()` function encodes `bin` as a Base64 string. `variant` must be one of: 68 | 69 | - `sodium_base64_VARIANT_ORIGINAL` 70 | - `sodium_base64_VARIANT_ORIGINAL_NO_PADDING` 71 | - `sodium_base64_VARIANT_URLSAFE` 72 | - `sodium_base64_VARIANT_URLSAFE_NO_PADDING` 73 | 74 | None of these Base64 variants provides any form of encryption; just like hex encoding, anyone can decode them. 75 | 76 | Computing a correct size for `b64_maxlen` is not straightforward and depends on the chosen variant. 77 | 78 | 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. 79 | 80 | The `sodium_base64_encoded_len(size_t bin_len, int variant)` function is also available for the same purpose. 81 | 82 | ``` c 83 | int sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen, 84 | const char * const b64, const size_t b64_len, 85 | const char * const ignore, size_t * const bin_len, 86 | const char ** const b64_end, const int variant); 87 | ``` 88 | 89 | The `sodium_base642bin()` function decodes a Base64 string using the given variant and an optional set of characters to ignore (typically: whitespaces and newlines). 90 | 91 | If `b64_end` is not `NULL`, it will be set to the address of the first byte after the last valid parsed character. 92 | 93 | 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. 94 | 95 | The function returns `0` on success. 96 | 97 | 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. 98 | 99 | ## Incrementing large numbers 100 | 101 | ``` c 102 | void sodium_increment(unsigned char *n, const size_t nlen); 103 | ``` 104 | 105 | The `sodium_increment()` function takes a pointer to an arbitrary-long unsigned number and increments it. 106 | 107 | It runs in constant time for a given length and considers the number to be encoded in a little-endian format. 108 | 109 | `sodium_increment()` can be used to increment nonces in constant time. 110 | 111 | ## Adding large numbers 112 | 113 | ``` c 114 | void sodium_add(unsigned char *a, const unsigned char *b, const size_t len); 115 | ``` 116 | 117 | The `sodium_add()` function accepts two pointers to unsigned numbers encoded in little-endian format, `a` and `b`, both of size `len` bytes. 118 | 119 | It computes `(a + b) mod 2^(8*len)` in constant time for a given length and overwrites `a` with the result. 120 | 121 | ## Subtracting large numbers 122 | 123 | ``` c 124 | void sodium_sub(unsigned char *a, const unsigned char *b, const size_t len); 125 | ``` 126 | 127 | The `sodium_sub()` function accepts two pointers to unsigned numbers encoded in little-endian format, `a` and `b`, both of size `len` bytes. 128 | 129 | It computes `(a - b) mod 2^(8*len)` in constant time for a given length and overwrites `a` with the result. 130 | 131 | This function was introduced in libsodium 1.0.17. 132 | 133 | ## Comparing large numbers 134 | 135 | ``` c 136 | int sodium_compare(const void * const b1_, const void * const b2_, size_t len); 137 | ``` 138 | 139 | Given `b1_` and `b2_`, two `len` bytes numbers encoded in little-endian format, this function returns: 140 | 141 | - `-1` if `b1_` is less than `b2_` 142 | - `0` if `b1_` equals `b2_` 143 | - `1` if `b1_` is greater than `b2_` 144 | 145 | The comparison is done in constant time for a given length. 146 | 147 | This function can be used with nonces to prevent replay attacks. 148 | 149 | ## Testing for all zeros 150 | 151 | ``` c 152 | int sodium_is_zero(const unsigned char *n, const size_t nlen); 153 | ``` 154 | 155 | This function returns `1` if the `nlen` bytes vector pointed by `n` contains only zeros. It returns `0` if non-zero bits are found. 156 | 157 | Its execution time is constant for a given length. 158 | 159 | ## Clearing the stack 160 | 161 | ``` c 162 | void sodium_stackzero(const size_t len); 163 | ``` 164 | 165 | 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. 166 | 167 | Note that these values can still be present in registers. 168 | 169 | This function was introduced in libsodium 1.0.16. 170 | 171 | ## Notes 172 | 173 | The `sodium_base64_VARIANT_*()` macros don’t have associated symbols. Bindings are encouraged to define specialized encoding/decoding functions instead. 174 | -------------------------------------------------------------------------------- /advanced/hmac-sha2.md: -------------------------------------------------------------------------------- 1 | # HMAC-SHA-2 2 | 3 | The keyed message authentication codes HMAC-SHA-256, HMAC-SHA-512 and HMAC-SHA512-256 (truncated HMAC-SHA-512) are provided. 4 | 5 | The [`crypto_auth`](../secret-key_cryptography/secret-key_authentication.md) API provides a simplified interface for message authentication. 6 | 7 | If required, a streaming API is available to process a message as a sequence of multiple chunks. 8 | 9 | ## Single-part example 10 | 11 | ``` c 12 | #define MESSAGE ((const unsigned char *) "Arbitrary data to hash") 13 | #define MESSAGE_LEN 22 14 | 15 | unsigned char hash[crypto_auth_hmacsha512_BYTES]; 16 | unsigned char key[crypto_auth_hmacsha512_KEYBYTES]; 17 | 18 | crypto_auth_hmacsha512_keygen(key); 19 | crypto_auth_hmacsha512(hash, MESSAGE, MESSAGE_LEN, key); 20 | ``` 21 | 22 | ## Multi-part example 23 | 24 | ``` c 25 | #define MESSAGE_PART1 \ 26 | ((const unsigned char *) "Arbitrary data to hash") 27 | #define MESSAGE_PART1_LEN 22 28 | 29 | #define MESSAGE_PART2 \ 30 | ((const unsigned char *) "is longer than expected") 31 | #define MESSAGE_PART2_LEN 23 32 | 33 | unsigned char hash[crypto_auth_hmacsha512_BYTES]; 34 | unsigned char key[crypto_auth_hmacsha512_KEYBYTES]; 35 | crypto_auth_hmacsha512_state state; 36 | 37 | crypto_auth_hmacsha512_keygen(key); 38 | 39 | crypto_auth_hmacsha512_init(&state, key, sizeof key); 40 | 41 | crypto_auth_hmacsha512_update(&state, MESSAGE_PART1, MESSAGE_PART1_LEN); 42 | crypto_auth_hmacsha512_update(&state, MESSAGE_PART2, MESSAGE_PART2_LEN); 43 | 44 | crypto_auth_hmacsha512_final(&state, hash); 45 | ``` 46 | 47 | ## Usage 48 | 49 | ### HMAC-SHA-256 50 | 51 | ``` c 52 | int crypto_auth_hmacsha256(unsigned char *out, 53 | const unsigned char *in, 54 | unsigned long long inlen, 55 | const unsigned char *k); 56 | ``` 57 | 58 | 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). 59 | 60 | ``` c 61 | int crypto_auth_hmacsha256_verify(const unsigned char *h, 62 | const unsigned char *in, 63 | unsigned long long inlen, 64 | const unsigned char *k); 65 | ``` 66 | 67 | 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). 68 | 69 | It returns `-1` if the verification fails, and `0` on success. 70 | 71 | A multi-part (streaming) API can be used instead of `crypto_auth_hmacsha256()`: 72 | 73 | ``` c 74 | int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state, 75 | const unsigned char *key, 76 | size_t keylen); 77 | ``` 78 | 79 | ``` c 80 | int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state, 81 | const unsigned char *in, 82 | unsigned long long inlen); 83 | ``` 84 | 85 | ``` c 86 | int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state, 87 | unsigned char *out); 88 | ``` 89 | 90 | This alternative API supports a key of arbitrary length `keylen`. 91 | 92 | However, please note that in the HMAC construction, a key larger than the block size gets reduced to `h(key)`. 93 | 94 | ``` c 95 | void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]); 96 | ``` 97 | 98 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 99 | 100 | 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. 101 | 102 | ### HMAC-SHA-512 103 | 104 | Similarily to the `crypto_auth_hmacsha256_*()` set of functions, the `crypto_auth_hmacsha512_*()` set of functions implements HMAC-SHA512: 105 | 106 | ``` c 107 | int crypto_auth_hmacsha512(unsigned char *out, 108 | const unsigned char *in, 109 | unsigned long long inlen, 110 | const unsigned char *k); 111 | ``` 112 | 113 | ``` c 114 | int crypto_auth_hmacsha512_verify(const unsigned char *h, 115 | const unsigned char *in, 116 | unsigned long long inlen, 117 | const unsigned char *k); 118 | ``` 119 | 120 | ``` c 121 | int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state, 122 | const unsigned char *key, 123 | size_t keylen); 124 | ``` 125 | 126 | ``` c 127 | int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state, 128 | const unsigned char *in, 129 | unsigned long long inlen); 130 | ``` 131 | 132 | ``` c 133 | int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state, 134 | unsigned char *out); 135 | ``` 136 | 137 | ``` c 138 | void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]); 139 | ``` 140 | 141 | ### HMAC-SHA-512-256 142 | 143 | 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. 144 | 145 | ``` c 146 | int crypto_auth_hmacsha512256(unsigned char *out, 147 | const unsigned char *in, 148 | unsigned long long inlen, 149 | const unsigned char *k); 150 | ``` 151 | 152 | ``` c 153 | int crypto_auth_hmacsha512256_verify(const unsigned char *h, 154 | const unsigned char *in, 155 | unsigned long long inlen, 156 | const unsigned char *k); 157 | ``` 158 | 159 | ``` c 160 | int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state, 161 | const unsigned char *key, 162 | size_t keylen); 163 | ``` 164 | 165 | ``` c 166 | int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state, 167 | const unsigned char *in, 168 | unsigned long long inlen); 169 | ``` 170 | 171 | ``` c 172 | int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state, 173 | unsigned char *out); 174 | ``` 175 | 176 | ``` c 177 | void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]); 178 | ``` 179 | 180 | ## Constants 181 | 182 | - `crypto_auth_hmacsha256_BYTES` 183 | - `crypto_auth_hmacsha256_KEYBYTES` 184 | - `crypto_auth_hmacsha512_BYTES` 185 | - `crypto_auth_hmacsha512_KEYBYTES` 186 | - `crypto_auth_hmacsha512256_BYTES` 187 | - `crypto_auth_hmacsha512256_KEYBYTES` 188 | 189 | ## Data types 190 | 191 | - `crypto_auth_hmacsha256_state` 192 | - `crypto_auth_hmacsha512_state` 193 | - `crypto_auth_hmacsha512256_state` 194 | 195 | ## Notes 196 | 197 | - 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()`. 198 | 199 | - Arbitrary key lengths are supported using the multi-part interface. 200 | 201 | - `crypto_auth_hmacsha256_*()` can be used to create AWS HMAC-SHA256 request signatures. 202 | 203 | - 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. 204 | -------------------------------------------------------------------------------- /secret-key_cryptography/original_chacha20-poly1305_construction.md: -------------------------------------------------------------------------------- 1 | # The original ChaCha20-Poly1305 construction 2 | 3 | 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). 4 | 5 | ## Example (combined mode) 6 | 7 | ``` c 8 | #define MESSAGE (const unsigned char *) "test" 9 | #define MESSAGE_LEN 4 10 | #define ADDITIONAL_DATA (const unsigned char *) "123456" 11 | #define ADDITIONAL_DATA_LEN 6 12 | 13 | unsigned char nonce[crypto_aead_chacha20poly1305_NPUBBYTES]; 14 | unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES]; 15 | unsigned char ciphertext[MESSAGE_LEN + crypto_aead_chacha20poly1305_ABYTES]; 16 | unsigned long long ciphertext_len; 17 | 18 | crypto_aead_chacha20poly1305_keygen(key); 19 | randombytes_buf(nonce, sizeof nonce); 20 | 21 | crypto_aead_chacha20poly1305_encrypt(ciphertext, &ciphertext_len, 22 | MESSAGE, MESSAGE_LEN, 23 | ADDITIONAL_DATA, ADDITIONAL_DATA_LEN, 24 | NULL, nonce, key); 25 | 26 | unsigned char decrypted[MESSAGE_LEN]; 27 | unsigned long long decrypted_len; 28 | if (crypto_aead_chacha20poly1305_decrypt(decrypted, &decrypted_len, 29 | NULL, 30 | ciphertext, ciphertext_len, 31 | ADDITIONAL_DATA, 32 | ADDITIONAL_DATA_LEN, 33 | nonce, key) != 0) { 34 | /* message forged! */ 35 | } 36 | ``` 37 | 38 | ## Combined mode 39 | 40 | In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. 41 | 42 | ``` c 43 | int crypto_aead_chacha20poly1305_encrypt(unsigned char *c, 44 | unsigned long long *clen_p, 45 | const unsigned char *m, 46 | unsigned long long mlen, 47 | const unsigned char *ad, 48 | unsigned long long adlen, 49 | const unsigned char *nsec, 50 | const unsigned char *npub, 51 | const unsigned char *k); 52 | ``` 53 | 54 | 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). 55 | 56 | 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`. 57 | 58 | `ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required. 59 | 60 | 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. 61 | 62 | `nsec` is not used by this particular construction and should always be `NULL`. 63 | 64 | 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. 65 | 66 | ``` c 67 | int crypto_aead_chacha20poly1305_decrypt(unsigned char *m, 68 | unsigned long long *mlen_p, 69 | unsigned char *nsec, 70 | const unsigned char *c, 71 | unsigned long long clen, 72 | const unsigned char *ad, 73 | unsigned long long adlen, 74 | const unsigned char *npub, 75 | const unsigned char *k); 76 | ``` 77 | 78 | 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). 79 | 80 | `ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required. 81 | 82 | `nsec` is not used by this particular construction and should always be `NULL`. 83 | 84 | The function returns `-1` if the verification fails. 85 | 86 | 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. 87 | 88 | At most `clen - crypto_aead_chacha20poly1305_ABYTES` bytes will be put into `m`. 89 | 90 | ## Detached mode 91 | 92 | Some applications may need to store the authentication tag and the encrypted message at different locations. 93 | 94 | For this specific use case, “detached” variants of the functions above are available. 95 | 96 | ``` c 97 | int crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c, 98 | unsigned char *mac, 99 | unsigned long long *maclen_p, 100 | const unsigned char *m, 101 | unsigned long long mlen, 102 | const unsigned char *ad, 103 | unsigned long long adlen, 104 | const unsigned char *nsec, 105 | const unsigned char *npub, 106 | const unsigned char *k); 107 | ``` 108 | 109 | 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`. 110 | 111 | 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. 112 | 113 | `nsec` is not used by this particular construction and should always be `NULL`. 114 | 115 | ``` c 116 | int crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m, 117 | unsigned char *nsec, 118 | const unsigned char *c, 119 | unsigned long long clen, 120 | const unsigned char *mac, 121 | const unsigned char *ad, 122 | unsigned long long adlen, 123 | const unsigned char *npub, 124 | const unsigned char *k); 125 | ``` 126 | 127 | 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. 128 | 129 | If the tag is not valid, the function returns `-1` and doesn’t do any further processing. 130 | 131 | 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. 132 | 133 | `nsec` is not used by this particular construction and should always be `NULL`. 134 | 135 | ``` c 136 | void crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]); 137 | ``` 138 | 139 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 140 | 141 | 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. 142 | 143 | ## Constants 144 | 145 | - `crypto_aead_chacha20poly1305_KEYBYTES` 146 | - `crypto_aead_chacha20poly1305_NPUBBYTES` 147 | - `crypto_aead_chacha20poly1305_ABYTES` 148 | 149 | ## Algorithm details 150 | 151 | - Encryption: ChaCha20 stream cipher 152 | - Authentication: Poly1305 MAC 153 | 154 | ## Notes 155 | 156 | 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. 157 | 158 | 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. 159 | 160 | ## See also 161 | 162 | - [ChaCha20 and Poly1305 based Cipher Suites for TLS](https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04) - Specification of the original construction 163 | -------------------------------------------------------------------------------- /advanced/ristretto.md: -------------------------------------------------------------------------------- 1 | # Ristretto255 2 | 3 | [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. 4 | 5 | libsodium 1.0.18+ implements ristreto255: ristretto on top of the Curve25519 curve. 6 | 7 | Compared to Curve25519 points encoded as their coordinates, ristretto makes it easier to safely implement protocols originally designed for prime-order groups. 8 | 9 | ## Example 10 | 11 | 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. 12 | 13 | ``` c 14 | // -------- First party -------- Send blinded p(x) 15 | unsigned char x[crypto_core_ristretto255_HASHBYTES]; 16 | randombytes_buf(x, sizeof x); 17 | 18 | // Compute px = p(x), a group element derived from x 19 | unsigned char px[crypto_core_ristretto255_BYTES]; 20 | crypto_core_ristretto255_from_hash(px, x); 21 | 22 | // Compute a = p(x) * g^r 23 | unsigned char r[crypto_core_ristretto255_SCALARBYTES]; 24 | unsigned char gr[crypto_core_ristretto255_BYTES]; 25 | unsigned char a[crypto_core_ristretto255_BYTES]; 26 | crypto_core_ristretto255_scalar_random(r); 27 | crypto_scalarmult_ristretto255_base(gr, r); 28 | crypto_core_ristretto255_add(a, px, gr); 29 | 30 | // -------- Second party -------- Send g^k and a^k 31 | unsigned char k[crypto_core_ristretto255_SCALARBYTES]; 32 | randombytes_buf(k, sizeof k); 33 | 34 | // Compute v = g^k 35 | unsigned char v[crypto_core_ristretto255_BYTES]; 36 | crypto_scalarmult_ristretto255_base(v, k); 37 | 38 | // Compute b = a^k 39 | unsigned char b[crypto_core_ristretto255_BYTES]; 40 | if (crypto_scalarmult_ristretto255(b, k, a) != 0) { 41 | return -1; 42 | } 43 | 44 | // -------- First party -------- Unblind f(x) 45 | // Compute vir = v^(-r) 46 | unsigned char ir[crypto_core_ristretto255_SCALARBYTES]; 47 | unsigned char vir[crypto_core_ristretto255_BYTES]; 48 | crypto_core_ristretto255_scalar_negate(ir, r); 49 | crypto_scalarmult_ristretto255(vir, ir, v); 50 | 51 | // Compute f(x) = b * v^(-r) = (p(x) * g^r)^k * (g^k)^(-r) 52 | // = (p(x) * g)^k * g^(-k) = p(x)^k 53 | unsigned char fx[crypto_core_ristretto255_BYTES]; 54 | crypto_core_ristretto255_add(fx, b, vir); 55 | ``` 56 | 57 | ## Encoded element validation 58 | 59 | ``` c 60 | int crypto_core_ristretto255_is_valid_point(const unsigned char *p); 61 | ``` 62 | 63 | The `crypto_core_ristretto255_is_valid_point()` function checks that `p` is a valid ristretto255-encoded element. 64 | 65 | This operation only checks that `p` is in canonical form. 66 | 67 | The function returns `1` on success, and `0` if the checks didn’t pass. 68 | 69 | ## Random group element 70 | 71 | ``` c 72 | void crypto_core_ristretto255_random(unsigned char *p); 73 | ``` 74 | 75 | Fills `p` with the representation of a random group element. 76 | 77 | ## Hash-to-group 78 | 79 | ``` c 80 | int crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r); 81 | ``` 82 | 83 | 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`. 84 | 85 | ## Scalar multiplication 86 | 87 | ``` c 88 | int crypto_scalarmult_ristretto255(unsigned char *q, const unsigned char *n, 89 | const unsigned char *p); 90 | ``` 91 | 92 | 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`. 93 | 94 | `q` should not be used as a shared key prior to hashing. 95 | 96 | The function returns `0` on success, or `-1` if `q` is the identity element. 97 | 98 | ``` c 99 | int crypto_scalarmult_ristretto255_base(unsigned char *q, const unsigned char *n); 100 | ``` 101 | 102 | The `crypto_scalarmult_ristretto255_base()` function multiplies the generator by a scalar `n` (`[0..L[` range) and puts the resulting element into `q`. 103 | 104 | The function returns `-1` if `n` is `0`, and `0` otherwise. 105 | 106 | ## Element addition/subtraction 107 | 108 | ``` c 109 | int crypto_core_ristretto255_add(unsigned char *r, 110 | const unsigned char *p, const unsigned char *q); 111 | ``` 112 | 113 | The `crypto_core_ristretto255_add()` function adds the element represented by `p` to the element `q` and stores the resulting element into `r`. 114 | 115 | The function returns `0` on success, or `-1` if `p` and/or `q` are not valid encoded elements. 116 | 117 | ``` c 118 | int crypto_core_ristretto255_sub(unsigned char *r, 119 | const unsigned char *p, const unsigned char *q); 120 | ``` 121 | 122 | The `crypto_core_ristretto255_sub()` function subtracts the element represented by `p` to the element `q` and stores the resulting element into `r`. 123 | 124 | The function returns `0` on success, or `-1` if `p` and/or `q` are not valid encoded elements. 125 | 126 | ## Scalar arithmetic over L 127 | 128 | 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). 129 | 130 | Non-reduced inputs are expected to be within that interval. 131 | 132 | A random scalar can be obtained using the `crypto_core_ristretto255_scalar_random()` function: 133 | 134 | ``` c 135 | void crypto_core_ristretto255_scalar_random(unsigned char *r); 136 | ``` 137 | 138 | `crypto_core_ristretto255_scalar_random()` fills `r` with a `crypto_core_ristretto255_SCALARBYTES` bytes representation of the scalar in the `]0..L[` interval. 139 | 140 | A scalar in the `[0..L[` interval can also be obtained by reducing a possibly larger value: 141 | 142 | ``` c 143 | void crypto_core_ristretto255_scalar_reduce(unsigned char *r, const unsigned char *s); 144 | ``` 145 | 146 | The `crypto_core_ristretto255_scalar_reduce()` function reduces `s` to `s mod L` and puts the `crypto_core_ristretto255_SCALARBYTES` integer into `r`. 147 | 148 | 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`. 149 | 150 | ``` c 151 | int crypto_core_ristretto255_scalar_invert(unsigned char *recip, const unsigned char *s); 152 | ``` 153 | 154 | The `crypto_core_ristretto255_scalar_invert()` function computes the multiplicative inverse of `s` over `L`, and puts it into `recip`. 155 | 156 | ``` c 157 | void crypto_core_ristretto255_scalar_negate(unsigned char *neg, const unsigned char *s); 158 | ``` 159 | 160 | The `crypto_core_ristretto255_scalar_negate()` function returns `neg` so that `s + neg = 0 (mod L)`. 161 | 162 | ``` c 163 | void crypto_core_ristretto255_scalar_complement(unsigned char *comp, const unsigned char *s); 164 | ``` 165 | 166 | The `crypto_core_ristretto255_scalar_complement()` function returns `comp` so that `s + comp = 1 (mod L)`. 167 | 168 | ``` c 169 | void crypto_core_ristretto255_scalar_add(unsigned char *z, 170 | const unsigned char *x, const unsigned char *y); 171 | ``` 172 | 173 | The `crypto_core_ristretto255_scalar_add()` function stores `x + y (mod L)` into `z`. 174 | 175 | ``` c 176 | void crypto_core_ristretto255_scalar_sub(unsigned char *z, 177 | const unsigned char *x, const unsigned char *y); 178 | ``` 179 | 180 | The `crypto_core_ristretto255_scalar_sub()` function stores `x - y (mod L)` into `z`. 181 | 182 | ``` c 183 | void crypto_core_ristretto255_scalar_mul(unsigned char *z, 184 | const unsigned char *x, const unsigned char *y); 185 | ``` 186 | 187 | The `crypto_core_ristretto255_scalar_mul()` function stores `x * y (mod L)` into `z`. 188 | 189 | ## Constants 190 | 191 | - `crypto_scalarmult_ristretto255_BYTES` 192 | - `crypto_scalarmult_ristretto255_SCALARBYTES` 193 | - `crypto_core_ristretto255_BYTES` 194 | - `crypto_core_ristretto255_HASHBYTES` 195 | - `crypto_core_ristretto255_SCALARBYTES` 196 | - `crypto_core_ristretto255_NONREDUCEDSCALARBYTES` 197 | 198 | ## Notes 199 | 200 | As Ristretto encodes a field element that is always smaller than 2^255, the top bit is not used. 201 | 202 | It can be thus used by applications to encode additional data. 203 | 204 | Forcing the top bit to zero in order to ignore it: 205 | 206 | ``` c 207 | s[31] &= 0x7f; 208 | ``` 209 | 210 | Rejecting a key that has the top bit set: 211 | 212 | ``` c 213 | if ((s[31] & 0x80) != 0) { 214 | return; 215 | } 216 | ``` 217 | 218 | ## Algorithms 219 | 220 | - `ristretto255` 221 | 222 | ## References 223 | 224 | - [Ristretto](https://ristretto.group) 225 | - [Decaf: Eliminating cofactors through point compression](https://eprint.iacr.org/2015/673.pdf) 226 | -------------------------------------------------------------------------------- /internals/README.md: -------------------------------------------------------------------------------- 1 | # Internals 2 | 3 | ## Naming conventions 4 | 5 | Sodium follows the NaCl naming conventions. 6 | 7 | Each operation defines functions and macros in a dedicated `crypto_operation` namespace. For example, the “hash” operation defines: 8 | 9 | - A description of the underlying primitive: `crypto_hash_PRIMITIVE`. 10 | - Constants, such as key and output lengths: `crypto_hash_BYTES`. 11 | - For each constant, a function returning the same value. The name is identical to the constant but all lowercase: `crypto_hash_bytes(void)`. 12 | - A set of functions with the same prefix or identical to the prefix: `crypto_hash()`. 13 | 14 | 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. 15 | 16 | To guarantee forward compatibility, specific implementations are intentionally not directly accessible. The library is responsible for choosing the best working implementation at runtime. 17 | 18 | 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. 19 | 20 | ## Avoiding type confusion 21 | 22 | An object type has only one public representation. 23 | 24 | Points and scalars are always accepted and returned as a fixed-size, compressed, portable, and serializable bit string. 25 | 26 | This simplifies usage and mitigates type confusion in languages that don’t enforce strict type safety. 27 | 28 | ## Thread safety 29 | 30 | Initializing the random number generator is the only operation that requires an internal lock. 31 | 32 | `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. 33 | 34 | On POSIX systems, everything in libsodium is guaranteed to be thread-safe. 35 | 36 | ## Heap allocations 37 | 38 | Cryptographic operations in Sodium never allocate memory on the heap (`malloc`, `calloc`, etc), except for `crypto_pwhash` and `sodium_malloc`. 39 | 40 | ## Prepended zeros 41 | 42 | For some operations, the traditional NaCl API requires extra zero bytes (`*_ZEROBYTES`, `*_BOXZEROBYTES`) before messages and ciphertexts. 43 | 44 | However, this proved to be error-prone. Therefore, functions whose input requires transformations before they can be used are discouraged in Sodium. 45 | 46 | When NaCl API compatibility is required, alternative functions that do not require extra steps are available and recommended. 47 | 48 | ## Branches 49 | 50 | Secrets are always compared in constant time using `sodium_memcmp()` or `crypto_verify_(16|32|64)()`. 51 | 52 | ## Alignment and endianness 53 | 54 | All operations work on big-endian and little-endian systems and do not require pointers to be aligned. 55 | 56 | ## C macros 57 | 58 | C header files cannot be used in other programming languages. 59 | 60 | For this reason, none of the documented functions are macros hiding the actual symbols. 61 | 62 | ## Security first 63 | 64 | When a balance is required, extra safety measures have a higher priority than speed. Examples include: 65 | 66 | - Sensitive data is wiped from memory when the cost remains reasonable compared to the cost of the actual computations. 67 | - Signatures use different code paths for verification to mitigate fault attacks and check for small order nonces. 68 | - X25519 checks for weak public keys. 69 | - Heap memory allocations ensure that pages are not swapped and cannot be shared with other processes. 70 | - 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. 71 | - 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. 72 | - 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. 73 | - 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. 74 | - 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. 75 | 76 | ## Testing 77 | 78 | ### Unit testing 79 | 80 | The test suite covers all the functions, symbols, and macros of the library built with `--enable-minimal`. 81 | 82 | In addition to fixed test vectors, all functions include non-deterministic tests using variable-length, random data. 83 | 84 | 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. 85 | 86 | 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. 87 | 88 | ### Static analysis 89 | 90 | Continuous static analysis of the Sodium source code is performed using Coverity and GitHub’s CodeQL scanner. 91 | 92 | On Windows, static analysis is done using Visual Studio and Viva64 PVS-Studio. 93 | 94 | The Clang static analyzer is also used on macOS and Linux. 95 | 96 | Releases are never shipped until all these tools report zero defects. 97 | 98 | ### Dynamic analysis 99 | 100 | 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). 101 | 102 | 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. 103 | 104 | - asmjs/V8 (node + in-browser), asmjs/SpiderMonkey, asmjs/JavaScriptCore 105 | - WebAssembly/V8, WebAssembly/Firefox, WebAssembly/WASI using zig cc 106 | - OpenBSD-current/x86\_64 107 | - Ubuntu/x86\_64 using GCC 12, `-fsanitize=address,undefined` and Valgrind (Memcheck, Helgrind, DRD, and SGCheck) 108 | - Ubuntu/x86\_64 using Clang 16, `-fsanitize=address,undefined` and Valgrind (Memcheck, Helgrind, DRD, and SGCheck) 109 | - Ubuntu/x86\_64 using TCC 110 | - Ubuntu/x86\_64 using CompCert 111 | - macOS using Xcode 15 112 | - macOS using zig cc 113 | - Windows 11 using Visual Studio 2019 and 2022 (x86 and x86\_64) 114 | - MSYS2 using MinGW32 and MinGW64 115 | - Arch Linux/x86\_64 116 | - Arch Linux/ARMv6 117 | - Debian/x86 118 | - Debian/SPARC 119 | - Debian/ppc 120 | - Raspbian/Cortex-A53 121 | - Ubuntu/AArch64 - Courtesy of the GCC Compile Farm project 122 | - Fedora/ppc64 - Courtesy of the GCC Compile Farm project 123 | - AIX 7.1/ppc64 - Courtesy of the GCC Compile Farm project 124 | - Debian/MIPS64 - Courtesy of the GCC Compile Farm project 125 | 126 | ### Cross-implementation testing 127 | 128 | [crypto test vectors](https://github.com/jedisct1/crypto-test-vectors) aims to generate large collections of test vectors for cryptographic primitives using different implementations. 129 | 130 | [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. 131 | 132 | ## Bindings for other languages 133 | 134 | Bindings are essential to the libsodium ecosystem. It is expected that: 135 | 136 | - New versions of libsodium will be installed along with bindings written before these libsodium versions were available. 137 | - Recent versions of these bindings will be installed along with older versions of libsodium (e.g. a stock package from a Linux distribution). 138 | 139 | For these reasons, ABI stability is critical: 140 | 141 | - 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. 142 | - However, symbols that will eventually be removed can be tagged with GCC’s `deprecated` attribute. They can also be removed from minimal builds. 143 | - 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. 144 | 145 | Any major change to the library should be tested for compatibility with popular bindings, especially those recompiling a copy of the library. 146 | -------------------------------------------------------------------------------- /secret-key_cryptography/encrypted-messages.md: -------------------------------------------------------------------------------- 1 | # Encrypting a sequence or a set of dependent messages 2 | 3 | The `crypto_secretbox`, `crypto_box` and `crypto_seal` APIs are designed to encrypt **independent** messages. 4 | 5 | However, applications may wish to encrypt a set of messages with the following constraints: 6 | 7 | - 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. 8 | - 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. 9 | 10 | Simply encrypting individual messages with a random nonce doesn’t respect these constraints. 11 | 12 | For sequences of messages, libsodium 1.0.14 and beyond implement the [`crypto_secretstream` API](secretstream.md) 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. 13 | 14 | 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. 15 | 16 | Recommended API: [`crypto_aead_xchacha20poly1305_ietf_*()`](xchacha20-poly1305_construction.md). 17 | 18 | ## Initialization vector 19 | 20 | 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. 21 | 22 | The easiest way to achieve this is to choose a random initial nonce, and to increment it after each message: 23 | 24 | ``` c 25 | unsigned char nonce[NPUBBYTES]; 26 | 27 | randombytes_buf(nonce, sizeof nonce); 28 | 29 | encrypt(c1, m1, key, nonce); 30 | sodium_increment(nonce, sizeof nonce); 31 | encrypt(c2, m2, key, nonce); 32 | sodium_increment(nonce, sizeof nonce); 33 | ... 34 | ``` 35 | 36 | 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. 37 | 38 | 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. 39 | 40 | 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. 41 | 42 | 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. 43 | 44 | ## Authentication tags 45 | 46 | AEAD constructions encrypt messages and append an authentication tag. That authentication tag is computed using the following data: 47 | 48 | - The secret key 49 | - The nonce 50 | - The message, before or after encryption 51 | - Optionally, some additional data 52 | 53 | 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. 54 | 55 | 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. 56 | 57 | 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. 58 | 59 | ## Additional data 60 | 61 | 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. 62 | 63 | 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. 64 | 65 | How additional data are used is specific to every application and protocol, but here are two sample use cases for them: 66 | 67 | - **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. 68 | 69 | - **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. 70 | 71 | ## Ordered and unordered messages 72 | 73 | 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. 74 | 75 | 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. 76 | 77 | 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. 78 | 79 | 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. 80 | 81 | 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 a an encrypted message whose attached nonce has been tampered with. 82 | 83 | ## Shared keys and repeated nonces 84 | 85 | As previously stated, it is important to avoid using the same nonce to encrypt different messages. 86 | 87 | 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. 88 | 89 | 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`. 90 | 91 | The key exchange API (`crypto_kx()` functions) creates two different keys for that purpose. 92 | 93 | ## Short nonces 94 | 95 | Ciphers such as `AES` do not feature nonces large enough to be randomly chosen without taking the risk of repeating a nonce. 96 | 97 | 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. 98 | 99 | 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. 100 | 101 | 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. 102 | 103 | The actual encryption is done as follows: 104 | 105 | - Using a pseudorandom function, a subkey and a shorter nonce are derived from the key and the large nonce 106 | - The cipher is used with this subkey and short nonce to encrypt or decrypt a message 107 | 108 | 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 arbitrary long nonce: 109 | 110 | ``` c 111 | unsigned char out[32 + 12]; 112 | unsigned char *subkey = out; 113 | unsigned char *subnonce = out + 32; 114 | crypto_generichash(out, sizeof out, nonce, sizeof nonce, key, sizeof key); 115 | ``` 116 | 117 | 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. 118 | 119 | Unless a cipher such as `AES` is a requirement, using a cipher with a longer nonce is easier and safer. 120 | 121 | ## Note 122 | 123 | Please refer to the [main page on AEAD constructions](aead.md) for detailed information about the limitations of each construction. 124 | -------------------------------------------------------------------------------- /secret-key_cryptography/xchacha20-poly1305_construction.md: -------------------------------------------------------------------------------- 1 | # The XChaCha20-Poly1305 construction 2 | 3 | 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). 4 | 5 | As an alternative to counters, its large nonce size (192-bit) allows random nonces to be safely used. 6 | 7 | For this reason, and if interoperability with other libraries is not a concern, this is the recommended AEAD construction. 8 | 9 | ## Example (combined mode) 10 | 11 | ``` c 12 | #define MESSAGE (const unsigned char *) "test" 13 | #define MESSAGE_LEN 4 14 | #define ADDITIONAL_DATA (const unsigned char *) "123456" 15 | #define ADDITIONAL_DATA_LEN 6 16 | 17 | unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES]; 18 | unsigned char key[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]; 19 | unsigned char ciphertext[MESSAGE_LEN + crypto_aead_xchacha20poly1305_ietf_ABYTES]; 20 | unsigned long long ciphertext_len; 21 | 22 | crypto_aead_xchacha20poly1305_ietf_keygen(key); 23 | randombytes_buf(nonce, sizeof nonce); 24 | 25 | crypto_aead_xchacha20poly1305_ietf_encrypt(ciphertext, &ciphertext_len, 26 | MESSAGE, MESSAGE_LEN, 27 | ADDITIONAL_DATA, ADDITIONAL_DATA_LEN, 28 | NULL, nonce, key); 29 | 30 | unsigned char decrypted[MESSAGE_LEN]; 31 | unsigned long long decrypted_len; 32 | if (crypto_aead_xchacha20poly1305_ietf_decrypt(decrypted, &decrypted_len, 33 | NULL, 34 | ciphertext, ciphertext_len, 35 | ADDITIONAL_DATA, 36 | ADDITIONAL_DATA_LEN, 37 | nonce, key) != 0) { 38 | /* message forged! */ 39 | } 40 | ``` 41 | 42 | ## Combined mode 43 | 44 | In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. 45 | 46 | ``` c 47 | int crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c, 48 | unsigned long long *clen_p, 49 | const unsigned char *m, 50 | unsigned long long mlen, 51 | const unsigned char *ad, 52 | unsigned long long adlen, 53 | const unsigned char *nsec, 54 | const unsigned char *npub, 55 | const unsigned char *k); 56 | ``` 57 | 58 | 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). 59 | 60 | 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`. 61 | 62 | `ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required. 63 | 64 | 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. 65 | 66 | `nsec` is not used by this particular construction and should always be `NULL`. 67 | 68 | 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 unpredicable. 69 | 70 | ``` c 71 | int crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m, 72 | unsigned long long *mlen_p, 73 | unsigned char *nsec, 74 | const unsigned char *c, 75 | unsigned long long clen, 76 | const unsigned char *ad, 77 | unsigned long long adlen, 78 | const unsigned char *npub, 79 | const unsigned char *k); 80 | ``` 81 | 82 | 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). 83 | 84 | `ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required. 85 | 86 | `nsec` is not used by this particular construction and should always be `NULL`. 87 | 88 | The function returns `-1` if the verification fails. 89 | 90 | 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. 91 | 92 | At most `clen - crypto_aead_xchacha20poly1305_ietf_ABYTES` bytes will be put into `m`. 93 | 94 | ## Detached mode 95 | 96 | Some applications may need to store the authentication tag and the encrypted message at different locations. 97 | 98 | For this specific use case, “detached” variants of the functions above are available. 99 | 100 | ``` c 101 | int crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c, 102 | unsigned char *mac, 103 | unsigned long long *maclen_p, 104 | const unsigned char *m, 105 | unsigned long long mlen, 106 | const unsigned char *ad, 107 | unsigned long long adlen, 108 | const unsigned char *nsec, 109 | const unsigned char *npub, 110 | const unsigned char *k); 111 | ``` 112 | 113 | 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`. 114 | 115 | 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. 116 | 117 | `nsec` is not used by this particular construction and should always be `NULL`. 118 | 119 | ``` c 120 | int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, 121 | unsigned char *nsec, 122 | const unsigned char *c, 123 | unsigned long long clen, 124 | const unsigned char *mac, 125 | const unsigned char *ad, 126 | unsigned long long adlen, 127 | const unsigned char *npub, 128 | const unsigned char *k); 129 | ``` 130 | 131 | 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. 132 | 133 | If the tag is not valid, the function returns `-1` and doesn’t do any further processing. 134 | 135 | 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. 136 | 137 | `nsec` is not used by this particular construction and should always be `NULL`. 138 | 139 | ``` c 140 | void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]); 141 | ``` 142 | 143 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 144 | 145 | 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. 146 | 147 | ## Constants 148 | 149 | - `crypto_aead_xchacha20poly1305_ietf_KEYBYTES` 150 | - `crypto_aead_xchacha20poly1305_ietf_NPUBBYTES` 151 | - `crypto_aead_xchacha20poly1305_ietf_ABYTES` 152 | 153 | ## Algorithm details 154 | 155 | - Encryption: XChaCha20 stream cipher 156 | - Authentication: Poly1305 MAC 157 | 158 | ## Notes 159 | 160 | XChaCha20-Poly1305 was introduced in libsodium 1.0.12. 161 | 162 | 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. 163 | -------------------------------------------------------------------------------- /secret-key_cryptography/ietf_chacha20-poly1305_construction.md: -------------------------------------------------------------------------------- 1 | # The IETF ChaCha20-Poly1305 construction 2 | 3 | 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 (approximatively 256 GiB). 4 | 5 | ## Example (combined mode) 6 | 7 | ``` c 8 | #define MESSAGE (const unsigned char *) "test" 9 | #define MESSAGE_LEN 4 10 | #define ADDITIONAL_DATA (const unsigned char *) "123456" 11 | #define ADDITIONAL_DATA_LEN 6 12 | 13 | unsigned char nonce[crypto_aead_chacha20poly1305_IETF_NPUBBYTES]; 14 | unsigned char key[crypto_aead_chacha20poly1305_IETF_KEYBYTES]; 15 | unsigned char ciphertext[MESSAGE_LEN + crypto_aead_chacha20poly1305_IETF_ABYTES]; 16 | unsigned long long ciphertext_len; 17 | 18 | crypto_aead_chacha20poly1305_ietf_keygen(key); 19 | randombytes_buf(nonce, sizeof nonce); 20 | 21 | crypto_aead_chacha20poly1305_ietf_encrypt(ciphertext, &ciphertext_len, 22 | MESSAGE, MESSAGE_LEN, 23 | ADDITIONAL_DATA, ADDITIONAL_DATA_LEN, 24 | NULL, nonce, key); 25 | 26 | unsigned char decrypted[MESSAGE_LEN]; 27 | unsigned long long decrypted_len; 28 | if (crypto_aead_chacha20poly1305_ietf_decrypt(decrypted, &decrypted_len, 29 | NULL, 30 | ciphertext, ciphertext_len, 31 | ADDITIONAL_DATA, 32 | ADDITIONAL_DATA_LEN, 33 | nonce, key) != 0) { 34 | /* message forged! */ 35 | } 36 | ``` 37 | 38 | ## Combined mode 39 | 40 | In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. 41 | 42 | ``` c 43 | int crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, 44 | unsigned long long *clen_p, 45 | const unsigned char *m, 46 | unsigned long long mlen, 47 | const unsigned char *ad, 48 | unsigned long long adlen, 49 | const unsigned char *nsec, 50 | const unsigned char *npub, 51 | const unsigned char *k); 52 | ``` 53 | 54 | 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). 55 | 56 | 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`. 57 | 58 | `ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required. 59 | 60 | 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. 61 | 62 | `nsec` is not used by this particular construction and should always be `NULL`. 63 | 64 | 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. 65 | 66 | ``` c 67 | int crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, 68 | unsigned long long *mlen_p, 69 | unsigned char *nsec, 70 | const unsigned char *c, 71 | unsigned long long clen, 72 | const unsigned char *ad, 73 | unsigned long long adlen, 74 | const unsigned char *npub, 75 | const unsigned char *k); 76 | ``` 77 | 78 | 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). 79 | 80 | `ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required. 81 | 82 | `nsec` is not used by this particular construction and should always be `NULL`. 83 | 84 | The function returns `-1` if the verification fails. 85 | 86 | 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. 87 | 88 | At most `clen - crypto_aead_chacha20poly1305_IETF_ABYTES` bytes will be put into `m`. 89 | 90 | ## Detached mode 91 | 92 | Some applications may need to store the authentication tag and the encrypted message at different locations. 93 | 94 | For this specific use case, “detached” variants of the functions above are available. 95 | 96 | ``` c 97 | int crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, 98 | unsigned char *mac, 99 | unsigned long long *maclen_p, 100 | const unsigned char *m, 101 | unsigned long long mlen, 102 | const unsigned char *ad, 103 | unsigned long long adlen, 104 | const unsigned char *nsec, 105 | const unsigned char *npub, 106 | const unsigned char *k); 107 | ``` 108 | 109 | 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`. 110 | 111 | 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. 112 | 113 | `nsec` is not used by this particular construction and should always be `NULL`. 114 | 115 | ``` c 116 | int crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, 117 | unsigned char *nsec, 118 | const unsigned char *c, 119 | unsigned long long clen, 120 | const unsigned char *mac, 121 | const unsigned char *ad, 122 | unsigned long long adlen, 123 | const unsigned char *npub, 124 | const unsigned char *k); 125 | ``` 126 | 127 | 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. 128 | 129 | If the tag is not valid, the function returns `-1` and doesn’t do any further processing. 130 | 131 | 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. 132 | 133 | `nsec` is not used by this particular construction and should always be `NULL`. 134 | 135 | ``` c 136 | void crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]); 137 | ``` 138 | 139 | This helper function introduced in libsodium 1.0.12 creates a random key `k`. 140 | 141 | 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. 142 | 143 | ## Constants 144 | 145 | - `crypto_aead_chacha20poly1305_IETF_ABYTES` 146 | - `crypto_aead_chacha20poly1305_IETF_KEYBYTES` 147 | - `crypto_aead_chacha20poly1305_IETF_NPUBBYTES` 148 | 149 | 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. 150 | 151 | ## Algorithm details 152 | 153 | - Encryption: ChaCha20 stream cipher 154 | - Authentication: Poly1305 MAC 155 | 156 | ## Notes 157 | 158 | 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. 159 | 160 | 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. 161 | 162 | ## See also 163 | 164 | - [ChaCha20 and Poly1305 for IETF protocols](https://tools.ietf.org/html/rfc7539) - Specification of the IETF variant 165 | -------------------------------------------------------------------------------- /advanced/point-arithmetic.md: -------------------------------------------------------------------------------- 1 | # Finite field arithmetic 2 | 3 | A set of low-level APIs to perform computations over the edwards25519 curve, only useful to implement custom constructions. 4 | 5 | Points are represented as their Y coordinate. 6 | 7 | ## Example 8 | 9 | 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. 10 | 11 | ``` c 12 | // -------- First party -------- Send blinded p(x) 13 | unsigned char x[crypto_core_ed25519_UNIFORMBYTES]; 14 | randombytes_buf(x, sizeof x); 15 | 16 | // Compute px = p(x), an EC point representative for x 17 | unsigned char px[crypto_core_ed25519_BYTES]; 18 | crypto_core_ed25519_from_uniform(px, x); 19 | 20 | // Compute a = p(x) * g^r 21 | unsigned char r[crypto_core_ed25519_SCALARBYTES]; 22 | unsigned char gr[crypto_core_ed25519_BYTES]; 23 | unsigned char a[crypto_core_ed25519_BYTES]; 24 | crypto_core_ed25519_scalar_random(r); 25 | crypto_scalarmult_ed25519_base_noclamp(gr, r); 26 | crypto_core_ed25519_add(a, px, gr); 27 | 28 | // -------- Second party -------- Send g^k and a^k 29 | unsigned char k[crypto_core_ed25519_SCALARBYTES]; 30 | randombytes_buf(k, sizeof k); 31 | 32 | // Compute v = g^k 33 | unsigned char v[crypto_core_ed25519_BYTES]; 34 | crypto_scalarmult_ed25519_base(v, k); 35 | 36 | // Compute b = a^k 37 | unsigned char b[crypto_core_ed25519_BYTES]; 38 | if (crypto_scalarmult_ed25519(b, k, a) != 0) { 39 | return -1; 40 | } 41 | 42 | // -------- First party -------- Unblind f(x) 43 | // Compute vir = v^(-r) 44 | unsigned char ir[crypto_core_ed25519_SCALARBYTES]; 45 | unsigned char vir[crypto_core_ed25519_BYTES]; 46 | crypto_core_ed25519_scalar_negate(ir, r); 47 | crypto_scalarmult_ed25519_noclamp(vir, ir, v); 48 | 49 | // Compute f(x) = b * v^(-r) = (p(x) * g^r)^k * (g^k)^(-r) 50 | // = (p(x) * g)^k * g^(-k) = p(x)^k 51 | unsigned char fx[crypto_core_ed25519_BYTES]; 52 | crypto_core_ed25519_add(fx, b, vir); 53 | ``` 54 | 55 | ## Point validation 56 | 57 | ``` c 58 | int crypto_core_ed25519_is_valid_point(const unsigned char *p); 59 | ``` 60 | 61 | 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. 62 | 63 | It returns `1` on success, and `0` if the checks didn’t pass. 64 | 65 | ## Random group element 66 | 67 | ``` c 68 | void crypto_core_ed25519_random(unsigned char *p); 69 | ``` 70 | 71 | Fills `p` with the representation of a random group element. 72 | 73 | ## Elligator 2 map 74 | 75 | ``` c 76 | int crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r); 77 | ``` 78 | 79 | The `crypto_core_ed25519_from_uniform()` function maps a 32 bytes vector `r` to a point, and stores its compressed representation into `p`. 80 | 81 | The point is guaranteed to be on the main subgroup. 82 | 83 | 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. 84 | 85 | ## Hash-to-group 86 | 87 | ## Scalar multiplication 88 | 89 | ``` c 90 | int crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, 91 | const unsigned char *p); 92 | ``` 93 | 94 | The `crypto_scalarmult_ed25519()` function multiplies a point `p` by a scalar `n` and puts the Y coordinate of the resulting point into `q`. 95 | 96 | `q` should not be used as a shared key prior to hashing. 97 | 98 | 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. 99 | 100 | 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). 101 | 102 | ``` c 103 | int crypto_scalarmult_ed25519_base(unsigned char *q, const unsigned char *n); 104 | ``` 105 | 106 | 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`. 107 | 108 | The function returns `-1` if `n` is `0`, and `0` otherwise. 109 | 110 | ## Scalar multiplication without clamping 111 | 112 | In order to prevent attacks using small subgroups, the `scalarmult` functions above clear lower bits of the scalar. This may be indesirable to build protocols that requires `n` to be invertible. 113 | 114 | 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. 115 | 116 | ``` c 117 | int crypto_scalarmult_ed25519_noclamp(unsigned char *q, const unsigned char *n, 118 | const unsigned char *p); 119 | ``` 120 | 121 | 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. 122 | 123 | ``` c 124 | int crypto_scalarmult_ed25519_base_noclamp(unsigned char *q, const unsigned char *n); 125 | ``` 126 | 127 | The function returns `0` on success, or `-1` if `n` is `0`. 128 | 129 | ## Point addition/subtraction 130 | 131 | ``` c 132 | int crypto_core_ed25519_add(unsigned char *r, 133 | const unsigned char *p, const unsigned char *q); 134 | ``` 135 | 136 | The `crypto_core_ed25519_add()` function adds the point `p` to the point `q` and stores the resulting point into `r`. 137 | 138 | The function returns `0` on success, or `-1` if `p` and/or `q` are not valid points. 139 | 140 | ``` c 141 | int crypto_core_ed25519_sub(unsigned char *r, 142 | const unsigned char *p, const unsigned char *q); 143 | ``` 144 | 145 | The `crypto_core_ed25519_sub()` function subtracts the point `p` to the point `q` and stores the resulting point into `r`. 146 | 147 | The function returns `0` on success, or `-1` if `p` and/or `q` are not valid points. 148 | 149 | ## Scalar arithmetic over L 150 | 151 | 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). 152 | 153 | Non-reduced inputs are expected to be within that interval. 154 | 155 | A random scalar can be obtained using the `crypto_core_ed25519_scalar_random()` function introduced in libsodium 1.0.17: 156 | 157 | ``` c 158 | void crypto_core_ed25519_scalar_random(unsigned char *r); 159 | ``` 160 | 161 | `crypto_core_ed25519_scalar_random()` fills `r` with a `crypto_core_ed25519_SCALARBYTES` bytes representation of the scalar in the `]0..L[` interval. 162 | 163 | A scalar in the `[0..L[` interval can also be obtained by reducing a possibly larger value: 164 | 165 | ``` c 166 | void crypto_core_ed25519_scalar_reduce(unsigned char *r, const unsigned char *s); 167 | ``` 168 | 169 | The `crypto_core_ed25519_scalar_reduce()` function reduces `s` to `s mod L` and puts the `crypto_core_ed25519_SCALARBYTES` integer into `r`. 170 | 171 | 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`. 172 | 173 | ``` c 174 | int crypto_core_ed25519_scalar_invert(unsigned char *recip, const unsigned char *s); 175 | ``` 176 | 177 | The `crypto_core_ed25519_scalar_invert()` function computes the multiplicative inverse of `s` over `L`, and puts it into `recip`. 178 | 179 | ``` c 180 | void crypto_core_ed25519_scalar_negate(unsigned char *neg, const unsigned char *s); 181 | ``` 182 | 183 | The `crypto_core_ed25519_scalar_negate()` function returns `neg` so that `s + neg = 0 (mod L)`. 184 | 185 | ``` c 186 | void crypto_core_ed25519_scalar_complement(unsigned char *comp, const unsigned char *s); 187 | ``` 188 | 189 | The `crypto_core_ed25519_scalar_complement()` function returns `comp` so that `s + comp = 1 (mod L)`. 190 | 191 | ``` c 192 | void crypto_core_ed25519_scalar_add(unsigned char *z, 193 | const unsigned char *x, const unsigned char *y); 194 | ``` 195 | 196 | The `crypto_core_ed25519_scalar_add()` function stores `x + y (mod L)` into `z`. 197 | 198 | ``` c 199 | void crypto_core_ed25519_scalar_sub(unsigned char *z, 200 | const unsigned char *x, const unsigned char *y); 201 | ``` 202 | 203 | The `crypto_core_ed25519_scalar_sub()` function stores `x - y (mod L)` into `z`. 204 | 205 | ``` c 206 | void crypto_core_ed25519_scalar_mul(unsigned char *z, 207 | const unsigned char *x, const unsigned char *y); 208 | ``` 209 | 210 | The `crypto_core_ed25519_scalar_mul()` function stores `x * y (mod L)` into `z`. 211 | 212 | ## Constants 213 | 214 | - `crypto_scalarmult_ed25519_BYTES` 215 | - `crypto_scalarmult_ed25519_SCALARBYTES` 216 | - `crypto_core_ed25519_BYTES` 217 | - `crypto_core_ed25519_UNIFORMBYTES` 218 | - `crypto_core_ed25519_SCALARBYTES` 219 | - `crypto_core_ed25519_NONREDUCEDSCALARBYTES` 220 | 221 | ## Note 222 | 223 | These functions were introduced in libsodium 1.0.16, 1.0.17 and 1.0.18. 224 | 225 | For a complete example using these functions, see the [SPAKE2+EE implementation](https://github.com/jedisct1/spake2-ee) for libsodium. 226 | 227 | `crypto_core_ed25519_from_uniform()` exposes the Elligator 2 map, using the high bit for the sign of the X coordinate. 228 | -------------------------------------------------------------------------------- /secret-key_cryptography/aegis/aegis-128l.md: -------------------------------------------------------------------------------- 1 | # AEGIS-128L 2 | 3 | AEGIS-128L is a modern AES-based cipher with unique properties making it easier and safer to use than common alternatives: 4 | 5 | - 256-bit authentication tags, ensuring collision resistance within a given key; a tag can thus be used as a unique identifier for a message. 6 | - It can safely encrypt a practically unlimited number of messages, without any practical limits on their lengths. 7 | - It has a 128 bit nonce size, allowing random nonces to be safely used up to 2^48 messages for a single key. 8 | - It has a better security margin than AES-GCM 9 | - Leaking the state doesn’t leak the key 10 | - 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. 11 | 12 | AEGIS-128L is also extremely fast on recent CPUs with AES pipelines, with lower memory usage than AES-GCM. 13 | 14 | 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. 15 | 16 | Unlike all other ciphers in libsodium, AEGIS-128L uses a 128 bit key. 17 | 18 | ## Example (combined mode) 19 | 20 | ``` c 21 | #define MESSAGE (const unsigned char *) "test" 22 | #define MESSAGE_LEN 4 23 | #define ADDITIONAL_DATA (const unsigned char *) "123456" 24 | #define ADDITIONAL_DATA_LEN 6 25 | 26 | unsigned char nonce[crypto_aead_aegis128l_NPUBBYTES]; 27 | unsigned char key[crypto_aead_aegis128l_KEYBYTES]; 28 | unsigned char ciphertext[MESSAGE_LEN + crypto_aead_aegis128l_ABYTES]; 29 | unsigned long long ciphertext_len; 30 | 31 | crypto_aead_aegis128l_keygen(key); 32 | randombytes_buf(nonce, sizeof nonce); 33 | 34 | crypto_aead_aegis128l_encrypt(ciphertext, &ciphertext_len, 35 | MESSAGE, MESSAGE_LEN, 36 | ADDITIONAL_DATA, ADDITIONAL_DATA_LEN, 37 | NULL, nonce, key); 38 | 39 | unsigned char decrypted[MESSAGE_LEN]; 40 | unsigned long long decrypted_len; 41 | if (crypto_aead_aegis128l_decrypt(decrypted, &decrypted_len, 42 | NULL, 43 | ciphertext, ciphertext_len, 44 | ADDITIONAL_DATA, 45 | ADDITIONAL_DATA_LEN, 46 | nonce, key) != 0) { 47 | /* message forged! */ 48 | } 49 | ``` 50 | 51 | ## Combined mode 52 | 53 | In combined mode, the authentication tag is directly appended to the encrypted message. This is usually what you want. 54 | 55 | ``` c 56 | int crypto_aead_aegis128l_encrypt(unsigned char *c, 57 | unsigned long long *clen_p, 58 | const unsigned char *m, 59 | unsigned long long mlen, 60 | const unsigned char *ad, 61 | unsigned long long adlen, 62 | const unsigned char *nsec, 63 | const unsigned char *npub, 64 | const unsigned char *k); 65 | ``` 66 | 67 | 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). 68 | 69 | 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`. 70 | 71 | `ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required. 72 | 73 | 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. 74 | 75 | `nsec` is not used by this particular construction and should always be `NULL`. 76 | 77 | 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. 78 | 79 | ``` c 80 | int crypto_aead_aegis128l_decrypt(unsigned char *m, 81 | unsigned long long *mlen_p, 82 | unsigned char *nsec, 83 | const unsigned char *c, 84 | unsigned long long clen, 85 | const unsigned char *ad, 86 | unsigned long long adlen, 87 | const unsigned char *npub, 88 | const unsigned char *k); 89 | ``` 90 | 91 | 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). 92 | 93 | `ad` can be a `NULL` pointer with `adlen` equal to `0` if no additional data are required. 94 | 95 | `nsec` is not used by this particular construction and should always be `NULL`. 96 | 97 | The function returns `-1` if the verification fails. 98 | 99 | 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. 100 | 101 | At most `clen - crypto_aead_aegis128l_ABYTES` bytes will be put into `m`. 102 | 103 | ## Detached mode 104 | 105 | Some applications may need to store the authentication tag and the encrypted message at different locations. 106 | 107 | For this specific use case, “detached” variants of the functions above are available. 108 | 109 | ``` c 110 | int crypto_aead_aegis128l_encrypt_detached(unsigned char *c, 111 | unsigned char *mac, 112 | unsigned long long *maclen_p, 113 | const unsigned char *m, 114 | unsigned long long mlen, 115 | const unsigned char *ad, 116 | unsigned long long adlen, 117 | const unsigned char *nsec, 118 | const unsigned char *npub, 119 | const unsigned char *k); 120 | ``` 121 | 122 | 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`. 123 | 124 | 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. 125 | 126 | `nsec` is not used by this particular construction and should always be `NULL`. 127 | 128 | ``` c 129 | int crypto_aead_aegis128l_decrypt_detached(unsigned char *m, 130 | unsigned char *nsec, 131 | const unsigned char *c, 132 | unsigned long long clen, 133 | const unsigned char *mac, 134 | const unsigned char *ad, 135 | unsigned long long adlen, 136 | const unsigned char *npub, 137 | const unsigned char *k); 138 | ``` 139 | 140 | 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. 141 | 142 | If the tag is not valid, the function returns `-1` and doesn’t do any further processing. 143 | 144 | 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. 145 | 146 | `nsec` is not used by this particular construction and should always be `NULL`. 147 | 148 | ``` c 149 | void crypto_aead_aegis128l_keygen(unsigned char k[crypto_aead_aegis128l_KEYBYTES]); 150 | ``` 151 | 152 | 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. 153 | 154 | ## Constants 155 | 156 | - `crypto_aead_aegis128l_ABYTES` 157 | - `crypto_aead_aegis128l_KEYBYTES` 158 | - `crypto_aead_aegis128l_NPUBBYTES` 159 | 160 | ## Notes 161 | 162 | - The key size is 128 bits (16 bytes), unlike all other ciphers in this library. 163 | - Unique nonces are required for each messsages. 164 | - 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. 165 | - However, it should *NOT* be used as a hash function. If the key is known, state collisions can be crafted. 166 | - 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. 167 | - AEGIS was added in libsodium version 1.0.19. 168 | 169 | ## See also 170 | 171 | - [The AEGIS Family Of Authenticated Encryption Algorithms](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aegis-aead) - AEGIS specification 172 | - [Reference implementations](https://github.com/cfrg/draft-irtf-cfrg-aegis-aead/tree/main/reference-implementations) 173 | - [libaegis](https://github.com/jedisct1/libaegis) - A more extensive C library for AEGIS variants 174 | --------------------------------------------------------------------------------