------------------------------------------------------------
-- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title      : The P round of Groestl
-- Project    : 
-------------------------------------------------------------------------------
-- File       : greostl_p.vhd
-- Author     : Frank K. Guerkaynak  
-- Company    : Integrated Systems Laboratory, ETH Zurich
-- Created    : 2011-08-21
-- Last update: 2011-09-05
-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: 1/8 of the round
-------------------------------------------------------------------------------
-- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011-08-21  1.0      kgf	Created
-- 2011-09-04  1.1      kgf     Corrected many bugs
-- 2011-09-05  1.2      kgf     Moved the register after the roundconstants to
--                              reduce the input timing
-------------------------------------------------------------------------------



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

entity groestl_p is

  port (
    ClkxCI        : in  std_logic;
    RstxRBI       : in  std_logic;
    RndxSI        : in  std_logic_vector(7 downto 0);
    SubRndxSI     : in  integer range 0 to 7;
    InxDI         : in  std_logic_vector(511 downto 0);
    OutxDO        : out std_logic_vector(511 downto 0));

end groestl_p;

architecture rtl of groestl_p is

  component g_mixbytes
    port (
      InxDI  : in  std_logic_vector(63 downto 0);
      OutxDO : out std_logic_vector(7 downto 0));
  end component;

  component groestl_subbytes
    port (
      DxDI : in  std_logic_vector(7 downto 0);
      DxDO : out std_logic_vector(7 downto 0));
  end component;

  type statematrix is array (0 to 7, 0 to 7) of std_logic_vector (7 downto 0);
  type statearray  is array (0 to 7) of std_logic_vector (7 downto 0);
  type incconsttype is array (0 to 7) of integer range 0 to 7;
  type minputtype is array (0 to 7) of std_logic_vector(63 downto 0);

   

-- KGF states
  signal   PxDP, PxDN, P1xD : statematrix;
  signal   RPxD             : std_logic_vector(63 downto 0);  -- selected column 
  signal   SPxD             : std_logic_vector(63 downto 0);  -- after Subbytes
  signal   MPxD             : statearray;                     -- after MixBytes
  signal   M1xD             : minputtype;
  signal   PStartxD         : std_logic_vector(511 downto 0);  -- start of the Calculation
  signal   PFinxD           : std_logic_vector(511 downto 0);  -- end of the calculation
  constant INCP             : incconsttype := (0, 1, 2, 3, 4, 5, 6, 7);  -- shift amounts for P
                                                                        
  
begin  -- rtl

-------------------------------------------------------------------------------
-- New start either a fresh vector or a state round
-------------------------------------------------------------------------------

  PStartxD <= InxDI when RndxSI = "00000000" else PFinxD;
  
  p_new : process (SubRndxSI, RndxSI, P1xD, PStartxD)
     variable varp : statematrix;
  begin  -- process p_new
     varp := P1xD;
    
     if SubRndxSI = 0 then                  -- Add round constant
       varp(0, 0) := PStartxD(511 downto 504) xor x"00" xor RndxSI;
       varp(1, 0) := PStartxD(447 downto 440) xor x"10" xor RndxSI;
       varp(2, 0) := PStartxD(383 downto 376) xor x"20" xor RndxSI;
       varp(3, 0) := PStartxD(319 downto 312) xor x"30" xor RndxSI;
       varp(4, 0) := PStartxD(255 downto 248) xor x"40" xor RndxSI;
       varp(5, 0) := PStartxD(191 downto 184) xor x"50" xor RndxSI;
       varp(6, 0) := PStartxD(127 downto 120) xor x"60" xor RndxSI;
       varp(7, 0) := PStartxD( 63 downto  56) xor x"70" xor RndxSI;

       for y in 1 to 7 loop
         for x in 0 to 7 loop
           varp(x,y) := PStartxD((((7-x) * 64) + ((7-y) *8) + 7) downto ((7-x) * 64) + ((7-y) *8));
         end loop;  -- x
       end loop;  -- y

     end if;
     
     PxDN <= varp;
  end process p_new;

