Описание программы.
Гост, как и любой другой алгоритм шифрования, состоит из простых операций.
Сдвиг, замена, суммирование по модулю 2, суммирование по модулю 2^32, объявление и присваивание переменных.
Мы пока попытаемся реализовать алгоритм шифрования в лоб. Без дополнительных надстроек позволяющих комфортно использовать алгоритм.
Шапка программы почти стандартная. С добавлением туда use IEEE.numeric_std.ALL;
Это понадобится для реализации функции сдвига.
Объявление переменных.
Пока – мы не будем получать их извне, поэтому поставим заглушки.
entity gost is
port
(
N1 : in std_logic_vector(31 downto 0)
N2 : in std_logic_vector(31 downto 0) ;
N1_out : out std_logic_vector(31 downto 0);
N2_out : out std_logic_vector(31 downto 0)
);
end gost;
std_logic_vector – это массив переменных.
(31 downto 0) – это размер массива.
Мы только что объявили, что у нас 2 входных порта N1 и N2 и два выходных N1_out и N2_out.
Согласно госту – там 2 порта, которые работают и на вход и на выход одновременно. Но при этом индикации о том, что в конкретный момент данных в этом буфере нету. То ли зашифрованные данные, то ли промежуточный результат, то ли еще исходные данные, которые еще не успели как-то изменить.
Реализация алгоритма в виде двух портов работающих и на вход и на выход одновременно ведет к зависанию программы.
Сигнала старта работы алгоритма тоже нет.
Позже понадобится ещё индикатор готовности к приему данных, индикатор готовности о том, что данные зашифровали, ключ на старт, сигнал синхронизации. Что бы это был не бесконечный автомат, а вполне рабочая система, которую можно легко встроить куда угодно, где есть в ней необходимость.
Переменные внутренние
Signal X0 : std_logic_vector(31 downto 0) := "01001111010010100001110010101010";
Signal X1 : std_logic_vector(31 downto 0) := "01001111010010100001110010101010";
Signal X2 : std_logic_vector(31 downto 0) := "01001111010010100001110010101010";
Signal X3 : std_logic_vector(31 downto 0) := "01001111010010100001110010101010";
Signal X4 : std_logic_vector(31 downto 0) := "01001111010010100001110010101010";
Signal X5 : std_logic_vector(31 downto 0) := "01001111010010100001110010101010";
Signal X6 : std_logic_vector(31 downto 0) := "01001111010010100001110010101010";
Signal X7 : std_logic_vector(31 downto 0) := "01001111010010100001110010101010";
Согласно госту – 256 бит ключа разбивается на 8 частей по 32 бита, которые храниться в X0-X7.
Signal SM1 : std_logic_vector(31 downto 0);
Signal SM2 : std_logic_vector(31 downto 0);
Это два сумматора.
Signal K : std_logic_vector(31 downto 0);
Signal R : std_logic_vector(31 downto 0);
K – это модуль, где происходит операция замены текста по заранее определенным таблицам.
sm1 <= n1 xor x0;
Сложение по модулю 2(надо заменить на 2^32. вероятно смена переменных). В этой операции мы складываем половину зашифрованных данных с первым ключом.
Затем данные подаются на таблицу замен.
process
begin
case sm1(31 downto 28) is
when "0000" => k(31 downto 28) <= "0100"; — 0 > 4
when "0001" => k(31 downto 28) <= "1010"; -- 1 > A
when "0010" => k(31 downto 28) <= "1001"; -- 2 > 9
when "0011" => k(31 downto 28) <= "0011"; -- 3 > 2
when "0100" => k(31 downto 28) <= "1101"; -- 4 > D
when "0101" => k(31 downto 28) <= "1000"; -- 5 > 8
when "0110" => k(31 downto 28) <= "0000"; -- 6 > 0
when "0111" => k(31 downto 28) <= "1110"; -- 7 > E
when "1000" => k(31 downto 28) <= "0110"; — 8 > 6
when "1001" => k(31 downto 28) <= "1011"; — 9 > B
when "1010" => k(31 downto 28) <= "0001"; -- A > 1
when "1011" => k(31 downto 28) <= "1100"; -- B > C
when "1100" => k(31 downto 28) <= "0110"; -- C > 7
when "1101" => k(31 downto 28) <= "1111"; -- D > F
when "1110" => k(31 downto 28) <= "0101"; -- E > 5
when "1111" => k(31 downto 28) <= "1001"; -- F > 9
when others => sm1(31 downto 28) <= "1001";
end case;
end process;
Данные разбиваются на 8 кусков по 4 бита. Каждый кусок заменяется согласно таблице, использующейся в криптографических приложениях ЦБ РФ. Это увеличивает стойкость шифрования к некоторым видам атак.
По поводу особенностей реализации. Можно через цикл реализовать, но это требует переменной, которая инициализирует цикл. Если оно работает без цикла – почему бы не обойтись без него. Как быстро написать оставшиеся таблицы для аналогичных узлов таблицы замен? Скопировать этот кусок, вставить в необходимом количестве и через поиск с заменой (F3) изменить необходимые значения.
Почему не реализовать через цикл for? Он требует дополнительной инициации. Т.е. нужно создавать дополнительные переменные. Что
Соответственно по тексту программы дальше идут еще 7 таких же таблиц замен в цикле процесс-бегин энд процесс. Без этого таблицы замен работать не будут. Имейте это в виду.
Дальше по тексту госта идет сдвиг. Собственно реализаций если верить различным учебникам много, но не хотят работать. Единственная работающая конструкция это:
r <= k(10 downto 0) & k(31 downto 11);
перемещение данных.
Далее наличествует еще один сумматор см2. в котором складывается вторая часть открытого текста с уже частично зашифрованными данными.
sm2 <= r xor n2;
n2_out <= n1;
n1_out <= sm2;
данные из н1 переписываются в н2.
end gost;
на этом текст программы заканичвается.
Итого с различными комментариями в тексте – 400 строчек. Не так уж много.

add comment
recommend
bookmark
subscribe