OpenCores
URL https://opencores.org/ocsvn/BasicRSA/BasicRSA/trunk

Subversion Repositories BasicRSA

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/tags/initial/rtl/vhdl/rsacypher.vhd
0,0 → 1,274
----------------------------------------------------------------------
---- ----
---- Basic RSA Public Key Cryptography IP Core ----
---- ----
---- Implementation of BasicRSA IP core according to ----
---- BasicRSA IP core specification document. ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Author(s): ----
---- - Steven R. McQueen, srmcqueen@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2001 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
--
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
--
 
-- This module implements the RSA Public Key Cypher. It expects to receive the data block
-- to be encrypted or decrypted on the indata bus, the exponent to be used on the inExp bus,
-- and the modulus on the inMod bus. The data block must have a value less than the modulus.
-- It may be worth noting that in practice the exponent is not restricted to the size of the
-- modulus, as would be implied by the bus sizes used in this design. This design must
-- therefore be regarded as a demonstration only.
--
-- A Square-and-Multiply algorithm is used in this module. For each bit of the exponent, the
-- message value is squared. For each '1' bit of the exponent, the message value is multiplied
-- by the result of the squaring operation. The operation ends when there are no more '1'
-- bits in the exponent. Unfortunately, the squaring multiplication must be performed whether
-- the corresponding exponent bit is '1' or '0', so very little is gained by skipping the
-- multiplication of the data value. A multiplication is performed for every significant bit
-- in the exponent.
--
-- Comments, questions and suggestions may be directed to the author at srmcqueen@mcqueentech.com.
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity RSACypher is
Generic (KEYSIZE: integer := 32);
Port (indata: in std_logic_vector(KEYSIZE-1 downto 0);
inExp: in std_logic_vector(KEYSIZE-1 downto 0);
inMod: in std_logic_vector(KEYSIZE-1 downto 0);
cypher: out std_logic_vector(KEYSIZE-1 downto 0);
clk: in std_logic;
ds: in std_logic;
reset: in std_logic;
ready: out std_logic
);
end RSACypher;
 
architecture Behavioral of RSACypher is
attribute keep: string;
 
component modmult is
Generic (MPWID: integer);
Port ( mpand : in std_logic_vector(MPWID-1 downto 0);
mplier : in std_logic_vector(MPWID-1 downto 0);
modulus : in std_logic_vector(MPWID-1 downto 0);
product : out std_logic_vector(MPWID-1 downto 0);
clk : in std_logic;
ds : in std_logic;
reset : in std_logic;
ready: out std_logic);
end component;
 
signal modreg: std_logic_vector(KEYSIZE-1 downto 0); -- store the modulus value during operation
signal root: std_logic_vector(KEYSIZE-1 downto 0); -- value to be squared
signal square: std_logic_vector(KEYSIZE-1 downto 0); -- result of square operation
signal sqrin: std_logic_vector(KEYSIZE-1 downto 0); -- 1 or copy of root
signal tempin: std_logic_vector(KEYSIZE-1 downto 0); -- 1 or copy of square
signal tempout: std_logic_vector(KEYSIZE-1 downto 0); -- result of multiplication
signal count: std_logic_vector(KEYSIZE-1 downto 0); -- working copy of exponent
 
signal multrdy, sqrrdy, bothrdy: std_logic; -- signals to indicate completion of multiplications
signal multgo, sqrgo: std_logic; -- signals to trigger start of multiplications
signal done: std_logic; -- signal to indicate encryption complete
 
-- The following attributes can be set to make signal tracing easier
 
--attribute keep of multrdy: signal is "true";
--attribute keep of sqrrdy: signal is "true";
--attribute keep of bothrdy: signal is "true";
--attribute keep of multgo: signal is "true";
--attribute keep of sqrgo: signal is "true";
 
 
begin
 
ready <= done;
bothrdy <= multrdy and sqrrdy;
-- Modular multiplier to produce products
modmultiply: modmult
Generic Map(MPWID => KEYSIZE)
Port Map(mpand => tempin,
mplier => sqrin,
modulus => modreg,
product => tempout,
clk => clk,
ds => multgo,
reset => reset,
ready => multrdy);
 
