------------------------------------------------------------
-- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title      : Skein for ETHZ
-- Project    : Shabziger
-------------------------------------------------------------------------------
-- File       : ethz_skein.vhd
-- Author     : Chrikell
-- Company    : Integrated Systems Laboratory, ETH Zurich
-- Created    : 2011-08-25
-- Last update: 2011-09-01
-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: 
-------------------------------------------------------------------------------
-- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011-08-25  1.0      Chrikell
-------------------------------------------------------------------------------

library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use work.skeinpkg.all;

entity ethz_skein is

  port (
    ClkxCI         : in  std_logic;
    RstxRBI        : in  std_logic;
    FinBlockxSI    : in  std_logic;
    InWrEnxSI      : in  std_logic;
    OutWrEnxSO     : out std_logic;
    PenUltCyclexSO : out std_logic;
    BlockxDI       : in  std_logic_vector(511 downto 0);
    MsgLenxDI      : in  std_logic_vector(63 downto 0);  -- size of current Block, in Bytes. Only used if FinBlockxSI = '1'
    HashxDO        : out std_logic_vector(255 downto 0);
    ScanInxTI      : in  std_logic;
    ScanEnxTI      : in  std_logic;
    ScanOutxTO     : out std_logic
    );

end ethz_skein;

architecture rtl of ethz_skein is


  type Tweak is array (0 to 2) of std_logic_vector(63 downto 0);
  type FSMState is (idle, first, run, final);

  signal StatexDP, StatexDN, StateTmpxD : HashState;
  signal TmpStatexDP, TmpStatexDN       : HashUnsigned;
  signal MsgBlkxDN, MsgBlkxDP           : HashState;
  signal KeyxDP, KeyxDN                 : Key;
  signal TweakxDN, TweakxDP             : Tweak;
  signal ByteCntxDN, ByteCntxDP         : unsigned(63 downto 0);
  signal RoundxSP, RoundxSN, RoundxSPP  : unsigned(6 downto 0);
  signal FSMStatexDP, FSMStatexDN       : FSMState;
  signal WaitxSN, WaitxSP               : std_logic;
  signal KeyUpdxSN, KeyUpdxSP           : std_logic;
  signal FinBlockxSN, FinBlockxSP       : std_logic;
  signal KeyAddxSN, KeyAddxSP           : std_logic;
  signal OutWrEnxSN, OutWrEnxSP         : std_logic;
  signal FrstBlkxS                      : std_logic;
  signal FrstBlkxSP, FrstBlkxSN         : std_logic;
  signal FinalizexS                     : std_logic;
  signal Debug                          : integer;
  
  
  
