The following is based on Creating newer ECC keys for GnuPG and OpenPGP Best Practices. The idea here is to create a locked-down set of single-purpose keys that are rotated once per year (the 13 month expiration provides a little bit of wiggle-room).

Create the initial key

gpg --expert --full-generate-key
  • Choose “ECC (set your own capabilities)”
  • Toggle the “Sign” capability off (S).
  • Finish choosing capabilities (Q).
  • Choose “Curve 25519”.
  • Expire in 13 months (13m).
  • Enter your name.
  • Enter the primary email address for the key.
  • Do not enter a comment.

Edit the key

gpg --expert --edit-key $KEYID

Add UIDs

  • Use adduid.
  • Enter your name.
  • Enter the primary email address for the key.
  • Do not enter a comment.

Add a signing subkey

  • Use addkey.
  • Choose “ECC (sign only)”
  • Choose “Curve 25519”.
  • Expire in 13 months (13m).

Add an authentication subkey

  • Use addkey.
  • Choose “ECC (set your own capabilities)”
  • Toggle the “Sign” capability off (S).
  • Toggle the “Authenticate” capability on (A).
  • Finish choosing capabilities (Q).
  • Choose “Curve 25519”.
  • Expire in 13 months (13m).

Add an encryption subkey

  • Use addkey.
  • Choose “ECC (encrypt only)”
  • Choose “Curve 25519”.
  • Expire in 13 months (13m).

Finish up

Be sure to save the key before exiting.

Remove the primary key for safe keeping

# Export keys
#
gpg --armor --export-secret-key $KEYID > $KEYID.asc
gpg --export-secret-subkeys $KEYID > subkeys.gpg
 
# Delete secret keys (BOTH primary and subkeys)
#
gpg --delete-secret-keys $KEYID
 
# Re-import secret subkeys
#
gpg --import subkeys.gpg
 
# Optionally verify that eveything worked...
#
gpg --list-keys
gpg --list-secret-keys
 
# Cleanup
#
rm subkeys.gpg

Once this is done, $KEYID.asc can be stored “offline” on a secure (encrypted!) drive, etc. Note that this key will need to be re-imported to generate new subkeys, add UIDs, extend expiration dates, or create updated revocation certificates.

Export the authentication subkey to SSH