---------------------------------------------------------------------------- -- Normal Basis Inversion (NB_inversion.vhd) -- -- Computes the inversion over normal basis in GF(2^m) -- The hardware is generated for a specific f. -- -- ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; package NB_parameters is -------------------------------------------------- -- tconst = t -------------------------------------------------- -- Constants for GF(2^4) with f(x) = x^4+x^3+1 constant M: integer := 4; constant V: integer := 2; -- V = M/2 constant tconst: integer := 3; -------------------------------------------------- -- Constants for GF(2^5) with f(x) = x^5+x^2+1 -- constant M: integer := 5; -- constant V: integer := 2; -- V = M/2 -- constant tconst: integer := 4; -------------------------------------------------- -- Constants for GF(2^13) with u = 23, t = 4, p = t*m + 1 = 53 -- constant M: integer := 13; -- constant V: integer := 6; -- V = (M-1)/2 -- constant tconst: integer := 4; -------------------------------------------------- -- Constants for GF(2^17) with u = 47, t = 6, p = t*m + 1 = 103 -- constant M: integer := 17; -- constant V: integer := 8; -- V = (M-1)/2 -- constant tconst: integer := 6; -------------------------------------------------- -- Constants for GF(2^19) with u = 7, t = 10, p = t*m + 1 = 191 -- constant M: integer := 19; -- constant V: integer := 9; -- V = (M-1)/2 -- constant tconst: integer := 10; -------------------------------------------------- -- Constants for GF(2^23) with u = 46, t = 2, p = t*m + 1 = 47 -- constant M: integer := 23; -- constant V: integer := 11; -- V = (M-1)/2 -- constant tconst: integer := 2; -------------------------------------------------- -- Constants for GF(2^29) with u = 58, t = 2, p = t*m + 1 = 59 -- constant M: integer := 29; -- constant V: integer := 14; -- V = (M-1)/2 -- constant tconst: integer := 2; -------------------------------------------------- -- Constants for GF(2^163) with u = 149, t = 4, p = t*m + 1 = 653 -- constant M: integer := 163; -- constant V: integer := 81; -- V = (M-1)/2 -- constant tconst: integer := 4; -------------------------------------------------- type h_array is array (1 to M/2) of integer; type w_aux is array (1 to tconst) of integer; type w_array is array (1 to M/2) of w_aux; type yij_array is array (0 to M-1) of std_logic_vector(1 to M/2); -------------------------------------------------- -- Values for GF(2^4) with f(x) = x^4+x^3+1 constant h: h_array := (3,2); constant w: w_array := ((0,1,3),(0,2,0)); -------------------------------------------------- -- Values for GF(2^5) with f(x) = x^5+x^2+1 -- constant h: h_array := (3,4); -- constant w: w_array := ((1,2,3,0),(0,1,2,4)); -------------------------------------------------- -- Values for GF(2^13) with u = 23, t = 4, p = t*m + 1 = 53 -- constant h: h_array := (4,4,4,4,4,2); -- constant w: w_array := ((0,3,4,5),(4,8,11,12),(1,7,8,12),(1,2,10,12),(1,7,8,10),(9,11,0,0)); -------------------------------------------------- -- Values for GF(2^17) with u = 47, t = 6, p = t*m + 1 = 103 -- constant h: h_array := (4,6,6,2,4,6,6,6); -- constant w: w_array := ((0,3,9,11,0,0),(6,7,8,9,12,16),(1,6,9,11,13,14),(7,15,0,0,0,0),(7,10,12,15,0,0),(2,3,7,9,14,15),(2,4,5,6,12,15),(2,9,10,11,14,16)); -------------------------------------------------- -- Values for GF(2^19) with u = 7, t = 10, p = t*m + 1 = 191 -- constant h: h_array := (10,4,4,8,6,8,6,6,6); -- constant w: w_array := ((0,2,4,6,7,11,12,13,15,18),(1,9,14,15,0,0,0,0,0,0),(11,13,15,18,0,0,0,0,0,0),(1,5,6,7,8,10,13,15,0,0),(4,7,10,11,14,18,0,0,0,0),(1,4,7,9,10,14,15,18,0,0),(1,4,5,6,8,17,0,0,0,0),(4,7,9,11,13,16,0,0,0,0),(2,6,8,13,14,15,0,0,0,0)); -------------------------------------------------- -- Values for GF(2^23) with u = 46, t = 2, p = t*m + 1 = 47 -- constant h: h_array := (2,2,2,2,2,2,2,2,2,2,2); -- constant w: w_array := ((0,19),(9,19),(12,15),(5,6),(4,13),(4,16),(13,21),(11,18),(2,20),(15,17),(8,14)); -------------------------------------------------- -- Values for GF(2^29) with u = 58, t = 2, p = t*m + 1 = 59 -- constant h: h_array := (2,2,2,2,2,2,2,2,2,2,2,2,2,2); -- constant w: w_array := ((0,21),(6,21),(13,18),(11,27),(17,20),(2,22),(13,25),(9,10),(8,14),(8,26),(4,14),(17,24),(3,7),(9,11)); -------------------------------------------------- -- Values for GF(2^163) with u = 149, t = 4, p = t*m + 1 = 653 -- constant h: h_array := (4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2); -- constant w: w_array := ((0,13,117,132),(92,111,117,145),(9,71,89,125),(40,87,99,137),(17,60,105,121),(22,134,136,160),(21,43,58,90),(33,61,124,139),(3,20,73,93),(35,63,77,137), -- (54,101,130,154),(110,131,158,162),(1,51,82,83),(54,101,111,156),(60,121,128,129),(37,59,64,157),(5,55,79,88),(20,93,96,136),(72,74,107,135),(9,18,89,140),(7,63,135,147), -- (6,45,61,68),(43,98,119,141),(32,109,115,126),(85,91,153,155),(30,36,84,133),(33,45,61,113),(47,49,57,76),(35,63,74,135),(26,56,86,122),(32,113,114,126),(24,31,44,123), -- (8,27,44,85),(49,93,134,136),(10,29,50,94),(26,101,156,159),(16,61,68,124),(41,79,146,150),(47,76,98,141),(4,72,107,149),(38,71,105,125),(47,57,97,142),(7,23,147,152), -- (32,33,67,113),(22,27,134,148),(47,48,97,141),(28,39,42,46),(46,72,135,147),(28,34,80,106),(35,77,81,94),(13,111,117,156),(54,66,103,130),(65,144,153,155),(11,14,52,78), -- (17,121,144,158),(30,75,96,133),(28,42,106,114),(7,63,99,137),(16,124,128,129),(5,15,112,138),(8,22,27,37),(73,76,98,146),(10,21,29,58),(16,68,122,154),(53,88,104,127), -- (52,08,112,138),(44,85,123,153),(22,37,64,160),(104,119,143,150),(79,88,104,150),(3,41,73,146),(19,40,48,97),(9,62,71,80),(19,29,77,94),(56,92,140,145),(28,39,62,80), -- (10,50,74,107),(54,103,111,145),(17,38,70,105),(49,73,76,93),(50,94,0,0)); -------------------------------------------------- end NB_parameters; ------------------------------------------------------------ -- NB_multiplier ------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.NB_parameters.all; entity NB_multiplier is port ( a, b: in std_logic_vector(M-1 downto 0); c: out std_logic_vector(M-1 downto 0) ); end NB_multiplier; architecture simple of NB_multiplier is signal t,c2: std_logic_vector(M-1 downto 0); begin P1: process(a,b) variable yij: yij_array; variable caux,r,t1: std_logic_vector(M-1 downto 0); variable s,te: integer; variable aux1: integer; begin for i in 0 to m-1 loop for j in 1 to v loop yij(i)(j) := (a(i) xor a((i+j) mod m)) and (b(i) xor b((i+j) mod m)); end loop; end loop; for i in 0 to m-1 loop caux(i) := a(i) and b(i); end loop; for j in 1 to v-1 loop for i in 0 to m-1 loop t1(i) := '0'; end loop; for k in 1 to h(j) loop for i in 0 to m-1 loop -- aux1 := (i - w(j)(k)) mod m; -- Computes aux1 mod m aux1 := i - w(j)(k); if aux1 <0 then aux1 := aux1 + m; elsif aux1 > m-1 then aux1 := aux1 rem m; end if; r(i) := yij(aux1)(j); end loop; for i in 0 to m-1 loop t1(i) := t1(i) xor r(i); end loop; end loop; for i in 0 to m-1 loop caux(i) := caux(i) xor t1(i); end loop; end loop; c2 <= caux; end process; P2: process(a,b) variable yij: yij_array; variable r,t2: std_logic_vector(M-1 downto 0); variable s,te: integer; variable aux2: integer; begin for i in 0 to m-1 loop t2(i) := '0'; end loop; if (m rem 2) /= 0 then s := h(v); te := m; else s := h(v)/2; te := m/2; end if; for i in 0 to te-1 loop yij(i)(v) := (a(i) xor a((v+i) mod m)) and (b(i) xor b((v+i) mod m)); end loop; if (m rem 2) = 0 then for i in 0 to (m/2)-1 loop yij(i+v)(v) := yij(i)(v); end loop; end if; for k in 1 to s loop for i in 0 to te-1 loop -- aux2 := (i - w(v)(k)) mod m; -- Computes aux2 mod m aux2 := i - w(v)(k); if aux2 <0 then aux2 := aux2 + m; elsif aux2 > m-1 then aux2 := aux2 rem m; end if; r(i) := yij(aux2)(v); end loop; if (m rem 2) = 0 then for i in 0 to (m/2)-1 loop r(i+m/2) := r(i); end loop; end if; for i in 0 to m-1 loop t2(i) := t2(i) xor r(i); end loop; end loop; t <= t2; end process; c <= c2 xor t; end simple; ------------------------------------------------------------ -- NB_inversion_datapath ------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.NB_parameters.all; entity NB_inversion_datapath is port ( a: in std_logic_vector(M-1 downto 0); clk, inic, shift_r, reset, ce_c: in std_logic; inv: out std_logic_vector(M-1 downto 0) ); end NB_inversion_datapath; architecture rtl of NB_inversion_datapath is component NB_multiplier is port ( a, b: in std_logic_vector(M-1 downto 0); c: out std_logic_vector(M-1 downto 0) ); end component; signal bb, cc, dd, inv_r: std_logic_vector(M-1 downto 0); begin multiplier: NB_multiplier port map (a => bb, b => cc, c => dd); sq_register: process(reset, clk) begin if reset = '1' then bb <= (others => '0'); elsif clk'event and clk = '1' then if inic = '1' then bb <= a; end if; if shift_r = '1' then bb <= bb(M-2 downto 0) & bb(M-1); end if; end if; end process sq_register; register_C: process(reset, inic, clk) begin if inic = '1' or reset = '1' then cc <= (others => '1'); elsif clk'event and clk = '1' then if ce_c = '1' then cc <= dd; else cc <= cc; end if; end if; end process register_C; inv <= dd; end rtl; ------------------------------------------------------------ -- NB_inversion ------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.NB_parameters.all; entity NB_inversion is port ( a: in std_logic_vector(M-1 downto 0); clk, reset, start: in std_logic; done: out std_logic; inv: out std_logic_vector(M-1 downto 0) ); end NB_inversion; architecture rtl of NB_inversion is component NB_inversion_datapath is port ( a: in std_logic_vector(M-1 downto 0); clk, inic, shift_r, reset, ce_c: in std_logic; inv: out std_logic_vector(M-1 downto 0) ); end component; signal inic, shift_r, ce_c: std_logic; signal count: natural range 0 to M; type states is range 0 to 4; signal current_state: states; begin data_path: NB_inversion_datapath port map (A => A, clk => clk, inic => inic, shift_r => shift_r, reset => reset, ce_c => ce_c, INV => INV); counter: process(reset, clk) begin if reset = '1' then count <= 0; elsif clk' event and clk = '1' then if inic = '1' then count <= 0; elsif shift_r = '1' then count <= count+1; end if; end if; end process counter; control_unit: process(clk, reset, current_state) begin case current_state is when 0 to 1 => inic <= '0'; shift_r <= '0'; done <= '1'; ce_c <= '0'; when 2 => inic <= '1'; shift_r <= '0'; done <= '0'; ce_c <= '0'; when 3 => inic <= '0'; shift_r <= '1'; done <= '0'; ce_c <= '0'; when 4 => inic <= '0'; shift_r <= '1'; done <= '0'; ce_c <= '1'; end case; if reset = '1' then current_state <= 0; elsif clk'event and clk = '1' then case current_state is when 0 => if start = '0' then current_state <= 1; end if; when 1 => if start = '1' then current_state <= 2; end if; when 2 => current_state <= 3; when 3 => current_state <= 4; when 4 => if count = M-2 then current_state <= 0; end if; end case; end if; end process control_unit; end rtl;