library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; package Montgomery_projective_parameters is constant M: integer := 163; constant logM: integer := 9;--logM is the number of bits of m plus an additional sign bit --constant F: std_logic_vector(M downto 0):= "100011011"; --for M=8 bits --constant F: std_logic_vector(M downto 0):= '1'& x"001B"; --for M=16 bits --constant F: std_logic_vector(M downto 0):= '1'& x"0101001B"; --for M=32 bits --constant F: std_logic_vector(M downto 0):= '1'& x"010100000101001B"; --for M=64 bits --constant F: std_logic_vector(M downto 0):= '1'& x"0000000000000000010100000101001B"; --for M=128 bits constant F: std_logic_vector(M downto 0):= x"800000000000000000000000000000000000000C9"; --for M=163 --constant F: std_logic_vector(M downto 0):= (0=> '1', 74 => '1', 233 => '1',others => '0'); --for M=233 end Montgomery_projective_parameters; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.Montgomery_projective_parameters.all; entity Montgomery_projective_data_path is port( xP, yP: in std_logic_vector(M-1 downto 0); clk, reset, start_mult, start_div,load, en_XA, en_XB, en_ZA, en_ZB, en_T1, en_T2: in std_logic; sel_a: in std_logic_vector(2 downto 0); sel_b, sel_c, sel_div, sel_square, sel_XA, sel_XB, sel_ZA: in std_logic_vector(1 downto 0); xQ, yQ: out std_logic_vector(M-1 downto 0); mult_done, div_done, infinity: out std_logic ); end Montgomery_projective_data_path; architecture circuit of Montgomery_projective_data_path is component binary_algorithm_polynomials is port( g, h: in std_logic_vector(M-1 downto 0); clk, reset, start: in std_logic; z: out std_logic_vector(M-1 downto 0); done: out std_logic ); end component; component classic_squarer is port ( a: in std_logic_vector(M-1 downto 0); c: out std_logic_vector(M-1 downto 0) ); end component; component interleaved_mult is port ( A, B: in std_logic_vector (M-1 downto 0); clk, reset, start: in std_logic; Z: out std_logic_vector (M-1 downto 0); done: out std_logic ); end component; signal XA, XB, ZA, ZB, T1, T2, next_XA, next_XB, next_ZA, square1, square2, square3, a, b, c, product, mult_out, num, den, div_out, s1, s2, s3, s4, XAxorxP, XBxorxP, xPxoryP: std_logic_vector (M-1 downto 0); constant zero: std_logic_vector(M-1 downto 0) := (others => '0'); constant one: std_logic_vector(M-1 downto 0) := conv_std_logic_vector(1, M); begin xor_gates1: for i in 0 to M-1 generate XAxorxP(i) <= XA(i) XOR xP(i); end generate; with sel_a select a <= XA when "000", XB when "001", xP when "010", T1 when "011", XAxorxP when others; xor_gates2: for i in 0 to M-1 generate XBxorxP(i) <= XB(i) XOR xP(i); end generate; with sel_b select b <= ZB when "00", ZA when "01", T2 when "10", XBxorxP when others; with sel_c select c <= XB when "00", XA when "01", square3 when "10", zero when others; a_mod_f_multiplier: interleaved_mult port map ( A => a, B => b, clk => clk, reset => reset, start => start_mult, Z => product, done => mult_done ); xor_gates7: for i in 0 to M-1 generate mult_out(i) <= product(i) XOR c(i); end generate; with sel_div select num <= XA when "00", XB when "01", ZA when others; with sel_div select den <= ZA when "00", ZB when "01", xP when others; a_mod_f_divider: binary_algorithm_polynomials port map( g => num, h => den, clk => clk, reset => reset, start => start_div, z => div_out, done => div_done ); with sel_square select s1 <= XA when "00", XB when "01", T1 when others; with sel_square select s2 <= ZA when "00", ZB when "01", T2 when "10", zero when others; xor_gates3: for i in 0 to M-1 generate s3(i) <= s1(i) XOR s2(i); end generate; a_squarer: classic_squarer port map ( a => s3, c => square2 ); a_second_squarer: classic_squarer port map ( a => square2, c => square1 ); a_third_squarer: classic_squarer port map ( a => xP, c => s4 ); xor_gates4: for i in 0 to M-1 generate square3(i) <= s4(i) XOR yP(i); end generate; with sel_XA select next_XA <= square1 when "00", mult_out when "01", xP when "10", div_out when others; register_XA: process(clk) begin if clk'event and clk = '1' then if load = '1' then XA <= one; elsif en_XA = '1' then XA <= next_XA; end if; end if; end process; with sel_XB select next_XB <= mult_out when "00", square1 when "01", div_out when others; register_XB: process(clk) begin if clk'event and clk = '1' then if load = '1' then XB <= xP; elsif en_XB = '1' then XB <= next_XB; end if; end if; end process; xor_gates5: for i in 0 to M-1 generate xPxoryP(i) <= xP(i) XOR yP(i); end generate; with sel_ZA select next_ZA <= square2 when "00", xPxoryP when "01", mult_out when "10", div_out when others; register_ZA: process(clk) begin if clk'event and clk = '1' then if load = '1' then ZA <= zero; elsif en_ZA = '1' then ZA <= next_ZA; end if; end if; end process; register_ZB: process(clk) begin if clk'event and clk = '1' then if load = '1' then ZB <= one; elsif en_ZB = '1' then ZB <= square2; end if; end if; end process; infinity <= '1' when ZB = zero else '0'; register_T1: process(clk) begin if clk'event and clk = '1' then if en_T1 = '1' then T1 <= mult_out; end if; end if; end process; register_T2: process(clk) begin if clk'event and clk = '1' then if en_T2 = '1' then T2 <= mult_out; end if; end if; end process; xQ <= XA; xor_gates6: for i in 0 to M-1 generate yQ(i) <= ZA(i) XOR yP(i); end generate; end circuit;