Skip to main content

Crate crypt_guard

Crate crypt_guard 

Source
Expand description

§CryptGuard v2

Crates.io MIT licensed Documentation Hashnode Blog GitHub Library

§Introduction

Current release status: 2.0.0. The safe-default Phase 4 upgrade is implemented, externally consumer-tested, and test-green. Before publishing, close the release hygiene gates tracked in guides/release-readiness.md.

CryptGuard is a post-quantum sealing library built on the NIST FIPS 203/204/205 final standards. The primary flow is:

ML-KEM (FIPS 203) -> HKDF -> Authenticated Envelope (HPKE-shaped, RFC 9180)

The v2 line replaces the old pqcrypto Kyber / Falcon / Dilithium path with FIPS-final ML-KEM, ML-DSA, and SLH-DSA as the default. The old path is still available behind --features legacy-pqclean for reading data created with v1.x.

§Key Features

  • ML-KEM-512/768/1024 (FIPS 203) for key encapsulation.
  • HKDF-SHA-256/512 key schedule with domain-separated labels following the NIST SP 800-227 direction: the shared secret is never used raw as a cipher key.
  • CGv2 Authenticated Envelope: one self-describing blob { header, kem_ciphertext, nonce, ciphertext } — nonce is internal, callers never juggle it separately.
  • XChaCha20-Poly1305 and AES-256-GCM-SIV authenticated AEAD.
  • ML-DSA-44/65/87 (FIPS 204) and SLH-DSA (FIPS 205) digital signatures.
  • Compile-enforced content-axis typestate: calling encrypt_file on a Message instance is a compile error (E0599).
  • Legacy Kyber / Falcon / Dilithium kept behind legacy-pqclean feature so v1.x data remains decryptable.

§Safe Default: Encryptor / Decryptor

The primary entry point is the staged-builder pair. The safe flow has no manual nonce handling and no tuple unpacking; current builders still accept key bytes while the lower kem module keeps typed key roles.

use crypt_guard::{Encryptor, Decryptor};
use crypt_guard::{MlKem768, XChaCha20Poly1305};
use crypt_guard::kem::{KemBackend, ml_kem::MlKem768Impl};
use crypt_guard::kem::backend::OsRng;

let mut rng = OsRng;
let (public_key, secret_key) = MlKem768Impl::keypair(&mut rng)?;

// Seal: ML-KEM encapsulate -> HKDF -> XChaCha20-Poly1305
let envelope = Encryptor::<MlKem768, XChaCha20Poly1305>::new()
    .recipient(public_key.as_ref().to_vec())
    .plaintext(b"hello post-quantum world")
    .seal()?;

// Open: ML-KEM decapsulate -> HKDF -> AEAD verify + decrypt
let plaintext = Decryptor::<MlKem768, XChaCha20Poly1305>::new()
    .secret_key(secret_key.as_ref().to_vec())
    .open(&envelope)?;

assert_eq!(plaintext, b"hello post-quantum world");

§Protocol: HPKE-Shaped CGv2 Envelope

The envelope structure mirrors HPKE (RFC 9180) as deployed by Cloudflare, AWS, and Google for post-quantum TLS key establishment. The sender output is a single blob, not a (ciphertext, kem_secret) tuple:

Sender:
  (kem_ct, shared_secret) = ML-KEM.Encapsulate(recipient_pk)
  session_key             = HKDF(ikm=shared_secret, salt=kem_ct,
                                 info="crypt_guard:v2:aead:<alg>")
  ciphertext              = AEAD.Seal(session_key, nonce, aad, plaintext)
  envelope                = { header, kem_ct, nonce, ciphertext }

Receiver:
  shared_secret = ML-KEM.Decapsulate(kem_ct, recipient_sk)
  session_key   = HKDF(same params)
  plaintext     = AEAD.Open(session_key, nonce, aad, ciphertext)

The shared secret is zeroized immediately after key derivation (NIST SP 800-227). The header carries kem_id, kdf_id, aead_id so the envelope is self-describing and forwards-compatible.

§Typestate Design: Kyber<Process, Size, Content, Algorithm>

The underlying type encodes four axes at the type level. Mismatching axes (wrong process direction, wrong content kind, wrong cipher) is a compile error, not a runtime panic:

AxisVariants
ProcessEncryption, Decryption
SizeMlKem512, MlKem768, MlKem1024
ContentData, Message, Files
AlgorithmXChaCha20Poly1305, AesGcmSiv, …

The Encryptor/Decryptor builders expose the Data content path. The full Kyber<P,S,C,A> API is available for direct use when you need Message or Files content handling.

§Feature Flags

FlagDefaultDescription
ml-kem-backendyesML-KEM-512/768/1024 (FIPS 203)
ml-dsa-backendyesML-DSA-44/65/87 (FIPS 204)
sign-slhdsanoSLH-DSA (FIPS 205)
aes-ctrnoAES-CTR stream cipher
aes-xtsnoAES-XTS disk encryption
archivenotar/xz/gz archive helpers
legacy-pqcleannoLegacy Kyber/Falcon/Dilithium + old tuple API

§Legacy Compatibility

Data encrypted with crypt_guard v1.x can still be decrypted by enabling the legacy-pqclean feature. The old Kyber<Encryption, Kyber1024, Message, AES> types, the encryption! / decryption! macros, the kyber_keypair! macro, and the tuple-returning encrypt_msg / decrypt_msg functions are all preserved under the legacy module.

// Legacy path — requires --features legacy-pqclean
use crypt_guard::{*, error::*};

let (public_key, secret_key) = kyber_keypair!(1024);
let (ciphertext, kyber_secret) = encryption!(
    public_key.to_owned(), 1024,
    b"hello".to_vec(), "passphrase", AES
)?;
let plaintext = decryption!(
    secret_key.to_owned(), 1024,
    ciphertext, "passphrase", kyber_secret, AES
)?;

