All notable changes to GreenfieldPQC will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.1.4 - 2026-03-31
IJweProvider.CreateJwe(ReadOnlySpan<byte> payloadBytes, byte[] publicKey): New overload that accepts the payload as raw bytes instead of anobject. This avoids the intermediate JSON serialization string and keeps callers inbyte[]land, so they can control the lifetime of the plaintext buffer. Prefer this for sensitive byte[] payloads.IJweProvider.DecryptJweBytes(string jweToken, byte[] privateKey): New method that returns the decrypted JWE payload asbyte[]instead of astring. Because .NET strings are immutable and cannot be reliably zeroed, callers that need best-effort plaintext memory hygiene should use this method and callCryptographicOperations.ZeroMemoryon the returned array when finished. Prefer this when the ability to clear plaintext from memory is required.
- Updated XML doc comments on
IJweProviderto include explicit security guidance: never log decrypted payloads or key material; prefer the newbyte[]overloads for sensitive data. - Existing
CreateJwe(object, byte[])andDecryptJwe(string, byte[])APIs are unchanged and fully backwards compatible. Kusumi512.Dispose(): Now overrides the baseDispose()to explicitly clear_startState,_workingState, and_keystreamBuffer— the arrays that hold key-derived state — before clearing the raw key and nonce bytes. This is best-effort managed-memory hygiene; the GC and JIT may still retain copies.Kusumi512Poly1305.Dispose(): Now overridesDispose()to dispose the innerKusumi512instance (triggering the state clearing above) before the base class clears the raw key and nonce.- Stream buffer clearing:
Kusumi512.EncryptStream,Kusumi512.EncryptStreamAsync, and all fourKusumi512Poly1305stream methods now clear their localbuffer(andsegmentBufferfor AEAD) infinallyblocks after the stream operation completes or fails. - AEAD ephemeral key material clearing:
Kusumi512Poly1305.Encrypt,Decrypt,EncryptAsync, andDecryptAsyncnow clearpoly1305Key(and the tag comparison arrays in the decrypt path) infinallyblocks.
- Do not log or include plaintext payloads or encryption keys in telemetry. Strings in .NET are immutable and cannot be reliably zeroed; use the new
byte[]-returningDecryptJweBytesand theReadOnlySpan<byte>-acceptingCreateJweoverload for sensitive payloads, and zero the arrays withCryptographicOperations.ZeroMemorywhen done. - Note: best-effort zeroing applies only to managed memory. Native library (liboqs) behavior for key material passed via P/Invoke is outside GreenfieldPQC's control.
1.1.3 - 2026-03-16
- Improved resolution of the native liboqs library when loading on Linux.
None. No public API surface changes in this release.
1.1.2 - 2026-02-06
- Minor fixes and stability improvements.
None. No public API surface changes in this release.
1.1.0 - 2026-02-05
CryptoFactory.CreateJwsProvider(int dilithiumLevel = 3): New factory method. Returns anIJwsProviderfor producing and verifying post-quantum signed JWTs using Dilithium. Dilithium levels: 2, 3, 5.CryptoFactory.CreateJwsProvider(DilithiumSecurityLevel level): Enum overload of the above; prefer this for new code.CryptoFactory.CreateJweProvider(int kyberLevel = 3, CipherAlgorithm kusumiAlgorithm = CipherAlgorithm.Kusumi512): New factory method. Returns anIJweProviderfor producing and verifying post-quantum encrypted JWTs using Kyber + Kusumi512. Kyber levels: 1, 3, 5.CryptoFactory.CreateJweProvider(KyberSecurityLevel level, CipherAlgorithm kusumiAlgorithm): Enum overload of the above; prefer this for new code.IJwsProvider(new interface):CreateJws(object payload, byte[] privateKey): Signs the payload and returns a compact three-segment JWS token (header.payload.signature).VerifyJws(string jwsToken, byte[] publicKey): Verifies the signature and returns the deserialized payload; throws on invalid token.
IJweProvider(new interface):CreateJwe(object payload, byte[] publicKey): Encrypts the payload and returns a compact five-segment JWE token (header.encrypted_key.iv.ciphertext.tag).DecryptJwe(string jweToken, byte[] privateKey): Decrypts the token and returns the raw JSON payload string; throws on invalid token.
1.0.1 - 2025-07-20
IKeyEncapsulationMechanism(new interface): Abstraction for Kyber operations —GenerateKeyPair(),Encapsulate(byte[] publicKey),Decapsulate(byte[] ciphertext, byte[] privateKey)— enabling mocking and dependency injection.ISigner(new interface): Abstraction for Dilithium operations —GenerateKeyPair(),Sign(byte[] message, byte[] privateKey),Verify(byte[] message, byte[] signature, byte[] publicKey),GetSignatureLength()— enabling mocking and dependency injection.CryptoFactory.CreateKyber(KyberSecurityLevel level): Enum-based factory overload returningIKeyEncapsulationMechanism; prefer this over theint-parameter overload for new code.CryptoFactory.CreateDilithium(DilithiumSecurityLevel level): Enum-based factory overload returningISigner; prefer this over theint-parameter overload for new code.
- Enhanced README with structured component details, key size tables for Kyber/Dilithium, expanded API examples (including async/stream), and security considerations.
- NuGet package tags/keywords in .csproj for better discoverability (e.g., post-quantum-cryptography, pqc, kyber, dilithium).
- Minor API clarifications and examples to align with best practices.
No breaking changes; fully backward-compatible with 1.0.0.
1.0.0 - 2025-07-15
CryptoFactory: Static factory class. Key methods:CreateKusumi512(byte[] key, byte[] nonce),CreateKyber(int parameter),CreateDilithium(int level),CreateSHA256(),CreateSHA512(),GenerateKey(CipherAlgorithm),GenerateNonce(CipherAlgorithm).ISymmetricCipher: Interface for Kusumi512/Kusumi512Poly1305 —Encrypt,Decrypt,EncryptInPlace,DecryptInPlace,EncryptAsync,DecryptAsync,EncryptInPlaceAsync,DecryptInPlaceAsync,EncryptStream,DecryptStream,EncryptStreamAsync,DecryptStreamAsync.IHashAlgorithm: Interface for SHA256/SHA512 —ComputeHash(byte[]),ComputeHash(Stream).Kusumi512: Post-quantum stream cipher implementation (512-bit key, 12-byte nonce).Kusumi512Poly1305: AEAD scheme combining Kusumi512 + Poly1305 (512-bit key, 16-byte appended MAC tag).- Benchmarks and basic unit tests.