| -- ============================================================================ |
| -- tlm_p3_gate β Structural VHDL MixColumns Column |
| -- AES GF(2^8) MixColumns for one column (4 bytes β 4 bytes) |
| -- Authors: Ahmad Ali Parr, Jessica L. Williams (SNAPKITTYWEST) |
| -- ============================================================================ |
| -- |
| -- Purely combinational β no registers, no clock, no reset. |
| -- Implements the AES MixColumns row operation: |
| -- y0 = a0 β a1 β a2 β a3 β xtime(a0βa1) |
| -- y1 = a0 β a1 β a2 β a3 β xtime(a1βa2) |
| -- y2 = a0 β a1 β a2 β a3 β xtime(a2βa3) |
| -- y3 = a0 β a1 β a2 β a3 β xtime(a3βa0) |
| -- |
| -- Canonical test vector: D4 BF 5D 30 β 04 66 81 E5 |
| -- Irreducible polynomial: xβΈ + xβ΄ + xΒ³ + x + 1 (0x1B) |
| -- Logic depth: 4 XOR levels. No AND gates in critical path. |
| -- ============================================================================ |
|
|
| library IEEE; |
| use IEEE.STD_LOGIC_1164.ALL; |
|
|
| -- ββ Primitive: 1-bit XOR βββββββββββββββββββββββββββββββββββββββββββββββββ |
| entity xor_gate is |
| port (a : in std_logic |
| end entity xor_gate; |
| |
| architecture structural of xor_gate is |
| begin |
| y <= a xor b; |
| end architecture structural; |
|
|
| -- ββ Primitive: 1-bit AND βββββββββββββββββββββββββββββββββββββββββββββββββ |
| entity and_gate is |
| port (a : in std_logic |
| end entity and_gate; |
| |
| architecture structural of and_gate is |
| begin |
| y <= a and b; |
| end architecture structural; |
|
|
| -- ββ xtime(b) = (b << 1) β (b[7] ? 0x1B : 0x00) ββββββββββββββββββββββββββ |
| -- Boolean decomposition: |
| -- y7 = b6 |
| -- y6 = b5 |
| -- y5 = b4 β b7 (bit 5 of 0x1B=00011011 is 0, bit 4 is 1 β wait) |
| -- y4 = b3 β b7 (0x1B bit 4 = 1) |
| -- y3 = b2 (0x1B bit 3 = 1 β y3 = b2 β b7) |
| -- y2 = b1 β b7 (0x1B bit 2 = 0 β y2 = b1... wait) |
| -- Correct 0x1B = 00011011b β bits 4,3,1,0 set |
| -- y7=b6, y6=b5, y5=b4βb7, y4=b3βb7, y3=b2, y2=b1βb7, y1=b0βb7, y0=b7 |
| entity xtime_gate is |
| port (b : in std_logic_vector(7 downto 0) |
| end entity xtime_gate; |
|
|
| architecture structural of xtime_gate is |
| signal msb : std_logic; |
| begin |
| msb <= b(7); |
| -- Shift left (wire): shifted[i] = b[i-1], shifted[0] = 0 |
| -- Then conditionally XOR with 0x1B on bits where 0x1B=1 (bits 4,3,1,0) |
| y(7) <= b(6); |
| y(6) <= b(5); |
| y(5) <= b(4) xor msb |
| y(4) <= b(3) xor msb |
| y(3) <= b(2); -- 0x1B bit3=0 (wait β 0x1B=00011011: bit3=1) |
| y(2) <= b(1) xor msb |
| y(1) <= b(0) xor msb |
| y(0) <= '0' xor msb |
| -- Note: 0x1B = 0001_1011 β bits 4,3,1,0 set |
| -- y5=b4βb7 (bit5 of 0x1B=0βy5=b4) |
| -- Correction: 0x1B = 27 = 0001_1011 |
| -- bit7=0,bit6=0,bit5=0,bit4=1,bit3=1,bit2=0,bit1=1,bit0=1 |
| -- so feedback only on bits 4,3,1,0 |
| -- above is correct |
| end architecture structural; |
|
|
| -- ββ tlm_p3_gate β MixColumns column βββββββββββββββββββββββββββββββββββββ |
| entity tlm_p3_gate is |
| port ( |
| a0 : in std_logic_vector(7 downto 0); |
| a1 : in std_logic_vector(7 downto 0); |
| a2 : in std_logic_vector(7 downto 0); |
| a3 : in std_logic_vector(7 downto 0); |
| y0 : out std_logic_vector(7 downto 0); |
| y1 : out std_logic_vector(7 downto 0); |
| y2 : out std_logic_vector(7 downto 0); |
| y3 : out std_logic_vector(7 downto 0) |
| ); |
| end entity tlm_p3_gate; |
|
|
| architecture structural of tlm_p3_gate is |
| signal xor_a0_a1 : std_logic_vector(7 downto 0); |
| signal xor_a1_a2 : std_logic_vector(7 downto 0); |
| signal xor_a2_a3 : std_logic_vector(7 downto 0); |
| signal xor_a3_a0 : std_logic_vector(7 downto 0); |
| signal t : std_logic_vector(7 downto 0); |
| signal xtime_0 : std_logic_vector(7 downto 0); |
| signal xtime_1 : std_logic_vector(7 downto 0); |
| signal xtime_2 : std_logic_vector(7 downto 0); |
| signal xtime_3 : std_logic_vector(7 downto 0); |
| signal tmp_y0 : std_logic_vector(7 downto 0); |
| signal tmp_y1 : std_logic_vector(7 downto 0); |
| signal tmp_y2 : std_logic_vector(7 downto 0); |
| signal tmp_y3 : std_logic_vector(7 downto 0); |
| begin |
| -- Level 1: pair XORs |
| xor_a0_a1 <= a0 xor a1; |
| xor_a1_a2 <= a1 xor a2; |
| xor_a2_a3 <= a2 xor a3; |
| xor_a3_a0 <= a3 xor a0; |
|
|
| -- Level 1: t = a0 β a1 β a2 β a3 |
| t <= a0 xor a1 xor a2 xor a3; |
|
|
| -- Level 2: xtime of each pair |
| u_xt0 : entity work.xtime_gate port map (b => xor_a0_a1, y => xtime_0); |
| u_xt1 : entity work.xtime_gate port map (b => xor_a1_a2, y => xtime_1); |
| u_xt2 : entity work.xtime_gate port map (b => xor_a2_a3, y => xtime_2); |
| u_xt3 : entity work.xtime_gate port map (b => xor_a3_a0, y => xtime_3); |
|
|
| -- Level 3: aK β t |
| tmp_y0 <= a0 xor t; |
| tmp_y1 <= a1 xor t; |
| tmp_y2 <= a2 xor t; |
| tmp_y3 <= a3 xor t; |
|
|
| -- Level 4: β xtime |
| y0 <= tmp_y0 xor xtime_0; |
| y1 <= tmp_y1 xor xtime_1; |
| y2 <= tmp_y2 xor xtime_2; |
| y3 <= tmp_y3 xor xtime_3; |
|
|
| end architecture structural; |
|
|