Дипломы, курсовые, рефераты, контрольные...
Срочная помощь в учёбе

Шифрование DES — теория и практика

РефератПомощь в написанииУзнать стоимостьмоей работы

Функция S (i), которая преобразует 6-битовые числа в 4-битовые. Эта операция расширяет правую половину данных, R (i) от 32 до 48 битов. Так как при этом не просто повторяются определённые биты, но и изменяется их порядок, эта операция называется перестановкой с расширением. У неё две задачи: привести размер правой половины в соответствии с ключом для операции XOR и получить более длинный… Читать ещё >

Шифрование DES — теория и практика (реферат, курсовая, диплом, контрольная)

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ ГОУ ВПО ИЖЕВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ КАФЕДРА «ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ»

Отчёт по курсу «МИСЗИ»

студента 5 курса специальности 230 105

(заочное отделение) Задание «Шифрование DES «

Группа 10−19−4з Выполнил Стерхов Д. В.

Принял Старыгин А. В.

Ижевск 2007

Теоретические сведения о DES

Процесс шифрования

DES представляет собой блочный шифр, он шифрует 64 — битовыми блоками. С одного конца алгоритма вводится 64 — битовый блок открытого текста, а с другого конца выходит 64 — битовый блок шифротекста. DES является симметричным алгоритмом: для шифрования и дешифрования используется одинаковые алгоритмы и ключ (за исключением различий в использовании ключа).

Длина ключа равна 56 битам. Ключ обычно представляется 64 — битовым числом, но каждый восьмой бит используется для проверки чётности и игнорируется. Биты чётности являются наименьшими значащими битами байтов ключа. Ключ, который может быть любым 56 — битовым числом, можно изменить в любой момент времени. Ряд чисел считаются слабыми ключами, но их можно легко избежать. Безопасность полностью определяется ключом.

На простейшем уровне алгоритм не представляет ничего большего, чем комбинация двух основных методов шифрования: смещения и диффузии. Фундаментальным строительным блоком DES является применение к тексту единичной комбинации этих методов (подстановка, а за ней перестановка), зависящей от ключа. Такой блок называется этапом. DES состоит из 16 этапов, одинаковая комбинация методов применяется к открытому тексту 16 раз.

Процесс шифрования данных поясняется рисунком 1. Сначала 64 бита входной последовательности перестанавливаются в соответствии с таблицей 1. Таким образом, бит 58 входной последовательности становится битом 1, бит 50 — 2 и т. д.

Таблица 1. " Начальная перестановка"

Полученная последовательность бит разделяется на две последовательности: L (0) (биты 58, 50, 42, …, 8) и R (0) (биты 57, 49, 41, …, 7), каждая из которых содержит 32 бита. Затем выполняется итеративный процесс шифрования, который описывается следующими формулами:

L (i)=R (i-1), i=1,2,…, 16.

R (i)=L (i-1) + F (R (i-1), K (i)), i=1,2,…, 16.

Функция F называется функцией шифрования. Ее аргументами являются последовательность R, полученная на предыдущем шаге, и 48-битовый ключ K (i), который является результатом функции преобразования 64-битового ключа шифра. Подробно функция шифрования и алгоритм получения ключей K (i) описаны ниже.

На последнем шаге итерации будут получены последовательности L (16) и R (16), которые конкатенируются в 64-х битовую последовательность R (16)L (16). Видно, что в полученной последовательности 64 бита, перестанавливаются в соответствии с таблицей 2. Как легко видеть данная перестановка является обратной по отношению к начальной (см. таблицу 1).

Таблица 2. «Конечная перестановка»

Полученная последовательность из 64 бит и будет являться зашифрованной последовательностью.

Рисунок 1

Процесс расшифрования

Процесс расшифрования данных является инверсным по отношению к процессу шифрования. Все действия должны быть выполнены в обратном порядке. Это означает, что расшифровываемые данные сначала переставляются в соответствии с таблицей 1, а затем над последовательностью бит R (16)L (16) выполняется те же действия, что и в процессе зашифрования, но в обратном порядке. Итеративный процесс расшифрования описан следующими формулами:

R (i-1)=L (i), i =16, 15, …, 1

L (i-1)=R (i)+F (L (i), K (i)), i=16, 15, …, 1.

На последнем шаге итерации будут получены последовательности L (0) и R (0), которые конкатенируются в 64 битовую последовательность L (0)R (0). В полученной последовательности 64 бита перестанавливаются в соответствии с таблицей 2. Результат преобразования — исходная последовательность бит (расшифрованное 64-битовое значение).

Функция шифрования

Функция шифрования F (R, K) схематически показана на рисунке 2. Для вычисления значения функции F используется функция E (расширение 32 бит до 48), функции S (1), S (2),…, S (8) преобразование 6-битового числа в 4-битовое) и функция P (перестановка бит в 32-битовой последовательности). Приведем определения этих функций. Аргументами функции шифрования являются R (32 бита) и K (48 бит). Результат функции E® есть 48-битовое число, которое складывается по модулю 2 с числом K. Таким образом, получается 48-битовая последовательность, которая рассматривается, как конкатенация 8 строк длиной по 6 бит (т.е. B (1)B (2)B (3)B (4)B (5)B (6)B (7)B (8)). Результат функции S (i)B (i) — 4 битовая последовательность, которую будем обозначать L (i). В результате конкатенации всех 8 полученных последовательностей L (i) имеем 32-битовую последовательность L=L (1)L (2)L (3)L (4)L (5)L (6)L (7)L (8). Наконец, для получения результат функции шифрования надо переставить биты последовательности L. Для этого применяется функция перестановки P (L).

Рисунок 2.

Функция расширения Е, выполняющая расширение 32 бит до 48, определяется таблицей. В соответствии с этой таблицей первые три бита Е® — это биты 32,1 и 2, а последние — 31,32,1.

" Функция расширения Е" (перестановка с расширением)

