diff --git a/128_192_256_enc_dec/aes.vhd b/128_192_256_enc_dec/aes.vhd new file mode 100644 index 0000000..4aaafea --- /dev/null +++ b/128_192_256_enc_dec/aes.vhd @@ -0,0 +1,35 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity AES is +port ( ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic; + mode: in std_logic; + version: in std_logic_vector(1 downto 0) + ); +end entity; + +architecture Behavioral of AES is + + -- pipeline related signals + signal state_exit_bit, last_rnd : std_logic; + signal round, round_key : std_logic_vector(3 downto 0); + signal count : std_logic_vector(6 downto 0); + signal count_key : std_logic_vector(7 downto 0); + +begin + + ct <= state_exit_bit; + + data_pipeline0: entity data_pipeline (Behavioral) port map(state_exit_bit, clk, round, count, round_key, count_key, mode, version, pt, key, last_rnd); + controller0: entity controller (Behavioral) port map(round, count, round_key, count_key, done, last_rnd, clk, rst, version); + +end architecture; diff --git a/128_192_256_enc_dec/controller.vhd b/128_192_256_enc_dec/controller.vhd new file mode 100644 index 0000000..df786ba --- /dev/null +++ b/128_192_256_enc_dec/controller.vhd @@ -0,0 +1,99 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity controller is +port ( + round: out std_logic_vector(3 downto 0); + count: out std_logic_vector(6 downto 0); + round_key: out std_logic_vector(3 downto 0); + count_key: out std_logic_vector(7 downto 0); + done: out std_logic; + last_rnd: out std_logic; + clk: in std_logic; + rst: in std_logic; + version: in std_logic_vector(1 downto 0) + ); +end entity; + +architecture Behavioral of controller is + + signal cnt_p : integer range 0 to 127; + signal rnd_p : integer range 0 to 15; + + signal cnt_key_p, cnt_key_n : integer range 0 to 255; + signal rnd_key_p, rnd_key_n : integer range 0 to 15; + + +begin + + -- We should prefer synchronous rst signal + -- it helps when we want to later use it in AEAD circuits + + process (clk) + begin + if rising_edge(clk) then + cnt_key_p <= cnt_key_n; + rnd_key_p <= rnd_key_n; + end if; + end process; + + done <= '1' when cnt_p = 127 and ((version="00" and rnd_p = 9) or (version="01" and rnd_p = 11) or (version="10" and rnd_p = 13)) else '0'; + last_rnd <= '1' when (version="00" and rnd_p = 10) or (version="01" and rnd_p = 12) or (version="10" and rnd_p = 14) else '0'; + + process (rst, version, cnt_key_p, rnd_key_p) + begin + + rnd_key_n <= rnd_key_p; + cnt_key_n <= cnt_key_p; + + + if version = "00" then + cnt_key_n <= (cnt_key_p + 1) mod 128; + elsif version = "01" then + cnt_key_n <= (cnt_key_p + 1) mod 192; + else + cnt_key_n <= (cnt_key_p + 1) mod 256; + end if; + + if version = "00" and cnt_key_p = 127 then + rnd_key_n <= (rnd_key_p + 1) mod 16; + elsif version = "01" and cnt_key_p = 191 then + rnd_key_n <= (rnd_key_p + 1) mod 16; + elsif cnt_key_p = 255 then + rnd_key_n <= (rnd_key_p + 1) mod 16; + end if; + + -- of course if reset signal is low-active, it should overwrite everything + if rst = '0' then + cnt_key_n <= 0; + rnd_key_n <= 0; + end if; + end process; + + process (version, cnt_key_p, rnd_key_p) + variable total_cycles : integer range 0 to 8191; -- should never take more than ~2k clock cycles anyway + begin + + if version = "00" then + total_cycles := (rnd_key_p*128 + cnt_key_p) mod 2048; + elsif version = "01" then + total_cycles := (rnd_key_p*192 + cnt_key_p) mod 2048; + else + total_cycles := (rnd_key_p*256 + cnt_key_p) mod 2048; + end if; + + rnd_p <= total_cycles / 128; + cnt_p <= total_cycles mod 128; + + end process; + + round <= std_logic_vector(to_unsigned(rnd_p, 4)); + count <= std_logic_vector(to_unsigned(cnt_p, 7)); + round_key <= std_logic_vector(to_unsigned(rnd_key_p, 4)); + count_key <= std_logic_vector(to_unsigned(cnt_key_p, 8)); + +end architecture; diff --git a/128_192_256_enc_dec/data_pipeline.vhd b/128_192_256_enc_dec/data_pipeline.vhd new file mode 100644 index 0000000..f1025d0 --- /dev/null +++ b/128_192_256_enc_dec/data_pipeline.vhd @@ -0,0 +1,323 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity data_pipeline is +port ( + state_exit_bit: out std_logic; + clk: in std_logic; + round: in std_logic_vector(3 downto 0); + count: in std_logic_vector(6 downto 0); + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + mode: in std_logic; + version: in std_logic_vector(1 downto 0); + newbit: in std_logic; + key: in std_logic; + last_rnd: in std_logic + ); +end entity data_pipeline; + +architecture Behavioral of data_pipeline is + +-- datapipeline related +signal d_p, d_n: std_logic_vector(127 downto 0); +signal d_out, s_nextbit: std_logic; + +-- keypipeline related signals +signal keybit : std_logic; + +-- mix columns related signals +signal mix_first_msb, mix_first_lsb, mix_first_out, mix_second_msb, mix_second_lsb, mix_second_out, mix_third_msb, mix_third_lsb, mix_third_out: std_logic_vector(3 downto 0); +signal mix_first_reduc, mix_first_notLSB, mix_second_reduc, mix_second_notLSB, mix_third_reduc, mix_third_notLSB: std_logic; + +signal mix_first_effs_p, mix_first_effs_n, mix_second_effs_p, mix_second_effs_n, mix_third_effs_p, mix_third_effs_n: std_logic_vector(3 downto 0); + +-- sbox related signals +signal sbox_port1, sbox_port2, sbox_port3, sbox_out: std_logic_vector(7 downto 0); +signal direction: std_logic; +signal sbox_sel : std_logic_vector(1 downto 0); + +-- Rotate the data pipeline +procedure rotate ( + variable s : inout std_logic_vector(127 downto 0); + variable b: in std_logic + ) is +begin + s := s(126 downto 0) & b; +end rotate; + +-- Make a swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +state_exit_bit <= d_out; -- Output bit + +sbox_port1 <= d_p(6 downto 0) & s_nextbit when mode='0' else + d_p(126 downto 119); -- First input of the SBOX multiplexer comming from the data pipeline + +mix_first: entity mixcolumns (moradi) port map (mix_first_msb, mix_first_lsb, mix_first_effs_p, mix_first_reduc, mix_first_notLSB, mix_first_out); -- Map the forward - first inverse mixcolumns component +mix_second: entity mixcolumns (moradi) port map (mix_second_msb, mix_second_lsb, mix_second_effs_p, mix_second_reduc, mix_second_notLSB, mix_second_out); -- Map the second inverse mixcolumns component +mix_third: entity mixcolumns (moradi) port map (mix_third_msb, mix_third_lsb, mix_third_effs_p, mix_third_reduc, mix_third_notLSB, mix_third_out); -- Map the third inverse mixcolumns component +s_box: entity sbox (maximov) port map(direction, sbox_sel, sbox_port1, sbox_port2, sbox_port3, sbox_out); -- Map the sbox +k_pipe: entity key_pipeline (Behavioral) port map (keybit, clk, round_key, count_key, version, mode, key, sbox_out, sbox_port2, sbox_port3); -- Map the key pipeline + +process (clk) +begin + if clk'event and clk = '1' then + d_p <= d_n; + mix_first_effs_p <= mix_first_effs_n; + mix_second_effs_p <= mix_second_effs_n; + mix_third_effs_p <= mix_third_effs_n; + end if; +end process; + +process (d_p, mix_first_effs_p, mode, mix_second_effs_p, mix_third_effs_p, round, version, count, count_key, newbit, key, sbox_out, mix_first_out, mix_second_out, mix_third_out, keybit, last_rnd) + variable s : std_logic_vector(127 downto 0); + variable m1, m2, m3 : std_logic_vector(3 downto 0); + variable v_nextbit: std_logic; -- nextbit + variable round_i : integer range 0 to 15; -- round of the data pipeline + variable count_i : integer range 0 to 127; -- cycle of the data pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + + -- Set the state + s := d_p; + m1 := mix_first_effs_p; + m2 := mix_second_effs_p; + m3 := mix_third_effs_p; + sbox_sel <= "XX"; + direction <= 'X'; + mix_first_notLSB <= 'X'; + mix_second_notLSB <= 'X'; + mix_third_notLSB <= 'X'; + mix_first_lsb <= (others => 'X'); + mix_second_lsb <= (others => 'X'); + mix_third_lsb <= (others => 'X'); + mix_first_msb <= (others => 'X'); + mix_second_msb <= (others => 'X'); + mix_third_msb <= (others => 'X'); + mix_first_reduc <= 'X'; + mix_second_reduc <= 'X'; + mix_third_reduc <= 'X'; + + -- Get the current round/cycle as int + count_key_i := to_integer(unsigned(count_key)); + round_i := to_integer(unsigned(round)); + count_i := to_integer(unsigned(count)); + + -- Modify the sbox selection input and selection forward - inverse depending on the cycle and the mode + if count_i mod 8 = 7 then + if mode='1' then + direction <= '0'; + elsif mode='0' then + direction <= '1'; + end if; + sbox_sel <= "00"; + elsif count_i mod 8 = 0 then + direction <= '1'; + sbox_sel <= "01"; + end if; + + -- Modify the sbox selection input depending on the version and the cycle + if version = "10" then + if count_key_i < 184 and count_key_i >= 64 and count_key_i mod 8 = 0 then + sbox_sel <= "10"; + elsif count_key_i mod 8 = 0 then + sbox_sel <= "01"; + end if; + end if; + + -- Input bit + if round_i = 0 then + v_nextbit := newbit xor keybit; + else + v_nextbit := s(127) xor keybit; + end if; + + -- XORed input bit + s_nextbit <= v_nextbit; + + -- SubByte + if (count_i mod 8 = 7) and (count_i /= 7) and (count_i /= 39) and (count_i /= 71) and (count_i /= 103) then + if mode='0' then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + else + s(126 downto 119) := sbox_out; + end if; + end if; + + -- ShiftRows + -- Swap d-96 + if count_i = 127 or (count_i < 7 and round_i /= 0) then + if mode='0' then + swap(s(6), s(102)); + else + swap(s(118), s(22)); + end if; + end if; + -- Swap d-64 + if (count_i >= 112 and count_i < 120) or (count_i >= 16 and count_i < 24 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0 and mode = '0') or + (count_i >= 8 and count_i < 16 and round_i /= 0 and mode = '1') then + swap(s(95), s(31)); + end if; + -- Swap d-32 + if (((count_i>= 72 and count_i < 80) or (count_i >= 104 and count_i < 112) or (count_i >= 8 and count_i < 16 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0)) and mode = '0') or + (((count_i>=88 and count_i < 96) or (count_i >= 120) or (count_i>=8 and count_i<16 and round_i/=0) or + (count_i>=24 and count_i<32 and round_i /= 0)) and mode = '1') then + swap(s(63), s(31)); + end if; + + -- Forward MixColumns / First for Inverse MixColumns + if (((count_i >= 0 and count_i < 8) or (count_i >= 32 and count_i < 40) or (count_i >= 64 and count_i < 72) or + (count_i >= 96 and count_i < 104)) and round_i /= 0 and last_rnd /= '1' and mode = '0') or + (((count_i >= 26 and count_i<34) or (count_i>=58 and count_i<66) or (count_i>=90 and count_i<98) or (count_i>=122) or + (count_i>=0 and count_i<2 and round_i > 1)) and round_i /= 0 and mode = '1') then + + if mode='0' then + mix_first_msb <= s(127) & s(119) & s(111) & s(103); + mix_first_lsb <= s(126) & s(118) & s(110) & s(102); + else + mix_first_msb <= s(25) & s(17) & s(9) & s(1); + mix_first_lsb <= s(24) & s(16) & s(8) & s(0); + end if; + + if (((count_i mod 8 = 3) or (count_i mod 8 = 4) or (count_i mod 8 = 6) or (count_i mod 8 = 7)) and mode='0') or + (((count_i mod 8 = 0) or (count_i mod 8 = 1) or (count_i mod 8 = 5) or (count_i mod 8 = 6)) and mode='1') then + mix_first_reduc <= '1'; + else + mix_first_reduc <= '0'; + end if; + + if (count_i mod 8 = 7 and mode='0') or (count_i mod 8 = 1 and mode='1') then + mix_first_notLSB <= '0'; + else + mix_first_notLSB <= '1'; + end if; + + if (count_i mod 8 = 0 and mode='0') then + m1 := s(127) & s(119) & s(111) & s(103); + elsif (count_i mod 8 = 2 and mode='1') then + m1 := s(25) & s(17) & s(9) & s(1); + end if; + + if mode = '0' then + s(127) := mix_first_out(3); + s(119) := mix_first_out(2); + s(111) := mix_first_out(1); + s(103) := mix_first_out(0); + + v_nextbit := s(127) xor keybit; + s_nextbit <= v_nextbit; + else + s(25) := mix_first_out(3); + s(17) := mix_first_out(2); + s(9) := mix_first_out(1); + s(1) := mix_first_out(0); + end if; + end if; + + -- Second for Inverse MixColumns + if((count_i >= 28 and count_i < 36) or (count_i>=60 and count_i<68) or (count_i>=92 and count_i < 100) or + (count_i>=124) or (count_i>=0 and count_i<4 and round_i > 1)) and round_i /= 0 and mode='1' then + + mix_second_msb <= s(27) & s(19) & s(11) & s(3); + mix_second_lsb <= s(26) & s(18) & s(10) & s(2); + + if (count_i mod 8 = 0) or (count_i mod 8 = 2) or (count_i mod 8 = 3) or (count_i mod 8 = 7) then + mix_second_reduc <= '1'; + else + mix_second_reduc <= '0'; + end if; + + if count_i mod 8 = 3 then + mix_second_notLSB <= '0'; + else + mix_second_notLSB <= '1'; + end if; + + if count_i mod 8 = 4 then + m2 := s(27) & s(19) & s(11) & s(3); + end if; + + s(27) := mix_second_out(3); + s(19) := mix_second_out(2); + s(11) := mix_second_out(1); + s(3) := mix_second_out(0); + end if; + + -- Third for Inverse MixColumns + if((count_i >= 30 and count_i < 38) or (count_i>=62 and count_i<70) or (count_i>=94 and count_i < 102) or + (count_i>=126) or (count_i>=0 and count_i<6 and round_i > 1)) and round_i /= 0 and mode='1' then + + mix_third_msb <= s(29) & s(21) & s(13) & s(5); + mix_third_lsb <= s(28) & s(20) & s(12) & s(4); + + if (count_i mod 8 = 1) or (count_i mod 8 = 2) or (count_i mod 8 = 4) or (count_i mod 8 = 5) then + mix_third_reduc <= '1'; + else + mix_third_reduc <= '0'; + end if; + + if count_i mod 8 = 5 then + mix_third_notLSB <= '0'; + else + mix_third_notLSB <= '1'; + end if; + + if count_i mod 8 = 6 then + m3 := s(29) & s(21) & s(13) & s(5); + end if; + + s(29) := mix_third_out(3); + s(21) := mix_third_out(2); + s(13) := mix_third_out(1); + s(5) := mix_third_out(0); + end if; + + -- SubByte + if count_i mod 8 = 7 and (count_i = 7 or count_i = 39 or count_i = 71 or count_i = 103) then + if mode='0' then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + else + s(126 downto 119) := sbox_out; + end if; + end if; + + -- Output bit assignment + if (round_i>0) then + d_out <= s(127) xor keybit; + else + d_out <= newbit xor keybit; + end if; + + -- Rotation of the pipeline + rotate(s, v_nextbit); + + -- State assignment + d_n <= s; + + mix_first_effs_n <= m1; + mix_second_effs_n <= m2; + mix_third_effs_n <= m3; + +end process; + +end architecture Behavioral; diff --git a/128_192_256_enc_dec/key_pipeline.vhd b/128_192_256_enc_dec/key_pipeline.vhd new file mode 100644 index 0000000..5283e74 --- /dev/null +++ b/128_192_256_enc_dec/key_pipeline.vhd @@ -0,0 +1,222 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity key_pipeline is +port ( + keybit: out std_logic; + clk: in std_logic; + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + version: in std_logic_vector(1 downto 0); + mode: in std_logic; + key: in std_logic; + sbox_out: in std_logic_vector(7 downto 0); + sbox_port2: out std_logic_vector(7 downto 0); + sbox_port3: out std_logic_vector(7 downto 0) + ); +end entity key_pipeline; + + +architecture Behavioral of key_pipeline is + +-- keypipeline related signals +constant ZERO_128 : std_logic_vector(127 downto 0) := (others => 'X'); -- 0 cte for wiring AES-128 +constant ZERO_192 : std_logic_vector(63 downto 0) := (others => 'X'); -- 0 cte for wiring AES-192 + +signal k_p, k_n: std_logic_vector(255 downto 0); +signal k_out: std_logic; + +-- Rotate the key pipeline +procedure rotate ( + variable s : inout std_logic_vector(255 downto 0); + variable v: in std_logic_vector(1 downto 0); + variable b: in std_logic + ) is +begin + -- Wire AES-128 and AES-192 + if v = "00" then + s := s(254 downto 192) & s(63) & ZERO_128 & s(62 downto 0) & b; + elsif v = "01" then + s := s(254 downto 128) & s(63) & ZERO_192 & s(62 downto 0) & b; + else + s := s(254 downto 0) & b; + end if; +end rotate; + +-- Swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +-- Output key assigment +keybit <= k_out; +sbox_port2 <= k_p(7 downto 0); +sbox_port3 <= k_p(15 downto 8); + +process (clk) +begin + if clk'event and clk = '1' then + k_p <= k_n; + end if; +end process; + +process (k_p, version, mode, round_key, count_key, key, sbox_out) + variable s : std_logic_vector(255 downto 0); -- Key state + variable nextbit: std_logic; -- Input bit + variable round_key_i : integer range 0 to 15; -- round_key of the key pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline + variable ver : std_logic_vector(1 downto 0); -- version +begin + -- Assign round_key, cycle, state and version + round_key_i := to_integer(unsigned(round_key)); + count_key_i := to_integer(unsigned(count_key)); + s := k_p; + k_out <= 'X'; + ver := version; + + -- Input bit + if round_key_i = 0 then + nextbit := key; + else + nextbit := s(255); + end if; + + -- Swap/Unswap + if (count_key_i >= 0 and count_key_i < 8) and (round_key_i > 0) then + swap(s(31), nextbit); + end if; + if count_key_i >= 16 and count_key_i < 24 and (round_key_i > 0) then + swap(s(15), s(47)); + end if; + + -- Sbox + xor + if not (round_key_i = 0 and count_key_i <= 8) and + (count_key_i = 0 or count_key_i = 8 or + ((count_key_i = 112 or count_key_i = 120) and version = "00") or + ((count_key_i = 176 or count_key_i = 184) and version = "01") or + ((count_key_i = 240 or count_key_i = 248) and version = "10")) then + s(239 downto 232) := s(239 downto 232) xor sbox_out; + end if; + -- Second sbox + xor AES-256 + if (round_key_i > 0) and (version = "10") and (count_key_i = 112 or count_key_i = 120 or count_key_i = 128 or count_key_i = 136) then + s(239 downto 232) := s(239 downto 232) xor sbox_out; + end if; + + -- Look up Rcon table for encryption/decryption + if + (((round_key_i=0 and mode='0') or (round_key_i=9 and mode='1')) and count_key_i=112 and version="00") or + (((round_key_i=1 and mode='0') or (round_key_i=8 and mode='1')) and count_key_i=111 and version="00") or + (((round_key_i=2 and mode='0') or (round_key_i=7 and mode='1')) and count_key_i=110 and version="00") or + (((round_key_i=3 and mode='0') or (round_key_i=6 and mode='1')) and count_key_i=109 and version="00") or + (((round_key_i=4 and mode='0') or (round_key_i=5 and mode='1')) and count_key_i=108 and version="00") or + (((round_key_i=5 and mode='0') or (round_key_i=4 and mode='1')) and count_key_i=107 and version="00") or + (((round_key_i=6 and mode='0') or (round_key_i=3 and mode='1')) and count_key_i=106 and version="00") or + (((round_key_i=7 and mode='0') or (round_key_i=2 and mode='1')) and count_key_i=105 and version="00") or + (((round_key_i=8 and mode='0') or (round_key_i=1 and mode='1')) and count_key_i=112 and version="00") or + (((round_key_i=8 and mode='0') or (round_key_i=1 and mode='1')) and count_key_i=111 and version="00") or + (((round_key_i=8 and mode='0') or (round_key_i=1 and mode='1')) and count_key_i=109 and version="00") or + (((round_key_i=8 and mode='0') or (round_key_i=1 and mode='1')) and count_key_i=108 and version="00") or + (((round_key_i=9 and mode='0') or (round_key_i=0 and mode='1')) and count_key_i=111 and version="00") or + (((round_key_i=9 and mode='0') or (round_key_i=0 and mode='1')) and count_key_i=110 and version="00") or + (((round_key_i=9 and mode='0') or (round_key_i=0 and mode='1')) and count_key_i=108 and version="00") or + (((round_key_i=9 and mode='0') or (round_key_i=0 and mode='1')) and count_key_i=107 and version="00") or + (((round_key_i=0 and mode='0') or (round_key_i=7 and mode='1')) and count_key_i=176 and version="01") or + (((round_key_i=1 and mode='0') or (round_key_i=6 and mode='1')) and count_key_i=175 and version="01") or + (((round_key_i=2 and mode='0') or (round_key_i=5 and mode='1')) and count_key_i=174 and version="01") or + (((round_key_i=3 and mode='0') or (round_key_i=4 and mode='1')) and count_key_i=173 and version="01") or + (((round_key_i=4 and mode='0') or (round_key_i=3 and mode='1')) and count_key_i=172 and version="01") or + (((round_key_i=5 and mode='0') or (round_key_i=2 and mode='1')) and count_key_i=171 and version="01") or + (((round_key_i=6 and mode='0') or (round_key_i=1 and mode='1')) and count_key_i=170 and version="01") or + (((round_key_i=7 and mode='0') or (round_key_i=0 and mode='1')) and count_key_i=169 and version="01") or + (((round_key_i=0 and mode='0') or (round_key_i=6 and mode='1')) and count_key_i=240 and version="10") or + (((round_key_i=1 and mode='0') or (round_key_i=5 and mode='1')) and count_key_i=239 and version="10") or + (((round_key_i=2 and mode='0') or (round_key_i=4 and mode='1')) and count_key_i=238 and version="10") or + (((round_key_i=3 and mode='0') or (round_key_i=3 and mode='1')) and count_key_i=237 and version="10") or + (((round_key_i=4 and mode='0') or (round_key_i=2 and mode='1')) and count_key_i=236 and version="10") or + (((round_key_i=5 and mode='0') or (round_key_i=1 and mode='1')) and count_key_i=235 and version="10") or + (((round_key_i=6 and mode='0') or (round_key_i=0 and mode='1')) and count_key_i=234 and version="10") then + s(232) := not s(232); + end if; + + -- Kxor + if (round_key_i > 0) and + ((count_key_i <96 and version /= "01") or (count_key_i <160 and version = "01")) and + (mode='0') then + s(223) := s(223) xor s(255); + end if; + if (round_key_i > 0) and + (count_key_i >=128) and (count_key_i <224) and (version = "10") and + (mode='0') then + s(223) := s(223) xor s(255); + end if; + + -- Decryption and-xors + if (mode='1') and (version /= "10") and (count_key_i>=96) and (count_key_i<128) then + nextbit := s(31) xor nextbit; + s(31) := s(63) xor s(31); + if (version = "00") then + s(63) := s(223) xor s(63); + end if; + end if; + if (mode='1') and (version = "10") and (((count_key_i>=224) and (count_key_i<256)) or ((count_key_i>=96) and (count_key_i<128) and (round_key_i > 0))) then + s(127) := s(159) xor s(127); + s(159) := s(191) xor s(159); + s(191) := s(223) xor s(191); + end if; + + -- Decryption output bit swap + if (version = "01") and (mode = '1') then + if (round_key_i>0) then + if (((round_key_i*192 + count_key_i) / 128) mod 3 = 2) then + k_out <= s(191); + elsif (((round_key_i*192 + count_key_i) / 128) mod 3 = 1) then + k_out <= s(63); + else + k_out <= s(255); + end if; + else + if (count_key_i >= 128) then + k_out <= s(63); + else + k_out <= key; + end if; + end if; + else + if (round_key_i>0) then + k_out <= s(255); + else + k_out <= key; + end if; + end if; + + -- Decryption and-xors AES-192 + if (version = "01") and (mode='1') and (count_key_i>=160) then + s(191) := s(223) xor s(191); + end if; + if (version = "01") and (mode='1') and (count_key_i>=32) and (count_key_i < 64) and (round_key_i>0) then + s(63) := s(159) xor s(63); + s(159) := s(191) xor s(159); + end if; + + -- Rotate the pipeline + rotate(s, ver, nextbit); + + -- Assign state + k_n <= s; +end process; + +end architecture Behavioral; + diff --git a/128_192_256_enc_dec/mix_columns.vhd b/128_192_256_enc_dec/mix_columns.vhd new file mode 100644 index 0000000..800d22b --- /dev/null +++ b/128_192_256_enc_dec/mix_columns.vhd @@ -0,0 +1,49 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity mixcolumns is + port ( + A: in std_logic_vector(3 downto 0); + B: in std_logic_vector(3 downto 0); + REG: in std_logic_vector(3 downto 0); + modRec: in std_logic; + notLSB: in std_logic; + OUTP: out std_logic_vector(3 downto 0)); +end entity mixcolumns; + +-- Taken from Bitsling + +architecture moradi of mixcolumns is + signal R0, R1, R2, R3: std_logic; + signal D0, D1, D2, D3: std_logic; + signal E0, E1, E2, E3: std_logic; +begin + + -- AND layer + R0 <= REG(3) and modRec; + R1 <= REG(2) and modRec; + R2 <= REG(1) and modRec; + R3 <= REG(0) and modRec; + + -- XOR-AND layer + D0 <= R0 xor (B(3) and notLSB) xor A(2); + D1 <= R1 xor (B(2) and notLSB) xor A(1); + D2 <= R2 xor (B(1) and notLSB) xor A(0); + D3 <= R3 xor (B(0) and notLSB) xor A(3); + + -- XOR layer + E0 <= D0 xor D1 xor A(0); + E1 <= D1 xor D2 xor A(3); + E2 <= D2 xor D3 xor A(2); + E3 <= D3 xor D0 xor A(1); + + OUTP(3) <= E0; + OUTP(2) <= E1; + OUTP(1) <= E2; + OUTP(0) <= E3; + +end architecture; \ No newline at end of file diff --git a/128_192_256_enc_dec/sbox_bonus.vhd b/128_192_256_enc_dec/sbox_bonus.vhd new file mode 100644 index 0000000..08a9701 --- /dev/null +++ b/128_192_256_enc_dec/sbox_bonus.vhd @@ -0,0 +1,203 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity sbox is + port ( + INV: in std_logic; -- ZF=1 forward ZF=0 inverse + SEL: in std_logic_vector(1 downto 0); + INP1: in std_logic_vector(7 downto 0); + INP2: in std_logic_vector(7 downto 0); + INP3: in std_logic_vector(7 downto 0); + OUP : out std_logic_vector(7 downto 0)); +end entity sbox; + +-- Taken from Maximov's CHES 2019 paper +-- The "bonus" version + +architecture maximov of sbox is + signal A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: std_logic; + signal Q15, Q4, Q0, Q14, Q3, Q1, Q6, Q8, Q9, Q2, Q10, Q7, Q12, Q11, Q5, Q13, Q17, Q16: std_logic; + signal H0, H1, H2, H4, H6, H7, H20, H8, H9, H10, H12, H15, H16, H19: std_logic; + signal S4, S2, S14, S1, S0, S5, S11, S6, S12, S7, S3, S15, S13: std_logic; + signal R0, R1, R2, R3, R4, R5, R6, R7: std_logic; + signal T0, T1, T2, T3, T4, T10, T11, T12, T13, T20, T21, T22, X0, X1, X2, X3, Y0, Y1, Y2, Y3 : std_logic; + signal Y00, Y01, Y02, Y13, Y23, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N16, N17 : std_logic; + signal U0, U1, U2, U3, U4, U5, U6, U7 : std_logic; + signal ZF: std_logic; +begin + + -- multiplexer input + U0 <= INP1(7) when SEL = "00" else + INP2(7) when SEL = "01" else + INP3(7); + U1 <= INP1(6) when SEL = "00" else + INP2(6) when SEL = "01" else + INP3(6); + U2 <= INP1(5) when SEL = "00" else + INP2(5) when SEL = "01" else + INP3(5); + U3 <= INP1(4) when SEL = "00" else + INP2(4) when SEL = "01" else + INP3(4); + U4 <= INP1(3) when SEL = "00" else + INP2(3) when SEL = "01" else + INP3(3); + U5 <= INP1(2) when SEL = "00" else + INP2(2) when SEL = "01" else + INP3(2); + U6 <= INP1(1) when SEL = "00" else + INP2(1) when SEL = "01" else + INP3(1); + U7 <= INP1(0) when SEL = "00" else + INP2(0) when SEL = "01" else + INP3(0); + + ZF <= INV; + + -- below: edited and pasted from the paper + + -- ctop.b + A0 <= U3 xnor U6; + Q15 <= U1 xnor ZF; + A1 <= U5 xor Q15; + A2 <= U2 xor A0; + A3 <= U4 xor A1; + A4 <= U4 xor U6; + A5 <= A2 when ZF = '1' else A4; -- MUX(ZF, A2, A4) + Q4 <= A3 xnor A5; + Q0 <= U0 xor Q4; + Q14 <= Q15 xor Q0; + A6 <= U0 xnor U2; + Q3 <= ZF xor A6; + Q1 <= Q4 xor Q3; + A7 <= U1 when ZF = '1' else Q0; -- MUX(ZF, U1, Q0) + Q6 <= A5 xnor A7; + Q8 <= Q3 xor Q6; + A8 <= Q1 when ZF = '1' else A4; -- MUX(ZF, Q1, A4) + Q9 <= U6 xor A8; + Q2 <= Q8 xor Q9; + Q10 <= Q4 xor Q9; + Q7 <= Q6 xor Q10; + A9 <= A0 when ZF = '1' else U4; -- MUX(ZF, A0, U4) + Q12 <= U7 xnor A9; + Q11 <= Q0 xor Q12; + A10 <= A6 when ZF = '1' else Q12; -- MUX(ZF, A6, Q12) + A11 <= A2 xor A10; + A12 <= A4 xor A11; + Q5 <= Q0 xor A12; + Q13 <= Q11 xor A12; + Q17 <= Q14 xor A12; + Q16 <= Q14 xor Q13; + + -- mulx.a + T20 <= Q6 nand Q12; + T21 <= Q3 nand Q14; + T22 <= Q1 nand Q16; + T10 <= (Q3 nor Q14) xor (Q0 nand Q7); + T11 <= (Q4 nor Q13) xor (Q10 nand Q11); + T12 <= (Q2 nor Q17) xor (Q5 nand Q9); + T13 <= (Q8 nor Q15) xor (Q2 nand Q17); + + X0 <= T10 xor (T20 xor T22); + X1 <= T11 xor (T21 xor T20); + X2 <= T12 xor (T21 xor T22); + X3 <= T13 xor (T21 xor (Q4 nand Q13)); + + + -- inv.a + T0 <= X0 nand X2; + T1 <= X1 nor X3; + T2 <= T0 xnor T1; + + Y0 <= T2 when X2 = '1' else X3; -- MUX(X2, T2, X3); + Y2 <= T2 when X0 = '1' else X1; -- MUX(X0, T2, X1); + T3 <= X2 when X1 = '1' else '1'; -- MUX(X1, X2, 1); + Y1 <= X3 when T2 = '1' else T3; -- MUX(T2, X3, T3); + T4 <= X0 when X3 = '1' else '1'; -- MUX(X3, X0, 1); + Y3 <= X1 when T2 = '1' else T4; -- MUX(T2, X1, T4) + + -- s0. a + -- calls inv.a; + Y02 <= Y2 xor Y0; + Y13 <= Y3 xor Y1; + Y23 <= Y3 xor Y2; + Y01 <= Y1 xor Y0; + Y00 <= Y02 xor Y13; + + + -- File: muln.a; + N0 <= Y01 nand Q11; + N1 <= Y0 nand Q12; + N2 <= Y1 nand Q0; + N3 <= Y23 nand Q17; + N4 <= Y2 nand Q5; + N5 <= Y3 nand Q15; + N6 <= Y13 nand Q14; + + N7 <= Y00 nand Q16; + N8 <= Y02 nand Q13; + N9 <= Y01 nand Q7; + N10 <= Y0 nand Q10; + N11 <= Y1 nand Q6; + N12 <= Y23 nand Q2; + N13 <= Y2 nand Q9; + N14 <= Y3 nand Q8; + + N15 <= Y13 nand Q3; + N16 <= Y00 nand Q1; + N17 <= Y02 nand Q4; + + -- cbot.b; + H0 <= N9 xor N10; + H1 <= N16 xor H0; + H2 <= N4 xor N5; + S4 <= N7 xor (N8 xor H2); + H4 <= N0 xor N2; + H6 <= N15 xor H1; + H7 <= H4 xor (N3 xor N5); + H20 <= H6 xor ZF; + S2 <= H20 xor H7; + S14 <= S4 xor H7; + H8 <= N13 xor H0; + H9 <= N12 xor H8; + S1 <= H20 xor H9; + H10 <= N17 xor H1; + H12 <= H2 xor (N1 xor N2); + S0 <= H6 xor H12; + S5 <= N6 xor (H9 xor (N8 xor H4)); + S11 <= H12 xor S5; + S6 <= S1 xor S11; + H15 <= N14 xor H10; + H16 <= H8 xor H15; + S12 <= S5 xor H16; + S7 <= S4 xnor (H10 xor (N9 xor N11)); + H19 <= H7 xnor S7; + S3 <= H16 xor H19; + S15 <= S11 xor H19; + S13 <= S4 xor (N12 xor H15); + R0 <= S0; + R1 <= S1; + R2 <= S2; + R3 <= S3 when ZF = '1' else S11; -- MUX(ZF, S3, S11) + R4 <= S4 when ZF = '1' else S12; -- MUX(ZF, S4, S12) + R5 <= S5 when ZF = '1' else S13; -- MUX(ZF, S5, S13) + R6 <= S6 when ZF = '1' else S14; -- MUX(ZF, S6, S14) + R7 <= S7 when ZF = '1' else S15; -- MUX(ZF, S7, S15) + + -- end of copying + + + OUP(7) <= R0; + OUP(6) <= R1; + OUP(5) <= R2; + OUP(4) <= R3; + OUP(3) <= R4; + OUP(2) <= R5; + OUP(1) <= R6; + OUP(0) <= R7; + +end architecture; \ No newline at end of file diff --git a/128_192_256_enc_dec/test_vectors.txt b/128_192_256_enc_dec/test_vectors.txt new file mode 100644 index 0000000..16f71cb --- /dev/null +++ b/128_192_256_enc_dec/test_vectors.txt @@ -0,0 +1,530 @@ +0 +0 +6d6b95820874a7651a5d9d1a26a650ac +b9e36a66914b818c0edbeb57fc55a5e1 +4B049B83666BC6032E423B14E91380E2 +1 +0 +4B049B83666BC6032E423B14E91380E2 +71FCF1F7CABBBF9E931EFF629F0DCF94 +6D6B95820874A7651A5D9D1A26A650AC +0 +1 +185b15bc2fafd9c9d3254148e1231abd +0c7de16e709bcb282163b763ba574ad16b44e2cb16bfd39b +62A7A27BD182E89ADF662ED7C252A292 +1 +1 +62A7A27BD182E89ADF662ED7C252A292 +BD9C626E1D32D3F7D24390CF57AFAD20CCCDB83381CF1076 +185B15BC2FAFD9C9D3254148E1231ABD +0 +2 +00112233445566778899aabbccddeeff +000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +8EA2B7CA516745BFEAFC49904B496089 +1 +2 +8EA2B7CA516745BFEAFC49904B496089 +24FC79CCBF0979E9371AC23C6D68DE364E5A6699A9F24FE07E572BAACDF8CDEA +00112233445566778899AABBCCDDEEFF +0 +1 +ca5929aaa26d62d88f39bf8c4b7910df +89dff256373b1fd26669689fe955123e543814cab1fc43ab +22D610C57D475AF3E2A19DDFB92344A4 +1 +2 +8f5ddb560cffef706756df53016c3c83 +b4c1151c50146fffdb7a9127c4eea8fe2107b5636618f63277e345a86eedb0ee +745102C6EFD0FABF0AD5A8DC90C093B0 +1 +1 +eafd592f2015d87ff5c95874761b2dc8 +f6127c4f4e6147a548730d289e27567404560af3b3dc3d5c +B197060BA15B8ED7FFA932F22BA08B59 +1 +1 +f59d07b01526717be110ee4be3785747 +7699d0d1ef2c99a64d00524de6fb5b4c88c266c85ba3beb7 +C9E2AA38129C8BB580D7CE968D3B3CAE +0 +1 +0d074d6fe8fe70f0f8644adffa65ab29 +f5c6a5612bfbab680ddfa31e1a1e0b058c2232215ed1afaf +1618E808E62DA06B32E5123CF279847C +0 +2 +7f46a7d2999ef3ae7c5cb8a6c00e6c5b +78717e2a40f3630f333ba8e86b806e234180b0136da14b2ec71b8f20031c75d2 +ED11B92C301EA7D982E8115C51344973 +1 +1 +7b01ff503d12b58ba8b88e7b69597144 +81b0ec8f135529c4279ef9ec3c354eb914723d9560ae6f5f +5455FB3A87D273DF0D071652FBA0F7CB +0 +2 +d7b6b0251f7fb124873b671cb5e156bd +14f357adbccdd7b916321860aea990ba36ab1c2c8d43f023f6904f5502b359ec +7C0091E288796903262BA4571292591D +0 +0 +13fa85b7a5837e1a67729d131c62dcf1 +6e4a2246f267c377b78064f815a0507b +C6F99717B24AE1FEB5232C01F7DE06A9 +0 +1 +366c39b0dc100c647fd9fe06777ff198 +13c94a54cc92f3c0eb36213083fc265905b9f0216b9e97c0 +DB8E821A76D7EFFDE8A8683A9FDE476D +1 +2 +c8f617805b3097032104cf2f4b92da72 +0d2ffd6f408c5cd1e612da79a8487dd01d1c981ef1d586a06ea49370d2e2299c +FC3DD7663C99ABEF77B4A680C61DE199 +0 +2 +0458b4d58ce12498e94ec46b055cdc95 +f57aa7b5f81b6d9042bd39135a284c951fe165b41ddd688723a0545f41fe0b11 +1FC161874A3DB67DED3F13E065CF049E +1 +2 +53665e2c0d9418828bf53eb5f075f924 +f4e08ffcefd65a89cebe3d000feab9873917af8a52cb57024c055b07fbd37348 +7DBC797BEC4F157740D212B970E25C04 +1 +0 +7f7b0ddb4cede9630ae0374266c503d2 +c7bf44a7c090d9ba5094979c4160eae2 +5299B5DC9A374BCB7EFD40EC06F3978B +1 +0 +9ba369a5efcaabc4979f85790522c6ae +b715a56e3107045d14c53a1e1fe13db4 +A22283797629DAAB592805B7F95FAF58 +0 +1 +9230306fdfa20eb9ab5ce82cd97a499f +1269555694a551b432a0c8d5bffa1745309e9ce21cd08105 +58B273C02867A30E052ECFE53A0F8F8B +1 +1 +00daebc09d6fbb59960d5984ac2c5c1c +4575f97f3fd98724f3719ca5e3b8892299cec75bd909a7d9 +C23B69C786212DD5B6D11FDD27FDB724 +0 +2 +4c143fe83421c12b83cec2f54992d3c6 +76414c4d0603e487f856c9f03ca241c61843698374ec7d9e39354b88c68b6210 +8BB9365D4491F62562965396088F3B40 +1 +0 +3e100f8038b54c23b81ef06eeea525ea +84eb99cf3e4fef70398d9981c2389931 +6A620B7DC04A645FAE2E7B8A0627DCDD +0 +1 +3317fdcaee1d786b04685805fca9d0fc +244de1b288f60dee2ae1dc7c971a6fec2a7cdcd829ac1cbc +82DA66A390DA00037AC3D2D099BA6606 +1 +0 +bf9289fc4268f0f914ff9cc8a16906d5 +026d900d35b765a76e4d57043b99d5ac +D0D6104DCBD5BD1693577C4687060C36 +1 +2 +248f901be4c7894efda031eaeeffbd8e +6aebda73cb5deb1aebd23246822e40e36edbb986f254022c8bb77724a5244356 +56140DF35CAD661B315D51B2ADB62580 +1 +2 +7fe4e6d3f880c0abbf3cf5d0c552a376 +af30609e6e56fac831f17ccc70364bd6ac94f9597648c8383ee9840c50546fe6 +4C747FC6774D53B0E184FA558D533AA7 +1 +1 +f6420288fc8b817cd0690ef7f52fe413 +b873578cb47f4a14f358c5ede97dda58fe0e544713f53845 +D2EC908C52E48445A4E2EF9C7555C3D9 +0 +1 +58b26129459db099e328fefb4c6a574a +39890dfec4ee38f29da21ff9ae2f90e47e76a631ea559b51 +D0130058604E60CAEA183AE082173FE0 +1 +1 +6990af201ab9d28ff6a2a738a95124fc +10bb09f9cca5fccd67423c149f7c3116f0e91fd54be7a80a +57D572D0BD19EE9C8DA65ECDF41442CF +1 +1 +fca4648098b1c5a6393474d678dad371 +15dd95141bcfe502da1d90c20f8573c71ddb6a22f9dc60f9 +3BB30F7F07E8B1C3B6EF5A6956A17A58 +0 +2 +08181d2a607dd0238529de9d7948bd43 +6c2cf471c30c9f3d6ba95b80b485bb81bd15976896e2c7366087ac6179936a44 +A3301D98BCE3627E9579943822B53CA2 +1 +2 +bda67dd48fcbedcf07dbe0650cd36623 +2e6158b8305ffa7a2b2db788ecb3bbd16b0e489518d7c28db5247a1ccd55957b +B62E4191E3B7DF32C43EB9325E4A4978 +1 +0 +8bad4606d375c72a184e15b4f10efada +32a70491b21c5b4b6aad3f8bf0267679 +3AF1886E9AA3D03AF7EC9C2E8F935709 +1 +2 +a48b96cb5d0683acad7a8dc71fb22f4e +be148a11d0e11ab1ef1849ec4cfcbac1a8673fcd41c407ef9d08e676e780db57 +92A5AF0AC12876C9DF2D51F635627438 +1 +2 +713407d417adaf863d03534da6406d41 +278a546567827f7c7b3e7fdacd47ba3525aba3a6dca3a9e6754681ac46f3d62b +69C9E4FC73B9A7CA7CE9EA84BF6D3BEA +1 +1 +56cd60558ad482d256c747d4581d9b9c +c1c57cc7729f6332e8741843c06318e9deec2693bdbbf0a5 +D7A79040BCF783F3EAAD946ACF864F3D +1 +0 +14e911dbbaddfb332dd7be446258ba43 +c7b787c0f7af0b00b60381c312522a97 +FFC8BCE8E76CCDB0F762C578AC9B9503 +1 +2 +45bad1967096b9e4feb5d06af041edd6 +ef03512da2f896161dcf731cf82f593365b1aa10c3030a9c684c043a4a75f1e3 +86899B1CF871EC3CE793A6860515DD6E +0 +2 +984845dc14f1fa32f31bb97fc900186b +1be059c99e464859aabd2074b50deb0b483dc4a5fb3175bf9515cd2fb5ecde90 +1466CFC576C356B7AEE170B370109E26 +1 +0 +12af36f81f59a05ac55e55552049a1a8 +fd7e1ea7d973df94e0bcf12dc503e6a7 +95FC3D421B9B26E17EE7F9B85B2B0BCA +0 +1 +88fa1af99cd3071dd5c07d12bdd47bea +0742929c612e80fbaa7f99ace4c7a19adc016e7eef1dab82 +09EAC5C6B7F9B4866178A96946A765BA +0 +0 +5ddf9ede3cdf098c74cfb1449350a8fb +5f0efd9921ffb8bf23678bb5e24f4a9a +7A4E238FC72869023FD6C1D6D603667E +1 +1 +22eee6f816d0f7a0a42c8d222621fad1 +45d60aa21995881ef7996b621f73cf695b5d09fb4a70585a +DAC212D244F0623AF8C9B7A30A78467C +1 +1 +b6f95e6e3f52b1c71533ac66e9be7832 +88ed5802cf7e9fca657e5d3f904768a781b8cab6ab859fc1 +801F1A04B3ACF31E253547EFFF51651B +0 +0 +a06c439de58a289a2dbbcf43b193de76 +8454dc5f9b9b61d3a2a34900f398c10c +F68DCE84A419B8DC7AA11C7D78044F56 +0 +0 +4a003e61bb1057358460cc1649302162 +61c205a0b39adc1195499d85df4b1226 +9984A671322FE771221D78364C977574 +1 +2 +e39b949fe036d5d8cdb00dbc6cbf0e7d +1af6415c2a035e75c0d8eccc0b722c5f781e1b6cb2392168c325e6c3fcd857e2 +8747790F2C5CFF332CC791DA1E107F56 +0 +1 +b11d39b84d4ba9a1fe440603d8c1edc1 +2e8a6391d85edbe7779c548f44d7fc5c60bdc78cf1327f69 +475E6248E9C888A9A94483038192D058 +1 +1 +f34ba1b135e91598c6eaecdd7e302b2a +1b8c36d2e80114bc58f37fe9c88e87d0e7474c3f30a53440 +69BEC00BDEF643A4374E2243A6387F73 +1 +1 +7fb7743bcedbb9af8c7cb877f2a94b28 +f954fb3ee96084cb642ddf2f0868e5e23c131b5ffedbcae6 +33822816CC317F63B71CE25DCCF66BE8 +1 +1 +112a298ace8d6992eceb99de19c21604 +e30cfefaad7fe6f853e42d0786e69ba9f0316897759431d1 +5F6D070F639F71900F385E80AA10E5F1 +1 +2 +9ef3d8ec042c33245c5796afa3b0f218 +e3d63c5f17787d9bd6ed7e5e0ca740e5846bb9091d89b402e33d648935e5c083 +0EFF69ED0EC1E440E45F16DDD5777347 +0 +2 +f9ec2a1b9af2b31b3503369e287cd8ff +62146ffc79f09678ee3412a2c2edcc1f0c7847b94d8b9df70b7ba2ec9768aef1 +B0D39314B1A679F3B58C122700AADEE6 +1 +0 +541bcad4e7cacf867fd5d09d0dc20332 +cff6b9ba16e454095ed36ab755990ab6 +8D4B4DEE80C0CA6A667E9A598A9DBEFA +0 +0 +8547cbbaddaa09a290d95347e9fdf546 +545b4798fe5ea480aad4e144e8f10ac7 +8A53DEC2860D4E0C8A15A08FAC54E14A +0 +0 +4d3a03ee12f8c5fee9a90c3bfa6fa23d +b922c04f8d2e9849024d34596335e4a1 +7FC26CCEA8C5229A76AED0EB9454E842 +1 +0 +df48f7a2ca0bb034283a353b8fc07728 +59f8d4946739d2b75cd8f15202b9450f +A1D73F1EFAFBB41503439858FD9C7E6A +0 +2 +344088c5f59c1f6a749726ebe52c476a +458baf6dae15651d5f8990b181b5a6412b83d41a23506fb69a6ff97574d1e3f0 +61BC26C788441B2EA50C0BB97A50B729 +0 +1 +62a5b2c671644bef4233e859131f09e7 +658f973b02cdb38833e6a7759199af29216bf7542495b569 +27C56975705EDB18D7234976009F327E +0 +1 +29424f99f1d4415740ed3cc5a08c5d18 +8c196cb73a312bdf03a96f977842ce3f0386aec56e8fb721 +D4AFD1E17ABC788832A2B0AA8D7EC2BD +0 +0 +2c37a64d1a0d1f8a2b643a98fb1bcefc +a77eaf748b8cb05ccca22b4ac6625021 +E735E6442E36DAFBF322678F1C119104 +1 +0 +723d1429b99d22f84a01a6b75582f129 +f953b4585c5a49b47d57d930b7fcaa26 +DA0A575475AB54D1DA57F3490E0C6B33 +0 +0 +a65441440617c5aeab332a78aef87d32 +07a1bd1dbfa1a1a523665868b6059687 +BFE046D31215A08C425A2537DF52CDE6 +0 +2 +8afefa3850d927b55b1b531b40c238ed +53da1fe3fbe188dc30d0fa3027b9f58a9b2ebf873e6427ba517276346a7a36c8 +D0C14AE6586B3D2A6B7F52F7459C23F0 +1 +2 +f0ef3ba2299dcb5249f543738c843855 +3a67b25cc61a8f017f3fb39db59be725d181f21cb56a069fc06c299b044fb262 +E10246F93A0C365D749EED5591B5DD77 +0 +0 +9c9b678a900d06b82e3359213628dfe1 +ee83636f413e16ba4e291a8f53a5c529 +0B5C5FC14438E52A16A1739DBC3E65F4 +1 +0 +c5347fcb851a73215ccf7ac8b2729d93 +cb178bb8a933219bb2c052f4b2e30218 +24D8C2AAC4B7FA26C19E4B42E3EF59AE +1 +1 +c34c75ce561726b325e3a8c37bc3644b +bec76d0000e048af20cbc1cbc16e9118f094b31c0f8ad1b8 +053E9DCA66CB2CD14D3D0499D65E5973 +0 +0 +60f58fc5b9a683aa2cedc1d0701297cf +f2d8dcd23f470e210680b5ee2e734233 +FAC98F8271D09AE73F7D9EEB4E1E118C +0 +2 +ad3c50812d1ce12c4d54192f25af75e9 +0c85c2873f06201340e178f76acda1e880c6c855dfcb2a2f75828925be0e7363 +E57E3141210407A68DAEAD8E7DF15CE2 +1 +1 +16817d3422834ad6df15a22af6253e27 +5177b6240270f94fc4db374544a4269f5b80806c478e3b7d +CC4859180792009516F3DDBE7C483CEB +0 +0 +9712ac81dbafb1524861a4ab70fd2e68 +3c6778b33c6c0ecb617bd15d5c37858e +CB5C223577E2305CC69979ED0774D459 +0 +0 +91f2c2c71602ae887d74c34b1f80e8a9 +289684e1227c9033ecf99266ce3ca434 +44C15DD83287B1CD167D3E74396F6A94 +1 +1 +d373c6deac2eb06cdfbe62012d575ca6 +9cc355467115a1a78c18e07a0b8e7ef006027ca7cd8cb2d5 +A7D4CC81D84C64C9FCBF3ED1E6A368FA +1 +2 +62835233ea6f10c1d5293272ad5b3563 +b0d1c3f281f8e5af8e7faad317d27c6f0a9b9a4e483b6f110f3ddf542a313c19 +204E0E86F4CA7B1487DC9383C873A39B +0 +2 +45aa497c100c426f51880903ee8dde1c +04e84087503b487a9ecc1fb24e212dd1709553a68c5014e8137ced6beab2858f +B32224A8A58EBF70F2947D3D3A45BFEF +0 +2 +ac7726b5250d6d873b374e5cda3176de +dd1d3425a89bf89d1ae1c7b488d6b9ec7de979df6b6ccf84c3cddb8f5870df5b +FC3C7B7FB92B80EC56C9EB42C840BA21 +0 +2 +10e68eee5849246741325a2b970fb2f0 +f1f76e1cc85ca86cff4faf71462b034aec615f1f8807c428fd96d01196085d8d +0A25E562B038FED054D09C42EB77940E +0 +1 +df709643d3404ba5a768fc0aad1b5ef6 +87d364fe70ae3e2e273a43fea051432a1e7a32e5ec06bbe3 +1E20356F166A1FE283C99A42D18AE8AF +0 +2 +6e9b9999c8d31edb95fd33366d83a7ca +ee7d6a879b0f749312372bbf9dd31815afd9320c10d3122736ae2e50dbb88427 +CDD319CE0B9BBB01E98B35AC7AC837A0 +0 +2 +8296a8ee75028ec636a39656baad9bba +7127f50c2b0eb7a81d5530daffe14d07ecf529efb727c9c0117f7ccfdbb9ff2e +63D4B43930701A8750DA02A117DE03A3 +0 +2 +a3b6961af9103d35a56de13f4e661c00 +617376dce738be0feb27080c0b2f4b417536b8a2a3ee15a6c58ae8fc9b22b55f +5F390430A746C8602039447A267C321B +1 +1 +6346e8b5e972d3c3e71844b2031b1258 +c3b67f994a926681f9b27794cabf1757be78e0cab6010b0d +39F3F6121961F3267E92DCCF278EA461 +0 +1 +54998e3c81c3bad5fa888e426c1e087e +0b9f139b02b3e571e1fbd9cc1043f16b735fde3e2efef8c5 +81308613213BFBC22DD2510BD8638C1F +0 +0 +4a0bf9441e01a30161e3882fb6318c81 +05c6f02c2ee1ab176fa471be21856a24 +95F06E5BD4EF9BAE4E8D144A8D9DEA5C +0 +2 +d94c8f4912a14d37eab00b403a3f6a69 +935ded5c26d8e8d7d4d5a799e1c7e51987dac7fd433ff0f79d8d6705a43c57c7 +10B80919BB91915751D91A96D3C4A230 +1 +0 +703761b3608edbf6d726aa9acff48923 +9ec54a8c630abad9a2df29672c64f863 +18BA662BB8EBF4C3A2B22E275F6A997C +1 +1 +eaa1b00d52d164ff67e240710bc21882 +0e5bc5e624d85c681c8ec9ae32ba90fdd63824f85b118be8 +E64B80271847BE7097BDB9048E17D453 +0 +1 +beafbea9d7efb55b730aab19a037a02e +f9be046d7b7a1164903da2d34851b4261cd92b1346df9207 +0D99CE8EA9AF50268A04DB710EE71A3E +1 +0 +83f002bf24d78be6c527eb868085207c +7d61675c13e86f44371ea5a17ae23b9d +5DA6FFB795054674BCA1ECBC0A6AB5E6 +0 +2 +a9e13a421c0dac9de1fd293192e6f9c3 +263b42119455a83c29c7872c40717a50caa549b4aa62fcf79cfab95212cb5f66 +97B8EC0807566B4B6AD198871EF72B92 +1 +0 +952cd1682f26274879b309616084d39d +506bd176dbab5b6fab0b150f28d95ee5 +FD033BF673E3E799C79C4D1429B709CB +0 +1 +ebf571922520ff53181711d67b3f5048 +d03a8e8e24c24a97d70ab308d595172de6035c6f7ff1af75 +983EEA3BEC3FEDC0E0E4763813F8C2F8 +1 +2 +2fa9fcf7fd4122aaab7063b4e7a6881d +e09903e06987f939bb549bf221410f435781e7495a1f7175adfb2ad04ddab9cf +C7952E31CE6605532DF8D8DFBF0EC489 +0 +0 +cfc954a1d6e8738a13b74e860da9aefd +18bbc25eada9ce8065adaec61339652d +98A9B8BF3B7DF3C161FB206C05B99AF8 +0 +0 +be7b9abf308f169b23d674ebedda5436 +3d6e6bd3ea2b4afc57dff3f36cce8f38 +9302DDC0CAEAE930C20D148552CCDA23 +0 +0 +5e0a6f205be26b9872d3ffe00f002e05 +45ff75cb24e0f2dd422497cea2066267 +93315DCB99A4D5CC25653AD470D30F58 +0 +1 +d7095f0e7866db963bff62384d82645f +10cd2778a0d5183e155ca8eb21978075211f8b25449bd77a +D4CAFCDD44192A6E0253F6F67AD302AC +0 +1 +bea4ceb8181b6bd690a3543ed14c73b7 +85f026a87bc0161163fea12f797bdd3ed141c4665e14d27a +51F3DA0B3DE5153F4C022247AE3FFFB3 +1 +0 +eddba7f0b4fe6fad5864372250729b43 +390ffa4240940f897b43648f7e4bda20 +4B5C14EB4F3626BF331C20DD60B03AFB +1 +1 +1fd88979ff336997800297d9e25fb7f7 +4e15a1aef7b393829a1834c99d5d79a0c63f9f96c672bf40 +D45323D11D39C40D3E68A1070B59798A +0 +2 +47ca417da3c490076e962acbc9ba321d +afcbd87fbf4e9946e78f1ccd7b7f19717f7d8cdd29328808be5f59718d592ec0 +85F3181C6D33DDC557C90D2325A14233 +1 +1 +b9519bef85ae87174925aceddf03983c +0c82c49bbc17a8b0ddfdb6289c3c00e38e1225c64ba2465f +C4D62924A54D03D9F6A613A3617F24DF \ No newline at end of file diff --git a/128_192_256_enc_dec/testbench.vhd b/128_192_256_enc_dec/testbench.vhd new file mode 100644 index 0000000..fe77d05 --- /dev/null +++ b/128_192_256_enc_dec/testbench.vhd @@ -0,0 +1,142 @@ +library std; +use std.textio.all; +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use work.all; + +entity tb_aes is +end tb_aes; + +architecture tb of tb_aes is + + constant clock_cycle : time:= 100 ns; + + file vector_file : TEXT; + + signal ct : std_logic; + signal pt : std_logic; + signal clk : std_logic; + signal rst : std_logic; + signal done : std_logic; + signal key : std_logic; + signal mode : std_logic; + signal version : std_logic_vector(1 downto 0); + + component AES + port ( + ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic; + mode: in std_logic; + version: in std_logic_vector(1 downto 0)); + end component AES; + +begin + + mut: AES port map (ct, done, clk, rst, pt, key, mode, version); + + process + begin + clk <= '1'; wait for clock_cycle/2; + clk <= '0'; wait for clock_cycle/2; + end process; + + process + variable tmp_line : line; + variable ver_v : std_logic_vector(3 downto 0); + variable mode_v : std_logic; + variable key128 : std_logic_vector(127 downto 0); + variable key192 : std_logic_vector(191 downto 0); + variable key256 : std_logic_vector(255 downto 0); + variable pt128 : std_logic_vector(127 downto 0); + variable ct128 : std_logic_vector(127 downto 0); + variable buffer128 : std_logic_vector(127 downto 0); + variable test_ctr : integer range 0 to 1000000; -- can fail if too many vectors + variable loading_ctr : integer range 0 to 255; -- can fail if too many vectors + variable reading_ctr : integer range 0 to 127; -- can fail if too many vectors + begin + file_open(vector_file, "test_vectors.txt", read_mode); + test_ctr := 1; + + while not (endfile(vector_file)) loop + + -- we first read a single test vector from a file + readline(vector_file, tmp_line); read(tmp_line, mode_v); -- read mode + readline(vector_file, tmp_line); hread(tmp_line, ver_v); -- read version, only ver_v(1 downto 0) is meaningful + readline(vector_file, tmp_line); hread(tmp_line, pt128); + if ver_v(1 downto 0) = "00" then + readline(vector_file, tmp_line); hread(tmp_line, key128); + elsif ver_v(1 downto 0) = "01" then + readline(vector_file, tmp_line); hread(tmp_line, key192); + else + readline(vector_file, tmp_line); hread(tmp_line, key256); + end if; + readline(vector_file, tmp_line); hread(tmp_line, ct128); + -- reading a single test vector is done + + rst <= '0'; + version <= ver_v(1 downto 0); + mode <= mode_v; + wait until rising_edge(clk); + + rst <= '1'; + loading_ctr := 0; + loading_loop: loop + if loading_ctr <= 127 then -- load pt only in the first 128 cycles always + pt <= pt128(127-loading_ctr); + end if; + + if ver_v(1 downto 0) = "00" then + key <= key128(127 - loading_ctr); + if loading_ctr = 127 then + exit loading_loop; + end if; + elsif ver_v(1 downto 0) = "01" then + key <= key192(191 - loading_ctr); + if loading_ctr = 191 then + exit loading_loop; + end if; + else + key <= key256(255 - loading_ctr); + if loading_ctr = 255 then + exit loading_loop; + end if; + end if; + loading_ctr := loading_ctr + 1; + wait until rising_edge(clk); + end loop; + + + waiting_loop: loop + wait until rising_edge(clk); + if done = '1' then -- done signals indicates that the encryption/decryption is almost over, and the result will be available during the following 128 cycles + exit waiting_loop; + end if; + end loop; + wait until rising_edge(clk); -- wait until the next rising_edge + + reading_ctr := 0; + reading_loop: loop + buffer128(127 - reading_ctr) := ct; + if reading_ctr = 127 then + exit reading_loop; + end if; + reading_ctr := reading_ctr + 1; + wait until rising_edge(clk); + end loop; + + assert buffer128 = ct128 report "======>>> DOES NOT MATCH <<<======" severity failure; + report "passed vector #: " & integer'image(test_ctr); + test_ctr := test_ctr + 1; + + end loop; + assert false report ">>> ALL GOOD <<<" severity failure; + wait; + end process; +end tb; diff --git a/192_enc/aes.vhd b/192_enc/aes.vhd new file mode 100644 index 0000000..e05dd50 --- /dev/null +++ b/192_enc/aes.vhd @@ -0,0 +1,33 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity AES is +port ( ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic + ); +end entity; + +architecture Behavioral of AES is + + -- pipeline related signals + signal state_exit_bit, last_rnd : std_logic; + signal round, round_key : std_logic_vector(3 downto 0); + signal count : std_logic_vector(6 downto 0); + signal count_key : std_logic_vector(7 downto 0); + +begin + + ct <= state_exit_bit; + + data_pipeline0: entity data_pipeline (Behavioral) port map(state_exit_bit, clk, round, count, round_key, count_key, pt, key, last_rnd); + controller0: entity controller (Behavioral) port map(round, count, round_key, count_key, done, last_rnd, clk, rst); + +end architecture; diff --git a/192_enc/controller.vhd b/192_enc/controller.vhd new file mode 100644 index 0000000..f307715 --- /dev/null +++ b/192_enc/controller.vhd @@ -0,0 +1,69 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity controller is +port ( + round: out std_logic_vector(3 downto 0); + count: out std_logic_vector(6 downto 0); + round_key: out std_logic_vector(3 downto 0); + count_key: out std_logic_vector(7 downto 0); + done: out std_logic; + last_rnd: out std_logic; + clk: in std_logic; + rst: in std_logic + ); +end entity; + +architecture Behavioral of controller is + + signal rnd_p : std_logic_vector(3 downto 0); + signal cnt_p : std_logic_vector(6 downto 0); + signal merged_counter_n : std_logic_vector(11 downto 0); + signal merged_counter_p : std_logic_vector(11 downto 0); + signal merged_counter_plus : std_logic_vector(11 downto 0); + +begin + + -- We should prefer synchronous rst signal + -- it helps when we want to later use it in AEAD circuits + + process (clk) + begin + if rising_edge(clk) then + merged_counter_p <= merged_counter_n; + end if; + end process; + + process (merged_counter_p) + variable ctr: integer range 0 to 4095; + begin + ctr := (to_integer(unsigned(merged_counter_p)) + 1) mod 4096; + merged_counter_plus <= std_logic_vector(to_unsigned(ctr, merged_counter_plus'length)); + end process; + + merged_counter_n <= (others => '0') when rst = '0' else merged_counter_plus; + + done <= '1' when cnt_p = "1111111" and rnd_p = "1011" else '0'; + last_rnd <= '1' when rnd_p = "1100" else '0'; + + process (merged_counter_p) + variable total_cycles : integer range 0 to 4095; -- should never take more than ~2k clock cycles anyway + begin + + total_cycles := to_integer(unsigned(merged_counter_p)); + + round_key <= std_logic_vector(to_unsigned(total_cycles / 192, round_key'length)); + count_key <= std_logic_vector(to_unsigned(total_cycles mod 192, count_key'length)); + + end process; + + rnd_p <= merged_counter_p(10 downto 7); + cnt_p <= merged_counter_p(6 downto 0); + round <= rnd_p; + count <= cnt_p; + +end architecture; diff --git a/192_enc/data_pipeline.vhd b/192_enc/data_pipeline.vhd new file mode 100644 index 0000000..549b957 --- /dev/null +++ b/192_enc/data_pipeline.vhd @@ -0,0 +1,202 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity data_pipeline is +port ( + state_exit_bit: out std_logic; + clk: in std_logic; + round: in std_logic_vector(3 downto 0); + count: in std_logic_vector(6 downto 0); + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + newbit: in std_logic; + key: in std_logic; + last_rnd: in std_logic + ); +end entity data_pipeline; + +architecture Behavioral of data_pipeline is + +-- datapipeline related +signal d_p, d_n: std_logic_vector(127 downto 0); +signal d_out, s_nextbit: std_logic; + +-- keypipeline related signals +signal keybit : std_logic; + +-- mix columns related signals +signal mix_first_msb, mix_first_lsb, mix_first_out: std_logic_vector(3 downto 0); +signal mix_first_reduc, mix_first_notLSB: std_logic; + +signal mix_first_effs_p, mix_first_effs_n: std_logic_vector(3 downto 0); + +-- sbox related signals +signal sbox_port1, sbox_port2, sbox_port3, sbox_out: std_logic_vector(7 downto 0); +signal direction: std_logic; +signal sbox_sel : std_logic; + +-- Rotate the data pipeline +procedure rotate ( + variable s : inout std_logic_vector(127 downto 0); + variable b: in std_logic + ) is +begin + s := s(126 downto 0) & b; +end rotate; + +-- Make a swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +state_exit_bit <= d_out; -- Output bit + +sbox_port1 <= d_p(6 downto 0) & s_nextbit; -- First input of the SBOX multiplexer comming from the data pipeline + +mix_first: entity mixcolumns (moradi) port map (mix_first_msb, mix_first_lsb, mix_first_effs_p, mix_first_reduc, mix_first_notLSB, mix_first_out); -- Map the forward - first inverse mixcolumns component +s_box: entity sbox (maximov) port map(direction, sbox_sel, sbox_port1, sbox_port2, sbox_out); -- Map the sbox +k_pipe: entity key_pipeline (Behavioral) port map (keybit, clk, round_key, count_key, key, sbox_out, sbox_port2); -- Map the key pipeline + +process (clk) +begin + if clk'event and clk = '1' then + d_p <= d_n; + mix_first_effs_p <= mix_first_effs_n; + end if; +end process; + +process (d_p, mix_first_effs_p, round, count, count_key, newbit, key, sbox_out, mix_first_out, keybit, last_rnd) + variable s : std_logic_vector(127 downto 0); + variable m1 : std_logic_vector(3 downto 0); + variable v_nextbit: std_logic; -- nextbit + variable round_i : integer range 0 to 15; -- round of the data pipeline + variable count_i : integer range 0 to 127; -- cycle of the data pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + + -- Set the state + s := d_p; + m1 := mix_first_effs_p; + sbox_sel <= 'X'; + direction <= 'X'; + mix_first_notLSB <= 'X'; + mix_first_lsb <= (others => 'X'); + mix_first_msb <= (others => 'X'); + mix_first_reduc <= 'X'; + + -- Get the current round/cycle as int + count_key_i := to_integer(unsigned(count_key)); + round_i := to_integer(unsigned(round)); + count_i := to_integer(unsigned(count)); + + -- Modify the sbox selection input and selection forward - inverse depending on the cycle and the mode + if count_i mod 8 = 7 then + direction <= '1'; + sbox_sel <= '0'; + elsif count_i mod 8 = 0 then + direction <= '1'; + sbox_sel <= '1'; + end if; + + -- Input bit + if round_i = 0 then + v_nextbit := newbit xor keybit; + else + v_nextbit := s(127) xor keybit; + end if; + + -- XORed input bit + s_nextbit <= v_nextbit; + + -- SubByte + if (count_i mod 8 = 7) and (count_i /= 7) and (count_i /= 39) and (count_i /= 71) and (count_i /= 103) then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + end if; + + -- ShiftRows + -- Swap d-96 + if count_i = 127 or (count_i < 7 and round_i /= 0) then + swap(s(6), s(102)); + end if; + -- Swap d-64 + if (count_i >= 112 and count_i < 120) or (count_i >= 16 and count_i < 24 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0) then + swap(s(95), s(31)); + end if; + -- Swap d-32 + if (((count_i>= 72 and count_i < 80) or (count_i >= 104 and count_i < 112) or (count_i >= 8 and count_i < 16 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0))) then + swap(s(63), s(31)); + end if; + + -- Forward MixColumns / First for Inverse MixColumns + if (((count_i >= 0 and count_i < 8) or (count_i >= 32 and count_i < 40) or (count_i >= 64 and count_i < 72) or + (count_i >= 96 and count_i < 104)) and round_i /= 0 and last_rnd /= '1') then + + mix_first_msb <= s(127) & s(119) & s(111) & s(103); + mix_first_lsb <= s(126) & s(118) & s(110) & s(102); + + if (((count_i mod 8 = 3) or (count_i mod 8 = 4) or (count_i mod 8 = 6) or (count_i mod 8 = 7))) then + mix_first_reduc <= '1'; + else + mix_first_reduc <= '0'; + end if; + + if (count_i mod 8 = 7) then + mix_first_notLSB <= '0'; + else + mix_first_notLSB <= '1'; + end if; + + if (count_i mod 8 = 0) then + m1 := s(127) & s(119) & s(111) & s(103); + end if; + + s(127) := mix_first_out(3); + s(119) := mix_first_out(2); + s(111) := mix_first_out(1); + s(103) := mix_first_out(0); + + v_nextbit := s(127) xor keybit; + s_nextbit <= v_nextbit; + + end if; + + -- SubByte + if count_i mod 8 = 7 and (count_i = 7 or count_i = 39 or count_i = 71 or count_i = 103) then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + end if; + + -- Output bit assignment + if (round_i>0) then + d_out <= s(127) xor keybit; + else + d_out <= newbit xor keybit; + end if; + + -- Rotation of the pipeline + rotate(s, v_nextbit); + + -- State assignment + d_n <= s; + + mix_first_effs_n <= m1; + +end process; + +end architecture Behavioral; diff --git a/192_enc/key_pipeline.vhd b/192_enc/key_pipeline.vhd new file mode 100644 index 0000000..19ab9c9 --- /dev/null +++ b/192_enc/key_pipeline.vhd @@ -0,0 +1,131 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity key_pipeline is +port ( + keybit: out std_logic; + clk: in std_logic; + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + key: in std_logic; + sbox_out: in std_logic_vector(7 downto 0); + sbox_port2: out std_logic_vector(7 downto 0) + ); +end entity key_pipeline; + + +architecture Behavioral of key_pipeline is + +-- keypipeline related signals + +signal k_p, k_n: std_logic_vector(191 downto 0); +signal k_out: std_logic; + +-- Rotate the key pipeline +procedure rotate ( + variable s : inout std_logic_vector(191 downto 0); + variable b: in std_logic + ) is +begin + -- Wire AES-128 and AES-192 + s := s(190 downto 0) & b; +end rotate; + +-- Swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +-- Output key assigment +keybit <= k_out; +sbox_port2 <= k_p(7 downto 0); + +process (clk) +begin + if clk'event and clk = '1' then + k_p <= k_n; + end if; +end process; + +process (k_p, round_key, count_key, key, sbox_out) + variable s : std_logic_vector(191 downto 0); -- Key state + variable nextbit: std_logic; -- Input bit + variable round_key_i : integer range 0 to 15; -- round_key of the key pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + -- Assign round_key, cycle, state and version + round_key_i := to_integer(unsigned(round_key)); + count_key_i := to_integer(unsigned(count_key)); + s := k_p; + k_out <= 'X'; + + -- Input bit + if round_key_i = 0 then + nextbit := key; + else + nextbit := s(191); + end if; + + -- Swap/Unswap + if (count_key_i >= 0 and count_key_i < 8) and (round_key_i > 0) then + swap(s(31), nextbit); + end if; + if count_key_i >= 16 and count_key_i < 24 and (round_key_i > 0) then + swap(s(15), s(47)); + end if; + + -- Sbox + xor + if not (round_key_i = 0 and count_key_i <= 8) and + (count_key_i = 0 or count_key_i = 8 or + ((count_key_i = 176 or count_key_i = 184))) then + s(175 downto 168) := s(175 downto 168) xor sbox_out; + end if; + + -- Look up Rcon table for encryption/decryption + if + (((round_key_i=0)) and count_key_i=176) or + (((round_key_i=1)) and count_key_i=175) or + (((round_key_i=2)) and count_key_i=174) or + (((round_key_i=3)) and count_key_i=173) or + (((round_key_i=4)) and count_key_i=172) or + (((round_key_i=5)) and count_key_i=171) or + (((round_key_i=6)) and count_key_i=170) or + (((round_key_i=7)) and count_key_i=169) then + s(168) := not s(168); + end if; + + -- Kxor + if (round_key_i > 0) and + ((count_key_i <160)) then + s(159) := s(159) xor s(191); + end if; + + -- Decryption output bit swap + if (round_key_i>0) then + k_out <= s(191); + else + k_out <= key; + end if; + + -- Rotate the pipeline + rotate(s, nextbit); + + -- Assign state + k_n <= s; +end process; + +end architecture Behavioral; + diff --git a/192_enc/mix_columns.vhd b/192_enc/mix_columns.vhd new file mode 100644 index 0000000..800d22b --- /dev/null +++ b/192_enc/mix_columns.vhd @@ -0,0 +1,49 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity mixcolumns is + port ( + A: in std_logic_vector(3 downto 0); + B: in std_logic_vector(3 downto 0); + REG: in std_logic_vector(3 downto 0); + modRec: in std_logic; + notLSB: in std_logic; + OUTP: out std_logic_vector(3 downto 0)); +end entity mixcolumns; + +-- Taken from Bitsling + +architecture moradi of mixcolumns is + signal R0, R1, R2, R3: std_logic; + signal D0, D1, D2, D3: std_logic; + signal E0, E1, E2, E3: std_logic; +begin + + -- AND layer + R0 <= REG(3) and modRec; + R1 <= REG(2) and modRec; + R2 <= REG(1) and modRec; + R3 <= REG(0) and modRec; + + -- XOR-AND layer + D0 <= R0 xor (B(3) and notLSB) xor A(2); + D1 <= R1 xor (B(2) and notLSB) xor A(1); + D2 <= R2 xor (B(1) and notLSB) xor A(0); + D3 <= R3 xor (B(0) and notLSB) xor A(3); + + -- XOR layer + E0 <= D0 xor D1 xor A(0); + E1 <= D1 xor D2 xor A(3); + E2 <= D2 xor D3 xor A(2); + E3 <= D3 xor D0 xor A(1); + + OUTP(3) <= E0; + OUTP(2) <= E1; + OUTP(1) <= E2; + OUTP(0) <= E3; + +end architecture; \ No newline at end of file diff --git a/192_enc/sbox_bonus.vhd b/192_enc/sbox_bonus.vhd new file mode 100644 index 0000000..abaf9e7 --- /dev/null +++ b/192_enc/sbox_bonus.vhd @@ -0,0 +1,194 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity sbox is + port ( + INV: in std_logic; -- ZF=1 forward ZF=0 inverse + SEL: in std_logic; + INP1: in std_logic_vector(7 downto 0); + INP2: in std_logic_vector(7 downto 0); + OUP : out std_logic_vector(7 downto 0)); +end entity sbox; + +-- Taken from Maximov's CHES 2019 paper +-- The "bonus" version + +architecture maximov of sbox is + signal A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: std_logic; + signal Q15, Q4, Q0, Q14, Q3, Q1, Q6, Q8, Q9, Q2, Q10, Q7, Q12, Q11, Q5, Q13, Q17, Q16: std_logic; + signal H0, H1, H2, H4, H6, H7, H20, H8, H9, H10, H12, H15, H16, H19: std_logic; + signal S4, S2, S14, S1, S0, S5, S11, S6, S12, S7, S3, S15, S13: std_logic; + signal R0, R1, R2, R3, R4, R5, R6, R7: std_logic; + signal T0, T1, T2, T3, T4, T10, T11, T12, T13, T20, T21, T22, X0, X1, X2, X3, Y0, Y1, Y2, Y3 : std_logic; + signal Y00, Y01, Y02, Y13, Y23, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N16, N17 : std_logic; + signal U0, U1, U2, U3, U4, U5, U6, U7 : std_logic; + signal ZF: std_logic; +begin + + -- multiplexer input + U0 <= INP1(7) when SEL = '0' else + INP2(7); + U1 <= INP1(6) when SEL = '0' else + INP2(6); + U2 <= INP1(5) when SEL = '0' else + INP2(5); + U3 <= INP1(4) when SEL = '0' else + INP2(4); + U4 <= INP1(3) when SEL = '0' else + INP2(3); + U5 <= INP1(2) when SEL = '0' else + INP2(2); + U6 <= INP1(1) when SEL = '0' else + INP2(1); + U7 <= INP1(0) when SEL = '0' else + INP2(0); + + ZF <= INV; + + -- below: edited and pasted from the paper + + -- ctop.b + A0 <= U3 xnor U6; + Q15 <= U1 xnor ZF; + A1 <= U5 xor Q15; + A2 <= U2 xor A0; + A3 <= U4 xor A1; + A4 <= U4 xor U6; + A5 <= A2 when ZF = '1' else A4; -- MUX(ZF, A2, A4) + Q4 <= A3 xnor A5; + Q0 <= U0 xor Q4; + Q14 <= Q15 xor Q0; + A6 <= U0 xnor U2; + Q3 <= ZF xor A6; + Q1 <= Q4 xor Q3; + A7 <= U1 when ZF = '1' else Q0; -- MUX(ZF, U1, Q0) + Q6 <= A5 xnor A7; + Q8 <= Q3 xor Q6; + A8 <= Q1 when ZF = '1' else A4; -- MUX(ZF, Q1, A4) + Q9 <= U6 xor A8; + Q2 <= Q8 xor Q9; + Q10 <= Q4 xor Q9; + Q7 <= Q6 xor Q10; + A9 <= A0 when ZF = '1' else U4; -- MUX(ZF, A0, U4) + Q12 <= U7 xnor A9; + Q11 <= Q0 xor Q12; + A10 <= A6 when ZF = '1' else Q12; -- MUX(ZF, A6, Q12) + A11 <= A2 xor A10; + A12 <= A4 xor A11; + Q5 <= Q0 xor A12; + Q13 <= Q11 xor A12; + Q17 <= Q14 xor A12; + Q16 <= Q14 xor Q13; + + -- mulx.a + T20 <= Q6 nand Q12; + T21 <= Q3 nand Q14; + T22 <= Q1 nand Q16; + T10 <= (Q3 nor Q14) xor (Q0 nand Q7); + T11 <= (Q4 nor Q13) xor (Q10 nand Q11); + T12 <= (Q2 nor Q17) xor (Q5 nand Q9); + T13 <= (Q8 nor Q15) xor (Q2 nand Q17); + + X0 <= T10 xor (T20 xor T22); + X1 <= T11 xor (T21 xor T20); + X2 <= T12 xor (T21 xor T22); + X3 <= T13 xor (T21 xor (Q4 nand Q13)); + + + -- inv.a + T0 <= X0 nand X2; + T1 <= X1 nor X3; + T2 <= T0 xnor T1; + + Y0 <= T2 when X2 = '1' else X3; -- MUX(X2, T2, X3); + Y2 <= T2 when X0 = '1' else X1; -- MUX(X0, T2, X1); + T3 <= X2 when X1 = '1' else '1'; -- MUX(X1, X2, 1); + Y1 <= X3 when T2 = '1' else T3; -- MUX(T2, X3, T3); + T4 <= X0 when X3 = '1' else '1'; -- MUX(X3, X0, 1); + Y3 <= X1 when T2 = '1' else T4; -- MUX(T2, X1, T4) + + -- s0. a + -- calls inv.a; + Y02 <= Y2 xor Y0; + Y13 <= Y3 xor Y1; + Y23 <= Y3 xor Y2; + Y01 <= Y1 xor Y0; + Y00 <= Y02 xor Y13; + + + -- File: muln.a; + N0 <= Y01 nand Q11; + N1 <= Y0 nand Q12; + N2 <= Y1 nand Q0; + N3 <= Y23 nand Q17; + N4 <= Y2 nand Q5; + N5 <= Y3 nand Q15; + N6 <= Y13 nand Q14; + + N7 <= Y00 nand Q16; + N8 <= Y02 nand Q13; + N9 <= Y01 nand Q7; + N10 <= Y0 nand Q10; + N11 <= Y1 nand Q6; + N12 <= Y23 nand Q2; + N13 <= Y2 nand Q9; + N14 <= Y3 nand Q8; + + N15 <= Y13 nand Q3; + N16 <= Y00 nand Q1; + N17 <= Y02 nand Q4; + + -- cbot.b; + H0 <= N9 xor N10; + H1 <= N16 xor H0; + H2 <= N4 xor N5; + S4 <= N7 xor (N8 xor H2); + H4 <= N0 xor N2; + H6 <= N15 xor H1; + H7 <= H4 xor (N3 xor N5); + H20 <= H6 xor ZF; + S2 <= H20 xor H7; + S14 <= S4 xor H7; + H8 <= N13 xor H0; + H9 <= N12 xor H8; + S1 <= H20 xor H9; + H10 <= N17 xor H1; + H12 <= H2 xor (N1 xor N2); + S0 <= H6 xor H12; + S5 <= N6 xor (H9 xor (N8 xor H4)); + S11 <= H12 xor S5; + S6 <= S1 xor S11; + H15 <= N14 xor H10; + H16 <= H8 xor H15; + S12 <= S5 xor H16; + S7 <= S4 xnor (H10 xor (N9 xor N11)); + H19 <= H7 xnor S7; + S3 <= H16 xor H19; + S15 <= S11 xor H19; + S13 <= S4 xor (N12 xor H15); + R0 <= S0; + R1 <= S1; + R2 <= S2; + R3 <= S3 when ZF = '1' else S11; -- MUX(ZF, S3, S11) + R4 <= S4 when ZF = '1' else S12; -- MUX(ZF, S4, S12) + R5 <= S5 when ZF = '1' else S13; -- MUX(ZF, S5, S13) + R6 <= S6 when ZF = '1' else S14; -- MUX(ZF, S6, S14) + R7 <= S7 when ZF = '1' else S15; -- MUX(ZF, S7, S15) + + -- end of copying + + + OUP(7) <= R0; + OUP(6) <= R1; + OUP(5) <= R2; + OUP(4) <= R3; + OUP(3) <= R4; + OUP(2) <= R5; + OUP(1) <= R6; + OUP(0) <= R7; + +end architecture; \ No newline at end of file diff --git a/192_enc/test_vectors_192_enc.txt b/192_enc/test_vectors_192_enc.txt new file mode 100644 index 0000000..c02b76b --- /dev/null +++ b/192_enc/test_vectors_192_enc.txt @@ -0,0 +1,300 @@ +d777af9e7398a84af2134455ea7ab885 +b3a6913dbb3c023f429a8e90eb48b18c24c5d776b52e41ae +79D70C8C78CA5A47E70B8DC082615B63 +549b1c3e5734d7640a65fda93a954f55 +22c18c94b69250ddcbd072f0d97ebac0a0c815cb1e3ae7cd +A209260864DF2FF17F264FCCA405DCEF +08825e7a80de54d22b0663a114b1cec8 +9a76f9daf98ea07051aeca38151cbaeb2a48f1f9fb554d5c +E4FAF26DE5FAE07D0123F6F6C034C324 +06f16c066dff5a493727ae93d2e621b0 +d19a1d66b882723b82ebad42cd5dae28f768f4a522825b8f +213C5B61BDDAFC5C79B2A760A6051CCE +09e05053bc8a77f80f8361589dae28bd +de583d81dcebb525d11889ad24dcd5fd049369e73bfc1663 +570EA2158A6592DBB8D46F1080E52AFE +ff2823a5326d0b02b710b1d3c8a439ff +72dc339ed1ae6bc4c728e4738a8619ef5c03534be5731a72 +9CECE6171C50FA1BB6EC98D8C016D78B +ee0fad7bf56238f10306fb07ed8bdba0 +2dc9b4538bd750165b1563e2cd21929140599822bdf3f73e +636CF43F70BA6751098BA4785F10AA88 +f48d40b9cc475269bdf8d1bb1277386b +71ed1a83ffaef95496f2654efba8392ea4bbaeaf53880e15 +E6877F879E69EA27BD2CA3A990B96E68 +827b5e3411b40680d0fdede69c69efb0 +2063f9b9dad9a25f2b1bbc498a4ac58ba38e4d3c5d87484e +8F6CB079A5D5C4A392C1FC38BE1E83BB +0c78c8308b3cc5691db4cd3824b1e470 +a37949c730e9dd96f468b485291964bac05a44c49b0c3c37 +091C0EB2850805624EAC49D659A3EFE4 +5dcff6774002b4e3f2bcc1d58776ad90 +16aec8d024bb06a13356f8efebb6ac5f76845571bb7f3c79 +154C61DB7C16DB085FE310E87EC216E2 +522e316d81972ee7f2c805fbb87f82e6 +38a80a66f9286e712b65768ad06ddd2823d1fb884d2cf3ef +A52E161601D3F01F37C1D4298640C51F +8de1143125d95b7e7044b69259691e55 +1b3ddefe61a1de8a3883c52ea351d256ce42521fa73d3d57 +8FC2576736649BAC70270E23DAF3BB70 +be1b38087793afaf6327168c66f695ae +445d259d10dd2eca0d2cea37a2ec240c31caa114da59cf64 +24FF009B9AA22C2712AA2B3CF9F713F5 +db2a554e15cc92c257c7036909f397b5 +654ffbf67e55b98be4cb9d9ed7924f965a8d5f5d9810c63b +C87D17A0D587BEAF436D01A07CA2D046 +ac8f9326787b4198c337d535ca745419 +4371d285dc75bd826c01b01bb026f1b0f9a13892f25a249d +C6593D33BF72ACCB63E405D057588DE1 +ed104b57a0ca2d0b11e363c0ff9a9b69 +a6ca5ef44843eedd8a090a2a58067e5a467b8d65a5b55883 +B0FAD7CF8D944FFDF816A4C3E5D9E11A +951ae48f7f95f4edc618ce44f47dfaad +4a7726282625765c7202592c83ac700cb4f1ddb15365ffe5 +DCC07C35928BFAC1C238E4FA10BC406D +531415b6cbb09d8b618e8406406b0dbd +688cd956c10b3dd8ba5de1ffa7f8777b505608cbda297f06 +4D5913625BBECF4C5C63B97FCE54FDA1 +a72f6f34f4599e7a5376ac5126891a9e +ea0730a72188a5bbd8deff78cd35cd39695e2852aefded3d +3774719512086169BC773F76F237E452 +7d3cd730787bba4a72281504fc8351c2 +02d457b38418c5800738ed7f6209a98ec851b34f48e98f4e +F0331610AA78E9C870C79DCAC5B2BF8D +1b6f8458d8e826ac286677cbb21f1940 +87a4fb84cfdc26fbf227514164829ab90aa505f118a3e333 +53C1B82C6E7613EBF46D81DAEB738186 +6ce9cbb48f821f26cf4cb49eddbd75dc +533174345942195f22d8f6d0ca09a27232c2c71471f93e9d +AFBECB744BD6CA735F2465FD0F5CC023 +dda382597124569fe459b575249ab7a1 +3e2fe3622610da0fc244018251ff4de8ada64d68fe1a149f +38F15F384C90459EA6485DEC30AF1E64 +8c708cf9afa43e7009a974abdc631eae +d6a15524a4b3715d9791b136bfaac5f6acd8706b9925a29a +3C1BC8CAAD9A53971E38059163229AA5 +dc64f27b78db352ae462452f6445d769 +96ac517f24fb4bf588d329db31f54c2d3b86616be48f8b95 +F3815A405B02E9A86B373C513881F899 +be8a737b05f2d6dfc5864cb5d9a595de +ebe18725ad29faf06e8889d13f1748917ef2291627ca86a3 +EED3CA90A57700330037082E8A4B49D0 +a5bbb5c2966c46e7885ff557fee51062 +cecd20f5a34165bcb65035880fc1cbf48154e617282e351b +7AAABFE9D62998A5A4BEEA40D37C0E64 +a34c68ef4a44405992414426516e1806 +09914347c704552f9c4751a714b9cabaf47bc57412d0ac0c +6E000CBACBD0EF42A87C3CFB3CD365D2 +ce5378bebf536a829956ea9eb3694a3f +b16e9b51d837dba4cac391fa547c06be5e112a0e32705ec9 +75C54CDF46E2CC96098921F5A41DB7C8 +1f163a1c0de11b079571842b101dfe53 +3b7ec2870f4f2d4eb66440f1ed7684fcd88958f258c99c65 +DA7F8B049F5623A01E2FEA2889226997 +978e83fa39b7e5772552650e9ddb5836 +15978fbcd137849962426d061b05df176a5cccdb4affd3a8 +E5D77185793A216586F1396BB7FDC9D9 +0af2a4ede8b1923084166be929dbdcfa +b03b41bd14d7a39c320d82170cc2d1a5beb05f13610e8a23 +A9C427D084B072399AA7E19E930B97C0 +f001bb6f68e5968ef29ca5b96ea8fdf9 +894bdf4fa741cdbec23a20bb57f3ca117e7038edd875b908 +A70B347AE46750D1962343E88DD74B51 +685cf59d4b9830d1d84781673c85aec0 +ee824493858af7f556e199717434b2645eadeb73f0d4ba6c +F36F720C385B64FE888DADB12CB7D976 +dbc0ea7a5aac6e907f9a11c5a6c39a0b +905532f9c3a20ac7cd3e6c661832dc1268de0898fc643cd6 +ED6762353B22C70B5A03D3400F23BD72 +0d9e22ab31a6ac6e0b5e8e4bc142ae3e +70397dbf8b0614636f569c7f82741e23ed0fcc09c9e10130 +5F857D34D2897829D0D768ABF329A132 +11770073f939baae42ef39b739c68015 +a2bfce7dbee488fd9a0d49a34ee31517ac6d8ddb6f5ef7f1 +337D4C62DC2E96267026A1B55A202CB4 +ad74fb88dce3baf27125740078db8bd0 +be5b813d352a3beee0b5c0a8c0d9d0c97db1055a62d7682e +F2699D8F508241E268A260EC8C7AF261 +fef06e550d84a65de06d2495937e4694 +e65976496750ced3f32bba9e48b5abd7dcf2e275d8d23a5c +9A1BEEB01B5777EB12E93BB832E84B19 +b1cabf780499ff44da6f2a4780718727 +630f86974b7654ee11104ab4634fc5ab914e08001b0681c4 +183FCBF4B87FB19441E635D02CDCB605 +fabef68686e4b10f6ef660988caa1557 +21ed01a17d348146f426ad6bcfc2538b41fddf082ee461fa +2FF37342C82D5B8DF5EA440F259E581B +d9552e70592ac67cd831af08f8987fba +27bfcdfe59a5904cdc5bee32c826bcdf8a0c6e82a36f231a +B4E920B50698B32FC6B5D7E5E9286A19 +79e6399583a1195b7ccde96adb8f8136 +832caed1786727b13316e7bf24d314dcb56d0bb091ccbebb +69AE7F867BBB59D00B0BD8D6EE02C832 +5091566aa068bf4b310d8884a3050bce +68427c4c87c85d3d94bea08423841f8b1b86ac312d5e3456 +23750DD27CD81EB2DFA165FCEC0A3371 +27c831b30a5bda48c024565da6c1a0f5 +9c48422a66895e1ccb468e3e80712ea1862f857357dacbdf +8C4784E77F2225EADC138625CA452241 +bae2046461abf04f2e539808dd224606 +2d9308039b30f974cb28d33e23174b5908e5faeb772fe365 +702D46EDC72D761E0042C83C61788469 +e75ac9cb6d35656efa55cc1e0d13f550 +786a579cec6f89b9ff7e12c95c41cee06c464817b9f4fcec +0F80B7FAB8C0161254BF4D6FA5A98FEF +675ad6ca9fd41186d12f8577c6cb47dc +01e1d327725ff200b67a61e35d798da3e22b6159ea4f7a1d +43001DF9B133586F91A36E933B20AD1D +c472fc2544efb0893cb7075f2442aa50 +bc676af7cb575e3190dcf6d8412d279a8c21a491668aaec8 +AA2F64B1A830A5D55BC4C21191C65479 +c61f44774cad0c7a85bd920945d546e8 +bd2d2d3d36e3e446721273666ef464796d88354cde3b10af +127247B69117B4C6958035A96D349F17 +690f45050237c00e3e51883566090984 +bf11d4c2ac06b799f18db63519a24f1cf1562b42264fb219 +ADB75183186589B80789812E7FCFC7E8 +d5e372b19095727373b3a9e69dd721eb +62c07a86df7064eed39b01cf07b3745606563f2969c455a9 +854CDE6A2B930379431F41CACDADEC7B +4b02570cbcec36bab6f0fffc5948c53a +ef0006e295b986db7a4721309cdfab319792e43515c4c233 +AA0BDDA43E07C8DBF455A814AE63C3A7 +7b01afd473c745e8fc33c2f8c8937968 +185da1aa73581eb0fcc4f1e77065a071712b3c08bd2c04bc +354EBAD1110813FCD7DE1282D18CD919 +8846e9429764a3356036e89ce9f6fa51 +74eb6a2c51cbe1a48a1519b9815d721a060cf3579a803126 +136E31EB453545E0FDD36D413FE56ED7 +ad509bac44f5ae9dc29538a49c0f4def +988770515b8d903ece4e033262a3da1f86d53d91c527cc23 +91A2F4194E69061672F9D56482C6E455 +905e344329ec19d625985187883ffe9e +53284c602f814a9db4d4fbd6d5f209aab1a5ed32104c0a1f +58FC14B6D08E93C1161200C9ADC76721 +cfbe7e3706cea9d9ddbb92f3e5d5dde0 +8ab4d5aadac85420ce886cec0f55725ec47e5519ac9c847b +237D2C441D1C142458899D78139C1B46 +55e8052425652c4e904dc434cdc89735 +5bdf6d576e04dc6589fd80e5fe034ec4dac416e5b84cbe92 +9C4A40C4C08AF9B6BE03FB4165AB9B8C +3adefb25b6d9555b9bc603e968c48c6d +f72d585300f46c6c13fde4b4a071854069ed4c90e91f7978 +5F54014EDB0C0BB5B9873254DB3C652B +37f478511a08c3a224fe1ebbc03873d6 +0c3c89ab918194563ea3bde39c40c4ffa3fc119ee65e5f6c +88D7A69AAF5C78AE0388C93EC9F6140F +cfdf5d23b30c50710279687a8770e2a0 +1b4b85094c7f0b44c74881cad8fdfdc68015e49085250930 +79F2EFD45694D72C5A06913343C6A063 +d38b20d9ea99fbc3c08b87b6e558f0e4 +eaca39d612c7831b8fb758106187a0ae2f37e4a390b0e99b +A33212D4A36C1A020C29148B99F5019D +ac82aac3bd475e03de9a9447dc7f7532 +9a00169cd06a8e4398556509f5d4165f3cba40c8929ed94b +6C92DD9406EC128619CFBA1116D7AC1C +0bf63628075e181c3f12306f368ae38a +7a767f46567465bf9bae85586bd2c5a4c5b4c50c7221d26b +E920E417B886AE645E560FDFA9B1D9E1 +9b8be9a52e3e434e6447ad4021bb9208 +5421fffb5329c5fbc87d3eed9848f0073c719b2a0c05b7b2 +13759FE45D416745242DCFD58C7A07BC +d3e4945387143dd425f2bf8a71daabb1 +016763251c3a451322bdebd2fbcada13e33f24c7b1732fb0 +CB33DAD2FBD77188DAFE143367752AC6 +0d54ae2f640e7a6376845d6c742ccab0 +f93ad6f76d1fe10d3a431a88e903075ae7f03a8f35906968 +D079F1F2B4E754ABB68EACD216B2EFF6 +131481752d9374b4782a109ed0097efa +f66890816076aa09faa9c9bfd64f3ba1e7ebd759385b9f70 +D6DED8A343BA32017FDB0C6D4AA3F0F1 +0812d9aa019355c10f615f816dc45f3d +1e4924c090c90e733cc9dec866d01f9111943726eacbe009 +832AF5CBD043EFB15029CB83B3212CE5 +598678d9d9eb5071cc0c1d714a7b9a22 +ef8779a4bc4bee170322da69ca98fe5f2a46c6008dcb7414 +D58F3DE5C8DC91ADB84AA062BCD5215D +07fddc43c02a9bc73eafd00e079b8a02 +08fe352e459e9bf31c67abf68d234fad3bcc4e6a255ab788 +0BC1AF46641D7C9B44EB89F9A69B0F2A +e949facf7f21ea54cce5765f490038bd +953d349e88cd1cda7cb3100289973d608875fe5813ea0da2 +4AA0B2D0F181C9930DE8D10606908E36 +5692370dad13d630b9fe1749cd8c0e87 +402a3712ced4e5792adfd6f3ddd5092d33831e22efb0eccd +0E0E47258CFF97657E241C6DA8601B6E +289a758903b868a88752abb07f11fc9b +b945ff85cc67371f77c0c9f04e6744216a4cfd131db91392 +ABF78B7FFD654AFEB2332F1D184A0CC4 +be32053f8ad252b26cc29c09cefd4e86 +1e258239f69d9a468b9b6fb035ea841db4defa86f83adaa1 +CE27898538A0D9626A8D53665E89B791 +b34c1b85696b397cdfe09a0271c672a2 +f532257f27383d57b76f33ae2c973c5cfbacc17fa930ccf6 +E68A373C0EADA92F5701236061087849 +55eb76037e94fe15867421f8f995ece3 +ba5eb4159bf15bda83d32e394112345d89db661f9b81eb9c +E0533AEA1A9385A2BEC0CD03F67F7AF7 +76397b59f399c025633b307606e1a71a +dd4b202123b786840000341804211d95ac550fd811107667 +8C91AB1513813F689B648E61D35DF976 +e27729e553b2df19ae63363952652599 +f7e25e0a2a38582c4a1b757aaee5ee0341574ec01fce9fb1 +DEC131CDE8378E7EAB5BADEDC240D318 +1bbd038eb0003a5f0fe270bd237c508f +08ab2d304e45c0d4b7ddeda85b4261837eae0c6ef8e9cf4e +17651AC920F792AE5E36AB7D1D6FACB3 +e85d465df3f93910218d02585598ebad +d6d0aa996f83f049318b67b96bebb2a2947585741baf8a34 +EE66CBB9F650AB108D5FE47331505C6C +2ac7ecbce822677979d984326476d4b4 +732e29c5cdeb500d3dab5f5720918e3692485d1506a5aeb3 +DEA3813E1D1BB454352EFB190D5E9FC2 +55c284cdd6e66e139cda89a5175bd372 +36e848810fdc4150adb72eed1469a941c2ff8de3fe4b5d44 +571C0D1EDBE584633E5FAFF4EAF8631A +9085beb48434982413a7744f7d960713 +e86e1c234cd406dfb1220669267a5f55a08be71147a987b9 +9D934F9AE855A5AFDBC81E1ECA30DF24 +5029878667654883b8c523e045827151 +eece08360d6b342956e2de24b9b4ff8413bc01870b2eec66 +BF4CEAC672A49DF6734CD3FAC62B4A65 +b5e54d36ebb6c2aecf9cd5833c33f5ff +318d6fafb3f658678de0ca081f52cdb792180c8dd6e3148d +2BE34E7EF0D5D3607EE8C319F5403261 +e1e8cfe6dde6a849e9e3e32c776a2821 +f870f4e31afcd7b208838d6599ebd436e7be26407fac56db +0047C1BB0671AFE9201A915EF13F7321 +390a888a2dfe922192225adf6ccd3571 +f06333b4123c2d9efde293d697dc2b834450f158b8a16f6d +861D0B8F7E840D92D123A51B0012E27E +57343a38a12d85ebbe49e5424635e8f0 +535aa2ec6513bbfabdc5067d45cebf7c1c14753f6be310d2 +F863B4A53B541C99309FAB6A53CDCC5F +7df928c35d4bebed026c8c973326cd6c +450ac5e2a2029cb8faa5ddb5de45a854d3ac417ff382935a +1D23600B0A1017D16EBFD09DCF17E6BA +e06e45f4152598f64e5e676e632167d4 +3600cdb1621946820e9c38e0cc1e4a400de7afbcc146692a +F04B0E00204C632EBFA4B3BF43C317B8 +720eb85dd995de1a780641bf2a3dae3d +93103efd64d7e4da0662dce5b9ae1a1f405ec22e26889068 +313D2556CCF0BC64ECC0FF00FDD1ACA1 +bf3c2726dc70ba123d7cf4d081f3bfff +31b5034abc044c7b4e1af7dd32123c77aa4fc8fbb330d797 +24732537D960CD03A9ECAA7EB1ECED4F +4365571d10b0218887f00d07e47e87e0 +f7c3e9b728f6c24e7c400b48f78ad5a84b43179ec29abf11 +FA09A8F584D4FDEB1B86EB9146F4532F +bccbdec61ba3f30f8f9f0ebced5888ce +5031adec3816e32aefff20262790a2f52f7a09212a6f41e5 +A9263A76164535F972B437574A51CC95 +c957b5a663584a966ef65b7dd069ce47 +2e05304ec60e384ebd92feb4058d098fe6db408982e1a250 +8A76DC53889C365CDF2E9B78DEE7197D +977ad623f36540a80db153c14090d8df +fd650b994ec62f1b12c742eb06b965c7dcf03af46f9e4207 +109AFA948C2C1DD11C84644B7783876A +91e914535c2380b072e2d061d23e811c +f45825fff32d7aef65656abd36c97c4c35a7cd5e5a8e4384 +226D231786A49E83C9E5D87E8034F2D2 diff --git a/192_enc/testbench.vhd b/192_enc/testbench.vhd new file mode 100644 index 0000000..4cb64b0 --- /dev/null +++ b/192_enc/testbench.vhd @@ -0,0 +1,113 @@ +library std; +use std.textio.all; +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use work.all; + +entity tb_aes is +end tb_aes; + +architecture tb of tb_aes is + + constant clock_cycle : time:= 100 ns; + + file vector_file : TEXT; + + signal ct : std_logic; + signal pt : std_logic; + signal clk : std_logic; + signal rst : std_logic; + signal done : std_logic; + signal key : std_logic; + + component AES + port ( + ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic); + end component AES; + +begin + + mut: AES port map (ct, done, clk, rst, pt, key); + + process + begin + clk <= '1'; wait for clock_cycle/2; + clk <= '0'; wait for clock_cycle/2; + end process; + + process + variable tmp_line : line; + variable key192 : std_logic_vector(191 downto 0); + variable pt128 : std_logic_vector(127 downto 0); + variable ct128 : std_logic_vector(127 downto 0); + variable buffer128 : std_logic_vector(127 downto 0); + variable test_ctr : integer range 0 to 1000000; -- can fail if too many vectors + variable loading_ctr : integer range 0 to 255; -- can fail if too many vectors + variable reading_ctr : integer range 0 to 127; -- can fail if too many vectors + begin + file_open(vector_file, "test_vectors_192_enc.txt", read_mode); + test_ctr := 1; + + while not (endfile(vector_file)) loop + + -- we first read a single test vector from a file + readline(vector_file, tmp_line); hread(tmp_line, pt128); + readline(vector_file, tmp_line); hread(tmp_line, key192); + readline(vector_file, tmp_line); hread(tmp_line, ct128); + -- reading a single test vector is done + + rst <= '0'; + wait until rising_edge(clk); + + rst <= '1'; + loading_ctr := 0; + loading_loop: loop + if loading_ctr <= 127 then -- load pt only in the first 128 cycles always + pt <= pt128(127-loading_ctr); + end if; + + key <= key192(191 - loading_ctr); + if loading_ctr = 191 then + exit loading_loop; + end if; + + loading_ctr := loading_ctr + 1; + wait until rising_edge(clk); + end loop; + + + waiting_loop: loop + wait until rising_edge(clk); + if done = '1' then -- done signals indicates that the encryption/decryption is almost over, and the result will be available during the following 128 cycles + exit waiting_loop; + end if; + end loop; + wait until rising_edge(clk); -- wait until the next rising_edge + + reading_ctr := 0; + reading_loop: loop + buffer128(127 - reading_ctr) := ct; + if reading_ctr = 127 then + exit reading_loop; + end if; + reading_ctr := reading_ctr + 1; + wait until rising_edge(clk); + end loop; + + assert buffer128 = ct128 report "======>>> DOES NOT MATCH <<<======" severity failure; + report "passed vector #: " & integer'image(test_ctr); + test_ctr := test_ctr + 1; + + end loop; + assert false report ">>> ALL GOOD <<<" severity failure; + wait; + end process; +end tb; diff --git a/192_enc_dec/aes.vhd b/192_enc_dec/aes.vhd new file mode 100644 index 0000000..dba75f3 --- /dev/null +++ b/192_enc_dec/aes.vhd @@ -0,0 +1,34 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity AES is +port ( ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic; + mode: in std_logic + ); +end entity; + +architecture Behavioral of AES is + + -- pipeline related signals + signal state_exit_bit, last_rnd : std_logic; + signal round, round_key : std_logic_vector(3 downto 0); + signal count : std_logic_vector(6 downto 0); + signal count_key : std_logic_vector(7 downto 0); + +begin + + ct <= state_exit_bit; + + data_pipeline0: entity data_pipeline (Behavioral) port map(state_exit_bit, clk, round, count, round_key, count_key, mode, pt, key, last_rnd); + controller0: entity controller (Behavioral) port map(round, count, round_key, count_key, done, last_rnd, clk, rst); + +end architecture; diff --git a/192_enc_dec/controller.vhd b/192_enc_dec/controller.vhd new file mode 100644 index 0000000..f307715 --- /dev/null +++ b/192_enc_dec/controller.vhd @@ -0,0 +1,69 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity controller is +port ( + round: out std_logic_vector(3 downto 0); + count: out std_logic_vector(6 downto 0); + round_key: out std_logic_vector(3 downto 0); + count_key: out std_logic_vector(7 downto 0); + done: out std_logic; + last_rnd: out std_logic; + clk: in std_logic; + rst: in std_logic + ); +end entity; + +architecture Behavioral of controller is + + signal rnd_p : std_logic_vector(3 downto 0); + signal cnt_p : std_logic_vector(6 downto 0); + signal merged_counter_n : std_logic_vector(11 downto 0); + signal merged_counter_p : std_logic_vector(11 downto 0); + signal merged_counter_plus : std_logic_vector(11 downto 0); + +begin + + -- We should prefer synchronous rst signal + -- it helps when we want to later use it in AEAD circuits + + process (clk) + begin + if rising_edge(clk) then + merged_counter_p <= merged_counter_n; + end if; + end process; + + process (merged_counter_p) + variable ctr: integer range 0 to 4095; + begin + ctr := (to_integer(unsigned(merged_counter_p)) + 1) mod 4096; + merged_counter_plus <= std_logic_vector(to_unsigned(ctr, merged_counter_plus'length)); + end process; + + merged_counter_n <= (others => '0') when rst = '0' else merged_counter_plus; + + done <= '1' when cnt_p = "1111111" and rnd_p = "1011" else '0'; + last_rnd <= '1' when rnd_p = "1100" else '0'; + + process (merged_counter_p) + variable total_cycles : integer range 0 to 4095; -- should never take more than ~2k clock cycles anyway + begin + + total_cycles := to_integer(unsigned(merged_counter_p)); + + round_key <= std_logic_vector(to_unsigned(total_cycles / 192, round_key'length)); + count_key <= std_logic_vector(to_unsigned(total_cycles mod 192, count_key'length)); + + end process; + + rnd_p <= merged_counter_p(10 downto 7); + cnt_p <= merged_counter_p(6 downto 0); + round <= rnd_p; + count <= cnt_p; + +end architecture; diff --git a/192_enc_dec/data_pipeline.vhd b/192_enc_dec/data_pipeline.vhd new file mode 100644 index 0000000..7254986 --- /dev/null +++ b/192_enc_dec/data_pipeline.vhd @@ -0,0 +1,313 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity data_pipeline is +port ( + state_exit_bit: out std_logic; + clk: in std_logic; + round: in std_logic_vector(3 downto 0); + count: in std_logic_vector(6 downto 0); + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + mode: in std_logic; + newbit: in std_logic; + key: in std_logic; + last_rnd: in std_logic + ); +end entity data_pipeline; + +architecture Behavioral of data_pipeline is + +-- datapipeline related +signal d_p, d_n: std_logic_vector(127 downto 0); +signal d_out, s_nextbit: std_logic; + +-- keypipeline related signals +signal keybit : std_logic; + +-- mix columns related signals +signal mix_first_msb, mix_first_lsb, mix_first_out, mix_second_msb, mix_second_lsb, mix_second_out, mix_third_msb, mix_third_lsb, mix_third_out: std_logic_vector(3 downto 0); +signal mix_first_reduc, mix_first_notLSB, mix_second_reduc, mix_second_notLSB, mix_third_reduc, mix_third_notLSB: std_logic; + +signal mix_first_effs_p, mix_first_effs_n, mix_second_effs_p, mix_second_effs_n, mix_third_effs_p, mix_third_effs_n: std_logic_vector(3 downto 0); + +-- sbox related signals +signal sbox_port1, sbox_port2, sbox_port3, sbox_out: std_logic_vector(7 downto 0); +signal direction: std_logic; +signal sbox_sel : std_logic; + +-- Rotate the data pipeline +procedure rotate ( + variable s : inout std_logic_vector(127 downto 0); + variable b: in std_logic + ) is +begin + s := s(126 downto 0) & b; +end rotate; + +-- Make a swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +state_exit_bit <= d_out; -- Output bit + +sbox_port1 <= d_p(6 downto 0) & s_nextbit when mode='0' else + d_p(126 downto 119); -- First input of the SBOX multiplexer comming from the data pipeline + +mix_first: entity mixcolumns (moradi) port map (mix_first_msb, mix_first_lsb, mix_first_effs_p, mix_first_reduc, mix_first_notLSB, mix_first_out); -- Map the forward - first inverse mixcolumns component +mix_second: entity mixcolumns (moradi) port map (mix_second_msb, mix_second_lsb, mix_second_effs_p, mix_second_reduc, mix_second_notLSB, mix_second_out); -- Map the second inverse mixcolumns component +mix_third: entity mixcolumns (moradi) port map (mix_third_msb, mix_third_lsb, mix_third_effs_p, mix_third_reduc, mix_third_notLSB, mix_third_out); -- Map the third inverse mixcolumns component +s_box: entity sbox (maximov) port map(direction, sbox_sel, sbox_port1, sbox_port2, sbox_out); -- Map the sbox +k_pipe: entity key_pipeline (Behavioral) port map (keybit, clk, round_key, count_key, mode, key, sbox_out, sbox_port2); -- Map the key pipeline + +process (clk) +begin + if clk'event and clk = '1' then + d_p <= d_n; + mix_first_effs_p <= mix_first_effs_n; + mix_second_effs_p <= mix_second_effs_n; + mix_third_effs_p <= mix_third_effs_n; + end if; +end process; + +process (d_p, mix_first_effs_p, mode, mix_second_effs_p, mix_third_effs_p, round, count, count_key, newbit, key, sbox_out, mix_first_out, mix_second_out, mix_third_out, keybit, last_rnd) + variable s : std_logic_vector(127 downto 0); + variable m1, m2, m3 : std_logic_vector(3 downto 0); + variable v_nextbit: std_logic; -- nextbit + variable round_i : integer range 0 to 15; -- round of the data pipeline + variable count_i : integer range 0 to 127; -- cycle of the data pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + + -- Set the state + s := d_p; + m1 := mix_first_effs_p; + m2 := mix_second_effs_p; + m3 := mix_third_effs_p; + sbox_sel <= 'X'; + direction <= 'X'; + mix_first_notLSB <= 'X'; + mix_second_notLSB <= 'X'; + mix_third_notLSB <= 'X'; + mix_first_lsb <= (others => 'X'); + mix_second_lsb <= (others => 'X'); + mix_third_lsb <= (others => 'X'); + mix_first_msb <= (others => 'X'); + mix_second_msb <= (others => 'X'); + mix_third_msb <= (others => 'X'); + mix_first_reduc <= 'X'; + mix_second_reduc <= 'X'; + mix_third_reduc <= 'X'; + + -- Get the current round/cycle as int + count_key_i := to_integer(unsigned(count_key)); + round_i := to_integer(unsigned(round)); + count_i := to_integer(unsigned(count)); + + -- Modify the sbox selection input and selection forward - inverse depending on the cycle and the mode + if count_i mod 8 = 7 then + if mode='1' then + direction <= '0'; + elsif mode='0' then + direction <= '1'; + end if; + sbox_sel <= '0'; + elsif count_i mod 8 = 0 then + direction <= '1'; + sbox_sel <= '1'; + end if; + + -- Input bit + if round_i = 0 then + v_nextbit := newbit xor keybit; + else + v_nextbit := s(127) xor keybit; + end if; + + -- XORed input bit + s_nextbit <= v_nextbit; + + -- SubByte + if (count_i mod 8 = 7) and (count_i /= 7) and (count_i /= 39) and (count_i /= 71) and (count_i /= 103) then + if mode='0' then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + else + s(126 downto 119) := sbox_out; + end if; + end if; + + -- ShiftRows + -- Swap d-96 + if count_i = 127 or (count_i < 7 and round_i /= 0) then + if mode='0' then + swap(s(6), s(102)); + else + swap(s(118), s(22)); + end if; + end if; + -- Swap d-64 + if (count_i >= 112 and count_i < 120) or (count_i >= 16 and count_i < 24 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0 and mode = '0') or + (count_i >= 8 and count_i < 16 and round_i /= 0 and mode = '1') then + swap(s(95), s(31)); + end if; + -- Swap d-32 + if (((count_i>= 72 and count_i < 80) or (count_i >= 104 and count_i < 112) or (count_i >= 8 and count_i < 16 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0)) and mode = '0') or + (((count_i>=88 and count_i < 96) or (count_i >= 120) or (count_i>=8 and count_i<16 and round_i/=0) or + (count_i>=24 and count_i<32 and round_i /= 0)) and mode = '1') then + swap(s(63), s(31)); + end if; + + -- Forward MixColumns / First for Inverse MixColumns + if (((count_i >= 0 and count_i < 8) or (count_i >= 32 and count_i < 40) or (count_i >= 64 and count_i < 72) or + (count_i >= 96 and count_i < 104)) and round_i /= 0 and last_rnd /= '1' and mode = '0') or + (((count_i >= 26 and count_i<34) or (count_i>=58 and count_i<66) or (count_i>=90 and count_i<98) or (count_i>=122) or + (count_i>=0 and count_i<2 and round_i > 1)) and round_i /= 0 and mode = '1') then + + if mode='0' then + mix_first_msb <= s(127) & s(119) & s(111) & s(103); + mix_first_lsb <= s(126) & s(118) & s(110) & s(102); + else + mix_first_msb <= s(25) & s(17) & s(9) & s(1); + mix_first_lsb <= s(24) & s(16) & s(8) & s(0); + end if; + + if (((count_i mod 8 = 3) or (count_i mod 8 = 4) or (count_i mod 8 = 6) or (count_i mod 8 = 7)) and mode='0') or + (((count_i mod 8 = 0) or (count_i mod 8 = 1) or (count_i mod 8 = 5) or (count_i mod 8 = 6)) and mode='1') then + mix_first_reduc <= '1'; + else + mix_first_reduc <= '0'; + end if; + + if (count_i mod 8 = 7 and mode='0') or (count_i mod 8 = 1 and mode='1') then + mix_first_notLSB <= '0'; + else + mix_first_notLSB <= '1'; + end if; + + if (count_i mod 8 = 0 and mode='0') then + m1 := s(127) & s(119) & s(111) & s(103); + elsif (count_i mod 8 = 2 and mode='1') then + m1 := s(25) & s(17) & s(9) & s(1); + end if; + + if mode = '0' then + s(127) := mix_first_out(3); + s(119) := mix_first_out(2); + s(111) := mix_first_out(1); + s(103) := mix_first_out(0); + + v_nextbit := s(127) xor keybit; + s_nextbit <= v_nextbit; + else + s(25) := mix_first_out(3); + s(17) := mix_first_out(2); + s(9) := mix_first_out(1); + s(1) := mix_first_out(0); + end if; + end if; + + -- Second for Inverse MixColumns + if((count_i >= 28 and count_i < 36) or (count_i>=60 and count_i<68) or (count_i>=92 and count_i < 100) or + (count_i>=124) or (count_i>=0 and count_i<4 and round_i > 1)) and round_i /= 0 and mode='1' then + + mix_second_msb <= s(27) & s(19) & s(11) & s(3); + mix_second_lsb <= s(26) & s(18) & s(10) & s(2); + + if (count_i mod 8 = 0) or (count_i mod 8 = 2) or (count_i mod 8 = 3) or (count_i mod 8 = 7) then + mix_second_reduc <= '1'; + else + mix_second_reduc <= '0'; + end if; + + if count_i mod 8 = 3 then + mix_second_notLSB <= '0'; + else + mix_second_notLSB <= '1'; + end if; + + if count_i mod 8 = 4 then + m2 := s(27) & s(19) & s(11) & s(3); + end if; + + s(27) := mix_second_out(3); + s(19) := mix_second_out(2); + s(11) := mix_second_out(1); + s(3) := mix_second_out(0); + end if; + + -- Third for Inverse MixColumns + if((count_i >= 30 and count_i < 38) or (count_i>=62 and count_i<70) or (count_i>=94 and count_i < 102) or + (count_i>=126) or (count_i>=0 and count_i<6 and round_i > 1)) and round_i /= 0 and mode='1' then + + mix_third_msb <= s(29) & s(21) & s(13) & s(5); + mix_third_lsb <= s(28) & s(20) & s(12) & s(4); + + if (count_i mod 8 = 1) or (count_i mod 8 = 2) or (count_i mod 8 = 4) or (count_i mod 8 = 5) then + mix_third_reduc <= '1'; + else + mix_third_reduc <= '0'; + end if; + + if count_i mod 8 = 5 then + mix_third_notLSB <= '0'; + else + mix_third_notLSB <= '1'; + end if; + + if count_i mod 8 = 6 then + m3 := s(29) & s(21) & s(13) & s(5); + end if; + + s(29) := mix_third_out(3); + s(21) := mix_third_out(2); + s(13) := mix_third_out(1); + s(5) := mix_third_out(0); + end if; + + -- SubByte + if count_i mod 8 = 7 and (count_i = 7 or count_i = 39 or count_i = 71 or count_i = 103) then + if mode='0' then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + else + s(126 downto 119) := sbox_out; + end if; + end if; + + -- Output bit assignment + if (round_i>0) then + d_out <= s(127) xor keybit; + else + d_out <= newbit xor keybit; + end if; + + -- Rotation of the pipeline + rotate(s, v_nextbit); + + -- State assignment + d_n <= s; + + mix_first_effs_n <= m1; + mix_second_effs_n <= m2; + mix_third_effs_n <= m3; + +end process; + +end architecture Behavioral; diff --git a/192_enc_dec/key_pipeline.vhd b/192_enc_dec/key_pipeline.vhd new file mode 100644 index 0000000..e121201 --- /dev/null +++ b/192_enc_dec/key_pipeline.vhd @@ -0,0 +1,166 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity key_pipeline is +port ( + keybit: out std_logic; + clk: in std_logic; + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + mode: in std_logic; + key: in std_logic; + sbox_out: in std_logic_vector(7 downto 0); + sbox_port2: out std_logic_vector(7 downto 0) + ); +end entity key_pipeline; + + +architecture Behavioral of key_pipeline is + +-- keypipeline related signals + +signal k_p, k_n: std_logic_vector(191 downto 0); +signal k_out: std_logic; + +-- Rotate the key pipeline +procedure rotate ( + variable s : inout std_logic_vector(191 downto 0); + variable b: in std_logic + ) is +begin + -- Wire AES-128 and AES-192 + s := s(190 downto 0) & b; +end rotate; + +-- Swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +-- Output key assigment +keybit <= k_out; +sbox_port2 <= k_p(7 downto 0); + +process (clk) +begin + if clk'event and clk = '1' then + k_p <= k_n; + end if; +end process; + +process (k_p, mode, round_key, count_key, key, sbox_out) + variable s : std_logic_vector(191 downto 0); -- Key state + variable nextbit: std_logic; -- Input bit + variable round_key_i : integer range 0 to 15; -- round_key of the key pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + -- Assign round_key, cycle, state and version + round_key_i := to_integer(unsigned(round_key)); + count_key_i := to_integer(unsigned(count_key)); + s := k_p; + k_out <= 'X'; + + -- Input bit + if round_key_i = 0 then + nextbit := key; + else + nextbit := s(191); + end if; + + -- Swap/Unswap + if (count_key_i >= 0 and count_key_i < 8) and (round_key_i > 0) then + swap(s(31), nextbit); + end if; + if count_key_i >= 16 and count_key_i < 24 and (round_key_i > 0) then + swap(s(15), s(47)); + end if; + + -- Sbox + xor + if not (round_key_i = 0 and count_key_i <= 8) and + (count_key_i = 0 or count_key_i = 8 or + ((count_key_i = 176 or count_key_i = 184))) then + s(175 downto 168) := s(175 downto 168) xor sbox_out; + end if; + + -- Look up Rcon table for encryption/decryption + if + (((round_key_i=0 and mode='0') or (round_key_i=7 and mode='1')) and count_key_i=176) or + (((round_key_i=1 and mode='0') or (round_key_i=6 and mode='1')) and count_key_i=175) or + (((round_key_i=2 and mode='0') or (round_key_i=5 and mode='1')) and count_key_i=174) or + (((round_key_i=3 and mode='0') or (round_key_i=4 and mode='1')) and count_key_i=173) or + (((round_key_i=4 and mode='0') or (round_key_i=3 and mode='1')) and count_key_i=172) or + (((round_key_i=5 and mode='0') or (round_key_i=2 and mode='1')) and count_key_i=171) or + (((round_key_i=6 and mode='0') or (round_key_i=1 and mode='1')) and count_key_i=170) or + (((round_key_i=7 and mode='0') or (round_key_i=0 and mode='1')) and count_key_i=169) then + s(168) := not s(168); + end if; + + -- Kxor + if (round_key_i > 0) and + ((count_key_i <160)) and + (mode='0') then + s(159) := s(159) xor s(191); + end if; + + -- Decryption and-xors + if (mode='1') and (count_key_i>=96) and (count_key_i<128) then + nextbit := s(31) xor nextbit; + s(31) := s(63) xor s(31); + end if; + + -- Decryption output bit swap + if (mode = '1') then + if (round_key_i>0) then + if (((round_key_i*192 + count_key_i) / 128) mod 3 = 2) then + k_out <= s(127); + elsif (((round_key_i*192 + count_key_i) / 128) mod 3 = 1) then + k_out <= s(63); + else + k_out <= s(191); + end if; + else + if (count_key_i >= 128) then + k_out <= s(63); + else + k_out <= key; + end if; + end if; + else + if (round_key_i>0) then + k_out <= s(191); + else + k_out <= key; + end if; + end if; + + -- Decryption and-xors AES-192 + if (mode='1') and (count_key_i>=160) then + s(127) := s(159) xor s(127); + end if; + if (mode='1') and (count_key_i>=32) and (count_key_i < 64) and (round_key_i>0) then + s(63) := s(95) xor s(63); + s(95) := s(127) xor s(95); + end if; + + -- Rotate the pipeline + rotate(s, nextbit); + + -- Assign state + k_n <= s; +end process; + +end architecture Behavioral; + diff --git a/192_enc_dec/mix_columns.vhd b/192_enc_dec/mix_columns.vhd new file mode 100644 index 0000000..800d22b --- /dev/null +++ b/192_enc_dec/mix_columns.vhd @@ -0,0 +1,49 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity mixcolumns is + port ( + A: in std_logic_vector(3 downto 0); + B: in std_logic_vector(3 downto 0); + REG: in std_logic_vector(3 downto 0); + modRec: in std_logic; + notLSB: in std_logic; + OUTP: out std_logic_vector(3 downto 0)); +end entity mixcolumns; + +-- Taken from Bitsling + +architecture moradi of mixcolumns is + signal R0, R1, R2, R3: std_logic; + signal D0, D1, D2, D3: std_logic; + signal E0, E1, E2, E3: std_logic; +begin + + -- AND layer + R0 <= REG(3) and modRec; + R1 <= REG(2) and modRec; + R2 <= REG(1) and modRec; + R3 <= REG(0) and modRec; + + -- XOR-AND layer + D0 <= R0 xor (B(3) and notLSB) xor A(2); + D1 <= R1 xor (B(2) and notLSB) xor A(1); + D2 <= R2 xor (B(1) and notLSB) xor A(0); + D3 <= R3 xor (B(0) and notLSB) xor A(3); + + -- XOR layer + E0 <= D0 xor D1 xor A(0); + E1 <= D1 xor D2 xor A(3); + E2 <= D2 xor D3 xor A(2); + E3 <= D3 xor D0 xor A(1); + + OUTP(3) <= E0; + OUTP(2) <= E1; + OUTP(1) <= E2; + OUTP(0) <= E3; + +end architecture; \ No newline at end of file diff --git a/192_enc_dec/sbox_bonus.vhd b/192_enc_dec/sbox_bonus.vhd new file mode 100644 index 0000000..abaf9e7 --- /dev/null +++ b/192_enc_dec/sbox_bonus.vhd @@ -0,0 +1,194 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity sbox is + port ( + INV: in std_logic; -- ZF=1 forward ZF=0 inverse + SEL: in std_logic; + INP1: in std_logic_vector(7 downto 0); + INP2: in std_logic_vector(7 downto 0); + OUP : out std_logic_vector(7 downto 0)); +end entity sbox; + +-- Taken from Maximov's CHES 2019 paper +-- The "bonus" version + +architecture maximov of sbox is + signal A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: std_logic; + signal Q15, Q4, Q0, Q14, Q3, Q1, Q6, Q8, Q9, Q2, Q10, Q7, Q12, Q11, Q5, Q13, Q17, Q16: std_logic; + signal H0, H1, H2, H4, H6, H7, H20, H8, H9, H10, H12, H15, H16, H19: std_logic; + signal S4, S2, S14, S1, S0, S5, S11, S6, S12, S7, S3, S15, S13: std_logic; + signal R0, R1, R2, R3, R4, R5, R6, R7: std_logic; + signal T0, T1, T2, T3, T4, T10, T11, T12, T13, T20, T21, T22, X0, X1, X2, X3, Y0, Y1, Y2, Y3 : std_logic; + signal Y00, Y01, Y02, Y13, Y23, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N16, N17 : std_logic; + signal U0, U1, U2, U3, U4, U5, U6, U7 : std_logic; + signal ZF: std_logic; +begin + + -- multiplexer input + U0 <= INP1(7) when SEL = '0' else + INP2(7); + U1 <= INP1(6) when SEL = '0' else + INP2(6); + U2 <= INP1(5) when SEL = '0' else + INP2(5); + U3 <= INP1(4) when SEL = '0' else + INP2(4); + U4 <= INP1(3) when SEL = '0' else + INP2(3); + U5 <= INP1(2) when SEL = '0' else + INP2(2); + U6 <= INP1(1) when SEL = '0' else + INP2(1); + U7 <= INP1(0) when SEL = '0' else + INP2(0); + + ZF <= INV; + + -- below: edited and pasted from the paper + + -- ctop.b + A0 <= U3 xnor U6; + Q15 <= U1 xnor ZF; + A1 <= U5 xor Q15; + A2 <= U2 xor A0; + A3 <= U4 xor A1; + A4 <= U4 xor U6; + A5 <= A2 when ZF = '1' else A4; -- MUX(ZF, A2, A4) + Q4 <= A3 xnor A5; + Q0 <= U0 xor Q4; + Q14 <= Q15 xor Q0; + A6 <= U0 xnor U2; + Q3 <= ZF xor A6; + Q1 <= Q4 xor Q3; + A7 <= U1 when ZF = '1' else Q0; -- MUX(ZF, U1, Q0) + Q6 <= A5 xnor A7; + Q8 <= Q3 xor Q6; + A8 <= Q1 when ZF = '1' else A4; -- MUX(ZF, Q1, A4) + Q9 <= U6 xor A8; + Q2 <= Q8 xor Q9; + Q10 <= Q4 xor Q9; + Q7 <= Q6 xor Q10; + A9 <= A0 when ZF = '1' else U4; -- MUX(ZF, A0, U4) + Q12 <= U7 xnor A9; + Q11 <= Q0 xor Q12; + A10 <= A6 when ZF = '1' else Q12; -- MUX(ZF, A6, Q12) + A11 <= A2 xor A10; + A12 <= A4 xor A11; + Q5 <= Q0 xor A12; + Q13 <= Q11 xor A12; + Q17 <= Q14 xor A12; + Q16 <= Q14 xor Q13; + + -- mulx.a + T20 <= Q6 nand Q12; + T21 <= Q3 nand Q14; + T22 <= Q1 nand Q16; + T10 <= (Q3 nor Q14) xor (Q0 nand Q7); + T11 <= (Q4 nor Q13) xor (Q10 nand Q11); + T12 <= (Q2 nor Q17) xor (Q5 nand Q9); + T13 <= (Q8 nor Q15) xor (Q2 nand Q17); + + X0 <= T10 xor (T20 xor T22); + X1 <= T11 xor (T21 xor T20); + X2 <= T12 xor (T21 xor T22); + X3 <= T13 xor (T21 xor (Q4 nand Q13)); + + + -- inv.a + T0 <= X0 nand X2; + T1 <= X1 nor X3; + T2 <= T0 xnor T1; + + Y0 <= T2 when X2 = '1' else X3; -- MUX(X2, T2, X3); + Y2 <= T2 when X0 = '1' else X1; -- MUX(X0, T2, X1); + T3 <= X2 when X1 = '1' else '1'; -- MUX(X1, X2, 1); + Y1 <= X3 when T2 = '1' else T3; -- MUX(T2, X3, T3); + T4 <= X0 when X3 = '1' else '1'; -- MUX(X3, X0, 1); + Y3 <= X1 when T2 = '1' else T4; -- MUX(T2, X1, T4) + + -- s0. a + -- calls inv.a; + Y02 <= Y2 xor Y0; + Y13 <= Y3 xor Y1; + Y23 <= Y3 xor Y2; + Y01 <= Y1 xor Y0; + Y00 <= Y02 xor Y13; + + + -- File: muln.a; + N0 <= Y01 nand Q11; + N1 <= Y0 nand Q12; + N2 <= Y1 nand Q0; + N3 <= Y23 nand Q17; + N4 <= Y2 nand Q5; + N5 <= Y3 nand Q15; + N6 <= Y13 nand Q14; + + N7 <= Y00 nand Q16; + N8 <= Y02 nand Q13; + N9 <= Y01 nand Q7; + N10 <= Y0 nand Q10; + N11 <= Y1 nand Q6; + N12 <= Y23 nand Q2; + N13 <= Y2 nand Q9; + N14 <= Y3 nand Q8; + + N15 <= Y13 nand Q3; + N16 <= Y00 nand Q1; + N17 <= Y02 nand Q4; + + -- cbot.b; + H0 <= N9 xor N10; + H1 <= N16 xor H0; + H2 <= N4 xor N5; + S4 <= N7 xor (N8 xor H2); + H4 <= N0 xor N2; + H6 <= N15 xor H1; + H7 <= H4 xor (N3 xor N5); + H20 <= H6 xor ZF; + S2 <= H20 xor H7; + S14 <= S4 xor H7; + H8 <= N13 xor H0; + H9 <= N12 xor H8; + S1 <= H20 xor H9; + H10 <= N17 xor H1; + H12 <= H2 xor (N1 xor N2); + S0 <= H6 xor H12; + S5 <= N6 xor (H9 xor (N8 xor H4)); + S11 <= H12 xor S5; + S6 <= S1 xor S11; + H15 <= N14 xor H10; + H16 <= H8 xor H15; + S12 <= S5 xor H16; + S7 <= S4 xnor (H10 xor (N9 xor N11)); + H19 <= H7 xnor S7; + S3 <= H16 xor H19; + S15 <= S11 xor H19; + S13 <= S4 xor (N12 xor H15); + R0 <= S0; + R1 <= S1; + R2 <= S2; + R3 <= S3 when ZF = '1' else S11; -- MUX(ZF, S3, S11) + R4 <= S4 when ZF = '1' else S12; -- MUX(ZF, S4, S12) + R5 <= S5 when ZF = '1' else S13; -- MUX(ZF, S5, S13) + R6 <= S6 when ZF = '1' else S14; -- MUX(ZF, S6, S14) + R7 <= S7 when ZF = '1' else S15; -- MUX(ZF, S7, S15) + + -- end of copying + + + OUP(7) <= R0; + OUP(6) <= R1; + OUP(5) <= R2; + OUP(4) <= R3; + OUP(3) <= R4; + OUP(2) <= R5; + OUP(1) <= R6; + OUP(0) <= R7; + +end architecture; \ No newline at end of file diff --git a/192_enc_dec/test_vectors_192_enc_dec.txt b/192_enc_dec/test_vectors_192_enc_dec.txt new file mode 100644 index 0000000..c7203dc --- /dev/null +++ b/192_enc_dec/test_vectors_192_enc_dec.txt @@ -0,0 +1,400 @@ +0 +571571fe43c721f461565368e121be111 +9d3a6933d273f4a85ebb7937acd04d8135814aea597ac55d1 +9F2D1639DFB77794B80094437D92B011 +1 +ab604d0d3b84054a87833f480418d8331 +d52eb30cb6e225ced207ee2e73fbd1439bdd52b029e19c9e1 +C65180B1B36A634765163E685FD13449 +1 +0b2695394c3187de9e35c900f9dceb051 +10689fc8d31ec8baaaa793e8f6f00cf120059f77907cbdaf1 +DB8DEE7429FA446C216C94B7BF380442 +0 +57c6bc81dc9908c3c238e4035ad807601 +8d8ced73837cfd0f620f0bdb64d1f4baad707557be822d451 +B7FEA63663EBE42323AFF2102E58CF3F +1 +42b1b34de9ecf4d282100c7196331dff1 +b44898c929bad451a9848e4d444304e191917b09a1ddd7c51 +12C8B867F3180E9B6B1EC1552B02893A +1 +10ca9fc00d73b520dbfe5369aa2e4e2b1 +9d15b374af03eea5f6b94af27d425b620f31bf0599de7c411 +87E1C2F6379BD80291393B258FEA9560 +1 +36df52e808547c4d772ff70247589a531 +4b4ff9e0a44fdab0721a661422f85304eb4e0e802f2d3b4f1 +81528A6F24514147B1CE0DDDFD9A3A5B +0 +1ebc0c06ba8b706345d1681c6e684ff01 +ed604333e9f6f85e58843e3a258b136ad14d9952e12b72281 +6EBFA5D5FA540B54B14F2AEA9630513F +0 +6bf5763f8699119c1078fb604f7bffa41 +eeae01fae79139697d391206ca4e7232f8e12896c2343f7c1 +36E3D40D784F28174894F33D3F8B4EC6 +0 +d7272531c41ec474e9fd302716de052e1 +bde396f0f0c5f76a7a353c0c07d107a4be8b9772b5d805441 +1C5C41E5A952A5B7165A0FF7CD983176 +1 +d69bdd5ebb4923dc7ee9e02eaf29136b1 +962f0ff11dfea9d03c4a9dd47bcbdfd6e2a5fff41da327f31 +6F7294AFF92887EEC3305A825BE64E9B +1 +50b629cc41746626e6e533561903decc1 +4d616f357ab0b4896be14e89a096abc0d3041fc663be39361 +AB326F8D2ECF0C97A54FDCE70079678C +0 +7756fdfdea8b86c7f0dbbba36ebe8a541 +793f066545949e7a3b5281654a7eaae37d3ddb32828b08ae1 +F05C221463EFC9EF7A92FC066592102F +0 +aa179dd8c2f7ccdebc7a905c417b18bf1 +d44d0f86d32cd31af793dd1fa9d02faf16b20b0be762f2fd1 +FBB5CD4698720F4060D5CF9CA6E69A3B +1 +57ce1e34d5934ad31ea3251c4b80e6bf1 +3b95ef8062707f32f87d91d3f7f272b924eb52e78c3fdd181 +13BE6F88F23CD91762AD687E3F7C90C8 +0 +fb4728bf90b79ce647f13671ab6d7d3f1 +070c21f477b1c12f7a8b857230f1a28e47e0feb71d3d104d1 +88D62EABB8C8EE3F5A3BF882FAAA0178 +1 +39c7680c6190ad6d1250e0825b3aff391 +0cdb830aedb6d5699c43b91a0f9563cbf0a00bbaaf2cc2021 +69BACE52FAD5A3A61114A21E8C007B6E +0 +7b2475195e705e5aae080edc26d2024c1 +809490ce1181c44c38e801ce90d552ca5b8f256624272a5e1 +8B9947C059636357F75B084CEF632676 +0 +1cebdbe1a0731580ebd38ec40fa847dc1 +959b532781715907adaaebfd9c2f635f6ec02d913385bd4a1 +0DAAEBA03B9ABA4612CFC84F41A415C9 +0 +5dcefa22b818a70775bc8db17274b2c21 +6b40c3b25168f36d4174ad0681e3b8e2db436124e465b9a51 +6ADCF82460A89836AAD9255CFD41B3DA +0 +7baad28ba1d9bb92bb54753172f995781 +f9e30385484ce640794b400979eb98e7ebe745152725c68d1 +28B05D15CF9002B2ACC3964DA04534C5 +1 +0667098a78b5913c52bae10564969caf1 +df0d1ab54c51e5f84778340942b4d288ca8ecabcbd59216d1 +4BE909764BB7BCA42766D770BA70B139 +1 +67818675843d971a0db1d440325aaebf1 +3220e162fa432986372c046eb4710dcc06dadd7127ce466f1 +CDD814EB128C17F35FB07DF3638B2C21 +1 +0a05f3810a77ff59458c5da69be95ca51 +a025ba6ea68d469bb9d9bde51b08bc59c464913f78dca8a41 +FB3F861E17102114FD291D91F09CF0EC +0 +1076ccfb745c08087789725411602c541 +0810e18858d37585206b3f6d3406dba5dc79e93fd09dc2491 +9BA020CE67749FAE2A4C062FAED7A69D +1 +e6ddecb0244981f9b33432c4cae56bac1 +f9991db8ebc75f1c4b71f9d8f4bce31ad82b98c0e10b40e61 +109D559EF773B8EAE6FC96A0943F07CF +1 +6187fb30acbd32fa68f184695c4b01f31 +3702aaa8ec003005f8806cce4521abc50ea1caa9cd1cd2631 +ED5AFA97346FF5CD1972AC02D633ECB0 +1 +5a042f4f1b2b7ce2ae9f4a707d9c85cd1 +4befc4b840fb23d78da4e6319ad24a9a0761fac5038c66c31 +D34A4DF9C47BFF5BF974C7B3AC22BB8A +1 +3b386e29bddedce364ee24be6bbaedea1 +a1a064756c2dbaee715cd25135a2fc20c9d6bb3f2fb39cd31 +FFA3695AB1F6F2885CBB499680D25889 +0 +3413e19bde89cf4a07202ce6e201b6ee1 +223a5ce72c97de3a4781ef6bf8cc172a7d286bee3ec125581 +6D33C27CC0A5D39A10E3F401EFB3FF8A +0 +fca1f0feb2574197cd040e159a0ed8871 +41cbfe642bbca72c26e937fb64cfc1c4b423626c59456d2b1 +AD37C388E1F6068ED17DB5D4FB140790 +0 +c62f85548560e30c9c9fee1245f3c6871 +4db62520f2bea66a92ca105e3e7f496b7015295730afac331 +87D8C0965EE5B637D1B75651A98D955A +0 +5e893a3c3a1fd120b49ed9b24a628cdb1 +6445d59e47ccb32dc61c50f6b25d70dc49f33bc4b6d72da81 +7D192CEE009542FBEAE728634E27E845 +1 +161f503083c08995ae69f2415c5d41d41 +99f1d0f83dad1973457c11c6443a50077e72bf98887f3ef31 +7F24D9D54CC4569FAD5CA930643FD5EB +0 +8bcc87f3f4daff98d908cc15bff0c6bb1 +dbbb1ee8194d80f73b25e5673d54b9f5582acdf165b756651 +1510B271F0A294A3313B31A2D5E4B4C2 +0 +74a15da0025382e1b1b11635212d34231 +551645dc61a4e376441dfeb06fb9c52c8c42e664146312bd1 +DCC9C071714AF7042F43DF5C183238E1 +0 +f1afb0a238dd721b874a93401dc8e6cb1 +6f7edc8c4e28f17d52d4522ddb2436f7b9e85314afcef0031 +225981075C2A3C686A17DC632202E66D +0 +5c77cc4f6594a275755bb7edc5fc0e7a1 +f3aa3ac35ba4e5bbbc23fc88c81229d908dbfabab32abbf11 +2A7103F01420D816E2C046EA5BC0E311 +0 +beb54470bd33c1884c9fdf1e47daa45c1 +58daad5539eb5cbfdc3a2514de4336edd205d3479a8b0a091 +0648DC88054EF24ACAE33327FB8307E6 +0 +0a3fb67cf5dd5aa5d1dc54c295a2db081 +86dbb694f24184baf5b1adc1f74f14d9f4ac1d44a9e778f81 +36C9DD2BF5EC6CEFC29EE9998DD3631F +1 +afc4e68ed3a95fa1260c86b754dd150d1 +f4ec27b165eb5783a8b80e53fc23eeac5ac19df4d74c5ce21 +2974C0A0D66A8BF96E31DBEB624D692B +1 +38e3f395314a2170b7f5a9735df6fa9a1 +7ed2933c2bf6f64feaa8bf7485837139c71b2df8af2035e61 +9DB7BA835ECB1BFB359F756B33256B94 +0 +a5311c8e275e741efb0cce68fa18f6581 +4c3ed149cc71d608c9783f2340dee1c775248ec694183d591 +27DA6FAC527A964E5F6E396595B01FBA +0 +33c538765df3bc89f44e99574183acbd1 +61cda1f10d877ce2347723861839219987057569e1112ee61 +B70A8EE3912E9493A15E09334C818EB6 +0 +1156afc9cef51e63fa720d28fd3b8b851 +16aade87a09cb5e63c2c27001c15afb272429376cc3febac1 +1C8BEAF66EA3E0C0A4077028F887C5D2 +1 +6ecd575433b954d47e16856d6f9642ea1 +876063c61710fa7f9a379561a1a8fe42bbe5e2df099277641 +9BC1E518F6F45C896FD45B4C7B657785 +1 +27cefabe4c205dbfb91ff153567ccc181 +cb8e3d72bc3a5a2fb19bdff750765457db5aac3906c2cb801 +70B89DC59B13E996A7B069625A9CFD05 +1 +ac1178d1bbf39a465c0e1886382478201 +3530a57edf1e7cb0d5ffcd18f540294fa1b9d3e2ecd0c9e21 +E5725FCEC842F22552053985603DD209 +1 +d2a3e3fdd7ca833b60a896dbd93b24991 +9b60af099d375f7ffaf8acb3f1a571abcc6fd18e658e89471 +307D530EB34CCF352D950A1949758202 +1 +e67fdd07bb60abd6868f8aa722b09b4b1 +41886c4b1dbb6ce6ee70925d06f94dd8f070f24ddc2c02651 +C7F0764F4E385AF3A7E29E7083D75A8C +1 +21375f0aee09d481b95bef43054b2c4a1 +715f4dc14ae713950c571d2d384eccbe15074a75e45798b41 +005A7493872ECDCA1EC1D8A211B2E636 +0 +8ab496f448c00d5b4efb7eab426be35e1 +3ac5c56c240d27c0c794efe92d8300213e2c1bad7c59d9351 +D4A2520445C364FBEBCBA1BB064E50E4 +0 +bbdecf68249fed424f28293654c7886e1 +03cb083b59b5f0454f1ae18725d3209b825e3e55822c7d941 +D70B437875725B8C218B026D4D753AE5 +1 +21c0c01514b967af00cf344259e602381 +d8443ab538d631dbad4fa1a03f841b55b0ca534add6c634f1 +0C2C814502B41427D2CEF5B1DB87077C +1 +da0842cf2f46424f35fb6a70c31af7d61 +dbc3d9c140413b5fc22dc9671f0439963006b75c72a1652e1 +EC8570CD0ECE18CCD934B1ED6C447251 +1 +80625dd0ffc192191e358ed550e9d4fb1 +79215c1e5b4bc84efd2b0d46120c20dd775e2d5565bd8be11 +418B87DD05E42BA36EC6A2E31F29059D +0 +4320112ab0b8a55e4af3913a5cb52e411 +7c43b8675a5cbf440a0313a895ceaabf996e374c9e904a181 +84DCD4534F70DB6F5D595A521CE07DB2 +1 +bb3ea169c27dee37a12b1a98f6226a931 +6482a1de945e7182a7ad6e530ffc520276eb4843326c2c051 +DA4392F268D1B5662DDA03F7F456642E +1 +6bb3d3a355643a1004a4e14e17ffcdc31 +c088faecec3d16742678e0110ca0021a5160868ce3cf1a2d1 +F032E072419E01C1EF33C62AE9214FCA +1 +e3aa256a844824c7474bcd99025c4ebf1 +ddb0a485f74a6c96ffe36394a89cc72229f1890a2ffa79e51 +3383F87817CE936D5C11A9E86E999B1F +0 +cafb6010127015ac063b78d49a9b2d0d1 +318998941e371c770d1766cdc80eae595a38406741930d941 +160651B2F9896BE90CE9CEBB32E3C082 +0 +c3685c1f343155ce3e84d534c4177e711 +8303372bfe279507816fd728fd1c9c3741b5275646567b321 +8BF25F283C90E63C8608C56D7F1B9ADF +1 +172e7ceddb288b63661ec43be27142fb1 +9b9bf38212cd97d06b27695120ede3e1db1185c25251a5a01 +876084A8C49239200695C7292EC80E4A +0 +61297565f4b95c19c335be7c37b9cc251 +5f47a619f5279bef01fd850eb385bcab09f20c918c8983ae1 +D76E73AE42E1E5D2A843B0DC627E78B6 +0 +89ac3146324bc7b7aecfdba09b3319b21 +428f20972bf60416af159f7b38c0b6d14300ea22c5cfae0d1 +153C6E2B37A89F26D81A030EA5ACE610 +1 +296b9765c77cf7c98e66e6b901b2134a1 +242ef9844daa35026ec409ac1f098d4b33acbb502742bd421 +AA8765608AA11B197FD7BE7E7D48E485 +0 +66fbaee3ca7c21a95b8748cd20be62c21 +c018fcd1d311ff0534c2445480082f4b7676336a1d708d2b1 +449BF6D506DAEBAC3045130CC8755C9E +0 +cf9e502fe434e98df2e793b944775a4a1 +20f457f93c2fa03194a6ea7c16d0cc12932fafa3e28c0da71 +99952C694CDB058CDF18F66F5FDF3456 +0 +5e9cae009945767bde0bc075ec03d68a1 +888fd56dd9ad3b87af0304127a98375e1ec182a92b3154981 +668F65F3F8D2C8C42023F74FE816E4AD +1 +5d843da386669c2e6aea39035c1daf821 +ba31af6858a70525e3cca2804606601f1003845c64ace7761 +6299070E3A0CA8EEAB69C035284515E5 +0 +9cca88a1f0619dcd4e300a83c07e01c61 +7dd827edf7727d098f15cd11f16f971862f215c4a0a3247b1 +C5E9CF35A087AE46843736FAC3C60424 +1 +a4a0250d31195f0b24401fcb4029c1011 +f7706c8f54ad5b1ecc7bc13cb9ebd303d9f1de7c9aba58ac1 +102200CD3F671D232224ECE05524496D +1 +4411f96d6e063daaea262692400fff321 +5db23c96593f474b403267fe9459312a1f6b45f3ea2097e31 +6EAEC8E4F29756A06B7C223C40A9E3B0 +1 +e6914207248a5489a294128105b7d2681 +a5480187111bed06ebd0fd8981501ddfdbe1281b4b81f7c31 +871BC63E138AD9E8507F69C9D38383E8 +0 +8e90131ee3ab5ec73d5ad4c7b2b8a3441 +6c0b6fcdfb3b765b4eea5fd19d3181815fe79fc465a32e711 +EECA17AA25F270021DF1104CB1FFCE22 +0 +1fdfdb036f4800cbb7c3af230b7dffba1 +883d5c8bb8322d487fac04ba6ffe321fd8c092842125b6281 +646B84B9EBD77217ABA2401868A5D047 +1 +e851f2e45ba991753ffe0cf2d73c9a131 +f4039b78179d732a7b8d4cf13c692de1bad732c7a1b9e23f1 +65FD5480110744FB6116A33B6ECD1D88 +0 +8e26c1202a02d0eb0dcc3f47b2f789831 +e2acc744270e1c52d8d6a284153a178dab65d93cd372958a1 +D83594CA1B5D6E9770F588F460F8D0E8 +0 +c7ee7ead3bfaac47b2f8a6da011ed6391 +daa47f76d432054ade3485fa5b6e5ef1b8c889d7b65d99501 +B3E8422C3BA8CF9900E67659B9BAA0AE +0 +4c5dd1b67d17c80eb715ac16eba051fd1 +85e39cde0f53351efe752fcf2065d7462ac7c6d212eacb791 +E438D8D1CCB5C98AEC4FC9A037BD66A3 +0 +6ea87316b095f0d9bf4441e73b0aa5f31 +289e2bfd1c1cb192207b6bb4f9b712611acfa6b09a7401031 +0774450A9F68F6969D90FB97ADF36978 +1 +09968522fe44cdb59574a37b6281fc441 +79d57f646102676059d4dba8af036ab16d2270068c9421b71 +FAE48285857DBC9D65292BB1033AD6DE +0 +d993d994ba4ee9854beb278a9b0e8d811 +8d9527329297b02ea114f140161c66cadce8264ba1a95c561 +1456EE32A116DF99A21F71FAFCCB19B9 +1 +b7b7b7a8301d039b223d5cd8be1ffe051 +de93274f801a2cdc49df227facbece405960f4af6f2adfc41 +CC7897D9B194E0BF1177C2BD7F610469 +0 +33c7dbedd5ea3da80224bcf5fae19e121 +30605074bba746f59de30c52847ea5ff473de8632edceac71 +EB3CC93354E950EB31A7F1B8402D82D8 +1 +be3f5eeda5e2295def639604f0d1a9591 +391a6daef19c00d6c5e17ee90ac31baae8724c9f4ea5d8fc1 +8176C1D0C178577D047CA9DCFEBDFF01 +0 +0bf9e3240e5a38a9d6059a6e19dcb4761 +1d858a1f48f9c94ba9e2b7f697a71692850b1d07cbcd98561 +FC74A69321E2D9C19E027C5647284484 +1 +7891ba47bef10eec8d25c22bed0849951 +1c2df95f4888da8320de091af0e99ce09b21defc951698a61 +2352118F86F6C58646F1550109AAA57D +0 +880fa2d954a9fb2512b78b6197eccfd41 +e1606cf528b9e7493c3fd380659257ddc43defe8d430dbf11 +9AF8E98C7B3DDFA67DA3DE45B5BD758E +0 +9337abcec64796ea31089a61fde693bf1 +f681894e4f71ecc12ff04b4fd0588addc82d50121ca1090a1 +31989DD15540F3FA261D3E119BEC7623 +1 +a9b00b1adc1edc0f7d8b144542dbb4c61 +e366d44a6f9607f1f3353a8aa148af78c70c4b3b373c231a1 +4C070F04B07FFDFD00B4C3B7A3F6CD84 +0 +9f6bf3633d7e93abe270a82d367a6e801 +324d48ebcb39fda58c5fdc0645eb299da610b9158fef084c1 +C1B028B865C22EE3E98CE483FB908B43 +0 +9edd5b0a55b268d0fb95e25c1ce1f4891 +867a3198338ec17a473dc81aedad1f74ef8bda74ac89eed01 +2A082A07672E00AC3536446FC74F64C4 +0 +bcc50b7fdbadb6f3f3baac920af335ee1 +6ca5d493afc3b45ec94db76479f1a2b7a731bb3cd5c1ef7d1 +B9327D9FA2A20C74F928B5EB2940E08D +0 +d1f95a70f8055c608bea8010a3d37ef11 +c5f8d338923b673ce22dc34753456f4e7613469f2774bfb91 +FE94B01DA01683B13BAC522148AE02F0 +0 +c168df51753ae8e4d5a0a176f8a604071 +6e322fd984cb985ca925f4bc4d6a9103eff0d4497470a61d1 +7201DB924BF42E4A5F4B0AE5537DD5BA +0 +f5805f0cc7d6314d1c80014eca949e961 +8a54e06030c6264bf40d2955c15206b6199ef15e885bc7001 +B3A51AC2095ACBB1C01ED2B01D992D1A +0 +7c71e709842bee1bdd7462cb69c8f74d1 +7676db1a6d2b5c9555181401da61beb57a7c05ed78568ebe1 +BEF6A6903EAC52FE0212E24F142EA3B6 +0 +7373b18976bfbe1d8ad83dd8aea714da1 +070a2d1730d5a209ac5284140329ffbc6298a2cdeabb51451 +7D7E5E8151F0297E3CF044FA7CD259E6 +0 +729156b24829236a50b556a15bae5d201 +ec63d28f45676672d7579e23a58ba9bc84aa5141ff8c19d91 +B47B4FCADD4D2F02B1265AD6113DB36F diff --git a/192_enc_dec/testbench.vhd b/192_enc_dec/testbench.vhd new file mode 100644 index 0000000..97a4204 --- /dev/null +++ b/192_enc_dec/testbench.vhd @@ -0,0 +1,118 @@ +library std; +use std.textio.all; +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use work.all; + +entity tb_aes is +end tb_aes; + +architecture tb of tb_aes is + + constant clock_cycle : time:= 100 ns; + + file vector_file : TEXT; + + signal ct : std_logic; + signal pt : std_logic; + signal clk : std_logic; + signal rst : std_logic; + signal done : std_logic; + signal key : std_logic; + signal mode : std_logic; + + component AES + port ( + ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic; + mode: in std_logic); + end component AES; + +begin + + mut: AES port map (ct, done, clk, rst, pt, key, mode); + + process + begin + clk <= '1'; wait for clock_cycle/2; + clk <= '0'; wait for clock_cycle/2; + end process; + + process + variable tmp_line : line; + variable mode_v : std_logic; + variable key192 : std_logic_vector(191 downto 0); + variable pt128 : std_logic_vector(127 downto 0); + variable ct128 : std_logic_vector(127 downto 0); + variable buffer128 : std_logic_vector(127 downto 0); + variable test_ctr : integer range 0 to 1000000; -- can fail if too many vectors + variable loading_ctr : integer range 0 to 255; -- can fail if too many vectors + variable reading_ctr : integer range 0 to 127; -- can fail if too many vectors + begin + file_open(vector_file, "test_vectors_192_enc_dec.txt", read_mode); + test_ctr := 1; + + while not (endfile(vector_file)) loop + + -- we first read a single test vector from a file + readline(vector_file, tmp_line); read(tmp_line, mode_v); -- read mode + readline(vector_file, tmp_line); hread(tmp_line, pt128); + readline(vector_file, tmp_line); hread(tmp_line, key192); + readline(vector_file, tmp_line); hread(tmp_line, ct128); + -- reading a single test vector is done + + rst <= '0'; + mode <= mode_v; + wait until rising_edge(clk); + + rst <= '1'; + loading_ctr := 0; + loading_loop: loop + if loading_ctr <= 127 then -- load pt only in the first 128 cycles always + pt <= pt128(127-loading_ctr); + end if; + + key <= key192(191 - loading_ctr); + if loading_ctr = 191 then + exit loading_loop; + end if; + + loading_ctr := loading_ctr + 1; + wait until rising_edge(clk); + end loop; + + + waiting_loop: loop + wait until rising_edge(clk); + if done = '1' then -- done signals indicates that the encryption/decryption is almost over, and the result will be available during the following 128 cycles + exit waiting_loop; + end if; + end loop; + wait until rising_edge(clk); -- wait until the next rising_edge + + reading_ctr := 0; + reading_loop: loop + buffer128(127 - reading_ctr) := ct; + if reading_ctr = 127 then + exit reading_loop; + end if; + reading_ctr := reading_ctr + 1; + wait until rising_edge(clk); + end loop; + + assert buffer128 = ct128 report "======>>> DOES NOT MATCH <<<======" severity failure; + report "passed vector #: " & integer'image(test_ctr); + test_ctr := test_ctr + 1; + + end loop; + assert false report ">>> ALL GOOD <<<" severity failure; + wait; + end process; +end tb; diff --git a/256_enc/aes.vhd b/256_enc/aes.vhd new file mode 100644 index 0000000..e05dd50 --- /dev/null +++ b/256_enc/aes.vhd @@ -0,0 +1,33 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity AES is +port ( ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic + ); +end entity; + +architecture Behavioral of AES is + + -- pipeline related signals + signal state_exit_bit, last_rnd : std_logic; + signal round, round_key : std_logic_vector(3 downto 0); + signal count : std_logic_vector(6 downto 0); + signal count_key : std_logic_vector(7 downto 0); + +begin + + ct <= state_exit_bit; + + data_pipeline0: entity data_pipeline (Behavioral) port map(state_exit_bit, clk, round, count, round_key, count_key, pt, key, last_rnd); + controller0: entity controller (Behavioral) port map(round, count, round_key, count_key, done, last_rnd, clk, rst); + +end architecture; diff --git a/256_enc/controller.vhd b/256_enc/controller.vhd new file mode 100644 index 0000000..b155458 --- /dev/null +++ b/256_enc/controller.vhd @@ -0,0 +1,60 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity controller is +port ( + round: out std_logic_vector(3 downto 0); + count: out std_logic_vector(6 downto 0); + round_key: out std_logic_vector(3 downto 0); + count_key: out std_logic_vector(7 downto 0); + done: out std_logic; + last_rnd: out std_logic; + clk: in std_logic; + rst: in std_logic + ); +end entity; + +architecture Behavioral of controller is + + signal rnd_p : std_logic_vector(3 downto 0); + signal cnt_p : std_logic_vector(6 downto 0); + signal merged_counter_n : std_logic_vector(11 downto 0); + signal merged_counter_p : std_logic_vector(11 downto 0); + signal merged_counter_plus : std_logic_vector(11 downto 0); + +begin + + -- We should prefer synchronous rst signal + -- it helps when we want to later use it in AEAD circuits + + process (clk) + begin + if rising_edge(clk) then + merged_counter_p <= merged_counter_n; + end if; + end process; + + done <= '1' when cnt_p = "1111111" and rnd_p = "1101" else '0'; + last_rnd <= '1' when rnd_p = "1110" else '0'; + + process (merged_counter_p) + variable ctr: integer range 0 to 4095; + begin + ctr := (to_integer(unsigned(merged_counter_p)) + 1) mod 4096; + merged_counter_plus <= std_logic_vector(to_unsigned(ctr, merged_counter_plus'length)); + end process; + + merged_counter_n <= (others => '0') when rst = '0' else merged_counter_plus; + + rnd_p <= merged_counter_p(10 downto 7); + cnt_p <= merged_counter_p(6 downto 0); + round <= rnd_p; + count <= cnt_p; + round_key <= merged_counter_p(11 downto 8); + count_key <= merged_counter_p(7 downto 0); + +end architecture; diff --git a/256_enc/data_pipeline.vhd b/256_enc/data_pipeline.vhd new file mode 100644 index 0000000..f06266f --- /dev/null +++ b/256_enc/data_pipeline.vhd @@ -0,0 +1,207 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity data_pipeline is +port ( + state_exit_bit: out std_logic; + clk: in std_logic; + round: in std_logic_vector(3 downto 0); + count: in std_logic_vector(6 downto 0); + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + newbit: in std_logic; + key: in std_logic; + last_rnd: in std_logic + ); +end entity data_pipeline; + +architecture Behavioral of data_pipeline is + +-- datapipeline related +signal d_p, d_n: std_logic_vector(127 downto 0); +signal d_out, s_nextbit: std_logic; + +-- keypipeline related signals +signal keybit : std_logic; + +-- mix columns related signals +signal mix_first_msb, mix_first_lsb, mix_first_out: std_logic_vector(3 downto 0); +signal mix_first_reduc, mix_first_notLSB: std_logic; + +signal mix_first_effs_p, mix_first_effs_n: std_logic_vector(3 downto 0); + +-- sbox related signals +signal sbox_port1, sbox_port2, sbox_port3, sbox_out: std_logic_vector(7 downto 0); +signal direction: std_logic; +signal sbox_sel : std_logic_vector(1 downto 0); + +-- Rotate the data pipeline +procedure rotate ( + variable s : inout std_logic_vector(127 downto 0); + variable b: in std_logic + ) is +begin + s := s(126 downto 0) & b; +end rotate; + +-- Make a swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +state_exit_bit <= d_out; -- Output bit + +sbox_port1 <= d_p(6 downto 0) & s_nextbit; -- First input of the SBOX multiplexer comming from the data pipeline + +mix_first: entity mixcolumns (moradi) port map (mix_first_msb, mix_first_lsb, mix_first_effs_p, mix_first_reduc, mix_first_notLSB, mix_first_out); -- Map the forward - first inverse mixcolumns component +s_box: entity sbox (maximov) port map(direction, sbox_sel, sbox_port1, sbox_port2, sbox_port3, sbox_out); -- Map the sbox +k_pipe: entity key_pipeline (Behavioral) port map (keybit, clk, round_key, count_key, key, sbox_out, sbox_port2, sbox_port3); -- Map the key pipeline + +process (clk) +begin + if clk'event and clk = '1' then + d_p <= d_n; + mix_first_effs_p <= mix_first_effs_n; + end if; +end process; + +process (d_p, mix_first_effs_p, round, count, count_key, newbit, key, sbox_out, mix_first_out, keybit, last_rnd) + variable s : std_logic_vector(127 downto 0); + variable m1 : std_logic_vector(3 downto 0); + variable v_nextbit: std_logic; -- nextbit + variable round_i : integer range 0 to 15; -- round of the data pipeline + variable count_i : integer range 0 to 127; -- cycle of the data pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + + -- Set the state + s := d_p; + m1 := mix_first_effs_p; + sbox_sel <= "XX"; + direction <= '1'; + mix_first_notLSB <= 'X'; + mix_first_lsb <= (others => 'X'); + mix_first_msb <= (others => 'X'); + mix_first_reduc <= 'X'; + + -- Get the current round/cycle as int + count_key_i := to_integer(unsigned(count_key)); + round_i := to_integer(unsigned(round)); + count_i := to_integer(unsigned(count)); + + -- Modify the sbox selection input and selection forward - inverse depending on the cycle and the mode + if count_i mod 8 = 7 then + sbox_sel <= "00"; + elsif count_i mod 8 = 0 then + sbox_sel <= "01"; + end if; + + -- Modify the sbox selection input depending on the version and the cycle + if count_key_i < 184 and count_key_i >= 64 and count_key_i mod 8 = 0 then + sbox_sel <= "10"; + elsif count_key_i mod 8 = 0 then + sbox_sel <= "01"; + end if; + + -- Input bit + if round_i = 0 then + v_nextbit := newbit xor keybit; + else + v_nextbit := s(127) xor keybit; + end if; + + -- XORed input bit + s_nextbit <= v_nextbit; + + -- SubByte + if (count_i mod 8 = 7) and (count_i /= 7) and (count_i /= 39) and (count_i /= 71) and (count_i /= 103) then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + end if; + + -- ShiftRows + -- Swap d-96 + if count_i = 127 or (count_i < 7 and round_i /= 0) then + swap(s(6), s(102)); + end if; + -- Swap d-64 + if (count_i >= 112 and count_i < 120) or (count_i >= 16 and count_i < 24 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0) then + swap(s(95), s(31)); + end if; + -- Swap d-32 + if ((count_i>= 72 and count_i < 80) or (count_i >= 104 and count_i < 112) or (count_i >= 8 and count_i < 16 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0)) then + swap(s(63), s(31)); + end if; + + -- Forward MixColumns / First for Inverse MixColumns + if (((count_i >= 0 and count_i < 8) or (count_i >= 32 and count_i < 40) or (count_i >= 64 and count_i < 72) or + (count_i >= 96 and count_i < 104)) and round_i /= 0 and last_rnd /= '1') then + + mix_first_msb <= s(127) & s(119) & s(111) & s(103); + mix_first_lsb <= s(126) & s(118) & s(110) & s(102); + + if ((count_i mod 8 = 3) or (count_i mod 8 = 4) or (count_i mod 8 = 6) or (count_i mod 8 = 7)) then + mix_first_reduc <= '1'; + else + mix_first_reduc <= '0'; + end if; + + if (count_i mod 8 = 7) then + mix_first_notLSB <= '0'; + else + mix_first_notLSB <= '1'; + end if; + + if (count_i mod 8 = 0) then + m1 := s(127) & s(119) & s(111) & s(103); + end if; + + s(127) := mix_first_out(3); + s(119) := mix_first_out(2); + s(111) := mix_first_out(1); + s(103) := mix_first_out(0); + + v_nextbit := s(127) xor keybit; + s_nextbit <= v_nextbit; + + end if; + + -- SubByte + if count_i mod 8 = 7 and (count_i = 7 or count_i = 39 or count_i = 71 or count_i = 103) then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + end if; + + -- Output bit assignment + if (round_i>0) then + d_out <= s(127) xor keybit; + else + d_out <= newbit xor keybit; + end if; + + -- Rotation of the pipeline + rotate(s, v_nextbit); + + -- State assignment + d_n <= s; + + mix_first_effs_n <= m1; + +end process; + +end architecture Behavioral; diff --git a/256_enc/key_pipeline.vhd b/256_enc/key_pipeline.vhd new file mode 100644 index 0000000..17ff765 --- /dev/null +++ b/256_enc/key_pipeline.vhd @@ -0,0 +1,140 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity key_pipeline is +port ( + keybit: out std_logic; + clk: in std_logic; + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + key: in std_logic; + sbox_out: in std_logic_vector(7 downto 0); + sbox_port2: out std_logic_vector(7 downto 0); + sbox_port3: out std_logic_vector(7 downto 0) + ); +end entity key_pipeline; + + +architecture Behavioral of key_pipeline is + +-- keypipeline related signals + +signal k_p, k_n: std_logic_vector(255 downto 0); +signal k_out: std_logic; + +-- Rotate the key pipeline +procedure rotate ( + variable s : inout std_logic_vector(255 downto 0); + variable b: in std_logic + ) is +begin + -- Wire AES-128 and AES-192 + s := s(254 downto 0) & b; +end rotate; + +-- Swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +-- Output key assigment +keybit <= k_out; +sbox_port2 <= k_p(7 downto 0); +sbox_port3 <= k_p(15 downto 8); + +process (clk) +begin + if clk'event and clk = '1' then + k_p <= k_n; + end if; +end process; + +process (k_p, round_key, count_key, key, sbox_out) + variable s : std_logic_vector(255 downto 0); -- Key state + variable nextbit: std_logic; -- Input bit + variable round_key_i : integer range 0 to 15; -- round_key of the key pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + -- Assign round_key, cycle, state and version + round_key_i := to_integer(unsigned(round_key)); + count_key_i := to_integer(unsigned(count_key)); + s := k_p; + k_out <= 'X'; + + -- Input bit + if round_key_i = 0 then + nextbit := key; + else + nextbit := s(255); + end if; + + -- Swap/Unswap + if (count_key_i >= 0 and count_key_i < 8) and (round_key_i > 0) then + swap(s(31), nextbit); + end if; + if count_key_i >= 16 and count_key_i < 24 and (round_key_i > 0) then + swap(s(15), s(47)); + end if; + + -- Sbox + xor + if not (round_key_i = 0 and count_key_i <= 8) and + (count_key_i = 0 or count_key_i = 8 or + (count_key_i = 240 or count_key_i = 248)) then + s(239 downto 232) := s(239 downto 232) xor sbox_out; + end if; + -- Second sbox + xor AES-256 + if (round_key_i > 0) and (count_key_i = 112 or count_key_i = 120 or count_key_i = 128 or count_key_i = 136) then + s(239 downto 232) := s(239 downto 232) xor sbox_out; + end if; + + -- Look up Rcon table for encryption/decryption + if + (((round_key_i=0)) and count_key_i=240) or + (((round_key_i=1)) and count_key_i=239) or + (((round_key_i=2)) and count_key_i=238) or + (((round_key_i=3)) and count_key_i=237) or + (((round_key_i=4)) and count_key_i=236) or + (((round_key_i=5)) and count_key_i=235) or + (((round_key_i=6)) and count_key_i=234) then + s(232) := not s(232); + end if; + + -- Kxor + if (round_key_i > 0) and + ((count_key_i <96)) then + s(223) := s(223) xor s(255); + end if; + if (round_key_i > 0) and + (count_key_i >=128) and (count_key_i <224) then + s(223) := s(223) xor s(255); + end if; + + -- Decryption output bit swap + if (round_key_i>0) then + k_out <= s(255); + else + k_out <= key; + end if; + + -- Rotate the pipeline + rotate(s, nextbit); + + -- Assign state + k_n <= s; +end process; + +end architecture Behavioral; + diff --git a/256_enc/mix_columns.vhd b/256_enc/mix_columns.vhd new file mode 100644 index 0000000..800d22b --- /dev/null +++ b/256_enc/mix_columns.vhd @@ -0,0 +1,49 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity mixcolumns is + port ( + A: in std_logic_vector(3 downto 0); + B: in std_logic_vector(3 downto 0); + REG: in std_logic_vector(3 downto 0); + modRec: in std_logic; + notLSB: in std_logic; + OUTP: out std_logic_vector(3 downto 0)); +end entity mixcolumns; + +-- Taken from Bitsling + +architecture moradi of mixcolumns is + signal R0, R1, R2, R3: std_logic; + signal D0, D1, D2, D3: std_logic; + signal E0, E1, E2, E3: std_logic; +begin + + -- AND layer + R0 <= REG(3) and modRec; + R1 <= REG(2) and modRec; + R2 <= REG(1) and modRec; + R3 <= REG(0) and modRec; + + -- XOR-AND layer + D0 <= R0 xor (B(3) and notLSB) xor A(2); + D1 <= R1 xor (B(2) and notLSB) xor A(1); + D2 <= R2 xor (B(1) and notLSB) xor A(0); + D3 <= R3 xor (B(0) and notLSB) xor A(3); + + -- XOR layer + E0 <= D0 xor D1 xor A(0); + E1 <= D1 xor D2 xor A(3); + E2 <= D2 xor D3 xor A(2); + E3 <= D3 xor D0 xor A(1); + + OUTP(3) <= E0; + OUTP(2) <= E1; + OUTP(1) <= E2; + OUTP(0) <= E3; + +end architecture; \ No newline at end of file diff --git a/256_enc/sbox_bonus.vhd b/256_enc/sbox_bonus.vhd new file mode 100644 index 0000000..08a9701 --- /dev/null +++ b/256_enc/sbox_bonus.vhd @@ -0,0 +1,203 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity sbox is + port ( + INV: in std_logic; -- ZF=1 forward ZF=0 inverse + SEL: in std_logic_vector(1 downto 0); + INP1: in std_logic_vector(7 downto 0); + INP2: in std_logic_vector(7 downto 0); + INP3: in std_logic_vector(7 downto 0); + OUP : out std_logic_vector(7 downto 0)); +end entity sbox; + +-- Taken from Maximov's CHES 2019 paper +-- The "bonus" version + +architecture maximov of sbox is + signal A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: std_logic; + signal Q15, Q4, Q0, Q14, Q3, Q1, Q6, Q8, Q9, Q2, Q10, Q7, Q12, Q11, Q5, Q13, Q17, Q16: std_logic; + signal H0, H1, H2, H4, H6, H7, H20, H8, H9, H10, H12, H15, H16, H19: std_logic; + signal S4, S2, S14, S1, S0, S5, S11, S6, S12, S7, S3, S15, S13: std_logic; + signal R0, R1, R2, R3, R4, R5, R6, R7: std_logic; + signal T0, T1, T2, T3, T4, T10, T11, T12, T13, T20, T21, T22, X0, X1, X2, X3, Y0, Y1, Y2, Y3 : std_logic; + signal Y00, Y01, Y02, Y13, Y23, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N16, N17 : std_logic; + signal U0, U1, U2, U3, U4, U5, U6, U7 : std_logic; + signal ZF: std_logic; +begin + + -- multiplexer input + U0 <= INP1(7) when SEL = "00" else + INP2(7) when SEL = "01" else + INP3(7); + U1 <= INP1(6) when SEL = "00" else + INP2(6) when SEL = "01" else + INP3(6); + U2 <= INP1(5) when SEL = "00" else + INP2(5) when SEL = "01" else + INP3(5); + U3 <= INP1(4) when SEL = "00" else + INP2(4) when SEL = "01" else + INP3(4); + U4 <= INP1(3) when SEL = "00" else + INP2(3) when SEL = "01" else + INP3(3); + U5 <= INP1(2) when SEL = "00" else + INP2(2) when SEL = "01" else + INP3(2); + U6 <= INP1(1) when SEL = "00" else + INP2(1) when SEL = "01" else + INP3(1); + U7 <= INP1(0) when SEL = "00" else + INP2(0) when SEL = "01" else + INP3(0); + + ZF <= INV; + + -- below: edited and pasted from the paper + + -- ctop.b + A0 <= U3 xnor U6; + Q15 <= U1 xnor ZF; + A1 <= U5 xor Q15; + A2 <= U2 xor A0; + A3 <= U4 xor A1; + A4 <= U4 xor U6; + A5 <= A2 when ZF = '1' else A4; -- MUX(ZF, A2, A4) + Q4 <= A3 xnor A5; + Q0 <= U0 xor Q4; + Q14 <= Q15 xor Q0; + A6 <= U0 xnor U2; + Q3 <= ZF xor A6; + Q1 <= Q4 xor Q3; + A7 <= U1 when ZF = '1' else Q0; -- MUX(ZF, U1, Q0) + Q6 <= A5 xnor A7; + Q8 <= Q3 xor Q6; + A8 <= Q1 when ZF = '1' else A4; -- MUX(ZF, Q1, A4) + Q9 <= U6 xor A8; + Q2 <= Q8 xor Q9; + Q10 <= Q4 xor Q9; + Q7 <= Q6 xor Q10; + A9 <= A0 when ZF = '1' else U4; -- MUX(ZF, A0, U4) + Q12 <= U7 xnor A9; + Q11 <= Q0 xor Q12; + A10 <= A6 when ZF = '1' else Q12; -- MUX(ZF, A6, Q12) + A11 <= A2 xor A10; + A12 <= A4 xor A11; + Q5 <= Q0 xor A12; + Q13 <= Q11 xor A12; + Q17 <= Q14 xor A12; + Q16 <= Q14 xor Q13; + + -- mulx.a + T20 <= Q6 nand Q12; + T21 <= Q3 nand Q14; + T22 <= Q1 nand Q16; + T10 <= (Q3 nor Q14) xor (Q0 nand Q7); + T11 <= (Q4 nor Q13) xor (Q10 nand Q11); + T12 <= (Q2 nor Q17) xor (Q5 nand Q9); + T13 <= (Q8 nor Q15) xor (Q2 nand Q17); + + X0 <= T10 xor (T20 xor T22); + X1 <= T11 xor (T21 xor T20); + X2 <= T12 xor (T21 xor T22); + X3 <= T13 xor (T21 xor (Q4 nand Q13)); + + + -- inv.a + T0 <= X0 nand X2; + T1 <= X1 nor X3; + T2 <= T0 xnor T1; + + Y0 <= T2 when X2 = '1' else X3; -- MUX(X2, T2, X3); + Y2 <= T2 when X0 = '1' else X1; -- MUX(X0, T2, X1); + T3 <= X2 when X1 = '1' else '1'; -- MUX(X1, X2, 1); + Y1 <= X3 when T2 = '1' else T3; -- MUX(T2, X3, T3); + T4 <= X0 when X3 = '1' else '1'; -- MUX(X3, X0, 1); + Y3 <= X1 when T2 = '1' else T4; -- MUX(T2, X1, T4) + + -- s0. a + -- calls inv.a; + Y02 <= Y2 xor Y0; + Y13 <= Y3 xor Y1; + Y23 <= Y3 xor Y2; + Y01 <= Y1 xor Y0; + Y00 <= Y02 xor Y13; + + + -- File: muln.a; + N0 <= Y01 nand Q11; + N1 <= Y0 nand Q12; + N2 <= Y1 nand Q0; + N3 <= Y23 nand Q17; + N4 <= Y2 nand Q5; + N5 <= Y3 nand Q15; + N6 <= Y13 nand Q14; + + N7 <= Y00 nand Q16; + N8 <= Y02 nand Q13; + N9 <= Y01 nand Q7; + N10 <= Y0 nand Q10; + N11 <= Y1 nand Q6; + N12 <= Y23 nand Q2; + N13 <= Y2 nand Q9; + N14 <= Y3 nand Q8; + + N15 <= Y13 nand Q3; + N16 <= Y00 nand Q1; + N17 <= Y02 nand Q4; + + -- cbot.b; + H0 <= N9 xor N10; + H1 <= N16 xor H0; + H2 <= N4 xor N5; + S4 <= N7 xor (N8 xor H2); + H4 <= N0 xor N2; + H6 <= N15 xor H1; + H7 <= H4 xor (N3 xor N5); + H20 <= H6 xor ZF; + S2 <= H20 xor H7; + S14 <= S4 xor H7; + H8 <= N13 xor H0; + H9 <= N12 xor H8; + S1 <= H20 xor H9; + H10 <= N17 xor H1; + H12 <= H2 xor (N1 xor N2); + S0 <= H6 xor H12; + S5 <= N6 xor (H9 xor (N8 xor H4)); + S11 <= H12 xor S5; + S6 <= S1 xor S11; + H15 <= N14 xor H10; + H16 <= H8 xor H15; + S12 <= S5 xor H16; + S7 <= S4 xnor (H10 xor (N9 xor N11)); + H19 <= H7 xnor S7; + S3 <= H16 xor H19; + S15 <= S11 xor H19; + S13 <= S4 xor (N12 xor H15); + R0 <= S0; + R1 <= S1; + R2 <= S2; + R3 <= S3 when ZF = '1' else S11; -- MUX(ZF, S3, S11) + R4 <= S4 when ZF = '1' else S12; -- MUX(ZF, S4, S12) + R5 <= S5 when ZF = '1' else S13; -- MUX(ZF, S5, S13) + R6 <= S6 when ZF = '1' else S14; -- MUX(ZF, S6, S14) + R7 <= S7 when ZF = '1' else S15; -- MUX(ZF, S7, S15) + + -- end of copying + + + OUP(7) <= R0; + OUP(6) <= R1; + OUP(5) <= R2; + OUP(4) <= R3; + OUP(3) <= R4; + OUP(2) <= R5; + OUP(1) <= R6; + OUP(0) <= R7; + +end architecture; \ No newline at end of file diff --git a/256_enc/test_vectors_256_enc.txt b/256_enc/test_vectors_256_enc.txt new file mode 100644 index 0000000..9d4b731 --- /dev/null +++ b/256_enc/test_vectors_256_enc.txt @@ -0,0 +1,300 @@ +79e23287b56f7bb62a99d8e28f67e387 +f6ba5fb7e6dcd26cc2c3045a060377c272bc61ac40592d2746bc555dc8d6744f +7002ACE6EA43E090424D94BCAB0695D8 +23bd218f5e9731d5e3255feddf73f6f2 +22f48d3f53ae5d1da78751e78a1aedcc1181a0d98b8f5ff7188070f081f024da +1DFB12476CA37E3D69FC9E15431E5CC2 +523dd5c42c1cea76a08438b3196a1488 +0f815ad35e90ecd5c33a40d6bf8b833c5e8225fb44c1e4aeab430ec8b4356045 +04A307CF9000BBF3AD255C0C1960B744 +e4f79f0d56edefe5aac790bce71ed370 +ff74fdcc3de88c042408ff5a542740953279628aab901a9c415ac005ce05055b +BC318A082DD6373039DB23AE6EE3065D +6a719ddfd108ca8023e8d45313fd8fb4 +65fe74719cc0df904b3e6d9153b7bc61c4fdf8e74df6605cfa613651a3e34b35 +924CAE6DD332799D7DE779B13A372CB2 +6f679be7cad57292e8512d254d2b5d13 +0bda0b7920a6769201b415a80dc62a606a4d03d0fb3930183543a611be3d7ec5 +603EFFDC84888CAD6825E28DE86A217D +ed5c990078bd1e117eabd95dacd8468c +45ca1d2fcc43e4ae000a266524a9fe6e66702dbbde0942d1ec5789ce0aecf941 +18D2A3C168BB7F0982FD04D8D0A67A5F +f12552ef7a9474ce61e70d3566e91a9a +9006cfa0bf48d7709c8715717f71a8b640b6697145f3d827ec9d93ab60fd3b97 +98992FDEAA98BDC259A2D12300D1D3FF +23fbf8074f8284e6fb4ac0acdd84c9bf +61224084b93316a2823152bfd32ed9180333e2b75d9db594ff450ec9ce41d0d1 +05643F72F4FD684EFF59055823C05487 +56fe11f3e98fbd29f58ccd7b95a16ce8 +72e4afd592b83877357ddeeb546bb373676429514066407917b6a10f5f70d075 +CFF02B8694E331151354BFEEA7FD7480 +82c126374da8eb8ea3745b62fb40a486 +d9f7fd269ecaa82e1408e626570b9b52dff9ceeafe9452323e7658c08a9ea5e9 +95AC3D59183D60E10112BC06FDB53D4E +4aba083c43326850eec9bc435e3d0f03 +97bfac635ceaaa5c58cc76e34433d7ed4d3f520b7cfe3b6a13fd40cdb18fff0b +62F7B5D1834499E7083EB4929FE7D16B +0b27ab4d4e0ccc9cae4485ab3d2c6188 +38c5dc4244f6d9b64c31f183f0124dd3662da4ef92060619b5e13ca3114b3f0e +BB9C8984C50EBDC9E1DBC10E6765C608 +b2964fd4c76439de50bd91e622f5fe95 +8c7de885f82defbc2842ce2cd9fafbb401544eeecd85b4a9d496c931910dc742 +241488E0AC3078E0535DE59B3AA08642 +b2c982fb41c854efde499afe11c4a5eb +8f5769c2d8f2bba2b3d3793f14b0b22affb1050795acad1bec9b588980b14d71 +D60DE247D35E772541447235B40CCAD4 +243b1f44cc385aae6e3219b6ff4aec49 +9923889904b883276ec0eddbd847f4e5bba1e277c253eb6ec48f6d546a352a2b +5171DF60A4652FDBFFA218D6BC5AB344 +29d59065ff6ed645183d7903e28ab940 +026efec6e1108b39098dd9ab81c77fda6029cb8bfcf2e29cc701ae067d8f5772 +49507D4BCB950E75A3677489B0C98B90 +861a8de1f6d6b9b041491b3922b98f34 +e5a2a8bce15789cf984dc4eaf33725dff3c6972bb7a0cd2452af084abfe74368 +2215C75560CAE1290F0EE565F0046AA4 +cc46c5a548c22c4a58e0de8fd46036f5 +56d16ec92789a908104b6bee4c2a2fb8566fe035dc9e6563dfb5dfc7146b6308 +D0CC22DE4D93C2EAADEE6CD285BB6F69 +7bc06c27d78eb636d75f99fd33e0614e +1cae39c5e308f6e8568526ef86faebce6248c731c4dafdd155dbd9f528945c6b +43CD603929F9344F40411D70D76BE094 +f8155408c28422d4931b1b169303b7b6 +c640dc4eafd4ce4c439c67614b990da4aa3962c000d3f8a07ac797c80edfcbec +9FCC0D5616E4BA21B72045C61D3D346B +1e434065781e32784e1c6615e66b398f +f8bfcc88972ed1533ab579ee6f1b521344ca4a55137dc641dcd5bb189e754253 +572A6FB28597567794AB90A85471A566 +b689476996e6fc42a20f4eb81b63a177 +9369404a7d5d8d524fd74613b974f58519a31b876edcf2513de2a38625c9a896 +CE6A5A2AD3246299A2A8D9801C62767C +204d06bb2ceecbc9e11795cc48c0fb79 +0e7b95e3df3f8b132b0113d0e3ad40443234f6a2bede2a994a9454afc4a82438 +7307C3A1474D68D5256DEFEAE6A747EB +6bafa11b52a559b37bffded35184461e +ecd24de9909ad8a8ff51a64862d176daacd8bfede44a3a20ffe49faf97f58da6 +5A491699320DDC62B808D2CECB5BF23C +d87dc82d6c5e87bb23b0796c6943c47f +c8addbadaf32854e3fe1b1b3ee9224a67d378c76dd0a21f00bf2f0f7ec0ec034 +5380C51CBEEF2E1B5247A6FB7A7295C0 +bf270567fd3bb1a465e18068aad0a0cc +173439e7bf5f77f60bebbc3ee9b45d0cefe70ce18b61a9ef3614ff632cc15d17 +B0EB0FC771C1E3B75C6C34C2F8F9E033 +a50053b216aac02e39e953bdadf5f208 +4aa28efc2be17b29133ebbd4818ece4278adac6eeeca468c5ef90c2b92a92492 +35C533F4DCFB967E3F7EA2CA021040BE +d6e37fd60148c694925c4009b906bb76 +df2209a77aee28ccad5f64e33fcfcac739740b3a9da57c9579afe2bb950106f6 +96470F931653690640227C1FC484384F +f4aa20b066c210001b85c472ef4a5d0e +8c2a3eb868f4e3e607dfc53e0f5379a14ffc85ee1c75d777fadb310b5d65b327 +A146C789A08DFE7AD9AE177A67BBF59A +045e8dde0f955ecf6a36a2931176854f +b693c0236c9a3d10c264c7ae6b78d0f197072beeaa2fe22c9937c18963393e46 +6D07B1BFB3A92718928478A716E60261 +74593b46986e737db84fd6fb116f34ce +720851098931f5ce16846eab146ecbf3a8211cb36990a8a2eee0bfe09ce37b79 +C7DA34893D299575DA55FE6CA818A7FF +4fb3d4d36087804f580e48dcfe92c81b +307d5620c0b014bb885cc15f360ff9c25ad5245b7807101c50079b7e8ca69937 +A35AF656AB116FAD8F44961ADCAB60AC +40c1398e6a3f703feaa24f850004d2b2 +569d1e3ab5148df65b3179b376cbcc64cc87cc5da94d934660f12759c520d6b7 +D73281017635568F3EAD1144CD6A557D +8ff520a250dd238e4ef5dfe22edf69d0 +9c688af267e8f64716b5e3de94882bccede049f022e45f6d63fe87925c164a96 +60DFCB7642C10EF7BC34159792CD2A83 +37bc10407930885ee627c88e091ca7a7 +9126801d7b5bc2eda22895fda80b72f28e12b4d26d417c636776115f82004541 +FFCD69C6AA89A4F50DE62D656B4D9014 +98d9ec0ac111de39fef4ee22a6b82598 +f63756ab199ad6b6f7461d23157542ba6e63722d05b1778be4f9df51f1513f87 +1CC3126E7C70EF0AC107A47548BBD02D +a3fe64104e9a5862f593d537559e038d +7f3ac9945c330f024d2c2d5d02b6122cadd57c1a4dafb7ced43a905360701f6b +886CD729F748709427CE1C8A6B504C12 +ec16c5cd52a6c09093b10a76c3b492bd +c7a79f3b2efe48e8623c36b4b8bfb336f41b3ec0c04fe43978f77b1acc1717fd +99F45848B08126705648FA45C7BBD077 +9dc36db6e9482ffedcb87efab3f3fdf6 +cb334c4aa003255459ecec470a602d58fbde7f731911bc1f6e26907fcd428de1 +47D98A4C843043BCB734BD520F6B2AF9 +0be9841b6947c5696a0c5545025f2648 +26af1420e85f8c4f56739b3ac13c09b8b2400f876925cdd2822ebd84c8e49420 +340475B617466C7A395323637CAEE3B3 +bb401e9a2e4257a0ac7fe0c7b269f043 +e0cab2487d97d15d0992052292dfe00872a839366b813b59fd425d546cafa1c7 +459AE1AAE5BC4714E33F564959F7158E +703b3ecadf02f2e41e6413882df8c001 +a08897abcd7e1704bcfaefbb02aad8feb4a59033f27793260b690ecf90683c6f +876C92D6A515CBA1B0870B129DDBDC35 +b3f539c24f2bd393dbe6d192baae2d90 +553aa0a4d71dfb31a8fe887ff4ccab73d18c1ca5d1e668a561e4351878a5bfbb +A12141508B51271A2F708F100F104800 +e748a28b7b1104d7fb2ee3dbd56edc4d +01c9636b792bd54d9282c9f373b3648699fdb515be6f12a22bd0c356372177a6 +6E04BD35721C443C6CCDF60417A075C6 +487d80a40c609f09be0c5bec7349ccf5 +44948db4642cacecc4b8f1640792116751c7d19feb241948b47cf53c36b2c731 +213089B91B79962387B0C7D95108E235 +f4b3c0f3aa1d3af4e2664a66109bfcdb +f7616200601f569b58d9a5f674c53328cc76cc5888401ebb77fc6bae7b7fd7fa +3E3DC8339AE5D416A9F8A1EB2D0A411F +b7d791c94bc47db078b78d788b5e4dbf +867ef646eebc34fce1d3f9d1170153d35f8dc18f7f46cd961a8d05b927a59bad +13B59356BFC114E3D46DE987EA86CF65 +718e3b206a487553cf6cf68414a76fee +d4dc3c34e51929b39f97584fd4da2237353e31c1ba05f9fd21400bc76c196232 +4789065BC12A5D0F8E9CC6ED178F7EC7 +9314125440863c7cf08a9a3c32f9732c +f175a3064ab6374c69243e9606e0006a0c4e58127be9b4ceff708ec5364c7545 +D63607754FACB3A066A955BD9DE4AD9B +6e29f51b7a06bfa2538074317d66a31a +bdd09b0f44101c63bdb062a8036505900b80e17a4abb13355686957c42cd0b4f +5F7AD63EC4B9AEB7728EF3E5EEA0D8C3 +9ad58fd31e2a83237f2e40c31e751af6 +fbb5bb149f762197f505f2713aaf42fd06e4a9540c1f50379134d8da42419b28 +A340C109AD4C1E146CB3A7E85C140B88 +bdba4be1697fd427c4611cb840c7800e +a8fb066f8747149754df30acdbd061f6615dea80e0731b0ea034e381d231b19c +5D4C4A062DC2FAA3157C0769016A7309 +04c82415b8c22c0ad4138b2b6cfc1032 +4fbb5cc6bfeba9b102b2f40d7238278652b7593bcde24a424850065f32c3828b +291F82ADE5337283FEDC6E0B69E2AC3D +d85e9f3fada465d94a3d86445c9d3e8d +073b704ee08d3453077246b0544ee7a348cb070ff527c1f510efab8a3f691a5e +BA227DD8E4687582AC0951538A70304D +212d6059599c1bf93b841722fdeee9b8 +be8b24c5b7ab4c0f5a9a28b440a6c4f13205783cd4b521550d42174b809579db +47F6E1FEDFD75A1E25E55AE3736B6E1E +d01c3bb19cd0abcc46a2c4523be90bf7 +a253941e671fb0aa2eace0a47c2df5ad80bc90b547eae2086af7806a1f71f29c +2204FC56F71A484F8E5AF05A1E3C29E2 +faa2067958f92b2d0bfa5da13596e51b +21e4654cd605116a3cbd94444b2c07487e66034bd7968ca6546312088369943d +F84CA09ECE74CDBCB805CC1AE174F68B +f6de8d746990141119f4d9fcbd3ee616 +22e79284a8e0b3f628708e50d48e2e1cc4f38d44afa38242f8ede69143e43672 +BBFAA9A0485E3659D20B908F56961CD0 +678d8849176d9f8d0e362c35c17e4cc7 +812f2afac268266e6a5c43f391d58245301b2d28ca1c6105867dd5f9520a23b6 +24974BABBD47EF9ECA72A1FE5535189E +5f95ef28f27b9c6851c401c4fc91c636 +55c3d602631b86d20e6d5ca50a6d0fe9292c203ca76266f6bb006e5e9564d559 +60C462A298C8835BD2AC31B21BF55AB9 +fc049777765fb08776d2be695bf749b7 +91cff4f06d4fee99ab62aea32e6504ddfdeb0bcf7981cf527824e2c5249ca516 +E06BA704553CAD7383A7A50106F45334 +72a4b0e6781d4c1e28068f4d136baab2 +f3f652519564158055358452845a2133647df544e5f14f307302cfd8c5546d19 +57E7EC2703983270273BFAA392D84012 +37fca1a2b0dcb837de12eb15a8bd9acb +9a81d39539f2b7909ea7e1dd12c6a4ceeae34088c6f82ae610abe82d00ac8614 +6080CDA8B924D8B4D3520DF7669421DC +b9d55ec96dda6a97f6ebf2b257797106 +3874a7f865849aeda9558cd29d515796550a4797ce885ccc7707580badcb25fd +200358F86CE16CAD0A5503E56F891F10 +9699d3c6fb8490268d79fb443e474092 +a4ee4546f77cfa205784478120274fd381310c88081bcebf5c5d0801afe7360a +82514C9A3486CE9CFABA70EE126543DD +fc188439d82a3ca62d40ff9938d5d072 +09eae067a3c4bbb60f588a1d5e681cd87369cd4db99a38780fd7eb887cf26be9 +C2895C9F477B6FF808B4074892239405 +766911b854d0997f2f7635d0fec01538 +e92d0812312bca7fddd7193351a4c5f55423644249f8a5ca7b50ac3534e7e1bc +D746E8FEE0961E736732DA0B7E1F58EC +b64e966525a636c22d58da09df027d7f +a7c93a3dec682d54344549927f7bec9a1f13afa719a8d5e474a925fb6194d892 +D9807BC969888BDD1ECE6684F36DFBB6 +5b9cb7f84bd25c6a6417759ebc2ebbed +110c2e08b68f943b923e03df8b601d742414f464f3da09cbde2aacd78ec55b26 +1CC038EE4484289124BD860E91EEC6A3 +642ad780eeaa3a82b5fe695ad0d72ee9 +916632e48261f2b901aa7fcf5cbdc84c44488441bd9efe34f15c254049c854d5 +87F2DF6C76DC900ACA8F9CD641258FA8 +84e0fd0491b7a6a7cde544813d5a1cda +e966dd992153a2ebe7525eb3d80733771c0dbd6fd0173c83d88da16ba040a8ce +4831EDAEC115C4A712F0E338CAF67521 +3914ce616e94af0f7bfe7db67301a10d +58a7df14c2b4eb1ec8c675c5c6790e7ecf44b378fe9ac988235efc7d07471458 +161622D804F6331904A55B5D04494B63 +88e2dd06934485984a4da1210edd9730 +99dc9524e49a23409ec36032b927e104102afa0bc295cf2ad55a4825e725058d +6FB7B90CC9EA7A29E972836A287883C9 +0d33a8cdecb25a7bfcaa66bafc5ae701 +1225ebf6eca88ba0028cdaa557f58a33bb98f4061c67d2fa47ccc1a080126b5b +E3F79B65AB03ACAE25669CF40770C7E0 +319fe1f6dacb1dc0abb3602382338396 +a617f76918b092710e38e1a29ccd9236b5ea06625b8bb0a3a24ea3d3bce732e2 +663B3AFA68CB66454FD99DEDF76CE5B4 +39117d098939d4b15ecf561228be4fce +769eca5dd7971912bdf7ef95c471165fd62be056bd44665ff91d7ce2133ec01d +D04C7FAF6FAA7DAA9E74725657B4DAB1 +ea410ffb315d01ab4c3dd9c50a7c7d0b +883aab3cb09f20d82eea60d3143adadadd9d98aead880f2c868cdef125f3baf4 +28A1CA276AB118514E7331BBB1E5234C +fc1c66ccaaee5ef8b54ba23ac722d783 +1e3f5230da56229341e3b0378e32a2d3085e2f3ccdec47183a0d7bce764b559d +C09A338167AA64262D5F5BD927E9459E +810caedf6ac06cab379cfa0ab3dc3268 +68469e260aa8fe1e56c5793c453145916c0565a883dcf7984b262ca711105627 +AE57B315E2BEC976ED086A90F48376F9 +394b8ba1f5fa564ab006d0ef21282b4f +79361512711b0717156c07c68fdfda8290931ccf861fed0a1ed10920f3168b86 +6C00BE93838E640856D25C24D7B3FE57 +dbf73126715b639e6e6a977a4d64e33f +634f9011287677c55a5f8f966ecc44df0f24084b8786ecbcd471f63e04c35306 +D5FCC2DFBD3E67E1AF7F5AD47211C8EF +af9658b82a06cf4b000137254045b1c5 +9f849e63bcd416e3b9c3058a45fb761a1c3f1464391dc28f92de8ce79df36755 +1D80359AF6A05469F4E26C9E489BBEBC +d371665f8fff0df0cf9fd0774cc3a8a0 +a1bc0d2a3e1940ac8f081d6fbc912869d6766ca848bb682463eb51c330db0f9b +C2BF85869113E4D7F8390358757BAE15 +a47fda4a7c12a61d3f8fd10672b3ed90 +47d11c9eefec425c53b4c0d2dbc2c075d6efa27e29326f99d0fd4facbb537fa7 +0208C799CDA3D3AC214CA654784DD623 +5e5d6019ed65302d5752019c5335cff1 +94f9dfc18d74905d568a947c92f76c02a6e6e5cb55348bf0554a5b7432766d00 +5180A5D92D60BE712CD6B8695D77B706 +6bf57cf6d2ef58da34ee7564ba32e46a +3d038213f2d264224bd08a6821ecab1c767e6be44faa237ea8b2e1639960e257 +8753FD7D492BCFE27B448CC0AA120D2D +6a7b96d7376384b89cfcbea41171cb31 +7b41eb681dcf7079924884d48026226e6790535a3227304e4380f917729b0995 +5765E1998D8CF4F8D2F2429F53D826E8 +84d9ac92a348c8c2abe5ca732fdea40a +34e17e54075880244f2caafe92a2a742fc4f53c21820127c76f358ff121ee8be +0A4B84673ED1B92DAB4A95A8053C781F +39a617b78686e70bf313c4cf51e4ff36 +9b3f2983424e14382d78b3d08d6f0639593941ab1ec7c3c620310742317ebb4c +8A4FFF2C8C996D3D4E5FDD36CB2F9EF9 +311667108a57aab62009a6118850a31d +0e044cdbd77f94d46a8e21098497150c53b3778a506e9dc4c007a92b0742d2b3 +798D17068AE2CBA40A4C15D67E1C19CC +a6f8a79152881dd9278deb1043ed8501 +4e1746db9e0ebb3c516e43debafb63857b74c48359100e5f419622c945879eea +84EFAD7BECCA58CB6726D50FB810DB74 +a6a099b77a0d3314130045c63e64b060 +605c9c3c342f8d99055476fa4c7736ed8c981c2018ded70e1ef50893819d1115 +18B7C6CFE389AE01786FEFD7ECF4672A +326d7cef6a07590947ef0ac9e971cbb4 +29f32878760c4d6ae82f5e6d461fe4772274d1a839e6fb182571686c8b354f3f +5B4BCCF769DFA356CD0EAFD0F27CC2CC +5f4ef6b165d42f0b9c3c4e891d213ee2 +4772b52f61282b80f1bfa729cb757048ea4379e740e9a59f8244241537565255 +E721314F827FB85D98AD7FE87F205D7E +38b7e2a2555ef5f3586ade8a48ef78ad +5e0f54b3093dad7fe0681255b45d8d00285c5f2b09874160e7d896f84ec386a9 +DEF1D8D946BDE9408DD2CCBB6CC33CE0 +5746ee89151ca7f1a060e0d6c58bbc11 +0f5957a53525a8070c90ff4c3f93864491f68bf672469df14f20875f1eaa37c8 +2638977DD4D09F1AC2D2B92367156036 +7ee2c6a712a38896c7d40dfa6f9e75ea +433fb07651e90b714eb019e65714304593ec5d88248c02513b9972d612b20c24 +06878A4F0EAB198537F778D60C55BC4E +b1935192fabcd0a44af68388d899b9b9 +bdaf871915528b40a867262e3c9fec52807abeddc1b70320557123ddacf5fcd1 +F9D88F2D3554FAE532F56A5F17737581 +f3c8a97b916cfe6824d7e9fe4678681c +ed471dea5f3880732fe7fe9d4972a2a53d2f2dad5956359d5cb1240eec06a781 +CC3098DBD4BDFC7082995E442F03E1A6 diff --git a/256_enc/testbench.vhd b/256_enc/testbench.vhd new file mode 100644 index 0000000..a2d9026 --- /dev/null +++ b/256_enc/testbench.vhd @@ -0,0 +1,113 @@ +library std; +use std.textio.all; +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use work.all; + +entity tb_aes is +end tb_aes; + +architecture tb of tb_aes is + + constant clock_cycle : time:= 100 ns; + + file vector_file : TEXT; + + signal ct : std_logic; + signal pt : std_logic; + signal clk : std_logic; + signal rst : std_logic; + signal done : std_logic; + signal key : std_logic; + + component AES + port ( + ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic); + end component AES; + +begin + + mut: AES port map (ct, done, clk, rst, pt, key); + + process + begin + clk <= '1'; wait for clock_cycle/2; + clk <= '0'; wait for clock_cycle/2; + end process; + + process + variable tmp_line : line; + variable key256 : std_logic_vector(255 downto 0); + variable pt128 : std_logic_vector(127 downto 0); + variable ct128 : std_logic_vector(127 downto 0); + variable buffer128 : std_logic_vector(127 downto 0); + variable test_ctr : integer range 0 to 1000000; -- can fail if too many vectors + variable loading_ctr : integer range 0 to 255; -- can fail if too many vectors + variable reading_ctr : integer range 0 to 127; -- can fail if too many vectors + begin + file_open(vector_file, "test_vectors_256_enc.txt", read_mode); + test_ctr := 1; + + while not (endfile(vector_file)) loop + + -- we first read a single test vector from a file + readline(vector_file, tmp_line); hread(tmp_line, pt128); + readline(vector_file, tmp_line); hread(tmp_line, key256); + readline(vector_file, tmp_line); hread(tmp_line, ct128); + -- reading a single test vector is done + + rst <= '0'; + wait until rising_edge(clk); + + rst <= '1'; + loading_ctr := 0; + loading_loop: loop + if loading_ctr <= 127 then -- load pt only in the first 128 cycles always + pt <= pt128(127-loading_ctr); + end if; + + key <= key256(255 - loading_ctr); + if loading_ctr = 255 then + exit loading_loop; + end if; + + loading_ctr := loading_ctr + 1; + wait until rising_edge(clk); + end loop; + + + waiting_loop: loop + wait until rising_edge(clk); + if done = '1' then -- done signals indicates that the encryption/decryption is almost over, and the result will be available during the following 128 cycles + exit waiting_loop; + end if; + end loop; + wait until rising_edge(clk); -- wait until the next rising_edge + + reading_ctr := 0; + reading_loop: loop + buffer128(127 - reading_ctr) := ct; + if reading_ctr = 127 then + exit reading_loop; + end if; + reading_ctr := reading_ctr + 1; + wait until rising_edge(clk); + end loop; + + assert buffer128 = ct128 report "======>>> DOES NOT MATCH <<<======" severity failure; + report "passed vector #: " & integer'image(test_ctr); + test_ctr := test_ctr + 1; + + end loop; + assert false report ">>> ALL GOOD <<<" severity failure; + wait; + end process; +end tb; diff --git a/256_enc_dec/aes.vhd b/256_enc_dec/aes.vhd new file mode 100644 index 0000000..dba75f3 --- /dev/null +++ b/256_enc_dec/aes.vhd @@ -0,0 +1,34 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity AES is +port ( ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic; + mode: in std_logic + ); +end entity; + +architecture Behavioral of AES is + + -- pipeline related signals + signal state_exit_bit, last_rnd : std_logic; + signal round, round_key : std_logic_vector(3 downto 0); + signal count : std_logic_vector(6 downto 0); + signal count_key : std_logic_vector(7 downto 0); + +begin + + ct <= state_exit_bit; + + data_pipeline0: entity data_pipeline (Behavioral) port map(state_exit_bit, clk, round, count, round_key, count_key, mode, pt, key, last_rnd); + controller0: entity controller (Behavioral) port map(round, count, round_key, count_key, done, last_rnd, clk, rst); + +end architecture; diff --git a/256_enc_dec/controller.vhd b/256_enc_dec/controller.vhd new file mode 100644 index 0000000..b155458 --- /dev/null +++ b/256_enc_dec/controller.vhd @@ -0,0 +1,60 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity controller is +port ( + round: out std_logic_vector(3 downto 0); + count: out std_logic_vector(6 downto 0); + round_key: out std_logic_vector(3 downto 0); + count_key: out std_logic_vector(7 downto 0); + done: out std_logic; + last_rnd: out std_logic; + clk: in std_logic; + rst: in std_logic + ); +end entity; + +architecture Behavioral of controller is + + signal rnd_p : std_logic_vector(3 downto 0); + signal cnt_p : std_logic_vector(6 downto 0); + signal merged_counter_n : std_logic_vector(11 downto 0); + signal merged_counter_p : std_logic_vector(11 downto 0); + signal merged_counter_plus : std_logic_vector(11 downto 0); + +begin + + -- We should prefer synchronous rst signal + -- it helps when we want to later use it in AEAD circuits + + process (clk) + begin + if rising_edge(clk) then + merged_counter_p <= merged_counter_n; + end if; + end process; + + done <= '1' when cnt_p = "1111111" and rnd_p = "1101" else '0'; + last_rnd <= '1' when rnd_p = "1110" else '0'; + + process (merged_counter_p) + variable ctr: integer range 0 to 4095; + begin + ctr := (to_integer(unsigned(merged_counter_p)) + 1) mod 4096; + merged_counter_plus <= std_logic_vector(to_unsigned(ctr, merged_counter_plus'length)); + end process; + + merged_counter_n <= (others => '0') when rst = '0' else merged_counter_plus; + + rnd_p <= merged_counter_p(10 downto 7); + cnt_p <= merged_counter_p(6 downto 0); + round <= rnd_p; + count <= cnt_p; + round_key <= merged_counter_p(11 downto 8); + count_key <= merged_counter_p(7 downto 0); + +end architecture; diff --git a/256_enc_dec/data_pipeline.vhd b/256_enc_dec/data_pipeline.vhd new file mode 100644 index 0000000..fa1bc38 --- /dev/null +++ b/256_enc_dec/data_pipeline.vhd @@ -0,0 +1,320 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity data_pipeline is +port ( + state_exit_bit: out std_logic; + clk: in std_logic; + round: in std_logic_vector(3 downto 0); + count: in std_logic_vector(6 downto 0); + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + mode: in std_logic; + newbit: in std_logic; + key: in std_logic; + last_rnd: in std_logic + ); +end entity data_pipeline; + +architecture Behavioral of data_pipeline is + +-- datapipeline related +signal d_p, d_n: std_logic_vector(127 downto 0); +signal d_out, s_nextbit: std_logic; + +-- keypipeline related signals +signal keybit : std_logic; + +-- mix columns related signals +signal mix_first_msb, mix_first_lsb, mix_first_out, mix_second_msb, mix_second_lsb, mix_second_out, mix_third_msb, mix_third_lsb, mix_third_out: std_logic_vector(3 downto 0); +signal mix_first_reduc, mix_first_notLSB, mix_second_reduc, mix_second_notLSB, mix_third_reduc, mix_third_notLSB: std_logic; + +signal mix_first_effs_p, mix_first_effs_n, mix_second_effs_p, mix_second_effs_n, mix_third_effs_p, mix_third_effs_n: std_logic_vector(3 downto 0); + +-- sbox related signals +signal sbox_port1, sbox_port2, sbox_port3, sbox_out: std_logic_vector(7 downto 0); +signal direction: std_logic; +signal sbox_sel : std_logic_vector(1 downto 0); + +-- Rotate the data pipeline +procedure rotate ( + variable s : inout std_logic_vector(127 downto 0); + variable b: in std_logic + ) is +begin + s := s(126 downto 0) & b; +end rotate; + +-- Make a swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +state_exit_bit <= d_out; -- Output bit + +sbox_port1 <= d_p(6 downto 0) & s_nextbit when mode='0' else + d_p(126 downto 119); -- First input of the SBOX multiplexer comming from the data pipeline + +mix_first: entity mixcolumns (moradi) port map (mix_first_msb, mix_first_lsb, mix_first_effs_p, mix_first_reduc, mix_first_notLSB, mix_first_out); -- Map the forward - first inverse mixcolumns component +mix_second: entity mixcolumns (moradi) port map (mix_second_msb, mix_second_lsb, mix_second_effs_p, mix_second_reduc, mix_second_notLSB, mix_second_out); -- Map the second inverse mixcolumns component +mix_third: entity mixcolumns (moradi) port map (mix_third_msb, mix_third_lsb, mix_third_effs_p, mix_third_reduc, mix_third_notLSB, mix_third_out); -- Map the third inverse mixcolumns component +s_box: entity sbox (maximov) port map(direction, sbox_sel, sbox_port1, sbox_port2, sbox_port3, sbox_out); -- Map the sbox +k_pipe: entity key_pipeline (Behavioral) port map (keybit, clk, round_key, count_key, mode, key, sbox_out, sbox_port2, sbox_port3); -- Map the key pipeline + +process (clk) +begin + if clk'event and clk = '1' then + d_p <= d_n; + mix_first_effs_p <= mix_first_effs_n; + mix_second_effs_p <= mix_second_effs_n; + mix_third_effs_p <= mix_third_effs_n; + end if; +end process; + +process (d_p, mix_first_effs_p, mode, mix_second_effs_p, mix_third_effs_p, round, count, count_key, newbit, key, sbox_out, mix_first_out, mix_second_out, mix_third_out, keybit, last_rnd) + variable s : std_logic_vector(127 downto 0); + variable m1, m2, m3 : std_logic_vector(3 downto 0); + variable v_nextbit: std_logic; -- nextbit + variable round_i : integer range 0 to 15; -- round of the data pipeline + variable count_i : integer range 0 to 127; -- cycle of the data pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + + -- Set the state + s := d_p; + m1 := mix_first_effs_p; + m2 := mix_second_effs_p; + m3 := mix_third_effs_p; + sbox_sel <= "XX"; + direction <= 'X'; + mix_first_notLSB <= 'X'; + mix_second_notLSB <= 'X'; + mix_third_notLSB <= 'X'; + mix_first_lsb <= (others => 'X'); + mix_second_lsb <= (others => 'X'); + mix_third_lsb <= (others => 'X'); + mix_first_msb <= (others => 'X'); + mix_second_msb <= (others => 'X'); + mix_third_msb <= (others => 'X'); + mix_first_reduc <= 'X'; + mix_second_reduc <= 'X'; + mix_third_reduc <= 'X'; + + -- Get the current round/cycle as int + count_key_i := to_integer(unsigned(count_key)); + round_i := to_integer(unsigned(round)); + count_i := to_integer(unsigned(count)); + + -- Modify the sbox selection input and selection forward - inverse depending on the cycle and the mode + if count_i mod 8 = 7 then + if mode='1' then + direction <= '0'; + elsif mode='0' then + direction <= '1'; + end if; + sbox_sel <= "00"; + elsif count_i mod 8 = 0 then + direction <= '1'; + sbox_sel <= "01"; + end if; + + -- Modify the sbox selection input depending on the version and the cycle + if count_key_i < 184 and count_key_i >= 64 and count_key_i mod 8 = 0 then + sbox_sel <= "10"; + elsif count_key_i mod 8 = 0 then + sbox_sel <= "01"; + end if; + + -- Input bit + if round_i = 0 then + v_nextbit := newbit xor keybit; + else + v_nextbit := s(127) xor keybit; + end if; + + -- XORed input bit + s_nextbit <= v_nextbit; + + -- SubByte + if (count_i mod 8 = 7) and (count_i /= 7) and (count_i /= 39) and (count_i /= 71) and (count_i /= 103) then + if mode='0' then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + else + s(126 downto 119) := sbox_out; + end if; + end if; + + -- ShiftRows + -- Swap d-96 + if count_i = 127 or (count_i < 7 and round_i /= 0) then + if mode='0' then + swap(s(6), s(102)); + else + swap(s(118), s(22)); + end if; + end if; + -- Swap d-64 + if (count_i >= 112 and count_i < 120) or (count_i >= 16 and count_i < 24 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0 and mode = '0') or + (count_i >= 8 and count_i < 16 and round_i /= 0 and mode = '1') then + swap(s(95), s(31)); + end if; + -- Swap d-32 + if (((count_i>= 72 and count_i < 80) or (count_i >= 104 and count_i < 112) or (count_i >= 8 and count_i < 16 and round_i /= 0) or + (count_i >= 24 and count_i < 32 and round_i /= 0)) and mode = '0') or + (((count_i>=88 and count_i < 96) or (count_i >= 120) or (count_i>=8 and count_i<16 and round_i/=0) or + (count_i>=24 and count_i<32 and round_i /= 0)) and mode = '1') then + swap(s(63), s(31)); + end if; + + -- Forward MixColumns / First for Inverse MixColumns + if (((count_i >= 0 and count_i < 8) or (count_i >= 32 and count_i < 40) or (count_i >= 64 and count_i < 72) or + (count_i >= 96 and count_i < 104)) and round_i /= 0 and last_rnd /= '1' and mode = '0') or + (((count_i >= 26 and count_i<34) or (count_i>=58 and count_i<66) or (count_i>=90 and count_i<98) or (count_i>=122) or + (count_i>=0 and count_i<2 and round_i > 1)) and round_i /= 0 and mode = '1') then + + if mode='0' then + mix_first_msb <= s(127) & s(119) & s(111) & s(103); + mix_first_lsb <= s(126) & s(118) & s(110) & s(102); + else + mix_first_msb <= s(25) & s(17) & s(9) & s(1); + mix_first_lsb <= s(24) & s(16) & s(8) & s(0); + end if; + + if (((count_i mod 8 = 3) or (count_i mod 8 = 4) or (count_i mod 8 = 6) or (count_i mod 8 = 7)) and mode='0') or + (((count_i mod 8 = 0) or (count_i mod 8 = 1) or (count_i mod 8 = 5) or (count_i mod 8 = 6)) and mode='1') then + mix_first_reduc <= '1'; + else + mix_first_reduc <= '0'; + end if; + + if (count_i mod 8 = 7 and mode='0') or (count_i mod 8 = 1 and mode='1') then + mix_first_notLSB <= '0'; + else + mix_first_notLSB <= '1'; + end if; + + if (count_i mod 8 = 0 and mode='0') then + m1 := s(127) & s(119) & s(111) & s(103); + elsif (count_i mod 8 = 2 and mode='1') then + m1 := s(25) & s(17) & s(9) & s(1); + end if; + + if mode = '0' then + s(127) := mix_first_out(3); + s(119) := mix_first_out(2); + s(111) := mix_first_out(1); + s(103) := mix_first_out(0); + + v_nextbit := s(127) xor keybit; + s_nextbit <= v_nextbit; + else + s(25) := mix_first_out(3); + s(17) := mix_first_out(2); + s(9) := mix_first_out(1); + s(1) := mix_first_out(0); + end if; + end if; + + -- Second for Inverse MixColumns + if((count_i >= 28 and count_i < 36) or (count_i>=60 and count_i<68) or (count_i>=92 and count_i < 100) or + (count_i>=124) or (count_i>=0 and count_i<4 and round_i > 1)) and round_i /= 0 and mode='1' then + + mix_second_msb <= s(27) & s(19) & s(11) & s(3); + mix_second_lsb <= s(26) & s(18) & s(10) & s(2); + + if (count_i mod 8 = 0) or (count_i mod 8 = 2) or (count_i mod 8 = 3) or (count_i mod 8 = 7) then + mix_second_reduc <= '1'; + else + mix_second_reduc <= '0'; + end if; + + if count_i mod 8 = 3 then + mix_second_notLSB <= '0'; + else + mix_second_notLSB <= '1'; + end if; + + if count_i mod 8 = 4 then + m2 := s(27) & s(19) & s(11) & s(3); + end if; + + s(27) := mix_second_out(3); + s(19) := mix_second_out(2); + s(11) := mix_second_out(1); + s(3) := mix_second_out(0); + end if; + + -- Third for Inverse MixColumns + if((count_i >= 30 and count_i < 38) or (count_i>=62 and count_i<70) or (count_i>=94 and count_i < 102) or + (count_i>=126) or (count_i>=0 and count_i<6 and round_i > 1)) and round_i /= 0 and mode='1' then + + mix_third_msb <= s(29) & s(21) & s(13) & s(5); + mix_third_lsb <= s(28) & s(20) & s(12) & s(4); + + if (count_i mod 8 = 1) or (count_i mod 8 = 2) or (count_i mod 8 = 4) or (count_i mod 8 = 5) then + mix_third_reduc <= '1'; + else + mix_third_reduc <= '0'; + end if; + + if count_i mod 8 = 5 then + mix_third_notLSB <= '0'; + else + mix_third_notLSB <= '1'; + end if; + + if count_i mod 8 = 6 then + m3 := s(29) & s(21) & s(13) & s(5); + end if; + + s(29) := mix_third_out(3); + s(21) := mix_third_out(2); + s(13) := mix_third_out(1); + s(5) := mix_third_out(0); + end if; + + -- SubByte + if count_i mod 8 = 7 and (count_i = 7 or count_i = 39 or count_i = 71 or count_i = 103) then + if mode='0' then + s(6 downto 0) := sbox_out(7 downto 1); + v_nextbit := sbox_out(0); + else + s(126 downto 119) := sbox_out; + end if; + end if; + + -- Output bit assignment + if (round_i>0) then + d_out <= s(127) xor keybit; + else + d_out <= newbit xor keybit; + end if; + + -- Rotation of the pipeline + rotate(s, v_nextbit); + + -- State assignment + d_n <= s; + + mix_first_effs_n <= m1; + mix_second_effs_n <= m2; + mix_third_effs_n <= m3; + +end process; + +end architecture Behavioral; diff --git a/256_enc_dec/key_pipeline.vhd b/256_enc_dec/key_pipeline.vhd new file mode 100644 index 0000000..813b3f1 --- /dev/null +++ b/256_enc_dec/key_pipeline.vhd @@ -0,0 +1,149 @@ +library ieee; +use ieee.std_logic_1164.all; + +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity key_pipeline is +port ( + keybit: out std_logic; + clk: in std_logic; + round_key: in std_logic_vector(3 downto 0); + count_key: in std_logic_vector(7 downto 0); + mode: in std_logic; + key: in std_logic; + sbox_out: in std_logic_vector(7 downto 0); + sbox_port2: out std_logic_vector(7 downto 0); + sbox_port3: out std_logic_vector(7 downto 0)); +end entity key_pipeline; + + +architecture Behavioral of key_pipeline is + +-- keypipeline related signals + +signal k_p, k_n: std_logic_vector(255 downto 0); +signal k_out: std_logic; + +-- Rotate the key pipeline +procedure rotate ( + variable s : inout std_logic_vector(255 downto 0); + variable b: in std_logic + ) is +begin + -- Wire AES-128 and AES-192 + s := s(254 downto 0) & b; +end rotate; + +-- Swap between a and b +procedure swap ( + variable a: inout std_logic; + variable b: inout std_logic + ) is + variable tmp : std_logic; +begin + tmp := a; + a := b; + b := tmp; +end swap; + +begin + +-- Output key assigment +keybit <= k_out; +sbox_port2 <= k_p(7 downto 0); +sbox_port3 <= k_p(15 downto 8); + +process (clk) +begin + if clk'event and clk = '1' then + k_p <= k_n; + end if; +end process; + +process (k_p, mode, round_key, count_key, key, sbox_out) + variable s : std_logic_vector(255 downto 0); -- Key state + variable nextbit: std_logic; -- Input bit + variable round_key_i : integer range 0 to 15; -- round_key of the key pipeline + variable count_key_i : integer range 0 to 255; -- cycle of the key pipeline +begin + -- Assign round_key, cycle, state and version + round_key_i := to_integer(unsigned(round_key)); + count_key_i := to_integer(unsigned(count_key)); + s := k_p; + k_out <= 'X'; + + -- Input bit + if round_key_i = 0 then + nextbit := key; + else + nextbit := s(255); + end if; + + -- Swap/Unswap + if (count_key_i >= 0 and count_key_i < 8) and (round_key_i > 0) then + swap(s(31), nextbit); + end if; + if count_key_i >= 16 and count_key_i < 24 and (round_key_i > 0) then + swap(s(15), s(47)); + end if; + + -- Sbox + xor + if not (round_key_i = 0 and count_key_i <= 8) and + (count_key_i = 0 or count_key_i = 8 or + ((count_key_i = 240 or count_key_i = 248))) then + s(239 downto 232) := s(239 downto 232) xor sbox_out; + end if; + -- Second sbox + xor AES-256 + if (round_key_i > 0) and (count_key_i = 112 or count_key_i = 120 or count_key_i = 128 or count_key_i = 136) then + s(239 downto 232) := s(239 downto 232) xor sbox_out; + end if; + + -- Look up Rcon table for encryption/decryption + if + (((round_key_i=0 and mode='0') or (round_key_i=6 and mode='1')) and count_key_i=240) or + (((round_key_i=1 and mode='0') or (round_key_i=5 and mode='1')) and count_key_i=239) or + (((round_key_i=2 and mode='0') or (round_key_i=4 and mode='1')) and count_key_i=238) or + (((round_key_i=3 and mode='0') or (round_key_i=3 and mode='1')) and count_key_i=237) or + (((round_key_i=4 and mode='0') or (round_key_i=2 and mode='1')) and count_key_i=236) or + (((round_key_i=5 and mode='0') or (round_key_i=1 and mode='1')) and count_key_i=235) or + (((round_key_i=6 and mode='0') or (round_key_i=0 and mode='1')) and count_key_i=234) then + s(232) := not s(232); + end if; + + -- Kxor + if (round_key_i > 0) and + ((count_key_i <96)) and + (mode='0') then + s(223) := s(223) xor s(255); + end if; + if (round_key_i > 0) and + (count_key_i >=128) and (count_key_i <224) and + (mode='0') then + s(223) := s(223) xor s(255); + end if; + + -- Decryption and-xors + if (mode='1') and (((count_key_i>=224) and (count_key_i<256)) or ((count_key_i>=96) and (count_key_i<128) and (round_key_i > 0))) then + s(127) := s(159) xor s(127); + s(159) := s(191) xor s(159); + s(191) := s(223) xor s(191); + end if; + + -- Decryption output bit swap + if (round_key_i>0) then + k_out <= s(255); + else + k_out <= key; + end if; + + -- Rotate the pipeline + rotate(s, nextbit); + + -- Assign state + k_n <= s; +end process; + +end architecture Behavioral; + diff --git a/256_enc_dec/mix_columns.vhd b/256_enc_dec/mix_columns.vhd new file mode 100644 index 0000000..800d22b --- /dev/null +++ b/256_enc_dec/mix_columns.vhd @@ -0,0 +1,49 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity mixcolumns is + port ( + A: in std_logic_vector(3 downto 0); + B: in std_logic_vector(3 downto 0); + REG: in std_logic_vector(3 downto 0); + modRec: in std_logic; + notLSB: in std_logic; + OUTP: out std_logic_vector(3 downto 0)); +end entity mixcolumns; + +-- Taken from Bitsling + +architecture moradi of mixcolumns is + signal R0, R1, R2, R3: std_logic; + signal D0, D1, D2, D3: std_logic; + signal E0, E1, E2, E3: std_logic; +begin + + -- AND layer + R0 <= REG(3) and modRec; + R1 <= REG(2) and modRec; + R2 <= REG(1) and modRec; + R3 <= REG(0) and modRec; + + -- XOR-AND layer + D0 <= R0 xor (B(3) and notLSB) xor A(2); + D1 <= R1 xor (B(2) and notLSB) xor A(1); + D2 <= R2 xor (B(1) and notLSB) xor A(0); + D3 <= R3 xor (B(0) and notLSB) xor A(3); + + -- XOR layer + E0 <= D0 xor D1 xor A(0); + E1 <= D1 xor D2 xor A(3); + E2 <= D2 xor D3 xor A(2); + E3 <= D3 xor D0 xor A(1); + + OUTP(3) <= E0; + OUTP(2) <= E1; + OUTP(1) <= E2; + OUTP(0) <= E3; + +end architecture; \ No newline at end of file diff --git a/256_enc_dec/sbox_bonus.vhd b/256_enc_dec/sbox_bonus.vhd new file mode 100644 index 0000000..08a9701 --- /dev/null +++ b/256_enc_dec/sbox_bonus.vhd @@ -0,0 +1,203 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.numeric_std.all; +use std.textio.all; +use work.all; + +entity sbox is + port ( + INV: in std_logic; -- ZF=1 forward ZF=0 inverse + SEL: in std_logic_vector(1 downto 0); + INP1: in std_logic_vector(7 downto 0); + INP2: in std_logic_vector(7 downto 0); + INP3: in std_logic_vector(7 downto 0); + OUP : out std_logic_vector(7 downto 0)); +end entity sbox; + +-- Taken from Maximov's CHES 2019 paper +-- The "bonus" version + +architecture maximov of sbox is + signal A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: std_logic; + signal Q15, Q4, Q0, Q14, Q3, Q1, Q6, Q8, Q9, Q2, Q10, Q7, Q12, Q11, Q5, Q13, Q17, Q16: std_logic; + signal H0, H1, H2, H4, H6, H7, H20, H8, H9, H10, H12, H15, H16, H19: std_logic; + signal S4, S2, S14, S1, S0, S5, S11, S6, S12, S7, S3, S15, S13: std_logic; + signal R0, R1, R2, R3, R4, R5, R6, R7: std_logic; + signal T0, T1, T2, T3, T4, T10, T11, T12, T13, T20, T21, T22, X0, X1, X2, X3, Y0, Y1, Y2, Y3 : std_logic; + signal Y00, Y01, Y02, Y13, Y23, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N16, N17 : std_logic; + signal U0, U1, U2, U3, U4, U5, U6, U7 : std_logic; + signal ZF: std_logic; +begin + + -- multiplexer input + U0 <= INP1(7) when SEL = "00" else + INP2(7) when SEL = "01" else + INP3(7); + U1 <= INP1(6) when SEL = "00" else + INP2(6) when SEL = "01" else + INP3(6); + U2 <= INP1(5) when SEL = "00" else + INP2(5) when SEL = "01" else + INP3(5); + U3 <= INP1(4) when SEL = "00" else + INP2(4) when SEL = "01" else + INP3(4); + U4 <= INP1(3) when SEL = "00" else + INP2(3) when SEL = "01" else + INP3(3); + U5 <= INP1(2) when SEL = "00" else + INP2(2) when SEL = "01" else + INP3(2); + U6 <= INP1(1) when SEL = "00" else + INP2(1) when SEL = "01" else + INP3(1); + U7 <= INP1(0) when SEL = "00" else + INP2(0) when SEL = "01" else + INP3(0); + + ZF <= INV; + + -- below: edited and pasted from the paper + + -- ctop.b + A0 <= U3 xnor U6; + Q15 <= U1 xnor ZF; + A1 <= U5 xor Q15; + A2 <= U2 xor A0; + A3 <= U4 xor A1; + A4 <= U4 xor U6; + A5 <= A2 when ZF = '1' else A4; -- MUX(ZF, A2, A4) + Q4 <= A3 xnor A5; + Q0 <= U0 xor Q4; + Q14 <= Q15 xor Q0; + A6 <= U0 xnor U2; + Q3 <= ZF xor A6; + Q1 <= Q4 xor Q3; + A7 <= U1 when ZF = '1' else Q0; -- MUX(ZF, U1, Q0) + Q6 <= A5 xnor A7; + Q8 <= Q3 xor Q6; + A8 <= Q1 when ZF = '1' else A4; -- MUX(ZF, Q1, A4) + Q9 <= U6 xor A8; + Q2 <= Q8 xor Q9; + Q10 <= Q4 xor Q9; + Q7 <= Q6 xor Q10; + A9 <= A0 when ZF = '1' else U4; -- MUX(ZF, A0, U4) + Q12 <= U7 xnor A9; + Q11 <= Q0 xor Q12; + A10 <= A6 when ZF = '1' else Q12; -- MUX(ZF, A6, Q12) + A11 <= A2 xor A10; + A12 <= A4 xor A11; + Q5 <= Q0 xor A12; + Q13 <= Q11 xor A12; + Q17 <= Q14 xor A12; + Q16 <= Q14 xor Q13; + + -- mulx.a + T20 <= Q6 nand Q12; + T21 <= Q3 nand Q14; + T22 <= Q1 nand Q16; + T10 <= (Q3 nor Q14) xor (Q0 nand Q7); + T11 <= (Q4 nor Q13) xor (Q10 nand Q11); + T12 <= (Q2 nor Q17) xor (Q5 nand Q9); + T13 <= (Q8 nor Q15) xor (Q2 nand Q17); + + X0 <= T10 xor (T20 xor T22); + X1 <= T11 xor (T21 xor T20); + X2 <= T12 xor (T21 xor T22); + X3 <= T13 xor (T21 xor (Q4 nand Q13)); + + + -- inv.a + T0 <= X0 nand X2; + T1 <= X1 nor X3; + T2 <= T0 xnor T1; + + Y0 <= T2 when X2 = '1' else X3; -- MUX(X2, T2, X3); + Y2 <= T2 when X0 = '1' else X1; -- MUX(X0, T2, X1); + T3 <= X2 when X1 = '1' else '1'; -- MUX(X1, X2, 1); + Y1 <= X3 when T2 = '1' else T3; -- MUX(T2, X3, T3); + T4 <= X0 when X3 = '1' else '1'; -- MUX(X3, X0, 1); + Y3 <= X1 when T2 = '1' else T4; -- MUX(T2, X1, T4) + + -- s0. a + -- calls inv.a; + Y02 <= Y2 xor Y0; + Y13 <= Y3 xor Y1; + Y23 <= Y3 xor Y2; + Y01 <= Y1 xor Y0; + Y00 <= Y02 xor Y13; + + + -- File: muln.a; + N0 <= Y01 nand Q11; + N1 <= Y0 nand Q12; + N2 <= Y1 nand Q0; + N3 <= Y23 nand Q17; + N4 <= Y2 nand Q5; + N5 <= Y3 nand Q15; + N6 <= Y13 nand Q14; + + N7 <= Y00 nand Q16; + N8 <= Y02 nand Q13; + N9 <= Y01 nand Q7; + N10 <= Y0 nand Q10; + N11 <= Y1 nand Q6; + N12 <= Y23 nand Q2; + N13 <= Y2 nand Q9; + N14 <= Y3 nand Q8; + + N15 <= Y13 nand Q3; + N16 <= Y00 nand Q1; + N17 <= Y02 nand Q4; + + -- cbot.b; + H0 <= N9 xor N10; + H1 <= N16 xor H0; + H2 <= N4 xor N5; + S4 <= N7 xor (N8 xor H2); + H4 <= N0 xor N2; + H6 <= N15 xor H1; + H7 <= H4 xor (N3 xor N5); + H20 <= H6 xor ZF; + S2 <= H20 xor H7; + S14 <= S4 xor H7; + H8 <= N13 xor H0; + H9 <= N12 xor H8; + S1 <= H20 xor H9; + H10 <= N17 xor H1; + H12 <= H2 xor (N1 xor N2); + S0 <= H6 xor H12; + S5 <= N6 xor (H9 xor (N8 xor H4)); + S11 <= H12 xor S5; + S6 <= S1 xor S11; + H15 <= N14 xor H10; + H16 <= H8 xor H15; + S12 <= S5 xor H16; + S7 <= S4 xnor (H10 xor (N9 xor N11)); + H19 <= H7 xnor S7; + S3 <= H16 xor H19; + S15 <= S11 xor H19; + S13 <= S4 xor (N12 xor H15); + R0 <= S0; + R1 <= S1; + R2 <= S2; + R3 <= S3 when ZF = '1' else S11; -- MUX(ZF, S3, S11) + R4 <= S4 when ZF = '1' else S12; -- MUX(ZF, S4, S12) + R5 <= S5 when ZF = '1' else S13; -- MUX(ZF, S5, S13) + R6 <= S6 when ZF = '1' else S14; -- MUX(ZF, S6, S14) + R7 <= S7 when ZF = '1' else S15; -- MUX(ZF, S7, S15) + + -- end of copying + + + OUP(7) <= R0; + OUP(6) <= R1; + OUP(5) <= R2; + OUP(4) <= R3; + OUP(3) <= R4; + OUP(2) <= R5; + OUP(1) <= R6; + OUP(0) <= R7; + +end architecture; \ No newline at end of file diff --git a/256_enc_dec/test_vectors_256_enc_dec.txt b/256_enc_dec/test_vectors_256_enc_dec.txt new file mode 100644 index 0000000..3d89a9f --- /dev/null +++ b/256_enc_dec/test_vectors_256_enc_dec.txt @@ -0,0 +1,400 @@ +0 +8bf9d89dfcd7a7a76717be5682acfd0b +a285d4f54b2bc647f127ab1f3316795ae4ccbe5ed4b8761e274f8ac3a42da0df +57C7077DD0762C3FC5E9D63ABCC626D7 +1 +89bc781f806c685f0ea7b26ec31e62aa +eabbef1d17f44ed303722f28b0c4474b08ae369c16705083a9d48dc9fde0d0a3 +06889C4E72468674AD0CD4FDBE0B507F +1 +cd19b62a28b67d123219afd9a74ad532 +8b4d7f318b2a40836ddb02908ed168965a3013d80986c516f17e55020fb33816 +BDBDC0C44CC8164C6E1C146B8F856E3A +0 +ac921577b56e3b6c4ef771dfb29242ae +9c65d6e2081608e2afaba846512d972361c06df319a6e8a044761a7bfb99567e +D26438BF7487ADC1545D5506AF65C953 +1 +3b6f94cf28d3242cc1dcf95bc2099924 +3d4f48fe48fb4d34a1ea39e5e51b710c7fefe46ac12b779cdcc9d085ce195ba0 +1346424C05170788D2954F2F93CF7168 +1 +51cd9871399372c5731583beca83688c +81f3aecaff0f12ca9529e85d5b6869b03d02fac49be739e0755f1bd355c726bd +5EE0B77BC3EF61DC481F29E5AC446953 +1 +17eaff93279765fe8f79c36123244577 +7dee67ea84a4202d855ea452eb3ac365e6754ffa1f6382af0976a2653f3ab21c +BA43D524414A193969E571D1591011DD +0 +eb463d87ddb5163d6ccd6d06e0cfa96a +040616813fbd3bdabc4f3e2b187a27334a1942aa09bfd0e1f09da25f74ed8675 +F423C85CD1D435B73C0CEDC0CCA17586 +0 +741fb9c89960adfa9655af00cedc931b +25eeed01084757c1874aa583cb30d7c249cd2ff088fd50340ffaa2aaf398016f +E8C4179DD03D99F9EA45AA2B181314E6 +0 +615be7357d94c4fa45fc2d4241082373 +7f41a0d99d2dab68ecbde257e1a10f91588f176ce6c936f9757fd8857b534718 +99AF0BA4212FF36E868EC2C96EAF26E8 +1 +31a71a252dedbf005a99c9fafcc9c43c +51216b3222beaddce2e6f731aade187061820e74b35078e8807eb3dcf2b546e1 +71CDDAA4C363A36B55053CF46A643C8F +1 +cf50002ca33209c4c9bddd353a7498cb +865cf1fd0f1c8c950418e41c788d6a073a9975babddaee60a258d00fb32cbe51 +075A1D56D96284021197238C42ACD1AB +0 +18e0e24be02f0eb0e90a595d9377f90a +97b8a14573908a389c363c14593749a1ce6380a09ff16789492e34b298e52103 +1022D21E4F75EF93DC67678658EF1D98 +0 +1fa98abfd3301c2f7d1844cfb5a0e606 +94b394346681bac7138b24c9721252d158b4d087f235e0fd9f58e53a0adc9e78 +0E477B8584244D95879638116BAA655D +1 +e8609a500264ec3ff820ccefa004c1a0 +b0333ccd54534d56979fe1d1cbfc8dfecf415d711bfec3bb9d2630b4b4db791e +21EF033DD945E361BB8A8ECF35871219 +0 +c67ef3b990e517ebaf514817ff8479b0 +ab9a628264d48c6a23b6d11468412dd153d262aecdb4353d5f4e1d1dc373657e +72FDDA4674F3D2A17D65F55824D6088D +1 +090fec8e9436dd0b52a4eb00a540ceaa +238bd7aba22c76d3cc2c5baf32c9fc87edaec09856c01e166e6be3def6c8279a +9CF203DF1A18A55FD41520D30722A301 +0 +a08b8bea4d319f85c068e3d85dffc267 +6b92ba1bd527018ea9035137823f22df1b9a56198cc1db3166b288a3f679afba +15468D3589E50121E0611A8F81804371 +0 +dff136a8eabf0cd3e142026e5c22d3b7 +3ad1ecee0b42d92ed0195632e48d7cbc711c3cd41446e50ffa760089e5d2b14a +4E8DAB1275D70581D3F621C8FEB89996 +0 +1c5cbc46c874e527d6dd9488f4bf2669 +943e2ad4014337bfd5ddf783e1df3f6136dc03dc2d6f8f8d2275c70399129fd2 +CFEF9A69A62B9E6C667D8FD5C1CE9D4E +0 +64082c7fdc1087bf58a660f00fb3c48c +f0ede3f81d54ea3c9d8f7d0292a6d93e275266cd131424d6c12d7f69c4961199 +DABF16BE94CCA1CF849F8EB8BC84710D +1 +e8fc7b4f6d989ae31f0746679275707c +1bac1f58a10c05c4a6dfdec412c4a097a60e27242e89a18e64f3df89384e3d1d +D0A47C4BB5B596F52E60F8C0DDB6123D +1 +dd1a5c031413ae888c44bc90a781a542 +7dc23865d337b9b5da5ce7e07a251bc97f72f439551b56f2ea116c217bf80029 +A513C49BAC226BBC72A16792B764868F +1 +19deab563a84e0dedfdc038cface79b1 +0528a44020554b2faa39480a12767e335ef57bb071e9171e8211b176e8a5693b +A9AC55E09C0950F1FA299370D6CEBB15 +0 +187d961d7e7d31ae23381f1939eded88 +ead752c232173ccc575ba1efa40cff40597ffb0e41a7cd7c4925d28a0791f476 +55B9EADDF673D71BA9ACE2F583CABAA4 +1 +eeb41c9cdf678c981e9e3ed39fd4f923 +1a397cf0dc628c95056c7e63a4983a8746df0ae39df3be3626604aa968256588 +E75A449CD1BF5DB3B5B6855237553917 +1 +41588dc438facc9ec530d31fd1d78a42 +25eab468d64f2ddf943eebaa5c965dd05dddcfa92f0f60a9384401a80ec91e13 +6A4DA13D0DF9A529C105296C8225E443 +1 +290a11c12cb6e49805e5441e5bd3b8e9 +0ebf239c8d65f3087653f4e905ba8a5403ecdb681449d6bd82313310542a031c +87B18CBB12C4F8DCACE93C769C2E2CAD +1 +47807924ac2e700e17c7418dd6d2b771 +494cc7f652c9e246a8a7e9a81c7ea4b3caf86dae0af4cb425da75e4772981b37 +1772AB30520074B99930E26DA6FC7349 +0 +461a2ae9c0defad7c1bcc70c9b168708 +58e004386cefd5b51d4d78d8a199ed383d0a6ea5139cfcb0427160af2d969707 +B18101EA319C237925497C3C7E6E4216 +0 +7c2d8b853839d3eba7289f3154afdfd1 +6ca6b53a9acef2034e26458152e5c489a12ddfc4d543d5267f51c4a05c4592ad +E923771CB8D773E28CFD04204317220F +0 +3c9e97a675db5c85ef8cba878361464b +4e3235c14bf8d01db57a6c459a385174ffb8647aa89884e9c470587461e27b7b +D1B1F931D74190CF16A128F9E162D44F +0 +e90cea51c849ea652e6f31b9d3f25037 +caf01c7beb7640f709ddb311ccffac5e81454d8e7d5c4732595f505a9733fe95 +E1AC47626A8FF9890AD5518B9EF01AAA +1 +3a2e906e73421e08a067716ab54dc07c +5ebd66cfcf52aa8d389ad58aea941e918515096242556ac511963955a660d0a7 +D7182F5F7E7807F7A456BC17E8C58163 +0 +c16bc9b5cf8fab0014af729e6158b529 +f83ab3f3e19fe23a8a7307e5b3a32f8f6b877837cadc501287e9a5ceb58bd6ef +7081440981D6B25539855D75F07CAF1E +0 +6dfa99c7483527878193979f0d61fa38 +f0ac424bee3d1201afd445f11e03680f48a00bd59dea7ff84621d02601033705 +EFAFDEE2D29D5A9BB944FBE009464B73 +0 +57ddde4f02f3f5114277b579cdd15c93 +095cd0dc8ff0fabcd243ec919a9a7756b980ab33c64bca2eb33f1bfb608378bf +8211A67264051EF21FBCDF30328B62EF +0 +7544273aca8b2bb7d707b24dde223be8 +e783d03791f77eaac65ea787b220a0e5fc1ed3998d457269f2e3f61272768d1c +A64AA62499C43D067667497F001D9D16 +0 +c4a006060212bf41c0ec80d41c9c262b +c8af1539a9762f2dbd5fcac588eec41efb50901c80abb26f26f3abe3d4b9ad62 +1AB89D6B4BAAF8687412B33CB752B788 +0 +24eacbde33eee398b8638578dfcebf6a +a16f6681d0474b9585f698e44a4c46574f065f16cf2509d507357906e332f32c +2BC004B013E9AB7C174EC0AD0969E37D +1 +f0ec96385ff7cae68b54be5693e32c61 +f2f1767d09ae4d727b7361404ea62b994b317aaae323de3aca77bab5a9e9a7fb +ADF414439F529CFC1777FDDF137E4011 +1 +99142991ec3abbea344125a8fad4461b +72a11aab4c96c8d25efa2c843d28c5cc8adc7487fe1614edebb54636c414a5ab +527E0C3B3C267A4E83F46E5B0EBEE0EA +0 +3210945884028a0fa2fcdd345b5d44f1 +d207920bffeba1ddde910eb3efb62295135f83b8e80a29cd7ed54303832dbc11 +CCA7A52CDBAE054D55AA1E4C7E6D9E40 +0 +e813af8ac3452b9ced3a91a3bf5f8629 +9f505c074f204c54fb74bd16d092efa4d0bda3275c94da41879880e1079b8d34 +7F1461CB0526BE4B32887AF8D9280048 +0 +850c73915bfd8d6775eefa3874c516fb +c10d16844a7c85a361ca7a940aaf7b9504f7b4a7a90fb0d496a2a9082fef93a7 +61A4085C5B8C20E7F0157238E6D52DB6 +1 +026d084f2a9dd13bcb918cf1fccdc9a3 +510c1625aed515207dbfd02126eabcdf2cfe1d12848060fa97b94270a04464ca +0B70A1E73C152C584DE86A264AFDDA84 +1 +d4a74a79ff75b77115cfeb497ba7b875 +6cbe4880723b863abe61df16ae0fa9c4cb21b8764a2725f2d797efd0608ac114 +D6F01AEDDB3EC9B1F8B99EC2BF9856AD +1 +89fdcace9ed28b7d58961c6fd987535d +cb2267ba798cba3f3c8cde3c40a2a86addee6abb46c900112b5f6b08b531d76d +C29EC5E5A083168F704B8748DD6D66A7 +1 +9346171c871921b157b7c1080e55bfb5 +8049b93f6558d6eaec32ec4a14d274cb650900f74a37fc2318e2f47ed4223bb8 +6D1AEA77E6AD89B3B7923AF3D04EBA16 +1 +d55348f91ca2c960067c9b0fe02dad83 +a85faac4c1a9ce0ace88cd40add9a588a22b57e3c6cb6cd203b147e6053c09ad +0ECF38BE5E7CA748181233D5DCEF10C1 +1 +ad5abfb20e3ade654f7adeabba2c88f2 +23512c4ff216a08ecafddc8891cbe66e75d9064f4e4c11745074fa9cc6764e5e +6611F13204052C4AFCB7BD6DAE81E79C +0 +90146f0cfc2cd1c7a21aa7980db75390 +3badfa61769ef0fa9bca8943bb5478869859379762ba5774e1525d72e57cc116 +AD36B71D96B292F03C3A305FA4D51205 +0 +52efcb5c245df54ae4176c21e849b2d5 +5f2ee05bd4c4e905d704a0e43d509a907cff2b6ac350693ce4e979e24aae8236 +F458A4B347834D0D6134DF891FF5A297 +1 +d1148ec2f43b0abfec82f53bee6051c0 +2a2a3df933598f729782d8d9e26cd4b970935e606f08380cce9587bb99c433bc +C600E23E174386641244242820EE7633 +1 +ebb1983ce46656e9a420081cadbda04f +b2758d7d1e84e579d493aa80d343d533dd638b72de71ce99656c7a3ed2fc7257 +F85B18116B6B6D3F83243D116EFC5FB5 +1 +750e7786f02f8b68ad511e12b36f8ba0 +a3be9751c80edd26892bb8da128cbc07b19e97e98652adf84364ce886c36b6c9 +03E7FC6C56D44E60A37AF335EF2B43FA +0 +c6a262027d0c128c3168a51e44308c4c +baf046834982498ece785e1a19c0e98b510577ca86b7d664da1bfefcf2ce99b4 +8AA9701706969081F96AFDFF749D8C75 +1 +90e50adc4ef2f7ea70f0e00d47ace2e5 +9b20575dee3341e42923b3a25f9055edcba129f9b0ee33bf09711e980aea04ee +92F8C44BF61A7E1ED18D18468BC9F1E3 +1 +7c8e956911dabff12c574741c503af1a +7c0be2cc26d9b36919542f2881eb1abd911675620cfe47d192b3ef33fe155206 +CBD194B2090521BFB6D6A82175531940 +1 +3d06bb68eea7d1fd84e90473734ac7bc +1d6007e3155e9c6ca003234030b7a37f829d87464c71acf5ace97029c10cfbcf +8032CFD8DA2F1117C4B9F1B69C3DD388 +0 +1bdd7dd3f3f217fbdf4aaeca870003dd +0bac4d4ee7f8ed053f1fac8830a7882de22967682c4fd780baf12967604d7a36 +144EC15DB0049528F6C89514CB1407D2 +0 +4955c59f5ad9e209f6c6d05a4f59dcb5 +45dd30286ca60c1aa87580f2226866e1452e2bb22f3ff425176d698afe7c8e06 +59243F445A6A142BCE54CDB468E34EAC +1 +664cac3390ec533ad715d84b889f460c +fb92645ff8c12881200bedea4c45cfaa420c73df880cded917c3ebba7d2bc0cd +6E260E06191F5E8B61B4587A28B875A5 +0 +d68c4e013cedee853e40b6b25e052cc9 +fffb5f46e14b16f66ba8de0579166d380d2bd6a1b5e7456706ef3f3fad00931d +D8AA8F4ADEA5558F20671EC60F1E7359 +0 +bd66542fec583cea3a30297f3334da5e +4e02d611cf05f9e47526ee838e9de08d51db174660b39afb42e3383456bb9195 +325A3418A07EEAF9AACB3D81422A848B +1 +7225600f5bde8a6650434137acedf621 +a8c1f96756af6eebce71c5fe136fd62c1f279fc738f2cd5e47d46af298b8c248 +DDAAB85050AF01DB26F2DD3230B4C771 +0 +2b67fd3173f5632474d9338bf4503d2a +cc899711dabf30ca0559969b5f3dad34ebb3941c4d16317c0e26555066f0b887 +D7C6B485280CEDED5A579802709EDF1E +0 +e14923ff3fb14f3d9b86028fc4f44ca4 +6841da987ddb386a84d6b6880c032774f465508c2d68d3f4ef5b2dfca0538d7a +34D5DE25464D4C47A2745C97A3348106 +0 +40a86705de6d60dfa30a7344bd21b231 +7be2f1c62811c8c8e8e28347a85fc5c26a2bae392e037f9d9795edc0b731bcf6 +5C87D4E7BEB4E879DCB0739C0CAED345 +1 +94adc5f7db27f7d695b20385cdca4160 +08440e2c66233c7339080e27970f377b9189ec2a0bdc689d4b27fccb4180fd7a +72B1AE9DA09BAD3E5093953A47A418E5 +0 +30b5cd15d8bf63464eb3a66f6561e0d1 +e334099be2398e0fb394f657685662dbb33cf97d00d189ab671386b2045b5879 +A3DD39196CD5979D55F68EA6982D198D +1 +e60119ac33756ccb5f4cee142c356a73 +f0e559e4efc759914d7e3baaeb4f2468303fea016a97c35d8889c23de10cf719 +97AECD06DAD0DC793BFFDCDBABEE1467 +1 +24afd88f29c68a387625d5ce2c018f59 +0fed820b4b8e81615e0427e7d836c7a8c834bbf7ebd20f5b8a908d1c87d37cc5 +83A399F01002AB59785BEEE8C4AA0AE0 +1 +4528a6112cfe78635099b1cb33bfa1c7 +3471d50f5acddc95b4be816688b2f94bb3a649897a4bdbcbb3172cede7a311c4 +914340DAEB68D390F876F9F2CC1762CA +0 +3ea4f08e4aeb1043d4dbe48078369536 +364ff79af615f47ae8453318c770ca088f33e0dc3e7c5e4945609a0c38031ac5 +8965FCBCFBC7F13EE8B1A302E89AAF71 +0 +84c9ffe0b5fa6eb682891a637d42519f +08cf34b885e2b81de78c976e910e75577f79910bc92c1f8b8caab78a8a205ebf +C1223475266BEE8E73C8DA3EDE377896 +1 +33c58c987474ecfb657cfa9349bee119 +529caf1576bf84604d4983e3cbd726b70055b39f9f1666e1cc70606844eb9f29 +4865F0406138F259F67659C19B57DF6D +0 +57ac4069d265a8070391b98818ac0c25 +27d468384a7df9f9262b19d07bb91e27a3d777773e9166e228e38cf2b5feff52 +E74A81BB283B0B63875BB4DCB83EDA99 +0 +db7ddbab8a002a03310235305393020c +bdf3c83544faa775f8c5b35ef0cd566603997b476e64b232d147f154cc350c3d +411DE8E1EA14C4DF2CD63A5A388A2FD3 +0 +ea25613e6a3e5e75fb595bc925f04c12 +8a5368658daed5810aaf6102fd993ccf547708f802dc1a42c8c7de1c341caea2 +3DA281F36863B256CAF96E40D58CC43C +0 +226af3197348778d484acf125fc6a68c +475d4a7c5bf10dedae38fac94da0fe8a34040e1237898b98687102abcad43b37 +67A6001F2022B9380A7D1AAB73FC7224 +1 +18f5af432ca3aa0156a1e108cfa29b6c +12022b1bf825e04652f05a4be3d7d4fe962d8df71a553efd8c29aa87292b6eb6 +4645957E382D3E7725D20D1654F57E62 +0 +242f42476301d0d3d7504cf1f92ce104 +90a590107a33596dcc0cec3b931e60e3718d77c4bf28aa30c663ba9c038e8b31 +88BBF697FEC3208ED852610E5A468E8F +1 +eafe3b32ac14a725cd4eab2c80c928bf +e3a9b87485fcce15605f46b01e1a9b8c285b53ad36cc9c8c3b0da4b49783dae1 +252F6B8113D6BE7022A2D41AC8231E9F +0 +fe38f2f46ad4534cac5ed8a8cafb4719 +843e46dbb3c62073758dfa8d2362d4b7bdc627970cb47309948e6f78e137828a +3B53D86E7EDE30ECCB4D48CDCFB4A5B4 +1 +5fc41b53082015bb82be890bdfcdc6ad +204affc90b752497bd62cececb1649572495eb86d1c0f71c90fbd55cddee7fba +61CDAEC76B59D80EE07C6E77E0347375 +0 +0200e9265e7a4c6173324abf8583f9b4 +20054a339bdf9212ef711e7031544a6d7553f3fa187fef2b070252482aa6560b +42946B0FD22FB65902C03E4002DA4F77 +1 +1ce8a90d31d4731e1961300e0c94e121 +f3b1b42a41ea19b6dd2bf8b03038a01f9c445cc540803c8676ae1539e9f4a9db +A83FFCF7087AB62F6D365610887D2C2F +0 +848047dba09fcaba835de66bb2690ee4 +1d06944aecc2d4df467faa054e9dda7be6508180d56e240e0a2fa697bd0e1801 +AE7AC08E24FD92EBAA1E3F18020CA6BF +0 +df5514064a807556c41e6b21f5d8ce11 +a31579402fd5584f68c42f69ae583c52b181adc86af104122ded12abbd350e43 +EC601E10E2FF361ACB72B53D6C7A9E35 +1 +cf7733c757c82b8f9c201a795aab4036 +f3bd0fe560f2adc8d67fdac537643af04208b35ab1207b1baa7c59ab2a567693 +AB161B921B1CB5ED2ECB9ECF6ED99C44 +0 +ee6d994833286198b25cf1656a549d2a +f7f10e71b9c5cdd6adde27a4a22d7df363d36217f450744b1234281653419a9b +CAF753B3D5FB09F1F4A708650161D691 +0 +5a10bc84df9fcb56f8be0426759552ae +2476137e2b07ee38cfe37bebc66fb7cd6181b31743fa75fe8ff6c000cd45cf8c +3BD488E3E5F768C6B3E079606873157A +0 +0cc1d4312e662aa627b485795aac2be8 +c9fc1bd3005cae8719598a08ed7f6bbfd1dffca5a4658a662bb4e949e0f4d976 +189A1425D400DAD901D5447CA69BA175 +0 +86e55a16939aab2d9f3aba30b9488505 +b1bcae769badfa923216673b36bab234eadfa38359634efba16ed6556a12e25d +6B5F09A6DDC3BA68E05E814D58E5A7F9 +0 +b20fdf115635d309c84e84d86a5c1c63 +2a821def75bafc7dae0c94deca259fe8cd67e23b04fa0f1c9547ebec436f8431 +55A567335B54490A624D5929985EBFCF +0 +84f60ab5fc5197b43929511a998b7a5f +01776f608425b3500a5e25044e247385d03929ccd9b0ec056ef7a479886707f6 +33212DC7C89B44793EDF0FD0AF8B60D3 +0 +ce23e67dcdd80f3d6b9e0aeb1beb4e8a +bf22621b2c4e197ec3d9a1dd5394cf44f4b1ca23b79ba2addd1d5df87b9911b3 +7DB4CC31A61CDB6954720EAF7401AFE1 +0 +3422040986e8017716774bd9a9af0439 +8162ef7b1eba1ed997b84967dc788b54263af336edff6ae0a69d2444600f074e +71BA9962AD4F5FE69A777855641984AF +0 +827f6bf1a0863b08625370ce5b38d225 +79b64c49385c4cd8becd9951e6357c5ef807a1b3da62b429e5c18841d7da8f99 +29D3D1757AE8F5AA7140C231BD35086E diff --git a/256_enc_dec/testbench.vhd b/256_enc_dec/testbench.vhd new file mode 100644 index 0000000..d235447 --- /dev/null +++ b/256_enc_dec/testbench.vhd @@ -0,0 +1,118 @@ +library std; +use std.textio.all; +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use work.all; + +entity tb_aes is +end tb_aes; + +architecture tb of tb_aes is + + constant clock_cycle : time:= 100 ns; + + file vector_file : TEXT; + + signal ct : std_logic; + signal pt : std_logic; + signal clk : std_logic; + signal rst : std_logic; + signal done : std_logic; + signal key : std_logic; + signal mode : std_logic; + + component AES + port ( + ct: out std_logic; + done: out std_logic; + clk: in std_logic; + rst: in std_logic; + pt: in std_logic; + key: in std_logic; + mode: in std_logic); + end component AES; + +begin + + mut: AES port map (ct, done, clk, rst, pt, key, mode); + + process + begin + clk <= '1'; wait for clock_cycle/2; + clk <= '0'; wait for clock_cycle/2; + end process; + + process + variable tmp_line : line; + variable mode_v : std_logic; + variable key256 : std_logic_vector(255 downto 0); + variable pt128 : std_logic_vector(127 downto 0); + variable ct128 : std_logic_vector(127 downto 0); + variable buffer128 : std_logic_vector(127 downto 0); + variable test_ctr : integer range 0 to 1000000; -- can fail if too many vectors + variable loading_ctr : integer range 0 to 255; -- can fail if too many vectors + variable reading_ctr : integer range 0 to 127; -- can fail if too many vectors + begin + file_open(vector_file, "test_vectors_256_enc_dec.txt", read_mode); + test_ctr := 1; + + while not (endfile(vector_file)) loop + + -- we first read a single test vector from a file + readline(vector_file, tmp_line); read(tmp_line, mode_v); -- read mode + readline(vector_file, tmp_line); hread(tmp_line, pt128); + readline(vector_file, tmp_line); hread(tmp_line, key256); + readline(vector_file, tmp_line); hread(tmp_line, ct128); + -- reading a single test vector is done + + rst <= '0'; + mode <= mode_v; + wait until rising_edge(clk); + + rst <= '1'; + loading_ctr := 0; + loading_loop: loop + if loading_ctr <= 127 then -- load pt only in the first 128 cycles always + pt <= pt128(127-loading_ctr); + end if; + + key <= key256(255 - loading_ctr); + if loading_ctr = 255 then + exit loading_loop; + end if; + + loading_ctr := loading_ctr + 1; + wait until rising_edge(clk); + end loop; + + + waiting_loop: loop + wait until rising_edge(clk); + if done = '1' then -- done signals indicates that the encryption/decryption is almost over, and the result will be available during the following 128 cycles + exit waiting_loop; + end if; + end loop; + wait until rising_edge(clk); -- wait until the next rising_edge + + reading_ctr := 0; + reading_loop: loop + buffer128(127 - reading_ctr) := ct; + if reading_ctr = 127 then + exit reading_loop; + end if; + reading_ctr := reading_ctr + 1; + wait until rising_edge(clk); + end loop; + + assert buffer128 = ct128 report "======>>> DOES NOT MATCH <<<======" severity failure; + report "passed vector #: " & integer'image(test_ctr); + test_ctr := test_ctr + 1; + + end loop; + assert false report ">>> ALL GOOD <<<" severity failure; + wait; + end process; +end tb; diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..828dc00 --- /dev/null +++ b/README.txt @@ -0,0 +1,2 @@ +This repo contains the source code for the paper "Six Shades Lighter: A bit-serial implementation of the AES family". +The code is licensed under GNU General Public License v3.