-- Modular multiplier to take care of squaring operations
modsqr: modmult
Generic Map(MPWID => KEYSIZE)
Port Map(mpand => root,
mplier => root,
modulus => modreg,
product => square,
clk => clk,
ds => multgo,
reset => reset,
ready =>sqrrdy);
 
--counter manager process tracks counter and enable flags
mngcount: process (clk, reset, done, ds, count, bothrdy) is
begin
-- handles DONE and COUNT signals
if reset = '1' then
count <= (others => '0');
done <= '1';
elsif rising_edge(clk) then
if done = '1' then
if ds = '1' then
-- first time through
count <= '0' & inExp(KEYSIZE-1 downto 1);
done <= '0';
end if;
-- after first time
elsif count = 0 then
if bothrdy = '1' and multgo = '0' then
cypher <= tempout; -- set output value
done <= '1';
end if;
elsif bothrdy = '1' then
if multgo = '0' then
count <= '0' & count(KEYSIZE-1 downto 1);
end if;
end if;
end if;
 
end process mngcount;
 
-- This process sets the input values for the squaring multitplier
setupsqr: process (clk, reset, done, ds) is
begin
if reset = '1' then
root <= (others => '0');
modreg <= (others => '0');
elsif rising_edge(clk) then
if done = '1' then
if ds = '1' then
-- first time through, input is sampled only once
modreg <= inMod;
root <= indata;
end if;
-- after first time, square result is fed back to multiplier
else
root <= square;
end if;
end if;
 
end process setupsqr;
-- This process sets input values for the product multiplier
setupmult: process (clk, reset, done, ds) is
begin
if reset = '1' then
tempin <= (others => '0');
sqrin <= (others => '0');
modreg <= (others => '0');
elsif rising_edge(clk) then
if done = '1' then
if ds = '1' then
-- first time through, input is sampled only once
-- if the least significant bit of the exponent is '1' then we seed the
-- multiplier with the message value. Otherwise, we seed it with 1.
-- The square is set to 1, so the result of the first multiplication will be
-- either 1 or the initial message value
if inExp(0) = '1' then
tempin <= indata;
else
tempin(KEYSIZE-1 downto 1) <= (others => '0');
tempin(0) <= '1';
end if;
modreg <= inMod;
sqrin(KEYSIZE-1 downto 1) <= (others => '0');
sqrin(0) <= '1';
end if;
-- after first time, the multiplication and square results are fed back through the multiplier.
-- The counter (exponent) has been shifted one bit to the right
-- If the least significant bit of the exponent is '1' the result of the most recent
-- squaring operation is fed to the multiplier.
-- Otherwise, the square value is set to 1 to indicate no multiplication.
else
tempin <= tempout;
if count(0) = '1' then
sqrin <= square;
else
sqrin(KEYSIZE-1 downto 1) <= (others => '0');
sqrin(0) <= '1';
end if;
end if;
end if;
 
end process setupmult;
-- this process enables the multipliers when it is safe to do so
crypto: process (clk, reset, done, ds, count, bothrdy) is
begin
if reset = '1' then
multgo <= '0';
elsif rising_edge(clk) then
if done = '1' then
if ds = '1' then
-- first time through - automatically trigger first multiplier cycle
multgo <= '1';
end if;
-- after first time, trigger multipliers when both operations are complete
elsif count /= 0 then
if bothrdy = '1' then
multgo <= '1';
end if;
end if;
-- when multipliers have been started, disable multiplier inputs
if multgo = '1' then
multgo <= '0';
end if;
end if;
 
end process crypto;
 
end Behavioral;
/tags/initial/rtl/vhdl/Testmult.vhd
0,0 → 1,81
 
-- VHDL Test Bench Created from source file modmult32.vhd -- 18:42:57 05/04/2003
--
-- 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.numeric_std.ALL;
 
ENTITY testbench IS
END testbench;
 
ARCHITECTURE behavior OF testbench IS
 
