evidence 0.1.0

Type-level tags for cryptographic primitives
Documentation
//! Encryption primitives and traits.
//!
//! This module provides the [`EncryptionPrimitive`] trait for abstracting over
//! authenticated encryption algorithms (AEAD).
//!
//! # Example
//!
//! ```
//! # #[cfg(feature = "chacha20poly1305")]
//! # {
//! use evidence::encryption::{chacha20poly1305::ChaCha20Poly1305, EncryptionPrimitive};
//!
//! let key = chacha20poly1305::Key::from([0u8; 32]);
//! let plaintext = b"hello world";
//!
//! let (ciphertext, nonce) = ChaCha20Poly1305::encrypt(&key, plaintext);
//! let decrypted = ChaCha20Poly1305::decrypt(&key, &nonce, &ciphertext).unwrap();
//!
//! assert_eq!(decrypted, plaintext);
//! # }
//! ```

use alloc::vec::Vec;
use core::fmt::Debug;
use hybrid_array::{Array, ArraySize};

/// An authenticated encryption primitive (AEAD).
///
/// This trait abstracts over different AEAD schemes (AES-GCM, ChaCha20-Poly1305, etc.)
/// similar to how [`DigestPrimitive`](crate::digest::DigestPrimitive) abstracts over hash algorithms.
pub trait EncryptionPrimitive {
    /// The secret key type.
    type Key;

    /// The nonce/IV size.
    type NonceSize: ArraySize;

    /// Error type returned when decryption fails.
    type Error: Debug;

    /// Encrypt plaintext and return (ciphertext, nonce).
    ///
    /// The nonce is generated randomly. For deterministic encryption,
    /// use [`encrypt_with_nonce`](Self::encrypt_with_nonce).
    fn encrypt(key: &Self::Key, plaintext: &[u8]) -> (Vec<u8>, Array<u8, Self::NonceSize>);

    /// Encrypt plaintext with a specific nonce.
    ///
    /// # Warning
    ///
    /// Nonce reuse with the same key completely breaks security.
    /// Prefer [`encrypt`](Self::encrypt) which generates a random nonce.
    fn encrypt_with_nonce(
        key: &Self::Key,
        nonce: &Array<u8, Self::NonceSize>,
        plaintext: &[u8],
    ) -> Vec<u8>;

    /// Decrypt ciphertext and return plaintext.
    ///
    /// # Errors
    ///
    /// Returns an error if decryption fails (e.g., invalid ciphertext or authentication tag).
    fn decrypt(
        key: &Self::Key,
        nonce: &Array<u8, Self::NonceSize>,
        ciphertext: &[u8],
    ) -> Result<Vec<u8>, Self::Error>;
}

#[cfg(feature = "chacha20poly1305")]
pub mod chacha20poly1305;

#[cfg(feature = "aes-gcm")]
pub mod aes_gcm;