------------------------------------------------------------ -- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich -- http://www.iis.ee.ethz.ch/~sha3 ------------------------------------------------------------ ------------------------------------------------------------------------------- -- Title : SHA256Main -- Project : ------------------------------------------------------------------------------- -- File : SHA256Main.vhdl -- Author : Köppel Benedikt;Schnydrig Mathias -- Company : Integrated Systems Laboratory, ETH Zurich -- Created : 2010-10-28 -- Last update: 2011-09-08 -- Platform : ModelSim (simulation), Synopsys (synthesis) -- Standard : VHDL'87 ------------------------------------------------------------------------------- -- Description: SHA 256 Main Part which calculates the SHA 256 sum for one -- message of 512 bits ------------------------------------------------------------------------------- -- Copyright (c) 2010 Integrated Systems Laboratory, ETH Zurich ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2010-10-28 1.0 sem10h7 Created ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.shapkg.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; entity SHA256Main is port ( MessageInxDI : in expmess_arr; InWrEnxSI : in std_logic; HInxDI : in h_arr; CLKxCI : in std_logic; RSTxRBI : in std_logic; VALIDOUTxSO : out std_logic; HOutxDO : out h_arr; MessageReadyxSI : in std_logic; -- EnablexSI PenUltCyclexSO : out std_logic; MessageReceivedxSO : out std_logic -- bin am shaen ); end SHA256Main; architecture behave of SHA256Main is -- for the message signal ExpMessxDP : expmess_arr; signal ExpMessxDN : expmess_arr; -- for the FSM itself type state is (Idle, Read, Hash, Output); signal StatexDP : state; signal StatexDN : state; -- for FSMs counter signal KKCounterxDP : std_logic_vector(5 downto 0); -- count from 0 to 63 for KK signal KKCounterxDN : std_logic_vector(5 downto 0); -- to connect the MessageExpansion signal WKK15xD : std_logic_vector(31 downto 0); signal WKK2xD : std_logic_vector(31 downto 0); signal WKK16xD : std_logic_vector(31 downto 0); signal WKK7xD : std_logic_vector(31 downto 0); signal WKKnewxD : std_logic_vector(31 downto 0); component MessageExpansion port ( WKK15xDI : in std_logic_vector(31 downto 0); WKK2xDI : in std_logic_vector(31 downto 0); WKK16xDI : in std_logic_vector(31 downto 0); WKK7xDI : in std_logic_vector(31 downto 0); WKKxDO : out std_logic_vector(31 downto 0)); end component; -- to connect the MainLoop signal AtoHmainxD : h_arr; signal AtoHnewxD : h_arr; signal WKKmainxD : std_logic_vector(31 downto 0); signal KKKmainxD : std_logic_vector(31 downto 0); component MainLoop port ( KKKxDI : in std_logic_vector(31 downto 0); WKKxDI : in std_logic_vector(31 downto 0); AtoHxDI : in h_arr; AtoHxDO : out h_arr ); end component; -- to connect StoreAtoH signal AtoHxDN : h_arr; signal AtoHxDP : h_arr; -- Signals in Message Expansion signal S0xD : std_logic_vector(31 downto 0); signal S1xD : std_logic_vector(31 downto 0); signal WKKsum1xD : std_logic_vector(31 downto 0); signal WKKsum2xD : std_logic_vector(31 downto 0); begin ------------------------------------------------------------------------------- -- Message Expansion ------------------------------------------------------------------------------- S0xD <= ("000"&WKK15xD(31 downto 3)) xor (WKK15xD(17 downto 0)&WKK15xD(31 downto 18)) xor (WKK15xD(6 downto 0)&WKK15xD(31 downto 7)); S1xD <= ("0000000000"&WKK2xD(31 downto 10)) xor (WKK2xD(18 downto 0)&WKK2xD(31 downto 19)) xor (WKK2xD(16 downto 0)&WKK2xD(31 downto 17)); WKKsum1xD <= S0xD + S1xD; WKKsum2xD <= WKK16xD + WKK7xD; WKKnewxD <= WKKsum1xD + WKKsum2xD; ------------------------------------------------------------------------------- -- Main Loop ------------------------------------------------------------------------------- -- instance for MainLoop i_MainLoop : MainLoop port map ( KKKxDI => KKKmainxD, WKKxDI => WKKmainxD, AtoHxDI => AtoHmainxD, AtoHxDO => AtoHnewxD ); ------------------------------------------------------------------------------- -- StreAtoH ------------------------------------------------------------------------------- p_mem_AtoH : process (CLKxCI, RSTxRBI) begin -- process p_mem if RSTxRBI = '0' then -- asynchronous reset (active low) AtoHxDP <= (others => (others => '0')); elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge AtoHxDP <= AtoHxDN; end if; end process p_mem_AtoH; ------------------------------------------------------------------------------- -- update H ------------------------------------------------------------------------------- HOutxDO(0) <= AtoHxDP(0) + HInxDI(0); HOutxDO(1) <= AtoHxDP(1) + HInxDI(1); HOutxDO(2) <= AtoHxDP(2) + HInxDI(2); HOutxDO(3) <= AtoHxDP(3) + HInxDI(3); HOutxDO(4) <= AtoHxDP(4) + HInxDI(4); HOutxDO(5) <= AtoHxDP(5) + HInxDI(5); HOutxDO(6) <= AtoHxDP(6) + HInxDI(6); HOutxDO(7) <= AtoHxDP(7) + HInxDI(7); -- purpose: Store the expanded message p_mess_mem : process (CLKxCI, RSTxRBI) begin -- process p_mem if RSTxRBI = '0' then -- asynchronous reset (active low) ExpMessxDP <= (others => (others => '0')); elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge ExpMessxDP <= ExpMessxDN; end if; end process p_mess_mem; -- purpose: update KK counter p_kkcount_mem : process (CLKxCI, RSTxRBI) begin -- process p_kkcount_mem if RSTxRBI = '0' then -- asynchronous reset (active low) KKCounterxDP <= (others => '0'); elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge KKCounterxDP <= KKCounterxDN; end if; end process p_kkcount_mem; p_update_state_mem_test : process (CLKxCI, RSTxRBI) begin -- process p_update_state_mem_test if RSTxRBI = '0' then -- asynchronous reset (active low) StatexDP <= Idle; elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge StatexDP <= StatexDN; end if; end process p_update_state_mem_test; -- purpose: calculate next FSM state p_calculate_state_memless : process (AtoHnewxD, AtoHxDP, ExpMessxDP, HInxDI, InWrEnxSI, KKCounterxDP, MessageInxDI, MessageReadyxSI, StatexDP, WKKnewxD) begin -- process p_calculate_state_memless -- default values ExpMessxDN <= ExpMessxDP; StatexDN <= StatexDP; KKCounterxDN <= KKCounterxDP; WKK15xD <= (others => '0'); WKK2xD <= (others => '0'); WKK16xD <= (others => '0'); WKK7xD <= (others => '0'); WKKmainxD <= (others => '0'); KKKmainxD <= (others => '0'); AtoHxDN <= AtoHxDP; AtoHmainxD <= AtoHxDP; VALIDOUTxSO <= '0'; PenUltCyclexSO <= '0'; -- MessageReceivedxSO <= '0'; case StatexDP is when Idle => if InWrEnxSI = '1' then ExpMessxDN <= MessageInxDI; end if; -- we are waiting for the message to come MessageReceivedxSO <= '0'; -- if input message is ready, go to Read -- else, wait in Idle mode if MessageReadyxSI = '1' then StatexDN <= Read; else StatexDN <= Idle; end if; when Read => -- we are reading the message (i.e. not yet received) MessageReceivedxSO <= '0'; -- read in the message from MessageInxDI into the FF -- reset the KK counter -- go into hash state -- ExpMessxDN MessageInxDI; KKCounterxDN <= (others => '0'); StatexDN <= Hash; -- read in the start values AtoHxDN <= HInxDI; when Hash => -- the input message was received MessageReceivedxSO <= '1'; -- for the first 16 words, we don't need the expansion and do -- only HashMain -- for the 16th word, we already need to start with the expansion, -- because the expanded word will be needed in the next increment if KKCounterxDP < 15 then -- no expansion: ExpMessage remains constant ExpMessxDN <= ExpMessxDP; -- from 16 to 64 we need to expand the next message else -- bring WKK15, WKK2, WKK16, WKK7 to MessageExpansion and store -- the output of the message expansion into the FF -- The FF has only 16 words, we can wrap-around it and overwrite the -- old words (they're unused) -- do the wrap-around with the mod 16 calculation WKK15xD <= ExpMessxDP((to_integer(unsigned(KKCounterxDP))-15+1) mod 16); WKK2xD <= ExpMessxDP((to_integer(unsigned(KKCounterxDP))-2+1) mod 16); WKK16xD <= ExpMessxDP((to_integer(unsigned(KKCounterxDP))-16+1) mod 16); WKK7xD <= ExpMessxDP((to_integer(unsigned(KKCounterxDP))-7+1) mod 16); --WKKnewTempxDN WKKnewxD; -- in round kk, store the expanded -- message word, in kk+1 it will go to -- the expanded message, so that it is -- valid in round kk+2 --ExpMessxDN((to_integer(unsigned(KKCounterxDP))+1) mod 16) WKKnewTempxDP; ExpMessxDN((to_integer(unsigned(KKCounterxDP))+1) mod 16) <= WKKnewxD; end if; -- in all cases, we do the MainLoop WKKmainxD <= ExpMessxDP(to_integer(unsigned(KKCounterxDP)) mod 16); KKKmainxD <= K_INITIAL(to_integer(unsigned(KKCounterxDP))); -- in the first round, we read AtoH from the inputs HInxDI -- all following rounds, we need to continue with the previously -- calculated values -- if KKCounterxDP = 0 then -- init HInx when reading the message -- AtoHmainxD HInxDI; -- else -- AtoHmainxD AtoHxDP; -- end if; AtoHmainxD <= AtoHxDP; -- move the new A..H values to StoreAtoH AtoHxDN <= AtoHnewxD; -- after doing the main loop, we go back to Hash for the first 63 times -- when the last one is done, we go to Output if KKCounterxDP = 63 then StatexDN <= Output; else StatexDN <= Hash; end if; -- increase the KK counter KKCounterxDN <= KKCounterxDP + 1; when Output => PenUltCyclexSO <= '1'; -- calculate the actual output -- A..H and Harr are connected to UpdateH and get then to output pins if MessageReadyxSI = '1' then StatexDN <= Read; else StatexDN <= Idle; end if; VALIDOUTxSO <= '1'; when others => null; end case; end process p_calculate_state_memless; end behave;