pub fn fors_pk_from_sig<P: Params>(
sig_fors: &[u8],
md: &[u8],
pk_seed: &[u8],
adrs_template: &Adrs,
) -> Vec<u8> ⓘExpand description
Compute a FORS public key from a FORS signature — constant-time.
Implements Algorithm 17 of FIPS 205. For each of the k FORS trees,
hashes the revealed secret leaf, then walks up the authentication path
to recover the tree root. The k roots are compressed into a single
n-byte public key via T_k. If the signature is valid, the returned
public key matches the one produced by the signer.
§Side-channel posture
The secret-dependent argument ordering of hash_h along each
authentication-path level is resolved by a branchless byte-wise
silentops::ct_select_u8 cswap rather than a Rust if. Address bytes
and the tree_index written into adrs are identical in both original
branches, so they need no extra masking. The per-iteration scratch is
drop-zeroized via silentops::ct_zeroize before return.
In the verifier path the FORS-tree digit idx is reconstructed from
the publicly transmitted message digest, so a timing leak on the digit
would be harmless. But the same routine is reused inside the signer
post-signing redundancy check (item T1-C of the SLH-DSA roadmap —
see fors_sign_into_redundant). At that point of the signing flow,
idx is derived from values (the freshly sampled randomizer R, the
secret SK.prf) that have not yet been published, so a control-flow
leak on the digit would become a secret-key leak. A single CT
implementation across both paths removes the foot-gun of a future call
site picking a variable-time variant by autocomplete.
§References
- Castelnovi-Martinelli-Prest, Grafting Trees: a Fault Attack against the SPHINCS framework, ePrint 2018/102 — motivates T1-C, which in turn motivates this CT routine.
- Adiletta et al., SLasH-DSA: Breaking SLH-DSA Using an Extensible End-to-End Rowhammer Framework, arXiv 2509.13048 (Aug 2025) — software realisation of the same attack class.
- Genêt, On Protecting SPHINCS+ Against Fault Attacks, TCHES 2023(3) (ePrint 2023/042) — recommends the recompute-and-compare redundancy that consumes this routine.