10 ms·
Show HN: Monocypher: a small, easy to use crypto library
- ktta 10y agoIf you don't mind me asking, how much time did it take approximately for you to write the whole library, excluding the online documentation and other stuff not directly related to the code? (2 hours each day for a couple months, 18 man hours total, etc.)
- loup-vaillant 10y agoI think about 9 weeks, full time. (I'm currently on sick leave.) Documentation took me relatively little time. Probably a week if I count my previous blog posts on the subject. I've had some false starts and gaps in my knowledge. I think that slowed me down by a factor of 2. If I lost all data, I think I can re-do it in a week and a half.
- ktta 10y agoThanks for the reply. I think we all will appreciate a follow up blog post on your experiences when you were writing it and also post-'Show HN'
- sporkenfang 10y agoI am curious as to why you've posted this as a tarball on a private website instead of to Github, Bitbucket, etc.
- loup-vaillant 10y agoMy web site, my domain name, my home, my freedom. I avoid centralised services whenever I can. Besides, my git history is not very interesting, so I didn't feel the need to publish it.
- laurent123456 10y agoWouldn't it make sense to share this over https though?
- cclemmons 10y agoI agree, https to serve software (libraries included) is a must, even if the source is open. (That's not to get into the debate on whether or not to use https for everything, but I am a proponent of that as well). Since he's running his own server, it should be easy enough to add a certificate from https://letsencrypt.org/ https://letsencrypt.org/
- loup-vaillant 10y agoIt's on my TODO list…
- FabHK 10y agoI'm torn about this. Brought to you by the person that wrote "Rolling your own crypto" (see earlier discussion linked below), with the motto "Impossible? Like that would stop me." Some fields of knowledge in certain phases benefit from iconoclasm and Sturm & Drang, but is cryptography one of them? On the other hand, many existing implementations are so crufty that a fresh wind might help (if only by pushing more experienced cryptographers to put out better implementations). At any rate, at least the writer followed through, though I'd not be inclined to use this in production anytime soon. http://loup-vaillant.fr/articles/rolling-your-own-crypto http://loup-vaillant.fr/articles/rolling-your-own-crypto https://news.ycombinator.com/item?id=13221923 https://news.ycombinator.com/item?id=13221923
- lvh 10y agoRight there with you. A question that helped answer this for me personally: does this library need to exist given that libsodium already exists? The answer seems "no" to me.
- loup-vaillant 10y agoThe very existence of TweeNaCl indicates that DJB would have answered "yes". And I do have a couple minor advantages over TweetNaCl…
- lvh 10y agoTweetNaCl was created approximately simultaneously (2013) with libsodium.
- loup-vaillant 10y agoHmm, that explains a number of things. Still, I've dug through libsodium, and it's still a bit of a mess —not that I would've done better given the constraints they had.
- VeejayRampay 10y agoThen again, the author worked on the topic, doesn't try to hide the fact that this is a personal project and provides open source, auditable code. As much as I understand that crypto is somehow special and cannot be done "almost right", this is just someone bringing something to the table no matter what. Maybe it will somehow encourage others to try to understand the concepts behind cryptography, which will foster exchange and debate, which is always good.
- VMG 10y agoWhy this instead libsodium?
- loup-vaillant 10y agoLibsodium is big. Smaller than NaCl, but still a little unwieldy. A bigger contender is TweetNaCl, but it doesn't provide password key derivation, and I dislike some of its primitives a tiny little bit. My library have two clear (albeit small) advantages: first, its interfaces are more consistent with its (non-existent) failure mode. NaCl and descendants have most of their function return an error code for no reason –the underlying primitives are foolproof. Second, my Argon2i implementation doesn't allocate. Okay, the user must allocate, but that give more control, and let me guarantee I cannot fail. For some reason, the reference implementation is not like that. Surprising, considering the Argon2 authors make sure implementers could avoid spurious allocations. --- My current recommendation still goes to TweetNaCl and Libsodium. My hope is to be able to recommend Monocypher instead. Maybe sometime later this year?
- VMG 10y agoThanks! Considering that this seems to be a popular question, maybe it makes sense to state this more clearly on the site.
- lvh 10y agoSaved you a click: it's many of the same ideas as libsodium, but mostly with ChaCha and allegedly easier to deploy. I'm not sure I believe the latter, and my recommendation to use libsodium stands. ChaCha20 is also available (but only in AEAD mode with Poly1305) in libsodium, if you really need it. I think XSalsa20 is a reasonable default: if you had a protocol where there's an obvious sequence number to use as a nonce, you probably should already be using TLS anyway; most of the things where libsodium is your best option is precisely in the cases where you don't have the luxury of solving that sort of coordination problem, and you want a random nonce (and hence, extended-nonce versions like XSalsa20 or XChaCha20. I don't know of anyone who has deployed XChaCha20, although the construction is "obvious".) I've previously criticized a blog by the same author called Rolling Your Own Crypto, which had serious flaws. AFAICT, this is ostensibly cryptographically fine (modulo some safeguards that probably only matter if you're Doing It Wrong already anyway), even though the final recommendation is still "avoid". There are many things I disagree with (don't put the documentation for the internal hash for ChaCha20 before the authenticated encryption API!), and using TweetNaCl as a base is less interesting than using libsodium which is both fast and has a lot more eyeballs on it.
- loup-vaillant 10y ago> allegedly easier to deploy. One .c file, one .h file. No fancy compiler option. It doesn't get any easier. I agree with most of the rest, including the "avoid" recommendation, since Monocypher had only one pair of eyeballs so far. > There are many things I disagree with Please, I need more! (The documentation order was out of laziness, I'll change it.) > using TweetNaCl as a base is less interesting than using libsodium which is both fast and has a lot more eyeballs on it. TweetNaCl is smaller. Much smaller. It doesn't need nearly as many eyeballs as libsodium to reach the same level of confidence. And I'm not sure libsodium had as much audits and static analyses as TweetNaCl, if only because its size may render some analyses impractical. I tried to use ref10 as a base. It's too much code.
- lvh 10y agoI'd disagree with "easier to deploy". Most users are going to do this via FFI, and then one .c and one .h pales in comparison to "already has a dylib/so" I can use. It may be true that it doesn't need as many eyeballs; alternative implementations of the same code have the benefit that they're pretty easy to automatedly check. libsodium is not anywhere near the size where static analyses become impractical -- do you have any evidence that would support that?
- tptacek 10y agoTwo things. First: it needs to be made clearer why anyone would use this rather than Nacl/Sodium. Second: this statement does not inspire confidence: "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." If your primitives don't match their test vectors, your tool doesn't work at all, so pretty much every crypto tool, including MiLiTARY-GRADE-CRYPTO v20 GOLD on the Android store or whatever, achieves this level of rigor. Here's a good Reddit comment on the last crypto thing the author wrote, a few weeks ago: https://www.reddit.com/r/programming/comments/5iv1ti/rolling_your_own_crypto/dbbmwwo/ https://www.reddit.com/r/programming/comments/5iv1ti/rolling...
- loup-vaillant 10y ago> First: it needs to be made clearer why anyone would use this rather than Nacl/Sodium. The advantages are marginal. Negligibly better primitives (Chacha over Salsa, Blake2b over SHA-512), ease of deployment (only one .c and one .h file), and cleaner interface (foolproof functions return void). Oh, and it has an Argon2i implementation that doesn't allocate. > Second: this statement does not inspire confidence: Actually, that's kind of intended. When I say "fairly" rigorously tested, I mean users should stay the hell away, at least for now. Right now I need reviews, specific counsel, criticism, possibly even audits. I've went as far as I could on my own. > If your primitives don't match their test vectors, your tool doesn't work at all Well of course, but you wouldn't believe how strong the temptation to punt on those test vectors can be. On the other hand, test vectors are surprisingly complete. Almost all of my primitives went from "utterly broken" to "probably perfect" with a few character changes. Heck, those test vectors even let me find a bug in the reference implementation of Argon2i. --- I'm close to the point where I'd trust this library with my own data. There's a good chance this library is bug free. There's just no way I'd trust it with your data just yet.
- arnarbi 10y ago> you wouldn't believe how strong the temptation to punt on those test vectors can be Tests on test vectors is the first thing I write, before I even start filling in the implementation of a primitive. I don't do this out of principle, but because I've never managed to get an implementation of a primitive right without it. Parent is right, test vectors are almost part of the declaration - and don't really count as actual testing. Side-note: Props for your humility towards criticism, both here and on reddit. > only one .c and one .h file If your library gains popularity, I predict this will be one of the largest contributing factors. In particular for embedded projects, the ability to just plop in a dependency free file is huge ("programmers are like water" and "path of least resistance" etc..)
- CiPHPerCoder 10y agoI don't see anything in the code that would stop someone from using 0 as a public key for a x25519 handshake.
- dchest 10y agoTo add more: Not only 0, but also some other keys listed here https://cr.yp.to/ecdh.html https://cr.yp.to/ecdh.html which produce all-zero shared key. DJB argues you shouldn't validate public keys except for "some unusual non-Diffie-Hellman elliptic-curve protocols that need to ensure ``contributory'' behavior". So NaCl/TweetNaCl also don't do anything about it. Libsodium, on the other hand, returns an indicator when the shared key is all-zero. One recent example where it was considered a ("low") vulnerability is in the recent wire audit: https://www.x41-dsec.de/reports/Kudelski-X41-Wire-Report-phase1-20170208.pdf https://www.x41-dsec.de/reports/Kudelski-X41-Wire-Report-pha... Therefore, if Bob sends all-zero ratchet public keys, subsequent message keys will only depend on the root key and not on Alice’s ephemeral private keys. A dishonest peer may therefore keep sending degenerate keys in order to reduce break-in recovery guarantees, or force all sessions initiated by a third party to use a same message key, while a network attacker may force the first message keys to a public constant value, for example.
- loup-vaillant 10y agoCrap, this is more severe than I anticipated. I'll think about it, and probably change the code and API. That's said, I don't understand why DJB says this is unnecessary for Diffie-Hellman? I mean, an all-zero shared secret sounds pretty bad, doesn't it? Or is it because DJB assumes that if one party decides to publish the communication, it can do so anyway?
- lvh 10y agoNot all AKEs require contributory behavior to guarantee their security properties, but many do. Your suggestion is pretty close to why; if you're using plain scalarmult as opposed to an AKE with fancier properties (say, 3DH, HMQV...) in the context of e.g. box, it's the sender that picks public keys anyway, so they don't care. In the context of most transport encryption, you presumably do want to prevent those keys from being selected by either party. That means either filtering those keys, or, perhaps better, using a fancier AKE like the 3DH in Signal/Noise or HMQV or something.
- niftich 10y agoThis project seems to be the culmination of a rhetorial question that the author posed a while ago: if the advice is 'don't roll your own crypto' [1], then how does any crypto ever come into being? [2] So perhaps the marketing is off: I don't view this as a "small, secure, auditable, easy to use crypto library"; I view this as a practical and ongoing study in investigating how to make small, secure, auditable, easy-to-use crypto libraries. To be fair, the page mentions that it's "not ready for production" and needing external review a quarter of the way down, but if the point is to prove that a sufficiently dedicated individual can learn the material, endure some criticism, and produce quality software following the example of well-acclaimed experts, then own this point, bare your disclaimers in the beginning, and make it more prominent. And once you phrase it that way -- which is arguably consistent with the author's previous posts (and HN comments) on the topic, it's suddenly a lot more palatable, and regardless of its ultimate outcome, I can only applaud. [1] I use an interpretation of "don't roll your own crypto" that's slightly less circular than the author's. In my opinion, it's shorthand for 'defer to the opinion of experts, use ready-made constructs when possible, and if not, then exercise caution when hooking crypto primitives together in unproven ways'. Originally posted here: [3] [2] http://loup-vaillant.fr/articles/rolling-your-own-crypto http://loup-vaillant.fr/articles/rolling-your-own-crypto [3] https://news.ycombinator.com/item?id=12400040 https://news.ycombinator.com/item?id=12400040
- loup-vaillant 10y agoI'm fairly confident I can write a bug free crypto library. Monocypher is probably already bug-free. On the other hand, I don't see how I can ensure my library is bug-free without external help. "Probably bug free" is not good enough. I need over 99.9% certainty, and I'm currently pretty far from that.
- e12e 10y agoProbably not what you had in mind, but if there's a 0.1% that you have a bug in any given line (let's assume that includes bugs in how lines interact as well) - there's about a 63% chance there's at least one bug for every 1000 lines of code, if my math isn't off. That's mostly to say: I agree with your assessment that you (and me and everyone) need help to review code and look for bugs.
- dchest 10y agoI like such tiny projects: you can drop .c and .h into your own project and have something useful ready-to-use. Thanks for sharing! For those asking, this is what distinguishes it from libsodium. Compared to NaCl or TweetNaCl, it has password hashing (Argon2), although, to be fair, I wouldn't recommend using non-optimized implementation of it, like in this library, for serious stuff. Some notes: - Let's call Ed25519 with BLAKE2b something like "Ed25519-BLAKE2b" to avoid confusion. - crypto_chacha20_random is a confusing name, I'd prefer crypto_chacha20_stream - Everyone uses "crypto_" for namespacing their libraries nowadays! Let's use something else to avoid collusions :)
- tptacek 10y agoSo, minus the thing you don't recommend people use, there is no advantage to this over TweetNacl?
- dchest 10y agoEven worse: users of TweetNaCl can easily switch over to the real deal (performance-wise) — NaCl or libsodium — without changing anything, while with this library they'll have to grab pieces of optimized code from various sources, and then dig into insides Ed25519 implementation to replace SHA-512 with BLAKE2b. Unless the author implements an optimized version of Monocypher, of course.
- loup-vaillant 10y ago> Unless the author implements an optimized version of Monocypher, of course. We may be able to compete with ref10 without too much code. I haven't found a way yet (very frustrating). In the mean time, you have the Donna implementation, which can be used with any hash (it's a compilation option).
- loup-vaillant 10y ago- Naming Ed25519 is not obvious: I do provide SHA-512 as an option. - I'll consider crypto_chacha20_stream - I'll stick with "crypto_", for 2 reason. First, you only need one crypto library. Second, a brutal search & replace will let you use another namespace in 30 seconds. Maybe I should provide a script to do that?
- jedahan 10y agoThe manual is absolutely amazing. It shows proper and improper use, and explains how and why to the lay person. http://loup-vaillant.fr/projects/monocypher/manual http://loup-vaillant.fr/projects/monocypher/manual Example from crypto_chacha20_init (grammar aside): "Warning: don't use the same nonce and key twice. You'd expose the XOR of subsequent encrypted messages, and destroying confidentiality."
- jedisct1 10y agoIn the same vein: libhydrogen [1]. Both the API and the underlying primitives are still moving targets, but one of the motivations behind this project was to revisit the NaCl/LibSodium/SUPERCOP API to build something more difficult to misuse. In particular, users never provide nonces. Contexts are mandatory everywhere. A broken PRG is not always catastrophic. Operations requiring keys have a dedicated keygen() function (eventually, keys may have their own type instead of generic byte buffers). There's no crypto_stream_* API, but a randombytes_buf_deterministic() function. libhydrogen is not meant to replace libsodium, but the libsodium2 API may resemble more to it than the current one. [1] https://github.com/jedisct1/libhydrogen https://github.com/jedisct1/libhydrogen