GnuPG は OpenPGP を実装しており、ファイルやメールの署名と暗号化、多くの Linux ディストリビューションでのパッケージ署名、git のコミット署名に使われています。ここに挙げた事実は、Alpine 3.24.2 のパッケージ(GnuPG 2.4.9、libgcrypt 1.12.2)で確認したものです。ユーザー ID だけを指定して gpg --quick-gen-key を実行すると、署名と証明(certification)用の Ed25519 の主鍵と、暗号化用の Curve25519(cv25519)の副鍵が、どちらもバージョン 4 の鍵として作成されます。有効期限を指定しない限り、主鍵は 1095 日(3 年)後に期限切れになります。鍵と署名は OpenPGP インスペクターで解析できます。
ECDSA 鍵は P-256、P-384、P-521、secp256k1 と 3 つの Brainpool r1 曲線で作成できます。nistp224 は「Unknown elliptic curve」で失敗します。署名パケットは r と s を 2 つの OpenPGP MPI として格納しており、DER でも固定長の r‖s でもありません。P-256 の署名はデフォルトで SHA-256 を使います。P-384 の鍵で SHA-256 を指定すると「signing failed: Invalid length」で失敗しますが、P-256 の鍵での SHA-512 は受け付けられます。
nonce は決定的です。時刻を固定する(--faked-system-time)と、同じファイルへの 2 つの署名はバイト単位で一致し、r は独立した RFC 6979 実装の値と一致しました。そのため、同じデータに 2 回署名しても、危険な形で nonce が再利用されることはありません。s は正規化されず、s を n − s に置き換えた署名も有効な署名として検証を通りました。署名が一意であることを前提とする場面では、この点に注意が必要です。
Ed25519 署名は従来の EdDSA 形式(アルゴリズム 22)を使います。R と S は MPI であり、Ed25519 が署名するのはファイルそのものではなく、ファイルと署名のハッシュ対象フィールドから計算した SHA-512 ダイジェストです。R と S をそれぞれ先頭からゼロで埋めて 32 バイトにした R‖S は、OpenSSL でそのダイジェストに対しては検証を通り、ファイルに対しては失敗しました。つまり、汎用の Ed25519 ライブラリで gpg の署名を検証するには、まず OpenPGP のダイジェストを計算する必要があります。Ed448 の鍵は、GnuPG が準拠する LibrePGP ドラフトの形式であるバージョン 5 の鍵パケットとして作成されます。一方、確認したデフォルトの鍵、ECDSA 鍵、Ed25519 鍵はすべてバージョン 4 でした。Ed448 を選ぶ前に、相手側がバージョン 5 を読み込めることを確認してください。このリリースにはポスト量子アルゴリズムがありません。公開鍵アルゴリズムの一覧は RSA、ELG、DSA、ECDH、ECDSA、EDDSA で、ky768_cv25519 は未知の曲線として拒否されます。
スクリプトでは、人間向けのテキストではなく、機械可読な --status-fd の出力を読んでください。有効な署名では GOODSIG と VALIDSIG が出力されて終了ステータスは 0、別のデータに対する署名では BADSIG で終了ステータスは 1、途中で切れたパケットでは NODATA で終了ステータスは 2 でした。フィンガープリントと ! を指定した gpg --export-ssh-key は、ECDSA 鍵と Ed25519 鍵について OpenSSH の公開鍵の行を出力します。一方、--export と --export-secret-keys は OpenPGP パケットを出力します。