@ Loup's

Impossible? Like that would stop me.

Monocypher

Monocypher is an easy to use crypto library inspired by libsodium and TweetNaCl. Here are its main selling points:

Documentation

The Mighty Manual.

Source code

Here, shipped with the test suite. Run thus:

$ tar -xzf monocypher-0.5.tar.gz
$ cd monocypher
$ make
$ ./test

Note the presence of SHA-512 in a separate compilation unit. It is meant to test ed25519 with official test vectors. In production, most users will be expected to use Blake2b —the default setting. (This won't prevent you from upgrading to faster implementations later: Floodyberry's very fast Donna implementation can work with a custom hash).

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 the provided sha512.h and sha512.c.

Current state

Version 0.6. Almost ready for production (needs some more external review). The interface is stable; changes until 1.0 are unlikely.

Test coverage is 100%, all under Valgrind. Each primitive has its set of test vectors. The current version have no known bug.

External review uncovered 4 bugs so far.

changes since 0.5

changes since 0.4

Fun fact: TweetNaCl and ref10 have the same bug. Libsodium have corrected the issue, though.

For those who don't comprehend the magnitude of this madness (I didn't until 2 hours ago), yes, the expression -1 << 3 is undefined in C. This is explained in section 6.5.7(§4) of the C11 standard.

changes since 0.3

changes since 0.2

No incompatible change.

changes since 0.1

Future work

I want static analysis, more runtime analysis, perhaps even a comprehensive security audit. I'm not a one man security company however, so I need help.

Signatures would run 1.5 times faster by leveraging Montgomery scalar multiplication (point addition and doubling in Edwards space require more multiplications). This would cost a couple dozen lines of code.

So far I managed to convert the points back and forth, but my attempts to recover the Y coordinate after the Montgomery ladder failed. (I'm using this paper). A patch would be welcome.

Current state in detail

The entire test suite is Valgrind Clean.

crypto_memcmp()

3 lines of code, used everywhere in the tests instead of memcmp().

crypto_chacha20_H()

Tested with vectors.

crypto_chacha20_init()

Tested with vectors.

crypto_chacha20_Xinit()

Tested with vectors.

crypto_chacha20_encrypt()

Tested with vectors.

crypto_chacha20_random()

Tested with vectors.

crypto_poly1305_init()

Tested with vectors.

crypto_poly1305_update()

Tested with vectors.

I have ascertained the absence of overflows manually, and the IETF test vectors specifically test for the kind of overflow we can fear. External review would be nice, but my fears are now mostly gone. It works.

crypto_poly1305_finish()

Tested with vectors.

crypto_poly1305_auth()

Tested with vectors.

crypto_blake2b_general_init()

Tested with vectors

crypto_blake2b_init()

Tested with vectors

crypto_blake2b_update()

Tested with vectors

crypto_blake2b_final()

Tested with vectors

crypto_blake2b_general()

Tested with vectors

Tested against another implementation by Mike Pechkin here.

crypto_blake2b()

Tested with vectors

Tested against another implementation by Mike Pechkin here.

crypto_argon2i()

Tested with vectors.

Those vectors were generated using the reference implementation. They are not published anywhere else.

crypto_x25519()

Tested with vectors, and the "million scalar products" Monte Carlo test. (Note: I only do 1000 products by default. The million products takes a couple minutes on my machine.)

The code is taken directly from ref10. I'm confident rarely occurring limb overflow bugs have been caught there.

crypto_x25519_public_key()

Tested with vectors.

crypto_ed25519_public_key()

Tested with vectors.

The code is a mix between TweetNaCl and ref10. I'm confident rarely occurring limb overflow bugs have been caught there.

crypto_ed25519_sign()

Tested with vectors.

The code is a mix between TweetNaCl and ref10. I'm confident rarely occurring limb overflow bugs have been caught there.

I'd like to add a Monte Carlo-like test.

crypto_ed25519_check()

Tested for consistency (accepts legitimate signatures, rejects forgeries). The code is a mix between TweetNaCl and ref10. I'm confident rarely occurring limb overflow bugs have been caught there.

crypto_key_exchange()

Tested with vectors.

crypto_aead_lock()

10 lines of straightforward code, tested for consistency in encryption-decryption roundtrips.

crypto_aead_unlock()

12 lines of straightforward code, tested for consistency in encryption-decryption roundtrips.

crypto_lock()

1 line of code, tested for consistency in encryption-decryption roundtrips.

crypto_unlock()

1 lines of code, tested for consistency in encryption-decryption roundtrips.