------------------------------------------------------------
-- 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.cubepkg.all;

entity cubehash is

  port (
    ClkxCI   : in  std_logic;
    RstxRBI  : in  std_logic;
    StartxSI : in  std_logic;
    INENxEI  : in  std_logic;
    OUTENxEO : out std_logic;
    DxDI     : in  std_logic_vector(255 downto 0);
    DxDO     : out std_logic_vector(HWIDTH-1 downto 0));

end cubehash;

architecture rtl of cubehash is
  
  component controller
    port (
      ClkxCI   : in  std_logic;
      RstxRBI  : in  std_logic;
      StartxSI : in  std_logic;
      INENxEI  : in  std_logic;
      OUTENxEO : out std_logic;
      XOR1xSO  : out std_logic);
  end component;

  signal XOR1xS             : std_logic;
  signal StatexDP, StatexDN : cubestate;
  signal OutRoundxD         : cubestate;
  
begin  -- rtl

  u_controller: controller
    port map (
      ClkxCI   => ClkxCI,
      RstxRBI  => RstxRBI,
      StartxSI => StartxSI,
      INENxEI  => INENxEI,
      OUTENxEO => OUTENxEO,
      XOR1xSO  => XOR1xS);

  -- ROUND
  -----------------------------------------------------------------------------
  p_round : process (StatexDP)
    variable PLUS1, ROT7, SWAP8, XOR1, SWAP2  : halfstate;
    variable PLUS2, ROT11, SWAP4, XOR2, SWAP1 : halfstate;
  begin  -- process p_round

    for i in 0 to 15 loop
      PLUS1(i) := std_logic_vector(unsigned(StatexDP(i)) + unsigned(StatexDP(i+16)));
    end loop;  -- i

    for i in 0 to 15 loop
      ROT7(i) := StatexDP(i)(31-7 downto 0) & StatexDP(i)(31 downto 32-7);
    end loop;  -- i

    for i in 0 to 7 loop
      SWAP8(i)   := ROT7(i+8);
      SWAP8(i+8) := ROT7(i);
    end loop;  -- i

    for i in 0 to 15 loop
      XOR1(i) := SWAP8(i) xor PLUS1(i);
    end loop;  -- i

    for i in 0 to 1 loop
      SWAP2(i)    := PLUS1(i+2);
      SWAP2(i+2)  := PLUS1(i);
      SWAP2(i+4)  := PLUS1(i+6);
      SWAP2(i+6)  := PLUS1(i+4);
      SWAP2(i+8)  := PLUS1(i+10);
      SWAP2(i+10) := PLUS1(i+8);
      SWAP2(i+12) := PLUS1(i+14);
      SWAP2(i+14) := PLUS1(i+12);
    end loop;  -- i

    ---------------------------- 

    for i in 0 to 15 loop
      PLUS2(i) := std_logic_vector(unsigned(XOR1(i)) + unsigned(SWAP2(i)));
    end loop;  -- i

    for i in 0 to 15 loop
      ROT11(i) := XOR1(i)(31-11 downto 0) & XOR1(i)(31 downto 32-11);
    end loop;  -- i

    for i in 0 to 3 loop
      SWAP4(i)    := ROT11(i+4);
      SWAP4(i+4)  := ROT11(i);
      SWAP4(i+8)  := ROT11(i+12);
      SWAP4(i+12) := ROT11(i+8);
    end loop;  -- i

    for i in 0 to 15 loop
      XOR2(i) := SWAP4(i) xor PLUS2(i);
    end loop;  -- i

    for i in 0 to 7 loop
      SWAP1(i*2)   := PLUS2(i*2+1);
      SWAP1(i*2+1) := PLUS2(i*2);
    end loop;  -- i

    for i in 0 to 15 loop
      OutRoundxD(i)    <= XOR2(i);
      OutRoundxD(i+16) <= SWAP1(i);
    end loop;  -- i
    
  end process p_round;

  -- Message XOR
  -----------------------------------------------------------------------------
  p_xorselect: process (DxDI, INENxEI, OutRoundxD, StartxSI, XOR1xS)
  begin  -- process p_xorselect

    if StartxSI = '1' and INENxEI = '1' then
      StatexDN                <= INITSTATE;
      
      for i in 0 to 7 loop
        StatexDN(i) <= INITSTATE(i) xor DxDI(256-32*(i)-1 downto 256-32*(i+1));
      end loop;  -- i
      
    elsif StartxSI = '0' and INENxEI = '1' then
      StatexDN                <= OutRoundxD;
      
      for i in 0 to 7 loop
        StatexDN(i) <= OutRoundxD(i) xor DxDI(256-32*(i)-1 downto 256-32*(i+1));
      end loop;  -- i
          
    else
      if XOR1xS = '1' then
        StatexDN        <= OutRoundxD;
        StatexDN(31)(0) <= OutRoundxD(31)(0) xor '1';
        
      else
       StatexDN <= OutRoundxD;

      end if;       
    end if;
    
  end process p_xorselect;

  -- Output Unform
  -----------------------------------------------------------------------------
  p_outext: for i in 0 to HWIDTH/32-1 generate
    p_outint: for j in 0 to 3 generate
      DxDO((HWIDTH/32-i)*32-j*8-1 downto (HWIDTH/32-i)*32-(j+1)*8) <= OutRoundxD(i)(8*(j+1)-1 downto 8*j);
    end generate p_outint;
  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'));
      
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      StatexDP <= StatexDN;
      
    end if;
  end process p_mem;
  

end rtl;

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