------------------------------------------------------------
-- 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.keccakpkg.all;
entity keccak is
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
FinBlockxSI : in std_logic;
INENxEI : in std_logic;
OUTENxEO : out std_logic;
DxDI : in std_logic_vector(1087 downto 0);
DxDO : out std_logic_vector(HWIDTH-1 downto 0));
end keccak;
architecture rtl of keccak is
component controller
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
FinBlockxSI : in std_logic;
INENxEI : in std_logic;
OUTENxEO : out std_logic;
StateSelxSO : out std_logic;
RcntxDO : out unsigned(4 downto 0));
end component;
signal ThetaInxD, ThetaOutxD, PiInxD, PiOutxD, RhoInxD, RhoOutxD, ChiInxD, ChiOutxD,
IotaInxD , IotaOutxD, IotaOutTempxD, StateTempxD : state;
signal CxD: sheet;
signal DxD : sheet;
-- signal ZerosxD : std_logic_vector(63 downto 0) := (others=>'0');
signal DInxD : state;
signal StateSelxS : std_logic;
signal RcntxD : unsigned(4 downto 0);
signal StatexDP, StatexDN : state;
signal StateInxD : state;
begin
u_controller : controller
port map (
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
FinBlockxSI => FinBlockxSI,
INENxEI => INENxEI,
OUTENxEO => OUTENxEO,
StateSelxSO => StateSelxS,
RcntxDO => RcntxD);
din01: for y in 0 to 2 generate
din02: for x in 0 to 4 generate
DInxD(x,y) <= DxDI(((3-y)*5-x+2)*64-1 downto ((3-y)*5-x+1)*64);
end generate din02;
end generate din01;
DInxD(0,3) <= DxDI(127 downto 64);
DInxD(1,3) <= DxDI(63 downto 0);
DInxD(0,4) <= (others=>'0');
DInxD(1,4) <= (others=>'0');
din03: for y in 3 to 4 generate
din04: for x in 2 to 4 generate
DInxD(x,y) <= (others => '0');
end generate din04;
end generate din03;
-- Connections
-------------------------------------------------------------------------------
ThetaInxD <= StatexDP;
RhoInxD <= ThetaOutxD;
PiInxD <= RhoOutxD;
ChiInxD <= PiOutxD;
IotaInxD <= ChiOutxD;
-- Theta
-------------------------------------------------------------------------------
-- theta01: for x in 0 to 4 generate
-- CxD(x) ThetaInxD(x,0) xor ThetaInxD(x,1) xor ThetaInxD(x,2) xor
-- ThetaInxD(x,3) xor ThetaInxD(x,4);
-- DxD(x) CxD(x)(63-1 downto 0) & '0') xor (ZerosxD(62 downto 0) & CxD(x)(63));
-- end generate theta01;
CxD(0) <= ThetaInxD(0,0) xor ThetaInxD(0,1) xor ThetaInxD(0,2) xor ThetaInxD(0,3) xor ThetaInxD(0,4);
CxD(1) <= ThetaInxD(1,0) xor ThetaInxD(1,1) xor ThetaInxD(1,2) xor ThetaInxD(1,3) xor ThetaInxD(1,4);
CxD(2) <= ThetaInxD(2,0) xor ThetaInxD(2,1) xor ThetaInxD(2,2) xor ThetaInxD(2,3) xor ThetaInxD(2,4);
CxD(3) <= ThetaInxD(3,0) xor ThetaInxD(3,1) xor ThetaInxD(3,2) xor ThetaInxD(3,3) xor ThetaInxD(3,4);
CxD(4) <= ThetaInxD(4,0) xor ThetaInxD(4,1) xor ThetaInxD(4,2) xor ThetaInxD(4,3) xor ThetaInxD(4,4);
DxD(0) <= CxD(0)(63-1 downto 0) & CxD(0)(63);
DxD(1) <= CxD(1)(63-1 downto 0) & CxD(1)(63);
DxD(2) <= CxD(2)(63-1 downto 0) & CxD(2)(63);
DxD(3) <= CxD(3)(63-1 downto 0) & CxD(3)(63);
DxD(4) <= CxD(4)(63-1 downto 0) & CxD(4)(63);
-- theta02: for x in 0 to 4 generate
-- theta03: for y in 0 to 4 generate
-- ThetaOutxD(x,y) ThetaInxD(x,y) xor DxD((x+1) mod 5) xor CxD((x+4) mod 5);
-- end generate theta03;
-- end generate theta02;
theta00: for y in 0 to 4 generate
ThetaOutxD(0,y) <= ThetaInxD(0,y) xor DxD(1) xor CxD(4);
end generate theta00;
theta01: for y in 0 to 4 generate
ThetaOutxD(1,y) <= ThetaInxD(1,y) xor DxD(2) xor CxD(0);
end generate theta01;
theta02: for y in 0 to 4 generate
ThetaOutxD(2,y) <= ThetaInxD(2,y) xor DxD(3) xor CxD(1);
end generate theta02;
theta03: for y in 0 to 4 generate
ThetaOutxD(3,y) <= ThetaInxD(3,y) xor DxD(4) xor CxD(2);
end generate theta03;
theta04: for y in 0 to 4 generate
ThetaOutxD(4,y) <= ThetaInxD(4,y) xor DxD(0) xor CxD(3);
end generate theta04;
-- Rho
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
RhoOutxD(0,0) <= RhoInxD(0,0);
-- rho00: for y in 1 to 4 generate
-- RhoOutxD(0,y) RhoInxD(0,y)(63-RhoOffsets(5*y) downto 0) & ZerosxD(RhoOffsets(5*y)-1 downto 0)) xor
-- (ZerosxD((63-RhoOffsets(5*y)) downto 0) & RhoInxD(0,y)(63 downto (63-RhoOffsets(5*y)+1)));
-- end generate rho00;
rho00: for y in 1 to 4 generate
RhoOutxD(0,y) <= RhoInxD(0,y)(63-RHOOFFSETS(5*y) downto 0) & RhoInxD(0,y)(63 downto (63-RHOOFFSETS(5*y)+1));
end generate rho00;
-- rho01: for x in 1 to 4 generate
-- rho02: for y in 0 to 4 generate
-- RhoOutxD(x,y) RhoInxD(x,y)(63-RhoOffsets(x+5*y) downto 0) & ZerosxD(RhoOffsets(x+5*y)-1 downto 0)) xor
-- (ZerosxD((63-RhoOffsets(x+5*y)) downto 0) & RhoInxD(x,y)(63 downto (63-RhoOffsets(x+5*y)+1)));
-- end generate rho02;
-- end generate rho01;
rho01: for x in 1 to 4 generate
rho02: for y in 0 to 4 generate
RhoOutxD(x,y) <= RhoInxD(x,y)(63-RHOOFFSETS(x+5*y) downto 0) & RhoInxD(x,y)(63 downto (63-RHOOFFSETS(x+5*y)+1));
end generate rho02;
end generate rho01;
-- Pi
-------------------------------------------------------------------------------
-- pi01: for x in 0 to 4 generate
-- pi02: for y in 0 to 4 generate
-- PiOutxD(y, (2*x+3*y) mod 5) PiInxD(x,y);
-- end generate pi02;
-- end generate pi01;
PiOutxD(0, 0) <= PiInxD(0, 0);
PiOutxD(1, 3) <= PiInxD(0, 1);
PiOutxD(2, 1) <= PiInxD(0, 2);
PiOutxD(3, 4) <= PiInxD(0, 3);
PiOutxD(4, 2) <= PiInxD(0, 4);
PiOutxD(0, 2) <= PiInxD(1, 0);
PiOutxD(1, 0) <= PiInxD(1, 1);
PiOutxD(2, 3) <= PiInxD(1, 2);
PiOutxD(3, 1) <= PiInxD(1, 3);
PiOutxD(4, 4) <= PiInxD(1, 4);
PiOutxD(0, 4) <= PiInxD(2, 0);
PiOutxD(1, 2) <= PiInxD(2, 1);
PiOutxD(2, 0) <= PiInxD(2, 2);
PiOutxD(3, 3) <= PiInxD(2, 3);
PiOutxD(4, 1) <= PiInxD(2, 4);
PiOutxD(0, 1) <= PiInxD(3, 0);
PiOutxD(1, 4) <= PiInxD(3, 1);
PiOutxD(2, 2) <= PiInxD(3, 2);
PiOutxD(3, 0) <= PiInxD(3, 3);
PiOutxD(4, 3) <= PiInxD(3, 4);
PiOutxD(0, 3) <= PiInxD(4, 0);
PiOutxD(1, 1) <= PiInxD(4, 1);
PiOutxD(2, 4) <= PiInxD(4, 2);
PiOutxD(3, 2) <= PiInxD(4, 3);
PiOutxD(4, 0) <= PiInxD(4, 4);
-- Chi
-------------------------------------------------------------------------------
-- chi01: for y in 0 to 4 generate
-- chi02: for x in 0 to 4 generate
-- ChiOutxD(x,y) ChiInxD(x,y) xor (not(ChiInxD((x+1)mod 5,y)) and ChiInxD((x+2)mod 5,y));
-- end generate chi02;
-- end generate chi01;
chi00: for y in 0 to 4 generate
ChiOutxD(0,y) <= ChiInxD(0,y) xor (not(ChiInxD(1,y)) and ChiInxD(2,y));
end generate chi00;
chi01: for y in 0 to 4 generate
ChiOutxD(1,y) <= ChiInxD(1,y) xor (not(ChiInxD(2,y)) and ChiInxD(3,y));
end generate chi01;
chi02: for y in 0 to 4 generate
ChiOutxD(2,y) <= ChiInxD(2,y) xor (not(ChiInxD(3,y)) and ChiInxD(4,y));
end generate chi02;
chi03: for y in 0 to 4 generate
ChiOutxD(3,y) <= ChiInxD(3,y) xor (not(ChiInxD(4,y)) and ChiInxD(0,y));
end generate chi03;
chi04: for y in 0 to 4 generate
ChiOutxD(4,y) <= ChiInxD(4,y) xor (not(ChiInxD(0,y)) and ChiInxD(1,y));
end generate chi04;
-- Iota
-------------------------------------------------------------------------------
iota01: for x in 1 to 4 generate
iota02: for y in 0 to 4 generate
IotaOutTempxD(x,y) <= IotaInxD(x,y);
end generate iota02;
end generate iota01;
IotaOutTempxD(0,0) <= IotaInxD(0,0) xor ROUNDCONSTANCES(to_integer(RcntxD));
iota03: for y in 1 to 4 generate
IotaOutTempxD(0,y) <= IotaInxD(0,y);
end generate iota03;
-- Reverse after Iota
-----------------------------------------------------------------------------
rev01: for x in 0 to 4 generate
rev02: for y in 0 to 4 generate
rev03: for i in 0 to 7 generate
IotaOutxD(x,y)(8*(i+1)-1 downto 8*i) <= IotaOutTempxD(x,y)(8*(8-i)-1 downto 8*(8-i-1));
end generate rev03;
end generate rev02;
end generate rev01;
-- State select
-----------------------------------------------------------------------------
StateInxD <= (others => (others => (others => '0'))) when StateSelxS = '0' else IotaOutxD;
-- New State Input
-------------------------------------------------------------------------------
statedn: process (DInxD, INENxEI, StateInxD)
begin
for x in 0 to 4 loop
for y in 0 to 4 loop
if INENxEI = '1' then
StateTempxD(x,y) <= StateInxD(x,y) xor DInxD(x,y);
else
StateTempxD(x,y) <= StateInxD(x,y);
end if;
-- for i in 0 to 7 loop
-- StatexDN(x,y)(8*(i+1)-1 downto 8*i) StateTempxD(x,y)(8*(8-i)-1 downto 8*(8-i-1));
-- end loop; -- i
end loop; -- y
end loop; -- x
end process statedn;
statedn01: for x in 0 to 4 generate
statedn02: for y in 0 to 4 generate
statednrev01: for i in 0 to 7 generate
StatexDN(x,y)(8*(i+1)-1 downto 8*i) <= StateTempxD(x,y)(8*(8-i)-1 downto 8*(8-i-1));
end generate statednrev01;
end generate statedn02;
end generate statedn01;
-- Output Unform
-----------------------------------------------------------------------------
dout: for i in 0 to 3 generate
DxDO(HWIDTH-(i*64)-1 downto HWIDTH-(i+1)*64) <= IotaOutxD(i,0);
end generate dout;
-- Memory
-----------------------------------------------------------------------------
p_mem: process (ClkxCI, RstxRBI)
begin -- process p_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
StatexDP <= (others => (others => (others => '0')));
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
StatexDP <= StatexDN;
end if;
end process p_mem;
end rtl;