SLH-DSA: add to wolfCrypt -Wconversion CI matrix and clean warnings#16
Closed
SLH-DSA: add to wolfCrypt -Wconversion CI matrix and clean warnings#16
Conversation
Adds --enable-slhdsa to the existing 11 wolfCrypt-Wconversion build rows and adds 4 dedicated rows for the sub-options that the default doesn't cover (small, small-mem, sha2, verify-only on 32-bit). Adds a test_slhdsa_runtime job mirroring test_lms_runtime / test_xmss_runtime that builds without --disable-crypttests and runs testwolfcrypt for five configs (default-SHAKE, small, sha2, verify-only, 32-bit). Cleans the conversion warnings that surface in wc_slhdsa.c and the SLH-DSA code paths in asn.c. Patterns applied (same as LMS PR #14 and XMSS PR #15): - U-suffix on integer literals that flow into word32 size fields (SLHDSA_W, SLHDSA_WM1, 2*n -> 2U*n, len*n -> (word32)len*n, sk-size literals 4 and 3 -> 4U / 3U at ForceZero / XMEMCPY / wc_RNG_GenerateBlock call sites). - (word32)1U << z for shifts whose exponent reaches the SLH-DSA tree height parameters (params->h, params->h_m, params->d) up to 68 for 256s/f variants - avoids 32-bit UB. - word16 csum / mask accumulators with explicit (word16) casts at the assignment boundary for WOTS+ checksum and base-2^b decomposition. - HA_*, SHAKE256_SET_*_X4 and HASH_H/HASH_F macros: parenthesise operands and add (word32) / (size_t) / (byte) casts so the argument types narrow at the macro boundary, not at every call site. - slhdsakey_chain_idx_x4_NN signature: byte i, byte s -> word32 i, word32 s; loop counters int j -> word32 j; call sites cast at invocation. - slhdsakey_shake256_set_seed_ha_x4 / _hash_x4 return type int -> word32; locals to word32. - XMSS / FORS tree generators: introduce const word32 wi = (word32)i / wz = (word32)z and use wi/wz in the inner-loop offset arithmetic so each multiplication / shift is in word32 from the start. - word64* cast-qual fixes: add const where the helper only reads its input (slhdsakey_hash_h_2_x4 inputs, etc.). - asn.c: int slhDsaParam = wc_SlhDsaOidToParam((int)keyOID) and ret = (int)outSz at three call sites where outSz is word32. Critical semantic fix: slhdsakey_base_2b wrote baseb[j] = (byte)((total >> bits) & mask); baseb is word16* and FORS values can be up to 14 bits (parameter a). The byte cast truncated values >255 and broke verification on FORS variants. Changed to (word16) - caught by testwolfcrypt under the new runtime job. Verified clean against all 15 build matrix rows (default, intelasm, smallstack, smallstack+intelasm, NO_INT128, 32-bit, mlkem-small, mlkem-no-large-code, smallstack+NO_INT128, mlkem-small-mem-32bit, mlkem-small-mem+NO_INT128, slhdsa=yes,small / small-mem / sha2 / verify-only-32bit). All five test_slhdsa_runtime configs pass testwolfcrypt's slhdsa_test(). Benchmark with -DBENCH_MIN_RUNTIME_SEC=5.0F across the six SHAKE variants (128s/f, 192s/f, 256s/f) shows sign / verify deltas within +/-5% of master after this change. https://claude.ai/code/session_01EJmy1bKDgHseTwZ5Qqpu1g SLH-DSA Wconversion: review fixes Address review findings from the previous commit: - wc_slhdsa.c:1681: replace the (incorrect) mask comment with a comment on the actual word16 cast. baseb is word16* and FORS values reach 14 bits (parameter a), so the original (byte) cast silently truncated. - wc_slhdsa.c:57-59: revert SLHDSA_W / SLHDSA_WM1 to plain int. The U suffix forced cascaded (int)SLHDSA_WM1, (sword8)SLHDSA_WM1 and (byte)(SLHDSA_WM1 - x) casts at every signed-comparison site without saving anything. The (word16) cast at the WOTS+ csum / mask assignment is sufficient. - wc_slhdsa.c: drop (int)SLHDSA_WM1 at three call sites in slhdsakey_chain_idx_to_max_{16,24,32}, made redundant by the WM1 revert. - wc_slhdsa.c: unify (word32)1U shift form across all eight call sites; the previous commit changed only four of them. - wc_slhdsa.c:8305, 8340: switch ExportPrivate / ExportPublic n back to byte to match every other internal use of params->n. - wc_slhdsa.c:127: add wc_static_assert(SLHDSA_MAX_MSG_SZ <= 255) to document the invariant that the WOTS+ chain helpers' (byte)i and (byte)j casts depend on (max len for current parameter sets is 2*32+3 = 67). - wc_slhdsa.c:4315-4320: deduplicate the csum-word16 explanatory comment; the second copy now defers to the first. - wolfCrypt-Wconversion.yml: bump build_library and test_slhdsa_runtime timeout-minutes from 6 to 10. SLH-DSA adds ~9 kLoC to every row and the 32-bit multilib + smallstack rows need headroom. All five representative build rows still compile clean (default, intelasm, smallstack, sha2, small-mem, verify-only-32bit). All five test_slhdsa_runtime configs still pass slhdsa_test(). https://claude.ai/code/session_01EJmy1bKDgHseTwZ5Qqpu1g
e1f5468 to
d9f91c3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Third in the hash-based-signature
-Wconversioncleanup series after PRs #14 (LMS) and #15 (XMSS). Independent of those branches.Phase A — CI matrix. Adds
--enable-slhdsato all 11 existingwolfCrypt-Wconversion.ymlbuild rows (each row already builds ML-KEM + all-crypto under conversion flags). Adds 4 dedicated SLH-DSA rows for sub-options the default does not cover (small,small-mem,sha2,verify-onlyon 32-bit-m32). Adds a newtest_slhdsa_runtimejob mirroring the LMS / XMSS runtime jobs that builds with crypttests and runs./wolfcrypt/test/testwolfcryptfor five configs (default-SHAKE, small, sha2, verify-only, 32-bit). Total: 15 build rows + 5 runtime rows.timeout-minutesraised to 10 — SLH-DSA adds ~9 kLoC per row and the 32-bit + smallstack rows need headroom.Phase B — clean conversion warnings in
wc_slhdsa.cand the SLH-DSA paths inasn.c. Patterns reused from PRs LMS: add to wolfCrypt -Wconversion CI matrix and clean conversion warnings #14 / XMSS: add to wolfCrypt -Wconversion CI matrix and clean conversion warnings #15:word32size fields (2*n → 2U*n,len*n → (word32)len*n, ForceZero / XMEMCPY /wc_RNG_GenerateBlocksize literals).(word32)1U << zfor shifts whose exponent reaches the SLH-DSA tree-height parameters (params->hup to 68 for 256s/f) — avoids 32-bit UB. All eight call sites use the same form.word16 csum/word16 maskaccumulators with(word16)casts at the assignment boundary for the WOTS+ checksum and base-2^b decomposition.HA_*,SHAKE256_SET_*_X4,HASH_H/HASH_Fmacros: parenthesise operands and add(word32)/(size_t)/(byte)casts so types narrow at the macro boundary, not at every call site.slhdsakey_chain_idx_x4_NNsignature:byte i, byte s → word32 i, word32 s; loop countersint j → word32 j; cast at invocation.slhdsakey_shake256_set_seed_ha_x4/_hash_x4return typeint → word32.const word32 wi = (word32)i; const word32 wz = (word32)z;and usewi/wzin the inner-loop offset arithmetic so each multiplication / shift is inword32from the start.word64*cast-qual fixes:conston read-only inputs inslhdsakey_hash_h_2_x4and friends.asn.c:wc_SlhDsaOidToParam((int)keyOID)and(int)outSzat the SLH-DSAMakeSignaturesite.Critical semantic fix.
slhdsakey_base_2boriginally wrotebaseb[j] = (byte)((total >> bits) & mask);.basebisword16*and FORS values reach 14 bits (parametera), so the(byte)cast silently truncated values >255 and broke verification on FORS configs. Caught bytestwolfcryptunder the newtest_slhdsa_runtimejob. Fixed to(word16).Branch history
b9a192ba— initial Wconversion cleanup + CI extension.e1f54685— review fixes: revertSLHDSA_WM1to plain int (the U-suffix forced cascading(int)/(sword8)/(byte)casts at every signed-comparison site without saving anything); unify(word32)1Ushift form across all eight sites; switch exportnback tobytefor consistency; deduplicate thecsumword16 comment; addwc_static_assert(SLHDSA_MAX_MSG_SZ <= 255)to document the invariant the(byte)i/(byte)jtruncations depend on; bump CI timeouts.Test plan
test_slhdsa_runtimeconfigs passslhdsa_test()intestwolfcrypt(default, small, sha2, verify-only, 32-bit).-DBENCH_MIN_RUNTIME_SEC=5.0Facross the six SHAKE variants (128s/f, 192s/f, 256s/f) — sign / verify deltas within ±5% of master.Out of scope
https://claude.ai/code/session_01EJmy1bKDgHseTwZ5Qqpu1g
Generated by Claude Code