URL
https://opencores.org/ocsvn/BasicRSA/BasicRSA/trunk
Subversion Repositories BasicRSA
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 3 to Rev 4
- ↔ Reverse comparison
Rev 3 → Rev 4
/tags/initial/rtl/vhdl/rsatest16.vhd
File deleted
/tags/initial/rtl/vhdl/rsacypher.vhd
File deleted
/tags/initial/rtl/vhdl/modmult.vhd
File deleted
/tags/initial/rtl/vhdl/Testmult.vhd
File deleted
/trunk/rtl/vhdl/rsatest16.vhd
File deleted
/trunk/rtl/vhdl/rsacypher.vhd
File deleted
/trunk/rtl/vhdl/modmult.vhd
File deleted
/trunk/rtl/vhdl/Testmult.vhd
File deleted
/BasicRSA/trunk/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; |
/BasicRSA/trunk/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; |
/BasicRSA/trunk/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; |
/BasicRSA/trunk/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; |
BasicRSA/trunk
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: BasicRSA/branches
===================================================================
--- BasicRSA/branches (nonexistent)
+++ BasicRSA/branches (revision 4)
BasicRSA/branches
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: BasicRSA/tags/initial/rtl/vhdl/rsacypher.vhd
===================================================================
--- BasicRSA/tags/initial/rtl/vhdl/rsacypher.vhd (nonexistent)
+++ BasicRSA/tags/initial/rtl/vhdl/rsacypher.vhd (revision 4)
@@ -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;
Index: BasicRSA/tags/initial/rtl/vhdl/Testmult.vhd
===================================================================
--- BasicRSA/tags/initial/rtl/vhdl/Testmult.vhd (nonexistent)
+++ BasicRSA/tags/initial/rtl/vhdl/Testmult.vhd (revision 4)
@@ -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;
Index: BasicRSA/tags/initial/rtl/vhdl/modmult.vhd
===================================================================
--- BasicRSA/tags/initial/rtl/vhdl/modmult.vhd (nonexistent)
+++ BasicRSA/tags/initial/rtl/vhdl/modmult.vhd (revision 4)
@@ -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;
Index: BasicRSA/tags/initial/rtl/vhdl/rsatest16.vhd
===================================================================
--- BasicRSA/tags/initial/rtl/vhdl/rsatest16.vhd (nonexistent)
+++ BasicRSA/tags/initial/rtl/vhdl/rsatest16.vhd (revision 4)
@@ -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;
Index: BasicRSA/tags
===================================================================
--- BasicRSA/tags (nonexistent)
+++ BasicRSA/tags (revision 4)
BasicRSA/tags
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##