Функция S (i), которая преобразует 6-битовые числа в 4-битовые. Эта операция расширяет правую половину данных, R(i) от 32 до 48 битов. Так как при этом не просто повторяются определённые биты, но и изменяется их порядок, эта операция называется перестановкой с расширением. У неё две задачи: привести размер правой половины в соответствии с ключом для операции XOR и получить более длинный результат, который можно будет сжать в ходе операции подстановки. Однако главный криптографический смысл совсем в другом. За счёт влияния одного бита на две подстановки быстрее возрастает зависимость битов результата от битов исходных данных. Это называется лавинным эффектом. DES спроектирован так, чтобы как можно быстрее добиться зависимости каждого бита шифротекста от каждого бита открытого текста и каждого бита ключа.

" Функции преобразования S (i)"

S (1)

S (2)

S (3)

S (4)

S (5)

S (6)

S (7)

S (8)

К таблице 4 требуются дополнительные пояснения. Каждая из функций S (i)B (i) преобразовывает 6-битовый код в 4-битовый выход по следующему алгоритму:

· первый и последний биты входной последовательности B, определяют номер строки k.

· второй, третий, четвертый и пятый биты последовательности B задают номер колонки l

· результат преобразования выбирается из строки k и колонки l.

Предположим, что B=11 011. Тогда S (1)(B)=0101. Действительно, k=1, l=13. В колонке 13 строки 1 задано значение 5, которое и является значением функции S (1)(11 011).

Функция перестановки бит P (L), также используемая для определения функции шифрования, задается значениями, приведенными в таблице 5. В последовательности L 32 перестанавливается так, чтобы бит 16 стал первым битом, бит 7 — вторым и т. д.

" Функция перестановки P"

Чтобы завершить описание алгоритма шифрования данных, осталось привести алгоритм получение ключей K (i), i=1,2,…, 16, размерностью в 48 бит. Ключи K (i) определяются по 64-битовому ключу шифра как это показано.

В начале над ключом шифра выполняется операция B, которая сводится к выбору определенных бит и их перестановке, как это показано выше. Причем, первые четыре строки определяют, как выбираются биты последовательности C (0) (первым битом C (0) будет бит 57 бит ключа шифра, затем бит 49 и т. д., а последними битами биты 44 и 36 ключа шифра), а следующие четыре строки — как выбираются биты последовательности D (0) (т.е. последовательность D (0) будем стоять из битов 63,55,…, 12, 4 ключа шифра).

" Функция перестановки и выбора последовательности B" (ключа)

Как видно из таблицы, для генерации последовательностей C (0) и D (0) не используются биты 8,16,25,32,40,48,56 и 64 ключа шифра. Эти биты не влияют на шифрование и могут служить для других целей (например, для контроля по четности). Таким образом, в действительности ключ шифра является 56-битовым. После определения C (0) и D (0) рекурсивно определяются C (i) и D (i), i=1,2,…, 16. Для этого применяются операции сдвига влево на один или два бита в зависимости от номера шага итерации, как это показано в таблицей 7. Операции сдвига выполняются для последовательностей C (i) и D (i) независимо. Например, последовательность C (3) получается, посредством сдвига влево на две позиции последовательности C (2), а последовательность D (3) — посредством сдвига влево на две позиции последовательности D (2). Следует иметь в виду, что выполняется циклический сдвиг влево. Например, единичный сдвиг влево последовательности C (i) приведет к тому, что первый бит C (i) станет последним и последовательность бит будет следующая: 2,3,…, 28,1.

" Функция сдвига Si"

Этап

Число

Ключ K (i), определяемый на каждом шаге итерации, есть результат выбора определенных бит из 56-битовой последовательности C (i)D (i) и их перестановки. Другими словами, K (i) = K (C (i)D (i)), где функция K определяется данными, приведенными в таблице.

" Функция перестановки и выбора K" (перестановка со сжатием)

После сдвига выбирается 48 из 56. Так как при этом не только выбирается подмножество битов, но и изменяется их порядок, эта операция называется перестановка со сжатием. Её результатом является набор из 48 битов.

Как следует из таблицы первый бит K (i) — это бит 14 последовательности C (i)D (i), второй — бит 17, последний — бит 32.

Пример

Шифруемое сообщение — шифровка = 11 111 000 11 101 000 11 110 100 11 110 000 11 101 110 11 100 010 11 101 010 11 100 000

Ключ шифрования 12 345 678 = 110 001 110 010 110 011 110 100 110 101 110 110 110 111 111 000

Шаг 1 Начальная перестановка

Входная последовательность

1 111 100 011 101 000 065 672 554 490 397 761 038 852 545 773 459 965 193 647 816 704 — согласно таблице начальной перестановки перестанавливаем биты в сообщении.

Полученная последовательность 1 111 111 100 001 100 912 522 515 411 411 521 363 114 294 401 075 296 962 367 979 520

Шаг 2 Получение последовательности L (0) и R (0)

Делим полученную последовательность согласно таблицам.

Последовательности получаются путём деления блока в 64 бита на 2 равных части.

L (0) перестановка

L(0) последовательность полученная 11 111 111 000 011 011 109 214 897 569 792

R (0) перестановка

R(0) последовательность полученная 11 111 111 111 111 109 705 751 521 656 832

Шаг 3 Функция выбора и перестановки последовательности В (преобразование ключа шифрования)

Входная последовательность

11 000 100 110 010 001 197 288 656 879 333 671 722 934 863 727 037 310 925 012 992

Полученная последовательность 1 111 111 111 110 110 019 961 382 288 418 286 862 336

Шаг 4 Получение последовательностей C (0) D (0)

Полученную последовательность (ключа) делим на две согласно таблицам.

C (0)

Последовательность C (0) = 111 111 111 111

D (0)

Последовательность D (0) = 110 011 001 111 000 099 449 733 120

Шаг 5 получение последовательности C (i)

По таблице сдвигаем биты в последовательностях

C (0) = 111 111 111 111

