------------------------------------------------------------ -- Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich -- http://www.iis.ee.ethz.ch/~sha3 ------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.shabalPkg.all; entity perm is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; NewBlockxSI : in std_logic; StartxSI : in std_logic; MxDI : in std_logic_vector(WWIDTH*16-1 downto 0); 1 downto 0); -- hash output (256 bit for Shabal-256) ValidOutxSO : out std_logic ); end perm; architecture rtl of perm is component fsm port ( ClkxCI : in std_logic; RstxRBI : in std_logic; NewBlockxSI : in std_logic; StatexDO : out integer range 0 to 6; CntxDO : out integer range 0 to 48; ValidOutxSO : out std_logic); end component; signal AxDN, AxDP : blockA; signal MxDN, MxDP, BxDN, BxDP, CxDN, CxDP : blockB; signal WxDN, WxDP : blockW; signal StatexD : integer range 0 to 6; signal CntxD : integer range 0 to 48; begin -- rtl u_fsm : fsm port map ( ClkxCI => ClkxCI, RstxRBI => RstxRBI, NewBlockxSI => NewBlockxSI, StatexDO => StatexD, CntxDO => CntxD, ValidOutxSO => ValidOutxSO); p_update : process (AxDP, BxDP, CntxD, CxDP, MxDI, MxDP, NewBlockxSI, StartxSI, StatexD, WxDP) variable Aperm, Inperm1, Inperm2, In1, In2, AddOut, XorOut, XorIn, XorIn2 : std_logic_vector(31 downto 0) := (others => '0'); variable winc : unsigned(63 downto 0); variable Wnew : blockW := (others => (others => '0')); begin -- process p_update AxDN <= AxDP; BxDN <= BxDP; CxDN <= CxDP; MxDN <= MxDP; WxDN <= WxDP; In1 := (others => '0'); In2 := (others => '0'); XorIn := (others => '0'); XorIn2 := (others => '0'); winc := unsigned(unsigned(WxDP(1)) & unsigned(WxDP(0)))+1; case StatexD is --when 1 => when 2 => In1 := BxDP(CntxD); In2 := MxDP(CntxD); when 3 => Inperm1 := Rotl(AxDP(11), 15); In1 := Inperm1; In2 := Inperm1(29 downto 0) & '0' & '0'; XorIn := AxDP(0); XorIn2 := CxDP(8); when 4 => Inperm2 := AxDP(0); In1 := Inperm2; In2 := Inperm2(30 downto 0) & '0'; XorIn := BxDP(o1); XorIn2 := MxDP(0); when 5 | 6 | 1 => In1 := AxDP(0); In2 := CxDP(3); --when 6 => --In1 := CxDP(CntxD); --In2 := std_logic_vector(unsigned(not MxDP(CntxD))+1); --In2 := not MxDP(CntxD); when others => null; end case; AddOut := std_logic_vector(unsigned(In1) + unsigned(In2)); XorOut := AddOut xor XorIn xor XorIn2; case StatexD is when 1 => Wnew := WxDP; if NewBlockxSI = '1' then -- initialize W for i in 0 to 15 loop MxDN(i) <= MxDI((16-i)*WWIDTH-1 downto (15-i)*WWIDTH); end loop; -- i Wnew(1) := std_logic_vector(winc(63 downto 32)); Wnew(0) := std_logic_vector(winc(31 downto 0)); end if; WxDN <= Wnew; AxDN(0) <= AxDP(0) xor Wnew(0); AxDN(1) <= AxDP(1) xor Wnew(1); if StartxSI = '1' then AxDN <= Ainit; BxDN <= Binit; CxDN <= Cinit; WxDN(1) <= x"00000000"; WxDN(0) <= x"00000001"; end if; when 2 => --BxDN(CntxD) <= Rotl(AddOut,17); BxDN(CntxD) <= Rotl(XorOut,17); when 3 => AxDN(0) <= XorOut; when 4 => Aperm := XorOut xor (BxDP(o2) and not(BxDP(o3))); for i in 0 to 10 loop AxDN(i) <= AxDP(i+1); end loop; -- i AxDN(11) <= Aperm; CxDN(0) <= CxDP(15); MxDN(0) <= MxDP(1); for i in 1 to 14 loop CxDN(i) <= CxDP(i-1); MxDN(i) <= MxDP(i+1); end loop; -- i CxDN(15) <= CxDP(14); MxDN(15) <= MxDP(0); for i in 0 to 14 loop BxDN(i) <= BxDP(i+1); end loop; -- i BxDN(15) <= Rotl(BxDP(0),1) xor not(Aperm); when 5 => for i in 0 to 10 loop AxDN(i) <= AxDP(i+1); end loop; --AxDN(11) <= AddOut; AxDN(11) <= XorOut; CxDN(15) <= CxDP(0); for i in 0 to 14 loop CxDN(i) <= CxDP(i+1); end loop; if CntxD = 35 then CxDN(0) <= CxDP(13); CxDN(1) <= CxDP(14); CxDN(2) <= CxDP(15); for i in 3 to 15 loop CxDN(i) <= CxDP(i-3); end loop; end if; when 6 => --BxDN(CntxD) <= std_logic_vector(unsigned(AddOut)+1); --BxDN(CntxD) <= AddOut; BxDN(CntxD) <= std_logic_vector(unsigned(CxDP(CntxD))- unsigned(MxDP(CntxD))); CxDN(CntxD) <= BxDP(CntxD); when others => null; end case; end process p_update; ----------------------------------------------------------------------------- -- OUTPUT ----------------------------------------------------------------------------- HashxDO(8*WWIDTH-1 downto 7*WWIDTH) <= CxDP(8); HashxDO(7*WWIDTH-1 downto 6*WWIDTH) <= CxDP(9); HashxDO(6*WWIDTH-1 downto 5*WWIDTH) <= CxDP(10); HashxDO(5*WWIDTH-1 downto 4*WWIDTH) <= CxDP(11); HashxDO(4*WWIDTH-1 downto 3*WWIDTH) <= CxDP(12); HashxDO(3*WWIDTH-1 downto 2*WWIDTH) <= CxDP(13); HashxDO(2*WWIDTH-1 downto WWIDTH) <= CxDP(14); HashxDO(WWIDTH-1 downto 0) <= CxDP(15); ----------------------------------------------------------------------------- -- MEMORY ----------------------------------------------------------------------------- p_mem: process (ClkxCI, RstxRBI) begin -- process p_mem if RstxRBI = '0' then -- asynchronous reset (active low) AxDP <= (others => (others => '0')); BxDP <= (others => (others => '0')); CxDP <= (others => (others => '0')); WxDP <= (others => (others => '0')); MxDP <= (others => (others => '0')); elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge AxDP <= AxDN; BxDP <= BxDN; CxDP <= CxDN; WxDP <= WxDN; MxDP <= MxDN; end if; end process p_mem; end rtl;