------------------------------------------------------------ -- 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; use work.luffapkg.all; entity luffa is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; FinBlockxSI : in std_logic; INENxEI : in std_logic; OUTENxEO : out std_logic; DxDI : in std_logic_vector(256-1 downto 0); DxDO : out std_logic_vector(HWIDTH-1 downto 0)); end luffa; architecture rtl of luffa is component controller port ( ClkxCI : in std_logic; RstxRBI : in std_logic; FinBlockxSI : in std_logic; INENxEI : in std_logic; OUTENxEO : out std_logic; StateRegSelxSO : out std_logic; StateInSelxSO : out std_logic); end component; component step port ( StateInxDI : in data; CInxDI : in constcouple; StateOutxDO : out data; COutxDO : out constcouple); end component; signal StateInSelxS, StateRegSelxS : std_logic; signal TmpxD, Tmp1xD, Tmp2xD, Tmp3xD : std_logic_vector(31 downto 0); signal DINxD : data; signal HashvalxD : data; signal CxDN, CxDP, CxD : const; signal CIn1xD, CIn2xD, CIn3xD : constcouple; signal COut1xD, COut2xD, COut3xD : constcouple; signal StatexDN, StatexDP : state; signal StateInMIxD, StateOutMIxD : state; signal StateInTweakxD, StateOutTweakxD : state; signal StateInStep1xD, StateInStep2xD : data; signal StateInStep3xD, StateOutStep1xD : data; signal StateOutStep2xD, StateOutStep3xD : data; signal StateOutStepxD, StateTmpxD : state; signal DataTmpxD, DataTmp1xD : data; signal TxD, T1xD : data; begin -- rtl p_inputstruct: for i in 0 to 7 generate DINxD(i) <= DxDI(HWIDTH-32*i-1 downto HWIDTH-32*(i+1)); end generate p_inputstruct; controller_1 : controller port map ( ClkxCI => ClkxCI, RstxRBI => RstxRBI, FinBlockxSI => FinBlockxSI, INENxEI => INENxEI, OUTENxEO => OUTENxEO, StateRegSelxSO => StateRegSelxS, StateInSelxSO => StateInSelxS); step_1: step port map ( StateInxDI => StateInStep1xD, CInxDI => CIn1xD, StateOutxDO => StateOutStep1xD, COutxDO => COut1xD); step_2: step port map ( StateInxDI => StateInStep2xD, CInxDI => CIn2xD, StateOutxDO => StateOutStep2xD, COutxDO => COut2xD); step_3: step port map ( StateInxDI => StateInStep3xD, CInxDI => CIn3xD, StateOutxDO => StateOutStep3xD, COutxDO => COut3xD); StateInTweakxD <= StateOutMIxD; -- Message Insertion ----------------------------------------------------------------------------- mi01: for i in 0 to 7 generate TxD(i) <= StateInMIxD(i) xor StateInMIxD(i+8) xor StateInMIxD(i+16); end generate mi01; TmpxD <= TxD(7); T1xD(7) <= TxD(6); T1xD(6) <= TxD(5); T1xD(5) <= TxD(4); T1xD(4) <= TxD(3) xor TmpxD; T1xD(3) <= TxD(2) xor TmpxD; T1xD(2) <= TxD(1); T1xD(1) <= TxD(0) xor TmpxD; T1xD(0) <= TmpxD; mi02 : for i in 0 to 7 generate StateTmpxD(i) <= StateInMIxD(i) xor T1xD(i); StateTmpxD(8+i) <= StateInMIxD(8+i) xor T1xD(i); StateTmpxD(16+i) <= StateInMIxD(16+i) xor T1xD(i); end generate mi02; mi03 : for i in 0 to 7 generate StateOutMIxD(i) <= StateTmpxD(i) xor DINxD(i); end generate mi03; Tmp1xD <= DINxD(7); DataTmpxD(7) <= DINxD(6); DataTmpxD(6) <= DINxD(5); DataTmpxD(5) <= DINxD(4); DataTmpxD(4) <= DINxD(3) xor Tmp1xD; DataTmpxD(3) <= DINxD(2) xor Tmp1xD; DataTmpxD(2) <= DINxD(1); DataTmpxD(1) <= DINxD(0) xor Tmp1xD; DataTmpxD(0) <= Tmp1xD; mi04 : for i in 0 to 7 generate StateOutMIxD(i+8) <= StateTmpxD(i+8) xor DataTmpxD(i); end generate mi04; Tmp2xD <= DataTmpxD(7); DataTmp1xD(7) <= DataTmpxD(6); DataTmp1xD(6) <= DataTmpxD(5); DataTmp1xD(5) <= DataTmpxD(4); DataTmp1xD(4) <= DataTmpxD(3) xor Tmp2xD; DataTmp1xD(3) <= DataTmpxD(2) xor Tmp2xD; DataTmp1xD(2) <= DataTmpxD(1); DataTmp1xD(1) <= DataTmpxD(0) xor Tmp2xD; DataTmp1xD(0) <= Tmp2xD; mi05 : for i in 0 to 7 generate StateOutMIxD(i+16) <= StateTmpxD(i+16) xor DataTmp1xD(i); end generate mi05; -- Tweak ----------------------------------------------------------------------------- tw01: for i in 0 to 11 generate StateOutTweakxD(i) <= StateInTweakxD(i); end generate tw01; tw02: for i in 12 to 15 generate StateOutTweakxD(i) <= StateInTweakxD(i)(31-1 downto 0) & StateInTweakxD(i)(31); end generate tw02; tw03: for i in 16 to 19 generate StateOutTweakxD(i) <= StateInTweakxD(i); end generate tw03; tw04: for i in 20 to 23 generate StateOutTweakxD(i) <= StateInTweakxD(i)(31-2 downto 0) & StateInTweakxD(i)(31 downto 30); end generate tw04; -- Step In ----------------------------------------------------------------------------- stpin: for i in 0 to 7 generate StateInStep1xD(i) <= StatexDP(i); StateInStep2xD(i) <= StatexDP(i+8); StateInStep3xD(i) <= StatexDP(i+16); end generate stpin; -- Step Out ----------------------------------------------------------------------------- stpout : for i in 0 to 7 generate StateOutStepxD(i) <= StateOutStep1xD(i); StateOutStepxD(i+8) <= StateOutStep2xD(i); StateOutStepxD(i+16) <= StateOutStep3xD(i); end generate stpout; const: for i in 0 to 1 generate CIn1xD(i) <= CxDP(i); CIn2xD(i) <= CxDP(i+2); CIn3xD(i) <= CxDP(i+4); CxD(i) <= COut1xD(i); CxD(i+2) <= COut2xD(i); CxD(i+4) <= COut3xD(i); end generate const; -- Constant select ----------------------------------------------------------------------------- CxDN <= C0 when StateRegSelxS = '0' else CxD; -- Message Insertion state select ----------------------------------------------------------------------------- StateInMIxD <= IV when StateInSelxS = '0' else StateOutStepxD; -- Next state select ----------------------------------------------------------------------------- StatexDN <= StateOutTweakxD when StateRegSelxS = '0' else StateOutStepxD; -- Hash value ----------------------------------------------------------------------------- hashval: for i in 0 to 7 generate HashvalxD(i) <= StateOutStepxD(i) xor StateOutStepxD(i+8) xor StateOutStepxD(i+16); end generate hashval; -- Output Unform ----------------------------------------------------------------------------- p_outext: for i in 0 to 7 generate DxDO((HWIDTH/8)*(8-i)-1 downto (HWIDTH/8)*(8-i)-32) <= HashvalxD(i); end generate p_outext; -- Memory ----------------------------------------------------------------------------- p_mem : process (ClkxCI, RstxRBI) begin -- process p_mem if RstxRBI = '0' then -- asynchronous reset (active low) StatexDP <= (others => (others => '0')); CxDP <= (others => (others => '0')); elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge StatexDP <= StatexDN; CxDP <= CxDN; end if; end process p_mem; end rtl;