Skip to content

test(k12): compare customization timings at equal length, not across lengths - #69

Merged
Nexlab-One merged 1 commit into
mainfrom
fix/k12-constant-time-flake
Jul 28, 2026
Merged

test(k12): compare customization timings at equal length, not across lengths#69
Nexlab-One merged 1 commit into
mainfrom
fix/k12-constant-time-flake

Conversation

@Nexlab-One

Copy link
Copy Markdown
Contributor

test_customization_constant_time compared customization strings of different lengths (0, 5, 27, 100 bytes) against a single 60% timing band.

That asserts something false by construction: the customization is absorbed into the sponge, so a longer one costs strictly more work. It only ever passed because hashing the 1000-byte message dominated the difference. It is also aimed at the wrong property - a customization string is a public domain separator, not key material, so length-dependent timing is not a side channel even in principle.

All four inputs are now exactly 32 bytes and differ only in content (all-zero, all-one, alternating, counter-derived), so the comparison isolates the property worth asserting: that timing does not depend on customization content at fixed length.

What this does not claim. It is not the fix for #57's red run. That failed on 2026-07-20 at merge-base 123fc27, which predates min_time (added 2026-07-25 in a515797), so it was still single-sample wall clock - and the reported outlier was customization 0, the empty string, i.e. the cheapest input timing slowest. That is noise. This change removes an unsound assertion and restores the margin the length spread was eating.

The 60% band is deliberately not tightened - all inputs now do identical work, so it only absorbs runner noise.

Verified locally: 5/5 consecutive runs green, fmt clean, clippy --all-targets --all-features -- -D warnings clean.

…lengths

`test_customization_constant_time` measured `""` (0 bytes), `"short"` (5),
`"medium_length_customization"` (27) and `[0xAA; 100]`, then asserted all four
timings sit within one 60% band. That asserts something false by construction.
The customization string is absorbed into the sponge, so its LENGTH changes how
much work Kt128 does -- 100 bytes costs strictly more than 0, and crossing a
block boundary costs an extra permutation. The assertion only ever held because
hashing the 1000-byte message dominated the difference: a test that passes only
while the effect it measures is drowned out is not measuring anything.

It is also aimed at the wrong property. A customization string is a domain
separator -- public input, not key material -- so a length-dependent timing is
not a side channel even in principle. The property actually worth asserting is
that timing does not depend on the customization's CONTENT at a fixed length,
which is what would matter if a customization ever carried secret material. All
four inputs are now exactly 32 bytes and differ only in their bytes (all-zero,
all-one, alternating, counter-derived), so the comparison is meaningful and the
systematic length bias is gone.

What this does NOT claim. It does not explain the observed CI failure on PR #57
(serde_json 1.0.150 -> 1.0.151), and it should not be sold as the fix for it. That
run failed on 2026-07-20 at merge-base 123fc27, which predates `min_time`
(introduced 2026-07-25 in a515797) -- so it was still single-sample wall clock,
and the reported outlier was customization 0, the EMPTY string, i.e. the cheapest
input timing slowest. That is noise, not length bias. Re-running #57 against
current `main`, which now has the repeated-measurement minimum, is what addresses
that failure; this commit removes an unsound assertion and restores the margin
the length spread was eating, which makes future noise-induced failures less
likely rather than impossible.

The 60% band is deliberately NOT tightened. All four inputs now do identical
work, so the band only absorbs runner noise; narrowing it would trade the bug
just fixed for a fresh source of intermittent failures.

This remains a coarse wall-clock smoke test, and the doc comment now says so:
real leakage assessment belongs to `lib-q-sca-test` and the dedicated
"Constant-Time Verification" job, and a pass here is not evidence of
constant-timeness.

Verified: 5/5 consecutive runs green, `cargo fmt -p lib-q-k12 -- --check` clean,
`cargo clippy -p lib-q-k12 --all-targets --all-features -- -D warnings` clean.
@github-actions

Copy link
Copy Markdown

🔒 Security Validation Report

Generated: Tue Jul 28 22:47:45 UTC 2026

📊 Summary

  • NIST compliance: success
  • Cryptographic validation: success
  • Constant-time operations: success
  • Memory safety: success
  • Dependency security: success
  • WASM security: success

✅ Overall Security Status: PASSED

All critical security validations passed successfully.

🔍 Details

This report covers:

  • NIST post-quantum algorithm compliance
  • Constant-time operation verification
  • Memory safety and zeroization checks
  • Dependency vulnerability scanning
  • WASM build artifact validation

📋 Next Steps

✅ Security validation passed. Code is ready for deployment.


Security validation passed! This code meets all security requirements.

@github-actions

Copy link
Copy Markdown

🔍 Pull Request Summary

Generated: Tue Jul 28 22:52:59 UTC 2026

📋 Validation Results

  • Core Validation: success
  • Security Validation: success
  • Test Coverage: success
  • WASM Compatibility: success
  • Documentation: success

✅ Overall Status: PASSED

🔒 Security Checklist

  • No classical cryptographic algorithms
  • Only SHA-3 family hash functions
  • Constant-time operations
  • Proper memory zeroization
  • Input validation
  • Error handling

📝 Review Notes

Please review the security implications of this change carefully.
All cryptographic changes require security team review.


Automated validation passed! This PR is ready for review.

@Nexlab-One
Nexlab-One merged commit df67e65 into main Jul 28, 2026
157 checks passed
@Nexlab-One
Nexlab-One deleted the fix/k12-constant-time-flake branch July 28, 2026 23:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant