@@ -4,14 +4,19 @@ const KEY : i64 = 0x133457799BBCDFF1;
4
4
5
5
6
6
fn main ( ) {
7
+
7
8
let key_plus = generate_key_plus ( KEY ) ;
8
9
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) ;
11
12
12
13
let message_permutation = initial_permutation_of_64bit_message ( MESS ) ;
13
14
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) ;
15
20
}
16
21
17
22
@@ -47,7 +52,7 @@ fn split_key(key : i64, key_len: u8) -> (i64, i64) {
47
52
48
53
const LEFT_SHIFTS : [ u8 ; 16 ] = [ 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 ] ;
49
54
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 ) > {
51
56
let mut subkeys : Vec < ( i64 , i64 ) > = Vec :: new ( ) ;
52
57
subkeys. push ( ( left_half, right_half) ) ;
53
58
for idx in 0 ..16 {
@@ -94,7 +99,7 @@ fn key_kn_from_pair(left: i64, right: i64) -> i64 {
94
99
}
95
100
96
101
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 > {
98
103
let mut keys_48_bit : Vec < i64 > = Vec :: new ( ) ;
99
104
for idx in 0 ..pairs. len ( ) {
100
105
keys_48_bit. push ( key_kn_from_pair ( pairs[ idx] . 0 , pairs[ idx] . 1 ) ) ;
@@ -139,14 +144,16 @@ const E_TABLE : [u8; 48] = [
139
144
28 , 29 , 30 , 31 , 32 , 1
140
145
] ;
141
146
147
+
142
148
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) ;
144
150
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)
146
153
}
147
154
148
155
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 {
150
157
let mut expanded = 0i64 ;
151
158
for idx in 0 ..48 {
152
159
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 {
157
164
}
158
165
159
166
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 {
161
168
let mut shrinked = 0i64 ;
162
169
let block_6bit_count = 8 ;
163
170
for idx in 0 ..block_6bit_count {
164
171
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;
166
173
let block_shited_left = only_6bit_block >> ( 42 - 6 * idx) ;
167
174
let row_idx = ( block_shited_left & 0b00001 ) | ( ( block_shited_left & 0b100000 ) >> 4 ) ;
168
175
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 ;
170
177
shrinked = ( shrinked << 4 ) | block_4bit;
171
178
}
172
179
shrinked
173
180
}
174
181
175
182
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 {
178
207
1 if row < 4 && col < 16 => S1 [ ( row * 16 + col) as usize ] ,
179
208
2 if row < 4 && col < 16 => S2 [ ( row * 16 + col) as usize ] ,
180
209
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 {
188
217
}
189
218
190
219
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
+
191
258
//S-Boxes :
192
259
const S1 : [ u8 ; 64 ] = [ 14 , 4 , 13 , 1 , 2 , 15 , 11 , 8 , 3 , 10 , 6 , 12 , 5 , 9 , 0 , 7 ,
193
260
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() {
257
324
#[ cfg( test) ]
258
325
#[ test]
259
326
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 ) ;
261
328
assert_eq ! ( 16 , subkeys. len( ) ) ;
262
329
//1
263
330
assert_eq ! ( 0b1110000110011001010101011111 , subkeys[ 0 ] . 0 ) ;
@@ -373,7 +440,7 @@ fn get_48_bit_keys_from_array_of_28_bit_pairs() {
373
440
0b111011001000010010110111111101100001100010111100 ,
374
441
0b111101111000101000111010110000010011101111111011 ] ;
375
442
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) ) ;
377
444
}
378
445
379
446
@@ -403,7 +470,7 @@ fn splitting_key_of_64_bit_into_32_bit_pair() {
403
470
fn expand_f0aaf0aa_using_Etable_will_result_7a15557a1555 ( ) {
404
471
let block_32bit = 0b11110000101010101111000010101010 ;
405
472
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) ) ;
407
474
}
408
475
409
476
#[ cfg( test) ]
@@ -413,7 +480,7 @@ fn expand_f0aaf0aa_using_Etable_will_result_7a15557a1555() {
413
480
fn shirnk_6117ba866537_using_Stable_will_result_5c82b597 ( ) {
414
481
let block_48bit = 0x6117ba866527 ;
415
482
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) ) ;
417
484
}
418
485
419
486
@@ -424,5 +491,84 @@ fn value_in_5th_S_position_2_10_is_12() {
424
491
let row = 2u8 ;
425
492
let col = 10u8 ;
426
493
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 ) ) ) ;
428
574
}
0 commit comments