C (1)

C (2)

C (3)

C (4)

C (5)

C (6)

C (7)

C (8)

C (9)

C (10)

C (11)

C (12)

C (13)

C (14)

C (15)

C (16)

Шаг 6 получение последовательности D (i)

По той же таблице сдвигаем биты в последовательностях

D (0) = 110 011 001 111 000 099 449 733 120

D (1)

D (2)

D (3)

D (4)

D (5)

D (6)

D (7)

D (8)

D (9)

D (10)

D (11)

D (12)

D (13)

D (14)

D (15)

D (16)

Шаг 7 получение последовательностей K (i)

Для получения последовательности K (i) произведём конкатенацию последовательностей C (i) и D (i). В полученной последовательности C (i)D (i) переставим биты согласно таблице.

K (0) = 10 100 010 010 110 009 892 034 205 744 280 471 664 787 980 288

K (1)

K (2)

K (3)

K (4)

K (5)

K (6)

K (7)

K (8)

K (9)

K (10)

K (11)

K (12)

K (13)

K (14)

K (15)

K (16)

Шаг 8 функция Е (шифрование, перестановка с расширением)

По таблице преобразовать последовательности R (i)

R (0) = 11 111 111 111 111 109 705 751 521 656 832

E (R (0)) = 11 111 111 111 111 110 612 336 678 101 112 658 331 831 369 728

Объединение R (i)K (i+1) XOR

R (0)K (1) xor = 1 011 111 101 001 101 087 771 495 050 382 141 501 923 655 680

Подстановка через S блоки (вход 6 бит выход 4 бита)

S (1) = 2 = 0010 S (2) = 14 = 1110 S (3) = 9 = 1001 S (4) = 2 = 0010

S (5) = 3 = 0011 S (6) = 3 = 0011 S (7) = 11 = 1011 S (8) = 1 = 0001

Выходная (S1.S8) = 101 110 100 100 100 005 414 123 339 776

Прямая перестановка с помощью P блоков

Результат = 1 100 110 011 009 999 949 056 708 706 304

L (i)R (i+1) XOR

L (0) = 11 111 111 000 011 011 109 214 897 569 792

R (0) = 1 100 110 011 009 999 949 056 708 706 304

XOR R (1)=10 011 001 011 001 009 912 207 630 139 392

L (1) = R (0)

В итоге этих действий появляется новая правая половина, а старая правая половина становится новой левой. Эти действия повторяются 16 раз, образуя 16 этапов DES.

L (1) = 11 111 111 111 111 109 705 751 521 656 832

R (1) = 10 011 001 011 001 009 912 207 630 139 392

E (R1) = 110 011 110 010 101 106 431 835 748 971 965 064 713 361 948 672

R (1) XOR K (2) = 100 111 111 000 011 104 132 627 268 117 317 535 927 948 541 952

S (1.8) = 101 001 100 011 011 118 294 584 262 656

P = 10 110 001 000 111 000 446 241 106 558 976

R (1) XOR L (1) = 1 001 110 111 000 109 963 197 856 874 496 = R (2)

L (2) = R (1) = 10 011 001 011 001 009 912 207 630 139 392

E (R2) = 101 001 011 101 011 091 667 872 043 820 872 422 549 799 043 072

R (2) XOR K (3) = 11 101 010 111 101 100 533 625 369 946 991 649 062 276 562 944

S (1.8) = 111 010 001 110 101 002 612 683 833 344

P = 1 010 101 010 110 100 041 296 886 366 208

R (2) XOR L (2) = 11 001 100 001 111 110 430 773 202 649 088 = R (3)

L (3) = R (2) = 1 001 110 111 000 109 963 197 856 874 496

E (R3) = 111 001 011 000 000 120 625 020 492 473 863 526 981 339 971 584

R (3) XOR K (4) = 1 010 010 011 111 010 943 228 480 746 255 682 969 272 320

S (1.8) = 111 000 110 110 110 013 284 417 536

P = 11 000 110 011 101 000 893 295 059 009 536

R (3) XOR L (3) = 10 001 000 100 101 109 843 894 208 561 152 = R (4)

L (4) = R (3) = 11 001 100 001 111 110 430 773 202 649 088

E (R4) = 10 001 010 001 010 010 407 013 419 276 726 017 370 330 497 024

R (4) XOR K (5) = 101 001 011 000 001 000 443 138 860 505 597 952 745 705 308 160

S (1.8) = 1 001 100 001 100 000 977 546 138 091 520

P = 11 111 001 010 001 000 069 452 529 664

R (4) XOR L (4) = 11 010 011 000 101 110 867 568 046 899 200 = R (5)

L (5) = R (4) = 10 001 000 100 101 109 843 894 208 561 152

E (R5) = 111 010 100 110 100 014 850 818 431 339 380 247 238 425 968 640

R (5) XOR K (6) = 10 101 111 101 011 011 334 233 381 839 050 996 092 764 160

S (1.8) = 1 000 010 100 111 101 040 294 994 378 752

P = 1 001 101 010 101 101 007 170 783 150 080

R (5) XOR L (5) = 11 000 101 110 000 011 894 693 189 124 096 = R (6)

L (6) = R (5) = 11 010 011 000 101 110 867 568 046 899 200

E (R6) = 11 000 001 011 111 000 509 023 220 117 279 014 134 107 602 944

R (6) XOR K (7) = 110 001 000 110 110 007 756 777 900 512 262 439 544 291 328 000

S (1.8) = 1 011 110 010 010 011 000 190 208 573 440

P = 11 010 011 000 010 012 054 305 596 506 112

R (6) XOR L (6) = 111 100 011 000 110 006 272 = R (7)

L (7) = R (6) = 11 000 101 110 000 011 894 693 189 124 096

E (R7) = 11 111 100 000 110 100 097 897 227 878 400

R (7) XOR K (8) = 101 001 100 101 001 106 802 354 497 516 955 277 681 502 453 760

