oqs-safe 0.2.5

Stable, minimal, safe Rust wrapper over libOQS for PQ KEM/SIG (ML-KEM/Dilithium) with explicit mock-only dev mode.
Documentation

oqs-safe

Crates.io Release Docs.rs License
CI

oqs-safe is a stable, minimal safe Rust wrapper over [libOQS] for NIST Post-Quantum Cryptography (PQC):

  • KEM: ML-KEM-768 (Kyber768)
  • SIG: ML-DSA-44 (Dilithium2)

Zeroizes secrets • Safe newtypes • Compile-time guardrails • Resilient to liboqs naming drift (“ML-KEM-768” ↔ “Kyber768”, “ML-DSA-44” ↔ “Dilithium2”)


Install

1. Add the crate

  • Default (mock backend for CI/dev):

    oqs-safe = { version = "0.2", features = ["kyber768", "dilithium2"] }
    
    
  • Production (real liboqs backend):

    oqs-safe = { version = "0.2", default-features = false, features = ["liboqs", "kyber768", "dilithium2"] }

2. (Prod only) Install libOQS

git clone https://github.com/open-quantum-safe/liboqs cd liboqs && mkdir build && cd build cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DOQS_DIST_BUILD=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX="$HOME/.local/liboqs" .. ninja && ninja install

  • Make oqs-safe find and load liboqs: export LIBOQS_DIR="$HOME/.local/liboqs"

  • macOS: ensure runtime linking finds liboqs.dylib: export DYLD_FALLBACK_LIBRARY_PATH="$HOME/.local/liboqs/lib:${DYLD_FALLBACK_LIBRARY_PATH}"

  • Optional: pkg-config: export PKG_CONFIG_PATH="$HOME/.local/liboqs/lib/pkgconfig:${PKG_CONFIG_PATH}"

Quickstart

KEM round-trip (Kyber / ML-KEM-768)

use oqs_safe::kem::{Kem, Kyber768};

let (pk, sk) = Kyber768::keypair()?; let (ct, ss1) = Kyber768::encapsulate(&pk)?; let ss2 = Kyber768::decapsulate(&ct, &sk)?; assert_eq!(ss1.len(), ss2.len());

Sign & verify (Dilithium / ML-DSA-44)

use oqs_safe::sig::{Dilithium2, SignatureScheme};

let (pk, sk) = Dilithium2::keypair()?; let msg = b"hello pqc"; let sig = Dilithium2::sign(&sk, msg)?; Dilithium2::verify(&pk, msg, &sig)?;

Derive session keys (HKDF over shared secret)

use oqs_safe::kem::{Kem, Kyber768}; use hkdf::Hkdf; use sha2::Sha256;

let (_, sk) = Kyber768::keypair()?; let (ct, ss1) = Kyber768::encapsulate(&Kyber768::keypair()?.0)?; let ss = Kyber768::decapsulate(&ct, &sk)?; let hk = Hkdf::::new(Some(b"oqs-safe context"), ss.as_bytes()); let mut key = [0u8; 32]; hk.expand(b"aes256-gcm key", &mut key)?;

Examples

  • Mock backend (fast, no native deps): cargo run --example kem_roundtrip --features "kyber768" cargo run --example dsa_sign_verify --features "dilithium2"

  • Real backend: cargo run --example kem_roundtrip --features "liboqs,kyber768" cargo run --example dsa_sign_verify --features "liboqs,dilithium2"

  • Tests:

  • Mock + negative-path tests: cargo test --features "mock,kyber768,dilithium2,testing"

  • Real liboqs: cargo test --features "liboqs,kyber768,dilithium2"

  • Linking Tips:

  • macOS:

  • To ensure binaries find liboqs.dylib, embed an rpath:

  • .cargo/config.toml: [target.aarch64-apple-darwin] rustflags = ["-C", "link-arg=-Wl,-rpath,@executable_path/../lib"]

  • Linux:

  • Use PKG_CONFIG_PATH or LD_LIBRARY_PATH=$HOME/.local/liboqs/lib.:

Security Notes

  • Always derive session keys via HKDF (or similar) before use.:
  • Bind identities and protocol transcripts to KEM exchanges.:
  • All secret materials (SecretKey, etc.) are zeroized on drop.:
  • Avoid serializing or logging secrets.:

MSRV & License

  • MSRV: Rust 1.70+:

License: MIT OR Apache-2.0

Acknowledgements

  • **Built atop libOQS from the Open Quantum Safe project.:- **
  • Contributions welcome for expanded PQC algorithms and integration with secure enclaves, blockchain key stores, or HSM interfaces.: