Skip to main content

dcrypt_algorithms/stream/
mod.rs

1//! Stream cipher implementations
2//!
3//! This module provides implementations of stream ciphers, which are symmetric
4//! key ciphers that encrypt plaintext digits one at a time with a pseudorandom
5//! keystream.
6//!
7//! # Available Stream Ciphers
8//!
9//! - ChaCha20: A high-speed stream cipher designed by Daniel J. Bernstein
10//!
11//! # Security Considerations
12//!
13//! Stream ciphers require unique nonces for each encryption operation with the
14//! same key. Reusing a nonce with the same key completely breaks the security
15//! of the cipher.
16
17#![cfg_attr(not(feature = "std"), no_std)]
18
19/// ChaCha family of stream cipher implementations
20pub mod chacha;
21
22// Re-export commonly used types
23pub use chacha::chacha20::{ChaCha20, CHACHA20_BLOCK_SIZE, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE};
24
25use crate::error::{Error, Result};
26
27/// Common trait for stream cipher implementations
28pub trait StreamCipher {
29    /// The key size in bytes
30    const KEY_SIZE: usize;
31
32    /// The nonce size in bytes
33    const NONCE_SIZE: usize;
34
35    /// The internal block size in bytes (if applicable)
36    const BLOCK_SIZE: usize;
37
38    /// Process data in place (encrypts for encryption, decrypts for decryption)
39    fn process(&mut self, data: &mut [u8]) -> Result<()>;
40
41    /// Encrypt data in place
42    fn encrypt(&mut self, data: &mut [u8]) -> Result<()> {
43        self.process(data)
44    }
45
46    /// Decrypt data in place
47    fn decrypt(&mut self, data: &mut [u8]) -> Result<()> {
48        self.process(data)
49    }
50
51    /// Generate keystream directly into an output buffer
52    fn keystream(&mut self, output: &mut [u8]) -> Result<()>;
53
54    /// Reset the cipher to its initial state
55    fn reset(&mut self) -> Result<()>;
56
57    /// Seek to a specific position in the keystream (if supported)
58    fn seek(&mut self, position: u64) -> Result<()>;
59}
60
61// Implement StreamCipher for ChaCha20
62impl StreamCipher for ChaCha20 {
63    const KEY_SIZE: usize = CHACHA20_KEY_SIZE;
64    const NONCE_SIZE: usize = CHACHA20_NONCE_SIZE;
65    const BLOCK_SIZE: usize = CHACHA20_BLOCK_SIZE;
66
67    fn process(&mut self, data: &mut [u8]) -> Result<()> {
68        ChaCha20::process(self, data)
69    }
70
71    fn keystream(&mut self, output: &mut [u8]) -> Result<()> {
72        ChaCha20::keystream(self, output)
73    }
74
75    fn reset(&mut self) -> Result<()> {
76        self.reset();
77        Ok(())
78    }
79
80    fn seek(&mut self, position: u64) -> Result<()> {
81        if position > u32::MAX as u64 {
82            // Use the new Error::param helper
83            return Err(Error::param(
84                "position",
85                "ChaCha20 seek position must fit in u32",
86            ));
87        }
88        ChaCha20::seek(self, position as u32)
89    }
90}