--- ============================================================================
--
-- Design unit      :   aes_gf_2exp8_arith
--
-- File Name        :   aes_gf_2exp8_arith.vhd
--
-- Purpose          :   Design file
--
--
-- Depends on       :
--
-- - Package(s)     :   -
--
-- - Module(s)      :   -
--
--
-- Dev. Platform    :   Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
--
-- - Simulator(s)   :   Modelsim XE III 6.0d
--
-- - Synthesis      :   Xilinx XST
--
-- - Place & Route  :   Xilinx PAR
--
--
-- Errors           :   None known
--
--
-- Limitations      :   None known
--
--
-- Notes            :   -
--
--
-- Author(s)        :   A. Freund (af) <a.freund@dsi-it.de>, 
--                      M.v.d.Wall (mvdw) <vdwall@dsi-it.de>
--                      Digitale Signalverabeitung & Informationstechnik GmbH,
--                      Bremen, Germany
--
-- ============================================================================
--
-- Revision List:
--
-- see SVN logs
--
-- ============================================================================
--
-- Naming conventions:
--
-- - coding style: record-signals for related purposes (Gaisler-style)
-- - active-low signals are indicated by appending "_n"
-- - constants are in UPPERCASE
-- - name parts are separated by "_"
--
-- ============================================================================

library ieee;
use ieee.std_logic_1164.all;


package aes_gf_2exp8_arith is


	subtype gf_2exp8_t is std_logic_vector(7 downto 0);


	function add_gf_2exp8(a, b : in gf_2exp8_t) return gf_2exp8_t;

	function mul_gf_2exp8(a, b : in gf_2exp8_t) return gf_2exp8_t;


end aes_gf_2exp8_arith;


-- AES irreducible polynomial
-- POLY = 2**8 + 2**4 + 2**3 + 2**1 + 2**0

package body aes_gf_2exp8_arith is


	function add_gf_2exp8(a, b : in gf_2exp8_t) return gf_2exp8_t is
	begin
		return (a xor b);
	end add_gf_2exp8;


	function mul_gf_2exp8(a, b : in gf_2exp8_t) return gf_2exp8_t is
		variable c : gf_2exp8_t;
	begin

    c(0) := ((a(0)) and b(0)) xor 
        ((a(7)) and b(1)) xor 
        ((a(6)) and b(2)) xor 
        ((a(5)) and b(3)) xor 
        ((a(4)) and b(4)) xor 
        ((a(3) xor a(7)) and b(5)) xor 
        ((a(2) xor a(6) xor a(7)) and b(6)) xor 
        ((a(1) xor a(5) xor a(6)) and b(7));

    c(1) := ((a(1)) and b(0)) xor 
        ((a(0) xor a(7)) and b(1)) xor 
        ((a(6) xor a(7)) and b(2)) xor 
        ((a(5) xor a(6)) and b(3)) xor 
        ((a(4) xor a(5)) and b(4)) xor 
        ((a(3) xor a(4) xor a(7)) and b(5)) xor 
        ((a(2) xor a(3) xor a(6)) and b(6)) xor 
        ((a(1) xor a(2) xor a(5) xor a(7)) and b(7));

    c(2) := ((a(2)) and b(0)) xor 
        ((a(1)) and b(1)) xor 
        ((a(0) xor a(7)) and b(2)) xor 
        ((a(6) xor a(7)) and b(3)) xor 
        ((a(5) xor a(6)) and b(4)) xor 
        ((a(4) xor a(5)) and b(5)) xor 
        ((a(3) xor a(4) xor a(7)) and b(6)) xor 
        ((a(2) xor a(3) xor a(6)) and b(7));

    c(3) := ((a(3)) and b(0)) xor 
        ((a(2) xor a(7)) and b(1)) xor 
        ((a(1) xor a(6)) and b(2)) xor 
        ((a(0) xor a(5) xor a(7)) and b(3)) xor 
        ((a(4) xor a(6) xor a(7)) and b(4)) xor 
        ((a(3) xor a(5) xor a(6) xor a(7)) and b(5)) xor 
        ((a(2) xor a(4) xor a(5) xor a(6) xor a(7)) and b(6)) xor 
        ((a(1) xor a(3) xor a(4) xor a(5) xor a(6) xor a(7)) and b(7));

    c(4) := ((a(4)) and b(0)) xor 
        ((a(3) xor a(7)) and b(1)) xor 
        ((a(2) xor a(6) xor a(7)) and b(2)) xor 
        ((a(1) xor a(5) xor a(6)) and b(3)) xor 
        ((a(0) xor a(4) xor a(5) xor a(7)) and b(4)) xor 
        ((a(3) xor a(4) xor a(6)) and b(5)) xor 
        ((a(2) xor a(3) xor a(5)) and b(6)) xor 
        ((a(1) xor a(2) xor a(4) xor a(7)) and b(7));

    c(5) := ((a(5)) and b(0)) xor 
        ((a(4)) and b(1)) xor 
        ((a(3) xor a(7)) and b(2)) xor 
        ((a(2) xor a(6) xor a(7)) and b(3)) xor 
        ((a(1) xor a(5) xor a(6)) and b(4)) xor 
        ((a(0) xor a(4) xor a(5) xor a(7)) and b(5)) xor 
        ((a(3) xor a(4) xor a(6)) and b(6)) xor 
        ((a(2) xor a(3) xor a(5)) and b(7));

    c(6) := ((a(6)) and b(0)) xor 
        ((a(5)) and b(1)) xor 
        ((a(4)) and b(2)) xor 
        ((a(3) xor a(7)) and b(3)) xor 
        ((a(2) xor a(6) xor a(7)) and b(4)) xor 
        ((a(1) xor a(5) xor a(6)) and b(5)) xor 
        ((a(0) xor a(4) xor a(5) xor a(7)) and b(6)) xor 
        ((a(3) xor a(4) xor a(6)) and b(7));

    c(7) := ((a(7)) and b(0)) xor 
        ((a(6)) and b(1)) xor 
        ((a(5)) and b(2)) xor 
        ((a(4)) and b(3)) xor 
        ((a(3) xor a(7)) and b(4)) xor 
        ((a(2) xor a(6) xor a(7)) and b(5)) xor 
        ((a(1) xor a(5) xor a(6)) and b(6)) xor 
        ((a(0) xor a(4) xor a(5) xor a(7)) and b(7));

		return c;

	end mul_gf_2exp8;


end aes_gf_2exp8_arith;
