------------------------------------------------------------
-- 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;
CntxDO : out unsigned(1 downto 0));
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 CInxD, COutxD : constcouple;
signal StatexDN, StatexDP : state;
signal StateInMIxD, StateOutMIxD : state;
signal StateInTweakxD, StateOutTweakxD : state;
signal StateInStepxD, StateOutStepxD : data;
signal StateOutxD : state;
signal StateTmpxD : state;
signal DataTmpxD, DataTmp1xD : data;
signal TxD, T1xD : data;
signal CntxD : unsigned(1 downto 0);
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,
CntxDO => CntxD);
step_1: step
port map (
StateInxDI => StateInStepxD,
CInxDI => CInxD,
StateOutxDO => StateOutStepxD,
COutxDO => COutxD);
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
-----------------------------------------------------------------------------
stepin : process (CntxD, CxDP, StatexDP)
variable IndAlg : integer;
begin
IndAlg := to_integer(CntxD);
case IndAlg is
when 0 => StateInStepxD(0) <= StatexDP(0);
StateInStepxD(1) <= StatexDP(1);
StateInStepxD(2) <= StatexDP(2);
StateInStepxD(3) <= StatexDP(3);
StateInStepxD(4) <= StatexDP(4);
StateInStepxD(5) <= StatexDP(5);
StateInStepxD(6) <= StatexDP(6);
StateInStepxD(7) <= StatexDP(7);
CInxD(0) <= CxDP(0);
CInxD(1) <= CxDP(1);
when 1 => StateInStepxD(0) <= StatexDP(8);
StateInStepxD(1) <= StatexDP(9);
StateInStepxD(2) <= StatexDP(10);
StateInStepxD(3) <= StatexDP(11);
StateInStepxD(4) <= StatexDP(12);
StateInStepxD(5) <= StatexDP(13);
StateInStepxD(6) <= StatexDP(14);
StateInStepxD(7) <= StatexDP(15);
CInxD(0) <= CxDP(2);
CInxD(1) <= CxDP(3);
when 2 => StateInStepxD(0) <= StatexDP(16);
StateInStepxD(1) <= StatexDP(17);
StateInStepxD(2) <= StatexDP(18);
StateInStepxD(3) <= StatexDP(19);
StateInStepxD(4) <= StatexDP(20);
StateInStepxD(5) <= StatexDP(21);
StateInStepxD(6) <= StatexDP(22);
StateInStepxD(7) <= StatexDP(23);
CInxD(0) <= CxDP(4);
CInxD(1) <= CxDP(5);
when others => StateInStepxD <= (others => (others => '0'));
CInxD <= (others => (others => '0'));
end case;
end process stepin;
-- Step Out
-----------------------------------------------------------------------------
stepout : process (COutxD, CntxD, CxDP, StateOutStepxD, StatexDP)
variable IndAlg : integer;
begin
IndAlg := to_integer(CntxD);
case IndAlg is
when 0 => StateOutxD <= StatexDP;
StateOutxD(0) <= StateOutStepxD(0);
StateOutxD(1) <= StateOutStepxD(1);
StateOutxD(2) <= StateOutStepxD(2);
StateOutxD(3) <= StateOutStepxD(3);
StateOutxD(4) <= StateOutStepxD(4);
StateOutxD(5) <= StateOutStepxD(5);
StateOutxD(6) <= StateOutStepxD(6);
StateOutxD(7) <= StateOutStepxD(7);
CxD <= CxDP;
CxD(0) <= COutxD(0);
CxD(1) <= COutxD(1);
when 1 => StateOutxD <= StatexDP;
StateOutxD(8) <= StateOutStepxD(0);
StateOutxD(9) <= StateOutStepxD(1);
StateOutxD(10) <= StateOutStepxD(2);
StateOutxD(11) <= StateOutStepxD(3);
StateOutxD(12) <= StateOutStepxD(4);
StateOutxD(13) <= StateOutStepxD(5);
StateOutxD(14) <= StateOutStepxD(6);
StateOutxD(15) <= StateOutStepxD(7);
CxD <= CxDP;
CxD(2) <= COutxD(0);
CxD(3) <= COutxD(1);
when 2 => StateOutxD <= StatexDP;
StateOutxD(16) <= StateOutStepxD(0);
StateOutxD(17) <= StateOutStepxD(1);
StateOutxD(18) <= StateOutStepxD(2);
StateOutxD(19) <= StateOutStepxD(3);
StateOutxD(20) <= StateOutStepxD(4);
StateOutxD(21) <= StateOutStepxD(5);
StateOutxD(22) <= StateOutStepxD(6);
StateOutxD(23) <= StateOutStepxD(7);
CxD <= CxDP;
CxD(4) <= COutxD(0);
CxD(5) <= COutxD(1);
when others => StateOutxD <= (others => (others => '0'));
CxD <= (others => (others => '0'));
end case;
end process stepout;
-- Constant select
-----------------------------------------------------------------------------
CxDN <= C0 when StateRegSelxS = '0' else CxD;
-- Message Insertion state select
-----------------------------------------------------------------------------
StateInMIxD <= IV when StateInSelxS = '0' else StateOutxD;
-- Next state select
-----------------------------------------------------------------------------
StatexDN <= StateOutTweakxD when StateRegSelxS = '0' else StateOutxD;
-- Hash value
-----------------------------------------------------------------------------
hashval: for i in 0 to 7 generate
HashvalxD(i) <= StateOutxD(i) xor StateOutxD(i+8) xor StateOutxD(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;