🌊 Sane C++ August 26
Welcome to the August 2026 update! This month introduces the new Cryptography library, adds native and optional OpenSSL backends, connects cryptography to AsyncStreams, and continues the Fibers work with incremental stacks and tighter scheduling evidence.
Cryptography
The biggest addition this month is the new
Cryptography library.
It provides a small synchronous interface for secure random bytes, AES-GCM, HMAC, HKDF, and legacy AES-CBC with PKCS#7 padding. Inputs and outputs are caller-owned spans, public objects keep provider state in fixed inline storage, and the native implementation delegates primitive operations to the operating system instead of bundling a portable cryptographic implementation.
The scope is intentionally narrow. This is a low-level primitive adapter, not a protocol library. It does not provide password hashing, signatures, public-key cryptography, certificate validation, key storage, nonce allocation, or protocol framing. AES-GCM is the preferred authenticated-encryption API; CBC remains available only for compatibility with protocols that already specify the required authentication, IV, framing, and failure rules.
Cryptography is still Draft and has not received a formal cryptographic or side-channel audit. The implementation has
NIST known-answer vectors, mutation tests, deterministic stress coverage, and cross-platform CI, but those are not a
replacement for a security review. I want that boundary to stay visible while the API and backend coverage are still
evolving.
The AES-GCM coverage now also compares the native and OpenSSL backends directly. It exercises message and associated-data boundary sizes, in-place operation, cross-backend decryption, and corrupted ciphertext, tags, and AAD. This catches provider differences that known-answer vectors alone may not expose.
The API also makes provider capability discovery explicit. Applications query the active backend before selecting a
primitive instead of assuming that every algorithm is available just because the code compiled. This matters most on
Linux, where the native AF_ALG algorithms are runtime kernel capabilities rather than build-time guarantees.
Detailed list of commits:
- Cryptography: Add native symmetric cryptography library
- Cryptography: Add deterministic CBC streaming stress coverage
- Cryptography: Harden Draft contracts and test coverage
- Cryptography: Expose maximum AEAD associated data size in Features
- Cryptography: Distinguish Windows authentication failures from parameter errors
- Cryptography: Widen NIST GCM corpus and pin HMAC long-key behavior
- Cryptography: Add AES-GCM backend differential testing
- Cryptography: Fix Windows build broken by ntstatus.h include
- Cryptography: Complete Draft capability coverage
- Cryptography: Add public umbrella header
Native and OpenSSL Backends
The native backend uses the platform facilities already present on each operating system: CommonCrypto on Apple, CNG
on Windows, and getrandom() plus AF_ALG on Linux. The public API stays the same, while queryFeatures() reports
what the selected backend can actually provide in the running process.
AES-GCM took the most platform-specific work. Linux uses the kernel AEAD interface with a bounded associated-data contract. Apple now has a narrowly scoped GCM composition over CommonCrypto AES because CommonCrypto does not expose a public GCM interface. The implementation keeps that construction private and exercises both key sizes with shared NIST vectors and corruption tests. Windows uses the native CNG authenticated-cipher path.
An optional OpenSSL 3 backend is also available on macOS, Windows, and Linux. It is selected explicitly and loaded at runtime, so Sane C++ still has no OpenSSL header or link-time dependency. A missing or policy-restricted OpenSSL library simply reports its features as unavailable and does not change the native backend.
There is an important allocation distinction here. The native Sane adapters use fixed storage and caller-owned buffers. When OpenSSL is selected, OpenSSL may allocate provider, algorithm, process, thread, and session state internally. The backend choice is therefore visible in both capability reporting and the end-to-end allocation contract.
The CI matrix now exercises OpenSSL cryptography on all three platforms. Windows uses a bundled OpenSSL 3 package so
the optional backend is tested from the same repeatable setup rather than relying on an arbitrary machine installation.
The Debug jobs also run the native, OpenSSL, AsyncStreams, and transform-stream cryptography suites under ASan and
UBSan on macOS and Linux.
Detailed list of commits:
- Cryptography: Add Linux AES-GCM backend
- CI: Require Linux AES-GCM cryptography coverage
- Cryptography: Add Apple AES-GCM backend
- Cryptography: Record Swift interoperability boundary
- Cryptography: Treat Linux primitives as runtime capabilities
- Cryptography: Offer OpenSSL alongside Linux AF_ALG
- Cryptography: Load OpenSSL on Apple and Windows
- Cryptography: Stabilize OpenSSL single-file coverage
- CI: Exercise OpenSSL cryptography on all platforms
- CI: Use bundled Windows OpenSSL 3
- CI: Gate Cryptography with sanitizers
Cryptography and AsyncStreams
The new library also connects to
AsyncStreams without creating a
hard dependency between them.
CryptographyTransformStreams.h contains header-only templates that can adapt a caller-selected cipher or HMAC
session. An application includes both libraries and instantiates the concrete type only where it builds the pipeline.
That keeps Cryptography synchronous, keeps AsyncStreams independent from a specific cryptography implementation,
and still allows encrypted or authenticated data to participate in a bounded asynchronous pipeline.
The cipher transform supports the incremental CBC interface, while the HMAC adapter is a sink that can share source buffers with a file or network destination through normal pipeline fan-out. The same adapters can receive an explicitly selected native or OpenSSL session.
There is deliberately no generic AES-GCM byte-stream transform. Safe AEAD decryption needs a bounded record protocol that defines nonces, tags, AAD, framing, and when plaintext may be released. Those policy decisions should not be hidden inside something that looks like an ordinary stream transform.
Detailed list of commits:
Fibers: Incremental Stacks and Scheduling
August also continued the work on
Fibers.
The largest addition is opt-in incremental stack commitment. A FiberStackClass can reserve the full virtual range but
initially commit only a bounded portion, then grow that commitment when the active fiber reaches a protected page. Full
commitment remains the default and the simpler portable option.
This is necessarily platform-sensitive work. A process-wide FiberStackGrowthRuntime owns fault-handler integration,
and every OS thread that may execute an incremental stack registers thread-affine growth state. POSIX workers use
caller-owned alternate signal-stack storage; Windows uses native guard-page behavior. Migration republishes the active
slot on the new worker, teardown releases the actual committed interval, and unsupported debugger or sanitizer
configurations reject incremental execution rather than silently changing fault ownership.
The benchmarks can now compare full and incremental commitment at equal virtual reservation, separating metadata,
current and peak commitment, suspension, wake, and completion costs. There are also two more practical bounded examples:
FibersMandelbrot uses stackless jobs for image rows, while AsyncFibersFileCopy combines fiber-shaped control flow with
asynchronous file operations.
The scheduler and benchmark paths received another correctness pass too. External injection claims are transactional, local job wakes are coalesced behind visible backlog, cancellation reuses the existing generation, and uncontended batches avoid unnecessary wake generations. The Skynet benchmark now assigns deterministic breadth-first slots instead of serializing the SC backends through a benchmark-only allocation counter. That correction makes the comparison more useful, even though benchmark results still remain machine- and configuration-specific development evidence.
Detailed list of commits:
- Fibers: Separate producer benchmark timing
- Fibers: Synchronize stack growth probe
- Fibers: Focus scheduler benchmark workers
- Fibers: Preserve benchmark symbols
- Fibers: Isolate scheduler benchmark workloads
- Fibers: Distribute injected task registries
- Fibers: Claim injection batches transactionally
- Fibers: Define incremental stack ownership
- Fibers: Add stack growth lifecycles
- Fibers: Register stack growth workers
- Fibers: Add incremental stack metadata
- Fibers: Execute incremental stack classes
- Fibers: Guard incremental high-water scans
- Fibers: Compare stack commitment density
- Fibers: Coalesce local job batch wakes
- Fibers: Add bounded consumer examples
- Fibers: Cover nested stack fault forwarding
- Fibers: Preserve Windows guard dispatch space
- Fibers: Keep Windows stack limit on guard
- Fibers: Accept native terminal stack faults
- Fibers: Forward nested POSIX stack faults
- Fibers: Correct Skynet scheduling evidence
- Fibers: Coalesce local single-job wakes
- Fibers: Preserve single-job parallelism
- Fibers: Streamline job cancellation preflight
- Fibers: Reuse cancellation generation for job stop
- Fibers: Avoid uncontended batch wake generations
Contracts, Tooling and CI
The remaining changes are smaller, but they tighten a few important edges.
Async can now remove loop timeouts synchronously from its userspace schedule. FileSystemWatcher tests preserve the
asynchronous event contract instead of allowing callback ordering to become accidental. The Fil-C package uses a more
reliable zlib source, and AsyncStreams has a Windows registry fallback for finding zlib.
The new cryptography work also exposed adjacent Windows integration issues. Hashing now links its CryptoAPI backend
correctly, and the CI jobs cover both native and OpenSSL cryptography paths rather than validating only compilation.
The generated library metrics and dependency documentation were refreshed as well, including the new Cryptography
dependency graph.
Detailed list of commits:
- Documentation: Replace broken links for Fibers and AsyncFibers
- Fibers: Fix Windows example discovery
- FileSystemWatcher: Preserve async event semantics
- Build: Use reliable Fil-C zlib source
- Async: Unschedule loop timeouts synchronously
- AsyncStreams: Link Windows zlib registry fallback
- Hashing: Link Windows CryptoAPI backend
- Documentation: Update LOC for August 2026
See you next month!