------------------------------------------------------------
-- Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.shabalPkg.all;

entity perm is
  port (
    ClkxCI      : in  std_logic;
    RstxRBI     : in  std_logic;
    NewBlockxSI : in  std_logic;
    StartxSI    : in  std_logic;
    MxDI        : in  std_logic_vector(WWIDTH*16-1 downto 0);
1 downto 0);  -- hash output (256 bit for Shabal-256)
    ValidOutxSO : out std_logic
    );

end perm;

architecture rtl of perm is

  component fsm
    port (
      ClkxCI      : in  std_logic;
      RstxRBI     : in  std_logic;
      NewBlockxSI : in  std_logic;
      StatexDO    : out integer range 0 to 6;
      CntxDO      : out integer range 0 to 48;
      ValidOutxSO : out std_logic);
  end component;
  
  signal AxDN, AxDP                         : blockA;
  signal MxDN, MxDP, BxDN, BxDP, CxDN, CxDP : blockB;
  signal WxDN, WxDP                         : blockW;
  signal StatexD                            : integer range 0 to 6;
  signal CntxD                              : integer range 0 to 48;
  
begin  -- rtl

  u_fsm : fsm
    port map (
      ClkxCI      => ClkxCI,
      RstxRBI     => RstxRBI,
      NewBlockxSI => NewBlockxSI,
      StatexDO    => StatexD,
      CntxDO      => CntxD,
      ValidOutxSO => ValidOutxSO);

  p_update : process (AxDP, BxDP, CntxD, CxDP, MxDI, MxDP, NewBlockxSI,
                      StartxSI, StatexD, WxDP)
    variable Aperm, Inperm1, Inperm2, In1, In2, AddOut, XorOut, XorIn, XorIn2 : std_logic_vector(31 downto 0) := (others => '0');
    variable winc                                                             : unsigned(63 downto 0);
    variable Wnew                                                             : blockW                        := (others => (others => '0'));
    
  begin  -- process p_update

    AxDN <= AxDP;
    BxDN <= BxDP;
    CxDN <= CxDP;
    MxDN <= MxDP;
    WxDN <= WxDP;

    In1    := (others => '0');
    In2    := (others => '0');
    XorIn  := (others => '0');
    XorIn2 := (others => '0');

    winc := unsigned(unsigned(WxDP(1)) & unsigned(WxDP(0)))+1;
    
    case StatexD is
      --when 1 =>
        
      when 2 =>
        In1 := BxDP(CntxD);
        In2 := MxDP(CntxD);

      when 3 =>
        Inperm1 := Rotl(AxDP(11), 15);
        In1     := Inperm1;
        In2     := Inperm1(29 downto 0) & '0' & '0';
        XorIn   := AxDP(0);
        XorIn2  := CxDP(8);

      when 4 =>
        Inperm2 := AxDP(0);
        In1     := Inperm2;
        In2     := Inperm2(30 downto 0) & '0';
        XorIn   := BxDP(o1);
        XorIn2  := MxDP(0);

      when 5 | 6 | 1 =>
        In1 := AxDP(0);
        In2 := CxDP(3);

      --when 6 =>
        --In1 := CxDP(CntxD);
        --In2 := std_logic_vector(unsigned(not MxDP(CntxD))+1);
        --In2 := not MxDP(CntxD);
        
      when others => null;
    end case;

    AddOut  := std_logic_vector(unsigned(In1) + unsigned(In2));
    XorOut  := AddOut xor XorIn xor XorIn2;

    case StatexD is
      
      when 1 =>
        Wnew := WxDP;
           
        if NewBlockxSI = '1' then
          -- initialize W
          for i in 0 to 15 loop
            MxDN(i) <= MxDI((16-i)*WWIDTH-1 downto (15-i)*WWIDTH);
          end loop;  -- i
        
          Wnew(1) := std_logic_vector(winc(63 downto 32));
          Wnew(0) := std_logic_vector(winc(31 downto 0));
          
        end if;

        WxDN    <= Wnew;
        AxDN(0) <= AxDP(0) xor Wnew(0);
        AxDN(1) <= AxDP(1) xor Wnew(1);

        if StartxSI = '1' then
          AxDN <= Ainit;
          BxDN <= Binit;
          CxDN <= Cinit;
          WxDN(1) <= x"00000000";
          WxDN(0) <= x"00000001";
        end if;
        
      when 2 =>
        --BxDN(CntxD) <= Rotl(AddOut,17);
        BxDN(CntxD) <= Rotl(XorOut,17);

      when 3 =>
        AxDN(0) <= XorOut;

      when 4 =>
        Aperm := XorOut xor (BxDP(o2) and not(BxDP(o3)));

        for i in 0 to 10 loop
          AxDN(i) <= AxDP(i+1);
        end loop;  -- i
        AxDN(11) <= Aperm;

        CxDN(0) <= CxDP(15);
        MxDN(0) <= MxDP(1);
        for i in 1 to 14 loop
          CxDN(i) <= CxDP(i-1);
          MxDN(i) <= MxDP(i+1);
        end loop;  -- i
        CxDN(15) <= CxDP(14);
        MxDN(15) <= MxDP(0);
        
        for i in 0 to 14 loop
          BxDN(i) <= BxDP(i+1);
        end loop;  -- i
        BxDN(15) <= Rotl(BxDP(0),1) xor not(Aperm);

      when 5 =>
        for i in 0 to 10 loop
          AxDN(i) <= AxDP(i+1);
        end loop;
        --AxDN(11) <= AddOut;
        AxDN(11) <= XorOut;

        CxDN(15) <= CxDP(0);
        for i in 0 to 14 loop
          CxDN(i) <= CxDP(i+1);
        end loop;

        if CntxD = 35 then
          CxDN(0) <= CxDP(13);
          CxDN(1) <= CxDP(14);
          CxDN(2) <= CxDP(15);
          for i in 3 to 15 loop
            CxDN(i) <= CxDP(i-3);
          end loop;
        end if;

      when 6 =>
        --BxDN(CntxD) <= std_logic_vector(unsigned(AddOut)+1);
        --BxDN(CntxD) <= AddOut;
        BxDN(CntxD) <= std_logic_vector(unsigned(CxDP(CntxD))- unsigned(MxDP(CntxD)));
        CxDN(CntxD) <= BxDP(CntxD);
        
      when others => null;
    end case;
    
  end process p_update;

  -----------------------------------------------------------------------------
  -- OUTPUT
  -----------------------------------------------------------------------------
  HashxDO(8*WWIDTH-1 downto 7*WWIDTH) <= CxDP(8);
  HashxDO(7*WWIDTH-1 downto 6*WWIDTH) <= CxDP(9);
  HashxDO(6*WWIDTH-1 downto 5*WWIDTH) <= CxDP(10);
  HashxDO(5*WWIDTH-1 downto 4*WWIDTH) <= CxDP(11);
  HashxDO(4*WWIDTH-1 downto 3*WWIDTH) <= CxDP(12);
  HashxDO(3*WWIDTH-1 downto 2*WWIDTH) <= CxDP(13);
  HashxDO(2*WWIDTH-1 downto WWIDTH)   <= CxDP(14);
  HashxDO(WWIDTH-1 downto 0)          <= CxDP(15);

  -----------------------------------------------------------------------------
  -- MEMORY
  -----------------------------------------------------------------------------
  
  p_mem: process (ClkxCI, RstxRBI)
  begin  -- process p_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      AxDP <= (others => (others => '0'));
      BxDP <= (others => (others => '0'));
      CxDP <= (others => (others => '0'));
      WxDP <= (others => (others => '0'));
      MxDP <= (others => (others => '0'));
      
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      AxDP <= AxDN;
      BxDP <= BxDN;
      CxDP <= CxDN;
      WxDP <= WxDN;
      MxDP <= MxDN;
      
    end if;
  end process p_mem;


end rtl;


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