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 self.process(data);
69 Ok(())
70 }
71
72 fn keystream(&mut self, output: &mut [u8]) -> Result<()> {
73 self.keystream(output);
74 Ok(())
75 }
76
77 fn reset(&mut self) -> Result<()> {
78 self.reset();
79 Ok(())
80 }
81
82 fn seek(&mut self, position: u64) -> Result<()> {
83 if position > u32::MAX as u64 {
84 // Use the new Error::param helper
85 return Err(Error::param(
86 "position",
87 "ChaCha20 seek position must fit in u32",
88 ));
89 }
90 self.seek(position as u32);
91 Ok(())
92 }
93}