struct Rc4Cipher {
s: [u8; 256],
i: u8,
j: u8,
}
impl Rc4Cipher {
fn new(key: &[u8]) -> Self {
let mut s = [0u8; 256];
for (i, val) in s.iter_mut().enumerate() {
*val = i as u8;
}
let mut j = 0u8;
for i in 0..256 {
j = j.wrapping_add(s[i]).wrapping_add(key[i % key.len()]);
s.swap(i, j as usize);
}
Self { s, i: 0, j: 0 }
}
fn next_byte(&mut self) -> u8 {
self.i = self.i.wrapping_add(1);
self.j = self.j.wrapping_add(self.s[self.i as usize]);
self.s.swap(self.i as usize, self.j as usize);
let k = self.s[self.i as usize].wrapping_add(self.s[self.j as usize]);
self.s[k as usize]
}
fn apply_keystream(&mut self, data: &mut [u8]) {
for byte in data.iter_mut() {
*byte ^= self.next_byte();
}
}
}
pub fn rc4_crypt(key: &[u8], data: &[u8]) -> Vec<u8> {
let mut cipher = Rc4Cipher::new(key);
let mut result = data.to_vec();
cipher.apply_keystream(&mut result);
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rc4_symmetric() {
let key = b"testkey";
let plaintext = b"Hello, World!";
let ciphertext = rc4_crypt(key, plaintext);
let decrypted = rc4_crypt(key, &ciphertext);
assert_eq!(plaintext, &decrypted[..]);
assert_ne!(plaintext, &ciphertext[..]);
}
#[test]
fn test_rc4_empty() {
let key = b"testkey";
let data = b"";
let result = rc4_crypt(key, data);
assert_eq!(result.len(), 0);
}
#[test]
fn test_rc4_different_keys() {
let plaintext = b"Secret message";
let encrypted1 = rc4_crypt(b"key1", plaintext);
let encrypted2 = rc4_crypt(b"key2", plaintext);
assert_ne!(encrypted1, encrypted2);
}
#[test]
fn test_rc4_known_vector() {
let key = b"Key";
let plaintext = b"Plaintext";
let ciphertext = rc4_crypt(key, plaintext);
assert_ne!(plaintext, &ciphertext[..]);
let decrypted = rc4_crypt(key, &ciphertext);
assert_eq!(plaintext, &decrypted[..]);
}
}