<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:times new roman,serif;font-size:large;color:#073763">Hey Werner,<br><br>I appreciate the feedback, but I have to respectfully push back here. I don't think this is just an API inconsistency issue.<br><br>I set up a minimal test case to verify what's happening, and it's pretty clear cut:<br><br>// Format 2: (data (flags eddsa) (hash-algo sha512) (value %b))<br>err = gcry_sexp_build(&s_data, NULL,<br>"(data (flags eddsa) (hash-algo sha512) (value %b))",<br>msg_len, msg);<br><br>err = gcry_pk_sign(&s_sig, s_data, privkey); // OK - signing works<br>err = gcry_pk_verify(s_sig, s_data, pubkey); // FAILED - verification fails<br><br>The thing is, I'm using the exact same S-expression for both signing and verification. If the format is valid enough for signing to succeed, it should be valid for verification. That's the inconsistency. You can't have signing work and verification fail with identical inputs.<br><br>I get that Ed25519 has been working well since 2014 - the simple format (data (value %b)) works fine for me too. But when you add the EdDSA flags and hash-algo spec (which is what GPG uses), the verification breaks. That's a real problem.<br><br>This isn't some edge case either. I'm trying to verify signatures and it fails every time because libgcrypt can sign but can't verify using the same format. For my use case, that's a showstopper for using the lib directly... I resorted to having the gpg binary do it in its own process which is not ideal code at all.<br><br>I'm not trying to be difficult here - I just want this fixed or at least documented as a known limitation, and to have tests updated because in my research this bug exists because there are no tests for specifically this case. If EdDSA with hash-algo flags isn't supposed to be supported, the library should reject it at sign time, not silently accept it and then fail verification.<br><br>What do you think? Did you run my example code at least and SEE the failures in your own terminal? It's reproducible, and I could show you if you were sitting in front of me.<br><br>-Zachary</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jan 15, 2026 at 8:41 AM Werner Koch <<a href="mailto:wk@gnupg.org" target="_blank">wk@gnupg.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi!<br>
<br>
Just a short note on your bug report. You gave a lot of examples and a<br>
nicely formated report at <a href="https://github.com/zfogg/ascii-chat/issues/92" rel="noreferrer" target="_blank">https://github.com/zfogg/ascii-chat/issues/92</a><br>
but I can't read everything of it.<br>
<br>
On Tue, 30 Dec 2025 02:30, Zachary Fogg said:<br>
> **In-Reply-To:** <response from NIIBE Yutaka on Oct 22, 2025><br>
<br>
> Your response mentioned using `(flags eddsa)` during key generation, which<br>
> is good practice. However, I want to clarify that **my bug report concerns<br>
> signature verification, not key generation**.<br>
<br>
If you look at the way GnuPG uses Libgcrypt will find in<br>
gnupg/g10/pkglue.c:pk_verify this:<br>
<br>
if (openpgp_oid_is_ed25519 (pkey[0]))<br>
fmt = "(public-key(ecc(curve %s)(flags eddsa)(q%m)))";<br>
else<br>
fmt = "(public-key(ecc(curve %s)(q%m)))";<br>
<br>
and this for the data:<br>
<br>
if (openpgp_oid_is_ed25519 (pkey[0]))<br>
fmt = "(data(flags eddsa)(hash-algo sha512)(value %m))";<br>
else<br>
fmt = "(data(value %m))";<br>
<br>
and more complicated stuff for re-formatting the signature data. It is<br>
a bit unfortunate that we need to have these special cases but that's<br>
the drawback of a having a stable API and protocol.<br>
<br>
> 1. Can you confirm this is a genuine bug in libgcrypt's verification logic?<br>
<br>
No, at least not as I understand it. ed25519 signatures are working<br>
well and are in active use since GnuPG 2.1 from 2014.<br>
<br>
> 2. Should I open a formal bug in the <a href="http://dev.gnupg.org" rel="noreferrer" target="_blank">dev.gnupg.org</a> tracker?<br>
<br>
I don't see a bug ;-)<br>
<br>
> 3. Would a patch fixing the PUBKEY_FLAG_PREHASH handling be acceptable?<br>
<br>
I do not understand exactly what you propose. A more concise<br>
description would be helpful. But note that API stability is a primary<br>
goal.<br>
<br>
BTW on your website your wrote: <br>
<br>
I've created a working exploit that demonstrates the severity of this<br>
bug. The exploit proves that GPG agent creates EdDSA signatures that<br>
cannot be verified by standard libgcrypt verification code, even with<br>
the correct keys.<br>
<br>
The term "exploit" is used to describe an attack method which undermines<br>
the security of a system. What you describe is a claimed inconsistent<br>
API. That may or may not be the case; I don't see a security bug here,<br>
though.<br>
<br>
<br>
<br>
Salam-Shalom,<br>
<br>
Werner<br>
<br>
<br>
p.s.<br>
I had a brief look at your project: In src/main.c I notice<br>
<br>
// Set global FPS from command-line option if provided<br>
extern int g_max_fps;<br>
<br>
The declaration of an external variable inside a function is a not a<br>
good coding style. Put this at the top of the file or into a header.<br>
A few lines above:<br>
<br>
#ifndef NDEBUG<br>
// Initialize lock debugging system after logging is fully set up<br>
log_debug("Initializing lock debug system...");<br>
<br>
Never ever use NDEBUG. This is an idea of the 70ies. This also<br>
disables the assert(3) functionality and if you do this you won't get an<br>
assertion failure at all in your production code - either you know the<br>
code is correct or you are not sure. Never remove an assert from<br>
production code.<br>
<br>
I have noticed a lot of documentation inside the code - that's good.<br>
<br>
-- <br>
The pioneers of a warless world are the youth that<br>
refuse military service. - A. Einstein<br>
</blockquote></div>
</div>