Skip to content

Commit eee15a5

Browse files
committed
Finished implementing algorithm
1 parent 8203ea8 commit eee15a5

File tree

1 file changed

+164
-18
lines changed

1 file changed

+164
-18
lines changed

src/main.rs

Lines changed: 164 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ const KEY : i64 = 0x133457799BBCDFF1;
44

55

66
fn main() {
7+
78
let key_plus = generate_key_plus(KEY);
89
let (left, right) = split_key(key_plus, 56);
9-
let subkey_pairs = create_16_subkeys(left, right);
10-
let _subkeys_48_bit = convert_pairs_to_encrypted_48_bit_keys(subkey_pairs);
10+
let subkey_pairs = create_16_pairs_blocks_32bit(left, right);
11+
let subkeys_48_bit = convert_pairs_to_encrypted_48_bit_keys(&subkey_pairs);
1112

1213
let message_permutation = initial_permutation_of_64bit_message(MESS);
1314
let (left_message, right_message) = split_key(message_permutation, 64);
14-
//println!("{:b}\n{:b}", left, right);
15+
let last_pair = generate_last_pair_of_32bit_blocks(left_message,
16+
right_message,
17+
&subkeys_48_bit);
18+
let encrypted_message = last_permutation_with_ip_table(last_pair);
19+
println!("{:x}", encrypted_message);
1520
}
1621

1722

@@ -47,7 +52,7 @@ fn split_key(key : i64, key_len: u8) -> (i64, i64) {
4752

4853
const LEFT_SHIFTS : [u8; 16] = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1];
4954

