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}