For symmetric encryption, if you’re recommending Salsa20/ChaCha20, it is absolutely necessary to discuss nonce management, since this is a major footgun people coming from AES may not be familiar with. You should always use the extended nonce variants of these algorithms (XSalsa20/XChaCha20) if possible, with a random nonce for every message. If not, you will have to be certain that nonces are never reused with the same key, possibly through some counter construction. The real solution to symmetric encryption for most people is to use something like Sodium‘s `crypto_secretstream`, which smooths out all the rough edges.
“Use ECC” is too generic as advice for asymmetric encryption. Use Elliptic-Curve Diffie-Hellman for key exchange (X25519 ideally), and then use a symmetric AEAD construction (XChaCha20-Poly1305 or AES-GCM) to actually encrypt messages. For people familiar with RSA, in which the asymmetric construction is actually used to encrypt messages, this is unfamiliar, so explanation is necessary.
I would not recommend just “SHA-2” as the first choice for generic hash algorithms anymore, due to length extension attacks. Use BLAKE2b, SHA-3, or one of the well-studied truncated variants of SHA-2.
Also, I think monocypher was written independently of NaCl, it’s not a fork.
This is a fork of tptacek's 2015's Cryptographic Right Answers Gist [1]. I think the original 2015 file is somewhat better than this fork. The fork is more up-to-date, but just offers too many options and is probably to confusing for a beginner. As far as I know, the latest "official" update to Cryptographic Right Answers is the Latacora blog post from 2018 [2].
Both the the 2015 version of Right Answers and the OP best practice guide mention (non-extended) ChaCha20-Poly1305, but if you look at their order of priorities, using NaCl/libsodium/monocypher is always mentioned first. That gives you XSalsa20-Poly1305 (NaCl, libsodium default) or XChaCha20-Poly1305 (monocypher, optional for libsodium). the non-extended ChaPoly20 is mentioned as lower priority than the extended versions, but higher priority than AES-GCM, which also features short nonces.
The same argument goes for ECC. The actual "Use" line in the document mentions NaCl, libsodium and monocypher, all of them use X25519 by default, although monocypher does not seem to offer an asymmetric encryption primitive. The main issue is the confusing language talking about ECC, when we know than some ECC (yes, I'm looking at you ECDSA) is not strictly better than RSA [3].
None of the answers in the OP guide seems wrong per se (I didn't review this thoroughly FWIW and I'm not an expert). But I'm still recommending this one, since it's simpler, and "simpler" is the entire point of this kind of guide. You want to avoid programmers shooting themselves in the foot - and shooting yourself in the foot is really easy when you're implementing cryptography.
> monocypher does not seem to offer an asymmetric encryption primitive.
Neither do NaCl and Libsodium. Their `crypto_box()` is a construction that does key exchange, derives a key from the resulting key exchange, and finally use that key to perform symmetric authenticated encryption. I simply omitted that particular construction for Monocypher.
I've often asked be why. My reason is that the NaCl libraries (all 3 of them) are low-level, and a straightforward application of `crypto_box()` lacks the security properties we've now come to expect of modern key exchanges, most notably forward secrecy. To get up to that level would require implementing Noise, and I personally feel that's a tad out of scope. I reckon however that higher-level libraries that implement full protocols however are sorely needed.
> For symmetric encryption, if you’re recommending Salsa20/ChaCha20, it is absolutely necessary to discuss nonce management, since this is a major footgun people coming from AES may not be familiar with.
The most popular AES mode here is AES-GCM, where nonce reuse is even more catastrophic than it is with ChaPoly. People coming from AES thus are familiar with nonce-reuse problems, unless they’re (i) incompetent or (ii) only ever used a nonce-misuse resistant construction, and those are still pretty niche.
Agreed that extended nonces are the safest default.
> “Use ECC” is too generic as advice for asymmetric encryption.
Which is why that’s not the actual advice? There’s a discussion about why ECC is better, but when it comes to the actual recommendations, I read:
Asymmetric Encryption
Use: NaCL, libsodium, or monocypher
Asymmetric Signatures
Use, in order of preference:
1. NaCL, libsodium, or monocypher
2. Ed25519
3. RFC6979 (deterministic DSA/ECDSA)
> Also, I think monocypher was written independently of NaCl, it’s not a fork.
As the author of Monocypher I can answer that one: though I did independently implement it, my choice of primitives puts its squarely in the NaCl family, and closest to libsodium. I even use libsodium to generate most of my test vectors. And with the exception of Elligator and streaming encryption we use compatible wire formats. And finally I did shamelessly stole some code from the Ref10 implementation of Curve25519, and the bignum arithmetic is still there.
Under my definition of a fork (clone repo then branch off), it’s not. But under a looser definition… I’m not too mad about it.
(Now I’m wondering how much of a fork of NaCl libsodium actually is…)
> For people familiar with RSA, in which the asymmetric construction is actually used to encrypt messages, this is unfamiliar, so explanation is necessary.
Are there really people using RSA for message encryption? That sounds very wasteful as it's going to spend a huge amount of CPU cycles for no good reason.
I probably should have said “can be”. The way RSA is often explained just details the mathematics, and explains how a message could be encrypted directly using RSA. It’s then not an unreasonable assumption for a complete beginner that this is how RSA works in practice, even though this is not the case.
Let's just put it like this: Most "simple" explanations of RSA are wrong.
The "advantage" of ECC is that there are no "simple" explanations of ECC, because there's no comic version of ECC that is insecure and easy to explain. For RSA, such an insecure comic version exists. However, I never found that a very convincing argument against RSA.
The Discrete Log Problem is relatively simple to explain in the context of a generic group. It's sort of intuitive that elliptic curve groups are a pretty good instance of a generic group.
So I don't think it is simpler to explain the security of RSA than the security of ECC.
Additionally, the best attack on ECDLP (Pollard's rho) is much easier to understand than the best attack on RSA (the number field sieve).
For symmetric encryption, if you’re recommending Salsa20/ChaCha20, it is absolutely necessary to discuss nonce management, since this is a major footgun people coming from AES may not be familiar with. You should always use the extended nonce variants of these algorithms (XSalsa20/XChaCha20) if possible, with a random nonce for every message. If not, you will have to be certain that nonces are never reused with the same key, possibly through some counter construction. The real solution to symmetric encryption for most people is to use something like Sodium‘s `crypto_secretstream`, which smooths out all the rough edges.
“Use ECC” is too generic as advice for asymmetric encryption. Use Elliptic-Curve Diffie-Hellman for key exchange (X25519 ideally), and then use a symmetric AEAD construction (XChaCha20-Poly1305 or AES-GCM) to actually encrypt messages. For people familiar with RSA, in which the asymmetric construction is actually used to encrypt messages, this is unfamiliar, so explanation is necessary.
I would not recommend just “SHA-2” as the first choice for generic hash algorithms anymore, due to length extension attacks. Use BLAKE2b, SHA-3, or one of the well-studied truncated variants of SHA-2.
Also, I think monocypher was written independently of NaCl, it’s not a fork.