COMPONENT modmult32
PORT(
mpand : IN std_logic_vector(31 downto 0);
mplier : IN std_logic_vector(31 downto 0);
modulus : IN std_logic_vector(31 downto 0);
clk : IN std_logic;
ds : IN std_logic;
reset : IN std_logic;
product : OUT std_logic_vector(31 downto 0);
ready : OUT std_logic
);
END COMPONENT;
 
SIGNAL mpand : std_logic_vector(31 downto 0);
SIGNAL mplier : std_logic_vector(31 downto 0);
SIGNAL modulus : std_logic_vector(31 downto 0);
SIGNAL product : std_logic_vector(31 downto 0);
SIGNAL clk : std_logic;
SIGNAL ds : std_logic;
SIGNAL reset : std_logic;
SIGNAL ready : std_logic;
 
BEGIN
 
uut: modmult32 PORT MAP(
mpand => mpand,
mplier => mplier,
modulus => modulus,
product => product,
clk => clk,
ds => ds,
reset => reset,
ready => ready
);
 
 
-- *** Test Bench - User Defined Section ***
tb : PROCESS
BEGIN
reset <= '1';
wait until clk = '1';
reset <= '0';
wait until clk = '0';
ds <= '1';
mpand <= x"00003285";
mplier <= x"00000015";
modulus <= x"00007f00";
wait; -- will wait forever
END PROCESS;
 
clkgen: process
begin
wait for 3 ns;
if clk = '1' then
clk <= '0';
else
clk <= '1';
end if;
end process;
-- *** End Test Bench - User Defined Section ***
 
END;
/tags/initial/rtl/vhdl/modmult.vhd
0,0 → 1,166
----------------------------------------------------------------------
---- ----
---- Modular Multiplier ----
---- RSA Public Key Cryptography IP Core ----
---- ----
---- This file is part of the BasicRSA project ----
---- http://www.opencores.org/ ----
---- ----
---- To Do: ----
---- - Speed and efficiency improvements ----
---- - Possible revisions for good engineering/coding practices ----
---- ----
---- Author(s): ----
---- - Steven R. McQueen, srmcqueen@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2003 Steven R. McQueen ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------
--
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
--
 
-- This module implements the modular multiplier for the RSA Public Key Cypher. It expects
-- to receive a multiplicand on th MPAND bus, a multiplier on the MPLIER bus, and a modulus
-- on the MODULUS bus. The multiplier and multiplicand must have a value less than the modulus.
--
-- A Shift-and-Add algorithm is used in this module. For each bit of the multiplier, the
-- multiplicand value is shifted. For each '1' bit of the multiplier, the shifted multiplicand
-- value is added to the product. To ensure that the product is always expressed as a remainder
-- two subtractions are performed on the product, P2 = P1-modulus, and P3 = P1-(2*modulus).
-- The high-order bits of these results are used to determine whether P sould be copied from
-- P1, P2, or P3.
--
-- The operation ends when all '1' bits in the multiplier have been used.
--
-- Comments, questions and suggestions may be directed to the author at srmcqueen@mcqueentech.com.
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity modmult is
Generic (MPWID: integer := 32);
Port ( mpand : in std_logic_vector(MPWID-1 downto 0);
mplier : in std_logic_vector(MPWID-1 downto 0);
modulus : in std_logic_vector(MPWID-1 downto 0);
product : out std_logic_vector(MPWID-1 downto 0);
clk : in std_logic;
ds : in std_logic;
reset : in std_logic;
ready : out std_logic);
end modmult;
 
architecture modmult1 of modmult is
 
signal mpreg: std_logic_vector(MPWID-1 downto 0);
signal mcreg, mcreg1, mcreg2: std_logic_vector(MPWID+1 downto 0);
signal modreg1, modreg2: std_logic_vector(MPWID+1 downto 0);
signal prodreg, prodreg1, prodreg2, prodreg3, prodreg4: std_logic_vector(MPWID+1 downto 0);
 
--signal count: integer;
signal modstate: std_logic_vector(1 downto 0);
signal first: std_logic;
 
begin
 
-- final result...
product <= prodreg4(MPWID-1 downto 0);
 
