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

  port (
    ClkxCI            : in  std_logic;
    RstxRBI           : in  std_logic;
    BlockAvailablexSI : in  std_logic;
    FinBlockxSI       : in  std_logic;
    BlockxDI          : in  std_logic_vector(255 downto 0);
    HashAvailablexSO  : out std_logic;
    HashxDO           : out std_logic_vector(255 downto 0));

end skein;

architecture rtl of skein is

  component permix
    port (
      MxDI         : in  std_logic_vector(255 downto 0);
      PerselectxSI : in  std_logic;
      CntxDI       : in  unsigned(2 downto 0);
      MxDO         : out std_logic_vector(255 downto 0));
  end component;


  component subkey
    port (
      KxDI       : in  std_logic_vector(255 downto 0);
      SxSI       : in  std_logic_vector(4 downto 0);
      KenablexSI : in  std_logic;
      KinitxSI   : in  std_logic;
      RstxRBI    : in  std_logic;
      ClkxCI     : in  std_logic;
      CntxDI     : in  unsigned(2 downto 0);
      TxDI       : in  std_logic_vector(127 downto 0);
      KsxDO      : out std_logic_vector(127 downto 0));
  end component;

  component tweak
    port (
      BnxSI    : in  std_logic_vector(95 downto 0);
      FirstxSI : in  std_logic;
      FinalxSI : in  std_logic;
      OutxSI   : in  std_logic;
      TxDO     : out std_logic_vector(127 downto 0));
  end component;

  component controller
    port (
      BlockAvailablexSI : in  std_logic;
      ClkxCI            : in  std_logic;
      RstxRBI           : in  std_logic;
      SxSO              : out std_logic_vector(4 downto 0);
      MenablexSO        : out std_logic;
      CntxDO            : out unsigned(2 downto 0);
      GselectxSO        : out std_logic;
      PerselectxSO      : out std_logic;
      KenablexSO        : out std_logic;
      BcontrolxSO       : out std_logic_vector(1 downto 0);
      FirstxSO          : out std_logic;
      FinBlockxSI       : in  std_logic;
      OutxSO            : out std_logic;
      KinitxSO          : out std_logic;
      LastxSO           : out std_logic;
      MzeroxSO          : out std_logic;
      HashAvailablexSO  : out std_logic);
  end component;

  signal MxDN, MxDP, GxDN, GxDP, GtxDP, GKxD, PMxD, GXxD         : std_logic_vector(255 downto 0);
  signal KsxD                                                    : std_logic_vector(127 downto 0);
  signal BnxSN, BnxSP, BnxS                                      : std_logic_vector(95 downto 0);
  signal GselectxS, KenablexS, FirstxS, FinalxS, OutxS, MzeroxS  : std_logic;
  signal KinitxS, MenablexS, GenablexS, PerselectxS, FinalFlagxS : std_logic;
  signal BcontrolxS                                              : std_logic_vector(1 downto 0);
  signal SxS                                                     : std_logic_vector(4 downto 0);
  signal TxD                                                     : std_logic_vector(127 downto 0);
  signal CntxD                                                   : unsigned(2 downto 0);
  signal LastxS                                                  : std_logic;

  signal Kadd0AxD, Kadd0BxD : unsigned(63 downto 0);
  signal Kadd0CxD           : std_logic_vector(63 downto 0);

  signal Kadd1AxD, Kadd1BxD : unsigned(63 downto 0);
  signal Kadd1CxD           : std_logic_vector(63 downto 0);


  -- constant IV : std_logic_vector(255 downto 0) := (X"388512680E660046" & X"4B72D5DEC5A8FF01" & X"281A9298CA5EB3A5" & X"54CA5249F46070C4");
  
