Skip to content

Simple ciphers: stream + symmetric cipher unification off the release branch, plus SHA-512/t for any t - #133

Closed
dghgit wants to merge 320 commits into
release/0.1.3alphafrom
feature/simple-ciphers
Closed

dghgit wants to merge 320 commits into
release/0.1.3alphafrom
feature/simple-ciphers

Conversation

@dghgit

@dghgit dghgit commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Consolidates the stacked pair #113 (feature/stream-cipher → release/0.1.3alpha) and #115
(feature/symmetric-cipher → feature/stream-cipher) into a single branch off the release
branch, and adds the SHA-512/t work on top.

feature/simple-ciphers was built by branching from release/0.1.3alpha and merging
feature/stream-cipher then feature/symmetric-cipher; both merges fast-forwarded, so the
content below the two new commits is exactly what #113 and #115 already carried — this is a
re-packaging, not new review surface. #113 (+21,938) and #115 (+2,310) sum to roughly the
+23,499 here.

New in this PR, on top of those two

core: SecurityStrength::from_bits / from_bytes become const fn (3912434) — two
keywords, no behaviour change. Needed so an associated const can derive a strength from a const
generic; split out ahead of the feature per CLAUDE.md's scope-of-changes rule.

sha2: SHA512t<T> is usable for every t FIPS 180-4 s. 5.3.6 defines a hash for (785dbef).
Previously only T = 224 and T = 256 had parameter impls, so nothing else could be named.

  • The t-value checks are back, and they are the spec's. b11f8f6 had narrowed sha512t_h0 to
    100 <= t < 512 and emitted a fixed three digits, since only 224 and 256 were reachable. With
    arbitrary t reachable that would produce the "0256" spelling s. 5.3.6 explicitly forbids —
    and hence the wrong IV — for every t below 100. The one- and two-digit branches are restored
    and check_t asserts the section's own rule: positive, < 512, not 384.
  • One deviation, documented: t must be a multiple of 8, because Hash is byte-oriented and
    a 100-bit digest has no representation here. BC Java's SHA512tDigest imposes the identical
    restriction, so the two libraries accept the same set of truncations.
  • Unapproved truncations are gated the way ElectronicCodeBook::ENCRYPTION_APPROVED gates
    two-key TDEA: SHA512tParams::<T>::FIPS_APPROVED is public and SHA512Internal::new asserts it
    in an inline const, so an unapproved t is a compile error at the call site and
    new_allow_unapproved_t() is the deliberate way in. That also blocks Default, which keeps an
    unapproved truncation out of generic code by accident.
  • ALG_NAME, OUTPUT_LEN and MAX_SECURITY_STRENGTH are derived from t, with const
    assertions pinning them to the values 224 and 256 previously had by hand.

Verification

  • cargo test --workspace: 943 passed, 0 failed (was 923). cargo fmt --check clean; no new
    clippy warnings. Both new commits build independently.
  • Spec text read from a freshly downloaded FIPS 180-4, not from recall.
  • Test vectors cross-checked against BC Java's SHA512tDigest, an independent implementation:
    eight truncations (8, 16, 24, 88, 96, 104, 264, 504) spanning all three decimal branches, over
    the FIPS 180-4 Appendix C messages plus the one-million-'a' case. The 224/256 rows in the same
    table match the NIST-published values.
  • cargo mutants on the changed files: 259 mutants — 180 caught, 5 timeout-kills, 69 unviable,
    5 missed. All five missed are the pre-existing XOR/OR equivalences already annotated at their
    sites in ch, maj and do_final_internal; no new missed mutants.

Note for reviewers

Adding const to a public core function is a forward compatibility commitment, and
SHA512tParams is currently its only caller. The alternative was a private copy of the rounding
ladder inside sha2, free to drift from the real one — happy to switch if the API-surface cost is
the greater worry.

🤖 Generated with Claude Code