begin  -- rtl

  -----------------------------------------------------------------------------
  -- FSM
  -----------------------------------------------------------------------------
  FSM : process (BlockxDI, ByteCntxDP, FSMStatexDP, FinBlockxSI, FinBlockxSP,
                 FrstBlkxSP, InWrEnxSI, KeyAddxSP, KeyUpdxSP, MsgBlkxDP,
                 MsgLenxDI, OutWrEnxSP, RoundxSP, WaitxSP)
  begin  -- process FSM

    FSMStatexDN    <= FSMStatexDP;
    MsgBlkxDN      <= MsgBlkxDP;
    RoundxSN       <= RoundxSP;
    FrstBlkxS      <= '0';
    FinBlockxSN    <= FinBlockxSP;
    KeyUpdxSN      <= '0';
    WaitxSN        <= '0';
    KeyAddxSN      <= '0';
    PenUltCyclexSO <= '0';
    OutWrEnxSN     <= '0';
    OutWrEnxSO     <= OutWrEnxSP;
    FinalizexS     <= '0';
    ByteCntxDN     <= ByteCntxDP;
    FrstBlkxSN     <= '0';



    case FSMStatexDP is
      -------------------------------------------------------------------------
      -- idle
      -------------------------------------------------------------------------
      when idle =>
        WaitxSN <= '1';
        if InWrEnxSI = '1' then
          for i in 0 to 7 loop
            for j in 0 to 7 loop
              MsgBlkxDN(7-j)((8*(i+1)-1) downto (8*i)) <= BlockxDI((j*64)+(8*(8-i)-1) downto (j*64)+(8*(7-i)));
            end loop;  --i
          end loop;  -- i
          KeyUpdxSN   <= '1';
          FSMStatexDN <= first;
          FinBlockxSN <= FinBlockxSI;
          KeyAddxSN   <= '1';
          WaitxSN     <= '0';
          ByteCntxDN  <= unsigned(MsgLenxDI);

        end if;
        RoundxSN <= (others => '0');


        -------------------------------------------------------------------------
        -- first
        -------------------------------------------------------------------------  
      when first =>
        FrstBlkxS <= '1';
        if RoundxSP(1 downto 0) = "10" then
          KeyUpdxSN <= '1';
        end if;
        if KeyAddxSP = '0' then
          RoundxSN <= RoundxSP +1;
          if RoundxSP(1 downto 0) = "11" then
            KeyAddxSN <= '1';
          end if;
        end if;
        if RoundxSP = 71 and FinBlockxSP = '0' then
          PenUltCyclexSO <= '1';
        end if;
        if RoundxSP = 72 then
          if FinBlockxSP = '1' then
            FSMStatexDN <= final;
            RoundxSN    <= (others => '0');
            KeyUpdxSN   <= '1';
            WaitxSN     <= '1';
            MsgBlkxDN   <= (others => (others => '0'));
            FrstBlkxSN  <= '1';
          elsif InWrEnxSI = '1' then
            FSMStatexDN <= run;
            RoundxSN    <= (others => '0');
            KeyUpdxSN   <= '1';
            WaitxSN     <= '1';
            FinBlockxSN <= FinBlockxSI;
            for i in 0 to 7 loop
              for j in 0 to 7 loop
                MsgBlkxDN(7-j)((8*(i+1)-1) downto (8*i)) <= BlockxDI((j*64)+(8*(8-i)-1) downto (j*64)+(8*(7-i)));
              end loop;  --i
            end loop;  -- i
            ByteCntxDN <= unsigned(MsgLenxDI);
          else
            RoundxSN <= RoundxSP;
            WaitxSN  <= '1';
          end if;
        end if;

        -------------------------------------------------------------------------
        -- run
        -------------------------------------------------------------------------  
      when run =>
        if RoundxSP = 0 and KeyUpdxSP = '1' then
          KeyAddxSN <= '1';
        end if;
        if RoundxSP(1 downto 0) = "10" then
          KeyUpdxSN <= '1';
        end if;
        if KeyAddxSP = '0' and WaitxSP = '0' then
          RoundxSN <= RoundxSP +1;
          if RoundxSP(1 downto 0) = "11" then
            KeyAddxSN <= '1';
          end if;
        end if;
        if RoundxSP = 71 and FinBlockxSP = '0' then
          PenUltCyclexSO <= '1';
        end if;
        if RoundxSP = 72 then
          if FinBlockxSP = '1' then
            FSMStatexDN <= final;
            RoundxSN    <= (others => '0');
            KeyUpdxSN   <= '1';
            WaitxSN     <= '1';
            MsgBlkxDN   <= (others => (others => '0'));
            FrstBlkxSN  <= '1';
          elsif InWrEnxSI = '1' then
            FSMStatexDN <= run;
            RoundxSN    <= (others => '0');
            KeyUpdxSN   <= '1';
            WaitxSN     <= '1';
            FinBlockxSN <= FinBlockxSI;
            for i in 0 to 7 loop
              for j in 0 to 7 loop
                MsgBlkxDN(7-j)((8*(i+1)-1) downto (8*i)) <= BlockxDI((j*64)+(8*(8-i)-1) downto (j*64)+(8*(7-i)));
              end loop;  --i
            end loop;  -- i
            ByteCntxDN <= unsigned(MsgLenxDI);
          else
            RoundxSN <= RoundxSP;
            WaitxSN  <= '1';
          end if;
          
        end if;

        -------------------------------------------------------------------------
        -- Final
        -------------------------------------------------------------------------  
      when final =>
        FrstBlkxSN <= FrstBlkxSP;
        FinalizexS <= '1';
        if RoundxSP = 0 and KeyUpdxSP = '1' then
          KeyAddxSN <= '1';
        end if;
        if RoundxSP(1 downto 0) = "10" then
          KeyUpdxSN <= '1';
        end if;
        if KeyAddxSP = '0' and WaitxSP = '0'then
          RoundxSN <= RoundxSP +1;
          if RoundxSP(1 downto 0) = "11" then
            KeyAddxSN <= '1';
          end if;
        end if;
        if RoundxSP = 71 then
          PenUltCyclexSO <= '1';
        end if;

        if RoundxSP = 72 then
          OutWrEnxSN <= '1';
          if InWrEnxSI = '1' then
            for i in 0 to 7 loop
              for j in 0 to 7 loop
                MsgBlkxDN(7-j)((8*(i+1)-1) downto (8*i)) <= BlockxDI((j*64)+(8*(8-i)-1) downto (j*64)+(8*(7-i)));
              end loop;  --i
            end loop;  -- i
            KeyUpdxSN   <= '1';
            FSMStatexDN <= first;
            FinBlockxSN <= FinBlockxSI;
            KeyAddxSN   <= '1';
            WaitxSN     <= '0';
            RoundxSN    <= (others => '0');
            ByteCntxDN  <= unsigned(MsgLenxDI);
          else
            FSMStatexDN <= idle;
            WaitxSN     <= '1';
          end if;
        end if;
      when others => null;
    end case;

  end process FSM;




  -----------------------------------------------------------------------------
  -- Key Management
  -----------------------------------------------------------------------------
  KeyMan : process (ByteCntxDP, FinBlockxSP, FinalizexS, FrstBlkxS, FrstBlkxSP,
                    KeyUpdxSP, KeyxDN, KeyxDP, MsgBlkxDP, RoundxSP, StatexDP,
                    TweakxDN, TweakxDP)
  begin  -- process KeyMan
    TweakxDN <= TweakxDP;
    KeyxDN   <= KeyxDP;


    if KeyUpdxSP = '1' then
      if RoundxSP = 0 or RoundxSP = 72 then
        if FrstBlkxS = '1' then
          for i in 0 to 7 loop
            KeyxDN(i) <= IV(i);
          end loop;  -- i
        else
          for i in 0 to 7 loop
            KeyxDN(i) <= StatexDP(i);
          end loop;  -- i          
        end if;  -- FrstBlkxS
        KeyxDN(8) <= C240 xor KeyxDN(0) xor KeyxDN(1) xor KeyxDN(2) xor KeyxDN(3) xor KeyxDN(4) xor KeyxDN(5) xor KeyxDN(6) xor KeyxDN(7);
        if FinalizexS = '0' then
          TweakxDN(1) <= FinBlockxSP & FrstBlkxS & "110000" &X"00000000000000";
          TweakxDN(0) <= std_logic_vector(ByteCntxDP);
        else
          TweakxDN(1) <= FinBlockxSP & FrstBlkxSP & "111111" &X"00000000000000";
          TweakxDN(0) <= X"000000000000000" & "1000";
        end if;
        TweakxDN(2) <= TweakxDN(0) xor TweakxDN(1);
      else
        TweakxDN(0) <= TweakxDP(1);
        TweakxDN(1) <= TweakxDP(2);
        TweakxDN(2) <= TweakxDP(0);

        KeyxDN(0) <= KeyxDP(1);
        KeyxDN(1) <= KeyxDP(2);
        KeyxDN(2) <= KeyxDP(3);
        KeyxDN(3) <= KeyxDP(4);
        KeyxDN(4) <= KeyxDP(5);
        KeyxDN(5) <= KeyxDP(6);
        KeyxDN(6) <= KeyxDP(7);
        KeyxDN(7) <= KeyxDP(8);
        KeyxDN(8) <= KeyxDP(0);
      end if;  --FrstRndxS

    end if;

    for i in 0 to 7 loop
      if RoundxSP = 0 then
        if i = 5 then
          StateTmpxD(i) <= std_logic_vector(unsigned(MsgBlkxDP(i)) + unsigned(KeyxDN(i))+unsigned(TweakxDN(0)));
        elsif i = 6 then
          StateTmpxD(i) <= std_logic_vector(unsigned(MsgBlkxDP(i)) + unsigned(KeyxDN(i))+unsigned(TweakxDN(1)));
        elsif i = 7 then
          StateTmpxD(i) <= std_logic_vector(unsigned(MsgBlkxDP(i)) + unsigned(KeyxDN(i))+RoundxSP(6 downto 2));
        else
          StateTmpxD(i) <= std_logic_vector(unsigned(MsgBlkxDP(i)) + unsigned(KeyxDN(i)));
        end if;
      elsif RoundxSP < 72 then
        if i = 5 then
          StateTmpxD(i) <= std_logic_vector(unsigned(StatexDP(i)) + unsigned(KeyxDN(i))+unsigned(TweakxDN(0)));
        elsif i = 6 then
          StateTmpxD(i) <= std_logic_vector(unsigned(StatexDP(i)) + unsigned(KeyxDN(i))+unsigned(TweakxDN(1)));
        elsif i = 7 then
          StateTmpxD(i) <= std_logic_vector(unsigned(StatexDP(i)) + unsigned(KeyxDN(i))+RoundxSP(6 downto 2));
        else
          StateTmpxD(i) <= std_logic_vector(unsigned(StatexDP(i)) + unsigned(KeyxDN(i)));
        end if;
      else
        if i = 5 then
          StateTmpxD(i) <= std_logic_vector((unsigned(StatexDP(i)) + unsigned(KeyxDN(i))+unsigned(TweakxDN(0))) xor unsigned(MsgBlkxDP(i)));
        elsif i = 6 then
          StateTmpxD(i) <= std_logic_vector((unsigned(StatexDP(i)) + unsigned(KeyxDN(i))+unsigned(TweakxDN(1))) xor unsigned(MsgBlkxDP(i)));
        elsif i = 7 then
          StateTmpxD(i) <= std_logic_vector((unsigned(StatexDP(i)) + unsigned(KeyxDN(i))+RoundxSP(6 downto 2)) xor unsigned(MsgBlkxDP(i)));
        else
          StateTmpxD(i) <= std_logic_vector((unsigned(StatexDP(i)) + unsigned(KeyxDN(i))) xor unsigned(MsgBlkxDP(i)));
        end if;
      end if;
      
    end loop;  -- i

  end process KeyMan;


