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't they the same?? I have to read the manpage every time.
I'd have otherwise guessed that this tool mainly exists just to test lib25519. Personally I'd only ever want a library, or some higher-level tool. A CLI tool that just does raw signing feels like a weird (and footgun-shaped) middle ground.
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.
It's why no one has succeeded in replacing GPG: you need 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.
You (knowingly?) picked the one counter example, lol. Web of trust is the one application of PGP/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:
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:
If you just want a raw ed25519 private key then `head -c32 /dev/urandom` does the job. But usually you want a DER/PEM wrapper or similar, which the openssl cli tools handle nicely.
That's such a user-hostile design decision. I can't fathom what justifies it (other than kinky taste).
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.
And to those who stay this adds flexibility: it doesn't. Those file descriptors are available under/dev/fd on linux, with named options you can do --pk /dev/fd/5. Or make a named pipe.
> Those file descriptors are available under/dev/fd on linux, with named options you can do --pk /dev/fd/5.
If you have a procfs mounted at /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.
It's 2025, dude. You can't be seriously telling me how difficult it is to parse arguments. It may be difficult in C, but then we're down another sick rabbit hole of justifying bad interface with bad language choice.
One open syscall in addition to dozens already made before your main function is started will have no observable effect whatsoever.
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 /dev/fd/n -> /proc/self/fd/n will not succeed for whatever reason, e.g. a restrictive sandbox.
Not involving argument parsing simplifies the interface 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.
Make a named pipe then. Shells have built-in primitives for that. I.e. <() and >() subshells in bash, or psub in fish. Or have an option to read either a file descriptor or a file.
I can't understand why you keep inflating the difficulty of simple commandline parsing, which the tool needs to do anyway — we shouldn'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's overhead has 1000× weight when we measure it against the overhead of implementing commandline parsing. This is preposterous.
> Not involving argument parsing simplifies the interface
From interface perspective, how is `5>secretkey` simpler than `--sk secretkey`? The latter is descriptive, searchable and allows bash completion. I'll type `ed25519-keypair`, hit tab and recall what the argument called.
You can'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.
ed25519-keypair 5>secretkey 9>publickey
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's written in "secretkey" and "publickey" 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.
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<$empty`. Have to explore more but yeah, this is a new pattern for me as well.
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/writable, etc. gets punted to the shell instead of being something the program itself has to worry about.
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?
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...
Short of suspecting a malicious tarball, I really can't think of a reason why "publish[ing] their code on an independent third-party public code sharing platform" would be a selling point. You're getting the source code straight from the horse's mouth this way.
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't they the same?? I have to read the manpage every time.