Skip to content
Open
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
31affff
sha2: partial-bit messages, compile-time IVs, CAVP SHAVS tests (PR #88)
dghgit Sep 6, 2026
aec1ae4
sha3: partial-byte fixes, CAVP SHA3VS tests, mem-usage bench, release…
dghgit Sep 6, 2026
d604906
sha2, hmac: add SHA-512/224 and SHA-512/256 (FIPS 180-4 s. 5.3.6) and…
dghgit Sep 6, 2026
a57d508
rng: use core::fmt in hash_drbg80090a.rs; the only part of PRs #92-#9…
dghgit Sep 6, 2026
fa0be5d
sm3: add bouncycastle-sm3 (GB/T 32905-2016) and HMAC-SM3 with factory…
dghgit Sep 6, 2026
34d7953
Partial bytes follow ASN.1 BIT STRING order (X.690 s. 8.6.2): message…
dghgit Sep 6, 2026
1140a61
release notes: SM3 partial bytes follow the ASN.1 BIT STRING order li…
dghgit Sep 6, 2026
1ad97fd
sha2, sm3: document the surviving cargo-mutants equivalences at their…
dghgit Sep 6, 2026
fe6fd58
core: split BlockCipher into block-aligned BlockCipherEncryptor/Decry…
dghgit Sep 6, 2026
58a1fed
aes-lowmemory: add bouncycastle-aes-lowmemory, a constant-time, table…
dghgit Sep 6, 2026
aa9454d
modes: add BlockPermutation trait, bouncycastle-modes with AES CBC, a…
dghgit Sep 6, 2026
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
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
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
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,13 @@ mutants.out*/

.idea/
.vscode/

# Claude Code: ignore personal/local state, but share team tooling
# (skills, slash commands, subagents, and project settings.json).
.claude/*
!.claude/settings.json
!.claude/skills/
!.claude/commands/
!.claude/agents/
.claude/settings.local.json
.claude 2/
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ cargo run --release -p mem_usage_benches --bin bench_mldsa_mem_usage

The workspace has three 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/*` — one sub-crate per primitive (`sha2`, `sha3`, `sm3`, `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::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
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ version = "0.1.3"

# *** Internal Dependencies ***
bouncycastle = { path = "./" }
bouncycastle-aes-lowmemory = { path = "./crypto/aes-lowmemory" }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion point: weird to have an aes_lowmemory without an aes. Should we rename this, or are we planning a fast-but-big AES implementation? I know that FIPS 197 has the EqInvCipher(), but I suspect we can just tuck that into the same crate.

@dghgit dghgit Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crate does not exist - see PR #115 - you already asked me to rename it, and I already have.

bouncycastle-base64 = { path = "./crypto/base64" }
bouncycastle-modes = { path = "./crypto/modes" }
bouncycastle-core = { path = "crypto/core" }
bouncycastle-core-test-framework = { path = "./crypto/core-test-framework" }
bouncycastle-factory = { path = "./crypto/factory" }
Expand All @@ -20,9 +22,11 @@ bouncycastle-mlkem = { path = "./crypto/mlkem" }
bouncycastle-mlkem-lowmemory = { path = "./crypto/mlkem-lowmemory" }
bouncycastle-mldsa = { path = "./crypto/mldsa" }
bouncycastle-mldsa-lowmemory = { path = "./crypto/mldsa-lowmemory" }
bouncycastle-padding = { path = "./crypto/padding" }
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,6 +45,7 @@ version.workspace = true
edition.workspace = true

[dependencies]
bouncycastle-aes-lowmemory.workspace = true
bouncycastle-base64.workspace = true
bouncycastle-core.workspace = true
bouncycastle-factory.workspace = true
Expand All @@ -51,6 +56,9 @@ bouncycastle-mldsa.workspace = true
bouncycastle-mldsa-lowmemory.workspace = true
bouncycastle-mlkem.workspace = true
bouncycastle-mlkem-lowmemory.workspace = true
bouncycastle-modes.workspace = true
bouncycastle-padding.workspace = true
bouncycastle-rng.workspace = true
bouncycastle-sha2.workspace = true
bouncycastle-sha3.workspace = true
bouncycastle-sm3.workspace = true
30 changes: 30 additions & 0 deletions QUALITY_AND_STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,36 @@ Note that rust macros tend not to play well with a lot of dev tooling for compil
`cargo mutants`, which is a good reason to avoid macros in core algorithm or data processing code. Macros can be used
more freely within test code.

## Unit tests vs integration tests

Unit tests are test code (and supporting helper functions) embedded in src/**.rs files. They have access to
crate-private or module-private functions and constants.

Integration tests are test code (and supporting helper functions) in tests/**.rs files. They test the crate's code from
the outside -- ie through its public APIs -- since tests/ is a separate crate from src/.

In general, integration tests are preferred over unit tests. This is for a number of reasons:

* To reduce reviewer burden; reviewers will typically focus more effort on the src/ than the tests/, so we want to keep
src/ as short as is reasonable.
* Usually it is easier to determine what is the correct behaviour at the public API level. For example, this is the
level at which we typically have KATs and test vectors.
* Tools like cargo mutants are very helpful at detecting branches that are not exercisable via the public APIs, which
often is an indicator that the branch isn't doing what you think it's doing, or is simply not useful and can be
deleted. Unit tests that bypass the public APIs to pin these sorts of branches obscure the fact that this code is
unreachable.

Unit tests are reasonable to include in the following cases:

* There is high-risk code (usually meaning that it is complex code whose behaviour is not obvious from inspection) where
unit tests help to document the behaviour and protect against accidental breakage via a benign-looking change.
* AND where known answer tests are available.
* AND where this behaviour cannot be tested from integration tests.

When writing unit tests, they should be contained with an `mod tests` at the bottom of the file, and ALL helper
functions that support the unit tests must be contained within that module. The intention is to clearly signal to a code
reviewer what is test code vs functional code.

# Docs

## Usage Examples
Expand Down
Loading
Loading