-----------------------------------------------------------------------------
-- MixRound
-----------------------------------------------------------------------------
  Mixround : process (KeyAddxSP, MsgBlkxDP, RoundxSP, StateTmpxD, StatexDP,
                      TmpStatexDN, TmpStatexDP, WaitxSP)
  begin  -- process MixRound
    Debug <= 0;

    if WaitxSP = '0' then
      if KeyAddxSP = '0' then
        if RoundxSP < 72 then
          TmpStatexDN(6) <= TmpStatexDP(0)+ TmpStatexDP(1);
          TmpStatexDN(1) <= (TmpStatexDP(1) rol RotxS(to_integer(RoundxSP(2 downto 0)))(0)) xor TmpStatexDN(6);
          TmpStatexDN(0) <= TmpStatexDP(2)+ TmpStatexDP(3);
          TmpStatexDN(7) <= (TmpStatexDP(3) rol RotxS(to_integer(RoundxSP(2 downto 0)))(1)) xor TmpStatexDN(0);
          TmpStatexDN(2) <= TmpStatexDP(4)+ TmpStatexDP(5);
          TmpStatexDN(5) <= (TmpStatexDP(5) rol RotxS(to_integer(RoundxSP(2 downto 0)))(2)) xor TmpStatexDN(2);
          Debug          <= RotxS(to_integer(RoundxSP(2 downto 0)))(2);
          TmpStatexDN(4) <= TmpStatexDP(6)+ TmpStatexDP(7);
          TmpStatexDN(3) <= (TmpStatexDP(7) rol RotxS(to_integer(RoundxSP(2 downto 0)))(3)) xor TmpStatexDN(4);
          
        else
          for i in 0 to 7 loop
            TmpStatexDN(i) <= unsigned(StateTmpxD(i)) xor unsigned(MsgBlkxDP(i));
          end loop;  -- i
        end if;  -- round < 72
      else
        for i in 0 to 7 loop
          TmpStatexDN(i) <= unsigned(StateTmpxD(i));
        end loop;  -- i      
      end if;  --keyadd
    else
      TmpStatexDN <= TmpStatexDP;
    end if;  -- wait

    for i in 0 to 7 loop
      TmpStatexDP(i) <= unsigned(StatexDP(i));
      StatexDN(i)    <= std_logic_vector(TmpStatexDN(i));
    end loop;  -- i
    
  end process Mixround;