-- add shifted value if place bit is '1', copy original if place bit is '0'
with mpreg(0) select
prodreg1 <= prodreg + mcreg when '1',
prodreg when others;
 
-- subtract modulus and subtract modulus * 2.
prodreg2 <= prodreg1 - modreg1;
prodreg3 <= prodreg1 - modreg2;
 
-- negative results mean that we subtracted too much...
modstate <= prodreg3(mpwid+1) & prodreg2(mpwid+1);
-- select the correct modular result and copy it....
with modstate select
prodreg4 <= prodreg1 when "11",
prodreg2 when "10",
prodreg3 when others;
 
-- meanwhile, subtract the modulus from the shifted multiplicand...
mcreg1 <= mcreg - modreg1;
-- select the correct modular value and copy it.
with mcreg1(MPWID) select
mcreg2 <= mcreg when '1',
mcreg1 when others;
 
ready <= first;
 
combine: process (clk, first, ds, mpreg, reset) is
 
begin
if reset = '1' then
first <= '1';
elsif rising_edge(clk) then
if first = '1' then
-- First time through, set up registers to start multiplication procedure
-- Input values are sampled only once
if ds = '1' then
mpreg <= mplier;
mcreg <= "00" & mpand;
modreg1 <= "00" & modulus;
modreg2 <= '0' & modulus & '0';
prodreg <= (others => '0');
first <= '0';
end if;
else
-- when all bits have been shifted out of the multiplicand, operation is over
-- Note: this leads to at least one waste cycle per multiplication
if mpreg = 0 then
first <= '1';
else
-- shift the multiplicand left one bit
mcreg <= mcreg2(MPWID downto 0) & '0';
-- shift the multiplier right one bit
mpreg <= '0' & mpreg(MPWID-1 downto 1);
-- copy intermediate product
prodreg <= prodreg4;
end if;
end if;
end if;
 
end process combine;
 
end modmult1;
/tags/initial/rtl/vhdl/rsatest16.vhd
0,0 → 1,92
 
-- VHDL Test Bench Created from source file rsacypher.vhd -- 13:35:16 05/04/2003
--
-- 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.numeric_std.ALL;
 
ENTITY testbench IS
END testbench;
 
ARCHITECTURE behavior OF testbench IS
 
COMPONENT rsacypher
PORT(
indata : IN std_logic_vector(31 downto 0);
inexp : IN std_logic_vector(31 downto 0);
inmod : IN std_logic_vector(31 downto 0);
clk : IN std_logic;
ds : IN std_logic;
reset : IN std_logic;
cypher : OUT std_logic_vector(31 downto 0);
ready : OUT std_logic
);
END COMPONENT;
 
SIGNAL indata : std_logic_vector(31 downto 0);
SIGNAL inexp : std_logic_vector(31 downto 0);
SIGNAL inmod : std_logic_vector(31 downto 0);
SIGNAL cypher : std_logic_vector(31 downto 0);
SIGNAL clk : std_logic;
SIGNAL ds : std_logic;
SIGNAL reset : std_logic;
SIGNAL ready : std_logic;
 
BEGIN
 
uut: rsacypher PORT MAP(
indata => indata,
inexp => inexp,
inmod => inmod,
cypher => cypher,
clk => clk,
ds => ds,
reset => reset,
ready => ready
);
 
 
-- *** Test Bench - User Defined Section ***
TB: PROCESS
BEGIN
wait for 120ns;
reset <= '1';
ds <= '0';
wait for 20ns;
wait until clk = '0';
reset <= '0';
wait until clk = '1';
wait until clk = '0';
inexp <= x"00903ad9";
inmod <= x"03b2c159";
indata <= x"00724183";
wait until clk = '1';
wait for 2ns;
ds <= '1';
wait until ready = '0';
ds <= '0';
wait until ready = '1';
wait;
-- decrypt exponent inexp <= x"02d80e39";
END PROCESS;
 
 
ClkGen : PROCESS
BEGIN
wait for 5300ps; -- will wait forever
if clk = '1' then
clk <= '0';
else
clk <= '1';
end if;
END PROCESS;
-- *** End Test Bench - User Defined Section ***
 
END;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.