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
# Symmetric Cipher Traits (`symmetric/cipher.rs`)

This file defines the core traits that all symmetric encryption algorithms within the `dcrypt-symmetric` crate should implement. These traits establish a consistent interface for creating and using symmetric ciphers, particularly focusing on Authenticated Encryption with Associated Data (AEAD) schemes.

## Core Traits

1.  **`SymmetricCipher`**:
    *   **Purpose**: This is the base trait for all symmetric encryption algorithms. It defines the minimal contract for a symmetric cipher.
    *   **Associated Types**:
        *   `type Key`: Specifies the concrete key type used by the cipher (e.g., `Aes128Key`, `ChaCha20Poly1305Key`). This key type is expected to handle its own security properties like zeroization.
    *   **Methods**:
        *   `new(key: &Self::Key) -> Result<Self> where Self: Sized`: A constructor that takes a reference to the cipher's specific key type and returns a new cipher instance or an error (e.g., if the key is invalid, though type safety for `Self::Key` should ideally prevent this).
        *   `name() -> &'static str`: Returns a static string slice representing the human-readable name of the cipher (e.g., "AES-128-GCM", "ChaCha20Poly1305").

2.  **`Aead` (Authenticated Encryption with Associated Data)**:
    *   **Purpose**: This trait extends `SymmetricCipher` and is implemented by ciphers that provide authenticated encryption. AEAD ciphers ensure confidentiality, integrity, and authenticity of the data.
    *   **Associated Types**:
        *   `type Nonce`: Specifies the concrete nonce (or IV) type used by the AEAD cipher (e.g., `GcmNonce`, `ChaCha20Poly1305Nonce`). This type should enforce correct nonce sizes.
    *   **Methods**:
        *   `encrypt(&self, nonce: &Self::Nonce, plaintext: &[u8], aad: Option<&[u8]>) -> Result<Vec<u8>>`: Encrypts the given `plaintext`.
            *   `nonce`: A nonce unique for each encryption with the same key.
            *   `plaintext`: The data to be encrypted.
            *   `aad`: Optional Associated Data that will be authenticated but not encrypted.
            *   Returns the ciphertext (which typically includes the authentication tag).
        *   `decrypt(&self, nonce: &Self::Nonce, ciphertext: &[u8], aad: Option<&[u8]>) -> Result<Vec<u8>>`: Decrypts the given `ciphertext`.
            *   `nonce`: The same nonce used during encryption.
            *   `ciphertext`: The encrypted data, including the authentication tag.
            *   `aad`: Optional Associated Data that was authenticated during encryption.
            *   Returns the original plaintext if decryption and authentication are successful. Otherwise, returns an error (e.g., `Error::Primitive(PrimitiveError::Authentication { .. })` if the tag is invalid).
        *   `generate_nonce() -> Self::Nonce`: A static method to generate a cryptographically secure random nonce appropriate for the AEAD scheme.

## How These Traits Are Used

-   Cipher implementations like `Aes128Gcm` or `ChaCha20Poly1305Cipher` in the `symmetric::aead` module implement both `SymmetricCipher` and `Aead`.
-   They associate their specific key types (e.g., `Aes128Key`) and nonce types (e.g., `GcmNonce`).
-   This allows users to write generic code that can work with any AEAD cipher conforming to these traits, while still benefiting from the type safety of specific key/nonce types.

**Example of Trait Usage (Conceptual):**

```rust
use dcrypt_symmetric::cipher::{SymmetricCipher, Aead};
use dcrypt_symmetric::error::Result;
use std::fmt::Debug; // For printing

// A generic function that can encrypt data using any AEAD cipher
fn perform_aead_encryption<C>(key: &C::Key, plaintext: &[u8], aad: Option<&[u8]>) -> Result<()>
where
    C: SymmetricCipher + Aead, // Cipher C must implement both traits
    C::Key: Debug, // For printing (keys usually redact themselves)
    C::Nonce: Debug, // For printing
{
    let cipher = C::new(key)?;
    let nonce = C::generate_nonce();

    println!("Using cipher: {}", C::name());
    println!("With key: {:?}", key); // Key's Debug impl should redact
    println!("Generated nonce: {:?}", nonce);

    let ciphertext = cipher.encrypt(&nonce, plaintext, aad)?;
    println!("Ciphertext length: {}", ciphertext.len());

    let decrypted = cipher.decrypt(&nonce, &ciphertext, aad)?;
    assert_eq!(plaintext, decrypted.as_slice());
    println!("Generic AEAD encryption and decryption successful for {}!", C::name());

    Ok(())
}

// Example with a concrete cipher would then call this:
// use dcrypt_symmetric::aead::gcm::Aes128Gcm;
// use dcrypt_symmetric::aes::Aes128Key;
// let my_key = Aes128Key::generate();
// perform_aead_encryption::<Aes128Gcm>(&my_key, b"test data", None).unwrap();
```

These traits form the core API contract for symmetric ciphers within the `dcrypt-symmetric` crate, promoting consistency and safety.