📄 phelix.vhd
字号:
--This software is provided 'as-is', without any express or implied warranty.
--In no event will the authors be held liable for any damages arising from the use of this software.
--Permission is granted to anyone to use this software for any purpose,
--excluding commercial applications, and to alter it and redistribute
--it freely except for commercial applications.
--File: phelix.vhd
--Author: Richard Stern (rstern01@utopia.poly.edu)
--Organization: Polytechnic University
--------------------------------------------------------
--Description: Phelix encryption algorithm
--------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity phelix is
port( clk, rst : in std_logic;
plain_sop, plain_eop : in std_logic;
key : in std_logic_vector(255 downto 0);
key_len : in std_logic_vector(8 downto 0);
nonce : in std_logic_vector(127 downto 0);
plain : in std_logic_vector(31 downto 0);
plain_length : in std_logic_vector(31 downto 0);
o_vld : out std_logic;
cipher : out std_logic_vector(31 downto 0);
mac : out std_logic_vector(31 downto 0);
mac_sop, mac_eop : out std_logic);
end phelix;
architecture do_it of phelix is
signal z0_i, z1_i, z2_i, z3_i, z4_i, p_i, xi_0, xi_1, z4_in4, s_i : std_logic_vector(31 downto 0);
signal z0_i_1, z1_i_1, z2_i_1, z3_i_1, z4_i_1 : std_logic_vector(31 downto 0);
signal z0_i_2, z1_i_2, z2_i_2, z3_i_2, z4_i_2 : std_logic_vector(31 downto 0);
signal z0_i_3, z1_i_3, z2_i_3, z3_i_3, z4_i_3 : std_logic_vector(31 downto 0);
signal z0_i_4, z1_i_4, z2_i_4, z3_i_4, z4_i_4 : std_logic_vector(31 downto 0);
signal z0_i_5, z1_i_5, z2_i_5, z3_i_5, z4_i_5 : std_logic_vector(31 downto 0);
signal z0_i_6, z1_i_6, z2_i_6, z3_i_6, z4_i_6 : std_logic_vector(31 downto 0);
signal z0_i_7, z1_i_7, z2_i_7, z3_i_7, z4_i_7 : std_logic_vector(31 downto 0);
signal z0_iplus1, z1_iplus1, z2_iplus1, z3_iplus1, z4_iplus1 : std_logic_vector(31 downto 0);
type k_type is array(0 to 7) of std_logic_vector(31 downto 0);
type n_type is array(0 to 7) of std_logic_vector(31 downto 0);
type z_type is array(0 to 4) of std_logic_vector(31 downto 0);
type statetype is (key_mixing, initialization, ready_to_begin_encryption, encryption, compute_MAC1, compute_MAC2);
signal state : statetype;
signal count : integer range 0 to 160;
signal k : k_type;
signal n: n_type;
signal z: z_type;
signal i, iplus4, iplus8: std_logic_vector(63 downto 0);
signal x_i_prime : std_logic_vector(31 downto 0);
signal mac_cnt : std_logic_vector(3 downto 0);
begin
--in: zo_i, z1_i, z2_i, z3_i, z4_i, p_i, xi_0, xi_1, z4_in4
--out: z0_iplus1, z1_iplus1, z2_iplus1, z3_iplus1, z4_iplus1, s_i
z0_i_1 <= z0_i + z3_i;
z1_i_1 <= z1_i + z4_i;
z2_i_1 <= z2_i xor z0_i_1;
z3_i_1 <= z3_i(16 downto 0) & z3_i(31 downto 17);
z4_i_1 <= z4_i(6 downto 0) & z4_i(31 downto 7);
z0_i_2 <= z0_i_1(22 downto 0) & z0_i_1(31 downto 23);
z1_i_2 <= z1_i_1(21 downto 0) & z1_i_1(31 downto 22);
z2_i_2 <= z2_i_1(14 downto 0) & z2_i_1(31 downto 15);
z3_i_2 <= z3_i_1 xor z1_i_1;
z4_i_2 <= z4_i_1 + z2_i_1;
z0_i_3 <= (z3_i_2 + xi_0) xor z0_i_2;
z1_i_3 <= z1_i_2 xor z4_i_2;
z2_i_3 <= z2_i_2 + z0_i_3;
z3_i_3 <= z3_i_2(1 downto 0) & z3_i_2(31 downto 2);
z4_i_3 <= z4_i_2(18 downto 0) & z4_i_2(31 downto 19);
z0_i_4 <= z0_i_3(11 downto 0) & z0_i_3(31 downto 12);
z1_i_4 <= z1_i_3(20 downto 0) & z1_i_3(31 downto 21);
z2_i_4 <= z2_i_3(26 downto 0) & z2_i_3(31 downto 27);
z3_i_4 <= z3_i_3 + z1_i_3;
z4_i_4 <= z4_i_3 xor z2_i_3;
s_i <= z4_i_4 + z4_in4;
z0_i_5 <= z0_i_4 + (p_i xor z3_i_4);
z1_i_5 <= z1_i_4 + z4_i_4;
z2_i_5 <= z2_i_4 xor z0_i_5;
z3_i_5 <= z3_i_4(16 downto 0) & z3_i_4(31 downto 17);
z4_i_5 <= z4_i_4(6 downto 0) & z4_i_4(31 downto 7);
z0_i_6 <= z0_i_5(22 downto 0) & z0_i_5(31 downto 23);
z1_i_6 <= z1_i_5(21 downto 0) & z1_i_5(31 downto 22);
z2_i_6 <= z2_i_5(14 downto 0) & z2_i_5(31 downto 15);
z3_i_6 <= z3_i_5 xor z1_i_5;
z4_i_6 <= z4_i_5 + z2_i_5;
z0_i_7 <= z0_i_6 xor (z3_i_6 + xi_1);
z1_i_7 <= z1_i_6 xor z4_i_6;
z2_i_7 <= z0_i_7 + z2_i_6;
z3_i_7 <= z3_i_6(1 downto 0) & z3_i_6(31 downto 2);
z4_i_7 <= z4_i_6(18 downto 0) & z4_i_6(31 downto 19);
z0_iplus1 <= z0_i_7(11 downto 0) & z0_i_7(31 downto 12);
z1_iplus1 <= z1_i_7(20 downto 0) & z1_i_7(31 downto 21);
z2_iplus1 <= z2_i_7(26 downto 0) & z2_i_7(31 downto 27);
z3_iplus1 <= z3_i_7 + z1_i_7;
z4_iplus1 <= z4_i_7 xor z2_i_7;
iplus4 <= i + X"0000000000000004";
iplus8 <= i + X"0000000000000008";
with i(1 downto 0) select
x_i_prime <= iplus8(62 downto 31) when "11",
("000000000000000000000000" & key_len(8 downto 3) & "00") when "01",
(others => '0') when OTHERS;
cipher <= plain xor s_i;
mac <= s_i;
--z delay
process(rst, clk)
begin
if (rst = '1') then
z(0) <= (others=>'0');
z(1) <= (others=>'0');
z(2) <= (others=>'0');
z(3) <= (others=>'0');
z(4) <= (others=>'0');
elsif(clk'event and clk='1') then
if (z(0) = z4_iplus1) then
else
z(0) <= z4_iplus1;
z(1) <= z(0);
z(2) <= z(1);
z(3) <= z(2);
z(4) <= z(3);
end if;
end if;
end process;
--state machine
process(rst, clk)
begin
if(rst = '1') then
state <= key_mixing;
o_vld <= '0';
z0_i <= (others=>'0');
z1_i <= (others=>'0');
z2_i <= (others=>'0');
z3_i <= (others=>'0');
z4_i <= (others => '0');
z4_in4 <= (others => '0');
p_i <= (others=>'0');
xi_0 <= (others=>'0');
xi_1 <= (others=>'0');
mac_cnt <= (others=>'0');
mac_sop <= '0';
mac_eop <= '0';
count <= 0;
n(0) <= nonce(127 downto 96);
n(1) <= nonce(95 downto 64);
n(2) <= nonce(63 downto 32);
n(3) <= nonce(31 downto 0);
n(4) <= (X"00000000" - nonce(127 downto 96));
n(5) <= (X"00000001" - nonce(95 downto 64));
n(6) <= (X"00000002" - nonce(63 downto 32));
n(7) <= (X"00000003" - nonce(31 downto 0));
i <= X"FFFFFFFFFFFFFFF8";
elsif(clk'event and clk='1') then
case state is
when key_mixing =>
if (count = 0) then
z4_i <= ("00000000000000000000000000" & key_len(8 downto 3)) + "00000000000000000000000001000000";
p_i <= (others=>'0');
xi_0 <= (others=>'0');
xi_1 <= (others=>'0');
z0_i <= key(255 downto 224);
z1_i <= key(223 downto 192);
z2_i <= key(191 downto 160);
z3_i <= key(159 downto 128);
count <= count + 1;
elsif (count = 1) then
k(4) <= z0_iplus1 xor key(127 downto 96);
k(5) <= z1_iplus1 xor key(95 downto 64);
k(6) <= z2_iplus1 xor key(63 downto 32);
k(7) <= z3_iplus1 xor key(31 downto 0);
z0_i <= z0_iplus1 xor key(127 downto 96);
z1_i <= z1_iplus1 xor key(95 downto 64);
z2_i <= z2_iplus1 xor key(63 downto 32);
z3_i <= z3_iplus1 xor key(31 downto 0);
count <= count + 1;
elsif (count = 2) then
k(0) <= z0_iplus1 xor key(255 downto 224);
k(1) <= z1_iplus1 xor key(223 downto 192);
k(2) <= z2_iplus1 xor key(191 downto 160);
k(3) <= z3_iplus1 xor key(159 downto 128);
z0_i <= z0_iplus1 xor key(255 downto 224);
z1_i <= z1_iplus1 xor key(223 downto 192);
z2_i <= z2_iplus1 xor key(191 downto 160);
z3_i <= z3_iplus1 xor key(159 downto 128);
count <= count + 1;
elsif ( count = 3) then
k(4) <= z0_iplus1 xor k(4);
k(5) <= z1_iplus1 xor k(5);
k(6) <= z2_iplus1 xor k(6);
k(7) <= z3_iplus1 xor k(7);
z0_i <= z0_iplus1 xor k(4);
z1_i <= z1_iplus1 xor k(5);
z2_i <= z2_iplus1 xor k(6);
z3_i <= z3_iplus1 xor k(7);
count <= count + 1;
elsif (count = 4) then
k(0) <= z0_iplus1 xor k(0);
k(1) <= z1_iplus1 xor k(1);
k(2) <= z2_iplus1 xor k(2);
k(3) <= z3_iplus1 xor k(3);
z0_i <= z0_iplus1 xor k(0);
z1_i <= z1_iplus1 xor k(1);
z2_i <= z2_iplus1 xor k(2);
z3_i <= z3_iplus1 xor k(3);
count <= count + 1;
elsif ( count = 5) then
k(4) <= z0_iplus1 xor k(4);
k(5) <= z1_iplus1 xor k(5);
k(6) <= z2_iplus1 xor k(6);
k(7) <= z3_iplus1 xor k(7);
z0_i <= z0_iplus1 xor k(4);
z1_i <= z1_iplus1 xor k(5);
z2_i <= z2_iplus1 xor k(6);
z3_i <= z3_iplus1 xor k(7);
count <= count + 1;
elsif (count = 6) then
k(0) <= z0_iplus1 xor k(0);
k(1) <= z1_iplus1 xor k(1);
k(2) <= z2_iplus1 xor k(2);
k(3) <= z3_iplus1 xor k(3);
z0_i <= z0_iplus1 xor k(0);
z1_i <= z1_iplus1 xor k(1);
z2_i <= z2_iplus1 xor k(2);
z3_i <= z3_iplus1 xor k(3);
count <= count + 1;
elsif ( count = 7) then
k(4) <= z0_iplus1 xor k(4);
k(5) <= z1_iplus1 xor k(5);
k(6) <= z2_iplus1 xor k(6);
k(7) <= z3_iplus1 xor k(7);
z0_i <= z0_iplus1 xor k(4);
z1_i <= z1_iplus1 xor k(5);
z2_i <= z2_iplus1 xor k(6);
z3_i <= z3_iplus1 xor k(7);
count <= count + 1;
elsif (count = 8) then
k(0) <= z0_iplus1 xor k(0);
k(1) <= z1_iplus1 xor k(1);
k(2) <= z2_iplus1 xor k(2);
k(3) <= z3_iplus1 xor k(3);
count <= 0;
state <= initialization;
else
end if;
when initialization =>
if ( i = X"FFFFFFFFFFFFFFF8") then
z0_i <= k(3) xor n(0);
z1_i <= k(4) xor n(1);
z2_i <= k(5) xor n(2);
z3_i <= k(6) xor n(3);
z4_i <= k(7);
p_i <= (others=>'0');
z4_in4 <= (others => '0');
xi_0 <= k(conv_integer(i(2 downto 0)));
xi_1 <= k(conv_integer(iplus4(2 downto 0))) + n(conv_integer(i(2 downto 0))) + x_i_prime + i(31 downto 0) + X"00000008";
elsif (i > X"FFFFFFFFFFFFFFFD") then
z0_i <= z0_iplus1;
z1_i <= z1_iplus1;
z2_i <= z2_iplus1;
z3_i <= z3_iplus1;
z4_i <= z4_iplus1;
p_i <= (others=>'0');
z4_in4 <= z(2);
xi_0 <= k(conv_integer(i(2 downto 0)));
xi_1 <= k(conv_integer(iplus4(2 downto 0))) + n(conv_integer(i(2 downto 0))) + x_i_prime + i(31 downto 0) + X"00000008";
else
z0_i <= z0_iplus1;
z1_i <= z1_iplus1;
z2_i <= z2_iplus1;
z3_i <= z3_iplus1;
z4_i <= z4_iplus1;
p_i <= (others=>'0');
z4_in4 <= (others => '0');
xi_0 <= k(conv_integer(i(2 downto 0)));
xi_1 <= k(conv_integer(iplus4(2 downto 0))) + n(conv_integer(i(2 downto 0))) + x_i_prime + i(31 downto 0) + X"00000008";
end if;
if (i = X"FFFFFFFFFFFFFFFF") then
i <= i + '1';
state <= ready_to_begin_encryption;
else
i <= i + '1';
state <= initialization;
end if;
when ready_to_begin_encryption =>
--i = 0 start encryption
if (plain_sop = '1') then
z0_i <= z0_iplus1;
z1_i <= z1_iplus1;
z2_i <= z2_iplus1;
z3_i <= z3_iplus1;
z4_i <= z4_iplus1;
p_i <= plain;
z4_in4 <= z(3);
xi_0 <= k(conv_integer(i(2 downto 0)));
xi_1 <= k(conv_integer(iplus4(2 downto 0))) + n(conv_integer(i(2 downto 0))) + x_i_prime + i(31 downto 0) + 8;
i <= i + '1';
o_vld <= '1';
state <= encryption;
else
state <= ready_to_begin_encryption;
end if;
when encryption =>
z0_i <= z0_iplus1;
z1_i <= z1_iplus1;
z2_i <= z2_iplus1;
z3_i <= z3_iplus1;
z4_i <= z4_iplus1;
p_i <= plain;
z4_in4 <= z(2);
xi_0 <= k(conv_integer(i(2 downto 0)));
xi_1 <= k(conv_integer(iplus4(2 downto 0))) + n(conv_integer(i(2 downto 0))) + x_i_prime + i(31 downto 0) + 8;
i <= i + '1';
o_vld <= '1';
if (plain_eop = '1') then
state <= compute_MAC1;
else
state <= encryption;
end if;
when compute_MAC1 =>
z0_i <= z0_iplus1 xor X"912d94f1";
z1_i <= z1_iplus1;
z2_i <= z2_iplus1;
z3_i <= z3_iplus1;
z4_i <= z4_iplus1;
p_i <= "000000000000000000000000000000" & plain_length(1 downto 0);
z4_in4 <= z(2);
xi_0 <= k(conv_integer(i(2 downto 0)));
xi_1 <= k(conv_integer(iplus4(2 downto 0))) + n(conv_integer(i(2 downto 0))) + x_i_prime + i(31 downto 0) + 8;
i <= i + '1';
mac_cnt <= mac_cnt + '1';
o_vld <= '0';
state <= compute_MAC2;
when compute_MAC2 =>
z0_i <= z0_iplus1;
z1_i <= z1_iplus1;
z2_i <= z2_iplus1;
z3_i <= z3_iplus1;
z4_i <= z4_iplus1;
p_i <= "000000000000000000000000000000" & plain_length(1 downto 0);
z4_in4 <= z(2);
xi_0 <= k(conv_integer(i(2 downto 0)));
xi_1 <= k(conv_integer(iplus4(2 downto 0))) + n(conv_integer(i(2 downto 0))) + x_i_prime + i(31 downto 0) + 8;
i <= i + '1';
mac_cnt <= mac_cnt + '1';
if(mac_cnt = "1000") then
mac_sop <= '1';
state <= compute_MAC2;
elsif(mac_cnt = "1011") then
mac_eop <= '1';
state <= ready_to_begin_encryption;
else
mac_sop <= '0';
mac_eop <= '0';
state <= compute_MAC2;
end if;
end case;
end if;
end process;
end do_it;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -