------------------------------------------------------------
-- 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 jh is

  port (
    ClkxCI      : in  std_logic;
    RstxRBI     : in  std_logic;
    EnxEI       : in  std_logic;
    OutputEnxSO : out std_logic;
    MsgInxDI    : in  std_logic_vector(511 downto 0);
    HashOutxDO  : out std_logic_vector(255 downto 0));

end jh;

architecture rtl of jh is

  type HGroup is array (0 to 255) of std_logic_vector (3 downto 0);
                                        -- type definition of 4bit group elements
  type SBOX is array (0 to 15) of std_logic_vector (3 downto 0);
  type CGroup is array (0 to 63) of std_logic_vector(3 downto 0);

  component FSM
    port (
      ClkxCI      : in  std_logic;
      RstxRBI     : in  std_logic;
      EnxEI       : in  std_logic;
      R36xSO      : out std_logic;
      SavexSO     : out std_logic;
      NewMsgxSO   : out std_logic;
      OutputEnxSO : out std_logic);
  end component;

  signal NewMsgxS, R36xS, SavexS                          : std_logic;
  signal HxDP, HxDN                                       : HGroup;
  signal MxDP, MxDN                                       : std_logic_vector(511 downto 0);
  signal CxDP, CxDN                                       : std_logic_vector(255 downto 0);
  signal HDegroupedxD, HFinalxD, A                        : std_logic_vector(1023 downto 0);
  signal Group1, Temp1, Temp2, Temp3, Temp4, Temp5, Temp6 : HGroup;
  signal CTemp1, CxD                                      : std_logic_vector(255 downto 0);
  signal CGroup1, CTemp2, CTemp3, CTemp4, CTemp5, CTemp6  : CGroup;
  signal C0, C1, C2, C3, D0, D1, D2, D3                   : std_logic_vector(127 downto 0);
  signal CC0, CC1, CC2, CC3, CD0, CD1, CD2, CD3           : std_logic_vector(31 downto 0);

  constant S0  : SBOX                           := ("1001", "0000", "0100", "1011", "1101", "1100", "0011", "1111", "0001", "1010", "0010", "0110", "0111", "0101", "1000", "1110");
  constant S1  : SBOX                           := ("0011", "1100", "0110", "1101", "0101", "0111", "0001", "1001", "1111", "0010", "0000", "0100", "1011", "1010", "1110", "1000");
  constant CR0 : std_logic_vector(255 downto 0) := "0110101000001001111001100110011111110011101111001100100100001000101100101111101100010011011001101110101010010101011111010011111000111010110111101100000101110101000100100111011101010000100110011101101000101111010110010000101100000110011001110011001000101010";

--  constant IV : Hgroup := ("1001", "0000", "1100", "1110", "0100", "1100", "0111", "0001", "1101", "0010", "0011", "0011", "0101", "0101", "1101", "1000", "0000", "0010", "1001", "1011", "1110", "0101", "0011", "0001", "1110", "0010", "0011", "1010", "0011", "0010", "0101", "1000", "1110", "1101", "0001", "0001", "1001", "1111", "1101", "1111", "1010", "0101", "0010", "1100", "0001", "1111", "0100", "1000", "1110", "1100", "1101", "1100", "1011", "0001", "0011", "1011", "0011", "1111", "0000", "0011", "1010", "0111", "0101", "1000", "1100", "0100", "1011", "0001", "0110", "0000", "0101", "0101", "0111", "0001", "1011", "1011", "0001", "1011", "1111", "0011", "0001", "0001", "0001", "1010", "1010", "1000", "1111", "1111", "1100", "0110", "0000", "0010", "1000", "0100", "0111", "1110", "0000", "0010", "1000", "0111", "0110", "0011", "1010", "1101", "1100", "1101", "0001", "1111", "0000", "1001", "1110", "1111", "0101", "0100", "1100", "1100", "1101", "1000", "0000", "1111", "1000", "1100", "1011", "0101", "1100", "1101", "0001", "0101", "0111", "0101", "1101", "0101", "0011", "1001", "0011", "0110", "0000", "1010", "0100", "1000", "1000", "1111", "0000", "1110", "0011", "1111", "1010", "1000", "1111", "0110", "1001", "0100", "1101", "0011", "1010", "1001", "1110", "1101", "0110", "1001", "0001", "0001", "1100", "1001", "0001", "1000", "0001", "0000", "0100", "0000", "1101", "0100", "0001", "0000", "1000", "1100", "1100", "0010", "1110", "1111", "1101", "1111", "0011", "1000", "1000", "1010", "1011", "0011", "1000", "0100", "1100", "0100", "0110", "0111", "0000", "0011", "0001", "0011", "1010", "0000", "1100", "0100", "1101", "1101", "0000", "1111", "1001", "0001", "0101", "1100", "1111", "0001", "1001", "1101", "1011", "0000", "1000", "1001", "0101", "0100", "1010", "0110", "0101", "1101", "1101", "0101", "1010", "0010", "1111", "1101", "0011", "0010", "0000", "0101", "1000", "0101", "1111", "1000", "0000", "0010", "1100", "0001", "1110", "0110", "1011", "0010", "0111", "0111", "0001", "0110", "1100", "0100", "0100", "0100", "1010", "1100");

  constant IV : std_logic_vector(1023 downto 0) := "1100100101101000101110001110001011000101001110100101100101101110010000100111111001000101111011110001110101111010111001101110010101100001010001011011011111011001000001100111000100011111011110100010111111000111011000010111100000000110101010010010001000000001011110110010100110010001110000011011100100011001001010011110001011000100001010110100110011100001100011001100010110100010110101100110001000100000101111101100101010010000000110110101110111011111110100111011001000000101011000111000111010100111101011000101111100010100001111101000110010111010011011010011000100110001000001001011000011100111000000000101010010010000010100100111001001110001010011001100111000110010000111100000011101011101111001010001000000011011101010000000000011101100111000100000001001010001011110001001111101010111011100100111100101011111110100010000010010100101111100001011100010110110001101000010010111110101101100100011100000010110011100001111101000111110010111111001000001111111000101111110001010001111110000000110010011100111011010011010110010010000";
  
begin  -- rtl

  controller : FSM
    port map (
      ClkxCI      => ClkxCI,
      RstxRBI     => RstxRBI,
      EnxEI       => EnxEI,
      R36xSO      => R36xS,
      SavexSO     => SavexS,
      NewMsgxSO   => NewMsgxS,
      OutputEnxSO => OutputEnxSO);



  -- INITIALIZATION
  -----------------------------------------------------------------------------

  MxDN <= MsgInxDI when EnxEI = '1' else MxDP;

  HxorM : for i in 0 to 511 generate
    A(512+i)        <= IV(512+i) xor MsgInxDI(i) when NewMsgxS = '1' else HFinalxD(512+i) xor MsgInxDI(i);
    A(i)            <= IV(i)                     when NewMsgxS = '1' else HFinalxD(i);
    HFinalxD(512+i) <= HDegroupedxD(512+i);
    HFinalxD(i)     <= HDegroupedxD(i) xor MxDP(i);
  end generate HxorM;

  -- GROUP
  -----------------------------------------------------------------------------
  grouping : for i in 0 to 127 generate
    Group1(2*i)   <= (A(1023-i), A(767-i), A(511-i), A(255-i));
    Group1(2*i+1) <= (A(895-i), A(639-i), A(383-i), A(127-i));
  end generate grouping;


-- Round8
--------------------------------------------------------------------------------

  Temp1 <= Group1 when EnxEI = '1' else HxDP;
  CxD   <= CR0    when EnxEI = '1' else CxDP;

  sub : for i in 0 to 255 generate      -- Sub 4bits with SBOX SO or S1
                                        -- (depending on constant vector)
i) = '0' else S1(to_integer(unsigned(Temp1(i)(3 downto 0))));  --SBOX
  end generate sub;

  L : for i in 0 to 127 generate        --Linear Transformation
    D0(i) <= Temp2(2*i+1)(3) xor Temp2(2*i)(2);
    D1(i) <= Temp2(2*i+1)(2) xor Temp2(2*i)(1);
    D2(i) <= Temp2(2*i+1)(1) xor Temp2(2*i)(0) xor Temp2(2*i)(3);
    D3(i) <= Temp2(2*i+1)(0) xor Temp2(2*i)(3);

    C0(i) <= Temp2(2*i)(3) xor D1(i);
    C1(i) <= Temp2(2*i)(2) xor D2(i);
    C2(i) <= Temp2(2*i)(1) xor D3(i) xor D0(i);
    C3(i) <= Temp2(2*i)(0) xor D0(i);


    Temp3(2*i)   <= (C0(i) , C1(i) , C2(i) , C3(i));
    Temp3(2*i+1) <= (D0(i) , D1(i) , D2(i) , D3(i));
  end generate L;

  pi : for i in 0 to 63 generate        -- Permutation P8
    Temp4(4*i)   <= Temp3(4*i);
    Temp4(4*i+1) <= Temp3(4*i+1);
    Temp4(4*i+2) <= Temp3(4*i+3);
    Temp4(4*i+3) <= Temp3(4*i+2);
  end generate pi;

  pprime : for i in 0 to 127 generate
    Temp5(i)     <= Temp4(2*i);
    Temp5(i+128) <= Temp4(2*i+1);
    Temp6(i)     <= Temp5(i);
  end generate pprime;

  phi : for i in 64 to 127 generate
    Temp6(2*i)   <= Temp5(2*i+1);
    Temp6(2*i+1) <= Temp5(2*i);
  end generate phi;

  --SAVE STATE
  -----------------------------------------------------------------------------
  HxDN <= Temp6 when R36xS = '0' and SavexS = '0' else Temp2 when R36xS = '1' else HxDP;

  --DEGROUP
  -----------------------------------------------------------------------------
  degroupelement : for j in 0 to 3 generate
    degroup : for i in 0 to 127 generate
      HDegroupedxD(1023-256*j-i) <= HxDP(2*i)(3-j);
      HDegroupedxD(895-256*j-i)  <= HxDP(2*i+1)(3-j);
    end generate degroup;
  end generate degroupelement;

--C Calculation: Round6
  -------------------------------------------------------------------------------------------------
  CTemp1 <= CR0 when EnxEI = '1' else CxDP;


  Csub : for i in 0 to 63 generate      --Sub 4 bits with SBOX S0
    CGroup1(i) <= (CTemp1(255-i*4), CTemp1(254-i*4), CTemp1(253-i*4), CTemp1(252-i*4));
    CTemp2(i)  <= S0(to_integer(unsigned(CGroup1(i)(3 downto 0))));  --SBOX
  end generate Csub;

  LC : for i in 0 to 31 generate        --Linear Transformation
    CD0(i) <= CTemp2(2*i+1)(3) xor CTemp2(2*i)(2);
    CD1(i) <= CTemp2(2*i+1)(2) xor CTemp2(2*i)(1);
    CD2(i) <= CTemp2(2*i+1)(1) xor CTemp2(2*i)(0) xor CTemp2(2*i)(3);
    CD3(i) <= CTemp2(2*i+1)(0) xor CTemp2(2*i)(3);

    CC0(i) <= CTemp2(2*i)(3) xor CD1(i);
    CC1(i) <= CTemp2(2*i)(2) xor CD2(i);
    CC2(i) <= CTemp2(2*i)(1) xor CD3(i) xor CD0(i);
    CC3(i) <= CTemp2(2*i)(0) xor CD0(i);


    CTemp3(2*i)   <= (CC0(i) , CC1(i) , CC2(i) , CC3(i));
    CTemp3(2*i+1) <= (CD0(i) , CD1(i) , CD2(i) , CD3(i));
  end generate LC;

  Cpid : for i in 0 to 15 generate      --Permutation P6
    CTemp4(4*i)   <= CTemp3(4*i);
    CTemp4(4*i+1) <= CTemp3(4*i+1);
    CTemp4(4*i+2) <= CTemp3(4*i+3);
    CTemp4(4*i+3) <= CTemp3(4*i+2);
  end generate Cpid;

  Cpprime : for i in 0 to 31 generate
    CTemp5(i)    <= CTemp4(2*i);
    CTemp5(i+32) <= CTemp4(2*i+1);
    CTemp6(i)    <= CTemp5(i);
  end generate Cpprime;

  Cphi : for i in 16 to 31 generate
    CTemp6(2*i)   <= CTemp5(2*i+1);
    CTemp6(2*i+1) <= CTemp5(2*i);
  end generate Cphi;

  tostring : for i in 0 to 63 generate  --CGroup to bitstring
    CxDN(255-4*i) <= CTemp6(i)(3);
    CxDN(254-4*i) <= CTemp6(i)(2);
    CxDN(253-4*i) <= CTemp6(i)(1);
    CxDN(252-4*i) <= CTemp6(i)(0);
  end generate tostring;


--Output
  -----------------------------------------------------------------------------
  HashOutxDO <= HFinalxD(255 downto 0);


  -- Memory
  -----------------------------------------------------------------------------
  p_mem : process (ClkxCI, RstxRBI)
  begin  -- process p_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      MxDP <= (others => '0');
      HxDP <= (others => (others => '0'));
      CxDP <= (others => '0');
      
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      MxDP <= MxDN;
      HxDP <= HxDN;
      CxDP <= CxDN;
    end if;
  end process p_mem;
  

end rtl;



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