You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fiat-Shamir H1 binds H_a_seed but not the syndrome y — intended? (comment says "H1(pk || salt ...)") #2
Hi — while reviewing the reference/optimized code I noticed that the first Fiat-Shamir hash H1 binds only the H_a_seed half of the public key, not the syndrome y, even though the surrounding comment reads // H1(pk || salt ...). Wanted to ask whether that's intended.
In sdith.c (e.g. Reference_Implementation/Hypercube_Variant/sdith_hypercube_cat1_gf256/sdith.c around line 1000), the message-commitment context is built as:
// H1(pk || salt ...)sdith_hash_digest_update(ctx->msg_commit_ctx, pk->compressed_pubkey.H_a_seed, PARAM_seed_size);
sdith_hash_digest_update(ctx->msg_commit_ctx, ctx->salt, PARAM_salt_size);
// ... per-iteration leaf commitments, then the message in the online phase
The public key is { H_a_seed, y } (sdith.h), but pk->compressed_pubkey.y is not absorbed here, and I couldn't find y fed into H1, the first challenge (r, eps) = XOF(h1), or H2 anywhere in the challenge chain. This is consistent across all 12 variants I looked at (Reference + Optimized x cat1/3/5 x gf256/p251).
I want to be clear this is a question, not a vulnerability report — I could not construct any attack.y is bound computationally: the MPC proof values that go into H2 are computed with y, and verification recomputes them with y, so a signature stays tied to y (forging still requires solving the syndrome-decoding instance, and a key-substitution to a different y' seems to fail the MPC output check). So as far as I can tell EUF-CMA is fine.
My question is about robustness / matching common practice: most FS-based signatures bind the entire statement/public key into the initial transcript (e.g. FAEST absorbs the full OWF output, Dilithium binds pk via tr, Picnic binds the full public key). Absorbing only H_a_seed and not y seems to deviate from that, and I wasn't sure whether it could matter for the ROM security reduction (where the statement is usually a hash input) or for the BUFF / exclusive-ownership properties. Given the comment says H1(pk || ...), it looked like it might be an unintended omission.
Would you be able to confirm whether binding only H_a_seed (not y) in H1 is intentional? Happy to be corrected if y is bound somewhere I missed.
Disclosure note: found during a manual review, assisted by our own tooling and an AI (Anthropic Claude/Opus). Thanks for the work on SDitH.
The intention was indeed to take the entire public key, even though I cannot find an attack either if only the hash only considers the seed into account.
We will leave the old v1 and v2 code unchanged since they are kept for historical purposes, but we confirm that the issue has been resolved from the round3 (v3) onwards.
Activity
aq-ngama commentedon Aug 27, 2026
Thank you very much for reporting this issue,
The intention was indeed to take the entire public key, even though I cannot find an attack either if only the hash only considers the seed into account.
We will leave the old v1 and v2 code unchanged since they are kept for historical purposes, but we confirm that the issue has been resolved from the round3 (v3) onwards.