S (1.8) = 1 001 010 010 111 110 073 141 046 542 336

P = 11 110 110 011 010 010 419 123 703 513 088

R (7) XOR L (7) = 110 011 101 010 000 111 639 185 063 936 = R (8)

L (8) = R (7) = 111 100 011 000 110 006 272

E (R8) = 100 110 100 111 110 105 062 811 633 740 760 547 101 541 138 432

R (8) XOR K (9) = 101 111 000 010 111 008 531 700 605 426 209 656 023 394 811 904

S (1.8) = 1 110 001 010 110 001 090 783 445 254 144

P = 111 000 001 111 100 013 003 407 360

R (8) XOR L (8) = 111 000 110 011 111 017 111 617 536 = R (9)

L (9) = R (8) = 110 011 101 010 000 111 639 185 063 936

E (R9) = 100 000 001 110 100 010 867 545 699 811 686 828 620 833 095 680

R (9) XOR K (10) = 101 011 111 011 100 107 678 415 411 335 511 109 854 291 820 544

S (1.8) = 10 010 101 100 101 101 017 132 217 401 344

P = 10 101 111 000 000 100 136 686 452 736

R (9) XOR L (9) = 100 110 010 010 000 014 684 322 791 424 = R (10)

L (10) = R (9) = 111 000 110 011 111 017 111 617 536

E (R10) = 100 001 100 001 001 005 963 934 740 098 423 867 775 647 744

R (10) XOR K (11) = 111 111 000 001 110 007 680 824 419 333 221 296 547 823 616

S (1.8) = 1 001 001 010 101 100 036 108 272 533 504

P = 1 100 011 110 111 111 137 716 076 544

R (10) XOR L (10) = 1 011 011 000 100 000 086 949 363 712 = R (11)

L (11) = R (10) = 100 110 010 010 000 014 684 322 791 424

E (R11) = 100 001 010 110 101 095 975 303 828 279 534 958 859 627 003 904

R (11) XOR K (12) = 100 110 100 010 101 007 676 149 029 357 336 850 712 760 418 304

S (1.8) = 10 001 110 111 111 101 495 713 514 651 648

P = 1 101 111 110 010 009 940 664 063 623 168

R (11) XOR L (11) = 1 001 001 100 000 009 961 164 112 920 576 = R (12)

L (12) = R (11) = 1 011 011 000 100 000 086 949 363 712

E (R12) = 1 001 010 011 109 999 924 776 807 702 705 443 787 205 771 264

R (12) XOR K (13) = 1 110 100 011 010 109 941 218 440 586 543 290 269 174 857 728

S (1.8) = 10 001 000 011 111 110 484 659 770 753 024

P = 10 111 100 110 011 109 925 737 275 064 320

R (12) XOR L (12) = 10 110 111 101 011 009 947 126 986 702 848 = R (13)

L (13) = R (12) = 1 001 001 100 000 009 961 164 112 920 576

E (R13) = 110 110 101 111 110 105 981 694 676 540 757 806 655 215 763 456

R (13) XOR K (14) = 110 000 011 101 010 101 332 446 654 115 244 324 894 514 610 176

S (1.8) = 11 111 011 111 010 999 203 734 610 771 968

P = 1 011 010 100 011 011 068 973 981 630 464

R (13) XOR L (13) = 10 011 000 011 001 101 370 605 436 928 = R (14)

L (14) = R (13) = 10 110 111 101 011 009 947 126 986 702 848

E (R14) = 100 010 100 110 100 007 066 846 700 528 940 723 716 440 981 504

R (14) XOR K (15) = 100 100 110 100 010 016 271 352 655 091 537 229 489 895 374 848

S (1.8) = 11 101 100 100 000 101 120 752 387 883 008

P = 101 011 110 011 101 002 257 821 335 552

R (14) XOR L (14) = 10 011 100 011 000 111 092 353 088 880 640 = R (15)

L (15) = R (14) = 10 011 000 011 001 101 370 605 436 928

E (R15) = 10 011 111 000 001 099 412 719 079 604 906 196 060 545 744 896

R (15) XOR K (16) = 111 101 010 111 109 994 476 500 099 941 818 055 343 996 928

S (1.8) = 1 000 100 011 111 110 995 547 271 462 912

P = 10 110 111 010 100 110 505 028 534 403 072

R (15) XOR L (15) = 10 100 100 010 111 110 494 990 284 881 920 = R (16)

L (16) = R (15) = 10 011 100 011 000 111 092 353 088 880 640

Шаг 9 заключительная перестановка (обратная)

Вход (L16R16) = 1 001 110 001 100 011 069 283 697 368 959 809 062 502 517 669 945 045 589 195 489 280

Полученная = 110 000 111 001 11 101 011 1 101 000 1 100 110 10 011 011 111 000 11 000 101 =

48 57 235 104 102 155 56 197 = 0 9 л h f > 8 Е

Программа

Шифрование

Расшифровка

Текст программы

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class (TForm)

Memo1: TMemo;

Memo2: TMemo;

Label1: TLabel;

Label2: TLabel;

Button1: TButton;

Button2: TButton;

Memo3: TMemo;

Label3: TLabel;

procedure Button1Click (Sender: TObject);