-------------------------------------------------------------------------------
-- Register is here PxDP PxDN
-------------------------------------------------------------------------------

  
-------------------------------------------------------------------------------
-- Select a vector to operate on. The shift is implicit in here
-------------------------------------------------------------------------------
 -- note that the SubRndxSI is one cycle behind, the register is before this
 p_selp: process (PxDP, SubRndxSI)
 begin  -- process p_selp
    case SubRndxSI is
      when 1      => RPxD <= PxDP(0,0) & PxDP(1,1) & PxDP(2,2) & PxDP(3,3) & PxDP(4,4) & PxDP(5,5) & PxDP(6,6) & PxDP(7,7);
      when 2      => RPxD <= PxDP(1,0) & PxDP(2,1) & PxDP(3,2) & PxDP(4,3) & PxDP(5,4) & PxDP(6,5) & PxDP(7,6) & PxDP(0,7);
      when 3      => RPxD <= PxDP(2,0) & PxDP(3,1) & PxDP(4,2) & PxDP(5,3) & PxDP(6,4) & PxDP(7,5) & PxDP(0,6) & PxDP(1,7);
      when 4      => RPxD <= PxDP(3,0) & PxDP(4,1) & PxDP(5,2) & PxDP(6,3) & PxDP(7,4) & PxDP(0,5) & PxDP(1,6) & PxDP(2,7);
      when 5      => RPxD <= PxDP(4,0) & PxDP(5,1) & PxDP(6,2) & PxDP(7,3) & PxDP(0,4) & PxDP(1,5) & PxDP(2,6) & PxDP(3,7);
      when 6      => RPxD <= PxDP(5,0) & PxDP(6,1) & PxDP(7,2) & PxDP(0,3) & PxDP(1,4) & PxDP(2,5) & PxDP(3,6) & PxDP(4,7);
      when 7      => RPxD <= PxDP(6,0) & PxDP(7,1) & PxDP(0,2) & PxDP(1,3) & PxDP(2,4) & PxDP(3,5) & PxDP(4,6) & PxDP(5,7);
      when others => RPxD <= PxDP(7,0) & PxDP(0,1) & PxDP(1,2) & PxDP(2,3) & PxDP(3,4) & PxDP(4,5) & PxDP(5,6) & PxDP(6,7);
    end case;
 end process p_selp;

-------------------------------------------------------------------------------
-- 8 x Sub bytes on this vector
-------------------------------------------------------------------------------
gen_p_sub: for i in 0 to 7 generate
    i_subbytes: groestl_subbytes  port map (DxDI => RPxD( (i*8) +7 downto i*8),
                                            DxDO => SPxD( (i*8) +7 downto i*8));
end generate gen_p_sub;

-------------------------------------------------------------------------------
-- We have a fixed MixBytes function. Normally the function is shifted, we will
-- shift the input data instead
-------------------------------------------------------------------------------
--   M1xD(0) SPxD;
--   M1xD(1) SPxD( 7 downto  0) & SPxD(63 downto  8);
--   M1xD(2) SPxD(15 downto  0) & SPxD(63 downto 16);
--   M1xD(3) SPxD(23 downto  0) & SPxD(63 downto 24);
--   M1xD(4) SPxD(31 downto  0) & SPxD(63 downto 32);
--   M1xD(5) SPxD(39 downto  0) & SPxD(63 downto 40);
--   M1xD(6) SPxD(47 downto  0) & SPxD(63 downto 48);
--   M1xD(7) SPxD(55 downto  0) & SPxD(63 downto 56);

   M1xD(0) <= SPxD;
   M1xD(1) <= SPxD(55 downto  0) & SPxD(63 downto 56);
   M1xD(2) <= SPxD(47 downto  0) & SPxD(63 downto 48);
   M1xD(3) <= SPxD(39 downto  0) & SPxD(63 downto 40);
   M1xD(4) <= SPxD(31 downto  0) & SPxD(63 downto 32);
   M1xD(5) <= SPxD(23 downto  0) & SPxD(63 downto 24);
   M1xD(6) <= SPxD(15 downto  0) & SPxD(63 downto 16);
   M1xD(7) <= SPxD( 7 downto  0) & SPxD(63 downto  8);


           
   gen_p_mix: for i in 0 to 7 generate
     i_mixbytes: g_mixbytes port map ( InxDI  => M1xD(i),
                                       OutxDO => MPxD(i));
   end generate gen_p_mix;
           

