OpenCores
URL https://opencores.org/ocsvn/nfcc/nfcc/trunk

Subversion Repositories nfcc

[/] [nfcc/] [trunk/] [rijndael/] [keyexpansion/] [keyexpansion.vhdl] - Rev 2

Compare with Previous | Blame | View Log

-- ------------------------------------------------------------------------
-- Copyright (C) 2010 Arif Endro Nugroho
-- All rights reserved.
-- 
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
-- 
-- 1. Redistributions of source code must retain the above copyright
--    notice, this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright
--    notice, this list of conditions and the following disclaimer in the
--    documentation and/or other materials provided with the distribution.
-- 
-- THIS SOFTWARE IS PROVIDED BY ARIF ENDRO NUGROHO "AS IS" AND ANY EXPRESS
-- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- DISCLAIMED. IN NO EVENT SHALL ARIF ENDRO NUGROHO BE LIABLE FOR ANY
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
-- 
-- End Of License.
-- ------------------------------------------------------------------------
--
-- KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk)
-- begin
--    word temp
--    i = 0
--    while (i < Nk)
--      w[i] = word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3])
--      i    = i + 1
--    end while
--    i = Nk
--    while (i < Nb * (Nr+1))
--      temp = w[i-1]
--      if (i mod Nk = 0)
--        temp = SubWord(RotWord(temp)) xor Rcon[i/Nk]
--      else if (Nk > 6 and i mod Nk = 4)
--        temp = SubWord(temp)
--      end if
--      w[i] = w[i-Nk] xor temp
--      i    = i + 1
--    end while
-- end
-- Nk (Number of Key), Nb (Number of Block), Nr (Number of Round)
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity keyexpansion is
  port (
  key : in  bit_vector (31 downto 00);      -- source key
  w   : out bit_vector (31 downto 00);      -- expanded keys
  Nk  : in  bit_vector (03 downto 00);      -- 128,192,256 => 4,6,8 (0100,0110,1000)
  ld  : in  bit;                            -- 'ld' must active for Nk clock to load keys.
  v   : out bit;                            -- output valid signal
  clk : in  bit;                            -- clock signal
  rst : in  bit                             -- reset signal, its wise to reset before any action.
  );
end keyexpansion;
 
architecture phy of keyexpansion is
 
  constant Rc  : bit_vector (79 downto 00) := ( X"01020408_10204080_1B36");
  signal Rcs   : bit_vector (79 downto 00) := ( X"01020408_10204080_1B36");
  signal int   : bit_vector (255 downto 0); -- 256 bit internal register
  signal cnt   : bit_vector (03 downto 00); --   4 bit counter start from 1 not 0
  signal cnts  : bit_vector (05 downto 00); --   6 bit counter start from 1 not 0
  signal Rcon  : bit_vector (07 downto 00); -- round constant
  signal rot   : bit;                       -- RotWord signal
  signal crst  : bit;                       -- reset counter
  signal rsts  : bit;                       -- reset state counter
  signal mod4  : bit;                       -- modulo 4 (used in case of 256bit key)
  signal Nk8s  : bit;                       -- Nk 8 signal
  signal ldi1  : bit;                       -- delayed load signal
  signal ldrs  : bit;                       -- reset signal from load
  signal vld   : bit;                       -- valid signal
  signal vrst1 : bit;                       -- reset valid signal for 128bit key
  signal vrst2 : bit;                       -- reset valid signal for 192bit key
  signal vrst3 : bit;                       -- reset valid signal for 256bit key
  signal rstsc : bit;                       -- reset state counter from reset valid signal
  signal sai   : bit_vector (07 downto 00); -- SubWord input signal
  signal sbi   : bit_vector (07 downto 00); -- SubWord input signal
  signal sci   : bit_vector (07 downto 00); -- SubWord input signal
  signal sdi   : bit_vector (07 downto 00); -- SubWord input signal
  signal sao   : bit_vector (07 downto 00); -- SubWord output signal
  signal sbo   : bit_vector (07 downto 00); -- SubWord output signal
  signal sco   : bit_vector (07 downto 00); -- SubWord output signal
  signal sdo   : bit_vector (07 downto 00); -- SubWord output signal
  signal wi1   : bit_vector (31 downto 00); -- w[i] state signal
  signal wiNk  : bit_vector (31 downto 00); -- w[i-Nk] state signal
  signal temp  : bit_vector (31 downto 00); -- SubWord,RotWord,Rcon signal
  signal tmp   : bit_vector (31 downto 00); -- SubWord,RotWord,Rcon signal
 
--For SubWord
  component sbox
    port (
    di : in  bit_vector (07 downto 00);
    do : out bit_vector (07 downto 00)
    );
  end component;
--For each round counter
  component c4b
    port (
    cnt : out bit_vector (03 downto 00);
    clk : in  bit;
    rst : in  bit
    );
  end component;
--For all iteration in keyexpansion
  component c6b
    port (
    cnt : out bit_vector (05 downto 00);
    clk : in  bit;
    rst : in  bit
    );
  end component;
 
begin
 