procedure Button2Click (Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

c, d, k: array [0.16] of AnsiString;

r, l, rez, z: AnsiString;

w, desK, desR: byte;

implementation

{$R *.dfm}

procedure DecToBin (input: string; var output: ansistring);

var

a, b: double;

ost, q, w: byte;

st: AnsiString;

str: string[8];

begin

str:= ' ';

for w:= 1 to 8 do

begin

q:= Ord (input[w]);

b:= q;

While b <> 1 do

begin

a:= q / 2;

b:= Int (a);

if a = b then

ost:= 0

else ost:= 1;

q:= Round (b);

st:= st + IntToStr (ost);

if b = 1 then st:= st + '1';

end;

ost:= 1;

for q:= Length (st) downto 1 do // ia? aai?io no? iee

begin

str[ost]: = st[q];

Inc (ost);

end;

case Length (st) of

1: Insert ('0', str, 1); // aiaaaeaiea iaainoa? ueo iieae

2: Insert ('0', str, 1);

3: Insert ('0', str, 1);

4: Insert ('0000', str, 1);

5: Insert ('000', str, 1);

6: Insert ('00', str, 1);

7: Insert ('0', str, 1);

end;

output:= output + str;// + ' ';

str:= ' ';

st:= '';

end;

end;

procedure BeginPerestanovka (input: ansistring; var output: ansistring);

begin

output:=

input[58] + input[50] + input[42] + input[34] + input[26] + input[18]

+ input[10] + input[2]

+ input[60] + input[52] + input[44] + input[36] + input[28] + input[20]

+ input[12] + input[4]

+ input[62] + input[54] + input[46] + input[38] + input[30] + input[22]

+ input[14] + input[6]

+ input[64] + input[56] + input[48] + input[40] + input[32] + input[24]

+ input[16] + input[8]

+ input[57] + input[49] + input[41] + input[33] + input[25] + input[17]

+ input[9] + input[1]

+ input[59] + input[51] + input[43] + input[35] + input[27] + input[19]

+ input[11] + input[3]

+ input[61] + input[53] + input[45] + input[37] + input[29] + input[21]

+ input[13] + input[5]

+ input[63] + input[55] + input[47] + input[39] + input[31] + input[23]

+ input[15] + input[7];

end;

procedure PerestanovkaKeyB (input: AnsiString; var output: AnsiString);

begin

output:= '';

output:=

input[57]+input[49]+input[41]+input[33]+input[25]+input[17]+input[9]

+input[1]+input[58]+input[50]+input[42]+input[34]+input[26]+input[18]

+input[10]+input[2]+input[59]+input[51]+input[43]+input[35]+input[27]

+input[19]+input[11]+input[3]+input[60]+input[52]+input[44]+input[36]

+input[63]+input[55]+input[47]+input[39]+input[31]+input[23]+input[15]

+input[7]+input[62]+input[54]+input[46]+input[38]+input[30]+input[22]

+input[14]+input[6]+input[61]+input[53]+input[45]+input[37]+input[29]

+input[21]+input[13]+input[5]+input[28]+input[20]+input[12]+input[4];

end;

procedure pocledovatelnostiK;

var

w: byte;

bufer: AnsiString;

begin

for w:= 0 to 16 do

begin

bufer:= Concat (c[w], d[w]);

k[w]: =

Concat (bufer[14], bufer[17], bufer[11], bufer[24], bufer[1], bufer[5],

bufer[3], bufer[28], bufer[15], bufer[6], bufer[21], bufer[10],

bufer[23], bufer[19], bufer[12], bufer[4], bufer[26], bufer[8],

bufer[16], bufer[7], bufer[27], bufer[20], bufer[13], bufer[2],

bufer[41], bufer[52], bufer[31], bufer[37], bufer[47], bufer[55],

bufer[30], bufer[40], bufer[51], bufer[45], bufer[33], bufer[48],

bufer[44], bufer[49], bufer[39], bufer[56], bufer[34], bufer[53],

bufer[46], bufer[42], bufer[50], bufer[36], bufer[29], bufer[32]);

end;

end;

procedure FuncE;

const

s1: array[0.3, 0.15] of string[4] =

(('1110','0100','1101','0001','0010','1111','1011','1000','0011','1010','0110','1100','0101','1001','0000','0111'),

('0000','1111','0111','0100','1110','0010','1101','0001','1010','0110','1100','1011','1001','0101','0011','1000'),

('0100','0001','1110','1000','1001','0110','0010','1011','1111','1100','1001','0111','0011','1010','0101','0000'),

('1111','1100','1000','0010','0100','1001','0001','0111','0101','1011','0011','1110','1010','0000','1001','1101'));

s2: array[0.3, 0.15] of string[4] =

(('1111','0001','1000','1110','0110','1011','0011','0100','1001','0111','0010','1101','1100','0000','0101','1010'),

('0011','1101','0100','0111','1111','0010','1000','1110','1100','0000','0001','1010','0110','1001','1011','0101'),

('0000','1110','0111','1011','1010','0100','1101','0001','0101','1000','1100','0110','1001','0011','0010','1111'),

('1101','1000','1010','0001','0011','1111','0100','0010','1011','0110','0111','1100','0000','0101','1110','1001'));

s3: array [0.3, 0.15] of string[4] =

(('1010','0000','1001','1110','0110','0011','1111','0101','0001','1101','1100','0111','1011','0100','0010','1000'),

('1101','0111','0000','1001','0011','0100','0110','1010','0010','1000','0101','1110','1100','1011','1111','0001'),

('1101','0110','0100','1001','1000','1111','0011','0000','1011','0001','0010','1100','0101','1010','1110','0111'),

('0001','1010','1101','0000','0110','1001','1000','0111','0100','1111','1110','0011','1011','0101','0010','1100'));

s4: array [0.3, 0.15] of string[4] =

(('0111','1101','1110','0011','0000','0110','1001','1010','0001','0010','1000','0101','1011','1100','0100','1111'),

('1101','1000','1011','0101','0110','1111','0000','0011','0100','0111','0010','1100','0001','1010','1110','1001'),

('1010','0110','1001','0000','1100','1011','0111','1101','1111','0001','0011','1110','0101','0010','1000','0100'),

('0011','1111','0000','0110','1010','0001','1101','1000','1001','0100','0101','1011','1100','0111','0010','1110'));

s5: array [0.3, 0.15] of string[4] =

(('0010','1100','0100','0001','0111','1010','1011','0110','1000','0101','0011','1111','1101','0000','1110','1001'),

('1110','1011','0010','1100','0100','0111','1101','0001','0101','0000','1111','1010','0011','1001','1000','0110'),

('0100','0010','0001','1011','1010','1101','0111','1000','1111','1001','1100','0101','0110','0011','0000','1110'),

('1011','1000','1100','0111','0001','1110','0010','1101','0110','1111','0000','1001','1010','0100','0101','0011'));

s6: array [0.3, 0.15] of string[4] =

(('1100','0001','1010','1111','1001','0010','0110','1000','0000','1101','0011','0100','1110','0111','0101','1011'),

('1010','1111','0100','0010','0111','1100','1001','0101','0110','0001','1101','1110','0000','1011','0011','1000'),

('1001','1110','1111','0101','0010','1000','1100','0011','0111','0000','0100','1010','0001','1101','1011','0110'),

('0100','0011','0010','1100','1001','0101','1111','1010','1011','1110','0001','0111','0110','0000','1000','1101'));

s7: array [0.3, 0.15] of string[4] =

(('0100','1011','0010','1110','1111','0000','1000','1101','0011','1100','1001','0111','0101','1010','0110','0001'),

('1101','0000','1011','0111','0100','1001','0001','1010','1110','0011','0101','1100','0011','1111','1000','0110'),

('0001','0100','1011','1101','1100','0011','0111','1110','1010','1111','0110','1000','0000','0101','1001','0010'),

('0110','1011','1101','1000','0001','0100','1010','0111','1001','0101','0000','1111','1110','0010','0011','1100'));

s8: array [0.3, 0.15] of string[4] =

(('1101','0010','1000','0100','0110','1111','1011','0001','1010','1001','0011','1110','0101','0000','1100','0111'),

('0001','1111','1101','1000','1010','0011','0111','0100','1100','0101','0110','1011','0000','1110','1001','0011'),

('0111','1011','0100','0001','1001','1100','1110','0010','0000','0110','1010','1101','1111','0011','0101','1000'),

('0010','0001','1110','0111','0100','1010','1000','1101','1111','1100','1001','0000','0011','0101','0110','1011'));

var

_1, _2: AnsiString;

p: string[6];

v, b, x, a, j: byte;

u: string[2];

o: string[4];

function s (var a, b: byte): byte;

begin

if u = '00' then a:= 0

else if u = '01' then a:= 1

else if u = '10' then a:= 2

else if u = '11' then a:= 3;

if o = '0000' then b:= 0

else if o = '0001' then b:= 1

else if o = '0010' then b:= 2

else if o = '0011' then b:= 3

else if o = '0100' then b:= 4

else if o = '0101' then b:= 5

else if o = '0110' then b:= 6

else if o = '0111' then b:= 7

else if o = '1000' then b:= 8

else if o = '1001' then b:= 9

else if o = '1010' then b:= 10

else if o = '1011' then b:= 11

else if o = '1100' then b:= 12

else if o = '1101' then b:= 13

else if o = '1110' then b:= 14

else if o = '1111' then b:= 15;

end;

begin

for a:= 1 to 16 do

begin

z:= Concat (r[32], r[1], r[2], r[3], r[4], r[5], r[4], r[5], r[6], r[7], r[8], r[9],

r[8], r[9], r[10], r[11], r[12], r[13], r[12], r[13], r[14], r[15], r[16], r[17],

r[16], r[17], r[18], r[19], r[20], r[21], r[20], r[21], r[21], r[23], r[24], r[25],

r[24], r[25], r[26], r[27], r[28], r[29], r[28], r[29], r[30], r[31], r[32], r[1]);

_1:= k[a];

r:= z;

for j:= 1 to 48 do // xor

begin

v:= StrToInt (r[j]);

b:= StrToInt (_1[j]);

x:= v xor b;

_2:= Concat (_2, IntToStr (x));

end;

p:= Copy (_2, 1, 6); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s1[v, b];

p:= Copy (_2, 7, 12); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s2[v, b];

p:= Copy (_2, 13, 18); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s3[v, b];

p:= Copy (_2, 19, 24); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s4[v, b];

p:= Copy (_2, 25, 30); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s5[v, b];

p:= Copy (_2, 31, 36); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s6[v, b];

p:= Copy (_2, 37, 42); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s7[v, b];

p:= Copy (_2, 43, 48); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s8[v, b];

//? ia? anoaiiaea

_2:= rez;

rez:= Concat (_2[16], _2[7], _2[20], _2[21], _2[29], _2[12], _2[28], _2[17],

_2[1], _2[15], _2[23], _2[26], _2[5], _2[18], _2[31], _2[10],

_2[2], _2[8], _2[24], _2[14], _2[32], _2[27], _2[3], _2[9],

_2[19], _2[13], _2[30], _2[6], _2[22], _2[11], _2[4], _2[25]);

for w:= 1 to 32 do

begin

v:= StrToInt (r[w]);

b:= StrToInt (l[w]);

x:= v xor b;

_2:= Concat (_2, IntToStr (x));

end;

l:= r;

r:= _2;

end;

_2:= Concat (l, r);

rez:= Concat (

_2[40], _2[8], _2[48], _2[16], _2[56], _2[24], _2[64], _2[32],

_2[39], _2[7], _2[47], _2[15], _2[55], _2[23], _2[63], _2[31],

_2[38], _2[6], _2[46], _2[14], _2[54], _2[22], _2[62], _2[30],

_2[37], _2[5], _2[45], _2[13], _2[53], _2[21], _2[61], _2[29],

_2[36], _2[4], _2[44], _2[12], _2[52], _2[20], _2[60], _2[28],

_2[35], _2[3], _2[43], _2[11], _2[51], _2[19], _2[59], _2[27],

_2[34], _2[2], _2[42], _2[10], _2[50], _2[18], _2[58], _2[26],

_2[33], _2[1], _2[41], _2[9], _2[49], _2[17], _2[57], _2[25]);

end;

procedure FuncER;

const

s1: array[0.3, 0.15] of string[4] =

(('1110','0100','1101','0001','0010','1111','1011','1000','0011','1010','0110','1100','0101','1001','0000','0111'),

('0000','1111','0111','0100','1110','0010','1101','0001','1010','0110','1100','1011','1001','0101','0011','1000'),

('0100','0001','1110','1000','1001','0110','0010','1011','1111','1100','1001','0111','0011','1010','0101','0000'),

('1111','1100','1000','0010','0100','1001','0001','0111','0101','1011','0011','1110','1010','0000','1001','1101'));

s2: array[0.3, 0.15] of string[4] =

(('1111','0001','1000','1110','0110','1011','0011','0100','1001','0111','0010','1101','1100','0000','0101','1010'),

('0011','1101','0100','0111','1111','0010','1000','1110','1100','0000','0001','1010','0110','1001','1011','0101'),

('0000','1110','0111','1011','1010','0100','1101','0001','0101','1000','1100','0110','1001','0011','0010','1111'),

('1101','1000','1010','0001','0011','1111','0100','0010','1011','0110','0111','1100','0000','0101','1110','1001'));

s3: array [0.3, 0.15] of string[4] =

(('1010','0000','1001','1110','0110','0011','1111','0101','0001','1101','1100','0111','1011','0100','0010','1000'),

('1101','0111','0000','1001','0011','0100','0110','1010','0010','1000','0101','1110','1100','1011','1111','0001'),

('1101','0110','0100','1001','1000','1111','0011','0000','1011','0001','0010','1100','0101','1010','1110','0111'),

('0001','1010','1101','0000','0110','1001','1000','0111','0100','1111','1110','0011','1011','0101','0010','1100'));

s4: array [0.3, 0.15] of string[4] =

(('0111','1101','1110','0011','0000','0110','1001','1010','0001','0010','1000','0101','1011','1100','0100','1111'),

('1101','1000','1011','0101','0110','1111','0000','0011','0100','0111','0010','1100','0001','1010','1110','1001'),

('1010','0110','1001','0000','1100','1011','0111','1101','1111','0001','0011','1110','0101','0010','1000','0100'),

('0011','1111','0000','0110','1010','0001','1101','1000','1001','0100','0101','1011','1100','0111','0010','1110'));

s5: array [0.3, 0.15] of string[4] =

(('0010','1100','0100','0001','0111','1010','1011','0110','1000','0101','0011','1111','1101','0000','1110','1001'),

('1110','1011','0010','1100','0100','0111','1101','0001','0101','0000','1111','1010','0011','1001','1000','0110'),

('0100','0010','0001','1011','1010','1101','0111','1000','1111','1001','1100','0101','0110','0011','0000','1110'),

('1011','1000','1100','0111','0001','1110','0010','1101','0110','1111','0000','1001','1010','0100','0101','0011'));

s6: array [0.3, 0.15] of string[4] =

(('1100','0001','1010','1111','1001','0010','0110','1000','0000','1101','0011','0100','1110','0111','0101','1011'),

('1010','1111','0100','0010','0111','1100','1001','0101','0110','0001','1101','1110','0000','1011','0011','1000'),

('1001','1110','1111','0101','0010','1000','1100','0011','0111','0000','0100','1010','0001','1101','1011','0110'),

('0100','0011','0010','1100','1001','0101','1111','1010','1011','1110','0001','0111','0110','0000','1000','1101'));

s7: array [0.3, 0.15] of string[4] =

(('0100','1011','0010','1110','1111','0000','1000','1101','0011','1100','1001','0111','0101','1010','0110','0001'),

('1101','0000','1011','0111','0100','1001','0001','1010','1110','0011','0101','1100','0011','1111','1000','0110'),

('0001','0100','1011','1101','1100','0011','0111','1110','1010','1111','0110','1000','0000','0101','1001','0010'),

('0110','1011','1101','1000','0001','0100','1010','0111','1001','0101','0000','1111','1110','0010','0011','1100'));

s8: array [0.3, 0.15] of string[4] =

(('1101','0010','1000','0100','0110','1111','1011','0001','1010','1001','0011','1110','0101','0000','1100','0111'),

('0001','1111','1101','1000','1010','0011','0111','0100','1100','0101','0110','1011','0000','1110','1001','0011'),

('0111','1011','0100','0001','1001','1100','1110','0010','0000','0110','1010','1101','1111','0011','0101','1000'),

('0010','0001','1110','0111','0100','1010','1000','1101','1111','1100','1001','0000','0011','0101','0110','1011'));

var

_1, _2: AnsiString;

p: string[6];

v, b, x, a, j: byte;

u: string[2];

o: string[4];

function s (var a, b: byte): byte;

begin

if u = '00' then a:= 0

else if u = '01' then a:= 1

else if u = '10' then a:= 2

else if u = '11' then a:= 3;

if o = '0000' then b:= 0

else if o = '0001' then b:= 1

else if o = '0010' then b:= 2

else if o = '0011' then b:= 3

else if o = '0100' then b:= 4

else if o = '0101' then b:= 5

else if o = '0110' then b:= 6

else if o = '0111' then b:= 7

else if o = '1000' then b:= 8

else if o = '1001' then b:= 9

else if o = '1010' then b:= 10

else if o = '1011' then b:= 11

else if o = '1100' then b:= 12

else if o = '1101' then b:= 13

else if o = '1110' then b:= 14

else if o = '1111' then b:= 15;

end;

begin

for a:= 16 downto 1 do

begin

z:= Concat (r[32], r[1], r[2], r[3], r[4], r[5], r[4], r[5], r[6], r[7], r[8], r[9],

r[8], r[9], r[10], r[11], r[12], r[13], r[12], r[13], r[14], r[15], r[16], r[17],

r[16], r[17], r[18], r[19], r[20], r[21], r[20], r[21], r[21], r[23], r[24], r[25],

r[24], r[25], r[26], r[27], r[28], r[29], r[28], r[29], r[30], r[31], r[32], r[1]);

_1:= k[a];

r:= z;

for j:= 1 to 48 do // xor

begin

v:= StrToInt (r[j]);

b:= StrToInt (_1[j]);

x:= v xor b;

_2:= Concat (_2, IntToStr (x));

end;

p:= Copy (_2, 1, 6); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s1[v, b];

p:= Copy (_2, 7, 12); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s2[v, b];

p:= Copy (_2, 13, 18); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s3[v, b];

p:= Copy (_2, 19, 24); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s4[v, b];

p:= Copy (_2, 25, 30); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s5[v, b];

p:= Copy (_2, 31, 36); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s6[v, b];

p:= Copy (_2, 37, 42); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s7[v, b];

p:= Copy (_2, 43, 48); u:= p[1] + p[6]; o:= Copy (p, 2, 5); s (v, b);

rez:= rez + s8[v, b];

//? ia? anoaiiaea

_2:= rez;

rez:= Concat (_2[16], _2[7], _2[20], _2[21], _2[29], _2[12], _2[28], _2[17],

_2[1], _2[15], _2[23], _2[26], _2[5], _2[18], _2[31], _2[10],

_2[2], _2[8], _2[24], _2[14], _2[32], _2[27], _2[3], _2[9],

_2[19], _2[13], _2[30], _2[6], _2[22], _2[11], _2[4], _2[25]);

for w:= 1 to 32 do

begin

v:= StrToInt (r[w]);

b:= StrToInt (l[w]);

x:= v xor b;

_2:= Concat (_2, IntToStr (x));

end;

l:= r;

r:= _2;

end;

_2:= Concat (l, r);

rez:= Concat (

_2[40], _2[8], _2[48], _2[16], _2[56], _2[24], _2[64], _2[32],

_2[39], _2[7], _2[47], _2[15], _2[55], _2[23], _2[63], _2[31],

_2[38], _2[6], _2[46], _2[14], _2[54], _2[22], _2[62], _2[30],

_2[37], _2[5], _2[45], _2[13], _2[53], _2[21], _2[61], _2[29],

_2[36], _2[4], _2[44], _2[12], _2[52], _2[20], _2[60], _2[28],

_2[35], _2[3], _2[43], _2[11], _2[51], _2[19], _2[59], _2[27],

_2[34], _2[2], _2[42], _2[10], _2[50], _2[18], _2[58], _2[26],

_2[33], _2[1], _2[41], _2[9], _2[49], _2[17], _2[57], _2[25]);

end;

procedure TForm1. Button1Click (Sender: TObject);

var

output, put, key, c0, d0, k0: AnsiString;

e1: string[1];

e2: string[2];

begin

DecToBin (Form1.Memo1.Text, output);

BeginPerestanovka (output, put);

l:= Copy (put, 1, 32);

r:= Copy (put, 33, 64);

DecToBin (Form1.Memo3.Text, key);

PerestanovkaKeyB (key, key);

c0:= Copy (key, 1, 28);

d0:= Copy (key, 29, 56);

c[0]: = c0;

d[0]: = d0;

for w:= 1 to 2 do

begin

e1:= c[w-1];

c[w]: = Copy (c[w-1], 2, 28) + e1;

e1:= d[w-1];

d[w]: = Copy (d[w-1], 2, 28) + e1;

end;

for w:= 3 to 8 do

begin

e2:= c[w-1];

c[w]: = Copy (c[w-1], 3, 28) + e2;

e2:= d[w-1];

d[w]: = Copy (d[w-1], 3, 28) + e2;

end;

e1:= c[8];

c[9]: = Copy (c[8], 2, 28) + e1;

e1:= d[8];

d[w]: = Copy (d[8], 2, 28) + e1;

for w:= 10 to 15 do

begin

e2:= c[w-1];

c[w]: = Copy (c[w-1], 3, 28) + e2;

e2:= d[w-1];

d[w]: = Copy (d[w-1], 3, 28) + e2;

end;

e1:= c[15];

c[16]: = Copy (c[15], 2, 28) + e1;

e1:= d[15];

d[16]: = Copy (d[15], 2, 28) + e1;

pocledovatelnostiK;

FuncE;

Form1.Memo2.Text:= rez;

end;

procedure TForm1. Button2Click (Sender: TObject);

var

output, put, key, c0, d0, k0: AnsiString;

e1: string[1];

e2: string[2];

begin

DecToBin (Form1.Memo2.Text, output);

BeginPerestanovka (output, put);

l:= Copy (put, 1, 32);

r:= Copy (put, 33, 64);

DecToBin (Form1.Memo3.Text, key);

PerestanovkaKeyB (key, key);

c0:= Copy (key, 1, 28);

d0:= Copy (key, 29, 56);

c[0]: = c0;

d[0]: = d0;

for w:= 1 to 2 do

begin

e1:= c[w-1];

c[w]: = Copy (c[w-1], 2, 28) + e1;

e1:= d[w-1];

d[w]: = Copy (d[w-1], 2, 28) + e1;

end;

for w:= 3 to 8 do

begin

e2:= c[w-1];

c[w]: = Copy (c[w-1], 3, 28) + e2;

e2:= d[w-1];

d[w]: = Copy (d[w-1], 3, 28) + e2;

end;

e1:= c[8];

c[9]: = Copy (c[8], 2, 28) + e1;

e1:= d[8];

d[w]: = Copy (d[8], 2, 28) + e1;

for w:= 10 to 15 do

begin

e2:= c[w-1];

c[w]: = Copy (c[w-1], 3, 28) + e2;

e2:= d[w-1];

d[w]: = Copy (d[w-1], 3, 28) + e2;

end;

e1:= c[15];

c[16]: = Copy (c[15], 2, 28) + e1;

e1:= d[15];

d[16]: = Copy (d[15], 2, 28) + e1;

pocledovatelnostiK;

FuncER;

Form1.Memo1.Text:= rez;

end;

end.

Показать весь текст
Заполнить форму текущей работой