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