All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Known-answer tests (
tests/kat.rs): the primitive is pinned to the official NIST CAVP GCMVS test set (gcmEncryptExtIV256.rsp/gcmDecrypt256.rsp, CAVS 14.0) -- 6 encrypt vectors, 6 decrypt vectors, and 6 official tag-mismatch (FAIL) vectors. Every vector was cross-verified with OpenSSL 3 (via Node'scryptomodule) before being committed. The crate's own format (version byte, nonce/tag positions, HKDF wiring) is pinned against an independently computed fixture (OpenSSL HKDF + AES-256-GCM) including empty-plaintext, layout, version byte, wrong-key/wrong-context, and tamper-rejection checks. - Property tests (
tests/proptests.rs): 13 properties, 1000 cases each in CI -- roundtrips (arbitrary bytes up to 64 KiB, arbitrary strings, both encodings), ciphertext uniqueness, context isolation, wrong-key rejection, every-byte-tamper-fails, URL-safe charset, exact 32-byte key handling. - Fuzzing (
fuzz/):decryptandencodingtargets with committed corpus seeds; a nightly CI job runs each target for 60 s and fails on any crash artifact. - Miri CI job:
cargo miri test --liband--test katon nightly -- the zeroize and memory-safety claims are now checked, not asserted. - MSRV CI job:
cargo test --all-featureson rustc 1.85.0 exactly; a regression in the declaredrust-versionnow fails CI.
- BREAKING:
MasterKey::generate()andgenerate_master_key()now returnResult<MasterKey, CryptoError>instead of panicking when the operating system's random number generator is unavailable. Migration: add.unwrap()or handle the newCryptoError::RandomnessFailedvariant. - BREAKING:
CryptoError::EncryptionFailedno longer carries the underlyingaeaderror string (unstable upstream surface). It is now a unit variant;CryptoErrorderivesPartialEq,Eq, andClone. - Nonce generation no longer panics on RNG failure — it returns
CryptoError::RandomnessFailed. TryFrom<Vec<u8>> for MasterKeynow zeroizes the source buffer before it is dropped, on both success and error paths, so no copy of the key material survives in the caller's allocation.- The HKDF output buffer in
derive_key()is zeroized after the AES key is constructed. aes-gcmnow enables itszeroizefeature, scrubbing the internal GHASH key after each encryption/decryption call.
- BREAKING: dropped the unused
randdependency (was declared but never used in code;getrandomis the only source of randomness).
- Added
#![forbid(unsafe_code)]— the crate guarantees it contains no unsafe code. - All public API panic paths removed: the crate returns
Resulteverywhere an operation can fail. Verified by a CI grep gate that rejectsunwrap()/expect()/panic!in non-test, non-doc code.
- Upgrade
aes-gcmfrom 0.10 to 0.11 (aead0.6) - Replace
OsRngwithgetrandomdirectly (removed inrand_core0.10) - Replace deprecated
Nonce::from_slice/Key::from_slicewithTryFrom - Fix encrypt/decrypt to pass nonce by reference (
aead0.6 API)
- Rename project from
encrypt-mantoencryptman - Update README installation version to match Cargo.toml
- Update CI pinned action SHAs to latest versions
encrypt_with_encoding()/decrypt_with_encoding()— encrypt with custom base64 encodingencrypt_bytes_with_context()/decrypt_bytes_with_context()— binary API for arbitrary dataEncodingenum (Standard,UrlSafeNoPad) with publicencode()/decode()methodsTryFrom<&[u8]>andTryFrom<Vec<u8>>implementations forMasterKeyEncryptionFailederror variant (separate fromKeyDerivation)UnsupportedVersionerror variant for unknown version bytes- Version prefix byte (
0x01) in ciphertext format for future compatibility - CI workflow (quality, test, audit jobs)
rust-toolchain.toml(pinned to stable)missing_docs = "deny"lint
- BREAKING: HKDF now uses
infoparameter for context instead ofsalt(RFC 5869) - BREAKING: Ciphertext format changed to
version || nonce || ciphertext derive_key()now returnsResultinstead of panicking withexpect()- License split into
LICENSE-MITandLICENSE-APACHE - README enhanced with badges, installation guide, URL-safe encoding example, and security notes
Encoding::encode()/decode()are nowpub(were private — dead API from outside crate)
MasterKeytype with zeroize-on-dropgenerate_master_key()convenience functionencrypt()/decrypt()with default contextencrypt_with_context()/decrypt_with_context()for context-isolated encryption- HKDF-SHA256 key derivation from master key
- AES-256-GCM authenticated encryption with random nonces
- Base64 encoding for safe storage
- Comprehensive test suite (14 tests)