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/// ChaCha family of stream cipher implementations
18pub mod chacha;
19
20// Re-export commonly used types
21pub use chacha::chacha20::{ChaCha20, CHACHA20_BLOCK_SIZE, CHACHA20_KEY_SIZE, CHACHA20_NONCE_SIZE};
22
23use crate::error::{Error, Result};
24
25/// Common trait for stream cipher implementations
26pub trait StreamCipher {
27    /// The key size in bytes
28    const KEY_SIZE: usize;
29
30    /// The nonce size in bytes
31    const NONCE_SIZE: usize;
32
33    /// The internal block size in bytes (if applicable)
34    const BLOCK_SIZE: usize;
35
36    /// Process data in place (encrypts for encryption, decrypts for decryption)
37    fn process(&mut self, data: &mut [u8]) -> Result<()>;
38
39    /// Encrypt data in place
40    fn encrypt(&mut self, data: &mut [u8]) -> Result<()> {
41        self.process(data)
42    }
43
44    /// Decrypt data in place
45    fn decrypt(&mut self, data: &mut [u8]) -> Result<()> {
46        self.process(data)
47    }
48
49    /// Generate keystream directly into an output buffer
50    fn keystream(&mut self, output: &mut [u8]) -> Result<()>;
51
52    /// Reset the cipher to its initial state
53    fn reset(&mut self) -> Result<()>;
54
55    /// Seek to a specific position in the keystream (if supported)
56    fn seek(&mut self, position: u64) -> Result<()>;
57}
58
59// Implement StreamCipher for ChaCha20
60impl StreamCipher for ChaCha20 {
61    const KEY_SIZE: usize = CHACHA20_KEY_SIZE;
62    const NONCE_SIZE: usize = CHACHA20_NONCE_SIZE;
63    const BLOCK_SIZE: usize = CHACHA20_BLOCK_SIZE;
64
65    fn process(&mut self, data: &mut [u8]) -> Result<()> {
66        ChaCha20::process(self, data)
67    }
68
69    fn keystream(&mut self, output: &mut [u8]) -> Result<()> {
70        ChaCha20::keystream(self, output)
71    }
72
73    fn reset(&mut self) -> Result<()> {
74        self.reset();
75        Ok(())
76    }
77
78    fn seek(&mut self, position: u64) -> Result<()> {
79        if position > u32::MAX as u64 {
80            // Use the new Error::param helper
81            return Err(Error::param(
82                "position",
83                "ChaCha20 seek position must fit in u32",
84            ));
85        }
86        ChaCha20::seek(self, position as u32)
87    }
88}