------------------------------------------------------------
-- 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;
use work.cubepkg.all;
entity cubehash is
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
StartxSI : in std_logic;
INENxEI : in std_logic;
OUTENxEO : out std_logic;
DxDI : in std_logic_vector(255 downto 0);
DxDO : out std_logic_vector(HWIDTH-1 downto 0));
end cubehash;
architecture rtl of cubehash is
component controller
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
StartxSI : in std_logic;
INENxEI : in std_logic;
OUTENxEO : out std_logic;
XOR1xSO : out std_logic;
SwitchxSO : out std_logic);
end component;
signal XOR1xS, SwitchxS : std_logic;
signal StatexDP, StatexDN : cubestate;
signal OutRoundxD : cubestate;
begin -- rtl
u_controller : controller
port map (
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
StartxSI => StartxSI,
INENxEI => INENxEI,
OUTENxEO => OUTENxEO,
XOR1xSO => XOR1xS,
SwitchxSO => SwitchxS);
-- ROUND
-----------------------------------------------------------------------------
p_round : process (StatexDP, SwitchxS)
variable PLUS, ROT, SWAP1, XOR1, SWAP2 : halfstate;
begin -- process p_round
-- Addition
for i in 0 to 15 loop
PLUS(i) := std_logic_vector(unsigned(StatexDP(i)) + unsigned(StatexDP(i+16)));
end loop; -- i
-- Rot7/11, Swap8/4
if SwitchxS = '0' then
for i in 0 to 15 loop
ROT(i) := StatexDP(i)(31-7 downto 0) & StatexDP(i)(31 downto 32-7);
end loop; -- i
for i in 0 to 7 loop
SWAP1(i) := ROT(i+8);
SWAP1(i+8) := ROT(i);
end loop; -- i
else
for i in 0 to 15 loop
ROT(i) := StatexDP(i)(31-11 downto 0) & StatexDP(i)(31 downto 32-11);
end loop; -- i
for i in 0 to 3 loop
SWAP1(i) := ROT(i+4);
SWAP1(i+4) := ROT(i);
SWAP1(i+8) := ROT(i+12);
SWAP1(i+12) := ROT(i+8);
end loop; -- i
end if;
-- XOR
for i in 0 to 15 loop
XOR1(i) := SWAP1(i) xor PLUS(i);
end loop; -- i
-- SWAP2/1
if SwitchxS = '0' then
for i in 0 to 1 loop
SWAP2(i) := PLUS(i+2);
SWAP2(i+2) := PLUS(i);
SWAP2(i+4) := PLUS(i+6);
SWAP2(i+6) := PLUS(i+4);
SWAP2(i+8) := PLUS(i+10);
SWAP2(i+10) := PLUS(i+8);
SWAP2(i+12) := PLUS(i+14);
SWAP2(i+14) := PLUS(i+12);
end loop; -- i
else
for i in 0 to 7 loop
SWAP2(i*2) := PLUS(i*2+1);
SWAP2(i*2+1) := PLUS(i*2);
end loop; -- i
end if;
----------------------------
for i in 0 to 15 loop
OutRoundxD(i) <= XOR1(i);
OutRoundxD(i+16) <= SWAP2(i);
end loop; -- i
end process p_round;
-- Message XOR
-----------------------------------------------------------------------------
p_xorselect: process (DxDI, INENxEI, OutRoundxD, StartxSI, XOR1xS)
begin -- process p_xorselect
-- Initialization
if StartxSI = '1' and INENxEI = '1' then
StatexDN <= INITSTATE;
for i in 0 to 7 loop
StatexDN(i) <= INITSTATE(i) xor DxDI(256-32*(i)-1 downto 256-32*(i+1));
end loop; -- i
-- Additional Block
elsif StartxSI = '0' and INENxEI = '1' then
StatexDN <= OutRoundxD;
for i in 0 to 7 loop
StatexDN(i) <= OutRoundxD(i) xor DxDI(256-32*(i)-1 downto 256-32*(i+1));
end loop; -- i
else
-- Last XOR '1'
if XOR1xS = '1' then
StatexDN <= OutRoundxD;
StatexDN(31)(0) <= OutRoundxD(31)(0) xor '1';
else
StatexDN <= OutRoundxD;
end if;
end if;
end process p_xorselect;
-- Output Unform
-----------------------------------------------------------------------------
p_outext: for i in 0 to HWIDTH/32-1 generate
p_outint: for j in 0 to 3 generate
DxDO((HWIDTH/32-i)*32-j*8-1 downto (HWIDTH/32-i)*32-(j+1)*8) <= OutRoundxD(i)(8*(j+1)-1 downto 8*j);
end generate p_outint;
end generate p_outext;
-- Memroy
-----------------------------------------------------------------------------
p_mem: process (ClkxCI, RstxRBI)
begin -- process p_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
StatexDP <= (others => (others => '0'));
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
StatexDP <= StatexDN;
end if;
end process p_mem;
end rtl;