@@ -4,14 +4,19 @@ const KEY : i64 = 0x133457799BBCDFF1;
44
55
66fn 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
4853const 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+
142148fn 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 :
192259const 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]
259326fn 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() {
403470fn 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() {
413480fn 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