begin  -- rtl

  i_controller : controller
    port map (
      BlockAvailablexSI => BlockAvailablexSI,
      ClkxCI            => ClkxCI,
      RstxRBI           => RstxRBI,
      SxSO              => SxS,
      MenablexSO        => MenablexS,
      CntxDO            => CntxD,
      GselectxSO        => GselectxS,
      PerselectxSO      => PerselectxS,
      KenablexSO        => KenablexS,
      BcontrolxSO       => BcontrolxS,
      FirstxSO          => FirstxS,
      FinBlockxSI       => FinalFlagxS,
      OutxSO            => OutxS,
      KinitxSO          => KinitxS,
      MzeroxSO          => MzeroxS,
      LastxSO           => LastxS,
      HashAvailablexSO  => HashAvailablexSO);

  i_permix : permix
    port map (
      MxDI         => GKxD,
      PerselectxSI => PerselectxS,
      CntxDI       => CntxD,
      MxDO         => PMxD);


  i_subkey : subkey
    port map (
      KxDI       => GXxD,
      SxSI       => SxS,
      KenablexSI => KenablexS,
      KinitxSI   => KinitxS,
      CntxDI     => CntxD,
      RstxRBI    => RstxRBI,
      ClkxCI     => ClkxCI,
      TxDI       => TxD,
      KsxDO      => KsxD);


  i_tweak : tweak
    port map (
      BnxSI    => BnxS,
      FirstxSI => FirstxS,
      FinalxSI => FinBlockxSI,
      OutxSI   => OutxS,
      TxDO     => TxD);




  MxDN <= BlockxDI when MzeroxS = '0'   else (others => '0');
  GxDN <= MxDN     when GselectxS = '0' else GKxD when LastxS = '1' else PMxD;
  GxDP <= GtxDP    when MzeroxS = '0'   else (others => '0');

  Kadd0AxD <= unsigned(GxDP(255 downto 192)) when CntxD = 0 else unsigned(GxDP(127 downto 64));
  Kadd0BxD <= unsigned(KsxD(127 downto 64));

  Kadd1AxD <= unsigned(GxDP(191 downto 128)) when CntxD = 0 else unsigned(GxDP(63 downto 0));
  Kadd1BxD <= unsigned(KsxD(63 downto 0));

  Kadd0CxD <= std_logic_vector(Kadd0AxD + Kadd0BxD);
  Kadd1CxD <= std_logic_vector(Kadd1AxD + Kadd1BxD);

  GKxD(255 downto 192) <= Kadd0CxD when CntxD = 0 else GxDP(255 downto 192);
  GKxD(191 downto 128) <= Kadd1CxD when CntxD = 0 else GxDP(191 downto 128);
  
  GKxD(127 downto 64)  <= Kadd0CxD when CntxD = 1 else GxDP(127 downto 64);
  GKxD(63 downto 0)    <= Kadd1CxD when CntxD = 1 else GxDP(63 downto 0);
  

--  GKxD(255 downto 192) GxDP(255 downto 192)) + unsigned(KsxD(255 downto 192)));
--  GKxD(191 downto 128) GxDP(191 downto 128)) + unsigned(KsxD(191 downto 128)));
--  GKxD(127 downto 64)  GxDP(127 downto 64)) + unsigned(KsxD(127 downto 64)));
--  GKxD(63 downto 0)    GxDP(63 downto 0)) + unsigned(KsxD(63 downto 0)));


  GXxD <= MxDP xor GKxD;
  
  HashxDO <= GXxD;


  -- BnxS Counter
  -----------------------------------------------------------------------------

  BnxSN <= std_logic_vector(unsigned(BnxSP) + 32);
  BnxS  <= BnxSP;

  bn_counter : process (ClkxCI, RstxRBI)
  begin  -- process bn_counter
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      BnxSP <= (others => '0');
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      if BcontrolxS = "11" then
        BnxSP <= BnxSP;
      elsif BcontrolxS = "10" then
        BnxSP(95 downto 6) <= (others => '0');
        BnxSP(5 downto 0)  <= "100000";
      elsif BcontrolxS = "01" then
        BnxSP <= BnxSN;
      elsif BcontrolxS = "00" then
        BnxSP(95 downto 6) <= (others => '0');
        BnxSP(5 downto 0)  <= "001000";
      else
        BnxSP <= (others => '0');
      end if;
    end if;
  end process bn_counter;



  -- M-register
  -----------------------------------------------------------------------------
  M_mem : process (ClkxCI, RstxRBI)
  begin  -- process M_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      MxDP <= (others => '0');
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      if MEnablexS = '1' then
        MxDP <= MxDN;
      end if;
    end if;
  end process M_mem;
  -----------------------------------------------------------------------------

  -- F-register
  -----------------------------------------------------------------------------
  F_mem : process (ClkxCI, RstxRBI)
  begin  -- process F_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      FinalFlagxS <= '0';
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      if MEnablexS = '1' then
        FinalFlagxS <= FinBlockxSI;
      end if;
    end if;
  end process F_mem;
  -----------------------------------------------------------------------------


  -- G-register
  -----------------------------------------------------------------------------
  G_mem : process (ClkxCI, RstxRBI)
  begin  -- process G_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      GtxDP <= (others => '0');
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      GtxDP <= GxDN;
    end if;
  end process G_mem;
  -----------------------------------------------------------------------------


end rtl;

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