§References

Re-exports§

pub use crate::key_control::file;
pub use api::open as hpke_open;
pub use api::seal as hpke_seal;
pub use api::AuthenticatedAead;
pub use api::Decryptor;
pub use api::DecryptorBuilder;
pub use api::Encryptor;
pub use api::EncryptorBuilder;
pub use api::MissingPlaintext;
pub use api::MissingRecipient;
pub use api::MissingSecretKey;
pub use api::WithPlaintext;
pub use api::WithRecipient;
pub use api::WithSecretKey;
pub use markers::AesGcmSiv;
pub use markers::XChaCha20Poly1305;
pub use protocol::Envelope;
pub use crate::markers::AesCtr;
pub use crate::markers::AesGcmSiv;
pub use crate::markers::AesXts;
pub use crate::markers::Data;
pub use crate::markers::Decryption;
pub use crate::markers::Encryption;
pub use crate::markers::Files;
pub use crate::markers::Message;
pub use crate::markers::XChaCha20;
pub use crate::markers::XChaCha20Poly1305;
pub use crate::markers::AES;
pub use crate::key_control::*;
pub use crate::log::*;

Modules§

api
Safe default public API over the Phase 3 ML-KEM + HKDF + AEAD envelope path. Safe public API over the Phase 3 CGv2 envelope protocol.
builder
Builder-style API for encryption/decryption, keygen, and signature flows Fluent builder API over the legacy Kyber encryption, decryption, and signing macros.
cipher_xchacha
XChaCha20 stream cipher implementation.
cipher_xchacha_poly
XChaCha20-Poly1305 AEAD implementation.
cryptography
Cryptographic related functionalitys, enums structs and modules
error
Error types Crate-wide error types for crypt_guard.
hub
Phase 3 hub module (src/core/hub/): EncryptFunctions + DecryptFunctions traits, FIPS primary size markers MlKem512/768/1024, ML-KEM + HKDF + Envelope-wired cipher impls. Hub module: Kyber<P, K, D, C> four-axis typestate, KEM variant traits, and cipher markers.
kdf
HKDF-SHA256/512 key schedule with domain separation. HKDF-based key schedule with domain separation (Phase 2 — always compiled).
kem
ML-KEM backend trait and ML-KEM-512/768/1024 implementations (FIPS 203). KEM (Key Encapsulation Mechanism) backend trait and ML-KEM implementations.
key_control
File and Key related functionalitys, enums structs and modules Typed key and file-metadata primitives for the key-control subsystem.
kyber
Legacy hub module (src/core/kyber/): keeps KyberData, Kyber struct, KyberFunctions trait, KyberSizeVariant, deprecated size markers, and key_controler (legacy-pqclean). Hub module: Kyber<P, K, D, C> four-axis typestate, KEM variant traits, and cipher markers.
log
Logging related functionalitys Tracing-based logging surface for crypt_guard.
markers
Shared zero-sized-type axis markers (Encryption/Decryption, Files/Message/Data, cipher markers). Re-exported here so crate::* continues to expose them. Shared zero-sized-type (ZST) axis markers used across core/, legacy/, and the public API.
protocol
CGv2 authenticated envelope protocol (Phase 3). CGv2 authenticated envelope protocol (src/protocol/).
sign
SignAlgorithm trait and ML-DSA/SLH-DSA implementations (FIPS 204/205). Digital signature backend trait and FIPS 204/205 implementations.
utils

Macros§

archive
Macro to archive a directory or file.
archive_util
Macro for archiving and extracting directories or files.
concat_cipher
decrypt_file
Macro for encryption of a file, taking a Kyber decryption instance, a PathBuf as well as a passphrase and ciphertext as arguments
decryption
encrypt_file
Macro for encryption of a file, taking a Kyber decryption instance, a PathBuf as well as a passphrase and ciphertext as arguments
encryption
extract
Macro to extract a .tar.xz archive.
impl_kyber_cipher
Generate EncryptFunctions + DecryptFunctions impls for one cipher marker.
log_activity
signature
split_cipher
verify
write_log

Structs§

Kyber
Represents a generic Kyber structure with templated parameters for process status, Kyber size, content status, and algorithm parameter.
Kyber512
Legacy KEM size marker: Kyber-512.
Kyber768
Legacy KEM size marker: Kyber-768.
Kyber1024
Legacy KEM size marker: Kyber-1024.
KyberData
Represents the data structure for Kyber algorithm, including key and nonce.
MlKem512
Primary KEM size marker: ML-KEM-512 (FIPS 203, security category 1).
MlKem768
Primary KEM size marker: ML-KEM-768 (FIPS 203, security category 3 — recommended).
MlKem1024
Primary KEM size marker: ML-KEM-1024 (FIPS 203, security category 5).

Enums§

KyberVariant
Enum representing Kyber variants.

Traits§

CryptographicFunctions
Abstract encrypt/decrypt trait.
DecryptData
Decrypt the byte ciphertext carried by an Envelope.
DecryptFile
Decrypt the file ciphertext carried by an Envelope.
DecryptText
Decrypt the message ciphertext carried by an Envelope.
EncryptData
Encrypt arbitrary bytes into an authenticated Envelope.
EncryptFile
Encrypt the contents of a file into an authenticated Envelope.
EncryptText
Encrypt a UTF-8 string message into an authenticated Envelope.
KyberFunctions
Trait for Kyber cryptographic functions.
KyberSizeVariant
Trait to specify Kyber size variants.

Functions§

activate_log
Function activating the log, it takes one arg: &str which represents the location of the logfile

Attribute Macros§

activate_log