-- ---------------------------------------------------------------------- -- FILE: DESmedium.vhd -- DATE: 26 November 2000 -- AUTHOR: Antonio Esteves, GEC-DI-UM -- -- DES CORE. -- -- (c) 1999, The Free IP Project and David Kessner -- (c) 2000, Antonio Esteves, GEC-DI, University of Minho -- ----------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; package DESlib is -- Inital permutation function DESip(din :std_logic_vector(64 downto 1)) return std_logic_vector; -- Final permutation function DESfp(din :std_logic_vector(64 downto 1)) return std_logic_vector; -- Key permutation, converts a 64 bit key into a 56 bit key, -- ignoring parity function DESpc1(din :std_logic_vector (64 downto 1)) return std_logic_vector; -- Compression permutation, converts a 56 bit key into a 48 bits function DESpc2(din :std_logic_vector (56 downto 1)) return std_logic_vector; -- Expansion permutation function DESep(din :std_logic_vector (32 downto 1)) return std_logic_vector; -- S-Box substitution, 48 bits in, 32 bits out function DESsbox(din :std_logic_vector (47 downto 0)) return std_logic_vector; -- P-Box permutation function DESpbox(din :std_logic_vector (32 downto 1)) return std_logic_vector; -- Key shift function DESkeyLshift (din : std_logic_vector (55 downto 0); n : std_logic_vector ( 4 downto 0)) return std_logic_vector; function DESkeyRshift (din : std_logic_vector (55 downto 0); n : std_logic_vector ( 4 downto 0)) return std_logic_vector; end DESlib; -- ----------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library work; use work.DESlib.all; package body DESlib is -------------------------------------------------------- -- Inital permutation (IP) -------------------------------------------------------- function DESip ( din : std_logic_vector(64 downto 1) ) return std_logic_vector is variable val : std_logic_vector (64 downto 1); begin -- ----------------------- -- 58 50 42 34 26 18 10 2 -- 60 52 44 36 28 20 12 4 -- 62 54 46 38 30 22 14 6 -- 64 56 48 40 32 24 16 8 -- 57 49 41 33 25 17 9 1 -- 59 51 43 35 27 19 11 3 -- 61 53 45 37 29 21 13 5 -- 63 55 47 39 31 23 15 7 -- ----------------------- val := din(7 ) & din(15) & din(23) & din(31) & din(39) & din(47) & din(55) & din(63) & din(5 ) & din(13) & din(21) & din(29) & din(37) & din(45) & din(53) & din(61) & din(3 ) & din(11) & din(19) & din(27) & din(35) & din(43) & din(51) & din(59) & din(1 ) & din(9 ) & din(17) & din(25) & din(33) & din(41) & din(49) & din(57) & din(8 ) & din(16) & din(24) & din(32) & din(40) & din(48) & din(56) & din(64) & din(6 ) & din(14) & din(22) & din(30) & din(38) & din(46) & din(54) & din(62) & din(4 ) & din(12) & din(20) & din(28) & din(36) & din(44) & din(52) & din(60) & din(2 ) & din(10) & din(18) & din(26) & din(34) & din(42) & din(50) & din(58) ; return val; end DESip; -------------------------------------------------------- -- Final permutation (IP^(-1) or FP) -------------------------------------------------------- function DESfp( din : std_logic_vector(64 downto 1)) return std_logic_vector is variable val : std_logic_vector (64 downto 1); begin -- --------------------------- -- 40 8 48 16 56 24 64 32 -- 39 7 47 15 55 23 63 31 -- 38 6 46 14 54 22 62 30 -- 37 5 45 13 53 21 61 29 -- 36 4 44 12 52 20 60 28 -- 35 3 43 11 51 19 59 27 -- 34 2 42 10 50 18 58 26 -- 33 1 41 9 49 17 57 25 -- --------------------------- val := din(25) & din(57) & din(17) & din(49) & din(9 ) & din(41) & din(1 ) & din(33) & din(26) & din(58) & din(18) & din(50) & din(10) & din(42) & din(2 ) & din(34) & din(27) & din(59) & din(19) & din(51) & din(11) & din(43) & din(3 ) & din(35) & din(28) & din(60) & din(20) & din(52) & din(12) & din(44) & din(4 ) & din(36) & din(29) & din(61) & din(21) & din(53) & din(13) & din(45) & din(5 ) & din(37) & din(30) & din(62) & din(22) & din(54) & din(14) & din(46) & din(6 ) & din(38) & din(31) & din(63) & din(23) & din(55) & din(15) & din(47) & din(7 ) & din(39) & din(32) & din(64) & din(24) & din(56) & din(16) & din(48) & din(8 ) & din(40) ; return val; end DESfp; -------------------------------------------------------- -- Permutation choice 1 (PC1): converts a 64 bit key into a 56 bit key, -- ignoring parity -------------------------------------------------------- function DESpc1 ( din : std_logic_vector (64 downto 1)) return std_logic_vector is variable val : std_logic_vector (55 downto 0); begin -- --------------------------- -- 57 49 41 33 25 17 9 -- 1 58 50 42 34 26 18 -- 10 2 59 51 43 35 27 -- 19 11 3 60 52 44 36 -- 63 55 47 39 31 23 15 -- 7 62 54 46 38 30 22 -- 14 6 61 53 45 37 29 -- 21 13 5 28 20 12 4 -- --------------------------- val := din(4 ) & din(12) & din(20) & din(28) & din(5 ) & din(13) & din(21) & din(29) & din(37) & din(45) & din(53) & din(61) & din(6 ) & din(14) & din(22) & din(30) & din(38) & din(46) & din(54) & din(62) & din(7 ) & din(15) & din(23) & din(31) & din(39) & din(47) & din(55) & din(63) & din(36) & din(44) & din(52) & din(60) & din(3 ) & din(11) & din(19) & din(27) & din(35) & din(43) & din(51) & din(59) & din(2 ) & din(10) & din(18) & din(26) & din(34) & din(42) & din(50) & din(58) & din(1 ) & din(9 ) & din(17) & din(25) & din(33) & din(41) & din(49) & din(57); return val; end DESpc1; -------------------------------------------------------- -- Compression permutation (C-box) / Permutation choice 2 (PC2): -- converts a 56 bit key into a 48 bits -------------------------------------------------------- function DESpc2 ( din : std_logic_vector (56 downto 1)) return std_logic_vector is variable val : std_logic_vector (48 downto 1); begin -- --------------------------- -- 14 17 11 24 1 5 -- 3 28 15 6 21 10 -- 23 19 12 4 26 8 -- 16 7 27 20 13 2 -- 41 52 31 37 47 55 -- 30 40 51 45 33 48 -- 44 49 39 56 34 53 -- 46 42 50 36 29 32 -- --------------------------- val := din(32) & din(29) & din(36) & din(50) & din(42) & din(46) & din(53) & din(34) & din(56) & din(39) & din(49) & din(44) & din(48) & din(33) & din(45) & din(51) & din(40) & din(30) & din(55) & din(47) & din(37) & din(31) & din(52) & din(41) & din(2 ) & din(13) & din(20) & din(27) & din(7 ) & din(16) & din(8 ) & din(26) & din(4 ) & din(12) & din(19) & din(23) & din(10) & din(21) & din(6 ) & din(15) & din(28) & din(3 ) & din(5 ) & din(1 ) & din(24) & din(11) & din(17) & din(14) ; return val; end DESpc2; -------------------------------------------------------- -- E operator: expands a permutation from 32 to 48 bits -------------------------------------------------------- function DESep ( din : std_logic_vector (32 downto 1)) return std_logic_vector is variable val : std_logic_vector (48 downto 1); begin -- --------------------------- -- 32 1 2 3 4 5 -- 4 5 6 7 8 9 -- 8 9 10 11 12 13 -- 12 13 14 15 16 17 -- 16 17 18 19 20 21 -- 20 21 22 23 24 25 -- 24 25 26 27 28 29 -- 28 29 30 31 32 1 -- --------------------------- val := din(1 ) & din(32) & din(31) & din(30) & din(29) & din(28) & din(29) & din(28) & din(27) & din(26) & din(25) & din(24) & din(25) & din(24) & din(23) & din(22) & din(21) & din(20) & din(21) & din(20) & din(19) & din(18) & din(17) & din(16) & din(17) & din(16) & din(15) & din(14) & din(13) & din(12) & din(13) & din(12) & din(11) & din(10) & din(9 ) & din(8 ) & din(9 ) & din(8 ) & din(7 ) & din(6 ) & din(5 ) & din(4 ) & din(5 ) & din(4 ) & din(3 ) & din(2 ) & din(1 ) & din(32) ; return val; end DESep; ------------------------------------------------------------------------ -- Substitution tables (S-Box 1:8): -- all together have 48 bits input, 32 bits output ------------------------------------------------------------------------ function DESsbox ( din : std_logic_vector (47 downto 0)) return std_logic_vector is variable val : std_logic_vector (31 downto 0); begin -- SBOX 8 case din( 5 downto 0) is when "000000" => val(3 downto 0) := "1101"; when "000001" => val(3 downto 0) := "0001"; when "000010" => val(3 downto 0) := "0010"; when "000011" => val(3 downto 0) := "1111"; when "000100" => val(3 downto 0) := "1000"; when "000101" => val(3 downto 0) := "1101"; when "000110" => val(3 downto 0) := "0100"; when "000111" => val(3 downto 0) := "1000"; when "001000" => val(3 downto 0) := "0110"; when "001001" => val(3 downto 0) := "1010"; when "001010" => val(3 downto 0) := "1111"; when "001011" => val(3 downto 0) := "0011"; when "001100" => val(3 downto 0) := "1011"; when "001101" => val(3 downto 0) := "0111"; when "001110" => val(3 downto 0) := "0001"; when "001111" => val(3 downto 0) := "0100"; when "010000" => val(3 downto 0) := "1010"; when "010001" => val(3 downto 0) := "1100"; when "010010" => val(3 downto 0) := "1001"; when "010011" => val(3 downto 0) := "0101"; when "010100" => val(3 downto 0) := "0011"; when "010101" => val(3 downto 0) := "0110"; when "010110" => val(3 downto 0) := "1110"; when "010111" => val(3 downto 0) := "1011"; when "011000" => val(3 downto 0) := "0101"; when "011001" => val(3 downto 0) := "0000"; when "011010" => val(3 downto 0) := "0000"; when "011011" => val(3 downto 0) := "1110"; when "011100" => val(3 downto 0) := "1100"; when "011101" => val(3 downto 0) := "1001"; when "011110" => val(3 downto 0) := "0111"; when "011111" => val(3 downto 0) := "0010"; when "100000" => val(3 downto 0) := "0111"; when "100001" => val(3 downto 0) := "0010"; when "100010" => val(3 downto 0) := "1011"; when "100011" => val(3 downto 0) := "0001"; when "100100" => val(3 downto 0) := "0100"; when "100101" => val(3 downto 0) := "1110"; when "100110" => val(3 downto 0) := "0001"; when "100111" => val(3 downto 0) := "0111"; when "101000" => val(3 downto 0) := "1001"; when "101001" => val(3 downto 0) := "0100"; when "101010" => val(3 downto 0) := "1100"; when "101011" => val(3 downto 0) := "1010"; when "101100" => val(3 downto 0) := "1110"; when "101101" => val(3 downto 0) := "1000"; when "101110" => val(3 downto 0) := "0010"; when "101111" => val(3 downto 0) := "1101"; when "110000" => val(3 downto 0) := "0000"; when "110001" => val(3 downto 0) := "1111"; when "110010" => val(3 downto 0) := "0110"; when "110011" => val(3 downto 0) := "1100"; when "110100" => val(3 downto 0) := "1010"; when "110101" => val(3 downto 0) := "1001"; when "110110" => val(3 downto 0) := "1101"; when "110111" => val(3 downto 0) := "0000"; when "111000" => val(3 downto 0) := "1111"; when "111001" => val(3 downto 0) := "0011"; when "111010" => val(3 downto 0) := "0011"; when "111011" => val(3 downto 0) := "0101"; when "111100" => val(3 downto 0) := "0101"; when "111101" => val(3 downto 0) := "0110"; when "111110" => val(3 downto 0) := "1000"; when "111111" => val(3 downto 0) := "1011"; when others => val(3 downto 0) := "1011"; end case; -- SBOX 7 case din(11 downto 6) is when "000000" => val(7 downto 4) := "0100"; when "000001" => val(7 downto 4) := "1101"; when "000010" => val(7 downto 4) := "1011"; when "000011" => val(7 downto 4) := "0000"; when "000100" => val(7 downto 4) := "0010"; when "000101" => val(7 downto 4) := "1011"; when "000110" => val(7 downto 4) := "1110"; when "000111" => val(7 downto 4) := "0111"; when "001000" => val(7 downto 4) := "1111"; when "001001" => val(7 downto 4) := "0100"; when "001010" => val(7 downto 4) := "0000"; when "001011" => val(7 downto 4) := "1001"; when "001100" => val(7 downto 4) := "1000"; when "001101" => val(7 downto 4) := "0001"; when "001110" => val(7 downto 4) := "1101"; when "001111" => val(7 downto 4) := "1010"; when "010000" => val(7 downto 4) := "0011"; when "010001" => val(7 downto 4) := "1110"; when "010010" => val(7 downto 4) := "1100"; when "010011" => val(7 downto 4) := "0011"; when "010100" => val(7 downto 4) := "1001"; when "010101" => val(7 downto 4) := "0101"; when "010110" => val(7 downto 4) := "0111"; when "010111" => val(7 downto 4) := "1100"; when "011000" => val(7 downto 4) := "0101"; when "011001" => val(7 downto 4) := "0010"; when "011010" => val(7 downto 4) := "1010"; when "011011" => val(7 downto 4) := "1111"; when "011100" => val(7 downto 4) := "0110"; when "011101" => val(7 downto 4) := "1000"; when "011110" => val(7 downto 4) := "0001"; when "011111" => val(7 downto 4) := "0110"; when "100000" => val(7 downto 4) := "0001"; when "100001" => val(7 downto 4) := "0110"; when "100010" => val(7 downto 4) := "0100"; when "100011" => val(7 downto 4) := "1011"; when "100100" => val(7 downto 4) := "1011"; when "100101" => val(7 downto 4) := "1101"; when "100110" => val(7 downto 4) := "1101"; when "100111" => val(7 downto 4) := "1000"; when "101000" => val(7 downto 4) := "1100"; when "101001" => val(7 downto 4) := "0001"; when "101010" => val(7 downto 4) := "0011"; when "101011" => val(7 downto 4) := "0100"; when "101100" => val(7 downto 4) := "0111"; when "101101" => val(7 downto 4) := "1010"; when "101110" => val(7 downto 4) := "1110"; when "101111" => val(7 downto 4) := "0111"; when "110000" => val(7 downto 4) := "1010"; when "110001" => val(7 downto 4) := "1001"; when "110010" => val(7 downto 4) := "1111"; when "110011" => val(7 downto 4) := "0101"; when "110100" => val(7 downto 4) := "0110"; when "110101" => val(7 downto 4) := "0000"; when "110110" => val(7 downto 4) := "1000"; when "110111" => val(7 downto 4) := "1111"; when "111000" => val(7 downto 4) := "0000"; when "111001" => val(7 downto 4) := "1110"; when "111010" => val(7 downto 4) := "0101"; when "111011" => val(7 downto 4) := "0010"; when "111100" => val(7 downto 4) := "1001"; when "111101" => val(7 downto 4) := "0011"; when "111110" => val(7 downto 4) := "0010"; when "111111" => val(7 downto 4) := "1100"; when others => val(7 downto 4) := "1100"; end case; -- SBOX 6 case din(17 downto 12) is when "000000" => val(11 downto 8) := "1100"; when "000001" => val(11 downto 8) := "1010"; when "000010" => val(11 downto 8) := "0001"; when "000011" => val(11 downto 8) := "1111"; when "000100" => val(11 downto 8) := "1010"; when "000101" => val(11 downto 8) := "0100"; when "000110" => val(11 downto 8) := "1111"; when "000111" => val(11 downto 8) := "0010"; when "001000" => val(11 downto 8) := "1001"; when "001001" => val(11 downto 8) := "0111"; when "001010" => val(11 downto 8) := "0010"; when "001011" => val(11 downto 8) := "1100"; when "001100" => val(11 downto 8) := "0110"; when "001101" => val(11 downto 8) := "1001"; when "001110" => val(11 downto 8) := "1000"; when "001111" => val(11 downto 8) := "0101"; when "010000" => val(11 downto 8) := "0000"; when "010001" => val(11 downto 8) := "0110"; when "010010" => val(11 downto 8) := "1101"; when "010011" => val(11 downto 8) := "0001"; when "010100" => val(11 downto 8) := "0011"; when "010101" => val(11 downto 8) := "1101"; when "010110" => val(11 downto 8) := "0100"; when "010111" => val(11 downto 8) := "1110"; when "011000" => val(11 downto 8) := "1110"; when "011001" => val(11 downto 8) := "0000"; when "011010" => val(11 downto 8) := "0111"; when "011011" => val(11 downto 8) := "1011"; when "011100" => val(11 downto 8) := "0101"; when "011101" => val(11 downto 8) := "0011"; when "011110" => val(11 downto 8) := "1011"; when "011111" => val(11 downto 8) := "1000"; when "100000" => val(11 downto 8) := "1001"; when "100001" => val(11 downto 8) := "0100"; when "100010" => val(11 downto 8) := "1110"; when "100011" => val(11 downto 8) := "0011"; when "100100" => val(11 downto 8) := "1111"; when "100101" => val(11 downto 8) := "0010"; when "100110" => val(11 downto 8) := "0101"; when "100111" => val(11 downto 8) := "1100"; when "101000" => val(11 downto 8) := "0010"; when "101001" => val(11 downto 8) := "1001"; when "101010" => val(11 downto 8) := "1000"; when "101011" => val(11 downto 8) := "0101"; when "101100" => val(11 downto 8) := "1100"; when "101101" => val(11 downto 8) := "1111"; when "101110" => val(11 downto 8) := "0011"; when "101111" => val(11 downto 8) := "1010"; when "110000" => val(11 downto 8) := "0111"; when "110001" => val(11 downto 8) := "1011"; when "110010" => val(11 downto 8) := "0000"; when "110011" => val(11 downto 8) := "1110"; when "110100" => val(11 downto 8) := "0100"; when "110101" => val(11 downto 8) := "0001"; when "110110" => val(11 downto 8) := "1010"; when "110111" => val(11 downto 8) := "0111"; when "111000" => val(11 downto 8) := "0001"; when "111001" => val(11 downto 8) := "0110"; when "111010" => val(11 downto 8) := "1101"; when "111011" => val(11 downto 8) := "0000"; when "111100" => val(11 downto 8) := "1011"; when "111101" => val(11 downto 8) := "1000"; when "111110" => val(11 downto 8) := "0110"; when "111111" => val(11 downto 8) := "1101"; when others => val(11 downto 8) := "1101"; end case; -- SBOX 5 case din(23 downto 18) is when "000000" => val(15 downto 12) := "0010"; when "000001" => val(15 downto 12) := "1110"; when "000010" => val(15 downto 12) := "1100"; when "000011" => val(15 downto 12) := "1011"; when "000100" => val(15 downto 12) := "0100"; when "000101" => val(15 downto 12) := "0010"; when "000110" => val(15 downto 12) := "0001"; when "000111" => val(15 downto 12) := "1100"; when "001000" => val(15 downto 12) := "0111"; when "001001" => val(15 downto 12) := "0100"; when "001010" => val(15 downto 12) := "1010"; when "001011" => val(15 downto 12) := "0111"; when "001100" => val(15 downto 12) := "1011"; when "001101" => val(15 downto 12) := "1101"; when "001110" => val(15 downto 12) := "0110"; when "001111" => val(15 downto 12) := "0001"; when "010000" => val(15 downto 12) := "1000"; when "010001" => val(15 downto 12) := "0101"; when "010010" => val(15 downto 12) := "0101"; when "010011" => val(15 downto 12) := "0000"; when "010100" => val(15 downto 12) := "0011"; when "010101" => val(15 downto 12) := "1111"; when "010110" => val(15 downto 12) := "1111"; when "010111" => val(15 downto 12) := "1010"; when "011000" => val(15 downto 12) := "1101"; when "011001" => val(15 downto 12) := "0011"; when "011010" => val(15 downto 12) := "0000"; when "011011" => val(15 downto 12) := "1001"; when "011100" => val(15 downto 12) := "1110"; when "011101" => val(15 downto 12) := "1000"; when "011110" => val(15 downto 12) := "1001"; when "011111" => val(15 downto 12) := "0110"; when "100000" => val(15 downto 12) := "0100"; when "100001" => val(15 downto 12) := "1011"; when "100010" => val(15 downto 12) := "0010"; when "100011" => val(15 downto 12) := "1000"; when "100100" => val(15 downto 12) := "0001"; when "100101" => val(15 downto 12) := "1100"; when "100110" => val(15 downto 12) := "1011"; when "100111" => val(15 downto 12) := "0111"; when "101000" => val(15 downto 12) := "1010"; when "101001" => val(15 downto 12) := "0001"; when "101010" => val(15 downto 12) := "1101"; when "101011" => val(15 downto 12) := "1110"; when "101100" => val(15 downto 12) := "0111"; when "101101" => val(15 downto 12) := "0010"; when "101110" => val(15 downto 12) := "1000"; when "101111" => val(15 downto 12) := "1101"; when "110000" => val(15 downto 12) := "1111"; when "110001" => val(15 downto 12) := "0110"; when "110010" => val(15 downto 12) := "1001"; when "110011" => val(15 downto 12) := "1111"; when "110100" => val(15 downto 12) := "1100"; when "110101" => val(15 downto 12) := "0000"; when "110110" => val(15 downto 12) := "0101"; when "110111" => val(15 downto 12) := "1001"; when "111000" => val(15 downto 12) := "0110"; when "111001" => val(15 downto 12) := "1010"; when "111010" => val(15 downto 12) := "0011"; when "111011" => val(15 downto 12) := "0100"; when "111100" => val(15 downto 12) := "0000"; when "111101" => val(15 downto 12) := "0101"; when "111110" => val(15 downto 12) := "1110"; when "111111" => val(15 downto 12) := "0011"; when others => val(15 downto 12) := "0011"; end case; -- SBOX 4 case din(29 downto 24) is when "000000" => val(19 downto 16) := "0111"; when "000001" => val(19 downto 16) := "1101"; when "000010" => val(19 downto 16) := "1101"; when "000011" => val(19 downto 16) := "1000"; when "000100" => val(19 downto 16) := "1110"; when "000101" => val(19 downto 16) := "1011"; when "000110" => val(19 downto 16) := "0011"; when "000111" => val(19 downto 16) := "0101"; when "001000" => val(19 downto 16) := "0000"; when "001001" => val(19 downto 16) := "0110"; when "001010" => val(19 downto 16) := "0110"; when "001011" => val(19 downto 16) := "1111"; when "001100" => val(19 downto 16) := "1001"; when "001101" => val(19 downto 16) := "0000"; when "001110" => val(19 downto 16) := "1010"; when "001111" => val(19 downto 16) := "0011"; when "010000" => val(19 downto 16) := "0001"; when "010001" => val(19 downto 16) := "0100"; when "010010" => val(19 downto 16) := "0010"; when "010011" => val(19 downto 16) := "0111"; when "010100" => val(19 downto 16) := "1000"; when "010101" => val(19 downto 16) := "0010"; when "010110" => val(19 downto 16) := "0101"; when "010111" => val(19 downto 16) := "1100"; when "011000" => val(19 downto 16) := "1011"; when "011001" => val(19 downto 16) := "0001"; when "011010" => val(19 downto 16) := "1100"; when "011011" => val(19 downto 16) := "1010"; when "011100" => val(19 downto 16) := "0100"; when "011101" => val(19 downto 16) := "1110"; when "011110" => val(19 downto 16) := "1111"; when "011111" => val(19 downto 16) := "1001"; when "100000" => val(19 downto 16) := "1010"; when "100001" => val(19 downto 16) := "0011"; when "100010" => val(19 downto 16) := "0110"; when "100011" => val(19 downto 16) := "1111"; when "100100" => val(19 downto 16) := "1001"; when "100101" => val(19 downto 16) := "0000"; when "100110" => val(19 downto 16) := "0000"; when "100111" => val(19 downto 16) := "0110"; when "101000" => val(19 downto 16) := "1100"; when "101001" => val(19 downto 16) := "1010"; when "101010" => val(19 downto 16) := "1011"; when "101011" => val(19 downto 16) := "0001"; when "101100" => val(19 downto 16) := "0111"; when "101101" => val(19 downto 16) := "1101"; when "101110" => val(19 downto 16) := "1101"; when "101111" => val(19 downto 16) := "1000"; when "110000" => val(19 downto 16) := "1111"; when "110001" => val(19 downto 16) := "1001"; when "110010" => val(19 downto 16) := "0001"; when "110011" => val(19 downto 16) := "0100"; when "110100" => val(19 downto 16) := "0011"; when "110101" => val(19 downto 16) := "0101"; when "110110" => val(19 downto 16) := "1110"; when "110111" => val(19 downto 16) := "1011"; when "111000" => val(19 downto 16) := "0101"; when "111001" => val(19 downto 16) := "1100"; when "111010" => val(19 downto 16) := "0010"; when "111011" => val(19 downto 16) := "0111"; when "111100" => val(19 downto 16) := "1000"; when "111101" => val(19 downto 16) := "0010"; when "111110" => val(19 downto 16) := "0100"; when "111111" => val(19 downto 16) := "1110"; when others => val(19 downto 16) := "1110"; end case; -- SBOX 3 case din(35 downto 30) is when "000000" => val(23 downto 20) := "1010"; when "000001" => val(23 downto 20) := "1101"; when "000010" => val(23 downto 20) := "0000"; when "000011" => val(23 downto 20) := "0111"; when "000100" => val(23 downto 20) := "1001"; when "000101" => val(23 downto 20) := "0000"; when "000110" => val(23 downto 20) := "1110"; when "000111" => val(23 downto 20) := "1001"; when "001000" => val(23 downto 20) := "0110"; when "001001" => val(23 downto 20) := "0011"; when "001010" => val(23 downto 20) := "0011"; when "001011" => val(23 downto 20) := "0100"; when "001100" => val(23 downto 20) := "1111"; when "001101" => val(23 downto 20) := "0110"; when "001110" => val(23 downto 20) := "0101"; when "001111" => val(23 downto 20) := "1010"; when "010000" => val(23 downto 20) := "0001"; when "010001" => val(23 downto 20) := "0010"; when "010010" => val(23 downto 20) := "1101"; when "010011" => val(23 downto 20) := "1000"; when "010100" => val(23 downto 20) := "1100"; when "010101" => val(23 downto 20) := "0101"; when "010110" => val(23 downto 20) := "0111"; when "010111" => val(23 downto 20) := "1110"; when "011000" => val(23 downto 20) := "1011"; when "011001" => val(23 downto 20) := "1100"; when "011010" => val(23 downto 20) := "0100"; when "011011" => val(23 downto 20) := "1011"; when "011100" => val(23 downto 20) := "0010"; when "011101" => val(23 downto 20) := "1111"; when "011110" => val(23 downto 20) := "1000"; when "011111" => val(23 downto 20) := "0001"; when "100000" => val(23 downto 20) := "1101"; when "100001" => val(23 downto 20) := "0001"; when "100010" => val(23 downto 20) := "0110"; when "100011" => val(23 downto 20) := "1010"; when "100100" => val(23 downto 20) := "0100"; when "100101" => val(23 downto 20) := "1101"; when "100110" => val(23 downto 20) := "1001"; when "100111" => val(23 downto 20) := "0000"; when "101000" => val(23 downto 20) := "1000"; when "101001" => val(23 downto 20) := "0110"; when "101010" => val(23 downto 20) := "1111"; when "101011" => val(23 downto 20) := "1001"; when "101100" => val(23 downto 20) := "0011"; when "101101" => val(23 downto 20) := "1000"; when "101110" => val(23 downto 20) := "0000"; when "101111" => val(23 downto 20) := "0111"; when "110000" => val(23 downto 20) := "1011"; when "110001" => val(23 downto 20) := "0100"; when "110010" => val(23 downto 20) := "0001"; when "110011" => val(23 downto 20) := "1111"; when "110100" => val(23 downto 20) := "0010"; when "110101" => val(23 downto 20) := "1110"; when "110110" => val(23 downto 20) := "1100"; when "110111" => val(23 downto 20) := "0011"; when "111000" => val(23 downto 20) := "0101"; when "111001" => val(23 downto 20) := "1011"; when "111010" => val(23 downto 20) := "1010"; when "111011" => val(23 downto 20) := "0101"; when "111100" => val(23 downto 20) := "1110"; when "111101" => val(23 downto 20) := "0010"; when "111110" => val(23 downto 20) := "0111"; when "111111" => val(23 downto 20) := "1100"; when others => val(23 downto 20) := "1100"; end case; -- SBOX 2 case din(41 downto 36) is when "000000" => val(27 downto 24) := "1111"; when "000001" => val(27 downto 24) := "0011"; when "000010" => val(27 downto 24) := "0001"; when "000011" => val(27 downto 24) := "1101"; when "000100" => val(27 downto 24) := "1000"; when "000101" => val(27 downto 24) := "0100"; when "000110" => val(27 downto 24) := "1110"; when "000111" => val(27 downto 24) := "0111"; when "001000" => val(27 downto 24) := "0110"; when "001001" => val(27 downto 24) := "1111"; when "001010" => val(27 downto 24) := "1011"; when "001011" => val(27 downto 24) := "0010"; when "001100" => val(27 downto 24) := "0011"; when "001101" => val(27 downto 24) := "1000"; when "001110" => val(27 downto 24) := "0100"; when "001111" => val(27 downto 24) := "1110"; when "010000" => val(27 downto 24) := "1001"; when "010001" => val(27 downto 24) := "1100"; when "010010" => val(27 downto 24) := "0111"; when "010011" => val(27 downto 24) := "0000"; when "010100" => val(27 downto 24) := "0010"; when "010101" => val(27 downto 24) := "0001"; when "010110" => val(27 downto 24) := "1101"; when "010111" => val(27 downto 24) := "1010"; when "011000" => val(27 downto 24) := "1100"; when "011001" => val(27 downto 24) := "0110"; when "011010" => val(27 downto 24) := "0000"; when "011011" => val(27 downto 24) := "1001"; when "011100" => val(27 downto 24) := "0101"; when "011101" => val(27 downto 24) := "1011"; when "011110" => val(27 downto 24) := "1010"; when "011111" => val(27 downto 24) := "0101"; when "100000" => val(27 downto 24) := "0000"; when "100001" => val(27 downto 24) := "1101"; when "100010" => val(27 downto 24) := "1110"; when "100011" => val(27 downto 24) := "1000"; when "100100" => val(27 downto 24) := "0111"; when "100101" => val(27 downto 24) := "1010"; when "100110" => val(27 downto 24) := "1011"; when "100111" => val(27 downto 24) := "0001"; when "101000" => val(27 downto 24) := "1010"; when "101001" => val(27 downto 24) := "0011"; when "101010" => val(27 downto 24) := "0100"; when "101011" => val(27 downto 24) := "1111"; when "101100" => val(27 downto 24) := "1101"; when "101101" => val(27 downto 24) := "0100"; when "101110" => val(27 downto 24) := "0001"; when "101111" => val(27 downto 24) := "0010"; when "110000" => val(27 downto 24) := "0101"; when "110001" => val(27 downto 24) := "1011"; when "110010" => val(27 downto 24) := "1000"; when "110011" => val(27 downto 24) := "0110"; when "110100" => val(27 downto 24) := "1100"; when "110101" => val(27 downto 24) := "0111"; when "110110" => val(27 downto 24) := "0110"; when "110111" => val(27 downto 24) := "1100"; when "111000" => val(27 downto 24) := "1001"; when "111001" => val(27 downto 24) := "0000"; when "111010" => val(27 downto 24) := "0011"; when "111011" => val(27 downto 24) := "0101"; when "111100" => val(27 downto 24) := "0010"; when "111101" => val(27 downto 24) := "1110"; when "111110" => val(27 downto 24) := "1111"; when "111111" => val(27 downto 24) := "1001"; when others => val(27 downto 24) := "1001"; end case; -- SBOX 1 case din(47 downto 42) is when "000000" => val(31 downto 28) := "1110"; when "000001" => val(31 downto 28) := "0000"; when "000010" => val(31 downto 28) := "0100"; when "000011" => val(31 downto 28) := "1111"; when "000100" => val(31 downto 28) := "1101"; when "000101" => val(31 downto 28) := "0111"; when "000110" => val(31 downto 28) := "0001"; when "000111" => val(31 downto 28) := "0100"; when "001000" => val(31 downto 28) := "0010"; when "001001" => val(31 downto 28) := "1110"; when "001010" => val(31 downto 28) := "1111"; when "001011" => val(31 downto 28) := "0010"; when "001100" => val(31 downto 28) := "1011"; when "001101" => val(31 downto 28) := "1101"; when "001110" => val(31 downto 28) := "1000"; when "001111" => val(31 downto 28) := "0001"; when "010000" => val(31 downto 28) := "0011"; when "010001" => val(31 downto 28) := "1010"; when "010010" => val(31 downto 28) := "1010"; when "010011" => val(31 downto 28) := "0110"; when "010100" => val(31 downto 28) := "0110"; when "010101" => val(31 downto 28) := "1100"; when "010110" => val(31 downto 28) := "1100"; when "010111" => val(31 downto 28) := "1011"; when "011000" => val(31 downto 28) := "0101"; when "011001" => val(31 downto 28) := "1001"; when "011010" => val(31 downto 28) := "1001"; when "011011" => val(31 downto 28) := "0101"; when "011100" => val(31 downto 28) := "0000"; when "011101" => val(31 downto 28) := "0011"; when "011110" => val(31 downto 28) := "0111"; when "011111" => val(31 downto 28) := "1000"; when "100000" => val(31 downto 28) := "0100"; when "100001" => val(31 downto 28) := "1111"; when "100010" => val(31 downto 28) := "0001"; when "100011" => val(31 downto 28) := "1100"; when "100100" => val(31 downto 28) := "1110"; when "100101" => val(31 downto 28) := "1000"; when "100110" => val(31 downto 28) := "1000"; when "100111" => val(31 downto 28) := "0010"; when "101000" => val(31 downto 28) := "1101"; when "101001" => val(31 downto 28) := "0100"; when "101010" => val(31 downto 28) := "0110"; when "101011" => val(31 downto 28) := "1001"; when "101100" => val(31 downto 28) := "0010"; when "101101" => val(31 downto 28) := "0001"; when "101110" => val(31 downto 28) := "1011"; when "101111" => val(31 downto 28) := "0111"; when "110000" => val(31 downto 28) := "1111"; when "110001" => val(31 downto 28) := "0101"; when "110010" => val(31 downto 28) := "1100"; when "110011" => val(31 downto 28) := "1011"; when "110100" => val(31 downto 28) := "1001"; when "110101" => val(31 downto 28) := "0011"; when "110110" => val(31 downto 28) := "0111"; when "110111" => val(31 downto 28) := "1110"; when "111000" => val(31 downto 28) := "0011"; when "111001" => val(31 downto 28) := "1010"; when "111010" => val(31 downto 28) := "1010"; when "111011" => val(31 downto 28) := "0000"; when "111100" => val(31 downto 28) := "0101"; when "111101" => val(31 downto 28) := "0110"; when "111110" => val(31 downto 28) := "0000"; when "111111" => val(31 downto 28) := "1101"; when others => val(31 downto 28) := "1101"; end case; return val; end DESsbox; -------------------------------------------------------- -- Permutation P (P-Box) -------------------------------------------------------- function DESpbox ( din : std_logic_vector (32 downto 1)) return std_logic_vector is variable val : std_logic_vector (32 downto 1); begin -- --------------------------- -- 16 7 20 21 -- 29 12 28 17 -- 1 15 23 26 -- 5 18 31 10 -- 2 8 24 14 -- 32 27 3 9 -- 19 13 30 6 -- 22 11 4 25 -- --------------------------- val := din(25) & din(4 ) & din(11) & din(22) & din(6 ) & din(30) & din(13) & din(19) & din(9 ) & din(3 ) & din(27) & din(32) & din(14) & din(24) & din(8 ) & din(2 ) & din(10) & din(31) & din(18) & din(5 ) & din(26) & din(23) & din(15) & din(1 ) & din(17) & din(28) & din(12) & din(29) & din(21) & din(20) & din(7 ) & din(16) ; return val; end DESpbox; ------------------------------------------------------------------------ -- Key left shift: left shifts the key "din" by the amount "n" ------------------------------------------------------------------------ function DESkeyLshift ( din : std_logic_vector (55 downto 0) ; n : std_logic_vector ( 4 downto 0) ) return std_logic_vector is variable val : std_logic_vector (55 downto 0); begin case n is when "00000" => val := din(55 downto 28) & din(27 downto 0) ; when "00001" => val := din(54 downto 28) & din (55) & din(26 downto 0) & din (27) ; when "00010" => val := din(53 downto 28) & din (55 downto 54) & din(25 downto 0) & din (27 downto 26) ; when others => val := din ; end case; return val; end DESkeyLshift; ------------------------------------------------------------------------ -- Key right shift: right shifts the key "din" by the amount "n" ------------------------------------------------------------------------ function DESkeyRshift ( din : std_logic_vector (55 downto 0) ; n : std_logic_vector ( 4 downto 0) ) return std_logic_vector is variable val : std_logic_vector (55 downto 0); begin case n is when "00000" => val := din(55 downto 28) & din(27 downto 0); when "00001" => val := din (28) & din(55 downto 29) & din (0) & din(27 downto 1) ; when "00010" => val := din (29 downto 28) & din(55 downto 30) & din(1 downto 0) & din(27 downto 2) ; when others => val := din; end case; return val; end DESkeyRshift; end DESlib; -- -----------------------------------------------------------------------