------------------------------------------------------------
-- Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich
-- http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
entity subkey is
port (
KxDI : in std_logic_vector(255 downto 0);
SxSI : in std_logic_vector(4 downto 0);
KenablexSI : in std_logic;
KinitxSI : in std_logic;
RstxRBI : in std_logic;
ClkxCI : in std_logic;
TxDI : in std_logic_vector(127 downto 0);
KsxDO : out std_logic_vector(255 downto 0));
end subkey;
architecture rtl of subkey is
type karray is array (0 to 4) of unsigned(63 downto 0);
signal KexDP, KexDN : karray;
type tarray is array (0 to 2) of unsigned(63 downto 0);
signal TexDP, TexDN : tarray;
begin -- rtl
KexDN(0) <= KexDP(1) when KenablexSI = '0' else unsigned(KxDI(255 downto 192));
KexDN(1) <= KexDP(2) when KenablexSI = '0' else unsigned(KxDI(191 downto 128));
KexDN(2) <= KexDP(3) when KenablexSI = '0' else unsigned(KxDI(127 downto 64));
KexDN(3) <= KexDP(4) when KenablexSI = '0' else unsigned(KxDI(63 downto 0));
KexDN(4) <= KexDP(0) when KenablexSI = '0' else x"5555555555555555" xor
unsigned(KxDI(255 downto 192)) xor unsigned(KxDI(191 downto 128)) xor
unsigned(KxDI(127 downto 64)) xor unsigned(KxDI(63 downto 0));
TexDN(0) <= TexDP(1) when KenablexSI = '0' else unsigned(TxDI(127 downto 64));
TexDN(1) <= TexDP(2) when KenablexSI = '0' else unsigned(TxDI(63 downto 0));
TexDN(2) <= TexDP(0) when KenablexSI = '0' else unsigned(TxDI(127 downto 64)) xor unsigned(TxDI(63 downto 0));
k_shiftreg : process (ClkxCI, RstxRBI)
begin -- process k_shiftreg
if RstxRBI = '0' then -- asynchronous reset (active low)
KexDP(0) <= (others => '0');
KexDP(1) <= (others => '0');
KexDP(2) <= (others => '0');
KexDP(3) <= (others => '0');
KexDP(4) <= (others => '0');
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
if KinitxSI = '1' then
KexDP(0) <= X"388512680E660046";
KexDP(1) <= X"4B72D5DEC5A8FF01";
KexDP(2) <= X"281A9298CA5EB3A5";
KexDP(3) <= X"54CA5249F46070C4";
KexDP(4) <= X"5555555555555555" xor KexDP(0) xor KexDP(1) xor KexDP(2) xor KexDP(3);
else
KexDP <= KexDN;
end if;
end if;
end process k_shiftreg;
t_shiftreg : process (ClkxCI, RstxRBI)
begin -- process t_shiftreg
if RstxRBI = '0' then -- asynchronous reset (active low)
TexDP(0) <= (others => '0');
TexDP(1) <= (others => '0');
TexDP(2) <= (others => '0');
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
--if KenablexSI = '1' then
TexDP <= TexDN;
--end if;
end if;
end process t_shiftreg;
KsxDO(255 downto 192) <= std_logic_vector(KexDP(0));
KsxDO(191 downto 128) <= std_logic_vector(KexDP(1) + TexDP(0));
KsxDO(127 downto 64) <= std_logic_vector(KexDP(2) + TexDP(1));
KsxDO(63 downto 0) <= std_logic_vector(KexDP(3) + unsigned(SxSI));
end rtl;