Following the initial introduction of (Maybe) LibOQS.NET a few months ago, the post-quantum cryptography landscape has continued to move rapidly. To keep pace with these developments, the library has undergone significant updates to provide broader algorithm support and deeper integration with the underlying native tooling.
Today marks the release of version 0.3.0, a major milestone that brings the wrapper up to date with liboqs 0.15.0. This release is more than just a version bump; it exposes pretty much all of the liboqs algorithms to .NET developers and adds support for signature context strings, as well as the ability to perform deterministic (derandomized) KEM operations.
The transition from liboqs 0.13.0 to 0.15.0 🔗
Since the project’s inception, work has focused on closing the gap between the original liboqs 0.13.0 build and the current latest releases. While the early emphasis was also strictly on the NIST-standardized algorithms, in particular ML-KEM and ML-DSA, the scope has now expanded to include a full set of available schemes, for diverse security needs.
In fact, there is now an almost full coverage of all algorithms provided by liboqs:
Key Encapsulation (KEM)
A total of 35 KEM algorithms are available in liboqs, and all 35 are implemented in the wrapper:
- ML-KEM (3 variants)
- Kyber (3 variants)
- BIKE (3 variants)
- HQC (3 variants)
- NTRU (6 variants)
- NTRU Prime (1 variant)
- Classic McEliece (10 variants)
- FrodoKEM (6 variants)
Signatures
We expose all 77 of the “standard” or “pure” liboqs signature variants - we only skipped the 144 prehash variants of SLH-DSA.
- ML-DSA (3 variants)
- Falcon (4 variants)
- SPHINCS+ (12 simple variants)
- MAYO (4 variants)
- CROSS (18 variants)
- UOV (12 variants)
- SNOVA (12 variants)
- SLH-DSA (Pure) (12 variants)
Few code examples 🔗
SLH-DSA (Standardized Signatures)
SLH-DSA is the latest NIST standard (FIPS-205) and is a standardized replacement for SPHINCS+. liboqs 0.15.0 is the last version to officially support SPHINCS+ as well. To mirror this, Maybe LibOQS.NET still exposes SPHINCS+ too.
SLH-DSA API follows the established patterns used for other signature schemes within the library:
using var sig = new SigInstance(SigAlgorithm.SlhDsaSha2128sPure);
// Keys for SLH-DSA are relatively small compared to other post-quantum schemes
var (pk, sk) = sig.GenerateKeypair();
// Sign and verify
var signature = sig.Sign(message, sk);
var isValid = sig.Verify(message, signature, pk);
NTRU (Traditional Lattice KEM)
NTRU is a classic lattice-based KEM which is now back in liboqs:
using var kem = new KemInstance(KemAlgorithm.NtruHps2048677);
// Standard e2e KEM flow
var (pk, sk) = kem.GenerateKeypair();
var (ct, ssBob) = kem.Encapsulate(pk);
var ssAlice = kem.Decapsulate(sk, ct);
// Both parties now share the same secret
bool success = ssBob.SequenceEqual(ssAlice);s
FrodoKEM (Conservative Unstructured Lattice KEM)
If you are looking for the most conservative choice that doesn’t rely on structured lattices, FrodoKEM is the way to go:
using var kem = new KemInstance(KemAlgorithm.FrodoKem640Shake);
// FrodoKEM has significantly larger keys, but the logic remains identical
var (pk, sk) = kem.GenerateKeypair();
// Step 1: Bob generates ciphertext and shared secret from Alice's public key
var (ct, ssBob) = kem.Encapsulate(pk);
// Step 2: Alice recovers the shared secret using her private key
var ssAlice = kem.Decapsulate(sk, ct);
Signature context strings
A significant feature in the latest NIST standards like ML-DSA and SLH-DSA is support for context strings. These strings allow for effective domain separation, ensuring that a signature generated for a specific application or protocol cannot be validly reused in a different context, even if the underlying message remains the same.
The SigInstance class now includes a SupportsContextString property and updated overloads for signing and verification:
using var sig = new SigInstance(SigAlgorithm.MlDsa44);
var ctxStr = Encoding.UTF8.GetBytes("MyApplication-v1-Context");
var signature = sig.Sign(message, secretKey, ctxStr);
var isValid = sig.Verify(message, signature, publicKey, ctxStr);
Deterministic KEM (Derandomized)
For use cases requiring predictable behavior—such as specific protocol testing or deterministic key derivation—the native derand functions are now exposed. For supported algorithms, an optional seed can be passed to GenerateKeypair or Encapsulate.
using var kem = new KemInstance(KemAlgorithm.MlKem512);
var seed = new byte[kem.KeypairSeedLength];
RandomNumberGenerator.Fill(seed);
// The same seed will consistently generate the same keypair
var (pk, sk) = kem.GenerateKeypair(seed);
Breaking changes: Removal of Dilithium 🔗
The transition to liboqs 0.15.0 means the removal of Dilithium, which is not longer supported by the library. Users currently relying on SigAlgorithm.Dilithium2/3/5 should migrate to the finalized FIPS standards: SigAlgorithm.MlDsa44/65/87.
Platform support and availability 🔗
Version 0.3.0 is available now via NuGet. The library maintains its cross-platform commitment, providing native binaries for:
- Windows (x64 & ARM64)
- Linux (x64 & ARM64)
- macOS (Apple Silicon)
It is also published as .NET Standard 2.0 library now, which ensures compatibility with a wide range of .NET implementations.
Documentation and Samples 🔗
The GitHub repository has been updated with new samples reflecting these changes, including a comprehensive example program that demonstrates context string support and algorithm comparisons.
The goal for (Maybe) LibOQS.NET remains focused on providing a high-performance, thin wrapper that delivers the full capabilities of liboqs to the .NET ecosystem. Thanks!