sboxa : sbox
  port map (
    di => sai,
    do => sao
    );
sboxb : sbox
  port map (
    di => sbi,
    do => sbo
    );
sboxc : sbox
  port map (
    di => sci,
    do => sco
    );
sboxd : sbox
  port map (
    di => sdi,
    do => sdo
    );
ctr1  : c4b
  port map (
    cnt => cnt,
    clk => clk,
    rst => crst
    );
ctr2  : c6b
  port map (
    cnt => cnts,
    clk => clk,
    rst => rsts
    );
 
--Special cases for Nk=8
  mod4             <= not(cnt(3) or not(cnt(2)) or cnt(1) or cnt(0));
  Nk8s             <= mod4 and not(not(Nk(3)) or Nk(2) or Nk(1) or Nk(0));
 
--RotWord detection
  rot              <= not( (Nk(3) xor cnt(3)) or (Nk(2) xor cnt(2)) or
                           (Nk(1) xor cnt(1)) or (Nk(0) xor cnt(0))   );
 
  process (clk)
  begin
    if ((clk = '1') and clk'event) then
      ldi1 <= ld;
    end if;
  end process;
  ldrs             <= ld xor ldi1; -- reset signal from load
 
--Keyexpansion need 4*(Nr+1) clock to do all calculation with
--Nr = 10 when Nk = 4 (128 bit) this would generate 44(101100) 32bit keys
--Nr = 12 when Nk = 6 (192 bit) this would generate 52(110100) 32bit keys
--Nr = 14 when Nk = 8 (256 bit) this would generate 60(111100) 32bit keys
 
  vrst1 <= not( not(cnts(5)) or cnts(4) or not(cnts(3)) or not(cnts(2)) or cnts(1) or cnts(0));     -- 44(101100)
  vrst2 <= not( not(cnts(5)) or not(cnts(4)) or cnts(3) or not(cnts(2)) or cnts(1) or cnts(0));     -- 52(110100)
  vrst3 <= not( not(cnts(5)) or not(cnts(4)) or not(cnts(3)) or not(cnts(2)) or cnts(1) or cnts(0));-- 60(111100)
 
  with Nk(03 downto 00) select
  rstsc <= vrst1 when B"0100", -- Nk 4(0100)
	   vrst2 when B"0110", -- Nk 6(0110)
	   vrst3 when B"1000", -- Nk 8(1000)
	   vrst1 when  others; -- default
 
--Setting up counter inline with Nk periode.
--For each round
  crst             <= rst or rot or ldrs;
--For the state
  rsts             <= rst or (ldrs and ld) or rstsc;
 
  process (clk)
  begin
    if ((clk = '1') and clk'event) then
      if (rst = '1') then
        vld <= '0';
      elsif (((ldrs and ld) or (rstsc and vld)) = '1') then -- (ldrs and ld) is start signal (rstsc and vld) is end signal
        vld <= not(vld);
      end if;
    end if;
  end process;
 
  v <= vld; -- valid key expansion output signal
 
--Round constant calculation
--Rcon sequence: 01 02 04 08 10 20 40 80 1b 36
  Rcon(07 downto 00)<= Rcs (79 downto 72);
  process (clk)
  begin
    if ((clk = '1') and clk'event) then
      if (rst = '1') then -- default reset
        Rcs  <= Rc;
      elsif (rot = '1') then -- shift one byte
        Rcs (79 downto 08)<= Rcs (71 downto 00);
	Rcs (07 downto 00)<= (others => '0');
      end if;
    end if;
  end process;
 
  with Nk(03 downto 00) select
  wiNk <= int(127 downto  96) when B"0100", -- Nk 4(0100)
          int(191 downto 160) when B"0110", -- Nk 6(0110)
          int(255 downto 224) when B"1000", -- Nk 8(1000)
          int(127 downto  96) when  others; -- default
 
  process (clk)
  begin
    if ((clk = '1') and clk'event) then
      if (rst = '1') then
        int(255 downto 00) <= (others => '0');
      elsif (ld = '1') then
        int(255 downto 00) <= int(223 downto 00) & key(31 downto 00);
      else
        int(255 downto 00) <= int(223 downto 00) & (wiNk xor temp);
      end if;
    end if;
  end process;
 
  wi1( 31 downto 00) <= int( 31 downto 00); -- first fifo
 
  sai(07 downto 00)<= wi1(31 downto 24);    -- SubWord
  sbi(07 downto 00)<= wi1(23 downto 16);    -- SubWord
  sci(07 downto 00)<= wi1(15 downto 08);    -- SubWord
  sdi(07 downto 00)<= wi1(07 downto 00);    -- SubWord
 
  tmp <=  sao            & sbo & sco & sdo when Nk8s='1' else -- special cases for Nk 8
         (sbo xor Rcon ) & sco & sdo & sao;                   -- others do: RotWord xor Rcon
 
  temp <= tmp when (rot='1' or Nk8s='1') else wi1;
 
  w  ( 31 downto 00) <= int( 31 downto 00) when vld = '1' else (others => '0'); -- key expansion result
 
end phy;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.