------------------------------------------------------------ -- 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; entity jh is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; EnxEI : in std_logic; OutputEnxSO : out std_logic; MsgInxDI : in std_logic_vector(511 downto 0); HashOutxDO : out std_logic_vector(255 downto 0)); -- ScanEnxTI : in std_logic; -- ScanInxTI : in std_logic; -- ScanOutxTO : out std_logic); end jh; architecture rtl of jh is type HGroup is array (0 to 255) of std_logic_vector (3 downto 0); -- type definition of 4bit group elements type SBOX is array (0 to 15) of std_logic_vector (3 downto 0); type CR is array (0 to 35) of std_logic_vector(255 downto 0); component JFSM port ( ClkxCI : in std_logic; RstxRBI : in std_logic; EnxEI : in std_logic; CntxDO : out unsigned(7 downto 0); R36xSO : out std_logic; SavexSO : out std_logic; NewMsgxSO : out std_logic; OutputEnxSO : out std_logic); end component; signal NewMsgxS, R36xS, SavexS : std_logic; signal HxDP, HxDN : HGroup; signal MxDP, MxDN : std_logic_vector(511 downto 0); signal HDegroupedxD, HFinalxD, A : std_logic_vector(1023 downto 0); signal CntxD : unsigned(7 downto 0); signal Group1, Temp1, Temp2, Temp3, Temp4, Temp5, Temp6 : HGroup; signal C0, C1, C2, C3, D0, D1, D2, D3 : std_logic_vector(127 downto 0); -- constant S0 : SBOX := ("1001", "0000", "0100", "1011", "1101", "1100", "0011", "1111", "0001", "1010", "0010", "0110", "0111", "0101", "1000", "1110"); -- constant S1 : SBOX := ("0011", "1100", "0110", "1101", "0101", "0111", "0001", "1001", "1111", "0010", "0000", "0100", "1011", "1010", "1110", "1000"); constant constants : CR := (x"6a09e667f3bcc908b2fb1366ea957d3e3adec17512775099da2f590b0667322a", x"bb896bf05955abcd5281828d66e7d99ac4203494f89bf12817deb43288712231", x"1836e76b12d79c55118a1139d2417df52a2021225ff6350063d88e5f1f91631c", x"263085a7000fa9c3317c6ca8ab65f7a7713cf4201060ce886af855a90d6a4eed", x"1cebafd51a156aeb62a11fb3be2e14f60b7e48de85814270fd62e97614d7b441", x"e5564cb574f7e09c75e2e244929e9549279ab224a28e445d57185e7d7a09fdc1", x"5820f0f0d764cff3a5552a5e41a82b9eff6ee0aa615773bb07e8603424c3cf8a", x"b126fb741733c5bfcef6f43a62e8e5706a26656028aa897ec1ea4616ce8fd510", x"dbf0de32bca77254bb4f562581a3bc991cf94f225652c27f14eae958ae6aa616", x"e6113be617f45f3de53cff03919a94c32c927b093ac8f23b47f7189aadb9bc67", x"80d0d26052ca45d593ab5fb3102506390083afb5ffe107dacfcba7dbe601a12b", x"43af1c76126714dfa950c368787c81ae3beecf956c85c962086ae16e40ebb0b4", x"9aee8994d2d74a5cdb7b1ef294eed5c1520724dd8ed58c92d3f0e174b0c32045", x"0b2aa58ceb3bdb9e1eef66b376e0c565d5d8fe7bacb8da866f859ac521f3d571", x"7a1523ef3d970a3a9b0b4d610e02749d37b8d57c1885fe4206a7f338e8356866", x"2c2db8f7876685f2cd9a2e0ddb64c9d5bf13905371fc39e0fa86e1477234a297", x"9df085eb2544ebf62b50686a71e6e828dfed9dbe0b106c9452ceddff3d138990", x"e6e5c42cb2d460c9d6e4791a1681bb2e222e54558eb78d5244e217d1bfcf5058", x"8f1f57e44e126210f00763ff57da208a5093b8ff7947534a4c260a17642f72b2", x"ae4ef4792ea148608cf116cb2bff66e8fc74811266cd641112cd17801ed38b59", x"91a744efbf68b192d0549b608bdb3191fc12a0e83543cec5f882250b244f78e4", x"4b5d27d3368f9c17d4b2a2b216c7e74e7714d2cc03e1e44588cd9936de74357c", x"0ea17cafb8286131bda9e3757b3610aa3f77a6d0575053fc926eea7e237df289", x"848af9f57eb1a616e2c342c8cea528b8a95a5d16d9d87be9bb3784d0c351c32b", x"c0435cc3654fb85dd9335ba91ac3dbde1f85d567d7ad16f9de6e009bca3f95b5", x"927547fe5e5e45e2fe99f1651ea1cbf097dc3a3d40ddd21cee260543c288ec6b", x"c117a3770d3a34469d50dfa7db020300d306a365374fa828c8b780ee1b9d7a34", x"8ff2178ae2dbe5e872fac789a34bc228debf54a882743caad14f3a550fdbe68f", x"abd06c52ed58ff091205d0f627574c8cbc1fe7cf79210f5a2286f6e23a27efa0", x"631f4acb8d3ca4253e301849f157571d3211b6c1045347befb7c77df3c6ca7bd", x"ae88f2342c23344590be2014fab4f179fd4bf7c90db14fa4018fcce689d2127b", x"93b89385546d71379fe41c39bc602e8b7c8b2f78ee914d1f0af0d437a189a8a4", x"1d1e036abeef3f44848cd76ef6baa889fcec56cd7967eb909a464bfc23c72435", x"a8e4ede4c5fe5e88d4fb192e0a0821e935ba145bbfc59c2508282755a5df53a5", x"8e4e37a3b970f079ae9d22a499a714c875760273f74a9398995d32c05027d810", x"61cfa42792f93b9fde36eb163e978709fafa7616ec3c7dad0135806c3d91a21b"); -- constant IV : Hgroup := ("1001", "0000", "1100", "1110", "0100", "1100", "0111", "0001", "1101", "0010", "0011", "0011", "0101", "0101", "1101", "1000", "0000", "0010", "1001", "1011", "1110", "0101", "0011", "0001", "1110", "0010", "0011", "1010", "0011", "0010", "0101", "1000", "1110", "1101", "0001", "0001", "1001", "1111", "1101", "1111", "1010", "0101", "0010", "1100", "0001", "1111", "0100", "1000", "1110", "1100", "1101", "1100", "1011", "0001", "0011", "1011", "0011", "1111", "0000", "0011", "1010", "0111", "0101", "1000", "1100", "0100", "1011", "0001", "0110", "0000", "0101", "0101", "0111", "0001", "1011", "1011", "0001", "1011", "1111", "0011", "0001", "0001", "0001", "1010", "1010", "1000", "1111", "1111", "1100", "0110", "0000", "0010", "1000", "0100", "0111", "1110", "0000", "0010", "1000", "0111", "0110", "0011", "1010", "1101", "1100", "1101", "0001", "1111", "0000", "1001", "1110", "1111", "0101", "0100", "1100", "1100", "1101", "1000", "0000", "1111", "1000", "1100", "1011", "0101", "1100", "1101", "0001", "0101", "0111", "0101", "1101", "0101", "0011", "1001", "0011", "0110", "0000", "1010", "0100", "1000", "1000", "1111", "0000", "1110", "0011", "1111", "1010", "1000", "1111", "0110", "1001", "0100", "1101", "0011", "1010", "1001", "1110", "1101", "0110", "1001", "0001", "0001", "1100", "1001", "0001", "1000", "0001", "0000", "0100", "0000", "1101", "0100", "0001", "0000", "1000", "1100", "1100", "0010", "1110", "1111", "1101", "1111", "0011", "1000", "1000", "1010", "1011", "0011", "1000", "0100", "1100", "0100", "0110", "0111", "0000", "0011", "0001", "0011", "1010", "0000", "1100", "0100", "1101", "1101", "0000", "1111", "1001", "0001", "0101", "1100", "1111", "0001", "1001", "1101", "1011", "0000", "1000", "1001", "0101", "0100", "1010", "0110", "0101", "1101", "1101", "0101", "1010", "0010", "1111", "1101", "0011", "0010", "0000", "0101", "1000", "0101", "1111", "1000", "0000", "0010", "1100", "0001", "1110", "0110", "1011", "0010", "0111", "0111", "0001", "0110", "1100", "0100", "0100", "0100", "1010", "1100"); constant IV : std_logic_vector(1023 downto 0) := "1100100101101000101110001110001011000101001110100101100101101110010000100111111001000101111011110001110101111010111001101110010101100001010001011011011111011001000001100111000100011111011110100010111111000111011000010111100000000110101010010010001000000001011110110010100110010001110000011011100100011001001010011110001011000100001010110100110011100001100011001100010110100010110101100110001000100000101111101100101010010000000110110101110111011111110100111011001000000101011000111000111010100111101011000101111100010100001111101000110010111010011011010011000100110001000001001011000011100111000000000101010010010000010100100111001001110001010011001100111000110010000111100000011101011101111001010001000000011011101010000000000011101100111000100000001001010001011110001001111101010111011100100111100101011111110100010000010010100101111100001011100010110110001101000010010111110101101100100011100000010110011100001111101000111110010111111001000001111111000101111110001010001111110000000110010011100111011010011010110010010000"; begin -- rtl controller : JFSM port map ( ClkxCI => ClkxCI, RstxRBI => RstxRBI, EnxEI => EnxEI, CntxDO => CntxD, R36xSO => R36xS, SavexSO => SavexS, NewMsgxSO => NewMsgxS, OutputEnxSO => OutputEnxSO); -- INITIALIZATION ----------------------------------------------------------------------------- MxDN <= MsgInxDI when EnxEI = '1' else MxDP; HxorM : for i in 0 to 511 generate A(512+i) <= IV(512+i) xor MsgInxDI(i) when NewMsgxS = '1' else HFinalxD(512+i) xor MsgInxDI(i); A(i) <= IV(i) when NewMsgxS = '1' else HFinalxD(i); HFinalxD(512+i) <= HDegroupedxD(512+i); HFinalxD(i) <= HDegroupedxD(i) xor MxDP(i); end generate HxorM; -- GROUP ----------------------------------------------------------------------------- grouping : for i in 0 to 127 generate Group1(2*i) <= (A(1023-i), A(767-i), A(511-i), A(255-i)); Group1(2*i+1) <= (A(895-i), A(639-i), A(383-i), A(127-i)); end generate grouping; -- Round8 -------------------------------------------------------------------------------- Temp1 <= Group1 when EnxEI = '1' else HxDP; sub : for i in 0 to 255 generate -- Sub 4bits with SBOX SO or S1 -- (depending on constant vector) i) = '0' else '1' xor Temp1(i)(0) xor Temp1(i)(1) xor (Temp1(i)(0) and Temp1(i)(2)) xor (Temp1(i)(1) and Temp1(i)(2)) xor (Temp1(i)(0) and Temp1(i)(1) and Temp1(i)(3)) xor(Temp1(i)(0) and Temp1(i)(2) and Temp1(i)(3)) xor (Temp1(i)(1) and Temp1(i)(2) and Temp1(i)(3)); --SBOX i) = '0' else '1' xor Temp1(i)(0) xor Temp1(i)(2) xor (Temp1(i)(0) and Temp1(i)(3)) xor (Temp1(i)(1) and Temp1(i)(3)) xor (Temp1(i)(2) and Temp1(i)(3)) xor(Temp1(i)(0) and Temp1(i)(1) and Temp1(i)(2)) xor (Temp1(i)(1) and Temp1(i)(2) and Temp1(i)(3)); --SBOX i) = '0' else Temp1(i)(0) xor Temp1(i)(1) xor Temp1(i)(2) xor Temp1(i)(3) xor (Temp1(i)(0) and Temp1(i)(1)) xor (Temp1(i)(0) and Temp1(i)(2)) xor(Temp1(i)(0) and Temp1(i)(1) and Temp1(i)(2)) xor (Temp1(i)(0) and Temp1(i)(1) and Temp1(i)(3)); --SBOX i) = '0' else Temp1(i)(0) xor Temp1(i)(3) xor (Temp1(i)(0) and Temp1(i)(2)) xor (Temp1(i)(1) and Temp1(i)(3)) xor (Temp1(i)(0) and Temp1(i)(1) and Temp1(i)(2)) xor(Temp1(i)(0) and Temp1(i)(1) and Temp1(i)(3)) xor (Temp1(i)(1) and Temp1(i)(2) and Temp1(i)(3)); --SBOX end generate sub; L : for i in 0 to 127 generate --Linear Transformation D0(i) <= Temp2(2*i+1)(3) xor Temp2(2*i)(2); D1(i) <= Temp2(2*i+1)(2) xor Temp2(2*i)(1); D2(i) <= Temp2(2*i+1)(1) xor Temp2(2*i)(0) xor Temp2(2*i)(3); D3(i) <= Temp2(2*i+1)(0) xor Temp2(2*i)(3); C0(i) <= Temp2(2*i)(3) xor D1(i); C1(i) <= Temp2(2*i)(2) xor D2(i); C2(i) <= Temp2(2*i)(1) xor D3(i) xor D0(i); C3(i) <= Temp2(2*i)(0) xor D0(i); Temp3(2*i) <= (C0(i) , C1(i) , C2(i) , C3(i)); Temp3(2*i+1) <= (D0(i) , D1(i) , D2(i) , D3(i)); end generate L; pi : for i in 0 to 63 generate -- Permutation P8 Temp4(4*i) <= Temp3(4*i); Temp4(4*i+1) <= Temp3(4*i+1); Temp4(4*i+2) <= Temp3(4*i+3); Temp4(4*i+3) <= Temp3(4*i+2); end generate pi; pprime : for i in 0 to 127 generate Temp5(i) <= Temp4(2*i); Temp5(i+128) <= Temp4(2*i+1); Temp6(i) <= Temp5(i); end generate pprime; phi : for i in 64 to 127 generate Temp6(2*i) <= Temp5(2*i+1); Temp6(2*i+1) <= Temp5(2*i); end generate phi; --SAVE STATE ----------------------------------------------------------------------------- HxDN <= Temp6 when R36xS = '0' and SavexS = '0' else Temp2 when R36xS = '1' else HxDP; --DEGROUP ----------------------------------------------------------------------------- degroupelement : for j in 0 to 3 generate degroup : for i in 0 to 127 generate HDegroupedxD(1023-256*j-i) <= HxDP(2*i)(3-j); HDegroupedxD(895-256*j-i) <= HxDP(2*i+1)(3-j); end generate degroup; end generate degroupelement; --Output ----------------------------------------------------------------------------- HashOutxDO <= HFinalxD(255 downto 0); -- Memory ----------------------------------------------------------------------------- p_mem : process (ClkxCI, RstxRBI) begin -- process p_mem if RstxRBI = '0' then -- asynchronous reset (active low) MxDP <= (others => '0'); HxDP <= (others => (others => '0')); elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge MxDP <= MxDN; HxDP <= HxDN; end if; end process p_mem; end rtl;