lib-q-core 0.0.5

Core types and traits for lib-Q post-quantum cryptography library
Documentation

lib-q-core

Core types and traits for the lib-Q post-quantum cryptography library.

Features

  • Algorithm Identifiers: Unified enum for all supported post-quantum algorithms
  • Error Handling: Comprehensive error types with detailed information
  • Key Types: Secure key structures with automatic memory zeroization
  • WASM Support: Full WebAssembly compatibility with JavaScript bindings
  • No-std Compatible: Works in embedded and constrained environments

No-std Support

This crate supports no_std environments through feature flags:

Feature Flags

  • std (default): Full standard library support with detailed error messages
  • alloc: Allocation support for dynamic memory (Vec, String)
  • no_std: Minimal no_std support without allocation
  • getrandom: Cryptographically secure random number generation
  • serde: Serialization support
  • wasm: WebAssembly bindings

Usage Examples

Full std support (default)

use lib_q_core::{Algorithm, KemContext, Utils};

let mut kem_ctx = KemContext::new();
let keypair = kem_ctx.generate_keypair(Algorithm::MlKem768)?;

// Full random number generation
let random_bytes = Utils::random_bytes(32)?;

// String formatting available
let hex = Utils::bytes_to_hex(&random_bytes);

No-std with allocation

use lib_q_core::{Algorithm, KemContext};

// In Cargo.toml: default-features = false, features = ["alloc"]
let mut kem_ctx = KemContext::new();
let keypair = kem_ctx.generate_keypair(Algorithm::MlKem768)?;
// Vec and String available, but no random generation

Minimal no-std

use lib_q_core::{Algorithm, KemContext};

// In Cargo.toml: default-features = false, features = ["no_std"]
let mut kem_ctx = KemContext::new();
let keypair = kem_ctx.generate_keypair(Algorithm::MlKem768)?;
// No allocation, no random generation, static error messages

Error Handling in no_std

In no_std mode, error messages use static strings instead of dynamic allocation:

// std mode
Error::InvalidAlgorithm { algorithm: format!("{alg:?} is not a KEM algorithm") }

// no_std mode  
Error::InvalidAlgorithm { algorithm: "algorithm is not a KEM algorithm" }

Random Number Generation

Random number generation requires the getrandom feature:

// With getrandom feature
let random_bytes = Utils::random_bytes(32)?;

// Without getrandom feature
let random_bytes = Utils::random_bytes(32); // Returns error

Supported Algorithms

Key Encapsulation Mechanisms (KEMs)

  • ML-KEM (FIPS 203): ML-KEM-512, ML-KEM-768, ML-KEM-1024
  • CB-KEM: Multiple parameter sets
  • HQC: HQC-128, HQC-192, HQC-256

Digital Signatures

  • ML-DSA (FIPS 204): ML-DSA-44, ML-DSA-65, ML-DSA-87 (see lib-q-ml-dsa, lib-q-ring)
  • FN-DSA (FIPS 206): FN-DSA-1, FN-DSA-5
  • SLH-DSA (FIPS 205): SHA-2 and SHAKE parameter families (lib-q-slh-dsa, lib-q-sig)

Hash Functions

  • SHA-3 family: SHA3-224, SHA3-256, SHA3-384, SHA3-512
  • SHAKE: SHAKE128, SHAKE256
  • Customizable SHAKE: cSHAKE128, cSHAKE256
  • KMAC: KMAC128, KMAC256
  • TupleHash: TupleHash128, TupleHash256
  • ParallelHash: ParallelHash128, ParallelHash256

Usage

Rust

use lib_q_core::{Algorithm, KemContext};

let mut kem_ctx = KemContext::new();
let keypair = kem_ctx.generate_keypair(Algorithm::MlKem768)?;

WebAssembly

import init, { available_algorithms, create_kem } from 'lib-q-kem';

await init();
const algorithms = available_algorithms();
const kem = create_kem(algorithms[0]);

Security

All cryptographic operations are implemented following NIST standards and best practices:

  • Constant-time operations where applicable
  • Secure memory handling with automatic zeroization
  • Side-channel resistance considerations
  • Comprehensive input validation

Workspace

This crate is part of the lib-Q workspace. Related pieces include lib-q-kem, lib-q-sig, lib-q-hpke, lib-q-zkp, lib-q-ring, and tooling crates such as lib-q-sca-test.

AEAD decrypt layers (0.0.2+)

  • Layer A (default): lib_q_core::Aead::decrypt and lib_q_core::api::AeadOperations::decrypt return Result only. Existing callers keep using this; behavior of decrypt is unchanged for algorithms that only extended Layer B alongside it.
  • Layer B (opt-in): lib_q_core::AeadDecryptSemantic::decrypt_semantic returns lib_q_core::Result<DecryptSemanticOutcome> (i.e. Result<DecryptSemanticOutcome, lib_q_core::Error>); authentication failure is Ok(DecryptSemanticOutcome::AuthenticationFailed) with no plaintext bytes in that arm. Operational errors (sizes, keys, nonces, unsupported AD) stay Err. Ciphertext shorter than the AEAD tag is Err(Error::InvalidCiphertextSize) (use Error::aead_ciphertext_shorter_than_tag at AEAD boundaries for consistent construction).
  • Migration: import AeadDecryptSemantic and match on DecryptSemanticOutcome; do not collapse the outcome to a secret-derived bool without a reviewed threat model. Concrete types implement the trait where shipped: lib_q_saturnin::SaturninAead, lib_q_saturnin::SaturninShortAead, lib_q_aead::Shake256Aead, lib_q_duplex_aead::DuplexSpongeAead, lib_q_tweak_aead::TweakAead, lib_q_romulus::{RomulusNAead, RomulusMAead}, and the corresponding lib-q-aead registry wrappers (SaturninAead, DuplexSpongeAead, …). For dyn AeadWithMetadata or metadata-driven dispatch, read AeadMetadata::supports_semantic_decrypt / AeadWithMetadata::supports_semantic_decrypt before assuming Layer B. HPKE exposes semantic decrypt on SaturninAeadImpl and Shake256AeadImpl.
  • Layer A Err variant names after a failed integrity check are not unified across algorithms (AuthenticationFailed vs VerificationFailed); see docs/adr/003-aead-decrypt-layers.md for the mapping table. Layer B uses AuthenticationFailed in the Ok arm consistently.
  • Full specification: docs/adr/003-aead-decrypt-layers.md. WASM AeadContext bindings remain Layer A unless extended deliberately.

License

Licensed under the Apache License, Version 2.0.