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

Generated on Fri Sep 24 10:39:12 CEST 2010
Home