7 comments

  • alexjurkiewicz3 days ago
    (2024)<p>My favourite part of these tools is the zany use of numbered file descriptors. `keypair` outputs the public key on fd 5 and secret key on fd 9. But signing reads the secret key on fd 8, while verification reads the public key on fd 4! Why aren&#x27;t they the same?? I have to read the manpage every time.
    • gnull2 days ago
      That&#x27;s such a user-hostile design decision. I can&#x27;t fathom what justifies it (other than kinky taste).<p>Makes your commands unreadable without a manual, leaves a lot of room for errors that are quietly ignored. And forces you into using a shell that comes with its own set of gotchas, bash is not known to be a particularly good tool for security.<p>And to those who stay this adds flexibility: it doesn&#x27;t. Those file descriptors are available under&#x2F;dev&#x2F;fd on linux, with named options you can do --pk &#x2F;dev&#x2F;fd&#x2F;5. Or make a named pipe.
      • minitech2 days ago
        &gt; Those file descriptors are available under&#x2F;dev&#x2F;fd on linux, with named options you can do --pk &#x2F;dev&#x2F;fd&#x2F;5.<p>If you have a procfs mounted at &#x2F;proc and the open syscall to use on it, sure (and even then, it’s wasteful and adds unnecessary failure paths). Even argument parsing is yet more code to audit.<p>I think the design is pretty good as-is.
        • gnull1 day ago
          It&#x27;s 2025, dude. You can&#x27;t be seriously telling me how difficult it is to parse arguments. It may be difficult in C, but then we&#x27;re down another sick rabbit hole of justifying bad interface with bad language choice.<p>One open syscall in addition to dozens already made before your main function is started will have no observable effect whatsoever.
          • minitech1 day ago
            The context is what’s essentially a shell-accessible library for a minimal set of cryptographic primitives. It’s very reasonable to want it to be as lightweight, portable, and easy to audit as possible, and to want it to run in environments where (continuing on Linux for example) the open syscall to &#x2F;dev&#x2F;fd&#x2F;n -&gt; &#x2F;proc&#x2F;self&#x2F;fd&#x2F;n will not succeed for whatever reason, e.g. a restrictive sandbox.<p>Not involving argument parsing simplifies the <i>interface</i> regardless of how easy the implementation is, and the cost is just having to look up a digit in a manual that I certainly hope anyone doing raw ed25519 in shell is reading anyway.
            • gnull18 hours ago
              Make a named pipe then. Shells have built-in primitives for that. I.e. &lt;() and &gt;() subshells in bash, or psub in fish. Or have an option to read either a file descriptor or a file.<p>I can&#x27;t understand why you keep inflating the difficulty of simple commandline parsing, which the tool needs to do anyway — we shouldn&#x27;t even be talking about it. Commandline parsing code is done once (and read once per audit) while a hostile user interface that bad commandline creates takes effort to use each time someone invokes the tool. If the tool has 1000 users, then bad interface&#x27;s overhead has 1000× weight when we measure it against the overhead of implementing commandline parsing. This is preposterous.<p>&gt; Not involving argument parsing simplifies the interface<p>From interface perspective, how is `5&gt;secretkey` simpler than `--sk secretkey`? The latter is descriptive, searchable and allows bash completion. I&#x27;ll type `ed25519-keypair`, hit tab and recall what the argument called.<p>You can&#x27;t justify poorly made interface that is unusable without opening the manual side by side. Moreover, the simplest shell scripts that call this tool are unreadable (and thus unauditable) without the the manual.<p><pre><code> ed25519-keypair 5&gt;secretkey 9&gt;publickey </code></pre> You see this line in a shell script. What does it do? Even before asking some deeper crypto-specific questions, you need to know what&#x27;s written in &quot;secretkey&quot; and &quot;publickey&quot; files. You will end up spending your time (even a minute) and context-switch to check the descriptor numbers instead of doing something actually useful.
              • minitech17 hours ago
                &gt; which the tool needs to do anyway<p>It doesn’t. The tool has no command-line arguments.<p>Please learn how the various shell concepts you’re referencing (like &lt;()) actually work and get back to me if you still need to after that.<p>In any case, I’m well aware of the readability benefit of named arguments, and was when I made the original comment. So as you can imagine, I maintain that it’s a more than reasonable tradeoff, and I’ve covered the reasons for that. If you have nothing (correct) to add beyond hammering on this point, save it.
                • gnull17 hours ago
                  You got me, it doesn&#x27;t have arguments. Luckily, my argument did not critically rely on this bit, and it&#x27;s still valid. Instead of occasional disconnected thoughts and vulgar attempts to insult, try to construct a complete, coherent argument for why you think your view is valid.<p>A suggestion on how you could approach it: try to make a table with 2-3 columns for the solutions you and I are comparing. And add a row for each aspect or characteristic you want to compare them with respect to; for example, usability, ease of implementation, room for error, you name it. In each cell, put either + or - if a solution is clearly managing that aspect well or badly, or a detailed comment. Try to express all of the things you&#x27;re feeling and that are coming to your mind. My comments are written with a table like that in mind, they easily translate to one. Once you have made your table and established that we disagree on what some cell should contain or what rows&#x2F;columns should be present, feel free to get back to have an actual discussion.
                  • minitech17 hours ago
                    You’ve misrepresented or ignored all of my arguments, which are fairly complete as written. You can reformat them into a table for your personal use if it helps; I haven’t seen evidence that continuing into “an actual discussion” with you on this would have any value. (<i>“It&#x27;s 2025, dude. You can&#x27;t be seriously telling me how difficult it is to parse arguments.”</i> was a bad start, and while I’m on it: wrong and right, respectively.)
                    • gnull16 hours ago
                      Haha, you got me again!<p>I honestly tried putting yours into a table and couldn&#x27;t in a way that makes it look defensible. About 2025: I generally find a bit of cheeky tone appropriate for a dramatic effect, apologies if I offended you.
              • minitech15 hours ago
                (nicer reply to this)<p>Yes, I’m aware of the readability benefit of named arguments, and made the original comment with that awareness too.<p>&gt; Make a named pipe then. Shells have built-in primitives for that. I.e. &lt;() and &gt;() subshells in bash,<p>That’s &#x2F;proc&#x2F;self&#x2F;fd again. But okay, you can make a named pipe to trade the procfs mount and corresponding open-for-read permission requirement for a named pipe open-for-write permission requirement without receiving the other benefits I listed of just passing a FD directly.<p>&gt; I can&#x27;t understand why you keep inflating the difficulty of simple commandline parsing<p>Not only have I not “kept inflating” this, I barely brought up the related concept of it being <i>unnecessary</i> complexity from an implementation side (which it is).<p>&gt; which the tool needs to do anyway<p>It doesn’t. The tool has no command-line arguments.<p>&gt; From interface perspective, how is `5&gt;secretkey` simpler than `--sk secretkey`? The latter is descriptive, searchable and allows bash completion. I&#x27;ll type `ed25519-keypair`, hit tab and recall what the argument called.<p>Not introducing More Than One Way To Do It after all (“Or have an option to read either a file descriptor or a file”) here is a good start, but it’s hard to beat passing a file descriptor for <i>simplicity</i>. If the program operates on a stream, the simplest interface passes the program a stream. (This program actually operates on something even simpler than a stream – a byte string – but Unix-likes, and shells especially, are terrible at passing those. And an FD isn’t just a stream, but the point is it’s closer.) A file path is another degree or more removed from that, and it’s up to the program if&#x2F;how it’ll open that file path, or even how it’ll derive a file path from the string (does `-` mean stdin to this tool? does it write multiple files with different suffixes? what permissions does it set if the file is a new file – will it overwrite an existing file? is this parameter an input or an output?).<p>Your attached arguments seem to be about convenience during interactive use, rather than the kind of simplicity I was referring to. (Bonus minor point: tab completion is not necessarily any different.)<p>&gt; Moreover, the simplest shell scripts that call this tool are unreadable (and thus unauditable) without the the manual.<p>That might be a stretch. But more importantly, who’s trying to audit use of these tools without the manual? You can be more sure of the program’s interpretation of `--sk secretkey` (well, maybe rather `--secret-key=.&#x2F;secretkey`) than `9&gt;` if you know it runs successfully, but for anything beyond that, you do need to know how the program is intended to work.<p>Finally, something I probably should have mentioned earlier: it’s very easy to wrap the existing implementation in a shell function to give it a named-parameter filepath-based interface if you want, but the reverse is impossible.
                • gnull11 hours ago
                  I see, you are more focused on providing the core functionality in the simplest way possible from purely technical perspective, and less so on what kind of &quot;language&quot; or interface it provides the end user — assuming someone who wants an interface can make a wrapper. I can see that your points make sense from this perspective, the solution with FDs is indeed simpler from this viewpoint.<p>I, on the other hand, criticized it as a complete interface made with some workflow in mind that would need no wrappers, would help the user discover itself and avoid footguns. Your interpretation sounds like what the authors may have had in mind when they made it.<p>&gt; who’s trying to audit use of these tools without the manual?<p>I&#x27;d try to work on different levels when understanding some system. Before getting into details, I&#x27;d try to understand the high-level components&#x2F;steps and their dataflows, and then gradually keep refining the level of detail. If a tool has 2-3 descriptively named arguments and you have a high-level idea of what the tool is for, you can usually track the dataflows of its call quite well without manual. Say, understanding a command like<p><pre><code> make -B -C .&#x2F;somewhere -k </code></pre> may require the manual if you haven&#x27;t worked with make in some time and don&#x27;t remember the options. But<p><pre><code> make --always-make --directory=.&#x2F;somewhere --keep-going </code></pre> gives you a pretty good idea. On the second read, where you&#x27;re being pedantic with details, you may want to open the manual and check what those things exactly mean and guarantee, but it&#x27;s not useless without the manual either.
      • PunchyHamster2 days ago
        it being <i>option</i> can be nice if you don&#x27;t want your keys touching disk and need to pass it over to other apps.<p>it being default is insanity
    • Retr0id3 days ago
      I&#x27;m curious, what do you actually use it for?<p>I&#x27;d have otherwise guessed that this tool mainly exists just to test lib25519. Personally I&#x27;d only ever want a library, or some higher-level tool. A CLI tool that <i>just</i> does raw signing feels like a weird (and footgun-shaped) middle ground.
      • tptacek3 days ago
        This mostly exists to test lib25519 and ostensibly to build systems with shell scripts (though: few people would do that). It is a weird and footgun-shaped middle ground.
      • XorNot3 days ago
        It&#x27;s why no one has succeeded in replacing GPG: you <i>need</i> a lot of systems to work in order to have an actual viable one, the ability to spit out signatures from keys is required but not sufficient.
        • adastra223 days ago
          GPG is pervasive for the same reason git is pervasive: network effects. There are plenty of better alternatives.
          • XorNot2 days ago
            Such as? I need an alternative which supports commutative trust relationships of some sort which are revocable.
            • adastra221 day ago
              You (knowingly?) picked the one counter example, lol. Web of trust is the one application of PGP&#x2F;GPG for which there isn’t a product ready replacement tool to point towards. GPG is built around web of trust, but this is generally believed to have been a very, very bad idea and the source of innumerable security problems for nearly every application that has tried to make use of it. The GPG replacements I would point to are purpose-built for specific domains and eschew web of trust:<p><a href="https:&#x2F;&#x2F;soatok.blog&#x2F;2024&#x2F;11&#x2F;15&#x2F;what-to-use-instead-of-pgp&#x2F;" rel="nofollow">https:&#x2F;&#x2F;soatok.blog&#x2F;2024&#x2F;11&#x2F;15&#x2F;what-to-use-instead-of-pgp&#x2F;</a><p>That said, you might find what you are looking for in the Rebooting Web of Trust project, and the various decentralized identity (DID) implementations that have come out of it:<p><a href="https:&#x2F;&#x2F;www.weboftrust.info&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.weboftrust.info&#x2F;</a>
              • XorNot1 day ago
                No I picked the case I&#x27;m dealing with most commonly: which is establishing trust. X509 certs will also do this.<p>I have numerous criticisms of the GPG system but it&#x27;s not a solution to just not implement any solution at all: I.e. I need revocation lists, I need intermediate keys, I need the ability to establish alternate chains of trust or promote a chain to trusted. Some of this is very hard to do with x509 even or not will supported.
                • adastra221 day ago
                  Trust meaning who you should do business with? Whose advice you should take?<p>Rather than “trust” you mean something very specific: whether a key was issued by an entity, or attested to from a set of authorities. The “web of trust” model that PGP&#x2F;GPG supports is not the ideal means of implementing this.
            • C4K32 days ago
              Keybase or any of the tools inspired by keybase (foks.pub etc)
              • adastra221 day ago
                Isn’t keybase to GPG what github is to git?
      • Fnoord3 days ago
        &gt; I&#x27;m curious, what do you actually use it for?<p>FTA:<p>&gt; These tools allow lib25519 to be easily used from shell scripts.<p>I&#x27;ve never used ed25519-cli, but not having to use a library is nice for someone who isn&#x27;t a programmer.
        • tptacek3 days ago
          The Venn diagram of &quot;not a programmer&quot; and &quot;can safely use Ed25519&quot; is two non-overlapping circles.
          • PunchyHamster2 days ago
            &quot;this app needs me to generate a key and point to it in config&quot; is plenty of overlap
            • Retr0id2 days ago
              If you just want a raw ed25519 private key then `head -c32 &#x2F;dev&#x2F;urandom` does the job. But usually you want a DER&#x2F;PEM wrapper or similar, which the openssl cli tools handle nicely.
          • kfreds2 days ago
            I don&#x27;t consider myself a programmer and I can use Ed25519 safely. I do however understand computing fairly well.
            • Retr0id2 days ago
              I consider myself a programmer and ed25519-understander, but the idea of using it directly within a shell script terrifies me.
          • alexjurkiewicz3 days ago
            Simply combine this tool with `openssl enc` and your shell script is as secure as any shell script could be
        • loeg3 days ago
          Someone writing shell scripts is a programmer, for better or worse.
    • jedahan3 days ago
      I was wondering the same thing. My best guess is that is to guard against operator misuse. Like usb-a only plugging in one way. Anything that is secret will never accidentally print to stdout. String interpolation in bash with `—option $empty` might be safer than `8&lt;$empty`. Have to explore more but yeah, this is a new pattern for me as well.
      • yellowapple2 days ago
        Another possible factor driving the decision to use numbered file descriptors: the logic to validate that a file exists (or can exist) at a given path, is readable&#x2F;writable, etc. gets punted to the shell instead of being something the program itself has to worry about.
      • gnull2 days ago
        Those descriptors like 5 could be mapped to anything, including descriptor 1, stdout.
    • chuckadams3 days ago
      What a strange convention. I&#x27;m partial to minisign, which works on plain old files.
      • tptacek3 days ago
        This little CLI is not meaningfully an alternative for signify&#x2F;minify. Here&#x27;s a good piece on signify from its author (who also comments here):<p><a href="https:&#x2F;&#x2F;www.openbsd.org&#x2F;papers&#x2F;bsdcan-signify.html" rel="nofollow">https:&#x2F;&#x2F;www.openbsd.org&#x2F;papers&#x2F;bsdcan-signify.html</a>
    • alfiedotwtf2 days ago
      I’m guessing it’s to support the test framework it’s built with?
    • pamcake3 days ago
      [dead]
    • pseudohadamard2 days ago
      It&#x27;s djb&#x27;s web site so it&#x27;s a djb design. With great genius comes great different thinking.
  • PunchyHamster2 days ago
    &gt; It writes the public key to file descriptor 5, and then writes the secret key to file descriptor 9.<p>Is the project trying to compete with GPG for worst interface ? Magic numbers BAD, especially in something that will mostly be used in scripts
  • why-o-why3 days ago
    Why not zoidbe... I mean, why not open ssh? It&#x27;s literally a CLI that does every crypto operation with every primitive (except some PQC)?
    • tptacek3 days ago
      If you mean the OpenSSL CLI, it&#x27;s hard to think of a more footgun-y cryptographic tool than the one that:<p>* defaults to unauthenticated encryption<p>* buries its one authenticated mode<p>* requires explicit command-line nonces<p>* defaults to an MD5 KDF<p>You could probably keep going for another 10 bullets. Never use the OpenSSL CLI for anything other than TLS stuff.
      • coppsilgold3 days ago
        You can use ssh-keygen for signing and verifying signatures.<p>You can also use age[1] to encrypt payloads targeting ssh public keys. And decrypt using ssh private keys.<p>[1] &lt;<a href="https:&#x2F;&#x2F;github.com&#x2F;FiloSottile&#x2F;age" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;FiloSottile&#x2F;age</a>&gt;
      • quotemstr3 days ago
        Yeah, the OpenSSL CLI sucks. So what&#x27;s to be done?<p>Sure, we can build a 25519-specific tool with a less footgun-y interface. Fine, whatever, for that one use case.<p>Or we can build an alternative OpenSSL CLI that explodes OpenSSL and its numerous useful features in a general way and helps fix lots of use cases.
        • tptacek3 days ago
          Nothing is to be done. Just don&#x27;t use the OpenSSL CLI. It&#x27;s a deeply cursed concept for a tool!
          • quotemstr3 days ago
            A command like cryptography swiss army knife useful though. If not openssl, then what?
            • tptacek3 days ago
              It&#x27;s useful as a toy and a learning tool, but for nothing else. For those two things, OpenSSL is fine as it is.
          • pamcake3 days ago
            [dead]
      • why-o-why2 days ago
        Are you confusing the open openSSL library with the CLI? Absolutely none of this is true when used as a signing tool on the CLI. Seems like you just needed to rant, rather than answer my question. Which is fine: I do it to, but I was legit asking a question that you ignored and you seem to know about openSSL?
  • WiSaGaN3 days ago
    I can&#x27;t find the source. Anyone can point to it?
    • minitech2 days ago
      The Download link in the header (<a href="https:&#x2F;&#x2F;lib25519.cr.yp.to&#x2F;download.html" rel="nofollow">https:&#x2F;&#x2F;lib25519.cr.yp.to&#x2F;download.html</a>).
  • mrbluecoat3 days ago
    Sounds like the perfect place to embed credential stealing malware. Good thing they publish their code on an independent third-party public code sharing platform. Oh wait...
    • perching_aix2 days ago
      Short of suspecting a malicious tarball, I really can&#x27;t think of a reason why &quot;publish[ing] their code on an independent third-party public code sharing platform&quot; would be a selling point. You&#x27;re getting the source code straight from the horse&#x27;s mouth this way.
  • esseph3 days ago
    &gt; feels like a weird (and footgun-shaped) middle ground.<p>hmm<p>&gt; It is a weird and footgun-shaped middle ground.<p>Oh? HMMMMM :|