------------------------------------------------------------ -- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich -- http://www.iis.ee.ethz.ch/~sha3 ------------------------------------------------------------ ------------------------------------------------------------------------------- -- Title : Keccak -- Project : ------------------------------------------------------------------------------- -- File : keccak.vhd -- Author : Frank K. Guerkaynak -- Company : Integrated Systems Laboratory, ETH Zurich -- Created : 2011-08-10 -- Last update: 2011-08-24 -- Platform : ModelSim (simulation), Synopsys (synthesis) -- Standard : VHDL'87 ------------------------------------------------------------------------------- -- Description: Main Keccak block original by Pietro Gendotti and Luca Henzen ------------------------------------------------------------------------------- -- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2011-08-10 1.0 kgf Added the PenUltCyclexSO signal that comes from -- the controller -- 2011-08-19 1.1 kgf Adapted the interface signal names -- 2011-08-24 1.2 kgf Added the scan signals ------------------------------------------------------------------------------- library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; use work.keccakpkg.all; entity ethz_keccak is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; ScanInxTI : in std_logic; ScanOutxTO : out std_logic; ScanEnxTI : in std_logic; FinBlockxSI : in std_logic; InWrEnxSI : in std_logic; OutWrEnxSO : out std_logic; PenUltCyclexSO : out std_logic; -- The penultimate cycle of -- computations DxDI : in std_logic_vector(1087 downto 0); DxDO : out std_logic_vector(HWIDTH-1 downto 0)); end ethz_keccak; architecture rtl of ethz_keccak is component keccak_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; PenUltCyclexSO : 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 : keccak_controller port map ( ClkxCI => ClkxCI, RstxRBI => RstxRBI, FinBlockxSI => FinBlockxSI, INENxEI => InWrEnxSI, OUTENxEO => OutWrEnxSO, StateSelxSO => StateSelxS, PenUltCyclexSO => PenUltCyclexSO, 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, InWrEnxSI, StateInxD) begin for x in 0 to 4 loop for y in 0 to 4 loop if InWrEnxSI = '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;