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

entity expansion is

  port (
    ClkxCI     : in  std_logic;
    RstxRBI    : in  std_logic;
    InputEnxEI : in  std_logic;
    DataBlkxDI : in  wordmat512;
    BitCntxDI  : in  wordmat64;
    SubKeyxDO  : out wordmat128);

end expansion;

architecture rtl of expansion is

  component aes
    port (
      ClkxCI   : in  std_logic;
      RstxRBI  : in  std_logic;
      PlainxDI : in  wordmat128;
      OutxDO   : out wordmat128);
  end component;

  signal AESInxD, AESOutxD, AESXorxD : wordmat128;
  signal StatexDP, StatexDN          : unsigned(5 downto 0);  --cycle counter:
  -- 0 = input fetch/AES, mod8=4 = XOR
  signal StateMatxDP, StateMatxDN    : wordmat512;
  
begin  -- rtl

  u_aes : aes
    port map (
      ClkxCI   => ClkxCI,
      RstxRBI  => RstxRBI,
      PlainxDI => AESInxD,
      OutxDO   => AESOutxD);


  -- Output
  output : for i in 3 downto 0 generate
    SubKeyxDO(i) <= StateMatxDP(i) when InputEnxEI = '0' else DataBlkxDI(i);
  end generate output;


  -- purpose: Control the expansion function
  -- type   : combinational
  -- inputs : AESOutxD, AESXorxD, BitCntxDI, DataBlkxDI, InputEnxEI, StateMatxDP, StatexDP
  -- outputs: AESInxD, AESXorxD, StateMatxDN, StatexDN
  p_fsm : process (AESOutxD, AESXorxD, BitCntxDI, DataBlkxDI, InputEnxEI,
                   StateMatxDP, StatexDP)
  begin  -- process p_fsm

    -- default assignments
    AESInxD(2) <= StateMatxDP(3);
    AESInxD(1) <= StateMatxDP(2);
    AESInxD(0) <= StateMatxDP(1);
    AESInxD(3) <= StateMatxDP(0);

    for i in 3 downto 0 loop
      AESXorxD(i) <= AESOutxD(i) xor StateMatxDP(12+i);
    end loop;  -- i
    StateMatxDN <= StateMatxDP;
    StatexDN    <= StatexDP+1;


    -- Walk through states 0...35
    StatexDN <= StatexDP+1;
    if to_integer(StatexDP) = 35 or (to_integer(StatexDP) = 0 and InputEnxEI = '0') then
      StatexDN <= (others => '0');
    end if;

    -- main operations: AES round, XOR of previous values
    if to_integer(StatexDP) mod 8 < 4 then  --AES
      for i in 0 to 3 loop
        StateMatxDN(i+12) <= AESXorxD(i);
      end loop;  -- i
    else                                    --XOR
      for i in 0 to 2 loop
        StateMatxDN(i+12) <= StateMatxDP(i) xor StateMatxDP(i+13);
      end loop;
      StateMatxDN(15) <= StateMatxDP(3) xor StateMatxDP(0) xor StateMatxDP(13);
    end if;

    -- Shift the state matrix
    for i in 11 downto 0 loop
      StateMatxDN(i) <= StateMatxDP(i+4);
    end loop;  -- i

    -- special cases
    case to_integer(StatexDP) is
      
      when 0 =>
        AESInxD(2)  <= DataBlkxDI(3);
        AESInxD(1)  <= DataBlkxDI(2);
        AESInxD(0)  <= DataBlkxDI(1);
        AESInxD(3)  <= DataBlkxDI(0);
        AESXorxD(0) <= AESOutxD(0) xor DataBlkxDI(12) xor BitCntxDI(0);
        AESXorxD(1) <= AESOutxD(1) xor DataBlkxDI(13) xor (not BitCntxDI(1));
        AESXorxD(2) <= AESOutxD(2) xor DataBlkxDI(14);
        AESXorxD(3) <= AESOutxD(3) xor DataBlkxDI(15);
        for i in 11 downto 0 loop
          StateMatxDN(i) <= DataBlkxDI(i+4);
        end loop;  -- i
        
      when 10 =>
        AESXorxD(0) <= AESOutxD(0) xor StateMatxDP(12);
        AESXorxD(1) <= AESOutxD(1) xor StateMatxDP(13) xor BitCntxDI(1);
        AESXorxD(2) <= AESOutxD(2) xor StateMatxDP(14) xor (not BitCntxDI(0));
        AESXorxD(3) <= AESOutxD(3) xor StateMatxDP(15);

      when 17 =>
        AESXorxD(0) <= AESOutxD(0) xor StateMatxDP(12);
        AESXorxD(1) <= AESOutxD(1) xor StateMatxDP(13);
        AESXorxD(2) <= AESOutxD(2) xor StateMatxDP(14) xor BitCntxDI(1);
        AESXorxD(3) <= AESOutxD(3) xor StateMatxDP(15) xor (not BitCntxDI(0));

      when 27 =>
        AESXorxD(0) <= AESOutxD(0) xor StateMatxDP(12) xor BitCntxDI(0);
        AESXorxD(1) <= AESOutxD(1) xor StateMatxDP(13);
        AESXorxD(2) <= AESOutxD(2) xor StateMatxDP(14);
        AESXorxD(3) <= AESOutxD(3) xor StateMatxDP(15) xor (not BitCntxDI(1));

      when others => null;

    end case;

  end process;


  p_mem : process (ClkxCI, RstxRBI)
  begin  -- process p_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      StatexDP    <= (others => '0');
      StateMatxDP <= (others => (others => '0'));

      
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      StatexDP    <= StatexDN;
      StateMatxDP <= StateMatxDN;
      
    end if;
  end process p_mem;

end rtl;

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