------------------------------------------------------------
-- 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 groestl is
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
EnxEI : in std_logic;
OutputEnxSO : out std_logic;
MsgInxDI : in std_logic_vector(511 downto 0);
HashOutxDO : out std_logic_vector(255 downto 0));
end groestl;
architecture rtl of groestl is
component FSM
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
EnxEI : in std_logic;
CntxDO : out unsigned(7 downto 0);
SetOupxSO : out std_logic;
NewMsgxSO : out std_logic;
ModexSO : out std_logic;
LastxSO : out std_logic;
OutputEnxSO : out std_logic);
end component;
component subbytes_groestl is
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
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);
signal CntxD : unsigned(7 downto 0);
signal QPxS : std_logic;
signal Col, Round : integer;
signal InputEnxS, SetOupxS, ModexS, NewMsgxS, LastxS : std_logic;
signal OutRoundxD, T1xD, T2xD : statearray;
signal ap, bp, cp, dp, ep, fp, gp, hp, dp1, ep1, gp1, hp1 : statearray;
signal aq, bq, cq, dq, eq, fq, gq, hq, dq1, eq1, gq1, hq1 : statearray;
signal StatePxDP, StatePxDN, StateQxDP, StateQxDN : statematrix;
signal InitStatePxD, InitStateQxD : statematrix;
signal FinalStatexDP, FinalStatexDN, HxD : statematrix;
begin -- rtl
controller : FSM
port map (
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
EnxEI => EnxEI,
CntxDO => CntxD,
SetOupxSO => SetOupxS,
NewMsgxSO => NewMsgxS,
ModexSO => ModexS,
LastxSO => LastxS,
OutputEnxSO => OutputEnxSO);
QPxS <= CntxD(3) or ModexS;
Round <= to_integer(CntxD(7 downto 4)) when ModexS = '0' else to_integer(CntxD(6 downto 3));
Col <= to_integer(CntxD(2 downto 0));
-- Initialization
-----------------------------------------------------------------------------
HxD(6, 7) <= x"01" when NewMsgxS = '1' else FinalStatexDN(6, 7);
hrow : for i in 0 to 5 generate
hcol : for j in 0 to 7 generate
HxD(i, j) <= x"00" when NewMsgxS = '1' else FinalStatexDN(i, j);
end generate hcol;
end generate hrow;
hline6 : for i in 0 to 6 generate
HxD(6, i) <= x"00" when NewMsgxS = '1' else FinalStatexDN(6, i);
end generate hline6;
hline7 : for i in 0 to 7 generate
HxD(7, i) <= x"00" when NewMsgxS = '1' else FinalStatexDN(7, i);
end generate hline7;
-- Init XOR
-------------------------------------------------------------------------
f_initi: for i in 0 to 7 generate
f_initj: for j in 0 to 7 generate
InitStateQxD(j, i) <= MsgInxDI(511-8*j-64*i downto 511-8*j-64*i-7);
InitStatePxD(j, i) <= MsgInxDI(511-8*j-64*i downto 511-8*j-64*i-7) xor HxD(j, i) when LastxS = '0' else HxD(j, i);
end generate f_initj;
end generate f_initi;
-- Input Mem
--------------------------------------------------------------------------------
p_inmem: process (Col, EnxEI, InitStatePxD, InitStateQxD, LastxS, OutRoundxD,
QPxS, StatePxDP, StateQxDP)
begin -- process p_inmem
StateQxDN <= StateQxDP;
StatePxDN <= StatePxDP;
if EnxEI = '1' or LastxS = '1' then
StateQxDN <= InitStateQxD;
StatePxDN <= InitStatePxD;
elsif QPxS = '0' then
if Col = 7 then
for i in 0 to 7 loop
StateQxDN(i, 0) <= StateQxDP(i, (i+1)mod 8);
StateQxDN(i, 1) <= StateQxDP(i, (i+2)mod 8);
StateQxDN(i, 2) <= StateQxDP(i, (i+3)mod 8);
StateQxDN(i, 3) <= StateQxDP(i, (i+4)mod 8);
StateQxDN(i, 4) <= StateQxDP(i, (i+5)mod 8);
StateQxDN(i, 5) <= StateQxDP(i, (i+6)mod 8);
StateQxDN(i, 6) <= StateQxDP(i, (i+7)mod 8);
StateQxDN(i, 7) <= OutRoundxD(i);
end loop; -- i
else
for i in 0 to 7 loop
StateQxDN(i, (i-1)mod 8) <= OutRoundxD(i);
StateQxDN(i, i) <= StateQxDP(i, (i+1)mod 8);
StateQxDN(i, (i+1)mod 8) <= StateQxDP(i, (i+2)mod 8);
StateQxDN(i, (i+2)mod 8) <= StateQxDP(i, (i+3)mod 8);
StateQxDN(i, (i+3)mod 8) <= StateQxDP(i, (i+4)mod 8);
StateQxDN(i, (i+4)mod 8) <= StateQxDP(i, (i+5)mod 8);
StateQxDN(i, (i+5)mod 8) <= StateQxDP(i, (i+6)mod 8);
StateQxDN(i, (i+6)mod 8) <= StateQxDP(i, (i+7)mod 8);
end loop; -- i
end if;
elsif QPxS = '1' then
if Col = 7 then
for i in 0 to 7 loop
StatePxDN(i, 0) <= StatePxDP(i, (i+1)mod 8);
StatePxDN(i, 1) <= StatePxDP(i, (i+2)mod 8);
StatePxDN(i, 2) <= StatePxDP(i, (i+3)mod 8);
StatePxDN(i, 3) <= StatePxDP(i, (i+4)mod 8);
StatePxDN(i, 4) <= StatePxDP(i, (i+5)mod 8);
StatePxDN(i, 5) <= StatePxDP(i, (i+6)mod 8);
StatePxDN(i, 6) <= StatePxDP(i, (i+7)mod 8);
StatePxDN(i, 7) <= OutRoundxD(i);
end loop; -- i
else
for i in 0 to 7 loop
StatePxDN(i, (i-1)mod 8) <= OutRoundxD(i);
StatePxDN(i, i) <= StatePxDP(i, (i+1)mod 8);
StatePxDN(i, (i+1)mod 8) <= StatePxDP(i, (i+2)mod 8);
StatePxDN(i, (i+2)mod 8) <= StatePxDP(i, (i+3)mod 8);
StatePxDN(i, (i+3)mod 8) <= StatePxDP(i, (i+4)mod 8);
StatePxDN(i, (i+4)mod 8) <= StatePxDP(i, (i+5)mod 8);
StatePxDN(i, (i+5)mod 8) <= StatePxDP(i, (i+6)mod 8);
StatePxDN(i, (i+6)mod 8) <= StatePxDP(i, (i+7)mod 8);
end loop; -- i
end if;
end if;
end process p_inmem;
-- AddRound Constants
-----------------------------------------------------------------------------
T1xD(0) <= StateQxDP(0, 0) when QPxS = '0' else
StatePxDP(0, 0) xor (x"0" & std_logic_vector(to_unsigned(Round, 4))) when (QPxS = '1' and Col = 0) else
StatePxDP(0, 0);
T1xD(1) <= StateQxDP(1, 1) when QPxS = '0' else StatePxDP(1, 1);
T1xD(2) <= StateQxDP(2, 2) when QPxS = '0' else StatePxDP(2, 2);
T1xD(3) <= StateQxDP(3, 3) when QPxS = '0' else StatePxDP(3, 3);
T1xD(4) <= StateQxDP(4, 4) when QPxS = '0' else StatePxDP(4, 4);
T1xD(5) <= StateQxDP(5, 5) when QPxS = '0' else StatePxDP(5, 5);
T1xD(6) <= StateQxDP(6, 6) when QPxS = '0' else StatePxDP(6, 6);
T1xD(7) <= StatePxDP(7, 7) when QPxS = '1' else
StateQxDP(7, 7) xor (x"F" & (not (std_logic_vector(CntxD(7 downto 4))))) when (QPxS = '0' and Col = 1) else
StateQxDP(7, 7);
-- SubBytes
-----------------------------------------------------------------------------
f_subb: for i in 0 to 7 generate
subbytes : subbytes_groestl
port map (
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
DxDI => T1xD(i),
DxDO => T2xD(i));
end generate f_subb;
-- MixBytes
-------------------------------------------------------------------------
mixcol : for j in 0 to 7 generate
-- 02
ap(j) <= T2xD(j)(6 downto 0)&'0' when T2xD(j)(7) = '0' else T2xD(j)(6 downto 0)&'0' xor x"1b";
-- 02
bp(j) <= T2xD((j+1)mod 8)(6 downto 0)&'0' when T2xD((j+1)mod 8)(7) = '0' else T2xD((j+1)mod 8)(6 downto 0)&'0' xor x"1b";
-- 03
cp(j) <= (T2xD((j+2) mod 8)(6 downto 0)&'0') xor T2xD((j+2) mod 8) when T2xD((j+2) mod 8)(7) = '0' else ((T2xD((j+2) mod 8)(6 downto 0)&'0') xor T2xD((j+2) mod 8)) xor x"1b";
-- 04
dp1(j) <= T2xD((j+3) mod 8)(5 downto 0)&'0'&'0';
dp(j) <= dp1(j) when T2xD((j+3) mod 8)(7) = '0' and T2xD((j+3) mod 8)(6) = '0' else dp1(j) xor x"36" when T2xD((j+3) mod 8)(7) = '1' and T2xD((j+3) mod 8)(6) = '0' else dp1(j) xor x"1b" when T2xD((j+3) mod 8)(7) = '0' and T2xD((j+3) mod 8)(6) = '1' else dp1(j) xor x"2d";
-- 05
ep1(j) <= (T2xD((j+4) mod 8)(5 downto 0)&'0'&'0') xor T2xD((j+4) mod 8);
ep(j) <= ep1(j) when T2xD((j+4) mod 8)(7) = '0' and T2xD((j+4) mod 8)(6) = '0' else ep1(j) xor x"36" when T2xD((j+4) mod 8)(7) = '1' and T2xD((j+4) mod 8)(6) = '0' else ep1(j) xor x"1b" when T2xD((j+4) mod 8)(7) = '0' and T2xD((j+4) mod 8)(6) = '1' else ep1(j) xor x"2d";
-- 03
fp(j) <= (T2xD((j+5) mod 8)(6 downto 0)&'0') xor T2xD((j+5) mod 8) when T2xD((j+5) mod 8)(7) = '0' else ((T2xD((j+5) mod 8)(6 downto 0)&'0') xor T2xD((j+5) mod 8)) xor x"1b";
-- 05
gp1(j) <= T2xD((j+6) mod 8)(5 downto 0)&'0'&'0' xor T2xD((j+6) mod 8);
gp(j) <= gp1(j) when T2xD((j+6) mod 8)(7) = '0' and T2xD((j+6) mod 8)(6) = '0' else gp1(j) xor x"36" when T2xD((j+6) mod 8)(7) = '1' and T2xD((j+6) mod 8)(6) = '0' else gp1(j) xor x"1b" when T2xD((j+6) mod 8)(7) = '0' and T2xD((j+6) mod 8)(6) = '1' else gp1(j) xor x"2d";
-- 07
hp1(j) <= (T2xD((j+7) mod 8)(6 downto 0)&'0') xor (T2xD((j+7) mod 8)(5 downto 0)&'0'&'0') xor T2xD((j+7) mod 8);
hp(j) <= hp1(j) when T2xD((j+7) mod 8)(7) = '0' and T2xD((j+7) mod 8)(6) = '0' else hp1(j) xor x"2d" when T2xD((j+7) mod 8)(7) = '1' and T2xD((j+7) mod 8)(6) = '0' else hp1(j) xor x"1b" when T2xD((j+7) mod 8)(7) = '0' and T2xD((j+7) mod 8)(6) = '1' else hp1(j) xor x"36";
OutRoundxD(j) <= (ap(j) xor bp(j)) xor (cp(j) xor dp(j)) xor (ep(j) xor fp(j)) xor (gp(j) xor hp(j));
end generate mixcol; --j
-- Final Xor
-----------------------------------------------------------------------------
f_fedforward: for i in 0 to 7 generate
FinalStatexDN(i, 0) <= x"00" when NewmsgxS = '1' else StateQxDP(i, 0) xor StatePxDP(i, (i+1)mod 8) xor FinalStatexDP(i, 0) when SetOupxS = '1' and ModexS = '0' else StatePxDP(i, (i+1)mod 8) xor FinalStatexDP(i, 0) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(i, 0);
FinalStatexDN(i, 1) <= x"00" when NewmsgxS = '1' else StateQxDP(i, 1) xor StatePxDP(i, (i+2)mod 8) xor FinalStatexDP(i, 1) when SetOupxS = '1' and ModexS = '0' else StatePxDP(i, (i+2)mod 8) xor FinalStatexDP(i, 1) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(i, 1);
FinalStatexDN(i, 2) <= x"00" when NewmsgxS = '1' else StateQxDP(i, 2) xor StatePxDP(i, (i+3)mod 8) xor FinalStatexDP(i, 2) when SetOupxS = '1' and ModexS = '0' else StatePxDP(i, (i+3)mod 8) xor FinalStatexDP(i, 2) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(i, 2);
FinalStatexDN(i, 3) <= x"00" when NewmsgxS = '1' else StateQxDP(i, 3) xor StatePxDP(i, (i+4)mod 8) xor FinalStatexDP(i, 3) when SetOupxS = '1' and ModexS = '0' else StatePxDP(i, (i+4)mod 8) xor FinalStatexDP(i, 3) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(i, 3);
FinalStatexDN(i, 4) <= x"00" when NewmsgxS = '1' else StateQxDP(i, 4) xor StatePxDP(i, (i+5)mod 8) xor FinalStatexDP(i, 4) when SetOupxS = '1' and ModexS = '0' else StatePxDP(i, (i+5)mod 8) xor FinalStatexDP(i, 4) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(i, 4);
FinalStatexDN(i, 5) <= x"00" when NewmsgxS = '1' else StateQxDP(i, 5) xor StatePxDP(i, (i+6)mod 8) xor FinalStatexDP(i, 5) when SetOupxS = '1' and ModexS = '0' else StatePxDP(i, (i+6)mod 8) xor FinalStatexDP(i, 5) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(i, 5);
FinalStatexDN(i, 6) <= x"00" when NewmsgxS = '1' else StateQxDP(i, 6) xor StatePxDP(i, (i+7)mod 8) xor FinalStatexDP(i, 6) when SetOupxS = '1' and ModexS = '0' else StatePxDP(i, (i+7)mod 8) xor FinalStatexDP(i, 6) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(i, 6);
end generate f_fedforward;
FinalStatexDN(0, 7) <= x"00" when NewmsgxS = '1' else StateQxDP(0, 7) xor OutRoundxD(0) xor FinalStatexDP(0, 7) when SetOupxS = '1' and ModexS = '0' else OutRoundxD(0) xor FinalStatexDP(0, 7) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(0, 7);
FinalStatexDN(1, 7) <= x"00" when NewmsgxS = '1' else StateQxDP(1, 7) xor OutRoundxD(1) xor FinalStatexDP(1, 7) when SetOupxS = '1' and ModexS = '0' else OutRoundxD(1) xor FinalStatexDP(1, 7) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(1, 7);
FinalStatexDN(2, 7) <= x"00" when NewmsgxS = '1' else StateQxDP(2, 7) xor OutRoundxD(2) xor FinalStatexDP(2, 7) when SetOupxS = '1' and ModexS = '0' else OutRoundxD(2) xor FinalStatexDP(2, 7) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(2, 7);
FinalStatexDN(3, 7) <= x"00" when NewmsgxS = '1' else StateQxDP(3, 7) xor OutRoundxD(3) xor FinalStatexDP(3, 7) when SetOupxS = '1' and ModexS = '0' else OutRoundxD(3) xor FinalStatexDP(3, 7) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(3, 7);
FinalStatexDN(4, 7) <= x"00" when NewmsgxS = '1' else StateQxDP(4, 7) xor OutRoundxD(4) xor FinalStatexDP(4, 7) when SetOupxS = '1' and ModexS = '0' else OutRoundxD(4) xor FinalStatexDP(4, 7) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(4, 7);
FinalStatexDN(5, 7) <= x"00" when NewmsgxS = '1' else StateQxDP(5, 7) xor OutRoundxD(5) xor FinalStatexDP(5, 7) when SetOupxS = '1' and ModexS = '0' else OutRoundxD(5) xor FinalStatexDP(5, 7) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(5, 7);
FinalStatexDN(6, 7) <= x"01" when NewmsgxS = '1' else StateQxDP(6, 7) xor OutRoundxD(6) xor FinalStatexDP(6, 7) when SetOupxS = '1' and ModexS = '0' else OutRoundxD(6) xor FinalStatexDP(6, 7) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(6, 7);
FinalStatexDN(7, 7) <= x"00" when NewmsgxS = '1' else StateQxDP(7, 7) xor OutRoundxD(7) xor FinalStatexDP(7, 7) when SetOupxS = '1' and ModexS = '0' else OutRoundxD(7) xor FinalStatexDP(7, 7) when SetOupxS = '1' and ModexS = '1' else FinalStatexDP(7, 7);
-- Output
-----------------------------------------------------------------------------
f_atosrow : for j in 4 to 7 generate
f_atoscol : for i in 0 to 7 generate
HashOutxDO(255-i*8-64*(j-4) downto 255-i*8-64*(j-4)-7) <= FinalStatexDN(i, j);
end generate f_atoscol;
end generate f_atosrow;
-- Memory
-----------------------------------------------------------------------------
p_mem : process (ClkxCI, RstxRBI)
begin -- process p_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
StatePxDP <= (others => (others => (others => '0')));
StateQxDP <= (others => (others => (others => '0')));
FinalStatexDP <= (others => (others => (others => '0')));
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
StatePxDP <= StatePxDN;
StateQxDP <= StateQxDN;
FinalStatexDP <= FinalStatexDN;
end if;
end process p_mem;
end rtl;