-------------------------------------------------------------------------------
-- Write back P 
-------------------------------------------------------------------------------
  
 p_shiftp: process (PxDP, SubRndxSI, MPxD)
    variable  varb: statematrix;
 begin  -- process p_selp
   -- default
   varb := PxDP;                        -- do not shift for the first 7 cycles;
      -- note that the SubRndxSI is one cycle behind, the register is before this
     case SubRndxSI is
      when 1      => varb(0,0) := MPxD(0); varb(1,1) := MPxD(1); varb(2,2) := MPxD(2); varb(3,3) := MPxD(3);
                     varb(4,4) := MPxD(4); varb(5,5) := MPxD(5); varb(6,6) := MPxD(6); varb(7,7) := MPxD(7);
      when 2      => varb(1,0) := MPxD(0); varb(2,1) := MPxD(1); varb(3,2) := MPxD(2); varb(4,3) := MPxD(3);
                     varb(5,4) := MPxD(4); varb(6,5) := MPxD(5); varb(7,6) := MPxD(6); varb(0,7) := MPxD(7);
      when 3      => varb(2,0) := MPxD(0); varb(3,1) := MPxD(1); varb(4,2) := MPxD(2); varb(5,3) := MPxD(3);
                     varb(6,4) := MPxD(4); varb(7,5) := MPxD(5); varb(0,6) := MPxD(6); varb(1,7) := MPxD(7);
      when 4      => varb(3,0) := MPxD(0); varb(4,1) := MPxD(1); varb(5,2) := MPxD(2); varb(6,3) := MPxD(3);
                     varb(7,4) := MPxD(4); varb(0,5) := MPxD(5); varb(1,6) := MPxD(6); varb(2,7) := MPxD(7);
      when 5      => varb(4,0) := MPxD(0); varb(5,1) := MPxD(1); varb(6,2) := MPxD(2); varb(7,3) := MPxD(3);
                     varb(0,4) := MPxD(4); varb(1,5) := MPxD(5); varb(2,6) := MPxD(6); varb(3,7) := MPxD(7);
      when 6      => varb(5,0) := MPxD(0); varb(6,1) := MPxD(1); varb(7,2) := MPxD(2); varb(0,3) := MPxD(3);
                     varb(1,4) := MPxD(4); varb(2,5) := MPxD(5); varb(3,6) := MPxD(6); varb(4,7) := MPxD(7);
      when 7      => varb(6,0) := MPxD(0); varb(7,1) := MPxD(1); varb(0,2) := MPxD(2); varb(1,3) := MPxD(3);
                     varb(2,4) := MPxD(4); varb(3,5) := MPxD(5); varb(4,6) := MPxD(6); varb(5,7) := MPxD(7);
       when others =>                    -- We wait for the shift until the last
                                        -- cycle. Now it iis time to shift all
                                        -- values
                     for y in 0 to 7 loop
                       for x in 0 to 6 loop
                         varb(x,y) := PxDP((x+INCP(y)) mod 8 , y);
                       end loop;  -- x
                       varb(7,y) := MPxD(y);
                     end loop;  -- y
    end case;
  P1xD <= varb;

 end process p_shiftp;

-------------------------------------------------------------------------------
-- Output 
-------------------------------------------------------------------------------

 p_out: process (P1xD)
   variable vout : std_logic_vector(511 downto 0);
 begin  -- process p_out
   for y in 0 to 7 loop
     for x in 0 to 7 loop
       vout( ((7-x)*64) + ((7-y) * 8) + 7  downto ((7-x)*64) + ((7-y)*8) ) := P1xD(x,y);
     end loop;  -- x
   end loop;  -- y
   PFinxD <= vout;
 end process p_out;


 OutxDO <= PFinxD;

 
  -- Memory
  -----------------------------------------------------------------------------
  p_mem : process (ClkxCI, RstxRBI)
  begin  -- process p_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      PxDP     <= (others => (others => (others => '0')));
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      PxDP     <= PxDN;
    end if;
  end process p_mem;


  
end rtl;



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