From 7f7c9c67a024f5c888f809b28313621caaf7d480 Mon Sep 17 00:00:00 2001 From: clawbot Date: Mon, 7 Sep 2026 14:16:29 +0000 Subject: [PATCH] keyfunc: age keys, age encrypt and decrypt, and derived mnemonics are in scope Per sneak. The age commands derive the identity at the generic path and encrypt or decrypt with it, always including the identity's own recipient. The mnemonic command derives child mnemonics through BIP-85's own mnemonic application. Model: fable-5-1 --- keyfunc/README.md | 56 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/keyfunc/README.md b/keyfunc/README.md index 74147ef..a5b03d6 100644 --- a/keyfunc/README.md +++ b/keyfunc/README.md @@ -7,8 +7,10 @@ same key. It uses the BIP-85 entropy deriver from `git.eeqj.de/sneak/secret/pkg/bip85` and takes the same steps as that repository's `agehd` package. -Commands are grouped by key type: `keyfunc ssh ...` for ed25519 SSH keys (in -this PR) and `keyfunc age ...` for age identities (planned, see below). +Commands are grouped by what is derived: `keyfunc ssh ...` for ed25519 SSH +keys, `keyfunc age ...` for age identities and for encrypting and decrypting +with them, and `keyfunc mnemonic ...` for child mnemonics derived from the +main one. ## Derivation @@ -106,15 +108,45 @@ with `-o IdentityAgent=` followed by the host and all remaining arguments unchanged. The tool exits with `ssh`'s exit status and removes the socket and directory on the way out. The private key is never written to disk. -## age identities: `keyfunc age` (planned) +## age identities: `keyfunc age` -Not in this PR, which delivers the SSH type first; it is the next type to add. -`keyfunc age pub` and `keyfunc age priv` will use application number -`657169`, path `m/83696968'/657169'/'`; the 32 bytes from step 4 are clamped -as X25519 requires and encoded as an `AGE-SECRET-KEY-1...` identity, the same -steps `sneak/secret` takes in its `agehd` package. `secret` derives at a -vendor-specific path today; for its keys to equal this tool's it moves to this -path, which is a change in `secret`, not here. +The application number is `657169`, path `m/83696968'/657169'/'`. The 32 +bytes from step 4 are clamped as X25519 requires and become an age identity, +the same steps `sneak/secret` takes in its `agehd` package. `secret` derives at +a vendor-specific path today; for its keys to equal this tool's it moves to +this path, which is a change in `secret`, not here. + +### `keyfunc age pub` + +Prints the recipient, the `age1...` public key, on one line. + +### `keyfunc age priv` + +Prints the identity, the `AGE-SECRET-KEY-1...` line, and nothing else. + +### `keyfunc age encrypt [-n N] [--to ...] [-o ] []` + +Encrypts the file (or standard input) with age. The recipients are the derived +identity's own recipient, plus any given with `--to`, so the same mnemonic can +always decrypt what it encrypted. Output goes to `-o` or standard output; +`--armor` writes the text form. Nothing is written except the output. + +### `keyfunc age decrypt [-n N] [-o ] []` + +Decrypts the file (or standard input) with the derived identity. Output goes to +`-o` or standard output. If the identity is not one of the recipients, the tool +says so and exits with status 1. + +## Derived mnemonics: `keyfunc mnemonic` + +### `keyfunc mnemonic [-n N] [--words 12|18|24]` + +Prints a child mnemonic derived from the main one, using BIP-85's own mnemonic +application (number `39`, English, path +`m/83696968'/39'/0'/'/'`, entropy taken as the specification says, +not through step 4). Default 12 words. A child mnemonic is a full mnemonic in +its own right: it can seed another `keyfunc`, another wallet, or `secret`, and +it never has to be written down, since it can be derived again. ## Adding a key type @@ -141,4 +173,8 @@ keyfunc ssh pub -n 3 --mnemonic-command 'secret get foo' keyfunc ssh priv -n 3 > ~/.ssh/id_bip85_3 keyfunc ssh install -n 3 user@example.com keyfunc ssh to -n 3 user@example.com uptime +keyfunc age pub -n 0 +keyfunc age encrypt -n 0 --armor -o notes.age notes.txt +keyfunc age decrypt -n 0 notes.age +keyfunc mnemonic -n 1 --words 24 ```