1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
pub fn feistel_encrypt(plaintext: &str, key: u32, rounds: u8) -> Vec<u32> {
let mut _left: Vec<u8> = plaintext.bytes().collect();
let plaintext_length: usize = _left.len();
let mut _right: Vec<u8> = _left.split_off(plaintext_length / 2);
let mut left: Vec<u32> = _left.into_iter().map(|x| x as u32).collect();
let mut right: Vec<u32> = _right.into_iter().map(|x| x as u32).collect();
let mut subkey: u32;
let mut salty: u32;
let mut updated_left: Vec<u32>;
let mut updated_right: Vec<u32>;
for x in 0..rounds {
salty = key.count_ones() + x as u32;
subkey = key.wrapping_mul(salty);
updated_left = right.clone();
updated_right = Vec::new();
right = round_fn(right, subkey);
if left.len() <= right.len() {
for i in 0..left.len() {
updated_right.push(left[i] ^ right[i]);
}
} else if left.len() > right.len() {
for i in 0..right.len() {
updated_right.push(left[i] ^ right[i]);
}
updated_right.push(left[left.len() - 1]);
}
right = updated_right;
left = updated_left;
}
let mut _ciphertext: Vec<u32> = right.clone();
_ciphertext.append(&mut left);
let ciphertext = _ciphertext;
ciphertext
}
fn round_fn(right: Vec<u32>, subkey: u32) -> Vec<u32> {
let mut updated_right = Vec::new();
let mut new_val: u32;
for byte in right {
new_val = byte.wrapping_mul(subkey.count_ones() + 1);
new_val = subkey % (new_val + 1);
new_val += (byte as f32).cbrt() as u32;
if new_val > byte.count_ones() {
new_val -= byte.count_ones();
}
updated_right.push(new_val);
}
updated_right
}
pub fn feistel_decrypt(ciphertext: Vec<u32>, key: u32, rounds: u8) -> String {
let mut left: Vec<u32> = ciphertext.clone();
let split_index;
if (rounds % 2 == 0) && (ciphertext.len() % 2 == 1) {
split_index = (ciphertext.len() / 2) + 1;
} else {
split_index = ciphertext.len() / 2;
}
let mut right: Vec<u32> = left.split_off(split_index);
let mut subkey: u32;
let mut salty: u32;
let mut updated_left: Vec<u32>;
let mut updated_right: Vec<u32>;
for x in 0..rounds {
salty = key.count_ones() + (rounds - 1 - x) as u32;
subkey = key.wrapping_mul(salty);
updated_left = right.clone();
updated_right = Vec::new();
right = round_fn(right, subkey);
if left.len() <= right.len() {
for i in 0..left.len() {
updated_right.push(left[i] ^ right[i]);
}
} else if left.len() > right.len() {
for i in 0..right.len() {
updated_right.push(left[i] ^ right[i]);
}
updated_right.push(left[left.len() - 1]);
}
right = updated_right;
left = updated_left;
}
let right_u8 = right.into_iter().map(|x| x as u8).collect();
let left_u8 = left.into_iter().map(|x| x as u8).collect();
let decrypted_left = String::from_utf8(right_u8).unwrap();
let decrypted_right = String::from_utf8(left_u8).unwrap();
let mut plaintext: String = String::new();
plaintext.push_str(&decrypted_left);
plaintext.push_str(&decrypted_right);
plaintext
}