EdDSA Verification Bug - Clarification on Format 2 Verification Failure
Zachary Fogg
zach.fogg at gmail.com
Tue Dec 30 08:30:00 CET 2025
**In-Reply-To:** <response from NIIBE Yutaka on Oct 22, 2025>
Hi NIIBE Yutaka,
Thank you for your response on October 22! I apologize for the delay - I am
new to the list and didn't receive your email until I checked the web
archives today.
## Clarifying the Bug
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**.
The issue is that **Format 2 S-expressions can successfully SIGN but cannot
VERIFY** Ed25519 signatures, even when keys are properly generated with the
eddsa flag.
### Reproduction
Here's a minimal test case showing the problem:
```c
// Key generation (with proper eddsa flag as you suggested)
gcry_sexp_t keypair;
gcry_sexp_build(&keypair, NULL, "(genkey (ecc (flags eddsa) (curve
Ed25519)))");
gcry_pk_genkey(&keypair, keypair);
// Extract public/private keys...
// TEST: Sign with Format 2 (what GPG agent uses)
gcry_sexp_t data_sexp;
gcry_sexp_build(&data_sexp, NULL,
"(data (flags eddsa) (hash-algo sha512) (value %b))",
32, message_hash);
gcry_sexp_t sig;
gcry_pk_sign(&sig, data_sexp, private_key); // ✓ SUCCEEDS
// TEST: Verify the same signature
gcry_error_t err = gcry_pk_verify(sig, data_sexp, public_key);
// ✗ FAILS with "Bad signature"
```
### Why This Matters
1. **GPG agent uses Format 2** - The failing format `(data (flags eddsa)
(hash-algo sha512) (value %b))` is what GPG agent generates (see
`gnupg/agent/pksign.c`)
2. **GPG agent skips EdDSA verification** - Line 420-425 of
`agent/pksign.c` shows verification is only performed for RSA, not EdDSA.
This hid the bug.
3. **Real-world impact** - Applications using libgcrypt to verify GPG agent
signatures will fail, even though the signatures are valid.
### Root Cause
The bug appears to be in `libgcrypt/cipher/ecc-eddsa.c` where the
`PUBKEY_FLAG_PREHASH` flag causes different hash computations during
signing vs verification:
- **During signing:** Hash is computed once and reused
- **During verification:** Hash is computed differently
- **Result:** Verification fails despite valid signature
### Test Results
| Format | Sign | Verify | Notes |
|--------|------|--------|-------|
| Format 1: `(data (value %b))` | ❌ | N/A | Expected - no hash-algo |
| Format 2: `(data (flags eddsa) (hash-algo sha512) (value %b))` | ✅ | ❌ |
**THE BUG** |
| Format 3: `(data (value %b))` | ✅ | ✅ | Works, but not what GPG uses |
### Proposed Fix
The PUBKEY_FLAG_PREHASH logic needs to be consistent between signing and
verification paths.
## Questions
1. Can you confirm this is a genuine bug in libgcrypt's verification logic?
2. Should I open a formal bug in the dev.gnupg.org tracker?
3. Would a patch fixing the PUBKEY_FLAG_PREHASH handling be acceptable?
Thanks,
Zachary Fogg
---
## Additional Context
- **Issue tracking:** https://github.com/zfogg/ascii-chat/issues/92
- **Test programs:** Available on request
- **Versions tested:** libgcrypt 1.11.2, GnuPG 2.4.8
- **Use case:** Terminal video chat app (ascii-chat) authenticating users
via GitHub GPG keys
--
--
🐨 ẔƑ 👾
zfo.gg/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.gnupg.org/pipermail/gcrypt-devel/attachments/20251230/4307fd02/attachment.html>
More information about the Gcrypt-devel
mailing list