EdDSA Verification Bug - Clarification on Format 2 Verification Failure
Werner Koch
wk at gnupg.org
Thu Jan 15 14:44:58 CET 2026
Hi!
Just a short note on your bug report. You gave a lot of examples and a
nicely formated report at https://github.com/zfogg/ascii-chat/issues/92
but I can't read everything of it.
On Tue, 30 Dec 2025 02:30, Zachary Fogg said:
> **In-Reply-To:** <response from NIIBE Yutaka on Oct 22, 2025>
> Your response mentioned using `(flags eddsa)` during key generation, which
> is good practice. However, I want to clarify that **my bug report concerns
> signature verification, not key generation**.
If you look at the way GnuPG uses Libgcrypt will find in
gnupg/g10/pkglue.c:pk_verify this:
if (openpgp_oid_is_ed25519 (pkey[0]))
fmt = "(public-key(ecc(curve %s)(flags eddsa)(q%m)))";
else
fmt = "(public-key(ecc(curve %s)(q%m)))";
and this for the data:
if (openpgp_oid_is_ed25519 (pkey[0]))
fmt = "(data(flags eddsa)(hash-algo sha512)(value %m))";
else
fmt = "(data(value %m))";
and more complicated stuff for re-formatting the signature data. It is
a bit unfortunate that we need to have these special cases but that's
the drawback of a having a stable API and protocol.
> 1. Can you confirm this is a genuine bug in libgcrypt's verification logic?
No, at least not as I understand it. ed25519 signatures are working
well and are in active use since GnuPG 2.1 from 2014.
> 2. Should I open a formal bug in the dev.gnupg.org tracker?
I don't see a bug ;-)
> 3. Would a patch fixing the PUBKEY_FLAG_PREHASH handling be acceptable?
I do not understand exactly what you propose. A more concise
description would be helpful. But note that API stability is a primary
goal.
BTW on your website your wrote:
I've created a working exploit that demonstrates the severity of this
bug. The exploit proves that GPG agent creates EdDSA signatures that
cannot be verified by standard libgcrypt verification code, even with
the correct keys.
The term "exploit" is used to describe an attack method which undermines
the security of a system. What you describe is a claimed inconsistent
API. That may or may not be the case; I don't see a security bug here,
though.
Salam-Shalom,
Werner
p.s.
I had a brief look at your project: In src/main.c I notice
// Set global FPS from command-line option if provided
extern int g_max_fps;
The declaration of an external variable inside a function is a not a
good coding style. Put this at the top of the file or into a header.
A few lines above:
#ifndef NDEBUG
// Initialize lock debugging system after logging is fully set up
log_debug("Initializing lock debug system...");
Never ever use NDEBUG. This is an idea of the 70ies. This also
disables the assert(3) functionality and if you do this you won't get an
assertion failure at all in your production code - either you know the
code is correct or you are not sure. Never remove an assert from
production code.
I have noticed a lot of documentation inside the code - that's good.
--
The pioneers of a warless world are the youth that
refuse military service. - A. Einstein
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openpgp-digital-signature.asc
Type: application/pgp-signature
Size: 284 bytes
Desc: not available
URL: <https://lists.gnupg.org/pipermail/gcrypt-devel/attachments/20260115/0af17dec/attachment.sig>
More information about the Gcrypt-devel
mailing list