------------------------------------------------------------
-- 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);
end component;
signal XOR1xS : 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);
-- ROUND
-----------------------------------------------------------------------------
p_round : process (StatexDP)
variable PLUS1, ROT7, SWAP8, XOR1, SWAP2 : halfstate;
variable PLUS2, ROT11, SWAP4, XOR2, SWAP1 : halfstate;
begin -- process p_round
for i in 0 to 15 loop
PLUS1(i) := std_logic_vector(unsigned(StatexDP(i)) + unsigned(StatexDP(i+16)));
end loop; -- i
for i in 0 to 15 loop
ROT7(i) := StatexDP(i)(31-7 downto 0) & StatexDP(i)(31 downto 32-7);
end loop; -- i
for i in 0 to 7 loop
SWAP8(i) := ROT7(i+8);
SWAP8(i+8) := ROT7(i);
end loop; -- i
for i in 0 to 15 loop
XOR1(i) := SWAP8(i) xor PLUS1(i);
end loop; -- i
for i in 0 to 1 loop
SWAP2(i) := PLUS1(i+2);
SWAP2(i+2) := PLUS1(i);
SWAP2(i+4) := PLUS1(i+6);
SWAP2(i+6) := PLUS1(i+4);
SWAP2(i+8) := PLUS1(i+10);
SWAP2(i+10) := PLUS1(i+8);
SWAP2(i+12) := PLUS1(i+14);
SWAP2(i+14) := PLUS1(i+12);
end loop; -- i
----------------------------
for i in 0 to 15 loop
PLUS2(i) := std_logic_vector(unsigned(XOR1(i)) + unsigned(SWAP2(i)));
end loop; -- i
for i in 0 to 15 loop
ROT11(i) := XOR1(i)(31-11 downto 0) & XOR1(i)(31 downto 32-11);
end loop; -- i
for i in 0 to 3 loop
SWAP4(i) := ROT11(i+4);
SWAP4(i+4) := ROT11(i);
SWAP4(i+8) := ROT11(i+12);
SWAP4(i+12) := ROT11(i+8);
end loop; -- i
for i in 0 to 15 loop
XOR2(i) := SWAP4(i) xor PLUS2(i);
end loop; -- i
for i in 0 to 7 loop
SWAP1(i*2) := PLUS2(i*2+1);
SWAP1(i*2+1) := PLUS2(i*2);
end loop; -- i
for i in 0 to 15 loop
OutRoundxD(i) <= XOR2(i);
OutRoundxD(i+16) <= SWAP1(i);
end loop; -- i
end process p_round;
-- Message XOR
-----------------------------------------------------------------------------
p_xorselect: process (DxDI, INENxEI, OutRoundxD, StartxSI, XOR1xS)
begin -- process p_xorselect
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
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
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;
-- Memory
-----------------------------------------------------------------------------
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;