INTRO(3MONOCYPHER)                    LOCAL                   INTRO(3MONOCYPHER)

     intro — introduction to Monocypher

     Monocypher is a cryptographic library.  It provides functions for
     authenticated encryption, hashing, password hashing and key derivation, key
     exchange, and public key signatures.

   Authenticated encryption
     crypto_lock(3monocypher) and crypto_unlock(3monocypher) use the Chacha20
     cipher and the Poly1305 one-time authenticator.

     Chacha20 is a stream cipher based on a cryptographic hash function.  It
     runs efficiently on a wide variety of hardware, and unlike AES naturally
     runs in constant time on all hardware.

     Poly1305 is a one-time authenticator, derived from Carter & Wegman
     universal hashing.  It is very fast and very simple.

     For specialised needs, crypto_chacha20(3monocypher) and
     crypto_poly1305(3monocypher) are available to implement constructions
     involving them.  Whenever possible, crypto_lock(3monocypher) should be
     preferred, however.

     crypto_blake2b(3monocypher) implements the Blake2b hash.  Blake2b combines
     the security of SHA-3 and the speed of MD5.  It is immune to length
     extension attacks and provides a keyed mode that makes it a safe, easy to
     use authenticator.

   Password hashing and key derivation
     crypto_argon2i(3monocypher) implements the Argon2i resource intensive hash
     algorithm, which can be used to hash passwords for storage and to derive
     keys from passwords.  Argon2 won the password hashing competition in 2015.
     Unlike Scrypt, Argon2i is immune to timing attacks.

   Key exchange
     crypto_key_exchange(3monocypher) implements X25519, an elliptic curve
     Diffie Hellman key exchange algorithm based on Curve25519.  X25519 derives
     a shared secret from two private/public key pairs.  It is fast, simple, and
     relatively easy to implement securely.

     For specialised protocols that require indistinguishability from random
     noise, crypto_curve_to_hidden(3monocypher) gives the option to disguise
     ephemeral (one-time use) X25519 public keys as random noise.

   Public key signatures
     crypto_sign(3monocypher) and crypto_check(3monocypher) implement EdDSA,
     with Curve25519 and Blake2b.  This is the same as the more famous Ed25519,
     with SHA-512 replaced by the faster and more secure Blake2b.

     For highly specialised needs, it is possible to use a custom hash function
     with EdDSA; see crypto_sign_init_first_pass_custom_hash(3monocypher).

   Constant time comparison
     crypto_verify16(3monocypher), crypto_verify32(3monocypher), and
     crypto_verify64(3monocypher) compare buffers in constant time.  They should
     be used to compare secrets to prevent timing attacks.

   Memory wipe
     crypto_wipe(3monocypher) wipes a buffer.  It is meant to erase secrets when
     they are no longer needed, to reduce the chances of leaks.

   Optional code
     If Monocypher was compiled and installed with USE_ED25519, SHA-512
     functions become available as well.  See crypto_ed25519_sign(3monocypher),
     crypto_sha512(3monocypher), and crypto_hmac_sha512(3monocypher).

     crypto_argon2i(3monocypher), crypto_argon2i_general(3monocypher),
     crypto_blake2b(3monocypher), crypto_blake2b_final(3monocypher),
     crypto_blake2b_general_init(3monocypher), crypto_blake2b_init(3monocypher),
     crypto_blake2b_update(3monocypher), crypto_chacha20(3monocypher),
     crypto_chacha20_ctr(3monocypher), crypto_check(3monocypher),
     crypto_check_final(3monocypher), crypto_check_init(3monocypher),
     crypto_check_update(3monocypher), crypto_curve_to_hidden(3monocypher),
     crypto_from_eddsa_public(3monocypher), crypto_hchacha20(3monocypher),
     crypto_hidden_key_pair(3monocypher), crypto_hidden_to_curve(3monocypher),
     crypto_ietf_chacha20(3monocypher), crypto_ietf_chacha20_ctr(3monocypher),
     crypto_key_exchange(3monocypher), crypto_lock(3monocypher),
     crypto_lock_aead(3monocypher), crypto_poly1305(3monocypher),
     crypto_poly1305_final(3monocypher), crypto_poly1305_init(3monocypher),
     crypto_poly1305_update(3monocypher), crypto_sign(3monocypher),
     crypto_sign_final(3monocypher), crypto_sign_init_first_pass(3monocypher),
     crypto_sign_update(3monocypher), crypto_unlock(3monocypher),
     crypto_unlock_aead(3monocypher), crypto_verify16(3monocypher),
     crypto_verify32(3monocypher), crypto_verify64(3monocypher),
     crypto_wipe(3monocypher), crypto_x25519(3monocypher),
     crypto_x25519_dirty_small(3monocypher), crypto_x25519_inverse(3monocypher),
     crypto_x25519_public_key(3monocypher), crypto_xchacha20(3monocypher),

   Optional code
     crypto_from_ed25519_public(3monocypher), crypto_ed25519_check(3monocypher),
     crypto_ed25519_public_key(3monocypher), crypto_ed25519_sign(3monocypher),
     crypto_ed25519_sign_final(3monocypher), crypto_hmac_sha512(3monocypher),
     crypto_hmac_sha512_final(3monocypher) crypto_sha512(3monocypher),
     crypto_sha512_init(3monocypher), crypto_sha512_update(3monocypher),

     Using cryptography securely is difficult.  Flaws that never manifest under
     normal use might be exploited by a clever adversary.  Cryptographic
     libraries are easy to misuse.  Even Monocypher allows a number of fatal

     Users should follow a formal introduction to cryptography.  We currently
     recommend the Crypto 101 online course:

   Random number generation
     Use the facilities of your operating system.  Avoid user space random
     number generators.  They are easy to misuse, which has lead to countless
     vulnerabilities in the past.  For instance, the random stream may be
     repeated if one is not careful with multi-threading, and forward secrecy is
     lost without proper key erasure.

     Different system calls are available on different systems:

     Recent versions of Linux (glibc >= 2.25, Linux >= 3.17), provide
         getrandom() in <linux/random.h>.  Do not set any flag.

     BSD, Darwin/macOS, illumos as well as Solaris provide arc4random_buf()
         in <stdlib.h> or <bsd/stdlib.h>.  This is easier to use than

     Windows provides BCryptGenRandom().

     The /dev/urandom special file may be used on systems that do not provide an
     easy to use system call.  Be careful though, being a file makes
     /dev/urandom hard to use correctly and securely.  Reads may be interrupted,
     and more attacks are possible on a file than on a system call.

   Timing attacks
     Monocypher runs in “constant time”.  There is no flow from secrets to
     timings.  No secret dependent indices, no secret dependent branches.
     Nevertheless, there are a couple important caveats.

     Comparing secrets should be done with constant-time comparison functions,
     such as crypto_verify16(3monocypher), crypto_verify32(3monocypher), or
     crypto_verify64(3monocypher).  Do not use standard comparison functions.
     They tend to stop as soon as a difference is spotted.  In many cases, this
     enables attackers to recover the secrets and destroy all security.

     The Poly1305 authenticator, X25519, and EdDSA use multiplication.  Some
     older processors do not multiply in constant time.  If the target platform
     is something other than Intel or AMD x86_64, double check how it handles
     multiplication.  In particular, ARM Cortex-M CPUs may lack constant-time
     multiplication.  Some VIA Nano x86 and x86_64 CPUs may lack constant-time
     multiplication as well.

   Data compression
     Encryption does not hide the length of the input plaintext.  Most
     compression algorithms work by using fewer bytes to encode previously seen
     data or common characters.  If an attacker can add data to the input before
     it is compressed and encrypted, they can observe changes to the ciphertext
     length to recover secrets from the input.  Researchers have demonstrated an
     attack on HTTPS to steal session cookies when compression is enabled,
     dubbed “CRIME”.

   Forward secrecy
     Long term secrets cannot be expected to stay safe indefinitely.  Users may
     reveal them by mistake, or the host computer might have a vulnerability and
     be compromised.  To mitigate this problem, some protocols guarantee that
     past messages are not compromised even if the long term keys are.  This is
     done by generating temporary keys, then encrypting messages using them.

     In general, secrets that went through a computer should not be compromised
     when this computer is stolen or infected at a later point.

     A first layer of defence is to explicitly wipe secrets as soon as they are
     no longer used.  Monocypher already wipes its own temporary buffers, and
     contexts are erased with the crypto_*_final() functions.  The secret keys
     and messages however are the responsibility of the user.  Use
     crypto_wipe(3monocypher) to erase them.

     A second layer of defence is to ensure those secrets are not swapped to
     disk while they are used.  There are several ways to do this.  The most
     secure is to disable swapping entirely.  Doing so is recommended on
     sensitive machines.  Another way is to encrypt the swap partition (this is
     less safe).  Finally, swap can be disabled locally – this is often the only

     UNIX systems can disable swap for specific buffers with mlock(), and
     disable swap for the whole process with mlockall().  Windows can disable
     swap for specific buffers with VirtualLock().

     Core dumps cause similar problems.  Disable them.  Also beware of suspend
     to disk (deep sleep mode), which writes all RAM to disk regardless of swap
     policy, as well as virtual machine snapshots.  Erasing secrets with
     crypto_wipe(3monocypher) is often the only way to mitigate these dangers.

   Undefined behaviour
     Monocypher is a C library.  C is notoriously unsafe.  Using Monocypher
     incorrectly can trigger undefined behaviour.  This can lead to data
     corruption, data theft, or even arbitrary code execution.

     Consider binding to a safe language if possible.

BSD                              March 31, 2020                              BSD