Loup-Vaillant wrote this on Lobste.rs in a dumb rant about my Matrix disclosure:
Personally I would actively avoid the check,
Hmm. What a weird thing to say.
Loup-Vaillant wrote a cryptography library called Monocypher, which famously had an EdDSA vulnerability mostly caused by their insistence on rolling their own custom EdDSA variant to avoid SHA512.
"I wonder how Monocypher holds up in 2026?"
Who said that? Well, anyway:
@soatok Feuding crypto-experts hate-reviewing each other's code is exactly the kind of vibe we need. Talk about adversary testing! 😎
@ticho I honestly welcome their feedback, no matter how dickish it will be, because it's a good way to learn your own blindspots before you ship to prod
@soatok because who checks for buffer lengths in c anyways it just wastes cycles
wat
also pretty sure "user error" is exactly how exploits are born
@soatok making input validation (with many preconditions and requiring specific knowledge) a user's responsibility sounds like a recipe for disaster
@soatok ugh I was using Monocypher for some things :( I’ll switch to uhh.. sodium I guess?
@david_chisnall @codecat Yeah @jedisct1 is one of my favorite crypto developers
@soatok
OMG. These two paragraphs are one after the other in their documentation (https://monocypher.org/manual/#CAVEATS ). Do they not see how tightly linked they are??
> CAVEATS
> Monocypher does not perform any input validation. Any deviation from the specified input and output length ranges results in undefined behaviour. Make sure your inputs are correct.
>
> SECURITY CONSIDERATIONS
> Using cryptography securely is difficult. Flaws that never manifest under normal use might be exploited by a clever adversary
@inex @soatok "Look, I only gave the user a foot-gun. Most users know how to not use the foot-gun. I mean yes, it is a gun; and yes, it is pointed automatically at their foot; and yes, it is loaded and has a hair trigger; but users should know better. I mean they are programmers, for heaven's sake, they should know about trigger discipline."
@soatok It's kind of crazy how there's crypto library devs that think non-crypto devs want to use something that will silently ruin the lives of users and end your whole career if you look at it wrong.
I know enough about crypto to know that I don't want to fiddle with crypto directly and I want boring libraries that will instead explicitly tell me to fuck off and try something else if I look at it wrong.
@soatok
> closed as not planned.
Lmao.
> The absence of input validation is core to the design of Monocypher, and Well documented. This allows Monocypher to simplify error handling and maximise portability. What you found was normal and expected.
Oh my dog
@lady_alys @soatok using crypto is difficult, even more so when you voluntarily don't validate inputs. Oh my dog. This lib should be in a kind of oss security blacklist!
@rusty__shackleford @soatok Trying to determine if this is bad snark on their part or the output of an AI agent
@cwebber @rusty__shackleford The "spell out the acronyms used in the filenames" part does gesture suggestively towards "AI"
The heel-turn on me allegedly not contacting them without an "You're absolutely right!" tells me that, even if it is AI, they at least edited the sycophancy out of it.
/Cinny
@rusty__shackleford @soatok personally my raccryptography libraries should just randomly silently explode because i didn’t check something it extremely trivially could check itself
@soatok Wait, so the entire input validation scheme is "don't call it wrong?"
That's... well, that's a choice you can make, I guess.
@wordshaper Our Threat Model is "You must only accept secure inputs if you want secure outputs".
@soatok good thing this code doesn’t have to operate in an adversarial environment. Something unfortunate could happen.
Sloccount counts under 2000 lines of code, small enough to allow audits. The binaries can be under 50KB, small enough for many embedded targets.
“Measuring software development by lines of code is like measuring aircraft design by weight”
Just that in this case, proving that too few is just as bad as too many.
That's not uncommon in C. The Java Native Interface has a design rationale document that says that it doesn't, for example, check null pointers because it's impossible to check for the general case of invalid pointers.
I don't really agree with this philosophy, but it did provide a nice showcase for CHERI (the JNI was explicitly designed to not be a trust boundary, so being able to turn it into a defensible one was great).
I'm not sure that's an improvement. You defined the macro as:
+#define MONOCYPHER_CHECK(cond) do { if (!(cond)) return; } while (0)
But this is returning without reporting any error. And that's necessary because the functions that they're in return void. But now they will simply not do the operation and fail. So now the outputs are full of uninitialised values.
EDIT: Ah, I see you mentioned that limitation in the comment at the end.
And that's why functions returning void are bad code smell in crypto libraries.
@david_chisnall @soatok @lain@lain.com @inex Indeed this seems worse. You need to either abort, longjmp to an error hander, or at least setup the structures in a form to defer the error til it's reportable later.
@dalias @david_chisnall @inex Yeah, the existing codebase is not amenable to good programming practices. I'm going to recommend libhydrogen instead.
@soatok @david_chisnall @inex If valid input parameters are actually part of the interface contract, aborting seems perfectly reasonable and the best-hardened choice. Current behavior is also reasonable (as long as contract is clearly documented) but poor in terms of hardening. I doubt it matters unless there's a viable scenario where these parameters come from external input not the calling program text.
To be fully transparent: I have turned down job offers before because I do not feel comfortable writing C. Almost everyone I've met that believes they can write secure C code is overconfident, and that scares me. So I'm certain that a better patch is possible.
That said:
You're going to get an invalid output if you proceed with invalid parameters. Silently aborting immediately versus allowing stack corruption is a losing position to be in.
@soatok @dalias @david_chisnall @inex not to toot my own horn or anything, it can be done, only because the following are not optional for me:
• Valgrind/Address Sanitizer
• gcov
• Obsessive use of RAII
• Insane number of tests
and this philosophy must be present from the beginning. look at Monocypher...good lord
@soatok Someone mentioned libhydrogen as what you would use if you considered using monocypher, and I'd like to point out: Reading libhydrogen's code, they have very simple input validation that would be easily replicable here, and yet the developer says "No, it would break portability to check" ?????
Libhydrogen is portable, so ?????
@soatok @dalias @david_chisnall @inex my attitude towards the C code I write is "I make no security guarantees, this fucker probably leaks memory somewhere too, and if you want to use my code securely then I urge you to reconsider"
@rusty__shackleford @soatok ROFLSTOMP!
The documentation clearly states that if the user supplies a string longer than MAX_PASSWORD_LEN, the buffers will overwrite system memory with the contents of the password, allowing remote shell access. This is not a bug, and changing it would mean I would have to write code. Plus I already wrote the docs.
@soatok @dalias @david_chisnall @inex Secure C and C++ code is a lie made up by Keith the Rat to make you bring him more cheese.
@soatok I am truly baffled that someone who considers themselves an engineer — a CRYPTOGRAPHIC engineer! — would read “the value MUST be between x and y” and consider it not their implementation’s responsibility to enforce but the user’s
@wolfcoder @soatok hang on what /century/ are we in? not like we are still programming Z80 or 6502 and trying to squeeze out every last bit of performance, surely a few extra clock cycles won't break the bank these days?
@vfrmedia @soatok everything* starts with c, if you're writing a fundamental library, a video game engine, part of an operating system, etc. you do want to be as lightweight as possible.
you do want to fight the attitude of not optimizing because then we get Electron apps and e-waste.
not buffer checking (for whatever reason) however saves you very little vs. how dangerous it is, i'll even range check when i'm writing Z80 or 6502 programs just to save headaches.
@vfrmedia @soatok and even then I would not be surprised if someone found an exploit in my game, its the attitude upon being made aware of said exploit that is very very important.
I'd trust software that had 1000s of reported vulns if the author was responsibly mitigating them vs. one with like 3 but the author was like "meh you're just using it wrong"