------------------------------------------------------------
-- 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 skein is
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
BlockAvailablexSI : in std_logic;
FinBlockxSI : in std_logic;
BlockxDI : in std_logic_vector(255 downto 0);
HashAvailablexSO : out std_logic;
HashxDO : out std_logic_vector(255 downto 0));
end skein;
architecture rtl of skein is
component permix
port (
MxDI : in std_logic_vector(255 downto 0);
PerselectxSI : in std_logic;
CntxDI : in unsigned(2 downto 0);
MxDO : out std_logic_vector(255 downto 0));
end component;
component subkey
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;
CntxDI : in unsigned(2 downto 0);
TxDI : in std_logic_vector(127 downto 0);
KsxDO : out std_logic_vector(127 downto 0));
end component;
component tweak
port (
BnxSI : in std_logic_vector(95 downto 0);
FirstxSI : in std_logic;
FinalxSI : in std_logic;
OutxSI : in std_logic;
TxDO : out std_logic_vector(127 downto 0));
end component;
component controller
port (
BlockAvailablexSI : in std_logic;
ClkxCI : in std_logic;
RstxRBI : in std_logic;
SxSO : out std_logic_vector(4 downto 0);
MenablexSO : out std_logic;
CntxDO : out unsigned(2 downto 0);
GselectxSO : out std_logic;
PerselectxSO : out std_logic;
KenablexSO : out std_logic;
BcontrolxSO : out std_logic_vector(1 downto 0);
FirstxSO : out std_logic;
FinBlockxSI : in std_logic;
OutxSO : out std_logic;
KinitxSO : out std_logic;
LastxSO : out std_logic;
MzeroxSO : out std_logic;
HashAvailablexSO : out std_logic);
end component;
signal MxDN, MxDP, GxDN, GxDP, GtxDP, GKxD, PMxD, GXxD : std_logic_vector(255 downto 0);
signal KsxD : std_logic_vector(127 downto 0);
signal BnxSN, BnxSP, BnxS : std_logic_vector(95 downto 0);
signal GselectxS, KenablexS, FirstxS, FinalxS, OutxS, MzeroxS : std_logic;
signal KinitxS, MenablexS, GenablexS, PerselectxS, FinalFlagxS : std_logic;
signal BcontrolxS : std_logic_vector(1 downto 0);
signal SxS : std_logic_vector(4 downto 0);
signal TxD : std_logic_vector(127 downto 0);
signal CntxD : unsigned(2 downto 0);
signal LastxS : std_logic;
signal Kadd0AxD, Kadd0BxD : unsigned(63 downto 0);
signal Kadd0CxD : std_logic_vector(63 downto 0);
signal Kadd1AxD, Kadd1BxD : unsigned(63 downto 0);
signal Kadd1CxD : std_logic_vector(63 downto 0);
-- constant IV : std_logic_vector(255 downto 0) := (X"388512680E660046" & X"4B72D5DEC5A8FF01" & X"281A9298CA5EB3A5" & X"54CA5249F46070C4");
begin -- rtl
i_controller : controller
port map (
BlockAvailablexSI => BlockAvailablexSI,
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
SxSO => SxS,
MenablexSO => MenablexS,
CntxDO => CntxD,
GselectxSO => GselectxS,
PerselectxSO => PerselectxS,
KenablexSO => KenablexS,
BcontrolxSO => BcontrolxS,
FirstxSO => FirstxS,
FinBlockxSI => FinalFlagxS,
OutxSO => OutxS,
KinitxSO => KinitxS,
MzeroxSO => MzeroxS,
LastxSO => LastxS,
HashAvailablexSO => HashAvailablexSO);
i_permix : permix
port map (
MxDI => GKxD,
PerselectxSI => PerselectxS,
CntxDI => CntxD,
MxDO => PMxD);
i_subkey : subkey
port map (
KxDI => GXxD,
SxSI => SxS,
KenablexSI => KenablexS,
KinitxSI => KinitxS,
CntxDI => CntxD,
RstxRBI => RstxRBI,
ClkxCI => ClkxCI,
TxDI => TxD,
KsxDO => KsxD);
i_tweak : tweak
port map (
BnxSI => BnxS,
FirstxSI => FirstxS,
FinalxSI => FinBlockxSI,
OutxSI => OutxS,
TxDO => TxD);
MxDN <= BlockxDI when MzeroxS = '0' else (others => '0');
GxDN <= MxDN when GselectxS = '0' else GKxD when LastxS = '1' else PMxD;
GxDP <= GtxDP when MzeroxS = '0' else (others => '0');
Kadd0AxD <= unsigned(GxDP(255 downto 192)) when CntxD = 0 else unsigned(GxDP(127 downto 64));
Kadd0BxD <= unsigned(KsxD(127 downto 64));
Kadd1AxD <= unsigned(GxDP(191 downto 128)) when CntxD = 0 else unsigned(GxDP(63 downto 0));
Kadd1BxD <= unsigned(KsxD(63 downto 0));
Kadd0CxD <= std_logic_vector(Kadd0AxD + Kadd0BxD);
Kadd1CxD <= std_logic_vector(Kadd1AxD + Kadd1BxD);
GKxD(255 downto 192) <= Kadd0CxD when CntxD = 0 else GxDP(255 downto 192);
GKxD(191 downto 128) <= Kadd1CxD when CntxD = 0 else GxDP(191 downto 128);
GKxD(127 downto 64) <= Kadd0CxD when CntxD = 1 else GxDP(127 downto 64);
GKxD(63 downto 0) <= Kadd1CxD when CntxD = 1 else GxDP(63 downto 0);
-- GKxD(255 downto 192) GxDP(255 downto 192)) + unsigned(KsxD(255 downto 192)));
-- GKxD(191 downto 128) GxDP(191 downto 128)) + unsigned(KsxD(191 downto 128)));
-- GKxD(127 downto 64) GxDP(127 downto 64)) + unsigned(KsxD(127 downto 64)));
-- GKxD(63 downto 0) GxDP(63 downto 0)) + unsigned(KsxD(63 downto 0)));
GXxD <= MxDP xor GKxD;
HashxDO <= GXxD;
-- BnxS Counter
-----------------------------------------------------------------------------
BnxSN <= std_logic_vector(unsigned(BnxSP) + 32);
BnxS <= BnxSP;
bn_counter : process (ClkxCI, RstxRBI)
begin -- process bn_counter
if RstxRBI = '0' then -- asynchronous reset (active low)
BnxSP <= (others => '0');
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
if BcontrolxS = "11" then
BnxSP <= BnxSP;
elsif BcontrolxS = "10" then
BnxSP(95 downto 6) <= (others => '0');
BnxSP(5 downto 0) <= "100000";
elsif BcontrolxS = "01" then
BnxSP <= BnxSN;
elsif BcontrolxS = "00" then
BnxSP(95 downto 6) <= (others => '0');
BnxSP(5 downto 0) <= "001000";
else
BnxSP <= (others => '0');
end if;
end if;
end process bn_counter;
-- M-register
-----------------------------------------------------------------------------
M_mem : process (ClkxCI, RstxRBI)
begin -- process M_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
MxDP <= (others => '0');
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
if MEnablexS = '1' then
MxDP <= MxDN;
end if;
end if;
end process M_mem;
-----------------------------------------------------------------------------
-- F-register
-----------------------------------------------------------------------------
F_mem : process (ClkxCI, RstxRBI)
begin -- process F_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
FinalFlagxS <= '0';
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
if MEnablexS = '1' then
FinalFlagxS <= FinBlockxSI;
end if;
end if;
end process F_mem;
-----------------------------------------------------------------------------
-- G-register
-----------------------------------------------------------------------------
G_mem : process (ClkxCI, RstxRBI)
begin -- process G_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
GtxDP <= (others => '0');
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
GtxDP <= GxDN;
end if;
end process G_mem;
-----------------------------------------------------------------------------
end rtl;