Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
261 commits
Select commit Hold shift + click to select a range
f56802e
padding: add Padding trait and bouncycastle-padding (PKCS7, PaddedEnc…
dghgit Sep 6, 2026
78a4021
core, modes, aes-lowmemory: in-place block cipher API with compile-ti…
dghgit Sep 6, 2026
c5f60fb
modes: add AES CFB128 mode with AES_CFB_* aliases, aes*-cfb CLI subco…
dghgit Sep 6, 2026
2c0567e
core: ElectronicCodeBook (was BlockPermutation), slice block hooks, b…
dghgit Sep 6, 2026
157b1c8
modes: add Ecb (SP 800-38A Sec 6.1) with AES_ECB_* aliases and aes*-e…
dghgit Sep 6, 2026
f6cb787
padding: add NoPadding (errors when asked to pad) with Padding::ALWAY…
dghgit Sep 6, 2026
a1c4e41
skills: add commit-range-report, a Markdown report of a commit range …
dghgit Sep 6, 2026
9c65521
mldsa, mlkem: replace the const-generic turbofish with sealed MLDSAPa…
ounsworth Sep 7, 2026
57dd3d0
core: replace StreamCipher with the split StreamCipherEncryptor / Str…
dghgit Sep 6, 2026
97ac6e3
modes: Cfb becomes a stream cipher taking any length with no padding,…
dghgit Sep 6, 2026
5c73617
release notes: CFB becomes a stream cipher with a short final segment…
dghgit Sep 6, 2026
e2b534d
modes: pin the single-call vs chunked equivalence of Cfb and Cfb8 aga…
dghgit Sep 6, 2026
f72bfe6
modes: add Ctr (SP 800-38A Sec 6.5), a stream cipher whose nonce leng…
dghgit Sep 6, 2026
0404ab9
modes: cross-check Ctr against BC Java's SICBlockCipher, which shares…
dghgit Sep 6, 2026
921e2b5
sha2: partial-bit messages, compile-time IVs, CAVP SHAVS tests (PR #88)
dghgit Sep 6, 2026
7b4e7fc
sha3: partial-byte fixes, CAVP SHA3VS tests, mem-usage bench, release…
dghgit Sep 6, 2026
c34c2f9
sha2, hmac: add SHA-512/224 and SHA-512/256 (FIPS 180-4 s. 5.3.6) and…
dghgit Sep 6, 2026
7df74a6
rng: use core::fmt in hash_drbg80090a.rs; the only part of PRs #92-#9…
dghgit Sep 6, 2026
ac896e2
sm3: add bouncycastle-sm3 (GB/T 32905-2016) and HMAC-SM3 with factory…
dghgit Sep 6, 2026
f34858d
Partial bytes follow ASN.1 BIT STRING order (X.690 s. 8.6.2): message…
dghgit Sep 6, 2026
46e2e79
release notes: SM3 partial bytes follow the ASN.1 BIT STRING order li…
dghgit Sep 6, 2026
607cfa7
sha2, sm3: document the surviving cargo-mutants equivalences at their…
dghgit Sep 6, 2026
4ca1274
core: split BlockCipher into block-aligned BlockCipherEncryptor/Decry…
dghgit Sep 6, 2026
a9627f6
aes-lowmemory: add bouncycastle-aes-lowmemory, a constant-time, table…
dghgit Sep 6, 2026
f403921
modes: add BlockPermutation trait, bouncycastle-modes with AES CBC, a…
dghgit Sep 6, 2026
e018929
padding: add Padding trait and bouncycastle-padding (PKCS7, PaddedEnc…
dghgit Sep 6, 2026
17372c9
core, modes, aes-lowmemory: in-place block cipher API with compile-ti…
dghgit Sep 6, 2026
d1bee58
modes: add AES CFB128 mode with AES_CFB_* aliases, aes*-cfb CLI subco…
dghgit Sep 6, 2026
ca53601
core: ElectronicCodeBook (was BlockPermutation), slice block hooks, b…
dghgit Sep 6, 2026
891669b
modes: add Ecb (SP 800-38A Sec 6.1) with AES_ECB_* aliases and aes*-e…
dghgit Sep 6, 2026
45941d1
padding: add NoPadding (errors when asked to pad) with Padding::ALWAY…
dghgit Sep 6, 2026
74e0100
skills: add commit-range-report, a Markdown report of a commit range …
dghgit Sep 6, 2026
37d0b3b
core: replace StreamCipher with the split StreamCipherEncryptor / Str…
dghgit Sep 6, 2026
c158860
modes: Cfb becomes a stream cipher taking any length with no padding,…
dghgit Sep 6, 2026
8c7ec71
release notes: CFB becomes a stream cipher with a short final segment…
dghgit Sep 6, 2026
9c1b9b7
modes: pin the single-call vs chunked equivalence of Cfb and Cfb8 aga…
dghgit Sep 6, 2026
5cec55d
modes: add Ctr (SP 800-38A Sec 6.5), a stream cipher whose nonce leng…
dghgit Sep 6, 2026
4adbebb
modes: cross-check Ctr against BC Java's SICBlockCipher, which shares…
dghgit Sep 6, 2026
0b06214
aes-lowmemory: the AES_CBC_* and AES_ECB_* aliases take a padding sch…
dghgit Sep 6, 2026
5e43a9d
core: stream ciphers also implement SymmetricCipherEncryptor / Symmet…
dghgit Sep 7, 2026
fe5c291
core: delete the SymmetricCipher trait and move its four one-shots on…
dghgit Sep 7, 2026
0986629
aes: rename bouncycastle-aes-lowmemory to bouncycastle-aes
dghgit Sep 7, 2026
fed518b
aes: drop Block, PaddedMode and the AesParams types from the public API
dghgit Sep 7, 2026
8f932ca
aes: the ElectronicCodeBook trait is the only public route to the per…
dghgit Sep 7, 2026
41ce203
aes: the permutation types keep the spec's capitalisation, AES / AES_…
dghgit Sep 9, 2026
d98f703
core: ElectronicCodeBook's pair methods are encrypt_2blocks / decrypt…
dghgit Sep 9, 2026
2845101
aes: cipher2 / inv_cipher2 after FIPS 197's CIPHER() and INVCIPHER(),…
dghgit Sep 9, 2026
69cfe5b
core: ElectronicCodeBook's eight-block methods are encrypt_8blocks / …
dghgit Sep 9, 2026
ab7b948
core: ElectronicCodeBook batches four blocks, encrypt_4blocks / decry…
dghgit Sep 9, 2026
c534f3b
release notes: the block-cipher trait section names the four-block me…
dghgit Sep 9, 2026
16552e9
core: SymmetricCipherEncryptor / SymmetricCipherDecryptor are SimpleC…
dghgit Sep 9, 2026
4c7eec7
gitignore: ignore editor swap and backup files, and drop the .fred.sw…
dghgit Sep 9, 2026
4bac3b3
Reverting the SKILL.md changes about producing a report since this se…
ounsworth Sep 9, 2026
fc2fcb7
Merge branch 'feature/stream-cipher' of git.bouncycastle.org:bc-rust …
ounsworth Sep 9, 2026
d66cd0b
Restructured the mem_usage_benchmarks sub-crate
ounsworth Sep 9, 2026
dc248f9
Reverting the SKILL.md changes about producing a report since this se…
ounsworth Sep 9, 2026
7539532
Moves sha512t_h0 tests out of unit tests and into integration tests. …
ounsworth Sep 9, 2026
b0bd491
rename sha2/tests/cavc_tests.rs to bc-test-data.rs to match other crates
ounsworth Sep 9, 2026
097c09b
Renaming / readability of some of the SHA2 internal traits.
ounsworth Sep 9, 2026
55f53f7
mem_usage_benches: fence the valgrind and ms_print snippets as text, …
dghgit Sep 9, 2026
0156990
sha2: the partial-byte example's three bits are message bits, not pad…
dghgit Sep 9, 2026
213473c
sha2: quote the SHA-512/t IV Generation Function as FIPS 180-4 s. 5.3…
dghgit Sep 9, 2026
5fc1370
CLAUDE.md: the build and test gates need --workspace, the mem_usage_b…
dghgit Sep 9, 2026
b11f8f6
sha2: sha512t_h0 asserts three-digit t and formats it as three digits…
dghgit Sep 9, 2026
5825050
Removing summary.md files
ounsworth Sep 12, 2026
0cc2799
minor tweaks to sha2
ounsworth Sep 12, 2026
b282942
Gave a massive hair-cut to Claude's massive release note
ounsworth Sep 12, 2026
8b48d93
Rename sha3/tasts/cavp_tests.rs to bc-test-data.rs for consistency wi…
ounsworth Sep 12, 2026
6cc74c2
small tweaks to sm3
ounsworth Sep 12, 2026
0558f26
doc change to the mem bench scripts
ounsworth Sep 12, 2026
b77f8a4
sha2: the SHA-224/256 message limit is 2^61 bytes rather than the 2^6…
dghgit Sep 13, 2026
cb0429c
sm3: the message limit is 2^61 bytes, GB/T 32905-2016 s. 5.1 allowing…
dghgit Sep 13, 2026
9c9861c
CLAUDE.md: add a scope-of-changes section, since an unrequested refac…
dghgit Sep 13, 2026
21b375c
Merge release/0.1.3alpha: HMAC and HKDF become generic utility crates…
dghgit Sep 13, 2026
91b3054
sm3: reinstate HMAC-SM3 under the per-crate layout the merge introduc…
dghgit Sep 13, 2026
3b8da02
Merge feature/stream-cipher: the HMAC and HKDF rework reaches this br…
dghgit Sep 13, 2026
3912434
core: SecurityStrength::from_bits and from_bytes become const fn, so …
dghgit Sep 16, 2026
785dbef
sha2: SHA512t becomes usable for every t FIPS 180-4 s. 5.3.6 defines …
dghgit Sep 16, 2026
4053f21
core, sha3: XOF extends Hash, so SHAKE128 and SHAKE256 are hashes; sq…
dghgit Sep 7, 2026
86819d7
sha3: pin the SHAKE block_bitlen and output_len values, which three m…
dghgit Sep 7, 2026
24ae9b4
core: XofOutput gains do_final and do_final_out, matching BC Java's d…
dghgit Sep 7, 2026
517cd59
sha3: add cSHAKE128 and cSHAKE256 (SP 800-185 Sec 3) with the Sec 2.3…
dghgit Sep 7, 2026
61d3d8e
docs: record the cargo mutants scoping flags, the bc-test-data conven…
dghgit Sep 7, 2026
63ca433
sha3: add KMAC128 and KMAC256 (SP 800-185 Sec 4) with KMACXOF, MACFac…
dghgit Sep 7, 2026
3adbfc1
core: drop the Default supertrait from Hash, so keyed constructions c…
dghgit Sep 7, 2026
b1fff3c
sha3: KMACXOF128 and KMACXOF256 as keyed XOFs, now that Hash no longe…
dghgit Sep 7, 2026
9efbf5f
core-test-framework: the XOF suite takes a constructor closure, so ke…
dghgit Sep 7, 2026
3913b55
sha3: add TupleHash and TupleHashXOF (SP 800-185 Sec 5), where each u…
dghgit Sep 7, 2026
90bd179
sha3: add ParallelHash and ParallelHashXOF (SP 800-185 Sec 6), comple…
dghgit Sep 7, 2026
5c6302a
cli: add tuplehash and parallelhash subcommands, completing SP 800-18…
dghgit Sep 7, 2026
68a3dbc
sha3: pin the Hash and XOF trait views of TupleHash, ParallelHash and…
dghgit Sep 7, 2026
50c125b
factory: replace the todo stub in xof_factory_tests with a differenti…
dghgit Sep 7, 2026
b95dd0c
core: Hash gains Clone as a supertrait, so a hash mid-stream can be f…
dghgit Sep 9, 2026
6707002
core: XOF gains default hash_xof and hash_xof_out bodies so only SHAK…
dghgit Sep 10, 2026
b466d95
core-test-framework: add test_hash_output_buffers, a closure-built Ha…
dghgit Sep 10, 2026
0e8b2f7
sha3: TupleHash and ParallelHash panicked on an output buffer shorter…
dghgit Sep 10, 2026
ad3fa52
core: drop XOFOutput::do_final and do_final_out, which no implementor…
dghgit Sep 10, 2026
8810ae7
core, core-test-framework, sha3, factory, mldsa, mlkem, cli: rename t…
dghgit Sep 14, 2026
0a2bb8f
core, core-test-framework, sha3: a final read of a XOF binds its outp…
dghgit Sep 14, 2026
8a46683
CLAUDE.md: record the cargo mutants mechanics this repo needs, since …
dghgit Sep 14, 2026
b5fcf99
core, core-test-framework: AEADCipherEncryptor/AEADCipherDecryptor ga…
officialfrancismendoza Sep 9, 2026
120b2fe
ascon, cli: add bouncycastle-ascon (SP 800-232 Ascon-AEAD128/Hash256/…
officialfrancismendoza Sep 9, 2026
2c479f4
Rebased #120 onto #118. Ported ASCON XOF/CXOF to new Hash/XOF/XOFSque…
officialfrancismendoza Sep 17, 2026
465e684
Minor doc fix to lib.rs given new XOF api (#119)
officialfrancismendoza Sep 17, 2026
7d8165b
sha2: SHA512t drops its FIPS-approval gate, per review on #133 -- SHA…
dghgit Sep 18, 2026
8e84dee
hmac: drop the stale dev-dependency comment block from Cargo.toml, wh…
dghgit Sep 18, 2026
386bbe3
Remediated documentation and test concerns (#119)
officialfrancismendoza Sep 18, 2026
61a0623
Merge remote-tracking branch 'origin/feature/simple-ciphers' into fea…
dghgit Sep 19, 2026
0161af2
Merge remote-tracking branch 'origin/release/0.1.3alpha' into feature…
dghgit Sep 19, 2026
76bb967
Merge remote-tracking branch 'origin/feature/simple-ciphers' into fea…
dghgit Sep 19, 2026
f28c388
Minor adjustment to the SHA512t docs.
ounsworth Sep 19, 2026
d64ed7c
sha2: address ounsworth's SHA512t re-review comments on #133 (SHA-384…
dghgit Sep 19, 2026
e59229d
Merge remote-tracking branch 'origin/feature/simple-ciphers' into fea…
dghgit Sep 19, 2026
631282c
Tweaks to docs for the new symmetric cipher traits.
ounsworth Sep 20, 2026
33576fc
modes: StreamCipherEncryptor::do_encrypt/encrypt/encrypt_rng and Stre…
dghgit Sep 20, 2026
86b2ed0
modes: BlockCipherEncryptor::do_encrypt_blocks/do_encrypt/encrypt/enc…
dghgit Sep 20, 2026
8beef64
core, padding: rename the trait bouncycastle_core::traits::Padding to…
dghgit Sep 20, 2026
4568928
Merge remote-tracking branch 'origin/feature/simple-ciphers' into fea…
dghgit Sep 20, 2026
3d265ad
Merge remote-tracking branch 'origin/feature/xof-cshake' into feature…
dghgit Sep 20, 2026
6d849a1
cli, ascon: document the generated-nonce stream layout and the 8 MiB …
dghgit Sep 20, 2026
bbc04e3
release notes: the current bouncycastle-ascon mutation figures (#119)
dghgit Sep 20, 2026
2f7c32a
core, core-test-framework, ascon: delete the AEADCipher trait, supers…
dghgit Sep 20, 2026
80098c4
release notes: record the AEADCipher removal and re-measure the mutat…
dghgit Sep 20, 2026
702246a
core, core-test-framework, ascon, cli: carry the inline ciphertext||t…
dghgit Sep 20, 2026
c8190be
release notes: re-measure bouncycastle-ascon after the AEAD trait cha…
dghgit Sep 20, 2026
f376c14
core, core-test-framework: close the mutation gaps a scoped run found…
dghgit Sep 20, 2026
a1468a9
release notes: record the scoped mutation figures for the AEAD trait …
dghgit Sep 20, 2026
7357e86
core, modes, aes, padding: rename SimpleCipherEncryptor / SimpleCiphe…
dghgit Sep 21, 2026
f99bf72
core, padding, modes: rename SymmetricCipherError::IncorrectOutputBuf…
dghgit Sep 21, 2026
8a13369
Merge branch 'feature/simple-ciphers' into feature/xof-cshake
dghgit Sep 21, 2026
ac72292
Merge branch 'feature/xof-cshake' into feature/officialfrancismendoza…
dghgit Sep 21, 2026
62e6a2b
docs: fix contributing typos
officialfrancismendoza Sep 21, 2026
7535274
Re-adding the changes I had committed on this branch a few days ago, …
ounsworth Sep 22, 2026
dcec6b8
Some docs tweaks
ounsworth Sep 22, 2026
df43a87
aes, core: restore the FIPS 197 Appendix B known-answer values in the…
dghgit Sep 22, 2026
ed09ae0
Merge branch 'feature/simple-ciphers' into feature/xof-cshake
dghgit Sep 22, 2026
e18dd46
core, modes, aes, core-test-framework: make do_encrypt_init_rng panic…
dghgit Sep 22, 2026
cf78449
Merge branch 'feature/simple-ciphers' into feature/xof-cshake
dghgit Sep 22, 2026
336f9cb
core, core-test-framework, ascon, cli: make AEADCipherEncryptor/AEADC…
dghgit Sep 24, 2026
2eb7a99
ascon: add Ascon_AEAD128<Dir>, naming the AEAD pair by direction
dghgit Sep 24, 2026
c89663a
Merge remote-tracking branch 'origin/feature/xof-cshake' into trial/c…
dghgit Sep 24, 2026
570ae03
Initial add of AES lightweight CCM mode (#125)
officialfrancismendoza Sep 10, 2026
5d5cf5c
core, modes: document why AEADCipherEncryptor/Decryptor were not resh…
officialfrancismendoza Sep 14, 2026
3dd3266
cli: --nonce-file for CCM reads raw bytes only, never hex-decodes
officialfrancismendoza Sep 15, 2026
3be43fb
modes, core: zeroize CCM's CBC-MAC state, and make BUFFER_LEN vs the …
officialfrancismendoza Sep 15, 2026
e95a25b
modes: batch CCM's CTR half, and fix docs that claimed it was impossible
officialfrancismendoza Sep 15, 2026
9f437ab
cli: stop BlockModeAction's shared help from describing behaviour CCM…
officialfrancismendoza Sep 15, 2026
4282833
cli: process CCM input in place instead of allocating a second buffer
officialfrancismendoza Sep 15, 2026
ac13ce0
modes: dedupe CcmEncryptor/CcmDecryptor over a shared CcmBuffer, drop…
officialfrancismendoza Sep 15, 2026
e877a32
modes: add a Wycheproof AES-CCM suite, move/drop CCM unit tests that …
officialfrancismendoza Sep 15, 2026
1b593c5
modes: close the mutation-testing gaps the batching and buffer-bounda…
officialfrancismendoza Sep 15, 2026
afa2b3c
modes: adapt CCM buffer errors to the #120 API
officialfrancismendoza Sep 21, 2026
8a24373
Fixed formatting with cargo fmt (#125)
officialfrancismendoza Sep 21, 2026
24a646c
Remediated concerns. F1-F10 fixed except F9 (optional), which was lef…
officialfrancismendoza Sep 23, 2026
b8a217f
Style / docs refactors: renamed AES, AES_128, AES_192, AES_256 to AES…
ounsworth Sep 24, 2026
67a7b45
modes, aes, core-test-framework: port CcmEncryptor/CcmDecryptor to th…
dghgit Sep 24, 2026
7a6e2a4
Initial add of AES lightengine GCM mode (#124)
officialfrancismendoza Sep 14, 2026
6bd4ed7
modes, aes, cli: follow the base branch's API renames in AES-GCM (#124)
dghgit Sep 24, 2026
788fd06
modes, aes, cli: implement AEADCipherEncryptor/AEADCipherDecryptor fo…
dghgit Sep 24, 2026
9da20d3
cli, modes, mem_usage_benches, aes: finish the AES_128 / AES_192 / AE…
ounsworth Sep 24, 2026
334cd2b
core, aes, modes, core-test-framework: make ElectronicCodeBook's encr…
dghgit Sep 25, 2026
15c2fa5
Merge branch 'feature/simple-ciphers' into feature/xof-cshake
dghgit Sep 25, 2026
52e63bc
Merge branch 'feature/xof-cshake' into feature/officialfrancismendoza…
dghgit Sep 25, 2026
e691aed
Merge the updated CCM branch into feature/officialfrancismendoza/124-…
dghgit Sep 25, 2026
127dddf
* BIG CHANGE: refactored this from Pornin's 32-bit bitsliced impl to …
ounsworth Sep 25, 2026
a559934
Applied skills/memory-hygiene-in-rust/SKILL.md and shaved the AES imp…
ounsworth Sep 25, 2026
a57d7dd
Applied skills/memory-hygiene-in-rust/SKILL.md and shaved the AES imp…
ounsworth Sep 25, 2026
627f619
docs tweaks
ounsworth Sep 26, 2026
8823c7b
Refactor core: removed SecurityStrength and impls from traits.rs
ounsworth Sep 26, 2026
7002d4a
core: fix the three do_hazardous_operations doctests broken by 8823c7…
dghgit Sep 26, 2026
a06b83a
Merge PR #137 (secbug/mldsa87_wycheproof: ML-DSA missing reduce32 lea…
dghgit Sep 26, 2026
77edc43
Merge branch 'feature/simple-ciphers' into feature/xof-cshake
dghgit Sep 26, 2026
d05e50e
Merge remote-tracking branch 'bcgit/feature/xof-cshake' into feature/…
officialfrancismendoza Sep 27, 2026
dd4e5f6
Merge remote-tracking branch 'origin/feature/officialfrancismendoza/1…
officialfrancismendoza Sep 27, 2026
2161a04
Fix batched keystream left on stack (#125)
officialfrancismendoza Sep 27, 2026
16a4ba5
Merge remote-tracking branch 'bcgit/feature/xof-cshake' into feature/…
officialfrancismendoza Sep 27, 2026
8e23ced
Merge the CCM branch (2161a04) into feature/officialfrancismendoza/12…
dghgit Sep 27, 2026
985eb94
modes: zeroize CTR's batched and single-block keystream, as 2161a04 d…
dghgit Sep 27, 2026
6a061ed
modes: CCM review fixes -- decryptor nonce floor, one error variant f…
dghgit Sep 27, 2026
f527ac9
aes: AES_CCM_*_Encryptor docs -- the nonce floor applies to the decry…
dghgit Sep 27, 2026
5de0f7d
cli: aes*-ccm -- warn on a nonce file ending in a newline, and explai…
dghgit Sep 27, 2026
30b871b
mem_usage_benches: make the CCM harness measure the streaming path it…
dghgit Sep 27, 2026
68a8934
aes: drop the redundant explicit link targets in the CCM module docs
dghgit Sep 27, 2026
174563c
mem_usage_benches: state the CCM streaming figures against the baseli…
dghgit Sep 27, 2026
62afc19
Intermediate add for CI fix changes
officialfrancismendoza Sep 27, 2026
2c32883
Merge remote-tracking branch 'origin/feature/officialfrancismendoza/1…
officialfrancismendoza Sep 27, 2026
3cee19b
Remove .claude/settings.json (#124)
dghgit Sep 27, 2026
2ed6768
modes: update the crate docs for GCM (#124)
dghgit Sep 27, 2026
01d725e
modes: keep GCM's H, tag mask and computed tag out of unzeroized stac…
dghgit Sep 27, 2026
117f06b
cli: --aad-file for GCM reads raw bytes only, never hex-decodes (#124)
dghgit Sep 27, 2026
f8f7a2e
modes: Ctr keeps its keystream out of unzeroized stack arrays, refill…
dghgit Sep 27, 2026
8575ea7
Merge branch 'feature/simple-ciphers' into feature/xof-cshake
dghgit Sep 27, 2026
7e83f10
Merge remote-tracking branch 'origin/feature/xof-cshake' into feature…
dghgit Sep 27, 2026
840bf42
Merge remote-tracking branch 'origin/feature/xof-cshake' into feature…
dghgit Sep 27, 2026
7aa826d
Merge the CCM branch (840bf42) into feature/officialfrancismendoza/12…
dghgit Sep 27, 2026
013d806
Aesthetic changes to padded_block_cipher
ounsworth Sep 27, 2026
3d7c5a7
Removed an uncessary turbofish from test code
ounsworth Sep 27, 2026
3ecabfd
Merge PR #126 (feature/officialfrancismendoza/125-AES-lightengine-CCM…
dghgit Sep 28, 2026
f8400c3
Merge PR #132 (feature/officialfrancismendoza/124-AES-lightengine-GCM…
dghgit Sep 28, 2026
6705a3f
Merge branch 'feature/xof-cshake' into feature/simple-ciphers
dghgit Sep 28, 2026
793c7f1
docs tweaks to modes
ounsworth Sep 28, 2026
1689005
modes, padding, core: follow-ups to 793c7f1's modes docs restructure …
dghgit Sep 28, 2026
f62f107
Restructuring of the cipher modes docs
ounsworth Sep 28, 2026
67a6f65
modes: Ccm's inherent one-shots take the library's _out names -- encr…
dghgit Sep 28, 2026
2d4d038
modes: fix the two doctests f62f107 left failing -- cbc.rs's streamin…
dghgit Sep 28, 2026
5946992
gitignore: stop un-ignoring .claude/settings.json, so a contributor's…
dghgit Sep 28, 2026
eaff5a5
Renaming the acvp_gcm helper file to indicate that it's a helper.
ounsworth Sep 28, 2026
085d1d9
Adding tests for ccm mode, specifically one that demonstrates that th…
ounsworth Sep 28, 2026
baf16b9
Adding tests for ccm mode, specifically one that demonstrates that th…
ounsworth Sep 28, 2026
9d7b354
Renamed SymmetricCipher from do_update to do_encrypt / do_decrypt.
ounsworth Sep 28, 2026
603d1cd
core, core-test-framework, modes: rename BlockCipherEncryptor::encryp…
dghgit Sep 28, 2026
bd6b8c1
core, core-test-framework, modes, aes, cli, mem_usage_benches: Stream…
dghgit Sep 28, 2026
d32af54
cli: aes{128,192,256}-ccm take --aad-file, raw bytes and never hex-de…
dghgit Sep 28, 2026
93eb292
modes: remove test_large_payload_symmetric_cipher, which still fails …
dghgit Sep 29, 2026
0fb4e79
modes: pin CCM_MAX_BUFFER_LEN at 512 KiB and CcmKeyStream's absolute …
dghgit Sep 29, 2026
ee3d2f3
Did a pass over CFB and CFB8 docs.
ounsworth Sep 29, 2026
d48d2dd
Tweaked docs for gcm
ounsworth Sep 29, 2026
1cbc22e
Refactored the cli helpers into a helpers/ submod
ounsworth Sep 30, 2026
1791f3c
Added a release note about MLDSA / MLKEM memory optimization
ounsworth Sep 30, 2026
641ac54
Docs update to ctr mode
ounsworth Sep 30, 2026
4fd492b
Removed the AES dependency from the core (non-vector-based) modes tes…
ounsworth Sep 30, 2026
f71c2f4
Fable de-duplicated the AES vector tests
ounsworth Sep 30, 2026
941743b
Refactored to move all AES tests out of the modes crate into the aes …
ounsworth Sep 30, 2026
50f5505
Split the AEAD and block-cipher runners out of core-test-framework's …
ounsworth Sep 30, 2026
dc6f5af
Tweaked docs for AES_CBC
ounsworth Sep 30, 2026
64f3923
ascon: seal the direction projection and trim the public API
dghgit Sep 30, 2026
3d01899
Merge PR #131 (utils ct: volatile optimisation barrier for Condition …
ounsworth Sep 30, 2026
5d38f54
hex: decode_out no longer indexes past the end of an input ending in …
ounsworth Oct 1, 2026
af10fde
Merge branch 'feature/simple-ciphers' of git.bouncycastle.org:bc-rust…
ounsworth Oct 1, 2026
ed341fb
cli: rng no longer appends a newline to binary output -- `rng --len N…
ounsworth Oct 1, 2026
26af712
Converted cli/tests to be bash tests. Written entirely by claude/fabl…
ounsworth Oct 1, 2026
3e2a6b9
aes docs tweaks
ounsworth Oct 1, 2026
9219216
QUALITY_AND_STYLE: add Docs "Proportion" and "Release Notes" rules, w…
dghgit Oct 1, 2026
037c8f5
hazmat: a path-based notice for the raw primitives (#156)
dghgit Oct 1, 2026
160ac18
aes: project the padded aliases through core's sealed Direction::Select
dghgit Oct 1, 2026
fa3186d
Swapped around the AES_CCM convenience types to remove direction and …
ounsworth Oct 1, 2026
8dff255
BIG REFACTOR: folded crates bouncycastle-modes and bouncycastle-paddi…
ounsworth Oct 1, 2026
a27d9e6
cipher: move StreamCipher and the direction markers out of core
ounsworth Oct 1, 2026
7f985aa
Adding wycheproof test harnesses for AES_CBC and AES_GCM
ounsworth Oct 2, 2026
4c8179a
aes, cipher: doc fixes from the house-rules review, and the AESIntern…
ounsworth Oct 2, 2026
5ee8db0
utils, core: move suspendable_state out of core and into bouncycastle…
ounsworth Oct 2, 2026
28f6e34
Implemented SuspendableKeyed for AES
ounsworth Oct 2, 2026
71d1ae2
core, cipher, aes, ascon: put `_out` last in the AEAD one-shot and fi…
ounsworth Oct 2, 2026
67e6ac3
cipher, aes: suspend-and-resume round-trip tests for every mode, adap…
ounsworth Oct 2, 2026
ae09850
cipher, aes, core: CCM's trait adapters stream a fixed-length frame i…
ounsworth Oct 2, 2026
1b70479
Merge branch 'feature/simple-ciphers' of git.bouncycastle.org:bc-rust…
ounsworth Oct 2, 2026
ca569ef
Adjusted header comment on hazmat mods
ounsworth Oct 2, 2026
bbbf333
Renamed AEADEncrypted to AEADEncryptedTuple
ounsworth Oct 2, 2026
85e39d4
Docs updates to core::traits::XOF, and updated the Security Considera…
ounsworth Oct 2, 2026
e54111c
tweaked release notes
ounsworth Oct 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
Cargo.lock
**/target
mutants.out*/
custom_mutants_output/


.idea/
.vscode/

# editor swap / backup files
*.swp
*.swo
*~

# Claude Code: ignore personal/local state, but share team tooling
# (skills, slash commands and subagents). settings.json stays local, so personal permission
# allowlists cannot ride along in a PR.
.claude/*
!.claude/skills/
!.claude/commands/
!.claude/agents/
.claude/settings.local.json
.claude 2/
84 changes: 69 additions & 15 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ previous session's reading of them.

- **[QUALITY_AND_STYLE.md](QUALITY_AND_STYLE.md) — read before writing or changing code, and before reviewing a
diff.** The authority on architecture, crate and API shape, naming conventions, fallibility, macros, what tests and
benchmarks a crate owes, and which sections crate docs must have. Its own opening line invites an AI to review a PR
against it, so treat it as exactly that checklist.
benchmarks a crate owes, which sections crate docs must have, and how much they should say. Its own opening line
invites an AI to review a PR against it, so treat it as exactly that checklist.
- **[CONTRIBUTING.md](CONTRIBUTING.md) — read before writing a commit message, opening a PR, or advising on how a
change gets merged.** The authority on coding philosophy, PR hygiene and self-review, the quality bar a submission
must clear to be accepted, how merges actually happen in this project, and the AI policy. That policy places
Expand All @@ -26,19 +26,39 @@ previous session's reading of them.
Where this file and one of those documents disagree, the document wins — and say so, so the stale line here gets
fixed.

## Project status: ALPHA

The library is pre-1.0 alpha (workspace version `0.1.x`, release branches named `release/<ver>alpha`) and has no
users to protect yet. Until the first stable release:

- **Breaking changes are fine.** Public API shape, trait signatures, crate layout and encodings may change in any
PR without deprecation cycles, compatibility shims, or migration notes. Prefer the right design over continuity.
- **Security bugs are ordinary bugs.** Fix them on a normal branch and PR, with a regression test and a plain
description of the defect and its impact. No security advisory, CVE, embargo, or coordinated release is needed.
SECURITY.md's reporting address still applies to reports from outside the project.

Revisit this section at the first non-alpha release.

## Toolchain

- Uses Rust **nightly** (pinned in `rust-toolchain.toml`) — `core/src/lib.rs` uses `#![feature(adt_const_params)]`.
- Builds on Rust **stable**: there is no toolchain pin, and no crate enables a `#![feature(...)]` gate, so
nightly-only tooling (`-Z` flags and the like) is not available. CI builds, tests and docs on stable; only the
`rustfmt` job installs nightly.
- 2024 edition (set workspace-wide in the root `Cargo.toml`).
- Minimum Rust is 1.88: `rust-version` in the root `Cargo.toml`, inherited by `bouncycastle-utils` (the crate that
needs it, for `slice::as_chunks`) and so enforced for every crate that depends on it.

## Common commands

Build / test / bench / docs run against the cargo workspace from the repo root:
Build / test / bench / docs run against the cargo workspace from the repo root. `--workspace` is
not optional: the root manifest is both the workspace and the umbrella `bouncycastle` package, so a
bare `cargo build` builds only that package (no `cli`, no benches) and a bare `cargo test` runs
**zero** tests and still exits 0, because the umbrella crate has none of its own.

```
cargo build # whole workspace incl. `bc-rust` CLI binary
cargo build --workspace # whole workspace incl. `bc-rust` CLI binary
cargo build -p bouncycastle-sha3 # one sub-crate
cargo test # all tests
cargo test --workspace # all tests
cargo test -p bouncycastle-mlkem # tests for one crate
cargo test -p bouncycastle-mlkem ml_kem_tests # one integration test file
cargo bench --all # all criterion benches
Expand All @@ -51,22 +71,34 @@ Quality / mutation testing:

```
./dev_scripts/quality_stats.sh ./crypto # lines-of-code, docstring & fallibility metrics; CI publishes this
cargo mutants # config in .cargo/mutants.toml (output: custom_mutants_output/)
cargo mutants -p bouncycastle-sha3 # config in .cargo/mutants.toml (output: custom_mutants_output/)
```

Stack-memory benches are separate binaries under `mem_usage_benches/`:
`-p` is as non-optional here as `--workspace` is for build and test, and for the same reason: a bare
`cargo mutants` examines only the root `bouncycastle` package, whose single `src/lib.rs` yields no
mutants, so it prints "No mutants found under the active filters" and exits **0**. See
[the mutation-testing mechanics](#notes-on-testing) for scoping a run to one file, for crates whose
tests live elsewhere, and for the test-data symlink.

Stack-memory benches are separate binaries under `mem_usage_benches/src/`, each declared as a
`[[bin]]` in that crate's `Cargo.toml`:

```
cargo run --release -p mem_usage_benches --bin bench_mlkem_mem_usage
cargo run --release -p mem_usage_benches --bin bench_mldsa_mem_usage
```

`mem_usage_benches/src/lib.rs` makes those sources modules of a lib target as well, so their `//!`
headers are rustdoc'd and any indented or fenced block in them is compiled as a Rust doctest. The
valgrind and `ms_print` recipes there are fenced as ```` ```text ```` for that reason — keep it that
way when adding a harness, or `cargo test --workspace` fails to compile them.

## Workspace architecture

The workspace has three top-level kinds of member:
The workspace has four top-level kinds of member:

1. `crypto/*` — one sub-crate per primitive (`sha2`, `sha3`, `hmac`, `hkdf`, `mlkem`, `mlkem_lowmemory`, `mldsa`, `mldsa_lowmemory`, `rng`, `hex`, `base64`, `utils`) plus the spine crates `core`, `core-test-framework`, and `factory`. Each crate is published as `bouncycastle-<name>` and depended on internally via the `workspace.dependencies` table in the root `Cargo.toml`.
2. `src/` — the umbrella `bouncycastle` crate, which is just `pub use` re-exports of every sub-crate (e.g. `bouncycastle::sha3`, `bouncycastle::mlkem`). It exists so downstream users can pull the whole library with one dependency; it has no code of its own.
1. `crypto/*` — the library's sub-crates, plus the spine crates `core`, `core-test-framework`, and `factory` described below. Most are one primitive each; some, such as `cipher`, hold generic building blocks (modes, padding) as sub-modules. The set changes over time, so take it from `ls crypto/` or the root `Cargo.toml` rather than from a list here. Each crate is published as `bouncycastle-<name>` and depended on internally via the `workspace.dependencies` table in the root `Cargo.toml`.
2. `src/` — the umbrella `bouncycastle` crate, which is just `pub use` re-exports of every sub-crate (e.g. `bouncycastle::sha3`, `bouncycastle::sm3`, `bouncycastle::mlkem`). It exists so downstream users can pull the whole library with one dependency; it has no code of its own.
3. `cli/` — the `bc-rust` binary built on top of `bouncycastle`, exposing every primitive as a streaming stdin→stdout subcommand using `clap`.
4. `mem_usage_benches/` — stand-alone binary crates that measure peak stack usage of algorithms (cannot be done via criterion).

Expand Down Expand Up @@ -106,9 +138,26 @@ Repo mechanics behind those rules, which the documents don't spell out:
- `./dev_scripts/quality_stats.sh` produces the fallibility metrics both documents ask you to check. Run it before
and after a change and compare, rather than eyeballing the diff.
- **CLI commands stream.** The `cli/` binary is stdin→stdout with ~1 KB buffers so commands compose in shell
pipelines; preserve that when adding subcommands.
pipelines; preserve that when adding subcommands. The exception is a construction that is not
itself streamable, such as CCM (SP 800-38C Sec 3: "CCM is not designed to support partial
processing or stream processing", because the payload length is inside the first block the MAC
covers) -- there, read the whole input once and process it in place, rather than adding a second
buffer the size of the input on top of it; see `aes_ccm_cmd.rs`.
- Trait → factory → CLI is the wiring path for a new primitive; see [the workspace architecture](#the-core--core-test-framework--factory-spine) above for the crates involved.

## Scope of changes

Implement what was asked and stop. Unrequested refactors — extracting a trait, renaming for
readability, restructuring impls — are not free even when they are correct: bundled into a feature
commit they make the diff unreviewable, because a reviewer cannot separate the new behaviour from
the restructuring, and the review time that costs is the reason not to do it.

- If a refactor genuinely unblocks the task, give it **its own commit ahead of** the feature, so it
can be reviewed or dropped on its own.
- If it unblocks nothing, propose it and wait rather than doing it.
- The same goes for drive-by comment rewrites, reformatting and file moves in code you are only
passing through.

## Working from specifications

QUALITY_AND_STYLE.md is where the requirement for spec-corresponding comments and justified deviations lives. This
Expand Down Expand Up @@ -143,11 +192,16 @@ Rules when working from the downloaded copy:
What a crate must be tested against — including the mutation-testing expectation, the trait test framework, and the
external vector suites — is specified in QUALITY_AND_STYLE.md and CONTRIBUTING.md. Repo-specific mechanics:

- `cargo mutants` is expected to be run on each crate; surviving mutants must be investigated but not all need to die (e.g. XOR/OR equivalences in crypto code are acceptable). Config lives in `.cargo/mutants.toml` (output dir `custom_mutants_output/`).
- Behaviour-critical private functions can use in-file `#[cfg(test)] mod tests` blocks when they can't be exercised from outside the crate.
- `cargo mutants` is expected to be run on each crate; surviving mutants must be investigated but not all need to die (e.g. XOR/OR equivalences in crypto code are acceptable). Config lives in `.cargo/mutants.toml` (output dir `custom_mutants_output/`). Four things about running it here:
- **Always pass `-p <crate>`.** Without it only the root package is examined, which has no mutants, and the run "passes" vacuously — see [Common commands](#common-commands).
- **`-f`/`--file` does nothing while the checked-in config is in play**, because its `examine_globs` wins over the CLI filter: `cargo mutants -p bouncycastle-sha3 -f '**/kmac.rs'` still examines all ~874 mutants in the crate. To scope a run to the files you changed, copy `.cargo/mutants.toml` somewhere outside the repo, delete its `examine_globs` block, and pass `--config <copy>`; `-f` then filters as documented. (`--config /dev/null` also works but throws away `skip_calls`, `error_values`, `cap_lints` and the timeout multipliers with it.)
- **Add `--test-workspace true` when a crate's mutants are killed by another crate's tests.** The `core` traits are the case that matters: their default method bodies are exercised from `sha3` and `factory`, so a `-p bouncycastle-core` run alone reports them all as missed.
- **Symlink the test data into `/tmp`.** `cargo mutants` copies the tree to `/tmp/cargo-mutants-<dir>-XXXX.tmp/`, so the `../../../bc-test-data/...` paths the vector suites use resolve to `/tmp/bc-test-data`. Without `ln -s <path-to>/bc-test-data /tmp/bc-test-data` those tests print their "not found" warning, pass vacuously, and every mutant they would have killed is reported as missed. Use `--jobs 3` and an explicit `--timeout`; note that a mutant which makes a squeeze return no bytes hangs a fill loop for real, so some timeouts are kills rather than false alarms.
- Integration tests in `tests/` are preferred over in-file `#[cfg(test)] mod tests` blocks — see "Unit tests vs integration tests" in QUALITY_AND_STYLE.md for the reasoning and the exceptions. A unit test is justified for high-risk code that has known-answer values and cannot be reached through the public API; when you write one, all of its helpers go inside that `mod tests`.
- A property that can be asserted at compile time (`const _: () = assert!(...)`) stays a compile-time assertion even when a test also covers it: `cargo mutants` cannot see a const assertion fail, so pair the two rather than trading the guarantee for the coverage.
- For traits in `core`, the canonical tests live in `core-test-framework` and are invoked from each implementor's integration tests — don't duplicate them per-implementation.
- The per-width `impl Condition<W>` blocks in `crypto/utils/src/ct.rs` (and their test modules) are deliberately duplicated rather than macro-generated: `cargo mutants` cannot see into `macro_rules!` bodies, so a macro would hide the mask identities from mutation testing. Do not fold them back into a macro. Any change to one width in a group (i64/i32, u64/u32) must be applied to every width in that group.

## CI

The only workflow is `.github/workflows/publish_doc_benches_to_ghpages.yaml`: on every PR it builds rustdoc and runs `quality_stats.sh`; on `main` it additionally runs `cargo bench --all` and publishes docs, code stats, and benchmark results to GitHub Pages (`https://bcgit.github.io/bc-rust/`). There is no separate CI test/lint job — local `cargo test` is the gate.
The only workflow is `.github/workflows/publish_doc_benches_to_ghpages.yaml`: on every PR it builds rustdoc and runs `quality_stats.sh`; on `main` it additionally runs `cargo bench --all` and publishes docs, code stats, and benchmark results to GitHub Pages (`https://bcgit.github.io/bc-rust/`). There is no separate CI test/lint job — local `cargo test --workspace` is the gate, and nothing but a developer running it stands between a broken test and `main`.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ Some specifics:
* Public APIs of a library should be both ergonomic and expressive. When defining a new trait or public function, ask
yourself whether a programmer who is new to cryptography is likely to use this in a way that will get them into
trouble.
* Variables should be well-named, well-structured, and well-commented (a comment-to-code ration of 1:1 is a goal to be
* Variables should be well-named, well-structured, and well-commented (a comment-to-code ratio of 1:1 is a goal to be
strived for!). Think about memory footprint and, where possible, use unnamed scopes to allow the compiler to pop
intermediate value variables off the stack as soon as they are no longer needed.
* Always run your code through `cargo mutants` and get the issue count as low as your can. As a first pass, this forces
* Always run your code through `cargo mutants` and get the issue count as low as you can. As a first pass, this forces
you to write thorough unit tests. As a second pass, this draws your attention to bits of your code that cannot be
tested from the outside. Often this means that the code can be simplified without affecting functionality (as defined
by your set of unit tests) -- "simpler code" usually means faster runtime and easier future maintenance.
Expand All @@ -71,7 +71,7 @@ For minor updates, you can instead choose to create an issue with short snippets

* For contributions touching multiple files try and split up the pull request, smaller changes are easier to review and
test, as well as being less likely to run into merge issues.
* Create a test cases for your change, it may be a simple addition to an existing test. If you do not know how to do
* Create test cases for your change; it may be a simple addition to an existing test. If you do not know how to do
this, ask us and we will help you.
* If you run into any merge issues, check out this [git tutorial](https://github.com/skills/resolve-merge-conflicts) to
help you resolve merge conflicts and other issues.
Expand Down
10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ members = ["cli", "crypto/*", "mem_usage_benches"]

[workspace.package]
edition = "2024"
# `bouncycastle-utils` uses `slice::as_chunks`, stable since 1.88; the 2024 edition alone needs 1.85.
rust-version = "1.88"
version = "0.1.3"

[workspace.dependencies]

# *** Internal Dependencies ***
bouncycastle = { path = "./" }
bouncycastle-aes = { path = "./crypto/aes" }
bouncycastle-ascon = { path = "./crypto/ascon" }
bouncycastle-base64 = { path = "./crypto/base64" }
bouncycastle-cipher = { path = "./crypto/cipher" }
bouncycastle-core = { path = "crypto/core" }
bouncycastle-core-test-framework = { path = "./crypto/core-test-framework" }
bouncycastle-factory = { path = "./crypto/factory" }
Expand All @@ -23,6 +28,7 @@ bouncycastle-mldsa-lowmemory = { path = "./crypto/mldsa-lowmemory" }
bouncycastle-rng = { path = "./crypto/rng" }
bouncycastle-sha2 = { path = "./crypto/sha2" }
bouncycastle-sha3 = { path = "./crypto/sha3" }
bouncycastle-sm3 = { path = "./crypto/sm3" }
bouncycastle-utils = { path = "./crypto/utils" }


Expand All @@ -41,7 +47,10 @@ version.workspace = true
edition.workspace = true

[dependencies]
bouncycastle-aes.workspace = true
bouncycastle-ascon.workspace = true
bouncycastle-base64.workspace = true
bouncycastle-cipher.workspace = true
bouncycastle-core.workspace = true
bouncycastle-factory.workspace = true
bouncycastle-hex.workspace = true
Expand All @@ -54,3 +63,4 @@ bouncycastle-mlkem-lowmemory.workspace = true
bouncycastle-rng.workspace = true
bouncycastle-sha2.workspace = true
bouncycastle-sha3.workspace = true
bouncycastle-sm3.workspace = true
Loading