age,cmd/age,cmd/age-keygen: add post-quantum hybrid keys

This commit is contained in:
Filippo Valsorda
2025-11-17 12:32:50 +01:00
committed by Filippo Valsorda
parent 6ece9e45ee
commit c6fcb5300c
20 changed files with 720 additions and 91 deletions

View File

@@ -3,7 +3,7 @@ age-keygen(1) -- generate age(1) key pairs
## SYNOPSIS
`age-keygen` [`-o` <OUTPUT>]<br>
`age-keygen` [`-pq`] [`-o` <OUTPUT>]<br>
`age-keygen` `-y` [`-o` <OUTPUT>] [<INPUT>]<br>
## DESCRIPTION
@@ -17,6 +17,11 @@ standard error.
## OPTIONS
* `-pq`:
Generate a post-quantum hybrid ML-KEM-768 + X25519 key pair.
In the future, this might become the default.
* `-o`, `--output`=<OUTPUT>:
Write the identity to <OUTPUT> instead of standard output.
@@ -31,22 +36,29 @@ standard error.
## EXAMPLES
Generate a new identity:
Generate a new post-quantum identity:
$ age-keygen -pq
# created: 2025-11-17T13:39:06+01:00
# public key: age1pq167[... 1950 more characters ...]
AGE-SECRET-KEY-PQ-1K30MYPZAHAXHR22YHH27EGDVLU0QNSUH3DSV7J7NR3X6D9LHXNWSDLTV4T
Generate a new traditional identity:
$ age-keygen
# created: 2021-01-02T15:30:45+01:00
# public key: age1lvyvwawkr0mcnnnncaghunadrqkmuf9e6507x9y920xxpp866cnql7dp2z
AGE-SECRET-KEY-1N9JEPW6DWJ0ZQUDX63F5A03GX8QUW7PXDE39N8UYF82VZ9PC8UFS3M7XA9
Write a new identity to `key.txt`:
Write a new post-quantum identity to `key.txt`:
$ age-keygen -o key.txt
Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
Public key: age1pq1cd[... 1950 more characters ...]
Convert an identity to a recipient:
$ age-keygen -y key.txt
age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
age1pq1cd[... 1950 more characters ...]
## SEE ALSO

View File

@@ -148,21 +148,35 @@ overhead per recipient, plus 16 bytes every 64KiB of plaintext.
to. `IDENTITIES` are private values, like a private key, that allow decrypting
a file encrypted to the corresponding `RECIPIENT`.
### Native X25519 keys
### Native keys
Native `age` key pairs are generated with age-keygen(1), and provide small
encodings and strong encryption based on X25519. They are the recommended
recipient type for most applications.
encodings and strong encryption based on X25519 for classic keys, and X25519 +
ML-KEM-768 for post-quantum hybrid keys. The post-quantum hybrid keys are secure
against future quantum computers and are the recommended recipient type for most
applications.
A `RECIPIENT` encoding begins with `age1` and looks like the following:
A hybrid `RECIPIENT` encoding begins with `age1pq1` and looks like the following:
age1pq167[... 1950 more characters ...]
A hybrid `IDENTITY` encoding begins with `AGE-SECRET-KEY-PQ-1` and looks like
the following:
AGE-SECRET-KEY-PQ-1K30MYPZAHAXHR22YHH27EGDVLU0QNSUH3DSV7J7NR3X6D9LHXNWSDLTV4T
A classic `RECIPIENT` encoding begins with `age1` and looks like the following:
age1gde3ncmahlqd9gg50tanl99r960llztrhfapnmx853s4tjum03uqfssgdh
An `IDENTITY` encoding begins with `AGE-SECRET-KEY-1` and looks like the
A classic `IDENTITY` encoding begins with `AGE-SECRET-KEY-1` and looks like the
following:
AGE-SECRET-KEY-1KTYK6RVLN5TAPE7VF6FQQSKZ9HWWCDSKUGXXNUQDWZ7XXT5YK5LSF3UTKQ
A file can't be encrypted to both post-quantum and classic keys, as that would
defeat the post-quantum security of the encryption.
An encrypted file can't be linked to the native recipient it's encrypted to
without access to the corresponding identity.
@@ -243,27 +257,26 @@ by default. In this case, a flag will be provided to force the operation.
## EXAMPLES
Generate a new identity, encrypt data, and decrypt:
Generate a new post-quantum identity, encrypt data, and decrypt:
$ age-keygen -o key.txt
Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
$ age-keygen -pq -o key.txt
Public key: age1pq167[... 1950 more characters ...]
$ tar cvz ~/data | age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p > data.tar.gz.age
$ tar cvz ~/data | age -r age1pq167[...] > data.tar.gz.age
$ age -d -o data.tar.gz -i key.txt data.tar.gz.age
Encrypt `example.jpg` to multiple recipients and output to `example.jpg.age`:
$ age -o example.jpg.age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p \
-r age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg example.jpg
$ age -o example.jpg.age -r age1pq167[...] -r age1pq1e3[...] example.jpg
Encrypt to a list of recipients:
$ cat > recipients.txt
# Alice
age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
age1pq167[... 1950 more characters ...]
# Bob
age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg
age1pq1e3[... 1950 more characters ...]
$ age -R recipients.txt example.jpg > example.jpg.age