------------------------------------------------------------
-- 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
                                                               -- (Shabal-256:8, Shabal-512:16)
    ValidOutxSO : out std_logic
    );

end perm;

architecture rtl of perm is
 
  component controller
    port (
      ClkxCI      : in  std_logic;
      RstxRBI     : in  std_logic;
      NewBlockxSI : in  std_logic;
      StatexDO    : out std_logic_vector(1 downto 0);
      CntxDO      : out unsigned(1 downto 0);
      LastxSO     : out std_logic;
      ValidOutxSO : out std_logic);
  
  end component;

  signal AxDN, AxDP                         : blockA;
  signal MxDN, MxDP, BxDN, BxDP, CxDN, CxDP : blockB;
  signal WxDN, WxDP                         : blockW;
  signal StatexD                            : std_logic_vector(1 downto 0);
  signal CntxD                              : unsigned(1 downto 0);
  signal LastxS                             : std_logic;
  
begin  -- rtl

  u_controller : controller
    port map (
      ClkxCI      => ClkxCI,
      RstxRBI     => RstxRBI,
      NewBlockxSI => NewBlockxSI,
      StatexDO    => StatexD,
      CntxDO      => CntxD,
      LastxSO     => LastxS,
      ValidOutxSO => ValidOutxSO);

  p_update : process (AxDP, BxDP, CntxD, CxDP, LastxS, MxDI, MxDP, NewBlockxSI,
                      StartxSI, StatexD, WxDP)
    variable Aperm, Wnew0, Wnew1, Anew0, Anew1 : std_logic_vector(31 downto 0);
    variable Marray, Bnew                      : blockB;
    
  begin  -- process p_update

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

    case StatexD is
      
      when "11" =>
        -- initialize M
        for i in 0 to 15 loop
          Marray(i) := MxDI((16-i)*WWIDTH-1 downto (15-i)*WWIDTH);
        end loop;  -- i

      
        if NewBlockxSI = '1' then
          MxDN <= Marray;
        end if;

        if StartxSI = '1' then
          -- initialize last 10 words of A
          AxDN(2 to 11) <= Ainit(2 to 11);

          Anew0 := Ainit(0);
          Anew1 := Ainit(1);
          Bnew := Binit;
        
          -- initialize C
          CxDN <= Cinit;
        
          Wnew0 := x"00000001";
          Wnew1 := (others => '0');
        
        else
          Anew0 := AxDP(0);
          Anew1 := AxDP(1);
          Bnew := BxDP;
          -- increment W unless the final block is processed
          if NewBlockxSI = '0' then
            Wnew0 := WxDP(0);
            Wnew1 := WxDP(1);
          else
            Wnew0 := std_logic_vector(unsigned(WxDP(0)) + 1);
            Wnew1 := WxDP(1);
            if Wnew0 = x"00000000" then
              Wnew1 := std_logic_vector(unsigned(WxDP(1)) + 1);
            end if;
          end if;
            
        end if;
      
        -- update/initialize W and first 2 words of A
        WxDN(0) <= Wnew0;
        WxDN(1) <= Wnew1;
        AxDN(0) <= Anew0 xor Wnew0;
        AxDN(1) <= Anew1 xor Wnew1;

        -- initialize B, add input block and rotate
        for i in 0 to 15 loop
          if LastxS = '0' then
            BxDN(i) <= Rotl(std_logic_vector(unsigned(Bnew(i)) + unsigned(Marray(i))),17);

          else
            BxDN(i) <= Rotl(std_logic_vector(unsigned(Bnew(i)) + unsigned(MxDP(i))),17);
            
          end if;
        end loop;

      -------------------------------------------------------------------------  
      when "01" =>
        for i in 0 to 10 loop
          AxDN(i) <= AxDP(i+1);
        end loop;  -- i
        Aperm := Ufun(AxDP(0) xor Vfun(Rotl(AxDP(11),15)) xor CxDP(8)) xor BxDP(o1) xor (BxDP(o2) and not(BxDP(o3))) xor MxDP(0);
        AxDN(11) <= Aperm;             -- A(i+16*j mod r) computation
--        for i in 0 to 15 loop
--          CxDN(i) CxDP(i-1 mod 16);
--          MxDN(i) MxDP(i+1 mod 16);
--        end loop;  -- i
        for i in 1 to 15 loop
          CxDN(i) <= CxDP(i-1);
        end loop;  -- i
        CxDN(0) <= CxDP(15);
        for i in 0 to 14 loop
          MxDN(i) <= MxDP(i+1);
        end loop;  -- i
        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 "10" =>
        for i in 0 to 11 loop
          AxDN(i) <= std_logic_vector(unsigned(AxDP(i)) + unsigned(CxDP(APCMATRIX(to_integer(CntxD),i))));
        end loop;  -- i
        
        -- after finishing the permutation, subtract the message block from C
        -- and swap B and C
        if CntxD = 2 then
          for i in 0 to 15 loop
            BxDN(i) <= std_logic_vector(unsigned(CxDP(i)) - unsigned(MxDP(i)));
            CxDN(i) <= BxDP(i);
          end loop;  -- i
      
        end if;

      -------------------------------------------------------------------------  
      when others => null;
    end case;
    
  end process p_update;

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

  -- Shabal-256 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