------------------------------------------------------------ -- 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;