50-
fn create_16_subkeys(left_half: i64, right_half: i64) -> Vec<(i64, i64)> {
55+
fn create_16_pairs_blocks_32bit(left_half: i64, right_half: i64) -> Vec<(i64, i64)> {
5156
let mut subkeys : Vec<(i64, i64)> = Vec::new();
5257
subkeys.push((left_half, right_half));
5358
for idx in 0..16 {
@@ -94,7 +99,7 @@ fn key_kn_from_pair(left: i64, right: i64) -> i64 {
9499
}
95100

96101

97-
fn convert_pairs_to_encrypted_48_bit_keys(pairs: Vec<(i64, i64)>) -> Vec<i64> {
102+
fn convert_pairs_to_encrypted_48_bit_keys(pairs: &Vec<(i64, i64)>) -> Vec<i64> {
98103
let mut keys_48_bit : Vec<i64> = Vec::new();
99104
for idx in 0..pairs.len() {
100105
keys_48_bit.push(key_kn_from_pair(pairs[idx].0, pairs[idx].1));
@@ -139,14 +144,16 @@ const E_TABLE : [u8; 48] = [
139144
28, 29,30, 31, 32, 1
140145
];
141146

147+
142148
fn encode_function(block_32bit: i64, block_48bit: i64) -> i64 {
143-
let expanded_block = expand_32bit_block_to_48bit_block_using_Etable(block_32bit);
149+
let expanded_block = expand_32bit_block_to_48bit_block_using_e_table(block_32bit);
144150
let xored = block_48bit ^ expanded_block;
145-
0
151+
let shrinked_xor = shrink_48bit_block_to_32bit_block_with_s_tables(xored);
152+
permutate_block_32bit_with_p_table(shrinked_xor)
146153
}
147154

148155

149-
fn expand_32bit_block_to_48bit_block_using_Etable(block : i64) -> i64 {
156+
fn expand_32bit_block_to_48bit_block_using_e_table(block : i64) -> i64 {
150157
let mut expanded = 0i64;
151158
for idx in 0..48 {
152159
let bit_at_index = (block >> (32 - E_TABLE[idx])) & 1;
@@ -157,24 +164,46 @@ fn expand_32bit_block_to_48bit_block_using_Etable(block : i64) -> i64 {
157164
}
158165

159166

160-
fn shrink_48bit_block_to_32bit_block_with_Stables(block_48bit : i64) -> i64 {
167+
fn shrink_48bit_block_to_32bit_block_with_s_tables(block_48bit : i64) -> i64 {
161168
let mut shrinked = 0i64;
162169
let block_6bit_count = 8;
163170
for idx in 0..block_6bit_count {
164171
let ones_at_block_index = bit_pattern_ones(6) << (42 - 6 * idx);
165-
let only_6bit_block = ((ones_at_block_index) & block_48bit);
172+
let only_6bit_block = (ones_at_block_index) & block_48bit;
166173
let block_shited_left = only_6bit_block >> (42 - 6 * idx);
167174
let row_idx = (block_shited_left & 0b00001) | ((block_shited_left & 0b100000) >> 4);
168175
let col_idx = (block_shited_left & 0b011110) >> 1;
169-
let block_4bit = value_from_S_at_position((idx + 1) as u8, row_idx as u8, col_idx as u8) as i64;
176+
let block_4bit = value_from_s_table_with_index((idx + 1) as u8, row_idx as u8, col_idx as u8) as i64;
170177
shrinked = (shrinked << 4) | block_4bit;
171178
}
172179
shrinked
173180
}
174181

175182

176-
fn value_from_S_at_position(theS: u8, row : u8, col: u8) -> u8 {
177-
match theS {
183+
const P : [u8; 32] = [
184+
16, 7,20,21,
185+
29,12,28,17,
186+
1,15,23,26,
187+
5,18,31,10,
188+
2, 8,24,14,
189+
32,27, 3, 9,
190+
19,13,30, 6,
191+
22,11, 4,25
192+
];
193+
194+
195+
fn permutate_block_32bit_with_p_table(block_32bit : i64) -> i64 {
196+
let mut permutated = 0i64;
197+
for idx in 0..32 {
198+
let bit_at_index = (block_32bit >> (32 - P[idx])) & 1;
199+
permutated = permutated << 1;
200+
permutated = permutated | bit_at_index;
201+
}
202+
permutated
203+
}
204+
205+
fn value_from_s_table_with_index(s_idx: u8, row : u8, col: u8) -> u8 {
206+
match s_idx {
178207
1 if row < 4 && col < 16 => S1[(row * 16 + col) as usize],
179208
2 if row < 4 && col < 16 => S2[(row * 16 + col) as usize],
180209
3 if row < 4 && col < 16 => S3[(row * 16 + col) as usize],
@@ -188,6 +217,44 @@ fn value_from_S_at_position(theS: u8, row : u8, col: u8) -> u8 {
188217
}
189218

190219

220+
fn produce_right_block_32bit(left_block_32bit: i64,prev_right_block_32bit : i64, block_48bit: i64) -> i64 {
221+
left_block_32bit ^ encode_function(prev_right_block_32bit, block_48bit)
222+
}
223+
224+
225+
fn generate_last_pair_of_32bit_blocks(left_block : i64, right_block : i64, blocks_48bit: &Vec<i64>) -> (i64,i64) {
226+
let mut pair = (left_block, right_block);
227+
for idx in 0..blocks_48bit.len() {
228+
let next_left = pair.1;
229+
let next_right = produce_right_block_32bit(pair.0, pair.1, blocks_48bit[idx]);
230+
pair = (next_left, next_right);
231+
}
232+
pair
233+
}
234+
235+
236+
const IP_INVERSE : [u8; 64] = [
237+
40, 8, 48, 16, 56, 24, 64, 32,
238+
39, 7, 47, 15, 55, 23, 63, 31,
239+
38, 6, 46, 14, 54, 22, 62, 30,
240+
37, 5, 45, 13, 53, 21, 61, 29,
241+
36, 4, 44, 12, 52, 20, 60, 28,
242+
35, 3, 43, 11, 51, 19, 59, 27,
243+
34, 2, 42, 10, 50, 18, 58, 26,
244+
33, 1, 41, 9, 49, 17, 57, 25
245+
];
246+
fn last_permutation_with_ip_table(pair : (i64, i64)) -> i64 {
247+
let block = (pair.1 << 32) | pair.0;
248+
let mut permutation = 0i64;
249+
for idx in 0..64 {
250+
let bit_at_index_in_message = (block >> (64 - IP_INVERSE[idx])) & 1;
251+
permutation = permutation << 1;
252+
permutation = permutation | bit_at_index_in_message;
253+
}
254+
permutation
255+
}
256+
257+
191258
//S-Boxes :
192259
const S1 : [u8; 64] = [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
193260
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
@@ -257,7 +324,7 @@ fn ones_for_2_is_11() {
257324
#[cfg(test)]
258325
#[test]
259326
fn creating_vector_with_keys_returns_correct_subkeys() {
260-
let subkeys = create_16_subkeys(0xf0ccaaf, 0x556678f);
327+
let subkeys = create_16_pairs_blocks_32bit(0xf0ccaaf, 0x556678f);
261328
assert_eq!(16, subkeys.len());
262329
//1
263330
assert_eq!(0b1110000110011001010101011111, subkeys[0].0);
@@ -373,7 +440,7 @@ fn get_48_bit_keys_from_array_of_28_bit_pairs() {
373440
0b111011001000010010110111111101100001100010111100,
374441
0b111101111000101000111010110000010011101111111011];
375442

376-
assert_eq!(expected, convert_pairs_to_encrypted_48_bit_keys(pairs_28_bit));
443+
assert_eq!(expected, convert_pairs_to_encrypted_48_bit_keys(&pairs_28_bit));
377444
}
378445

379446

@@ -403,7 +470,7 @@ fn splitting_key_of_64_bit_into_32_bit_pair() {
403470
fn expand_f0aaf0aa_using_Etable_will_result_7a15557a1555() {
404471
let block_32bit = 0b11110000101010101111000010101010;
405472
let expected_block = 0b011110100001010101010101011110100001010101010101;
406-
assert_eq!(expected_block, expand_32bit_block_to_48bit_block_using_Etable(block_32bit));
473+
assert_eq!(expected_block, expand_32bit_block_to_48bit_block_using_e_table(block_32bit));
407474
}
408475

409476
#[cfg(test)]
@@ -413,7 +480,7 @@ fn expand_f0aaf0aa_using_Etable_will_result_7a15557a1555() {
413480
fn shirnk_6117ba866537_using_Stable_will_result_5c82b597() {
414481
let block_48bit = 0x6117ba866527;
415482
let expected_output = 0x5c82b597;
416-
assert_eq!(expected_output, shrink_48bit_block_to_32bit_block_with_Stables(block_48bit));
483+
assert_eq!(expected_output, shrink_48bit_block_to_32bit_block_with_s_tables(block_48bit));
417484
}
418485

419486

@@ -424,5 +491,84 @@ fn value_in_5th_S_position_2_10_is_12() {
424491
let row = 2u8;
425492
let col = 10u8;
426493
let expected = 12u8;
427-
assert_eq!(expected, value_from_S_at_position(Stable_index, row, col));
494+
assert_eq!(expected, value_from_s_table_with_index(Stable_index, row, col));
495+
}
496+
497+
498+
#[cfg(test)]
499+
#[test]
500+
fn test_value_from_s_table_is_0_when_row_or_col_is_too_big() {
501+
let s_table_index = 4;
502+
let row = 4;
503+
let col = 15;
504+
let expected = 0;
505+
assert_eq!(expected, value_from_s_table_with_index(s_table_index, row, col));
506+
}
507+
508+
509+
#[cfg(test)]
510+
#[test]
511+
//1111 0000 1010 1010 1111 0000 1010 1010
512+
//0001 1011 0000 0010 1110 1111 1111 1100 0111 0000 0111 0010
513+
514+
//0010 0011 0100 1010 1010 1001 1011 1011
515+
fn encode_function_returns_234aa9bb() {
516+
let (block_32bit, block_48bit) = (0xf0aaf0aa, 0x1b02effc7072);
517+
let output = 0x234aa9bb;
518+
assert_eq!(output, encode_function(block_32bit, block_48bit));
519+
}
520+
521+
522+
#[cfg(test)]
523+
#[test]
524+
//0101 1100 1000 0010 1011 0101 1001 0111
525+
//0010 0011 0100 1010 1010 1001 1011 1011
526+
fn permutate_5c82b597_by_P_table_will_output_234559bb() {
527+
let input = 0x5c82b597;
528+
let output = 0x234aa9bb;
529+
assert_eq!(output, permutate_block_32bit_with_p_table(input));
530+
}
531+
532+
533+
#[cfg(test)]
534+
#[test]
535+
//l0 = 1100 1100 0000 0000 1100 1100 1111 1111
536+
//r0 = 1111 0000 1010 1010 1111 0000 1010 1010
537+
//K1 = 0001 1011 0000 0010 1110 1111 1111 1100 0111 0000 0111 0010
538+
//R1 = 1110 1111 0100 1010 0110 0101 0100 0100
539+
fn right_block_R1_created_from_l0_r0_K1() {
540+
let l0 = 0xcc00ccff;
541+
let r0 = 0xf0aaf0aa;
542+
let K1 = 0x1b02effc7072;
543+
let R1 = 0xef4a6544;
544+
assert_eq!(R1, produce_right_block_32bit(l0, r0, K1));
545+
}
546+
547+
548+
#[cfg(test)]
549+
#[test]
550+
//l0 = 1100 1100 0000 0000 1100 1100 1111 1111
551+
//r0 = 1111 0000 1010 1010 1111 0000 1010 1010
552+
//L16 = 0100 0011 0100 0010 0011 0010 0011 0100
553+
//R16 = 0000 1010 0100 1100 1101 1001 1001 0101
554+
fn final_pair_is_generated() {
555+
let l0 = 0xcc00ccff;
556+
let r0 = 0xf0aaf0aa;
557+
558+
let L16 = 0x43423234;
559+
let R16 = 0xA4CD995;
560+
//because this 2 functions are tested they are safe to call here
561+
let subkeys = create_16_pairs_blocks_32bit(0xf0ccaaf, 0x556678f);
562+
let keys_block_48bit = convert_pairs_to_encrypted_48_bit_keys(&subkeys);
563+
assert_eq!((L16, R16), generate_last_pair_of_32bit_blocks(l0, r0, &keys_block_48bit));
564+
}
565+
566+
567+
#[cfg(test)]
568+
#[test]
569+
fn final_permutation_is_85E813540F0AB405_from_43423234_and_A4CD995() {
570+
let L16 = 0x43423234;
571+
let R16 = 0xA4CD995;
572+
let permutation = 0x85E813540F0AB405;
573+
assert_eq!(permutation, last_permutation_with_ip_table((L16, R16)));
428574
}

0 commit comments

Comments
 (0)