dghgit and others added 30 commits September 10, 2026 08:02
…so the lib target the src/ move introduced does not compile them as failing Rust doctests
…ding, and the SHA-512/t sealing trait is now named SHA512InitValue
….6 prints it, with H(0)'' on the left of the XOR and as the IV of the final SHA-512 call
…enches sources moved under src/ and are now doctested, and integration tests are preferred per QUALITY_AND_STYLE.md
…, dropping the one- and two-digit branches of s. 5.3.6 that no approved-t caller or test could reach; of its 43 mutants none is now missed
…4 a comment claimed, and exceeding it truncates the 64-bit length field silently instead of panicking on the byte-count add, so do_update asserts it in debug builds; sha512t_h0's assertion stops crediting FIPS 180-4 s. 5.3.6 with the t >= 100 its own three-digit formatting imposes, and a new test pins the 128-bit length carry that exempts SHA-512
… l < 2^64 bits, and exceeding it truncates the 64-bit length field silently instead of panicking on the byte-count add, so do_update asserts it in debug builds
…tor bundled into a feature commit makes the diff unreviewable however correct it is, so a refactor that unblocks the task goes in its own commit ahead of it and one that unblocks nothing gets proposed rather than done
… whose per-hash instantiations live in the hash crates, so HMAC_SHA512_224 and HMAC_SHA512_256 move to sha2::hmac as HMACParams impls; HMAC-SM3 is dropped here and reinstated under the new layout in the following commit, which is the only way to keep both commits building
…ed, as a new sm3::hmac module holding the HMACParams impl, the HMAC_SM3 alias and the OSCCA OID, with its criterion bench, factory and CLI wiring and known-answer tests restored alongside it
…anch, taking the shortened release notes from b282942 over the long form this branch still carried and accepting 5825050's deletion of core-test-framework/summary.md; no code conflicts, since the MAC factory and CLI changes are additive here
…a parameter set can derive MAX_SECURITY_STRENGTH from a const generic instead of naming a variant by hand; no behaviour change, and the following commit is the first caller that needs it

Assisted-by: Claude:claude-opus-5

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…a hash for, not just the two approved truncations, so the IV Generation Function regains the one- and two-digit decimal branches that b11f8f6 dropped as unreachable -- writing a fixed three digits gives the "0256" spelling the section forbids, and hence the wrong IV, for every t below 100; t is checked against the section's own rule (positive, below 512, not 384) plus this crate's multiple-of-8 requirement, which BC Java's SHA512tDigest also imposes, and the unapproved truncations carry SHA512tParams::FIPS_APPROVED = false which SHA512Internal::new asserts in an inline const, so reaching one takes new_allow_unapproved_t() the way an encrypting mode takes ENCRYPTION_APPROVED; ALG_NAME, OUTPUT_LEN and MAX_SECURITY_STRENGTH are now derived from t and pinned to their old values for t = 224 and t = 256; new sha512t_tests.rs cross-checks eight truncations spanning all three digit branches against BC Java, and of the file's 259 mutants 180 are caught, 5 die on timeout and the 5 missed are the XOR/OR equivalences already documented at their sites

