dcrypt 1.2.3

dcrypt is a pure-Rust, software-only cryptography library providing both classical and post-quantum primitives with a focus on security, hybrid KEMs/signatures, and memory-safe, no-FFI design.
Documentation
# Authenticated Encryption with Associated Data (AEAD) - Symmetric (`symmetric/aead`)

This module within the `dcrypt-symmetric` crate provides high-level implementations and wrappers for Authenticated Encryption with Associated Data (AEAD) ciphers. It builds upon the core AEAD primitives found in `dcrypt-algorithms/src/aead` to offer more ergonomic APIs, including key management, nonce generation, and ciphertext packaging.

## Purpose

AEAD ciphers are essential for modern symmetric encryption as they provide:
1.  **Confidentiality**: Ensuring the plaintext is unreadable without the secret key.
2.  **Integrity**: Ensuring the plaintext has not been tampered with during transit or storage.
3.  **Authenticity**: Verifying that the message originated from a party possessing the secret key (for the message itself and optionally for unencrypted Associated Data).

## Implemented AEAD Schemes

The primary AEAD schemes exposed through this module are:

1.  **ChaCha20Poly1305 (`chacha20poly1305`)**:
    *   Wraps `algorithms::aead::chacha20poly1305::ChaCha20Poly1305`.
    *   Provides `ChaCha20Poly1305Cipher` and `XChaCha20Poly1305Cipher` (for extended nonces).
    *   Defines user-friendly key and nonce types: `ChaCha20Poly1305Key`, `ChaCha20Poly1305Nonce` (12-byte), and `XChaCha20Poly1305Nonce` (24-byte).
    *   Includes `ChaCha20Poly1305CiphertextPackage` for bundling nonce and ciphertext.
    *   Offers key derivation (`derive_chacha20poly1305_key`) and salt generation utilities.

2.  **AES-GCM (`gcm`)**:
    *   Wraps `algorithms::aead::gcm::Gcm` instantiated with AES block ciphers (`algorithms::block::aes::Aes128` or `Aes256`).
    *   Provides `Aes128Gcm` and `Aes256Gcm` cipher structures.
    *   Uses key types `Aes128Key` and `Aes256Key` (defined in `symmetric::aes::keys`).
    *   Defines `GcmNonce` (12-byte) and `AesCiphertextPackage`.

## Core Traits Implemented

The cipher structs in this module (e.g., `ChaCha20Poly1305Cipher`, `Aes128Gcm`) implement:

-   **`crate::cipher::SymmetricCipher`**:
    *   `type Key`: Specifies the dedicated key type (e.g., `ChaCha20Poly1305Key`).
    *   `new(key: &Self::Key) -> Result<Self>`: Constructor.
    *   `name() -> &'static str`: Algorithm name.

-   **`crate::cipher::Aead`**:
    *   `type Nonce`: Specifies the dedicated nonce type (e.g., `GcmNonce`).
    *   `encrypt(&self, nonce: &Self::Nonce, plaintext: &[u8], aad: Option<&[u8]>) -> Result<Vec<u8>>`.
    *   `decrypt(&self, nonce: &Self::Nonce, ciphertext: &[u8], aad: Option<&[u8]>) -> Result<Vec<u8>>`.
    *   `generate_nonce() -> Self::Nonce`: Generates a cryptographically secure random nonce suitable for the algorithm.

## Key and Nonce Management

A key design goal of this module is to provide type-safe and convenient ways to handle keys and nonces:

-   **Key Types** (e.g., `ChaCha20Poly1305Key`, `Aes128Key`):
    *   Fixed-size arrays wrapped in structs that implement `Zeroize` and `ZeroizeOnDrop`.
    *   Provide `generate()` methods for creating random keys.
    *   Offer `to_secure_string()` and `from_secure_string()` for a simple, somewhat protected way to serialize/deserialize keys (primarily for illustrative or specific storage scenarios, not a replacement for robust key management systems).
-   **Nonce Types** (e.g., `ChaCha20Poly1305Nonce`, `GcmNonce`):
    *   Fixed-size arrays ensuring correct nonce length for the algorithm.
    *   Provide `generate()` methods.
    *   Offer `to_string()` (base64) and `from_string()` for serialization.
-   **Ciphertext Packages** (e.g., `ChaCha20Poly1305CiphertextPackage`):
    *   Structs that combine a nonce and its corresponding ciphertext.
    *   Provide `to_string()` and `from_string()` methods for a simple serialized format (e.g., `dcrypt-ALGORITHM:{nonce_b64}:{ciphertext_b64}`). This helps ensure the correct nonce is used during decryption.

## Usage Example (AES-256-GCM)

```rust
use dcrypt_symmetric::aes::{Aes256Gcm, Aes256Key, GcmNonce, AesCiphertextPackage};
use dcrypt_symmetric::cipher::{SymmetricCipher, Aead};
use dcrypt_symmetric::error::Result;

fn aes_gcm_example() -> Result<()> {
    // Generate key and cipher instance
    let (cipher, key) = Aes256Gcm::generate()?; // Helper that generates key and new()
    // Or:
    // let key = Aes256Key::generate();
    // let cipher = Aes256Gcm::new(&key)?;

    let plaintext = b"Sensitive data requiring strong authenticated encryption.";
    let aad = Some(b"Metadata that needs authentication but not encryption.");

    // Encrypt using a randomly generated nonce
    let (ciphertext_bytes, nonce_used) = cipher.encrypt_with_random_nonce(plaintext, aad)?;
    println!("AES-256-GCM Ciphertext (hex): {}", hex::encode(&ciphertext_bytes));
    println!("AES-256-GCM Nonce (base64): {}", nonce_used.to_string());

    // Decrypt
    let decrypted_bytes = cipher.decrypt(&nonce_used, &ciphertext_bytes, aad)?;
    assert_eq!(plaintext, decrypted_bytes.as_slice());
    println!("AES-256-GCM Decryption successful!");

    // Using CiphertextPackage
    let package = cipher.encrypt_to_package(plaintext, aad)?;
    let serialized_package = package.to_string();
    println!("Serialized Package: {}", serialized_package);

    let parsed_package = AesCiphertextPackage::from_string(&serialized_package)?;
    let decrypted_from_package = cipher.decrypt_package(&parsed_package, aad)?;
    assert_eq!(plaintext, decrypted_from_package.as_slice());
    println!("Decryption from package successful!");

    Ok(())
}
```
This module simplifies the use of AEAD ciphers by abstracting away some of the direct interactions with the `algorithms` crate primitives and providing more holistic types for keys, nonces, and packaged ciphertexts.