1#[derive(Clone)]
19struct Rc4 {
20 perm: [u8; 256],
21 x: u8,
22 y: u8,
23}
24
25impl Rc4 {
26 fn new(key: &[u8]) -> Self {
31 let mut perm = [0u8; 256];
32 for (i, slot) in perm.iter_mut().enumerate() {
33 *slot = u8::try_from(i).unwrap_or(0);
34 }
35 let mut j = 0u8;
36 for i in 0..=u8::MAX {
37 let k = key
38 .get(usize::from(i) % key.len().max(1))
39 .copied()
40 .unwrap_or(0);
41 j = j.wrapping_add(at(&perm, i)).wrapping_add(k);
42 perm.swap(usize::from(i), usize::from(j));
43 }
44 Self { perm, x: 0, y: 0 }
45 }
46
47 fn apply(&mut self, data: &mut [u8]) {
49 for byte in data {
50 self.x = self.x.wrapping_add(1);
51 self.y = self.y.wrapping_add(at(&self.perm, self.x));
52 self.perm.swap(usize::from(self.x), usize::from(self.y));
53 let s = at(&self.perm, self.x).wrapping_add(at(&self.perm, self.y));
54 *byte ^= at(&self.perm, s);
55 }
56 }
57}
58
59fn at(perm: &[u8; 256], index: u8) -> u8 {
65 perm.get(usize::from(index)).copied().unwrap_or(0)
66}
67
68#[must_use]
78pub fn rc4(key: &[u8], data: &[u8]) -> Vec<u8> {
79 let mut out = data.to_vec();
80 rc4_in_place(key, &mut out);
81 out
82}
83
84pub(crate) fn rc4_in_place(key: &[u8], data: &mut [u8]) {
86 Rc4::new(key).apply(data);
87}
88
89#[cfg(test)]
90mod tests {
91 use super::rc4;
92
93 fn short_plaintext() -> Vec<u8> {
96 let mut v = b"The Quick Fox Jumped Over The Lazy Brown Dog.".to_vec();
97 v.push(0);
98 v
99 }
100
101 fn long_plaintext() -> Vec<u8> {
102 let mut v = concat!(
103 "The Quick Fox Jumped Over The Lazy Brown Dog.\n",
104 "1234567890123456789012345678901234567890123456789012345678901234567890\n",
105 "1234567890123456789012345678901234567890123456789012345678901234567890\n",
106 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
107 "!@#$%^&*()[]{};':\",.<>/?\\|\r\t\n"
108 )
109 .as_bytes()
110 .to_vec();
111 v.push(0);
112 v
113 }
114
115 #[test]
118 fn empty_key_short_data() {
119 let expected: [u8; 46] = [
120 138, 112, 236, 97, 242, 66, 52, 89, 225, 38, 88, 8, 47, 78, 216, 24, 170, 106, 26, 199,
121 208, 131, 157, 242, 55, 11, 25, 90, 66, 182, 19, 255, 210, 181, 85, 69, 31, 240, 206,
122 171, 97, 62, 202, 172, 30, 252,
123 ];
124 assert_eq!(rc4(&[], &short_plaintext()), expected);
125 }
126
127 #[test]
130 fn empty_key_long_data() {
131 let expected: [u8; 271] = [
132 138, 112, 236, 97, 242, 66, 52, 89, 225, 38, 88, 8, 47, 78, 216, 24, 170, 106, 26, 199,
133 208, 131, 157, 242, 55, 11, 25, 90, 66, 182, 19, 255, 210, 181, 85, 69, 31, 240, 206,
134 171, 97, 62, 202, 172, 30, 246, 19, 43, 184, 0, 173, 27, 140, 90, 167, 240, 122, 125,
135 184, 49, 149, 71, 63, 104, 171, 144, 242, 106, 121, 124, 209, 149, 61, 1, 66, 186, 252,
136 47, 51, 170, 253, 75, 95, 41, 203, 28, 197, 174, 144, 209, 166, 98, 142, 125, 44, 5,
137 147, 42, 73, 178, 119, 90, 253, 69, 103, 178, 15, 136, 51, 112, 39, 81, 37, 111, 129,
138 232, 106, 159, 126, 142, 120, 124, 48, 140, 253, 12, 223, 208, 106, 76, 60, 238, 5,
139 162, 100, 226, 251, 156, 169, 35, 193, 10, 242, 210, 20, 96, 37, 84, 99, 183, 179, 203,
140 62, 122, 54, 6, 51, 239, 142, 250, 238, 41, 223, 58, 48, 101, 29, 187, 43, 235, 3, 5,
141 176, 33, 14, 171, 36, 26, 234, 207, 105, 79, 69, 126, 82, 183, 105, 228, 31, 173, 8,
142 240, 99, 5, 147, 206, 215, 140, 48, 190, 165, 50, 41, 232, 29, 105, 156, 64, 229, 165,
143 12, 64, 163, 255, 146, 108, 212, 125, 142, 101, 13, 99, 174, 10, 160, 68, 196, 120,
144 110, 201, 254, 158, 97, 215, 0, 207, 90, 23, 208, 161, 105, 226, 164, 114, 80, 137, 58,
145 107, 109, 42, 110, 100, 202, 170, 224, 89, 28, 5, 138, 19, 253, 105, 220, 105, 24, 187,
146 109, 89, 205, 89, 202,
147 ];
148 assert_eq!(rc4(&[], &long_plaintext()), expected);
149 }
150
151 #[test]
153 fn foobar_key_short_data() {
154 let expected: [u8; 46] = [
155 59, 193, 117, 206, 167, 54, 218, 7, 229, 214, 188, 55, 90, 205, 196, 25, 36, 114, 199,
156 218, 161, 107, 122, 119, 106, 167, 44, 175, 240, 123, 192, 102, 174, 167, 105, 187,
157 202, 70, 121, 81, 17, 30, 5, 138, 116, 166,
158 ];
159 assert_eq!(rc4(b"foobar", &short_plaintext()), expected);
160 }
161
162 #[test]
164 fn foobar_key_long_data() {
165 let expected: [u8; 271] = [
166 59, 193, 117, 206, 167, 54, 218, 7, 229, 214, 188, 55, 90, 205, 196, 25, 36, 114, 199,
167 218, 161, 107, 122, 119, 106, 167, 44, 175, 240, 123, 192, 102, 174, 167, 105, 187,
168 202, 70, 121, 81, 17, 30, 5, 138, 116, 172, 169, 50, 160, 116, 237, 117, 108, 241, 127,
169 61, 83, 45, 77, 176, 0, 106, 191, 221, 132, 143, 219, 94, 2, 235, 204, 166, 201, 139,
170 140, 163, 104, 115, 48, 37, 18, 114, 168, 49, 235, 163, 179, 131, 182, 218, 120, 200,
171 9, 90, 60, 47, 55, 235, 135, 37, 21, 170, 48, 112, 185, 169, 43, 233, 88, 134, 117,
172 126, 248, 40, 176, 248, 30, 131, 108, 43, 139, 68, 232, 219, 7, 39, 223, 45, 199, 243,
173 54, 171, 31, 37, 161, 24, 38, 251, 13, 144, 106, 215, 179, 203, 5, 253, 25, 32, 25,
174 146, 109, 193, 143, 141, 177, 226, 134, 222, 95, 79, 156, 202, 240, 34, 153, 145, 169,
175 150, 231, 63, 113, 242, 156, 39, 136, 249, 108, 50, 181, 22, 22, 180, 57, 76, 69, 62,
176 254, 47, 141, 249, 235, 90, 25, 34, 40, 194, 66, 86, 110, 192, 235, 191, 205, 133, 91,
177 32, 104, 65, 43, 36, 140, 36, 228, 156, 105, 251, 169, 168, 203, 189, 238, 221, 64,
178 200, 68, 137, 153, 9, 183, 84, 153, 140, 239, 0, 15, 50, 126, 145, 22, 110, 43, 56, 94,
179 127, 48, 96, 47, 172, 3, 31, 130, 249, 243, 73, 206, 89, 9, 93, 156, 167, 205, 166, 75,
180 227, 36, 34, 81, 124, 195, 246, 152,
181 ];
182 assert_eq!(rc4(b"foobar", &long_plaintext()), expected);
183 }
184
185 #[test]
186 fn empty_input_yields_empty_output() {
187 assert!(rc4(b"key", &[]).is_empty());
188 assert!(rc4(&[], &[]).is_empty());
189 }
190
191 #[test]
192 fn crypting_twice_restores_the_input() {
193 let data: Vec<u8> = (0..300u32).map(|i| (i * 7 % 251) as u8).collect();
194 for key in [&b""[..], b"k", b"a longer key than one block would need"] {
195 assert_eq!(rc4(key, &rc4(key, &data)), data, "key {key:?}");
196 }
197 }
198}