Repository navigation
Conversation
…ricCipherDecryptor with FINAL_LEN = 0, by blanket impls over the in-place methods, so any of the five modes can be held through one trait
…to AEADCipher, its only remaining user; the framework suite follows, and both AEAD security-strength loops gain the key-length guard the other suites already had
…_2blocks (were *_blocks2), the reading Mike Ounsworth gave them in 736b0ac; modes, aes, the framework suite, benches and notes follow
… a debug self-check that sub_word's eight broadcast planes agree, in-place benches with decrypt paths for every key length and key-expansion throughput, summary.md removed, and acvp_tests.rs becomes bc-test-data.rs; the rest of Mike Ounsworth's 736b0ac review that still applied
…decrypt_8blocks (were *_blocks8), so they read like the pair methods; modes, the framework suite, benches and notes follow
…pt_4blocks (was eight): AES fills a pair and the u16/u32-plane engines fill four, so eight was two passes for every engine and left a four-lane engine half-empty on a 4-to-7-block tail; modes chunk fours, then pairs, then singles, the framework suite and the rotated-four toy pin the four path, benches and notes follow
…thods by their current name
…ipherEncryptor / SimpleCipherDecryptor; the framework suite becomes TestFrameworkSimpleCipher and the modes API test file is renamed to match; aes, padding, modes and the notes follow
…p Vim swap file that d98f703 swept in
…ems like a personal workflow rather than a general thing.
…into feature/stream-cipher
…ems like a personal workflow rather than a general thing.
…Added a note about this to QUALITY_AND_STYLE.md.
…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
ounsworth
reviewed
Oct 6, 2026
ounsworth
reviewed
Oct 6, 2026
ounsworth
reviewed
Oct 6, 2026
ounsworth
reviewed
Oct 6, 2026
ounsworth
reviewed
Oct 7, 2026
ounsworth
reviewed
Oct 7, 2026
…for NIST SP 800-232
…c-rust into feature/simple-ciphers
…is is a large diff because adding that required updating the generic mode types/tests, but this prevents technical debt via maintenance for core
…lgorithm, but enabled reverse-compatible generic to not blow up the existing codebase + allow generate first, bind-later, generic use for raw AES, etc.
…zmat/aes_internal.rs, and hazmat/ecb.rs
- CcmEncryptor/CcmDecryptor override every one-shot (detached and inline, with and without AAD, with and without a caller's RNG) to call Ccm's own, since with the whole message in hand there is nothing to declare or hold back: no AAD buffer, and no DATA_LEN or AAD_LEN bound. Those two parameters now govern the streaming methods only, and decrypt_out_len is C less its tag as for any AEAD. The core-test-framework's fixed-length checks move accordingly: one-shots must round trip every length, a stream of the wrong length must be refused. - AEADCipherEncryptor gains do_encrypt_init_nonce and the encrypt_detached_nonce[_out] / encrypt_with_aad_nonce[_out] one-shots, for protocols that manage their own nonces, with the uniqueness obligation in the trait docs; implemented for GCM, Ascon-AEAD128 and CCM, and exercised by the framework against the rng forms under the same nonce. - CCM's 12-byte nonce floor moves from the adapters' shape check to the forms that draw a nonce, so the supplied-nonce forms and the decryptor take every A.1 length from 7 through 13 (802.11 CCMP's 13/8 covered in sp800_38c_tests). - CCM memory table re-measured with massif from one build. Assisted-by: Claude:claude-mythos-5-1 Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
…mplementing pair The lengths-declaring type is the one for SP 800-38C Sec 3's "packet environment, i.e., when all of the data is available in storage before CCM is applied", so it takes that name: CcmPacket in bouncycastle-cipher, AES_CCM_128_Packet and friends in bouncycastle-aes. The CcmEncryptor/CcmDecryptor pair, which implements the AEAD traits and now covers any length, a supplied or generated nonce and every A.1 nonce length through its one-shots, takes the plain AES_CCM_128 name, as AES_GCM_128 and the other modes' aliases name their trait implementors. No behaviour change. Assisted-by: Claude:claude-mythos-5-1 Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
…o do_{en,de}crypt_final_detached[_out]
The one-shots, their _len helpers and the rng and nonce forms already say "detached", and the tag is the only thing an AEAD can detach, so the four streaming finals follow. Mechanical rename across core, cipher, aes, ascon, the test framework, the CLI helpers and the mem benches; no behaviour change.
Assisted-by: Claude:claude-mythos-5-1
Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
…te-machine flag `AsconAead128` takes `Encrypting` or `Decrypting` as a type parameter, and each direction's constructor, one-shot, update and final live on that type only, so the four wrong-direction panics become compile errors (a `compile_fail` doctest pins one). The call-order state machine drops from six states to three. The suspended layout is unchanged: the call-state byte keeps the direction in bit 2, and resume refuses a state from the other direction. The trait wrappers are unchanged in shape and hold the typed cipher. Assisted-by: Claude:claude-mythos-5-1
The inherent streaming methods transform their buffer in place, which is what the stream-cipher traits call `do_*_inplace`; `do_*_update` read as the out-of-place form the AEAD traits provide. Assisted-by: Claude:claude-mythos-5-1
…s crate-private
`AsconAead128<Dir>` and its constructors, one-shots and finals are no
longer exported: everything they offered is on `AsconAead128Encryptor` /
`AsconAead128Decryptor` through the AEAD and symmetric-cipher traits,
including the caller-supplied nonce (`do_encrypt_init_nonce`,
`encrypt_with_aad_nonce_out`). The one thing the traits lack, in-place
streaming, stays as `do_encrypt_inplace` / `do_decrypt_inplace` on the
wrappers; the decryptor's keeps the same hold-back as `do_decrypt_out`, so
the two interleave and either final can follow.
`SuspendableKeyed` moves onto the wrappers: the encryptor's state is the
cipher's 46 bytes as before, the decryptor's adds the held-back bytes and
their count (`SUSPENDED_ASCON_AEAD128_{ENCRYPTOR,DECRYPTOR}_STATE_LEN`).
The CLI's explicit-nonce path and the tests go through the pair; the
CLI reproduces the embedded KAT tag under a supplied nonce.
Assisted-by: Claude:claude-mythos-5-1
…Dir> is a plain alias The two wrapper structs fold into the cipher type: the AEAD and symmetric-cipher trait impls, the in-place pair and `SuspendableKeyed` are written on `AsconAEAD128<Encrypting>` / `AsconAEAD128<Decrypting>` directly, and `Ascon_AEAD128<Dir>` aliases it the way `AES_GCM_128<Dir>` aliases `Gcm`, rather than projecting through `Direction::Select`. The private core methods take names that do not collide with the trait methods (`absorb_aad`, `encrypt_bytes`, `finish_tag`, `decrypt_bytes`, `verify_tag`). The decrypting side's held-back bytes live in the struct for both directions, unused when encrypting, so both are 96 bytes in memory; the suspended layouts and their two length constants are unchanged. Assisted-by: Claude:claude-mythos-5-1
The cipher type takes the spec spelling directly, `Ascon_AEAD128<Dir>`, in place of `AsconAEAD128<Dir>` plus an alias to it; the alias's usage example moves onto the struct. Assisted-by: Claude:claude-mythos-5-1
Assisted-by: Claude:claude-mythos-5-1
The CCM packet decryptor's streaming method transforms its buffer in place, which is what the stream-cipher traits and Ascon call `do_*_inplace`; `do_decrypt_update` read as the out-of-place form the AEAD traits provide. Two labels that named a `do_encrypt_update` which never existed now name `do_encrypt`. Assisted-by: Claude:claude-mythos-5-1
Assisted-by: Claude:claude-mythos-5-1
Assisted-by: Claude:claude-mythos-5-1
This branch has not been deployed
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.
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 releasebranch, and adds the SHA-512/t work on top.
feature/simple-cipherswas built by branching fromrelease/0.1.3alphaand mergingfeature/stream-cipherthenfeature/symmetric-cipher; both merges fast-forwarded, so thecontent 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_bytesbecomeconst fn(3912434) — twokeywords, 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 everytFIPS 180-4 s. 5.3.6 defines a hash for (785dbef).Previously only
T = 224andT = 256had parameter impls, so nothing else could be named.sha512t_h0to100 <= t < 512and emitted a fixed three digits, since only 224 and 256 were reachable. Witharbitrary
treachable that would produce the"0256"spelling s. 5.3.6 explicitly forbids —and hence the wrong IV — for every
tbelow 100. The one- and two-digit branches are restoredand
check_tasserts the section's own rule: positive,< 512, not 384.tmust be a multiple of 8, becauseHashis byte-oriented anda 100-bit digest has no representation here. BC Java's
SHA512tDigestimposes the identicalrestriction, so the two libraries accept the same set of truncations.
ElectronicCodeBook::ENCRYPTION_APPROVEDgatestwo-key TDEA:
SHA512tParams::<T>::FIPS_APPROVEDis public andSHA512Internal::newasserts itin an inline
const, so an unapprovedtis a compile error at the call site andnew_allow_unapproved_t()is the deliberate way in. That also blocksDefault, which keeps anunapproved truncation out of generic code by accident.
ALG_NAME,OUTPUT_LENandMAX_SECURITY_STRENGTHare derived fromt, withconstassertions pinning them to the values 224 and 256 previously had by hand.
Verification
cargo test --workspace: 943 passed, 0 failed (was 923).cargo fmt --checkclean; no newclippy warnings. Both new commits build independently.
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 mutantson 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,majanddo_final_internal; no new missed mutants.Note for reviewers
Adding
constto a publiccorefunction is a forward compatibility commitment, andSHA512tParamsis currently its only caller. The alternative was a private copy of the roundingladder inside
sha2, free to drift from the real one — happy to switch if the API-surface cost isthe greater worry.
🤖 Generated with Claude Code