Assisted-by: Claude:claude-opus-5

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…tions and the commit message style in CLAUDE.md
Comment thread cli/src/main.rs
Comment thread crypto/cipher/src/modes/mod.rs
ounsworth and others added 5 commits October 21, 2026 17:49
…tructions for what to do for a permutation that does not impl all modes
Keeping a key to one algorithm is moving to compile-time key types
(#167), so the opt-in runtime binding that 0de70ae added goes. Nothing
outside the tests ever bound a key, so no cipher call outside them
changes outcome; KeyMaterial's Display/Debug lose the `algorithm` field.

Removed:
- KeyMaterial's `algorithm` field and KeyMaterialTrait::algorithm,
  set_algorithm and check_algorithm.
- The 26 check_algorithm calls: 24 in crypto/cipher, one in Ascon's
  checked_key, one in the ToyCbc test double. The cipher imports go
  back to KeyMaterial alone.
- The framework's key_binding module and its four suite blocks, two
  tests in key_material_tests.rs, and aes/tests/key_binding_tests.rs,
  including the cross-size test 6994217 added there.

This is not `git revert 0de70ae`: that commit also folded the two
ToyBlockCipher copies into the cipher crate's, which stays, and a plain
revert conflicts with 6994217. Files no later commit touched are back
to 0de70ae~1 byte for byte.

#172's from_key_material and #157's ChaCha20 keys still call
check_algorithm, and need the same removal when they next merge this.

cargo test --workspace --no-fail-fast: 1106 passed, 1 failed. The
failure is ascon_wycheproof, whose vector file is missing from the
local wycheproof checkout; it fails the same way without this change.

Assisted-by: Claude:claude-opus-5-5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread crypto/cipher/src/stream.rs Outdated
Comment thread crypto/cipher/src/stream.rs Outdated
Comment thread crypto/factory/src/hash_factory.rs
Comment thread crypto/factory/tests/hash_factory_tests.rs
Comment thread crypto/core/src/traits.rs Outdated
Comment thread mem_usage_benches/src/bench_ascon_mem_usage.rs Outdated
Comment thread mem_usage_benches/src/bench_ccm_mem_usage.rs Outdated
ounsworth and others added 5 commits October 22, 2026 12:53
…cipher traits in favour of the _blocks_inplace ones (since the former were shallow wrappers around the second with a worse public API). Also added a new SymmetricCipherError::DataNotBlockAligned to handle runtime checks for misalignments. Assisted-by: Claude Opus 5.5
…ike the others, not from the command line

Assisted-by: Claude:claude-mythos-5-1
…e the others, not from the command line

Assisted-by: Claude:claude-mythos-5-1
…inal methods

A public parameterless function that returned a constant (PR #133 review).
cargo mutants will report the [] at each site as surviving against [0; 0]
and [1; 0]; a zero-length array has no element to differ in, so those are
equivalent. The usize mutant that returns 1 is caught by the tests.

Assisted-by: Claude:claude-mythos-5-1
…n at the six do_*_out methods

A pub free function taking the in-place step as a closure (PR #133 review).
It was a free function because do_*_out belongs to SymmetricCipher*, and
StreamCipher* cannot supply a default body for a supertrait's method; the
six-line body written at each site is what GCM, CCM and Ascon already do,
and drops the second zeroing of the output buffer.

Assisted-by: Claude:claude-mythos-5-1
… not written or read in-band

The default is unchanged: encrypt generates the IV (or 12-byte nonce for
CTR and GCM) and prepends it, decrypt reads it off the front. With --iv,
encrypt writes only ciphertext (GCM: ciphertext || tag) and decrypt reads
only that, for formats that carry the IV themselves and for published
vectors. Covers aes*-cbc, -cfb, -cfb8, -ctr and -gcm; ECB has no IV and
CCM keeps its own variable-length --nonce. The "deliberately no --iv"
lines are gone from the help and the helper docs.

The IV reaches a mode through do_encrypt_init_rng and a one-shot FixedIv
RNG in block_mode_helpers (GCM uses do_encrypt_init_nonce), since the mode
types have no IV-taking constructor. Checked by hand against SP 800-38A
F.2.1 (CBC), F.3.7/F.3.8 (CFB8), F.3.13/F.3.14 (CFB128), the in-tree
OpenSSL-derived CTR vector, and CAVP gcmEncryptExtIV128 Count 0; all
reproduce in both directions.

Assisted-by: Claude:claude-mythos-5-1
hubot pushed a commit that referenced this pull request Oct 23, 2026
…as PKCS7 padding), Ascon, SHA2/t, and SHA3 derived functions: cSHAKE, KMAC, TupleHash, ParallelHash. Created by David Hook, Francis Mendoza, Mike Ounsworth.Assisted-by: Claude Opus 5.5. Assisted-by: Claude Fable 5.1
@ounsworth

Copy link
Copy Markdown
Contributor

Review finally done.
Merged manually.

@ounsworth ounsworth closed this Oct 23, 2026
@ounsworth ounsworth mentioned this pull request Oct 24, 2026
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.

3 participants