URL
https://opencores.org/ocsvn/rsa_512/rsa_512/trunk
Subversion Repositories rsa_512
Compare Revisions
- This comparison shows the changes necessary to convert path
/rsa_512
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/trunk/bench/test_512.vhd
0,0 → 1,442
-------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 17:40:28 12/13/2009 |
-- Design Name: |
-- Module Name: |
-- Project Name: ciosspartan |
-- Target Device: |
-- Tool versions: |
-- Description: |
-- |
-- VHDL Test Bench Created by ISE for module: rsa_top |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
-- Notes: |
-- This testbench has been automatically generated using types std_logic and |
-- std_logic_vector for the ports of the unit under test. Xilinx recommends |
-- that these types always be used for the top-level I/O of a design in order |
-- to guarantee that the testbench will bind correctly to the post-implementation |
-- simulation model. |
-------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.numeric_std.all; |
|
entity test_rsa_512 is |
end test_rsa_512; |
|
architecture behavior of test_rsa_512 is |
|
-- Component Declaration for the Unit Under Test (UUT) |
|
component rsa_top |
port( |
clk : in std_logic; |
reset : in std_logic; |
valid_in : in std_logic; |
x : in std_logic_vector(15 downto 0); |
y : in std_logic_vector(15 downto 0); |
m : in std_logic_vector(15 downto 0); |
r_c : in std_logic_vector(15 downto 0); |
n_c : in std_logic_vector(15 downto 0); |
s : out std_logic_vector(15 downto 0); |
valid_out : out std_logic; |
bit_size : in std_logic_vector(15 downto 0) |
); |
end component; |
|
|
--Inputs |
signal clk : std_logic := '0'; |
signal reset : std_logic := '0'; |
signal valid_in : std_logic := '0'; |
signal x : std_logic_vector(15 downto 0) := (others => '0'); |
signal y : std_logic_vector(15 downto 0) := (others => '0'); |
signal m : std_logic_vector(15 downto 0) := (others => '0'); |
signal r_c : std_logic_vector(15 downto 0) := (others => '0'); |
signal n_c : std_logic_vector(15 downto 0) := (others => '0'); |
signal bit_size : std_logic_vector(15 downto 0) := x"0200"; |
--Outputs |
signal s : std_logic_vector(15 downto 0); |
signal valid_out : std_logic; |
|
-- Clock period definitions |
constant clk_period : time := 1ns; |
|
begin |
|
-- Instantiate the Unit Under Test (UUT) |
uut : rsa_top port map ( |
clk => clk, |
reset => reset, |
valid_in => valid_in, |
x => x, |
y => y, |
m => m, |
r_c => r_c, |
n_c => n_c, |
s => s, |
valid_out => valid_out, |
bit_size => bit_size |
); |
|
-- Clock process definitions |
clk_process : process |
begin |
clk <= '0'; |
wait for clk_period/2; |
clk <= '1'; |
wait for clk_period/2; |
end process; |
|
|
-- Stimulus process |
stim_proc : process |
begin |
valid_in <= '0'; |
-- hold reset state for 100ms. |
reset <= '1'; |
wait for 10ns; |
reset <= '0'; |
wait for clk_period*10; |
|
-- insert stimulus here |
|
--n_c and valid signal and the r_c constant are also required |
n_c <= x"738f"; |
valid_in <= '1'; |
x <= x"f3ad"; |
y <= x"42b1"; |
m <= x"b491"; |
r_c <= x"f579"; |
wait for clk_period; |
x <= x"8e40"; |
y <= x"1ad3"; |
m <= x"1417"; |
r_c <= x"6ee9"; |
wait for clk_period; |
x <= x"6af9"; |
y <= x"a827"; |
m <= x"b498"; |
r_c <= x"972d"; |
wait for clk_period; |
x <= x"4e63"; |
y <= x"0d64"; |
m <= x"e1b7"; |
r_c <= x"5052"; |
wait for clk_period; |
x <= x"9600"; |
y <= x"3f76"; |
m <= x"e47c"; |
r_c <= x"1dca"; |
wait for clk_period; |
x <= x"68f4"; |
y <= x"6670"; |
m <= x"b186"; |
r_c <= x"bc81"; |
wait for clk_period; |
x <= x"5a12"; |
y <= x"5a1c"; |
m <= x"93f0"; |
r_c <= x"377e"; |
wait for clk_period; |
x <= x"d62e"; |
y <= x"4844"; |
m <= x"b183"; |
r_c <= x"04ef"; |
wait for clk_period; |
x <= x"8fc1"; |
y <= x"d5f2"; |
m <= x"f8f1"; |
r_c <= x"3a2a"; |
wait for clk_period; |
x <= x"031d"; |
y <= x"b65a"; |
m <= x"eed1"; |
r_c <= x"291b"; |
wait for clk_period; |
x <= x"f496"; |
y <= x"034f"; |
m <= x"0083"; |
r_c <= x"c159"; |
wait for clk_period; |
x <= x"1268"; |
y <= x"9635"; |
m <= x"981c"; |
r_c <= x"9336"; |
wait for clk_period; |
x <= x"2e5a"; |
y <= x"386e"; |
m <= x"6441"; |
r_c <= x"1bd0"; |
wait for clk_period; |
x <= x"c1d6"; |
y <= x"fb73"; |
m <= x"fcd8"; |
r_c <= x"317d"; |
wait for clk_period; |
x <= x"cd8f"; |
y <= x"5623"; |
m <= x"cbf0"; |
r_c <= x"64b4"; |
wait for clk_period; |
x <= x"e4d2"; |
y <= x"9041"; |
m <= x"e3ca"; |
r_c <= x"8793"; |
wait for clk_period; |
x <= x"36c6"; |
y <= x"99da"; |
m <= x"41d9"; |
r_c <= x"85f5"; |
wait for clk_period; |
x <= x"df4a"; |
y <= x"cd68"; |
m <= x"b7a0"; |
r_c <= x"7c8d"; |
wait for clk_period; |
x <= x"8e40"; |
y <= x"9a94"; |
m <= x"146e"; |
r_c <= x"64d9"; |
wait for clk_period; |
x <= x"6af9"; |
y <= x"ccc8"; |
m <= x"4776"; |
r_c <= x"c7f6"; |
wait for clk_period; |
x <= x"4e63"; |
y <= x"ed49"; |
m <= x"ec50"; |
r_c <= x"fba0"; |
wait for clk_period; |
x <= x"9600"; |
y <= x"4d25"; |
m <= x"c07c"; |
r_c <= x"e3e0"; |
wait for clk_period; |
x <= x"68f4"; |
y <= x"3b8e"; |
m <= x"e698"; |
r_c <= x"b567"; |
wait for clk_period; |
x <= x"5a12"; |
y <= x"36d5"; |
m <= x"d85f"; |
r_c <= x"3172"; |
wait for clk_period; |
x <= x"d62e"; |
y <= x"3a75"; |
m <= x"729c"; |
r_c <= x"111a"; |
wait for clk_period; |
x <= x"8fc1"; |
y <= x"77a3"; |
m <= x"19b6"; |
r_c <= x"1971"; |
wait for clk_period; |
x <= x"d2cd"; |
y <= x"367f"; |
m <= x"05d3"; |
r_c <= x"9f9b"; |
wait for clk_period; |
x <= x"c6e4"; |
y <= x"68de"; |
m <= x"cacd"; |
r_c <= x"b574"; |
wait for clk_period; |
x <= x"4a36"; |
y <= x"59a4"; |
m <= x"e16f"; |
r_c <= x"4a50"; |
wait for clk_period; |
x <= x"f6df"; |
y <= x"9f89"; |
m <= x"f67b"; |
r_c <= x"6d56"; |
wait for clk_period; |
x <= x"061c"; |
y <= x"ed71"; |
m <= x"7066"; |
r_c <= x"bdc6"; |
wait for clk_period; |
x <= x"06c8"; |
y <= x"059f"; |
m <= x"08de"; |
r_c <= x"0400"; |
wait for clk_period; |
valid_in <= '0'; |
|
--valid_in <='0'; |
wait for clk_period*200000; |
|
--Now with the public key x"10001"; |
|
bit_size <= x"0011"; |
valid_in <= '1'; |
x <= x"f3ad"; |
y <= x"0001"; |
m <= x"b491"; |
r_c <= x"f579"; |
wait for clk_period; |
x <= x"8e40"; |
y <= x"0001"; |
m <= x"1417"; |
r_c <= x"6ee9"; |
wait for clk_period; |
x <= x"6af9"; |
y <= x"0000"; |
m <= x"b498"; |
r_c <= x"972d"; |
wait for clk_period; |
x <= x"4e63"; |
m <= x"e1b7"; |
r_c <= x"5052"; |
wait for clk_period; |
x <= x"9600"; |
m <= x"e47c"; |
r_c <= x"1dca"; |
wait for clk_period; |
x <= x"68f4"; |
m <= x"b186"; |
r_c <= x"bc81"; |
wait for clk_period; |
x <= x"5a12"; |
m <= x"93f0"; |
r_c <= x"377e"; |
wait for clk_period; |
x <= x"d62e"; |
m <= x"b183"; |
r_c <= x"04ef"; |
wait for clk_period; |
x <= x"8fc1"; |
m <= x"f8f1"; |
r_c <= x"3a2a"; |
wait for clk_period; |
x <= x"031d"; |
m <= x"eed1"; |
r_c <= x"291b"; |
wait for clk_period; |
x <= x"f496"; |
m <= x"0083"; |
r_c <= x"c159"; |
wait for clk_period; |
x <= x"1268"; |
|
m <= x"981c"; |
r_c <= x"9336"; |
wait for clk_period; |
x <= x"2e5a"; |
|
m <= x"6441"; |
r_c <= x"1bd0"; |
wait for clk_period; |
x <= x"c1d6"; |
|
m <= x"fcd8"; |
r_c <= x"317d"; |
wait for clk_period; |
x <= x"cd8f"; |
|
m <= x"cbf0"; |
r_c <= x"64b4"; |
wait for clk_period; |
x <= x"e4d2"; |
|
m <= x"e3ca"; |
r_c <= x"8793"; |
wait for clk_period; |
x <= x"36c6"; |
|
m <= x"41d9"; |
r_c <= x"85f5"; |
wait for clk_period; |
x <= x"df4a"; |
|
m <= x"b7a0"; |
r_c <= x"7c8d"; |
wait for clk_period; |
x <= x"8e40"; |
|
m <= x"146e"; |
r_c <= x"64d9"; |
wait for clk_period; |
x <= x"6af9"; |
|
m <= x"4776"; |
r_c <= x"c7f6"; |
wait for clk_period; |
x <= x"4e63"; |
|
m <= x"ec50"; |
r_c <= x"fba0"; |
wait for clk_period; |
x <= x"9600"; |
|
m <= x"c07c"; |
r_c <= x"e3e0"; |
wait for clk_period; |
x <= x"68f4"; |
|
m <= x"e698"; |
r_c <= x"b567"; |
wait for clk_period; |
x <= x"5a12"; |
|
m <= x"d85f"; |
r_c <= x"3172"; |
wait for clk_period; |
x <= x"d62e"; |
|
m <= x"729c"; |
r_c <= x"111a"; |
wait for clk_period; |
x <= x"8fc1"; |
|
m <= x"19b6"; |
r_c <= x"1971"; |
wait for clk_period; |
x <= x"d2cd"; |
|
m <= x"05d3"; |
r_c <= x"9f9b"; |
wait for clk_period; |
x <= x"c6e4"; |
|
m <= x"cacd"; |
r_c <= x"b574"; |
wait for clk_period; |
x <= x"4a36"; |
|
m <= x"e16f"; |
r_c <= x"4a50"; |
wait for clk_period; |
x <= x"f6df"; |
|
m <= x"f67b"; |
r_c <= x"6d56"; |
wait for clk_period; |
x <= x"061c"; |
|
m <= x"7066"; |
r_c <= x"bdc6"; |
wait for clk_period; |
x <= x"06c8"; |
|
m <= x"08de"; |
r_c <= x"0400"; |
wait for clk_period; |
valid_in <= '0'; |
|
wait; |
end process; |
|
END; |
/trunk/rtl/montgomery_mult.vhd
0,0 → 1,366
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 20:03:35 11/02/2009 |
-- Design Name: |
-- Module Name: etapas - Behavioral |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity montgomery_mult is |
|
port( |
clk : in std_logic; |
reset : in std_logic; |
valid_in : in std_logic; |
a : in std_logic_vector(15 downto 0); |
b : in std_logic_vector(15 downto 0); |
n : in std_logic_vector(15 downto 0); |
s_prev : in std_logic_vector(15 downto 0); |
n_c : in std_logic_vector(15 downto 0); |
s : out std_logic_vector( 15 downto 0); |
valid_out : out std_logic -- es le valid out TODO : cambiar nombre |
); |
|
end montgomery_mult; |
|
architecture Behavioral of montgomery_mult is |
|
component montgomery_step is |
port( |
clk : in std_logic; |
reset : in std_logic; |
valid_in : in std_logic; |
a : in std_logic_vector(15 downto 0); |
b : in std_logic_vector(15 downto 0); |
n : in std_logic_vector(15 downto 0); |
s_prev : in std_logic_vector(15 downto 0); |
n_c : in std_logic_vector(15 downto 0); |
s : out std_logic_vector( 15 downto 0); |
valid_out : out std_logic; -- es le valid out TODO : cambiar nombre |
busy : out std_logic; |
b_req : out std_logic; |
a_out : out std_logic_vector(15 downto 0); |
|
c_step : out std_logic; --genera un pulso cuando termina su computo para avisar al modulo superior |
stop : in std_logic |
); |
end component; |
|
component fifo_512_bram |
port ( |
clk : in std_logic; |
rst : in std_logic; |
din : in std_logic_vector(15 downto 0); |
wr_en : in std_logic; |
rd_en : in std_logic; |
dout : out std_logic_vector(15 downto 0); |
full : out std_logic; |
empty : out std_logic); |
end component; |
|
component fifo_256_feedback |
port ( |
clk : in std_logic; |
rst : in std_logic; |
din : in std_logic_vector(48 downto 0); |
wr_en : in std_logic; |
rd_en : in std_logic; |
dout : out std_logic_vector(48 downto 0); |
full : out std_logic; |
empty : out std_logic); |
end component; |
|
type arr_dat_out is array(0 to 7) of std_logic_vector(15 downto 0); |
type arr_val is array(0 to 7) of std_logic; |
type arr_b is array(0 to 7) of std_logic_vector(15 downto 0); |
|
signal b_reg, next_b_reg : arr_b; |
signal valid_mid, fifo_reqs, fifo_reqs_reg, next_fifo_reqs_reg, stops : arr_val; |
signal a_out_mid, n_out_mid, s_out_mid : arr_dat_out; --std_logic_vector(15 downto 0); |
|
|
signal wr_en, rd_en, empty : std_logic; |
signal fifo_out : std_logic_vector(15 downto 0); |
|
signal fifo_out_feedback, fifo_in_feedback : std_logic_vector(48 downto 0); |
signal read_fifo_feedback, empty_feedback : std_logic; |
|
|
signal a_in, s_in, n_in : std_logic_vector(15 downto 0); |
signal f_valid, busy_pe : std_logic; |
|
--salida c_step del primer PE para ir contando y saber cuando sacar el valor correcto. |
signal c_step, reg_c_step : std_logic; |
|
|
signal count, next_count : std_logic_vector(7 downto 0); |
|
|
signal wr_fifofeed : std_logic; |
|
type state_type is (wait_start, process_data, dump_feed); |
signal state, next_state : state_type; |
signal reg_busy : std_logic; |
signal reset_fifos : std_logic; |
signal count_feedback, next_count_feedback : std_logic_vector(15 downto 0); |
|
begin |
|
--Fifo para almacenar b |
fifo_b : fifo_512_bram port map ( |
clk => clk, |
rst => reset_fifos, |
din => b, |
wr_en => wr_en, |
rd_en => rd_en, |
dout => fifo_out, |
empty => empty |
); |
|
--Fifo para el feedback al primer PE |
fifo_feed : fifo_256_feedback port map ( |
clk => clk, |
rst => reset_fifos, |
din => fifo_in_feedback, |
wr_en => wr_fifofeed, |
rd_en => read_fifo_feedback, |
dout => fifo_out_feedback, |
empty => empty_feedback |
); |
|
|
|
--Primer PE |
et_first : montgomery_step port map( |
clk => clk, |
reset => reset, |
valid_in => f_valid, |
a => a_in, |
b => b_reg(0), |
n => n_in, |
s_prev => s_in, |
n_c => n_c, |
s => s_out_mid(0), |
valid_out => valid_mid(0), |
busy => busy_pe, |
b_req => fifo_reqs(0), |
a_out => a_out_mid(0), |
n_out => n_out_mid(0), |
c_step => c_step, |
stop => stops(0) |
); |
|
--Ultimo PE |
et_last : montgomery_step port map( |
clk => clk, |
reset => reset, |
valid_in => valid_mid(6), |
a => a_out_mid(6), |
b => b_reg(7), |
n => n_out_mid(6), |
s_prev => s_out_mid(6), |
n_c => n_c, |
s => s_out_mid(7), |
valid_out => valid_mid(7), |
b_req => fifo_reqs(7), |
a_out => a_out_mid(7), |
n_out => n_out_mid(7), |
stop => stops(7) |
); |
|
g1 : for i in 1 to 6 generate |
et_i : montgomery_step port map( |
clk => clk, |
reset => reset, |
valid_in => valid_mid(i-1), |
a => a_out_mid(i-1), |
b => b_reg(i), |
n => n_out_mid(i-1), |
s_prev => s_out_mid(i-1), |
n_c => n_c, |
s => s_out_mid(i), |
valid_out => valid_mid(i), |
b_req => fifo_reqs(i), |
a_out => a_out_mid(i), |
n_out => n_out_mid(i), |
stop => stops(i) |
); |
|
end generate g1; |
|
|
process(clk, reset) |
begin |
|
if(clk = '1' and clk'event) then |
|
if(reset = '1')then |
state <= wait_start; |
count_feedback <= (others => '0'); |
reg_busy <= '0'; |
for i in 0 to 7 loop |
b_reg(i) <= (others => '0'); |
fifo_reqs_reg (i) <= '0'; |
count <= (others => '0'); |
reg_c_step <= '0'; |
|
end loop; |
else |
state <= next_state; |
reg_busy <= busy_pe; |
count_feedback <= next_count_feedback; |
for i in 0 to 7 loop |
b_reg(i) <= next_b_reg(i); |
fifo_reqs_reg (i) <= next_fifo_reqs_reg(i); |
count <= next_count; |
reg_c_step <= c_step; |
end loop; |
end if; |
end if; |
|
end process; |
|
|
--Proceso combinacional que controla las lecturas a la fifo |
process(fifo_reqs_reg, fifo_out, b, fifo_reqs, b_reg, state, empty) |
begin |
|
|
for i in 0 to 7 loop |
next_b_reg(i) <= b_reg(i); |
next_fifo_reqs_reg(i) <= fifo_reqs(i); |
end loop; |
|
if(state = wait_start) then |
next_b_reg(0) <= b; |
next_fifo_reqs_reg(0) <= '0'; --anulamos la peticion de b |
for i in 1 to 7 loop |
next_b_reg(i) <= (others => '0'); |
next_fifo_reqs_reg(i) <= '0'; |
end loop; |
else |
for i in 0 to 7 loop |
if(fifo_reqs_reg(i) = '1' and empty = '0') then |
next_b_reg(i) <= fifo_out; |
end if; |
end loop; |
end if; |
end process; |
|
--Proceso combinacional fsm principal |
process( valid_in, b, state, fifo_reqs, a_out_mid, n_out_mid, s_out_mid, valid_mid, a, s_prev, n, busy_pe, empty_feedback, fifo_out_feedback, count, reg_c_step, reset, reg_busy, count_feedback ) |
begin |
|
--las peticiones a la fifo son las or de los modulos |
rd_en <= fifo_reqs(0) or fifo_reqs(1) or fifo_reqs(2) or fifo_reqs(3) or fifo_reqs(4) or fifo_reqs(5) or fifo_reqs(6) or fifo_reqs(7); |
next_state <= state; |
wr_en <= '0'; |
fifo_in_feedback <= a_out_mid(7)&n_out_mid(7)&s_out_mid(7)&valid_mid(7); |
read_fifo_feedback <= '0'; |
wr_fifofeed <= '0'; |
--Controlamos el primer PE |
a_in <= a; |
s_in <= s_prev; |
n_in <= n; |
f_valid <= valid_in; |
reset_fifos <= reset; |
--ponemos las salidas |
s <= (others => '0'); |
valid_out <= '0'; |
|
--Incrementamos el contador solo cuando el primer PE termina su cuenta |
next_count <= count; |
next_count_feedback <= count_feedback; |
|
if(reg_c_step = '1') then |
next_count <= count + 8; |
end if; |
--durante el ciclo de la pipeline que sea considerado el ultimo, sacamos los datos |
if( count = x"20") then |
s <= s_out_mid(0); |
valid_out <= valid_mid(0); |
end if; |
|
for i in 0 to 7 loop |
stops(i) <= '0'; |
end loop; |
|
case state is |
--Esperamos a que tengamos un input y vamos cargando las b's |
when wait_start => |
reset_fifos <= '1'; |
if(valid_in = '1') then |
reset_fifos <= '0'; |
--next_b_reg(0) <= b; |
next_state <= process_data; |
--wr_en <= '1'; |
end if; |
|
when process_data => |
wr_fifofeed <= valid_mid(7); |
if(valid_in = '1') then |
wr_en <= '1'; |
end if; |
--Miramos si hay que volver a meter datos a la b |
if(empty_feedback = '0' and reg_busy = '0') then |
read_fifo_feedback <= '1'; |
next_state <= dump_feed; |
next_count_feedback <= x"0000"; |
end if; |
|
--Si ya hemos sobrepasado el limite paramos y volvemos a la espera |
if( count > x"23") then |
next_state <= wait_start; |
--y |
for i in 0 to 7 loop |
stops(i) <= '1'; |
end loop; |
next_count <= (others => '0'); |
end if; |
|
--Vacia la fifo de feedback |
when dump_feed => |
if(empty_feedback='0') |
then |
next_count_feedback <= count_feedback+1; |
end if; |
wr_fifofeed <= valid_mid(7); |
read_fifo_feedback <= '1'; |
a_in <= fifo_out_feedback(48 downto 33); |
n_in <= fifo_out_feedback(32 downto 17); |
s_in <= fifo_out_feedback(16 downto 1); |
f_valid <= fifo_out_feedback(0); |
if(empty_feedback='1') then |
next_state <= process_data; |
|
end if; |
if(count_feedback = x"22") then |
read_fifo_feedback <= '0'; |
next_state <= process_data; |
end if; |
end case; |
|
end process; |
end Behavioral; |
|
/trunk/rtl/pe.vhd
0,0 → 1,133
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 20:36:31 10/27/2009 |
-- Design Name: |
-- Module Name: PE - Behavioral |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity pe is |
port ( clk : in std_logic; |
reset : in std_logic; |
a_j : in std_logic_vector(15 downto 0); |
b_i : in std_logic_vector(15 downto 0); |
s_prev : in std_logic_vector(15 downto 0); --entrada de la s anterior para la suma |
m : in std_logic_vector(15 downto 0); |
n_j : in std_logic_vector(15 downto 0); |
s_next : out std_logic_vector(15 downto 0); --salida con la siguiente s |
aj_bi : out std_logic_vector(15 downto 0); --salida de multiplicador reutilizado para calcular a*b |
ab_valid_in : in std_logic; --indica que los datos de entrada en el multiplicador son validos |
|
ab_valid_out : out std_logic; --indica que la multiplicacion de un a y b validos se ha realizado con exito |
valid_out : out std_logic; |
fifo_req : out std_logic); --peticion de las siguientes entradas a, b, s, m |
end pe; |
|
architecture Behavioral of pe is |
|
signal prod_aj_bi, next_prod_aj_bi, mult_aj_bi : std_logic_vector(31 downto 0); -- registros para la primera mult |
signal prod_nj_m, next_prod_nj_m, mult_nj_m, mult_nj_m_reg : std_logic_vector(31 downto 0); |
signal sum_1, next_sum_1 : std_logic_vector(31 downto 0); |
signal sum_2, next_sum_2 : std_logic_vector(31 downto 0); |
signal ab_valid_reg, valid_out_reg, valid_out_reg2, valid_out_reg3 : std_logic; |
signal n_reg, next_n_reg, s_prev_reg, next_s_prev_reg, ab_out_reg : std_logic_vector(15 downto 0); |
--signal prod_aj_bi_out, next_prod_aj_bi_out : std_logic_vector(15 downto 0); |
|
begin |
|
|
mult_aj_bi <= a_j * b_i; |
mult_nj_m <= n_reg *m; |
|
|
process(clk, reset) |
begin |
|
if(clk = '1' and clk'event) |
then |
if(reset = '1') then |
prod_aj_bi <= (others => '0'); |
prod_nj_m <= (others => '0'); |
sum_1 <= (others => '0'); |
sum_2 <= (others => '0'); |
ab_valid_reg <= '0'; |
n_reg <= (others => '0'); |
valid_out_reg <= '0'; |
valid_out_reg2 <= '0'; |
valid_out_reg3 <= '0'; |
s_prev_reg <= (others => '0'); |
else |
--prod_aj_bi_out <= next_prod_aj_bi_out; |
prod_aj_bi <= next_prod_aj_bi; |
prod_nj_m <= next_prod_nj_m; |
sum_1 <= next_sum_1; |
sum_2 <= next_sum_2; |
ab_valid_reg <= ab_valid_in; |
ab_out_reg <= mult_aj_bi(15 downto 0); |
n_reg <= next_n_reg; |
valid_out_reg <= valid_in; --registramos el valid out para sacarle al tiempo de los datos validos |
valid_out_reg2 <= valid_out_reg; |
valid_out_reg3 <= valid_out_reg2; |
s_prev_reg <= next_s_prev_reg; |
--mult_nj_m_reg <= mult_nj_m; |
end if; |
end if; |
|
end process; |
|
process(s_prev, prod_aj_bi, prod_nj_m, sum_1, sum_2, mult_aj_bi, mult_nj_m, valid_in, ab_valid_reg, n_j, n_reg, valid_out_reg3, s_prev_reg, ab_out_reg) |
begin |
ab_valid_out <= ab_valid_reg; |
aj_bi <= ab_out_reg(15 downto 0); --Sacamos uno de los dos registros de la multiplicacion fuera para el calculo de la constante |
s_next <= sum_2(15 downto 0); --salida de la pipe |
fifo_req <= valid_in; |
valid_out <= valid_out_reg3; |
next_sum_1 <= sum_1; |
next_sum_2 <= sum_2; |
next_prod_nj_m <= prod_nj_m; |
next_prod_aj_bi <= prod_aj_bi; |
next_n_reg <= n_reg; |
next_s_prev_reg <= s_prev_reg; |
if(valid_in = '1') then |
next_s_prev_reg <= s_prev; |
next_n_reg <= n_j; |
next_prod_aj_bi <= mult_aj_bi; |
next_prod_nj_m <= mult_nj_m; --registramos la multiplicacion de n_j,m |
next_sum_1 <= prod_aj_bi+sum_1(31 downto 16)+s_prev_reg; |
next_sum_2 <= prod_nj_m+sum_2(31 downto 16) + sum_1(15 downto 0); |
else |
next_s_prev_reg <= (others => '0'); |
next_n_reg <= (others => '0'); |
next_prod_aj_bi <= (others => '0'); |
next_prod_nj_m <= (others => '0'); |
next_sum_1 <= (others =>'0'); |
next_sum_2 <= (others=>'0'); |
end if; |
|
|
|
end process; |
|
end Behavioral; |
|
/trunk/rtl/pe_wrapper.vhd
0,0 → 1,137
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 19:08:19 10/29/2009 |
-- Design Name: |
-- Module Name: montgomery - Behavioral |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity pe_wrapper is |
|
port( |
clk : in std_logic; |
reset : in std_logic; |
ab_valid : in std_logic; |
valid_in : in std_logic; |
a : in std_logic_vector(15 downto 0); |
b : in std_logic_vector(15 downto 0); |
n : in std_logic_vector(15 downto 0); |
s_prev : in std_logic_vector(15 downto 0); |
n_c : in std_logic_vector(15 downto 0); |
s : out std_logic_vector( 15 downto 0); |
data_ready : out std_logic; |
fifo_req : out std_logic; |
m_val : out std_logic; |
reset_the_PE : in std_logic); -- estamos preparados para aceptar el siguiente dato |
|
end pe_wrapper; |
|
architecture Behavioral of pe_wrapper is |
|
component pe is |
port ( clk : in std_logic; |
reset : in std_logic; |
a_j : in std_logic_vector(15 downto 0); |
b_i : in std_logic_vector(15 downto 0); |
s_prev : in std_logic_vector(15 downto 0); --entrada de la s anterior para la suma |
m : in std_logic_vector(15 downto 0); |
n_j : in std_logic_vector(15 downto 0); |
s_next : out std_logic_vector(15 downto 0); --salida con la siguiente s |
aj_bi : out std_logic_vector(15 downto 0); --salida de multiplicador reutilizado para calcular a*b |
ab_valid_in : in std_logic; --indica que los datos de entrada en el multiplicador son validos |
|
ab_valid_out : out std_logic; --indica que la multiplicacion de un a y b validos se ha realizado con exito |
valid_out : out std_logic; |
fifo_req : out std_logic); |
end component; |
|
component m_calc is |
port( |
clk : in std_logic; |
reset : in std_logic; |
ab : in std_logic_vector (15 downto 0); |
t : in std_logic_vector (15 downto 0); |
n_cons : in std_logic_vector (15 downto 0); |
m : out std_logic_vector (15 downto 0); |
mult_valid : in std_logic; |
m_valid : out std_logic); |
end component; |
|
signal aj_bi, m, next_m, m_out : std_logic_vector(15 downto 0); |
signal mult_valid, valid_m, valid_m_reg : std_logic; --lo registro para compararlos |
|
begin |
|
pe_0 : pe port map( |
clk => clk, |
reset => reset, |
a_j => a, |
b_i => b, |
s_prev => s_prev, |
m => m, |
n_j => n, |
s_next => s, |
aj_bi => aj_bi, |
ab_valid_in => ab_valid, |
valid_in => valid_in, |
ab_valid_out => mult_valid, |
valid_out => data_ready, |
fifo_req => fifo_req); |
|
mcons_0 : m_calc port map( |
clk => clk, |
reset => reset, |
ab => aj_bi, |
t => s_prev, |
n_cons => n_c, |
m => m_out, |
mult_valid => mult_valid, |
m_valid => valid_m); |
|
process(clk, reset) |
begin |
if(clk='1' and clk'event) then |
|
if(reset='1')then |
m <= (others=> '0' ); |
valid_m_reg <= '0'; |
else |
m <= next_m; |
valid_m_reg <= valid_m; |
end if; |
end if; |
end process; |
|
process(m_out,valid_m, valid_m_reg, m) |
begin |
m_val <= valid_m_reg; |
if(valid_m = '1' and valid_m_reg ='0') then |
next_m <= m_out; |
else |
next_m <= m; |
end if; |
end process; |
|
end Behavioral; |
|
/trunk/rtl/rsa_top.vhd
0,0 → 1,496
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 16:01:04 12/13/2009 |
-- Design Name: |
-- Module Name: rsa_top - Behavioral |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
-- synthesis translate_off |
library UNISIM; |
use UNISIM.VCOMPONENTS.all; |
-- synthesis translate_on |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity rsa_top is |
port( |
clk : in std_logic; |
reset : in std_logic; |
valid_in : in std_logic; |
x : in std_logic_vector(15 downto 0); -- estos 3 son x^y mod m |
y : in std_logic_vector(15 downto 0); |
m : in std_logic_vector(15 downto 0); |
r_c : in std_logic_vector(15 downto 0); --constante de montgomery r^2 mod m |
n_c : in std_logic_vector(15 downto 0); --constante necesaria en la multiplicacion |
s : out std_logic_vector( 15 downto 0); |
valid_out : out std_logic; |
bit_size : in std_logic_vector(15 downto 0) --tamano bit del exponente y (log2(y)) |
); |
end rsa_top; |
|
architecture Behavioral of rsa_top is |
|
|
--Multiplicador de Montgomery que sera instanciado 2 veces |
component montgomery_mult is |
port( |
clk : in std_logic; |
reset : in std_logic; |
valid_in : in std_logic; |
a : in std_logic_vector(15 downto 0); |
b : in std_logic_vector(15 downto 0); |
n : in std_logic_vector(15 downto 0); |
s_prev : in std_logic_vector(15 downto 0); |
n_c : in std_logic_vector(15 downto 0); |
s : out std_logic_vector( 15 downto 0); |
valid_out : out std_logic -- es le valid out TODO : cambiar nombre |
); |
end component; |
|
--Memoria para guardar el exponente y el modulo |
component Mem_b |
port ( |
clka : in std_logic; |
wea : in std_logic_vector(0 downto 0); |
addra : in std_logic_vector(5 downto 0); |
dina : in std_logic_vector(15 downto 0); |
douta : out std_logic_vector(15 downto 0)); |
end component; |
|
|
--fifos para los resultados de las mult parciales |
component res_out_fifo |
port ( |
clk : in std_logic; |
rst : in std_logic; |
din : in std_logic_vector(31 downto 0); |
wr_en : in std_logic; |
rd_en : in std_logic; |
dout : out std_logic_vector(31 downto 0); |
full : out std_logic; |
empty : out std_logic); |
end component; |
|
|
signal valid_in_mon_1, valid_in_mon_2, valid_out_mon_1, valid_out_mon_2, fifo_1_rd, fifo_1_wr : std_logic; |
|
signal a_mon_1, b_mon_1, n_mon_1, s_p_mon_1, s_out_mon_1, a_mon_2, b_mon_2, n_mon_2, s_p_mon_2, s_out_mon_2, fifo_1_in, fifo_2_in, fifo_1_out, exp_out, n_out : std_logic_vector(15 downto 0); |
|
signal fifo_out, fifo_in : std_logic_vector(31 downto 0); |
|
signal addr_exp, addr_n, next_addr_exp, next_addr_n : std_logic_vector(5 downto 0); |
|
type state_type is (wait_start, prepare_data, wait_constants, writting_cts_fifo, processing_data_0, processing_data_1, wait_results, transition, prepare_next, writting_results, final_mult, show_final, prepare_final, wait_final); |
signal state, next_state : state_type; |
signal w_numb, next_w_numb : std_logic_vector(7 downto 0); |
|
signal n_c_reg, next_n_c_reg : std_logic_vector(15 downto 0); |
--Cuenta los datos que se van metiendo al multiplicador para generar el padding por si solo. |
signal count_input, next_count_input, bit_counter, next_bit_counter : std_logic_vector(15 downto 0); |
|
signal bsize_reg, next_bsize_reg : std_logic_vector (15 downto 0); |
signal write_b_n : std_logic_vector(0 downto 0); |
|
begin |
|
|
mon_1 : montgomery_mult port map( |
clk => clk, |
reset => reset, |
valid_in => valid_in_mon_1, |
a => a_mon_1, |
b => b_mon_1, |
n => n_mon_1, |
s_prev => s_p_mon_1, |
n_c => n_c_reg, |
s => s_out_mon_1, |
valid_out => valid_out_mon_1 |
); |
|
mon_2 : montgomery_mult port map( |
clk => clk, |
reset => reset, |
valid_in => valid_in_mon_2, |
a => a_mon_2, |
b => b_mon_2, |
n => n_mon_2, |
s_prev => s_p_mon_2, |
n_c => n_c_reg, |
s => s_out_mon_2, |
valid_out => valid_out_mon_2 |
); |
|
|
fifo_mon_out : res_out_fifo |
port map ( |
clk => clk, |
rst => reset, |
din => fifo_in, |
wr_en => fifo_1_wr, |
rd_en => fifo_1_rd, |
dout => fifo_out |
); |
|
exp : Mem_b port map ( |
clka => clk, |
wea => write_b_n, |
addra => addr_exp, |
dina => y, |
douta => exp_out); |
|
n_mod : Mem_b port map ( |
clka => clk, |
wea => write_b_n, |
addra => addr_n, |
dina => m, |
douta => n_out); |
|
|
|
process(clk, reset) |
begin |
|
if(clk = '1' and clk'event) then |
|
if(reset = '1')then |
state <= wait_start; |
n_c_reg <= (others => '0'); |
w_numb <= (others => '0'); |
count_input <= (others => '0'); |
addr_exp <= (others => '0'); |
addr_n <= (others => '0'); |
bit_counter <= (others => '0'); |
bsize_reg <= (others => '0'); |
else |
state <= next_state; |
n_c_reg <= next_n_c_reg; |
w_numb <= next_w_numb; |
count_input <= next_count_input; |
addr_exp <= next_addr_exp; |
addr_n <= next_addr_n; |
bit_counter <= next_bit_counter; |
bsize_reg <= next_bsize_reg; |
end if; |
end if; |
end process; |
|
process(state, bsize_reg, n_c_reg, valid_in, x, n_c, r_c, m, y, w_numb, count_input, addr_exp, addr_n, s_out_mon_1, s_out_mon_2, bit_size, valid_out_mon_1, bit_counter, exp_out, fifo_out, n_out) |
|
variable mask : std_logic_vector(3 downto 0); |
|
begin |
|
--Registers update |
next_state <= state; |
next_n_c_reg <= n_c_reg; |
next_w_numb <= w_numb; |
next_count_input <= count_input; |
next_bsize_reg <= bsize_reg; |
--Entradas de los montgomerys. |
valid_in_mon_1 <= '0'; |
valid_in_mon_2 <= '0'; |
a_mon_1 <= (others => '0'); |
b_mon_1 <= (others => '0'); |
n_mon_1 <= (others => '0'); |
a_mon_2 <= (others => '0'); |
b_mon_2 <= (others => '0'); |
n_mon_2 <= (others => '0'); |
s_p_mon_1 <= (others => '0'); |
s_p_mon_2 <= (others => '0'); |
--Control de las fifos |
fifo_1_rd <= '0'; |
fifo_in <= (others => '0'); |
fifo_1_wr <= '0'; |
--Control de memorias de exp y modulo |
write_b_n <= b"0"; |
next_addr_exp <= addr_exp; |
next_addr_n <= addr_n; |
next_bit_counter <= bit_counter; |
--Outputs |
valid_out <= '0'; |
s <= (others => '0'); |
case state is |
|
when wait_start => |
|
valid_in_mon_1 <= valid_in; |
valid_in_mon_2 <= valid_in; |
if(valid_in = '1') then |
a_mon_1 <= x; |
b_mon_1 <= r_c; |
n_mon_1 <= m; |
|
a_mon_2 <= x"0001"; |
b_mon_2 <= r_c; |
n_mon_2 <= m; |
next_w_numb <= x"23"; --Se extiende en 3 para poder usar las multiplicaciones modulares |
next_n_c_reg <= n_c; |
next_state <= prepare_data; |
next_count_input <= x"0001"; |
|
write_b_n <= b"1"; --Notificamos que hay que guardar el exponente y modulo |
next_addr_exp <= "000001"; |
next_addr_n <= "000001"; |
next_bsize_reg <= bit_size-1; |
end if; |
|
when prepare_data => |
next_count_input <= count_input+1; |
valid_in_mon_1 <= '1'; |
valid_in_mon_2 <= '1'; |
--Esto es solo mientras los datos en la entrada son validos, cuando no lo son |
--se meten 0s para la extension de 3 palabras en los montgomerys |
if(valid_in = '1') then |
a_mon_1 <= x; |
b_mon_1 <= r_c; |
n_mon_1 <= m; |
b_mon_2 <= r_c; |
n_mon_2 <= m; |
|
write_b_n <= b"1"; |
next_addr_exp <= addr_exp+1; |
next_addr_n <= addr_n+1; |
end if; |
if(count_input = w_numb) then |
next_state <= wait_constants; |
next_addr_n <= (others => '0'); |
|
next_addr_exp <= bsize_reg(9 downto 4); |
--Decodificador para establecer la mascara |
mask := bsize_reg(3 downto 0); |
case (mask) is |
when "0000" => next_bit_counter <= "0000000000000001"; |
when "0001" => next_bit_counter <= "0000000000000010"; |
when "0010" => next_bit_counter <= "0000000000000100"; |
when "0011" => next_bit_counter <= "0000000000001000"; |
when "0100" => next_bit_counter <= "0000000000010000"; |
when "0101" => next_bit_counter <= "0000000000100000"; |
when "0110" => next_bit_counter <= "0000000001000000"; |
when "0111" => next_bit_counter <= "0000000010000000"; |
when "1000" => next_bit_counter <= "0000000100000000"; |
when "1001" => next_bit_counter <= "0000001000000000"; |
when "1010" => next_bit_counter <= "0000010000000000"; |
when "1011" => next_bit_counter <= "0000100000000000"; |
when "1100" => next_bit_counter <= "0001000000000000"; |
when "1101" => next_bit_counter <= "0010000000000000"; |
when "1110" => next_bit_counter <= "0100000000000000"; |
when "1111" => next_bit_counter <= "1000000000000000"; |
when others => |
end case; |
next_count_input <= (others => '0'); |
end if; |
|
--Esperamos los valores validos de la salida de los montgomery |
when wait_constants => |
|
--Comienzo a escribir en la fifo de datos |
if(valid_out_mon_1 = '1') then |
fifo_1_wr <= '1'; |
fifo_in <= s_out_mon_1 & s_out_mon_2; |
next_count_input <= count_input+1; |
next_state <= writting_cts_fifo; |
end if; |
|
--Escribimos las dos constantes iniciales en las fifos |
when writting_cts_fifo => |
fifo_1_wr <= valid_out_mon_1; |
next_count_input <= count_input+1; |
if(count_input < x"20") then |
fifo_in <= s_out_mon_1 & s_out_mon_2; |
end if; |
|
--Pedimos el siguiente input para la multiplicacion |
if(valid_out_mon_1 = '0') then |
next_count_input <= (others => '0'); |
next_state <= transition; |
end if; |
|
when transition => |
|
next_count_input <= count_input+1; |
|
if(count_input > 2) then |
next_count_input <= (others => '0'); |
--fifo_1_rd <= '1'; |
--next_addr_n <= addr_n+1; |
if((bit_counter and exp_out) = x"0000") then |
next_state <= processing_data_0; |
else |
next_state <= processing_data_1; |
end if; |
|
end if; |
|
--se van ejecutando las multiplicaciones sucesivas |
when processing_data_1 => |
|
|
if(count_input > x"0000")then |
valid_in_mon_1 <= '1'; |
valid_in_mon_2 <= '1'; |
end if; |
|
|
fifo_1_rd <= '1'; |
|
a_mon_1 <= fifo_out(31 downto 16); |
b_mon_1 <= fifo_out(15 downto 0); |
n_mon_1 <= n_out; |
|
a_mon_2 <= fifo_out(31 downto 16); |
b_mon_2 <= fifo_out(31 downto 16); |
n_mon_2 <= n_out; |
|
next_addr_n <= addr_n+1; |
next_count_input <= count_input +1; |
|
--Cuando llego al final cambio de estado a esperar resultados |
if(count_input = w_numb) then |
next_state <= wait_results; |
end if; |
|
when processing_data_0 => |
|
if(count_input > x"0000")then |
valid_in_mon_1 <= '1'; |
valid_in_mon_2 <= '1'; |
end if; |
|
fifo_1_rd <= '1'; |
|
a_mon_1 <= fifo_out(15 downto 0); |
b_mon_1 <= fifo_out(15 downto 0); |
n_mon_1 <= n_out; |
|
a_mon_2 <= fifo_out(31 downto 16); |
b_mon_2 <= fifo_out(15 downto 0); |
n_mon_2 <= n_out; |
|
next_addr_n <= addr_n+1; |
next_count_input <= count_input +1; |
|
--Cuando llego al final cambio de estado a esperar resultados |
if(count_input = w_numb) then |
next_state <= wait_results; |
next_count_input <= (others => '0'); |
end if; |
|
when wait_results => |
|
--Comienzo a escribir en la fifo de datos |
if(valid_out_mon_1 = '1') then |
fifo_1_wr <= '1'; |
fifo_in <= s_out_mon_2 & s_out_mon_1; |
next_count_input <= x"0001"; |
next_state <= writting_results; |
end if; |
|
when writting_results => |
|
next_addr_n <= (others => '0'); |
fifo_1_wr <= valid_out_mon_1; |
next_count_input <= count_input+1; |
if(count_input < x"20") then |
fifo_in <= s_out_mon_2 & s_out_mon_1; |
end if; |
|
--Pedimos el siguiente input para la multiplicacion |
if(valid_out_mon_1 = '0') then |
next_count_input <= (others => '0'); |
next_state <= prepare_next; |
--Calculo del siguiente bit del exponente |
--Shifto uno la mascara |
next_bit_counter <= '0'&bit_counter(15 downto 1); |
if(bit_counter = x"0001") |
then |
next_addr_exp <= addr_exp -1; |
next_bit_counter <= "1000000000000000"; |
end if; |
if((bit_counter = x"0001") and addr_exp = "000000000") |
then |
next_state <= final_mult; |
next_count_input <= (others => '0'); |
next_addr_exp <= (others => '0'); |
end if; |
end if; |
|
when prepare_next => |
next_state <= transition; |
next_count_input <= (others => '0'); |
fifo_1_rd <= '0'; |
|
when final_mult => |
next_count_input <= count_input+1; |
|
if(count_input > 2) then |
next_count_input <= (others => '0'); |
next_state <= prepare_final; |
end if; |
|
when prepare_final => |
|
if(count_input > x"0000")then |
valid_in_mon_1 <= '1'; |
end if; |
|
fifo_1_rd <= '1'; |
|
a_mon_1 <= fifo_out(15 downto 0); |
if(count_input = x"0001") then |
b_mon_1 <= x"0001"; |
end if; |
n_mon_1 <= n_out; |
|
next_addr_n <= addr_n+1; |
next_count_input <= count_input +1; |
|
--Cuando llego al final cambio de estado a esperar resultados |
if(count_input = w_numb) then |
next_state <= wait_final; |
next_count_input <= (others =>'0'); |
end if; |
|
when wait_final => |
|
if(valid_out_mon_1 = '1') then |
valid_out <= '1'; |
s <= s_out_mon_1; |
next_state <= show_final; |
next_count_input <= count_input +1; |
end if; |
|
when show_final => |
valid_out <= '1'; |
s <= s_out_mon_1; |
next_count_input <= count_input +1; |
--Cuando llego al final cambio de estado a esperar resultados |
if(count_input = x"20") then |
valid_out <= '0'; |
next_state <= wait_start; |
end if; |
|
end case; |
|
end process; |
|
end Behavioral; |
|
/trunk/rtl/montgomery_step.vhd
0,0 → 1,255
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 10:40:41 11/01/2009 |
-- Design Name: |
-- Module Name: module_with_fifo - Behavioral |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity montgomery_step is |
port( |
clk : in std_logic; |
reset : in std_logic; |
valid_in : in std_logic; |
a : in std_logic_vector(15 downto 0); |
b : in std_logic_vector(15 downto 0); |
n : in std_logic_vector(15 downto 0); |
s_prev : in std_logic_vector(15 downto 0); |
n_c : in std_logic_vector(15 downto 0); |
s : out std_logic_vector( 15 downto 0); |
valid_out : out std_logic; -- es le valid out TODO : cambiar nombre |
busy : out std_logic; |
b_req : out std_logic; |
a_out : out std_logic_vector(15 downto 0); |
|
c_step : out std_logic; --genera un pulso cuando termina su computo para avisar al modulo superior |
stop : in std_logic |
); |
end montgomery_step; |
|
architecture Behavioral of montgomery_step is |
|
component pe_wrapper |
port( |
clk : in std_logic; |
reset : in std_logic; |
ab_valid : in std_logic; |
valid_in : in std_logic; |
a : in std_logic_vector(15 downto 0); |
b : in std_logic_vector(15 downto 0); |
n : in std_logic_vector(15 downto 0); |
s_prev : in std_logic_vector(15 downto 0); |
n_c : in std_logic_vector(15 downto 0); |
s : out std_logic_vector( 15 downto 0); |
data_ready : out std_logic; |
fifo_req : out std_logic; |
m_val : out std_logic; |
reset_the_PE : in std_logic); -- estamos preparados para aceptar el siguiente dato |
end component; |
|
--Inputs |
|
signal ab_valid : std_logic; |
signal valid_mont, fifo_read, m_val, valid_mont_out, reset_pe : std_logic; |
--Outputs |
|
|
--definimos los estados |
type state_type is (wait_valid, wait_m, mont_proc, getting_results, prep_m, b_stable); |
signal state, next_state : state_type; |
signal counter, next_counter : std_logic_vector(7 downto 0); -- cuenta las palabras que han salido para ir cortando |
|
|
|
signal mont_input_a, mont_input_n, mont_input_s : std_logic_vector(15 downto 0); |
signal reg_constant, next_reg_constant, next_reg_input, reg_input : std_logic_vector(47 downto 0); |
signal reg_out, reg_out_1, reg_out_2, reg_out_3, reg_out_4 : std_logic_vector(31 downto 0); |
signal next_reg_out : std_logic_vector(31 downto 0); |
|
--Cadena de registros hacia fuera |
signal reg_input_1, reg_input_2, reg_input_3, reg_input_4, reg_input_5 : std_logic_vector(47 downto 0); |
|
|
begin |
|
mont : pe_wrapper port map ( |
clk => clk, |
reset => reset, |
ab_valid => ab_valid, |
a => mont_input_a, |
b => b, |
n => mont_input_n, |
s_prev => mont_input_s, |
n_c => n_c, |
s => s, |
valid_in => valid_mont, |
data_ready => valid_mont_out, |
m_val => m_val, |
reset_the_PE => reset_pe |
); |
|
process(clk, reset) |
begin |
if(clk = '1' and clk'event) then |
|
if(reset = '1')then |
state <= wait_valid; |
counter <= (others => '0'); |
reg_constant <= (others => '0'); |
reg_input <= (others => '0'); |
reg_input_1 <= (others => '0'); |
reg_input_2 <= (others => '0'); |
reg_input_3 <= (others => '0'); |
reg_input_4 <= (others => '0'); |
|
reg_out <= (others => '0'); |
reg_out_1 <= (others => '0'); |
reg_out_2 <= (others => '0'); |
reg_out_3 <= (others => '0'); |
reg_out_4 <= (others => '0'); |
|
else |
reg_input <= next_reg_input; |
reg_input_1 <= reg_input; |
reg_input_2 <= reg_input_1; |
reg_input_3 <= reg_input_2; |
reg_input_4 <= reg_input_3; |
reg_input_5 <= reg_input_4; |
|
reg_out <= reg_input_4(47 downto 32) & reg_input_4(31 downto 16); |
reg_out_1 <= reg_out; |
reg_out_2 <= reg_out_1; |
reg_out_3 <= reg_out_2; |
reg_out_4 <= reg_out_3; |
|
state <= next_state; |
counter <= next_counter; |
reg_constant <= next_reg_constant; |
end if; |
end if; |
end process; |
|
process(state, valid_in, m_val, a, n, s_prev, counter, valid_mont_out, stop, reg_constant, reg_input_5, reg_out_4) |
begin |
--reset_fifo <= '0'; |
|
--next_reg_out <= a&n; --Vamos retrasando la entrada TODO add variable |
|
|
a_out <= reg_out_4(31 downto 16); |
n_out <= reg_out_4(15 downto 0); |
|
next_state <= state; |
next_counter <= counter; |
--write_fifos <= valid_in; |
ab_valid <= '0'; |
valid_mont <= '0'; |
valid_out <= '0'; |
reset_pe <= '0'; |
busy <= '1'; |
b_req <= '0'; |
c_step <= '0'; |
|
--Todo esto es nuevo |
mont_input_a <= (others => '0'); |
mont_input_n <= (others => '0'); |
mont_input_s <= (others => '0'); |
next_reg_constant <= reg_constant; |
|
case state is |
when wait_valid => |
busy <= '0'; --esperamos la peticion |
reset_pe <= '1'; |
if(valid_in = '1') then |
|
b_req <= '1'; --Solicitamos al modulo externo la b |
next_state <= b_stable; |
next_reg_constant <= a&n&s_prev; --TODO add variable |
end if; |
when b_stable => |
next_state <= prep_m; |
when prep_m => |
mont_input_a <= reg_constant(47 downto 32); --TODO add this to sensitivity |
mont_input_n <= reg_constant(31 downto 16); |
mont_input_s <= reg_constant(15 downto 0); |
ab_valid <= '1'; |
next_state <= wait_m; |
when wait_m => |
|
--Mantenemos las entradas para que nos calcule m correctamente |
mont_input_a <= reg_constant(47 downto 32); --TODO add this to sensitivity |
mont_input_n <= reg_constant(31 downto 16); |
mont_input_s <= reg_constant(15 downto 0); |
|
|
if (m_val = '1') then |
|
valid_mont <= '1'; |
next_state <= mont_proc; |
mont_input_a <= reg_input_5(47 downto 32); |
mont_input_n <= reg_input_5(31 downto 16); |
mont_input_s <= reg_input_5(15 downto 0); |
|
end if; |
|
when mont_proc => |
|
valid_mont <= '1'; |
mont_input_a <= reg_input_5(47 downto 32); |
mont_input_n <= reg_input_5(31 downto 16); |
mont_input_s <= reg_input_5(15 downto 0); |
|
if(valid_mont_out = '1') then |
|
next_counter <= x"00"; |
next_state <= getting_results; |
end if; |
|
when getting_results => |
|
valid_out <= '1'; |
next_counter <= counter+1; |
valid_mont <= '1'; |
|
mont_input_a <= reg_input_5(47 downto 32); |
mont_input_n <= reg_input_5(31 downto 16); |
mont_input_s <= reg_input_5(15 downto 0); |
|
if(counter = (x"22")) then |
next_state <= wait_valid; |
c_step <= '1'; |
reset_pe <= '1'; |
end if; |
|
end case; |
|
if(stop='1') then |
next_state <= wait_valid; |
--reset_fifo <= '1'; |
reset_pe <= '1'; |
end if; |
|
end process; |
|
end Behavioral; |
/trunk/rtl/m_calc.vhd
0,0 → 1,83
---------------------------------------------------------------------------------- |
-- Company: |
-- Engineer: |
-- |
-- Create Date: 20:33:10 10/29/2009 |
-- Design Name: |
-- Module Name: m_calc - Behavioral |
-- Project Name: |
-- Target Devices: |
-- Tool versions: |
-- Description: |
-- |
-- Dependencies: |
-- |
-- Revision: |
-- Revision 0.01 - File Created |
-- Additional Comments: |
-- |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
---- Uncomment the following library declaration if instantiating |
---- any Xilinx primitives in this code. |
--library UNISIM; |
--use UNISIM.VComponents.all; |
|
entity m_calc is |
|
port( |
clk : in std_logic; |
reset : in std_logic; |
ab : in std_logic_vector (15 downto 0); |
t : in std_logic_vector (15 downto 0); |
n_cons : in std_logic_vector (15 downto 0); |
m : out std_logic_vector (15 downto 0); |
mult_valid : in std_logic; -- indica que los datos de entrada son validos |
m_valid : out std_logic); -- la m calculada es valida |
end m_calc; |
|
architecture Behavioral of m_calc is |
|
|
|
signal sum_res, next_sum_res : std_logic_vector(15 downto 0); |
signal mult_valid_1, mult_valid_2 : std_logic; --delay del valido a lo largo del calculo |
signal mult : std_logic_vector(31 downto 0); |
begin |
|
|
mult <= sum_res * n_cons; |
|
process(clk, reset) |
begin |
|
if(clk = '1' and clk'event) then |
|
if(reset = '1') then |
sum_res <= (others => '0'); |
mult_valid_1 <= '0'; |
mult_valid_2 <= '0'; |
else |
sum_res <= next_sum_res; |
mult_valid_1 <= mult_valid; |
mult_valid_2 <= mult_valid_1; |
|
end if; |
|
end if; |
|
end process; |
|
process(ab, t, mult_valid_2) |
begin |
m <= mult(15 downto 0); |
next_sum_res <= ab+t; |
m_valid <= mult_valid_2; |
end process; |
|
end Behavioral; |
|
/trunk/doc/rsa 512.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/doc/rsa 512.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/src/constant_gen.c
===================================================================
--- trunk/src/constant_gen.c (nonexistent)
+++ trunk/src/constant_gen.c (revision 3)
@@ -0,0 +1,64 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define uint16 unsigned short int
+#define uint32 unsigned int
+#define uint64 unsigned long long int
+#define WORD_SIZE 32
+
+
+uint32 getMpzSize(mpz_t n)
+{
+
+ return (mpz_size(n)*2);
+
+}
+
+uint16 getlimb(mpz_t n, int i)
+{
+ uint32 aux=mpz_getlimbn(n,i/2);
+ if(i%2 == 0)
+ return (uint16) (aux&0xffff);
+ return (uint16) (aux>>16);
+
+}
+
+
+
+int main()
+{
+
+ int i;
+
+ mpz_t m,x,y,r,r_aux, n_cons, zero, recons;
+
+ char *template;
+
+ mpz_init_set_str(m,"8de7066f67be16fcacd05d319b6729cd85fe698c07cec504776146eb7a041d9e3cacbf0fcd86441981c0083eed1f8f1b18393f0b186e47ce1b7b4981417b491",16); //mpz_init_set_str(m,"c3217fff",16);
+
+ mpz_init(r);
+ mpz_init(r_aux);
+ mpz_init(n_cons);
+ mpz_init_set_ui(zero,0);
+
+ //Calculo de la constante para salir de la representacion de montgomery
+ mpz_ui_pow_ui(r,2,16*(getMpzSize(m)+1));
+ mpz_mul(r_aux,r,r);
+ mpz_mod(r_aux,r_aux,m);
+
+ mpz_sub(n_cons,zero,m);
+ mpz_invert(n_cons,n_cons,r);
+
+
+
+ printf ("n_c <= %x;\n\n", (uint32)mpz_getlimbn(n_cons,0)&0xffff);
+ gmp_printf("r_c <= %Zx\n\n", r_aux);
+
+ return 0;
+}
Index: trunk/src/Makefile
===================================================================
--- trunk/src/Makefile (nonexistent)
+++ trunk/src/Makefile (revision 3)
@@ -0,0 +1,3 @@
+all:
+ gcc constant_gen.c -lgmp -o constant_gen
+ constant_gen
Index: trunk/sim/transcript
===================================================================
--- trunk/sim/transcript (nonexistent)
+++ trunk/sim/transcript (revision 3)
@@ -0,0 +1,10 @@
+# // ModelSim SE-64 6.5d Nov 18 2009 Linux 2.6.18-164.11.1.el5.centos.plus
+# //
+# // Copyright 1991-2009 Mentor Graphics Corporation
+# // All Rights Reserved.
+# //
+# // THIS WORK CONTAINS TRADE SECRET AND
+# // PROPRIETARY INFORMATION WHICH IS THE PROPERTY
+# // OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS
+# // AND IS SUBJECT TO LICENSE TERMS.
+# //