------------------------------------------------------------
-- 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 GFSM
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
EnxEI : in std_logic;
CntxDO : out unsigned(7 downto 0);
PQxSO : out std_logic;
SetOupxSO : out std_logic;
ModexSO : out std_logic;
NewMsgxSO : 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 statearray is array (0 to 7, 0 to 7) of std_logic_vector (7 downto 0);
signal CntxD : unsigned(7 downto 0);
signal SetOupxS, ModexS, PQxS, NewMsgxS : std_logic;
signal MStatexDP, MStatexDN, HStatexDP, HStatexDN : statearray;
signal InitStatexD, InitHStatexD : statearray;
signal PipeStatexDP, PipeStatexDN, HxD : statearray;
signal Temp1, Temp2 : statearray;
signal ap, bp, cp, dp, ep, fp, gp, hp, dp1, ep1, gp1, hp1 : statearray;
type ARRAY2048 is array (0 to 255) of std_logic_vector (7 downto 0);
constant SUBARRAY : ARRAY2048 := ("01100011", "01111100", "01110111", "01111011", "11110010", "01101011", "01101111", "11000101", "00110000", "00000001", "01100111", "00101011", "11111110", "11010111", "10101011", "01110110",
"11001010", "10000010", "11001001", "01111101", "11111010", "01011001", "01000111", "11110000", "10101101", "11010100", "10100010", "10101111", "10011100", "10100100", "01110010", "11000000",
"10110111", "11111101", "10010011", "00100110", "00110110", "00111111", "11110111", "11001100", "00110100", "10100101", "11100101", "11110001", "01110001", "11011000", "00110001", "00010101",
"00000100", "11000111", "00100011", "11000011", "00011000", "10010110", "00000101", "10011010", "00000111", "00010010", "10000000", "11100010", "11101011", "00100111", "10110010", "01110101",
"00001001", "10000011", "00101100", "00011010", "00011011", "01101110", "01011010", "10100000", "01010010", "00111011", "11010110", "10110011", "00101001", "11100011", "00101111", "10000100",
"01010011", "11010001", "00000000", "11101101", "00100000", "11111100", "10110001", "01011011", "01101010", "11001011", "10111110", "00111001", "01001010", "01001100", "01011000", "11001111",
"11010000", "11101111", "10101010", "11111011", "01000011", "01001101", "00110011", "10000101", "01000101", "11111001", "00000010", "01111111", "01010000", "00111100", "10011111", "10101000",
"01010001", "10100011", "01000000", "10001111", "10010010", "10011101", "00111000", "11110101", "10111100", "10110110", "11011010", "00100001", "00010000", "11111111", "11110011", "11010010",
"11001101", "00001100", "00010011", "11101100", "01011111", "10010111", "01000100", "00010111", "11000100", "10100111", "01111110", "00111101", "01100100", "01011101", "00011001", "01110011",
"01100000", "10000001", "01001111", "11011100", "00100010", "00101010", "10010000", "10001000", "01000110", "11101110", "10111000", "00010100", "11011110", "01011110", "00001011", "11011011",
"11100000", "00110010", "00111010", "00001010", "01001001", "00000110", "00100100", "01011100", "11000010", "11010011", "10101100", "01100010", "10010001", "10010101", "11100100", "01111001",
"11100111", "11001000", "00110111", "01101101", "10001101", "11010101", "01001110", "10101001", "01101100", "01010110", "11110100", "11101010", "01100101", "01111010", "10101110", "00001000",
"10111010", "01111000", "00100101", "00101110", "00011100", "10100110", "10110100", "11000110", "11101000", "11011101", "01110100", "00011111", "01001011", "10111101", "10001011", "10001010",
"01110000", "00111110", "10110101", "01100110", "01001000", "00000011", "11110110", "00001110", "01100001", "00110101", "01010111", "10111001", "10000110", "11000001", "00011101", "10011110",
"11100001", "11111000", "10011000", "00010001", "01101001", "11011001", "10001110", "10010100", "10011011", "00011110", "10000111", "11101001", "11001110", "01010101", "00101000", "11011111",
"10001100", "10100001", "10001001", "00001101", "10111111", "11100110", "01000010", "01101000", "01000001", "10011001", "00101101", "00001111", "10110000", "01010100", "10111011", "00010110");
begin -- rtl
controller : GFSM
port map (
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
EnxEI => EnxEI,
CntxDO => CntxD,
PQxSO => PQxS,
SetOupxSO => SetOupxS,
ModexSO => ModexS,
NewMsgxSO => NewMsgxS,
OutputEnxSO => OutputEnxSO);
subwolki: for i in 0 to 7 generate
subwolkj: for j in 0 to 7 generate
PipeStatexDN(i, j) <= SUBARRAY(to_integer(unsigned(temp2(i, ((j+i) mod 8)))));
-- sub : subbytes_groestl
-- port map (
-- ClkxCI => ClkxCI,
-- RstxRBI => RstxRBI,
-- DxDI => temp2(i, ((j+i) mod 8)),
-- DxDO => PipeStatexDN(i, j));
end generate subwolkj;
end generate subwolki;
-- INITIALIZATION
-----------------------------------------------------------------------------
HxD(6, 7) <= x"01" when NewMsgxS = '1' else HStatexDP (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 HStatexDP (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 HStatexDP (6, i);
end generate hline6;
hline7 : for i in 0 to 7 generate
HxD(7, i) <= x"00" when NewMsgxS = '1' else HStatexDP (7, i);
end generate hline7;
-- ROUND
--------------------------------------------------------------------------------
Temp1 <= InitStatexD when CntxD = 0 and PQxS = '0' else MStatexDP;
Temp2(0, 0) <= std_logic_vector(CntxD) xor Temp1(0, 0) when PQxS = '0' else Temp1(0, 0); --addroundconstant P
Temp2(7, 0) <= std_logic_vector(CntxD) xor x"ff" xor Temp1(7, 0) when PQxS = '1' else Temp1(7, 0); --Addroundconstant Q
line07 : for i in 1 to 7 generate
Temp2(0, i) <= Temp1(0, i);
Temp2(7, i) <= Temp1(7, i);
end generate;
row : for i in 1 to 6 generate
column : for j in 0 to 7 generate
Temp2(i, j) <= Temp1(i, j);
end generate column; --j
end generate row; --i
mixrow : for i in 0 to 7 generate --mixbytes
mixcol : for j in 0 to 7 generate
7) xor HxD(i, j) when ModexS = '0' else HxD(i, j); --setinitstateP
MStatexDN(i, j) <= MsgInxDI(511-8*i-64*j downto 511-8*i-64*j-7) when CntxD = 0 and PQxS = '0' else (ap(i, j) xor bp(i, j)) xor (cp(i, j) xor dp(i, j)) xor (ep(i, j) xor fp(i, j)) xor (gp(i, j) xor hp(i, j));
-- The subshiftbytes operation is now carried out with the subbytes compontent
-- and directly writen to the PipeState-Register
ap(i, j) <= PipeStatexDP(i, j)(6 downto 0)&'0' when PipeStatexDP(i, j)(7) = '0' else PipeStatexDP(i, j)(6 downto 0)&'0' xor x"1b";
bp(i, j) <= PipeStatexDP(((i+1) mod 8), j)(6 downto 0)&'0' when PipeStatexDP(((i+1) mod 8), j)(7) = '0' else PipeStatexDP(((i+1) mod 8), j)(6 downto 0)&'0' xor x"1b";
cp(i, j) <= (PipeStatexDP(((i+2) mod 8), j)(6 downto 0)&'0') xor PipeStatexDP(((i+2) mod 8), j) when PipeStatexDP(((i+2) mod 8), j)(7) = '0' else ((PipeStatexDP(((i+2) mod 8), j)(6 downto 0)&'0') xor PipeStatexDP(((i+2) mod 8), j)) xor x"1b";
dp1(i, j) <= PipeStatexDP(((i+3) mod 8), j)(5 downto 0)&'0'&'0';
dp(i, j) <= dp1(i, j) when PipeStatexDP(((i+3) mod 8), j)(7) = '0' and PipeStatexDP(((i+3) mod 8), j)(6) = '0' else dp1(i, j) xor x"36" when PipeStatexDP(((i+3) mod 8), j)(7) = '1' and PipeStatexDP(((i+3) mod 8), j)(6) = '0' else dp1(i, j) xor x"1b" when PipeStatexDP(((i+3) mod 8), j)(7) = '0' and PipeStatexDP(((i+3) mod 8), j)(6) = '1' else dp1(i, j) xor x"2d";
ep1(i, j) <= (PipeStatexDP(((i+4) mod 8), j)(5 downto 0)&'0'&'0') xor PipeStatexDP(((i+4) mod 8), j);
ep(i, j) <= ep1(i, j) when PipeStatexDP(((i+4) mod 8), j)(7) = '0' and PipeStatexDP(((i+4) mod 8), j)(6) = '0' else ep1(i, j) xor x"36" when PipeStatexDP(((i+4) mod 8), j)(7) = '1' and PipeStatexDP(((i+4) mod 8), j)(6) = '0' else ep1(i, j) xor x"1b" when PipeStatexDP(((i+4) mod 8), j)(7) = '0' and PipeStatexDP(((i+4) mod 8), j)(6) = '1' else ep1(i, j) xor x"2d";
fp(i, j) <= (PipeStatexDP(((i+5) mod 8), j)(6 downto 0)&'0') xor PipeStatexDP(((i+5) mod 8), j) when PipeStatexDP(((i+5) mod 8), j)(7) = '0' else ((PipeStatexDP(((i+5) mod 8), j)(6 downto 0)&'0') xor PipeStatexDP(((i+5) mod 8), j)) xor x"1b";
gp1(i, j) <= PipeStatexDP(((i+6) mod 8), j)(5 downto 0)&'0'&'0' xor PipeStatexDP(((i+6) mod 8), j);
gp(i, j) <= gp1(i, j) when PipeStatexDP(((i+6) mod 8), j)(7) = '0' and PipeStatexDP(((i+6) mod 8), j)(6) = '0' else gp1(i, j) xor x"36" when PipeStatexDP(((i+6) mod 8), j)(7) = '1' and PipeStatexDP(((i+6) mod 8), j)(6) = '0' else gp1(i, j) xor x"1b" when PipeStatexDP(((i+6) mod 8), j)(7) = '0' and PipeStatexDP(((i+6) mod 8), j)(6) = '1' else gp1(i, j) xor x"2d";
hp1(i, j) <= (PipeStatexDP(((i+7) mod 8), j)(6 downto 0)&'0') xor (PipeStatexDP(((i+7) mod 8), j)(5 downto 0)&'0'&'0') xor PipeStatexDP(((i+7) mod 8), j);
hp(i, j) <= hp1(i, j) when PipeStatexDP(((i+7) mod 8), j)(7) = '0' and PipeStatexDP(((i+7) mod 8), j)(6) = '0' else hp1(i, j) xor x"2d" when PipeStatexDP(((i+7) mod 8), j)(7) = '1' and PipeStatexDP(((i+7) mod 8), j)(6) = '0' else hp1(i, j) xor x"1b" when PipeStatexDP(((i+7) mod 8), j)(7) = '0' and PipeStatexDP(((i+7) mod 8), j)(6) = '1' else hp1(i, j) xor x"36";
--Compression
HStatexDN(i, j) <= MStatexDN(i, j) xor MStatexDP(i, j) xor HStatexDP(i, j) when SetOupxS = '1' and ModexS = '0' else MStatexDN(i, j) xor HStatexDP(i, j) when SetOupxS = '1' and ModexS = '1' else HxD(i, j);
end generate mixcol; --j
end generate mixrow; --i
--Output
atosrow : for j in 4 to 7 generate
atoscol : for i in 0 to 7 generate
HashOutxDO(255-i*8-64*(j-4) downto 255-i*8-64*(j-4)-7) <= HStatexDN(i, j);
end generate atoscol;
end generate atosrow;
-- Memory
-----------------------------------------------------------------------------
p_mem : process (ClkxCI, RstxRBI)
begin -- process p_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
MStatexDP <= (others => (others => (others => '0')));
HStatexDP <= (others => (others => (others => '0')));
PipeStatexDP <= (others => (others => (others => '0')));
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
MStatexDP <= MStatexDN;
HStatexDP <= HStatexDN;
PipeStatexDP <= PipeStatexDN;
end if;
end process p_mem;
end rtl;