URL
https://opencores.org/ocsvn/cryptography/cryptography/trunk
Subversion Repositories cryptography
[/] [cryptography/] [trunk/] [encryption/] [encry.vhd.bak] - Rev 4
Compare with Previous | Blame | View Log
----------------------------------------------------------------------------------
-- Description:Implements the RC6 encryption algorithm.
-- Everything based on a positive edge of clock and
-- an asynchronous reset.
--
-- Module contains two finite state machines.
--
-- One fsm controls the calculation of the various
-- rounds. Another fsm is responsible for outputting
-- the ciphertext so the encryptor can accept plain
-- text while cipher text is still in the process of
-- going out.
--
-- We assume the number of rounds to be 20.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- encryptor module declaration
entity encryptor is
port (
plaintext_e :in std_logic_vector(15 downto 0);-- 16 bit Plaintext output of decryptor
round_keyse :in std_logic_vector(15 downto 0);-- 16 bit roundkeys given to decryptor
start_e:in std_logic; --1 bit ready signal for encryptor
reset :in std_logic; --reset
clock :in std_logic ; --clock
ready_e :out std_logic; -- 1 bit ready output of decryptor
ciphertext: out std_logic_vector(15 downto 0)-- 16 bit ciphertext input to decrytpor which is output of encryptor
);
end encryptor;
Architecture arch_encryptor of encryptor is
-------wallace tree
component multiplier
port( B :in std_logic_vector(15 downto 0);
Product :out std_logic_vector(15 downto 0)
);
end component;
-------- constant for key generation.
constant p:std_logic_vector(15 downto 0):= "1011011111100001";------constant value p
constant q:std_logic_vector(15 downto 0):= "1001111000110111";------constant value q
type s_tp is array(43 downto 0) of std_logic_vector(15 downto 0);--array of 44 * 16
signal s :s_tp;
type l_tp is array(42 downto 0) of std_logic_vector(15 downto 0);--array of 43 *16
signal l :l_tp;
--------- constants for the plain text fsm
constant out_idle:std_logic_vector(3 downto 0):= "0000";
constant out_A :std_logic_vector(3 downto 0):= "0001";
constant out_B :std_logic_vector(3 downto 0):= "0010";
constant out_C :std_logic_vector(3 downto 0):= "0011";
constant out_D :std_logic_vector(3 downto 0):= "0100";
--------- signals needed for internal connections
signal cleanup_A,cleanup_C ,start_d1,last_round: std_logic;
signal next_state_out: std_logic_vector( 3 downto 0);
signal state:std_logic_vector(5 downto 0); --state of primary fsm
signal state_out:std_logic_vector(3 downto 0); -- state of plaintext fsm
signal utemp1,ttemp1:std_logic_vector(15 downto 0);
signal sig3,sig4:INTEGER RANGE 0 TO 15;
signal A_final,B_final,C_final,D_final:std_logic_vector(15 downto 0);
signal product1,product2 : std_logic_vector(15 downto 0);
begin
sig3<=conv_integer(unsigned(utemp1(3 downto 0)));
sig4<=conv_integer(unsigned(ttemp1(3 downto 0)));
--------key generation operation------
s(0) <= P ; -- initialize constant array
l(0)<=(round_keyse +s(0));
s(1)<=(l(0)+ s(0)+ q);
l(1)<=( l(0)+s(1));
s(2)<=(l(1)+ s(1)+ q);
l(2)<=( l(1)+s(2));
s(3)<=(l(2)+ s(2)+ q);
l(3)<=( l(2)+s(3));
s(4)<=(l(3)+ s(3)+ q);
l(4)<=( l(3)+s(4));
s(5)<=(l(4)+ s(4)+ q);
l(5)<=( l(4)+s(5));
s(6)<=(l(5)+ s(5)+ q);
l(6)<=( l(5)+s(6));
s(7)<=(l(6)+ s(6)+ q);
l(7)<=( l(6)+s(7));
s(8)<=(l(7)+ s(7)+ q);
l(8)<=( l(7)+s(8));
s(9)<=(l(8)+s(8)+ q);
l(9)<=( l(8)+s(9));
s(10)<=(l(9)+s(9)+ q);
l(10)<=( l(9)+s(10 ));
s(11)<=(l(10)+s(10)+ q);
l(11)<=( l(10)+s(11));
s(12)<=(l(11)+ s(11)+ q);
l(12)<=( l(11)+s(12));
s(13)<=(l(12)+s(12)+ q);
l(13)<=( l(12)+s(13));
s(14)<=(l(13)+ s(13)+ q);
l(14)<=( l(13)+s(14));
s(15)<=(l(14)+ s(14)+ q);
l(15)<=( l(14)+s(15));
s(16)<=(l(15)+ s(15)+ q);
l(16)<=( l(15)+s(16));
s(17)<=(l(16)+ s(16)+ q);
l(17)<=( l(16)+s(17));
s(18)<=(l(17)+ s(17)+ q);
l(18)<=( l(17)+s(18));
s(19)<=(l(18)+ s(18)+ q);
l(19)<=( l(18)+s(19));
s(20)<=(l(19)+ s(19)+ q);
l(20)<=( l(19)+s(20));
s(21)<=(l(20)+ s(20)+ q);
l(21)<=( l(20)+s(21));
s(22)<=(l(21)+ s(21)+ q);
l(22)<=( l(21)+s(22));
s(23)<=(l(22)+ s(22)+ q);
l(23)<=( l(22)+s(23));
s(24)<=(l(23)+ s(23)+ q);
l(24)<=( l(23)+s(24));
s(25)<=(l(24)+ s(24)+ q);
l(25)<=( l(24)+s(25));
s(26)<=(l(25)+ s(25)+ q);
l(26)<=( l(25)+s(26));
s(27)<=(l(26)+ s(26)+ q);
l(27)<=( l(26)+s(27));
s(28)<=(l(27)+ s(27)+ q);
l(28)<=( l(27)+s(28));
s(29)<=(l(28)+ s(28)+ q);
l(29)<=( l(23)+s(24));
s(30)<=(l(29)+ s(29)+ q);
l(30)<=( l(29)+s(30));
s(31)<=(l(30)+ s(30)+ q);
l(31)<=( l(30)+s(31));
s(32)<=(l(31)+ s(31)+ q);
l(32)<=( l(31)+s(32));
s(33)<=(l(32)+ s(32)+ q);
l(33)<=( l(32)+s(33));
s(34)<=(l(33)+ s(33)+ q);
l(34)<=( l(33)+s(34));
s(35)<=(l(34)+ s(34)+ q);
l(35)<=( l(34)+s(35));
s(36)<=(l(35)+ s(35)+ q);
l(36)<=( l(35)+s(36));
s(37)<=(l(36)+ s(36)+ q);
l(37)<=( l(36)+s(37));
s(38)<=(l(37)+ s(37)+ q);
l(38)<=( l(37)+s(38));
s(39)<=(l(38)+ s(38)+ q);
l(39)<=( l(33)+s(34));
s(40)<=(l(39)+ s(39)+ q);
l(40)<=( l(39)+s(40));
s(40)<=(l(39)+ s(39)+ q);
l(41)<=( l(40)+s(40));
s(41)<=(l(40)+ s(40)+ q);
l(42)<=( l(41)+s(41));
s(42)<=(l(41)+ s(41)+ q);
s(43)<=(l(42)+ s(42)+ q);
--------fsm for input --------
process(clock,reset,plaintext_e,sig3,sig4)
-----internal variable declaration
variable A,B,C,D,t_pre,u_pre:std_logic_vector(15 downto 0);
VARIABLE t,u,A_temp2,C_temp2,A_temp1,C_temp1:std_logic_vector( 15 downto 0);
variable tempA,tempB,tempC,tempD :std_logic_vector(15 downto 0);
variable temp_AB,temp_BC,temp_CD,temp_DA :std_logic_vector(15 downto 0);
variable cnt: std_logic_vector(6 downto 0):="0000000";
begin
if (reset='1') then
state <= "000001"; -- reset state
ready_e <= '0';
cnt:=(others=>'0');
A := (others=>'0');
B := (others=>'0');
C := (others=>'0');
D := (others=>'0');
ready_e <= '0';
elsif(clock'event and clock='1') then
case state is --synopsys parallel_case
when"000001"=>
if (start_e = '0') then
state <= "000001";
else
state <= "000010";
ready_e <= '1';
end if;
when "000010"=>
state <= "000011";
A := plaintext_e;--read ciphertext into A
ready_e <= '0';
when "000011"=>
state <= "000100";
B := plaintext_e; -- read ciphertext into B
ready_e <= '0';
when "000100"=>
state <= "000101";
C := plaintext_e ; -- read ciphertext - into C
B := B+ s(0) ;-- Use round keys to calculate new value of B
ready_e<= '0';
when "000101"=>
state <= "000110";
D := plaintext_e;--assign ciphertext to D
ready_e <= '0';
when "000110"=> -- begin calculation of plaintext loop from r downto 1
state<= "000111" ;
D := D + s(1); -- Use round keys to calculate new value of D
ready_e <='0';
when "000111" =>
STATE <="001000";
--t= (B * (2B+1))
t_pre := product1;
--t= (D * (2D+1))
u_pre := product2;
t:= t_pre(11 downto 0)& t_pre(15 downto 12);
ttemp1<=t;
--t= (B * (2B+1)) <<<4
u:= u_pre(11 downto 0)& u_pre(15 downto 12);
utemp1<=u;
--u= (D * (2D+1)) <<<4
A_temp1 := (A xor t);
C_temp1 := (C xor u);
when "001000" =>
state <="001001" ;
A_temp2:=A_temp1(15-sig3 downto 0)& A_temp1(15 downto 15-sig3+1);
---rotate (A xor t) << u
C_temp2:=C_temp1(15-sig4 downto 0)& C_temp1(15 downto 15-sig4+1);
---rotate (c xor u) << t
for i in 1 to 20 loop
A := (A_temp2 + s(2*i));
C := (C_temp2 + s(2*i+1));
end loop;
when "001001"=>
state <="001010";
-------swap operation---------
TEMPA:=A;
TEMPB:=B;
TEMPC:=C;
TEMPD:=D;
temp_AB:= tempA xor tempB;
A:= temp_AB xor tempA;
temp_BC:= tempB xor tempC;
B:= temp_BC xor tempB;
temp_CD:= tempC xor tempD;
C:= temp_CD xor tempC;
temp_DA:= tempD xor tempA;
D:= temp_DA xor tempD;
ready_e <= '0';
WHEN "001010" =>
------start counter------
if(cnt<19)then
cnt:=cnt+1 ;
state <="000111";
else
state<="001011";
cnt:="0000000" ;
last_round <='1';
end if;
when "001011" =>
state <= "001100";
if (last_round ='1') then
-- calculate last A value
cleanup_A <= '1';
-- calculate last C value
cleanup_C <= '1';
else
cleanup_A <= '0';
cleanup_C <= '0';
end if;
when "001100" =>
state <= "000001";
--rounds are over
--now do the cleanup
if (cleanup_A='1') then
A_final <= A + s(42); --A_temp2 + round_keys_e_saved;
B_final <= B;--B_temp2;
D_final <= D;--D_temp2;
else
A_final <= A_final;
B_final <= B_final;
D_final <= D_final;
end if;
if (cleanup_C='1') then
C_final <= C + s(43);
start_d1 <= '1';
else
C_final <= C_final;
start_d1 <= '0';
end if;
when others =>
state <="000001" ;
end case;
end if;
end process;
-- current state logic for output FSM
process(clock,reset )
begin
-- if reset stay idle
-- else output based on
--state
if (reset='1') then
state_out <= out_idle;
elsif(clock'event and clock='1') then
state_out <= next_state_out;
end if;
end process;
-- next state, output logic for output FSM
process(state_out,start_d1,A_final,B_final,C_final,D_final)
begin
case state_out is --synopsys parallel_case
when out_idle=>
-- wait for start_d
if (start_d1='1') then
next_state_out <= out_A;
else
next_state_out <= out_idle;
ciphertext <= (others=>'0');
end if;
when out_A=>
next_state_out <= out_B;
-- output A
ciphertext <= A_final;----------ouput cipher text 1
when out_B=>
next_state_out <= out_C;
-- output B
ciphertext <= B_final;----------ouput cipher text 2
when out_C=>
next_state_out <= out_D;
-- output C
ciphertext <= C_final;----------ouput cipher text 3
when out_D=>
next_state_out <= out_idle;
-- output D
ciphertext <= D_final;----------ouput cipher text 4
when others=>
next_state_out <= out_idle;
ciphertext <= (others=>'0');
end case;
-----------------------complete output come after 93 clock---------------------
end process;
end arch_encryptor ;