Monocypher is a small, secure, auditable, easy to use crypto library. It is heavily inspired by libsodium and TweetNaCl . It uses state of the art cryptographic primitives (Chacha20, Poly1305, Blake2b, Argon2i, x25519, and ed25519), and provides easy constructions on top of them.
Monocypher is small and auditable. Its implementation code fits in less than 1100 lines of code (counted by sloccount ), optimised for simplicity and readability.
Monocypher is immune to timing attacks. This is achieved by avoiding secret dependent branches and secret dependent array indices.
Monocypher is easy to use. The user have very few choices, and the primitives cannot fail on correct input. The same is true of libsodium and TweetNaCl, but their interface doesn't make this clear (many functions have useless return codes).
Monocypher is easy to deploy. It comprises 2 portable C11 files, monocypher.c and monocypher.h .
DocumentationThe Mighty Manual .
Source codeHere, shipped with the test suite.
Note the presence of SHA-512 in a separate compilation unit. It is meant to test ed25519 with the test vectors I got from the RFC. In production, most users will be expected to use Blake2b ―the default setting.
Such signatures are incompatible with with the real ed25519 of course, but Blake2b is more flexible than SHA-512, harder to misuse (no length extension attack), and already needed for Argon2i.
If you want the official ed25519, you can use SHA-512 instead of Blake2b, by compiling with option -DED25519_SHA512 , as I did for the tests. You can provide the implementation yourself, or use mine ―it's ready for production, test vectors and all.
Current stateBeta quality. Not ready for production yet. Interfaces may change a little before the first stable version.
The current code is fairly rigorously tested. Every primitive match their respective test vectors, and most constructions are tested for consistency. The entire test suite is Valgrind clean.
What this library needs most right now is external review. There might be a few holes here and there, but I can't know for sure because I only have 2 eyeballs.
I have deemed a number of functions "ready for production". Since no external reviews has been performed yet, do not take my word for it. Nevertheless, I would be extremely surprised if any of you found a bug in one of those.
Future workMost of the code is fairly fast, except curve25519, which is based on the slow TweetNaCl. I'd like it to be 3 times as fast, without paying more than 100 additional lines of code. Some stuff worth looking into:
Ref10 is much faster than TweetNaCl, and portable. Alas, the mixed radix 25-26 takes too much code. Radix 51 would be fast and concise, but requires 128-bit multiplication. Radix 26 overflows the multiplication algorithm. Radix 25 makes division by 2-19 non trivial. Current state in detail crypto_memcmp()Ready for production.
3 lines of code, used everywhere in the tests instead of memcmp() .
crypto_chacha20_H()Needs external review.
12 lines of code. Build on the same principles as HSalsa20, with Chacha20 instead of Salsa20. I am not aware of any test vectors for HChacha20 or XChacha20.
crypto_chacha20_init()Ready for production. Tested with vectors.
crypto_chacha20_Xinit()Needs external review.
3 lines of code, rely on crypto_chacha20() . I don't know of any test vector.
crypto_chacha20_encrypt()Ready for production. Tested with vectors.
crypto_chacha20_random()Ready for production. Tested with vectors.
crypto_poly1305_init()Ready for production. Tested with vectors.
crypto_poly1305_update()Needs external review.
Tested with vectors, but poly_block() might have an overflow in some rare cases.
crypto_poly1305_finish()Needs external review.
Tested with vectors, but poly_block() might not guarantee h is below 2 ―subtracting 2-5 might not be enough in some rare cases.
crypto_poly1305_auth()Depends on crypto_poly1305_update() and crypto_poly1305_finish(). Ready for production when those are.
4 lines of code, tested for consistency in encryption-decryption round trips.
crypto_blake2b_general_init()Ready for production. Tested with vectors
crypto_blake2b_init()Ready for production. Tested with vectors
crypto_blake2b_update()Ready for production. Tested with vectors
crypto_blake2b_final()Ready for production. Tested with vectors
crypto_blake2b_general()Ready for production. Tested with vectors
crypto_blake2b()Needs external review.
1 line of code, untested.
crypto_argon2i()Ready for production. Tested with vectors.
Those vectors were generated using the reference implementation. They are not published anywhere else.
crypto_x25519()Ready for production. Tested with vectors.
The code is taken directly from TweetNaCl. I'm confident rarely occurring limb overflow bugs have been caught there.
crypto_x25519_public_key()Ready for production.
1 line of code, involved in consistency checks.
crypto_ed25519_public_key()Ready for production. Tested with vectors.
The code is taken directly from TweetNaCl. I'm confident rarely occurring limb overflow bugs have been caught there.
crypto_ed25519_sign()Ready for production. Tested with vectors.
The code is taken directly from TweetNaCl. I'm confident rarely occurring limb overflow bugs have been caught there.
crypto_ed25519_check()Ready for production.
Tested for consistency (accept legitimate signatures, reject forgeries). The code is taken directly from TweetNaCl. I'm confident rarely occurring limb overflow bugs have been caught there.
crypto_ae_lock_detached()Needs external review. Tested for consistency in encryption-decryption roundtrips.
crypto_ae_unlock_detached()Needs external review. Tested for consistency in encryption-decryption roundtrips.
crypto_ae_lock()Depends on crypto_ae_lock_detached() . Ready for production when it is.
1 line of code, tested for for consistency in encryption-decryption roundtrips.
crypto_ae_unlock()Depends on crypto_ae_unlock_detached() . Ready for production when it is.
1 line of code, tested for for consistency in encryption-decryption roundtrips.
crypto_lock_key()Depends on crypto_chacha20_H() . Ready for production when it is.
Tested for consistency in an encryption-decryption roundtrip.
crypto_lock_detached() Depends on crypto_ae_lock_detached() . Re