-----------------------------------------------------------------------------
-- Output Process
-----------------------------------------------------------------------------
  Output : process (StatexDP)
  begin  -- process Output
    for i in 0 to 7 loop
      for j in 0 to 3 loop
        HashxDO((j*64)+(8*(i+1)-1) downto (j*64)+(8*i)) <= StatexDP(3-j)((8*(8-i)-1) downto (8*(7-i)));
      end loop;  --i
    end loop;  -- i
  end process Output;


-----------------------------------------------------------------------------
-- register
-----------------------------------------------------------------------------
  P_Reg : process (ClkxCI, RstxRBI)
  begin  -- process Register
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      FSMStatexDP <= idle;
      StatexDP    <= (others => (others => '0'));
      MsgBlkxDP   <= (others => (others => '0'));
      KeyxDP      <= (others => (others => '0'));
      TweakxDP    <= (others => (others => '0'));
      ByteCntxDP  <= (others => '0');
      RoundxSP    <= (others => '0');
      RoundxSPP   <= (others => '0');
      WaitxSP     <= '0';
      KeyUpdxSP   <= '0';
      FinBlockxSP <= '0';
      KeyAddxSP   <= '0';
      OutWrEnxSP  <= '0';
      FrstBlkxSP  <= '0';
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      FSMStatexDP <= FSMStatexDN;
      StatexDP    <= StatexDN;
      MsgBlkxDP   <= MsgBlkxDN;
      KeyxDP      <= KeyxDN;
      TweakxDP    <= TweakxDN;
      ByteCntxDP  <= ByteCntxDN;
      RoundxSP    <= RoundxSN;
      RoundxSPP   <= RoundxSP;
      WaitxSP     <= WaitxSN;
      KeyUpdxSP   <= KeyUpdxSN;
      FinBlockxSP <= FinBlockxSN;
      KeyAddxSP   <= KeyAddxSN;
      OutWrEnxSP  <= OutWrEnxSN;
      FrstBlkxSP  <= FrstBlkxSN;
    end if;
  end process P_Reg;


end rtl;


Generated on Tue Nov 22 15:16:34 CET 2011
Home