-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEncryptionLib.py
More file actions
1789 lines (1474 loc) · 93 KB
/
Copy pathEncryptionLib.py
File metadata and controls
1789 lines (1474 loc) · 93 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import math
import random
import socket
import threading
import time
import Operators as op
# Global Variable used for communications with AES and 3DES
socketHolder = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
class AES:
"""
Creates an aes object which can encrypt and decrypt any message or file given a key using the encrypt
and decrypt methods.
"""
# ------INITIALIZE NECESSARY LOOKUP TABLES----------
# Rijndael S-box
sbox = ['01100011', '01111100', '01110111', '01111011', '11110010', '01101011', '01101111', '11000101',
'00110000', '00000001', '01100111', '00101011', '11111110', '11010111', '10101011', '01110110',
'11001010', '10000010', '11001001', '01111101', '11111010', '01011001', '01000111', '11110000',
'10101101', '11010100', '10100010', '10101111', '10011100', '10100100', '01110010', '11000000',
'10110111', '11111101', '10010011', '00100110', '00110110', '00111111', '11110111', '11001100',
'00110100', '10100101', '11100101', '11110001', '01110001', '11011000', '00110001', '00010101',
'00000100', '11000111', '00100011', '11000011', '00011000', '10010110', '00000101', '10011010',
'00000111', '00010010', '10000000', '11100010', '11101011', '00100111', '10110010', '01110101',
'00001001', '10000011', '00101100', '00011010', '00011011', '01101110', '01011010', '10100000',
'01010010', '00111011', '11010110', '10110011', '00101001', '11100011', '00101111', '10000100',
'01010011', '11010001', '00000000', '11101101', '00100000', '11111100', '10110001', '01011011',
'01101010', '11001011', '10111110', '00111001', '01001010', '01001100', '01011000', '11001111',
'11010000', '11101111', '10101010', '11111011', '01000011', '01001101', '00110011', '10000101',
'01000101', '11111001', '00000010', '01111111', '01010000', '00111100', '10011111', '10101000',
'01010001', '10100011', '01000000', '10001111', '10010010', '10011101', '00111000', '11110101',
'10111100', '10110110', '11011010', '00100001', '00010000', '11111111', '11110011', '11010010',
'11001101', '00001100', '00010011', '11101100', '01011111', '10010111', '01000100', '00010111',
'11000100', '10100111', '01111110', '00111101', '01100100', '01011101', '00011001', '01110011',
'01100000', '10000001', '01001111', '11011100', '00100010', '00101010', '10010000', '10001000',
'01000110', '11101110', '10111000', '00010100', '11011110', '01011110', '00001011', '11011011',
'11100000', '00110010', '00111010', '00001010', '01001001', '00000110', '00100100', '01011100',
'11000010', '11010011', '10101100', '01100010', '10010001', '10010101', '11100100', '01111001',
'11100111', '11001000', '00110111', '01101101', '10001101', '11010101', '01001110', '10101001',
'01101100', '01010110', '11110100', '11101010', '01100101', '01111010', '10101110', '00001000',
'10111010', '01111000', '00100101', '00101110', '00011100', '10100110', '10110100', '11000110',
'11101000', '11011101', '01110100', '00011111', '01001011', '10111101', '10001011', '10001010',
'01110000', '00111110', '10110101', '01100110', '01001000', '00000011', '11110110', '00001110',
'01100001', '00110101', '01010111', '10111001', '10000110', '11000001', '00011101', '10011110',
'11100001', '11111000', '10011000', '00010001', '01101001', '11011001', '10001110', '10010100',
'10011011', '00011110', '10000111', '11101001', '11001110', '01010101', '00101000', '11011111',
'10001100', '10100001', '10001001', '00001101', '10111111', '11100110', '01000010', '01101000',
'01000001', '10011001', '00101101', '00001111', '10110000', '01010100', '10111011', '00010110']
# Galois field multiplication by 2
mul2 = ['00000000', '00000010', '00000100', '00000110', '00001000', '00001010', '00001100', '00001110',
'00010000', '00010010', '00010100', '00010110', '00011000', '00011010', '00011100', '00011110',
'00100000', '00100010', '00100100', '00100110', '00101000', '00101010', '00101100', '00101110',
'00110000', '00110010', '00110100', '00110110', '00111000', '00111010', '00111100', '00111110',
'01000000', '01000010', '01000100', '01000110', '01001000', '01001010', '01001100', '01001110',
'01010000', '01010010', '01010100', '01010110', '01011000', '01011010', '01011100', '01011110',
'01100000', '01100010', '01100100', '01100110', '01101000', '01101010', '01101100', '01101110',
'01110000', '01110010', '01110100', '01110110', '01111000', '01111010', '01111100', '01111110',
'10000000', '10000010', '10000100', '10000110', '10001000', '10001010', '10001100', '10001110',
'10010000', '10010010', '10010100', '10010110', '10011000', '10011010', '10011100', '10011110',
'10100000', '10100010', '10100100', '10100110', '10101000', '10101010', '10101100', '10101110',
'10110000', '10110010', '10110100', '10110110', '10111000', '10111010', '10111100', '10111110',
'11000000', '11000010', '11000100', '11000110', '11001000', '11001010', '11001100', '11001110',
'11010000', '11010010', '11010100', '11010110', '11011000', '11011010', '11011100', '11011110',
'11100000', '11100010', '11100100', '11100110', '11101000', '11101010', '11101100', '11101110',
'11110000', '11110010', '11110100', '11110110', '11111000', '11111010', '11111100', '11111110',
'00011011', '00011001', '00011111', '00011101', '00010011', '00010001', '00010111', '00010101',
'00001011', '00001001', '00001111', '00001101', '00000011', '00000001', '00000111', '00000101',
'00111011', '00111001', '00111111', '00111101', '00110011', '00110001', '00110111', '00110101',
'00101011', '00101001', '00101111', '00101101', '00100011', '00100001', '00100111', '00100101',
'01011011', '01011001', '01011111', '01011101', '01010011', '01010001', '01010111', '01010101',
'01001011', '01001001', '01001111', '01001101', '01000011', '01000001', '01000111', '01000101',
'01111011', '01111001', '01111111', '01111101', '01110011', '01110001', '01110111', '01110101',
'01101011', '01101001', '01101111', '01101101', '01100011', '01100001', '01100111', '01100101',
'10011011', '10011001', '10011111', '10011101', '10010011', '10010001', '10010111', '10010101',
'10001011', '10001001', '10001111', '10001101', '10000011', '10000001', '10000111', '10000101',
'10111011', '10111001', '10111111', '10111101', '10110011', '10110001', '10110111', '10110101',
'10101011', '10101001', '10101111', '10101101', '10100011', '10100001', '10100111', '10100101',
'11011011', '11011001', '11011111', '11011101', '11010011', '11010001', '11010111', '11010101',
'11001011', '11001001', '11001111', '11001101', '11000011', '11000001', '11000111', '11000101',
'11111011', '11111001', '11111111', '11111101', '11110011', '11110001', '11110111', '11110101',
'11101011', '11101001', '11101111', '11101101', '11100011', '11100001', '11100111', '11100101']
# Galois field multiplication by 3
mul3 = ['00000000', '00000011', '00000110', '00000101', '00001100', '00001111', '00001010', '00001001',
'00011000', '00011011', '00011110', '00011101', '00010100', '00010111', '00010010', '00010001',
'00110000', '00110011', '00110110', '00110101', '00111100', '00111111', '00111010', '00111001',
'00101000', '00101011', '00101110', '00101101', '00100100', '00100111', '00100010', '00100001',
'01100000', '01100011', '01100110', '01100101', '01101100', '01101111', '01101010', '01101001',
'01111000', '01111011', '01111110', '01111101', '01110100', '01110111', '01110010', '01110001',
'01010000', '01010011', '01010110', '01010101', '01011100', '01011111', '01011010', '01011001',
'01001000', '01001011', '01001110', '01001101', '01000100', '01000111', '01000010', '01000001',
'11000000', '11000011', '11000110', '11000101', '11001100', '11001111', '11001010', '11001001',
'11011000', '11011011', '11011110', '11011101', '11010100', '11010111', '11010010', '11010001',
'11110000', '11110011', '11110110', '11110101', '11111100', '11111111', '11111010', '11111001',
'11101000', '11101011', '11101110', '11101101', '11100100', '11100111', '11100010', '11100001',
'10100000', '10100011', '10100110', '10100101', '10101100', '10101111', '10101010', '10101001',
'10111000', '10111011', '10111110', '10111101', '10110100', '10110111', '10110010', '10110001',
'10010000', '10010011', '10010110', '10010101', '10011100', '10011111', '10011010', '10011001',
'10001000', '10001011', '10001110', '10001101', '10000100', '10000111', '10000010', '10000001',
'10011011', '10011000', '10011101', '10011110', '10010111', '10010100', '10010001', '10010010',
'10000011', '10000000', '10000101', '10000110', '10001111', '10001100', '10001001', '10001010',
'10101011', '10101000', '10101101', '10101110', '10100111', '10100100', '10100001', '10100010',
'10110011', '10110000', '10110101', '10110110', '10111111', '10111100', '10111001', '10111010',
'11111011', '11111000', '11111101', '11111110', '11110111', '11110100', '11110001', '11110010',
'11100011', '11100000', '11100101', '11100110', '11101111', '11101100', '11101001', '11101010',
'11001011', '11001000', '11001101', '11001110', '11000111', '11000100', '11000001', '11000010',
'11010011', '11010000', '11010101', '11010110', '11011111', '11011100', '11011001', '11011010',
'01011011', '01011000', '01011101', '01011110', '01010111', '01010100', '01010001', '01010010',
'01000011', '01000000', '01000101', '01000110', '01001111', '01001100', '01001001', '01001010',
'01101011', '01101000', '01101101', '01101110', '01100111', '01100100', '01100001', '01100010',
'01110011', '01110000', '01110101', '01110110', '01111111', '01111100', '01111001', '01111010',
'00111011', '00111000', '00111101', '00111110', '00110111', '00110100', '00110001', '00110010',
'00100011', '00100000', '00100101', '00100110', '00101111', '00101100', '00101001', '00101010',
'00001011', '00001000', '00001101', '00001110', '00000111', '00000100', '00000001', '00000010',
'00010011', '00010000', '00010101', '00010110', '00011111', '00011100', '00011001', '00011010']
# RCon Index
rcon = ['10001101', '00000001', '00000010', '00000100', '00001000', '00010000', '00100000', '01000000',
'10000000', '00011011', '00110110', '01101100', '11011000', '10101011', '01001101', '10011010',
'00101111', '01011110', '10111100', '01100011', '11000110', '10010111', '00110101', '01101010',
'11010100', '10110011', '01111101', '11111010', '11101111', '11000101', '10010001', '00111001',
'01110010', '11100100', '11010011', '10111101', '01100001', '11000010', '10011111', '00100101',
'01001010', '10010100', '00110011', '01100110', '11001100', '10000011', '00011101', '00111010',
'01110100', '11101000', '11001011', '10001101', '00000001', '00000010', '00000100', '00001000',
'00010000', '00100000', '01000000', '10000000', '00011011', '00110110', '01101100', '11011000',
'10101011', '01001101', '10011010', '00101111', '01011110', '10111100', '01100011', '11000110',
'10010111', '00110101', '01101010', '11010100', '10110011', '01111101', '11111010', '11101111',
'11000101', '10010001', '00111001', '01110010', '11100100', '11010011', '10111101', '01100001',
'11000010', '10011111', '00100101', '01001010', '10010100', '00110011', '01100110', '11001100',
'10000011', '00011101', '00111010', '01110100', '11101000', '11001011', '10001101', '00000001',
'00000010', '00000100', '00001000', '00010000', '00100000', '01000000', '10000000', '00011011',
'00110110', '01101100', '11011000', '10101011', '01001101', '10011010', '00101111', '01011110',
'10111100', '01100011', '11000110', '10010111', '00110101', '01101010', '11010100', '10110011',
'01111101', '11111010', '11101111', '11000101', '10010001', '00111001', '01110010', '11100100',
'11010011', '10111101', '01100001', '11000010', '10011111', '00100101', '01001010', '10010100',
'00110011', '01100110', '11001100', '10000011', '00011101', '00111010', '01110100', '11101000',
'11001011', '10001101', '00000001', '00000010', '00000100', '00001000', '00010000', '00100000',
'01000000', '10000000', '00011011', '00110110', '01101100', '11011000', '10101011', '01001101',
'10011010', '00101111', '01011110', '10111100', '01100011', '11000110', '10010111', '00110101',
'01101010', '11010100', '10110011', '01111101', '11111010', '11101111', '11000101', '10010001',
'00111001', '01110010', '11100100', '11010011', '10111101', '01100001', '11000010', '10011111',
'00100101', '01001010', '10010100', '00110011', '01100110', '11001100', '10000011', '00011101',
'00111010', '01110100', '11101000', '11001011', '10001101', '00000001', '00000010', '00000100',
'00001000', '00010000', '00100000', '01000000', '10000000', '00011011', '00110110', '01101100',
'11011000', '10101011', '01001101', '10011010', '00101111', '01011110', '10111100', '01100011',
'11000110', '10010111', '00110101', '01101010', '11010100', '10110011', '01111101', '11111010',
'11101111', '11000101', '10010001', '00111001', '01110010', '11100100', '11010011', '10111101',
'01100001', '11000010', '10011111', '00100101', '01001010', '10010100', '00110011', '01100110',
'11001100', '10000011', '00011101', '00111010', '01110100', '11101000', '11001011', '10001101']
# -------INVERSE LOOKUP TABLES FOR DECRYPTION ----------
# Inverse S-Box
inv_sbox = ['01010010', '00001001', '01101010', '11010101', '00110000', '00110110', '10100101', '00111000',
'10111111', '01000000', '10100011', '10011110', '10000001', '11110011', '11010111', '11111011',
'01111100', '11100011', '00111001', '10000010', '10011011', '00101111', '11111111', '10000111',
'00110100', '10001110', '01000011', '01000100', '11000100', '11011110', '11101001', '11001011',
'01010100', '01111011', '10010100', '00110010', '10100110', '11000010', '00100011', '00111101',
'11101110', '01001100', '10010101', '00001011', '01000010', '11111010', '11000011', '01001110',
'00001000', '00101110', '10100001', '01100110', '00101000', '11011001', '00100100', '10110010',
'01110110', '01011011', '10100010', '01001001', '01101101', '10001011', '11010001', '00100101',
'01110010', '11111000', '11110110', '01100100', '10000110', '01101000', '10011000', '00010110',
'11010100', '10100100', '01011100', '11001100', '01011101', '01100101', '10110110', '10010010',
'01101100', '01110000', '01001000', '01010000', '11111101', '11101101', '10111001', '11011010',
'01011110', '00010101', '01000110', '01010111', '10100111', '10001101', '10011101', '10000100',
'10010000', '11011000', '10101011', '00000000', '10001100', '10111100', '11010011', '00001010',
'11110111', '11100100', '01011000', '00000101', '10111000', '10110011', '01000101', '00000110',
'11010000', '00101100', '00011110', '10001111', '11001010', '00111111', '00001111', '00000010',
'11000001', '10101111', '10111101', '00000011', '00000001', '00010011', '10001010', '01101011',
'00111010', '10010001', '00010001', '01000001', '01001111', '01100111', '11011100', '11101010',
'10010111', '11110010', '11001111', '11001110', '11110000', '10110100', '11100110', '01110011',
'10010110', '10101100', '01110100', '00100010', '11100111', '10101101', '00110101', '10000101',
'11100010', '11111001', '00110111', '11101000', '00011100', '01110101', '11011111', '01101110',
'01000111', '11110001', '00011010', '01110001', '00011101', '00101001', '11000101', '10001001',
'01101111', '10110111', '01100010', '00001110', '10101010', '00011000', '10111110', '00011011',
'11111100', '01010110', '00111110', '01001011', '11000110', '11010010', '01111001', '00100000',
'10011010', '11011011', '11000000', '11111110', '01111000', '11001101', '01011010', '11110100',
'00011111', '11011101', '10101000', '00110011', '10001000', '00000111', '11000111', '00110001',
'10110001', '00010010', '00010000', '01011001', '00100111', '10000000', '11101100', '01011111',
'01100000', '01010001', '01111111', '10101001', '00011001', '10110101', '01001010', '00001101',
'00101101', '11100101', '01111010', '10011111', '10010011', '11001001', '10011100', '11101111',
'10100000', '11100000', '00111011', '01001101', '10101110', '00101010', '11110101', '10110000',
'11001000', '11101011', '10111011', '00111100', '10000011', '01010011', '10011001', '01100001',
'00010111', '00101011', '00000100', '01111110', '10111010', '01110111', '11010110', '00100110',
'11100001', '01101001', '00010100', '01100011', '01010101', '00100001', '00001100', '01111101']
# Multiplication by 9
mul9 = ['00000000', '00001001', '00010010', '00011011', '00100100', '00101101', '00110110', '00111111',
'01001000', '01000001', '01011010', '01010011', '01101100', '01100101', '01111110', '01110111',
'10010000', '10011001', '10000010', '10001011', '10110100', '10111101', '10100110', '10101111',
'11011000', '11010001', '11001010', '11000011', '11111100', '11110101', '11101110', '11100111',
'00111011', '00110010', '00101001', '00100000', '00011111', '00010110', '00001101', '00000100',
'01110011', '01111010', '01100001', '01101000', '01010111', '01011110', '01000101', '01001100',
'10101011', '10100010', '10111001', '10110000', '10001111', '10000110', '10011101', '10010100',
'11100011', '11101010', '11110001', '11111000', '11000111', '11001110', '11010101', '11011100',
'01110110', '01111111', '01100100', '01101101', '01010010', '01011011', '01000000', '01001001',
'00111110', '00110111', '00101100', '00100101', '00011010', '00010011', '00001000', '00000001',
'11100110', '11101111', '11110100', '11111101', '11000010', '11001011', '11010000', '11011001',
'10101110', '10100111', '10111100', '10110101', '10001010', '10000011', '10011000', '10010001',
'01001101', '01000100', '01011111', '01010110', '01101001', '01100000', '01111011', '01110010',
'00000101', '00001100', '00010111', '00011110', '00100001', '00101000', '00110011', '00111010',
'11011101', '11010100', '11001111', '11000110', '11111001', '11110000', '11101011', '11100010',
'10010101', '10011100', '10000111', '10001110', '10110001', '10111000', '10100011', '10101010',
'11101100', '11100101', '11111110', '11110111', '11001000', '11000001', '11011010', '11010011',
'10100100', '10101101', '10110110', '10111111', '10000000', '10001001', '10010010', '10011011',
'01111100', '01110101', '01101110', '01100111', '01011000', '01010001', '01001010', '01000011',
'00110100', '00111101', '00100110', '00101111', '00010000', '00011001', '00000010', '00001011',
'11010111', '11011110', '11000101', '11001100', '11110011', '11111010', '11100001', '11101000',
'10011111', '10010110', '10001101', '10000100', '10111011', '10110010', '10101001', '10100000',
'01000111', '01001110', '01010101', '01011100', '01100011', '01101010', '01110001', '01111000',
'00001111', '00000110', '00011101', '00010100', '00101011', '00100010', '00111001', '00110000',
'10011010', '10010011', '10001000', '10000001', '10111110', '10110111', '10101100', '10100101',
'11010010', '11011011', '11000000', '11001001', '11110110', '11111111', '11100100', '11101101',
'00001010', '00000011', '00011000', '00010001', '00101110', '00100111', '00111100', '00110101',
'01000010', '01001011', '01010000', '01011001', '01100110', '01101111', '01110100', '01111101',
'10100001', '10101000', '10110011', '10111010', '10000101', '10001100', '10010111', '10011110',
'11101001', '11100000', '11111011', '11110010', '11001101', '11000100', '11011111', '11010110',
'00110001', '00111000', '00100011', '00101010', '00010101', '00011100', '00000111', '00001110',
'01111001', '01110000', '01101011', '01100010', '01011101', '01010100', '01001111', '01000110']
# Multiplication by 11
mul11 = ['00000000', '00001011', '00010110', '00011101', '00101100', '00100111', '00111010', '00110001',
'01011000', '01010011', '01001110', '01000101', '01110100', '01111111', '01100010', '01101001',
'10110000', '10111011', '10100110', '10101101', '10011100', '10010111', '10001010', '10000001',
'11101000', '11100011', '11111110', '11110101', '11000100', '11001111', '11010010', '11011001',
'01111011', '01110000', '01101101', '01100110', '01010111', '01011100', '01000001', '01001010',
'00100011', '00101000', '00110101', '00111110', '00001111', '00000100', '00011001', '00010010',
'11001011', '11000000', '11011101', '11010110', '11100111', '11101100', '11110001', '11111010',
'10010011', '10011000', '10000101', '10001110', '10111111', '10110100', '10101001', '10100010',
'11110110', '11111101', '11100000', '11101011', '11011010', '11010001', '11001100', '11000111',
'10101110', '10100101', '10111000', '10110011', '10000010', '10001001', '10010100', '10011111',
'01000110', '01001101', '01010000', '01011011', '01101010', '01100001', '01111100', '01110111',
'00011110', '00010101', '00001000', '00000011', '00110010', '00111001', '00100100', '00101111',
'10001101', '10000110', '10011011', '10010000', '10100001', '10101010', '10110111', '10111100',
'11010101', '11011110', '11000011', '11001000', '11111001', '11110010', '11101111', '11100100',
'00111101', '00110110', '00101011', '00100000', '00010001', '00011010', '00000111', '00001100',
'01100101', '01101110', '01110011', '01111000', '01001001', '01000010', '01011111', '01010100',
'11110111', '11111100', '11100001', '11101010', '11011011', '11010000', '11001101', '11000110',
'10101111', '10100100', '10111001', '10110010', '10000011', '10001000', '10010101', '10011110',
'01000111', '01001100', '01010001', '01011010', '01101011', '01100000', '01111101', '01110110',
'00011111', '00010100', '00001001', '00000010', '00110011', '00111000', '00100101', '00101110',
'10001100', '10000111', '10011010', '10010001', '10100000', '10101011', '10110110', '10111101',
'11010100', '11011111', '11000010', '11001001', '11111000', '11110011', '11101110', '11100101',
'00111100', '00110111', '00101010', '00100001', '00010000', '00011011', '00000110', '00001101',
'01100100', '01101111', '01110010', '01111001', '01001000', '01000011', '01011110', '01010101',
'00000001', '00001010', '00010111', '00011100', '00101101', '00100110', '00111011', '00110000',
'01011001', '01010010', '01001111', '01000100', '01110101', '01111110', '01100011', '01101000',
'10110001', '10111010', '10100111', '10101100', '10011101', '10010110', '10001011', '10000000',
'11101001', '11100010', '11111111', '11110100', '11000101', '11001110', '11010011', '11011000',
'01111010', '01110001', '01101100', '01100111', '01010110', '01011101', '01000000', '01001011',
'00100010', '00101001', '00110100', '00111111', '00001110', '00000101', '00011000', '00010011',
'11001010', '11000001', '11011100', '11010111', '11100110', '11101101', '11110000', '11111011',
'10010010', '10011001', '10000100', '10001111', '10111110', '10110101', '10101000', '10100011']
# Mutiplication by 13
mul13 = ['00000000', '00001101', '00011010', '00010111', '00110100', '00111001', '00101110', '00100011',
'01101000', '01100101', '01110010', '01111111', '01011100', '01010001', '01000110', '01001011',
'11010000', '11011101', '11001010', '11000111', '11100100', '11101001', '11111110', '11110011',
'10111000', '10110101', '10100010', '10101111', '10001100', '10000001', '10010110', '10011011',
'10111011', '10110110', '10100001', '10101100', '10001111', '10000010', '10010101', '10011000',
'11010011', '11011110', '11001001', '11000100', '11100111', '11101010', '11111101', '11110000',
'01101011', '01100110', '01110001', '01111100', '01011111', '01010010', '01000101', '01001000',
'00000011', '00001110', '00011001', '00010100', '00110111', '00111010', '00101101', '00100000',
'01101101', '01100000', '01110111', '01111010', '01011001', '01010100', '01000011', '01001110',
'00000101', '00001000', '00011111', '00010010', '00110001', '00111100', '00101011', '00100110',
'10111101', '10110000', '10100111', '10101010', '10001001', '10000100', '10010011', '10011110',
'11010101', '11011000', '11001111', '11000010', '11100001', '11101100', '11111011', '11110110',
'11010110', '11011011', '11001100', '11000001', '11100010', '11101111', '11111000', '11110101',
'10111110', '10110011', '10100100', '10101001', '10001010', '10000111', '10010000', '10011101',
'00000110', '00001011', '00011100', '00010001', '00110010', '00111111', '00101000', '00100101',
'01101110', '01100011', '01110100', '01111001', '01011010', '01010111', '01000000', '01001101',
'11011010', '11010111', '11000000', '11001101', '11101110', '11100011', '11110100', '11111001',
'10110010', '10111111', '10101000', '10100101', '10000110', '10001011', '10011100', '10010001',
'00001010', '00000111', '00010000', '00011101', '00111110', '00110011', '00100100', '00101001',
'01100010', '01101111', '01111000', '01110101', '01010110', '01011011', '01001100', '01000001',
'01100001', '01101100', '01111011', '01110110', '01010101', '01011000', '01001111', '01000010',
'00001001', '00000100', '00010011', '00011110', '00111101', '00110000', '00100111', '00101010',
'10110001', '10111100', '10101011', '10100110', '10000101', '10001000', '10011111', '10010010',
'11011001', '11010100', '11000011', '11001110', '11101101', '11100000', '11110111', '11111010',
'10110111', '10111010', '10101101', '10100000', '10000011', '10001110', '10011001', '10010100',
'11011111', '11010010', '11000101', '11001000', '11101011', '11100110', '11110001', '11111100',
'01100111', '01101010', '01111101', '01110000', '01010011', '01011110', '01001001', '01000100',
'00001111', '00000010', '00010101', '00011000', '00111011', '00110110', '00100001', '00101100',
'00001100', '00000001', '00010110', '00011011', '00111000', '00110101', '00100010', '00101111',
'01100100', '01101001', '01111110', '01110011', '01010000', '01011101', '01001010', '01000111',
'11011100', '11010001', '11000110', '11001011', '11101000', '11100101', '11110010', '11111111',
'10110100', '10111001', '10101110', '10100011', '10000000', '10001101', '10011010', '10010111']
# Multiplication by 14
mul14 = ['00000000', '00001110', '00011100', '00010010', '00111000', '00110110', '00100100', '00101010',
'01110000', '01111110', '01101100', '01100010', '01001000', '01000110', '01010100', '01011010',
'11100000', '11101110', '11111100', '11110010', '11011000', '11010110', '11000100', '11001010',
'10010000', '10011110', '10001100', '10000010', '10101000', '10100110', '10110100', '10111010',
'11011011', '11010101', '11000111', '11001001', '11100011', '11101101', '11111111', '11110001',
'10101011', '10100101', '10110111', '10111001', '10010011', '10011101', '10001111', '10000001',
'00111011', '00110101', '00100111', '00101001', '00000011', '00001101', '00011111', '00010001',
'01001011', '01000101', '01010111', '01011001', '01110011', '01111101', '01101111', '01100001',
'10101101', '10100011', '10110001', '10111111', '10010101', '10011011', '10001001', '10000111',
'11011101', '11010011', '11000001', '11001111', '11100101', '11101011', '11111001', '11110111',
'01001101', '01000011', '01010001', '01011111', '01110101', '01111011', '01101001', '01100111',
'00111101', '00110011', '00100001', '00101111', '00000101', '00001011', '00011001', '00010111',
'01110110', '01111000', '01101010', '01100100', '01001110', '01000000', '01010010', '01011100',
'00000110', '00001000', '00011010', '00010100', '00111110', '00110000', '00100010', '00101100',
'10010110', '10011000', '10001010', '10000100', '10101110', '10100000', '10110010', '10111100',
'11100110', '11101000', '11111010', '11110100', '11011110', '11010000', '11000010', '11001100',
'01000001', '01001111', '01011101', '01010011', '01111001', '01110111', '01100101', '01101011',
'00110001', '00111111', '00101101', '00100011', '00001001', '00000111', '00010101', '00011011',
'10100001', '10101111', '10111101', '10110011', '10011001', '10010111', '10000101', '10001011',
'11010001', '11011111', '11001101', '11000011', '11101001', '11100111', '11110101', '11111011',
'10011010', '10010100', '10000110', '10001000', '10100010', '10101100', '10111110', '10110000',
'11101010', '11100100', '11110110', '11111000', '11010010', '11011100', '11001110', '11000000',
'01111010', '01110100', '01100110', '01101000', '01000010', '01001100', '01011110', '01010000',
'00001010', '00000100', '00010110', '00011000', '00110010', '00111100', '00101110', '00100000',
'11101100', '11100010', '11110000', '11111110', '11010100', '11011010', '11001000', '11000110',
'10011100', '10010010', '10000000', '10001110', '10100100', '10101010', '10111000', '10110110',
'00001100', '00000010', '00010000', '00011110', '00110100', '00111010', '00101000', '00100110',
'01111100', '01110010', '01100000', '01101110', '01000100', '01001010', '01011000', '01010110',
'00110111', '00111001', '00101011', '00100101', '00001111', '00000001', '00010011', '00011101',
'01000111', '01001001', '01011011', '01010101', '01111111', '01110001', '01100011', '01101101',
'11010111', '11011001', '11001011', '11000101', '11101111', '11100001', '11110011', '11111101',
'10100111', '10101001', '10111011', '10110101', '10011111', '10010001', '10000011', '10001101']
def __init__(self, plainkey):
"""
This init method takes the plain key and manipulates into a byte array used in encryption and decryption
:param plainkey: This is the plainkey that the user enters. This object will use this key for all
encryption and decryption.
"""
self.key = self.getkey(plainkey)
self.key = self.keyexpansion(self.key)
@staticmethod
def keyexpansioncore(byte, index):
"""
:param byte: An array of length 4 with a byte in each index
:param index: This is an index used during the rcon step
:return: Returns a modified version of the param byte
"""
# Rotate Left
temp = [0, 0, 0, 0]
temp[0] = byte[1]
temp[1] = byte[2]
temp[2] = byte[3]
temp[3] = byte[0]
# Substitute using the S-box. Converts the binary to an integer and funds its substitute in the sbox
temp[0] = AES.sbox[op.bintoint(temp[0])]
temp[1] = AES.sbox[op.bintoint(temp[1])]
temp[2] = AES.sbox[op.bintoint(temp[2])]
temp[3] = AES.sbox[op.bintoint(temp[3])]
# RCon
temp[0] = op.bitxor(temp[0], AES.rcon[index])
return temp
def keyexpansion(self, inputkey):
"""
:param inputkey: An array of length 16 with a byte in each index
:return: This function returns an array of length 176 with a byte in each index, the expanded key
"""
# Copies the input key to the expanded key
expandedkey = inputkey
# Variables
bytesgenerated = 16 # The original key is 128 bits or 16 bytes which is what we start with
rconiteration = 1 # Rcon iteration begins at 1
temp = [0, 0, 0, 0] # Temporary storage for bytes
while bytesgenerated < 176:
# Read the last 4 bytes into the core / temp array
for j in range(4):
temp[j] = expandedkey[j + bytesgenerated - 4]
if bytesgenerated % 16 == 0:
temp = self.keyexpansioncore(temp, rconiteration)
rconiteration += 1
for a in range(4):
expandedkey.append(op.bitxor(expandedkey[bytesgenerated - 16], temp[a]))
bytesgenerated += 1
return expandedkey
@staticmethod
def subbytes(state):
"""
:param state: This is an array of length 16 with 1 byte in each index
:return: Returns an array with each index of state substituted with it's match in the Rigndael S-box
"""
newstate = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in range(16):
integer = op.bintoint(state[i])
newstate[i] = AES.sbox[integer]
return newstate
@staticmethod
def inv_subbytes(state):
"""
:param state: This is an array of length 16 with 1 byte in each index
:return: Returns an array with each index of state substituted with it's match in the Rigndael inverse S-box
"""
newstate = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in range(16):
integer = op.bintoint(state[i])
newstate[i] = AES.inv_sbox[integer]
return newstate
@staticmethod
def shiftrows(state):
"""
:param state: This is an array of length 16 with 1 byte in each index
:return: returns the array shifted a specific way.
"""
"""This operation imagines the array of length 16 as a 4x4 grid
0 4 8 12
1 5 9 13
2 6 10 14
3 6 11 15
The first row is not rotated.
The second row is rotated left once.
The third row is rotated left twice.
The fourth row is rotated left three times.
Doing these rotations produces this mapping of the
original grid to the new grid.
"""
temp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
temp[0] = state[0]
temp[1] = state[5]
temp[2] = state[10]
temp[3] = state[15]
temp[4] = state[4]
temp[5] = state[9]
temp[6] = state[14]
temp[7] = state[3]
temp[8] = state[8]
temp[9] = state[13]
temp[10] = state[2]
temp[11] = state[7]
temp[12] = state[12]
temp[13] = state[1]
temp[14] = state[6]
temp[15] = state[11]
return temp
@staticmethod
def inv_shiftrows(state):
"""
:param state: This is an array of length 16 with 1 byte in each index
:return: returns the array shifted a specific way.
"""
"""This operation imagines the array of length 16 as a 4x4 grid
0 4 8 12
1 5 9 13
2 6 10 14
3 6 11 15
The first row is not rotated.
The second row is rotated right once.
The third row is rotated right twice.
The fourth row is rotated right three times.
Doing these rotations produces this mapping of the
original grid to the new grid.
Notice that the indexes of the arrays are swapped from the shiftrows method
"""
temp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
temp[0] = state[0]
temp[5] = state[1]
temp[10] = state[2]
temp[15] = state[3]
temp[4] = state[4]
temp[9] = state[5]
temp[14] = state[6]
temp[3] = state[7]
temp[8] = state[8]
temp[13] = state[9]
temp[2] = state[10]
temp[7] = state[11]
temp[12] = state[12]
temp[1] = state[13]
temp[6] = state[14]
temp[11] = state[15]
return temp
@staticmethod
def mixcolumns(state):
"""
:param state: An array of length 16 with a byte in each index
:return: returns an array of length 16 with a byte in each index
"""
"""
To calculate the new array, this step finds every dot product of 2 matrix's. The first matrix is the state
and the second one is a predetermined one.
These are the 2 matrix's:
s s s s 2 3 1 1
s s s s 1 2 3 1
s s s s 1 1 2 3
s s s s 3 1 1 2
in the new state, p:
p(0) = (s(0) * 2) + (s(1) * 3) + (s(2) * 1) + (s(2) * 1)
p(1) = (s(1) * 2) + (s(2) * 3) + (s(3) * 1) + (s(0) * 1)
....
However unlike a regular dot product, addition is XOR because we are treating each byte as a galois field
GF(2^8). In this case addition is the same as an XOR operation.
And instead of regular multiplication, we use a lookup table. Simply, this is to keep the result within
byte.
"""
tmp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
tmp[0] = op.bitxor(AES.mul2[op.bintoint(state[0])], AES.mul3[op.bintoint(state[1])], state[2], state[3])
tmp[1] = op.bitxor(AES.mul2[op.bintoint(state[1])], AES.mul3[op.bintoint(state[2])], state[3], state[0])
tmp[2] = op.bitxor(AES.mul2[op.bintoint(state[2])], AES.mul3[op.bintoint(state[3])], state[0], state[1])
tmp[3] = op.bitxor(AES.mul2[op.bintoint(state[3])], AES.mul3[op.bintoint(state[0])], state[1], state[2])
tmp[4] = op.bitxor(AES.mul2[op.bintoint(state[4])], AES.mul3[op.bintoint(state[5])], state[6], state[7])
tmp[5] = op.bitxor(AES.mul2[op.bintoint(state[5])], AES.mul3[op.bintoint(state[6])], state[7], state[4])
tmp[6] = op.bitxor(AES.mul2[op.bintoint(state[6])], AES.mul3[op.bintoint(state[7])], state[4], state[5])
tmp[7] = op.bitxor(AES.mul2[op.bintoint(state[7])], AES.mul3[op.bintoint(state[4])], state[5], state[6])
tmp[8] = op.bitxor(AES.mul2[op.bintoint(state[8])], AES.mul3[op.bintoint(state[9])], state[10], state[11])
tmp[9] = op.bitxor(AES.mul2[op.bintoint(state[9])], AES.mul3[op.bintoint(state[10])], state[11], state[8])
tmp[10] = op.bitxor(AES.mul2[op.bintoint(state[10])], AES.mul3[op.bintoint(state[11])], state[8], state[9])
tmp[11] = op.bitxor(AES.mul2[op.bintoint(state[11])], AES.mul3[op.bintoint(state[8])], state[9], state[10])
tmp[12] = op.bitxor(AES.mul2[op.bintoint(state[12])], AES.mul3[op.bintoint(state[13])], state[14],
state[15])
tmp[13] = op.bitxor(AES.mul2[op.bintoint(state[13])], AES.mul3[op.bintoint(state[14])], state[15],
state[12])
tmp[14] = op.bitxor(AES.mul2[op.bintoint(state[14])], AES.mul3[op.bintoint(state[15])], state[12],
state[13])
tmp[15] = op.bitxor(AES.mul2[op.bintoint(state[15])], AES.mul3[op.bintoint(state[12])], state[13],
state[14])
return tmp
@staticmethod
def inv_mixcolumns(state):
"""
:param state: An array of length 16 with a byte in each index
:return: returns an array of length 16 with a byte in each index
"""
"""
To calculate the new array, this step finds every dot product of 2 matrix's. The first matrix is the state
and the second one is a predetermined one.
These are the 2 matrix's:
s s s s 14 11 13 09
s s s s 09 14 11 13
s s s s 13 09 14 11
s s s s 11 13 09 14
This is the exact same as regular mixcolumns except the predetermined matrix is different.
"""
tmp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
tmp[0] = op.bitxor(AES.mul14[op.bintoint(state[0])], AES.mul11[op.bintoint(state[1])],
AES.mul13[op.bintoint(state[2])], AES.mul9[op.bintoint(state[3])])
tmp[1] = op.bitxor(AES.mul14[op.bintoint(state[1])], AES.mul11[op.bintoint(state[2])],
AES.mul13[op.bintoint(state[3])], AES.mul9[op.bintoint(state[0])])
tmp[2] = op.bitxor(AES.mul14[op.bintoint(state[2])], AES.mul11[op.bintoint(state[3])],
AES.mul13[op.bintoint(state[0])], AES.mul9[op.bintoint(state[1])])
tmp[3] = op.bitxor(AES.mul14[op.bintoint(state[3])], AES.mul11[op.bintoint(state[0])],
AES.mul13[op.bintoint(state[1])], AES.mul9[op.bintoint(state[2])])
tmp[4] = op.bitxor(AES.mul14[op.bintoint(state[4])], AES.mul11[op.bintoint(state[5])],
AES.mul13[op.bintoint(state[6])], AES.mul9[op.bintoint(state[7])])
tmp[5] = op.bitxor(AES.mul14[op.bintoint(state[5])], AES.mul11[op.bintoint(state[6])],
AES.mul13[op.bintoint(state[7])], AES.mul9[op.bintoint(state[4])])
tmp[6] = op.bitxor(AES.mul14[op.bintoint(state[6])], AES.mul11[op.bintoint(state[7])],
AES.mul13[op.bintoint(state[4])], AES.mul9[op.bintoint(state[5])])
tmp[7] = op.bitxor(AES.mul14[op.bintoint(state[7])], AES.mul11[op.bintoint(state[4])],
AES.mul13[op.bintoint(state[5])], AES.mul9[op.bintoint(state[6])])
tmp[8] = op.bitxor(AES.mul14[op.bintoint(state[8])], AES.mul11[op.bintoint(state[9])],
AES.mul13[op.bintoint(state[10])], AES.mul9[op.bintoint(state[11])])
tmp[9] = op.bitxor(AES.mul14[op.bintoint(state[9])], AES.mul11[op.bintoint(state[10])],
AES.mul13[op.bintoint(state[11])], AES.mul9[op.bintoint(state[8])])
tmp[10] = op.bitxor(AES.mul14[op.bintoint(state[10])], AES.mul11[op.bintoint(state[11])],
AES.mul13[op.bintoint(state[8])], AES.mul9[op.bintoint(state[9])])
tmp[11] = op.bitxor(AES.mul14[op.bintoint(state[11])], AES.mul11[op.bintoint(state[8])],
AES.mul13[op.bintoint(state[9])], AES.mul9[op.bintoint(state[10])])
tmp[12] = op.bitxor(AES.mul14[op.bintoint(state[12])], AES.mul11[op.bintoint(state[13])],
AES.mul13[op.bintoint(state[14])], AES.mul9[op.bintoint(state[15])])
tmp[13] = op.bitxor(AES.mul14[op.bintoint(state[13])], AES.mul11[op.bintoint(state[14])],
AES.mul13[op.bintoint(state[15])], AES.mul9[op.bintoint(state[12])])
tmp[14] = op.bitxor(AES.mul14[op.bintoint(state[14])], AES.mul11[op.bintoint(state[15])],
AES.mul13[op.bintoint(state[12])], AES.mul9[op.bintoint(state[13])])
tmp[15] = op.bitxor(AES.mul14[op.bintoint(state[15])], AES.mul11[op.bintoint(state[12])],
AES.mul13[op.bintoint(state[13])], AES.mul9[op.bintoint(state[14])])
return tmp
@staticmethod
def addroundkey(state, roundkey):
"""
:param state: This is an array of length 16 with 1 byte in each index.
:param roundkey: This is another array of length 16 with a byte in each index.
:return: Returns an array with each index of state added with each index roundkey as galois fields.
This is the same as the XOR operation.
"""
newstate = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in range(16):
newstate[i] = op.bitxor(state[i], roundkey[i])
return newstate
@staticmethod
def getkey(key):
"""
:param key: A key in plaintext or list of hex values. Length 16
:return: Returns the key but formatted as an array of length 16 with a byte in each index.
This function basically returns the key in binary as an array.
"""
keytype = str(type(key))
keylength = len(key)
newkey = []
if keytype == "<class 'list'>":
for i in range(16):
if i < keylength:
newkey.append(op.hextobin(key[i]))
else:
newkey.append("00000000")
elif keytype == "<class 'str'>":
for i in range(16):
if i < keylength:
newkey.append(op.stringtobin(key[i]))
else:
newkey.append("00000000")
else:
print("Key Type is Invalid. Must be string or list of hex valus. eg. ['4f', '2a', '0b'.....]")
print("Key used will be all null")
for i in range(16):
newkey.append("00000000")
return newkey
def encrypt(self, message, message_type, output_type="hex"):
"""
:param message: The message to be encrypted. Either a file or string
:param message_type: The type of the message. 'string' or 'file'
:param output_type: The type of the output. 'hex' or 'string' or 'bytes'
:return: Returns the encrypted message
"""
numofrounds = 9
proceed = True # This variable will monitor if all the parameters are correct.
# ------------This section gets a byte array from the message------------------------------------
# Get the byte array
if message_type == "file":
message_bytes = op.getbytearray(message)
elif message_type == "string":
message_bytes = []
for i in range(len(message)):
message_bytes.append(op.inttobin(ord(message[i])))
else:
print("MESSSAGE TYPE IS INVALID. CHOOSE 'string' OR 'file'.")
proceed = False
# Check to make sure the message is a string
if str(type(message)) != "<class 'str'>":
proceed = False
print("The message must be a string")
# This section initializes the encrypted message as either a list or a string
# depending on the output type
if output_type == "hex" or output_type == "string":
encryptedmessage = ""
elif output_type == "bytes":
encryptedmessage = []
else:
proceed = False
print("OUTPUT TYPE IS INVALID. CHOOSE 'hex' or 'string' or 'bytes'.")
# --------------------------------------------------------------------------------------------------------------
if proceed:
# Pad the byte array
while len(message_bytes) % 16 != 0:
message_bytes.append("00000000")
loops = len(message_bytes) // 16
for k in range(loops):
# --------THIS SECTION DEALS THIS GETTING THE 16 BYTE ARRAY CALLED THE STATE FROM THE MESSAGE------------
# Initialize the state and get the necessary block of 16 characters
state = message_bytes[k * 16: (k + 1) * 16]
# --------------NOW WE HAVE OUR STATE AND CAN START ENCRYPTION-------------------------------------------
# Initial Round
state = self.addroundkey(state, self.key[0:16]) # Whitening / Add round key
# Main Rounds
for icounter in range(numofrounds):
state = self.subbytes(state)
state = self.shiftrows(state)
state = self.mixcolumns(state)
state = self.addroundkey(state, self.key[16 * (icounter + 1): 16 * (icounter + 2)])
# Final Round
state = self.subbytes(state)
state = self.shiftrows(state)
state = self.addroundkey(state, self.key[160:])
# -------------------------------------------------------------------------------------------------------
# AT THIS POINT, THE ENCRYPTION IS DONE.
# THE FOLLOWEING CODE IS JUST HOW THE ENCRYPTED MESSAGE SHOULD BE OUTPUTTED.
if output_type == "hex":
for i in range(16):
state[i] = op.bintohex(state[i])[6:]
encryptedmessage += (state[i])
elif output_type == "string":
for i in range(16):
state[i] = op.bintostring(state[i])
encryptedmessage += (state[i])
elif output_type == "bytes":
encryptedmessage += state
else:
print("INVALID OUTPUT TYPE. Choose 'hex' 'string' 'bytes'")
return encryptedmessage
def decrypt(self, message, message_type, output_type="string"):
"""
:param message: The message to be decrypted
:param message_type: The type of the encrypted message. 'hex' or 'string' or 'bytes' or 'file'
:param output_type: The type of the output. 'string' or 'bytes'
:return: The orginal message.
"""
numofrounds = 9
proceed = True # This variable will monitor if all the parameters are correct.
# ----------THIS SECTION CHECKS ALL PARAMETERS BEFORE STARTING THE DECRYPTON--------------
# ------------This section gets a byte array from the message-----------------------------------
# Get the byte array
message_bytes = []
if message_type == "hex":
for i in range(len(message) // 2):
message_bytes.append(op.hextobin(message[(i * 2):(i * 2) + 2]))
elif message_type == "string":
for i in range(len(message)):
message_bytes.append(op.inttobin(ord(message[i])))
elif message_type == "bytes":
message_bytes = message
elif message_type == "file":
message_bytes = op.getbytearray(message)
else:
print("MESSSAGE TYPE IS INVALID. CHOOSE 'hex' or 'string' or 'bytes' or 'file'.")
proceed = False
# --------------
if len(message_bytes) % 16 != 0:
proceed = False
print("The bytes in message parameter is of the wrong size")
# Check to make sure the message is a string or bytearray
if str(type(message)) != "<class 'str'>" and str(type(message)) != "<class 'list'>":
proceed = False
print("The message must be a string or a bytearray.")
# This section initializes the decrypted message as either a list or a string
# depending on the output type
if output_type == "string":
decryptedmessage = ""
elif output_type == "bytes":
decryptedmessage = []
else:
proceed = False
print("OUTPUT TYPE IS INVALID. CHOOSE 'string' or 'bytes'.")
if proceed:
loops = len(message_bytes) // 16
for k in range(loops):
# Initialize the state and get the necessary block of 16 characters
# Here, we have the bytes and we just have to write the current block of 16 to the state
state = message_bytes[k * 16:(k + 1) * 16]
# Now we have our key and state and we can start the decryption
# First step is reverse the final round
state = self.addroundkey(state, self.key[160:])
state = self.inv_shiftrows(state)
state = self.inv_subbytes(state)
# Reverse the main rounds
for icounter in range(numofrounds):
state = self.addroundkey(state, self.key[16 * (9 - icounter): 16 * (10 - icounter)])
state = self.inv_mixcolumns(state)
state = self.inv_shiftrows(state)
state = self.inv_subbytes(state)
# Reverse the initial round
state = self.addroundkey(state, self.key[0:16])
if output_type == "string":
for icounter in range(16):
decryptedmessage += chr(op.bintoint(state[icounter]))
else:
decryptedmessage += state
return decryptedmessage
def communicate(self, sender=False, IP='0.0.0.0'):
"""
This is the method to call when the user wants to communicate between 2 computers
:param sender: If this computer sends first, set this value to True
:param IP: If sender is True, then the IP of the receiving computer must be inserted here
"""
global socketHolder
if sender:
socketHolder.connect((IP, 54321))
print("connected")
else:
socketHolder.bind(('0.0.0.0', 54321))
socketHolder.listen()
connection, address = socketHolder.accept()
socketHolder = connection
a = threading.Thread(target=self.sends)
b = threading.Thread(target=self.recv)
a.start()
b.start()
def sends(self):
global socketHolder # call variable as global
while True:
msg = input("") # placeholder for a way fof getting input
msg = self.encrypt(msg, "string", "string")
socketHolder.send(msg.encode(encoding='utf-8', errors='ignore')) # sends input(add your encryption here)
def recv(self):
global socketHolder # call variable as global
while True:
data = socketHolder.recv(4096).decode(encoding='utf-8', errors='strict') # recieves data from connection
print(self.decrypt(data, "string", "string"))
class SHA256:
# --------Unchanging Constants-------
# these are constants used in the calculations
# The list is available on wikipedia but must be in binary for the calculations
constants = ['01000010100010100010111110011000', '01110001001101110100010010010001',
'10110101110000001111101111001111',
'11101001101101011101101110100101', '00111001010101101100001001011011',
'01011001111100010001000111110001',
'10010010001111111000001010100100', '10101011000111000101111011010101',
'11011000000001111010101010011000',
'00010010100000110101101100000001', '00100100001100011000010110111110',
'01010101000011000111110111000011',
'01110010101111100101110101110100', '10000000110111101011000111111110',
'10011011110111000000011010100111',
'11000001100110111111000101110100', '11100100100110110110100111000001',
'11101111101111100100011110000110',
'00001111110000011001110111000110', '00100100000011001010000111001100',
'00101101111010010010110001101111',
'01001010011101001000010010101010', '01011100101100001010100111011100',
'01110110111110011000100011011010',
'10011000001111100101000101010010', '10101000001100011100011001101101',
'10110000000000110010011111001000',
'10111111010110010111111111000111', '11000110111000000000101111110011',
'11010101101001111001000101000111',
'00000110110010100110001101010001', '00010100001010010010100101100111',
'00100111101101110000101010000101',
'00101110000110110010000100111000', '01001101001011000110110111111100',
'01010011001110000000110100010011',
'01100101000010100111001101010100', '01110110011010100000101010111011',
'10000001110000101100100100101110',
'10010010011100100010110010000101', '10100010101111111110100010100001',
'10101000000110100110011001001011',
'11000010010010111000101101110000', '11000111011011000101000110100011',
'11010001100100101110100000011001',
'11010110100110010000011000100100', '11110100000011100011010110000101',
'00010000011010101010000001110000',
'00011001101001001100000100010110', '00011110001101110110110000001000',
'00100111010010000111011101001100',
'00110100101100001011110010110101', '00111001000111000000110010110011',
'01001110110110001010101001001010',
'01011011100111001100101001001111', '01101000001011100110111111110011',
'01110100100011111000001011101110',
'01111000101001010110001101101111', '10000100110010000111100000010100',
'10001100110001110000001000001000',
'10010000101111101111111111111010', '10100100010100000110110011101011',
'10111110111110011010001111110111',
'11000110011100010111100011110010']
@staticmethod
def create_salt():
"""
This method simply uses a random number generator to get a random salt
:return: A random string
"""
saltval = op.bintohex(op.inttobin(random.getrandbits(128)))
return saltval
@staticmethod
def hash(message, messagetype, salt=""):
"""
This method hashes any string.
:param message: The messaee that needs to be hashed
:param salt: A salt is appended to a message, it is optional whether you want to include a salt while hashing
:param messagetype: The type of message. 'string' or 'file'
:return: The hashed message
"""
# ---------Initial Hash Values-------
# these hash values change for each 512 bit chunk, and start as the following
h0 = "01101010000010011110011001100111"
h1 = "10111011011001111010111010000101"
h2 = "00111100011011101111001101110010"
h3 = "10100101010011111111010100111010"
h4 = "01010001000011100101001001111111"
h5 = "10011011000001010110100010001100"
h6 = "00011111100000111101100110101011"
h7 = "01011011111000001100110100011001"
# -----------------Padding-----------------
# This sections initializes the first 16 "words". Each "word" is 32 bits.
# gets the message input and turns it into binary
if messagetype == "string":
paddedmessage = op.stringtobin(message + salt)
elif messagetype == "file":
file_array = op.getbytearray(message)
paddedmessage = ""
for icounter in range(len(file_array)):
paddedmessage += file_array[icounter]
else:
print("Message Type Invalid. Must be 'string' or 'file' defaulted to string")