------------------------------------------------------------ -- 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;