好的家伙,对不起,如果这是一个已被问过的问题,因为我对VHDL逻辑设计有足够的新意,不知道如何定义一个特定的概念。
我要做的是在VHDL中实现AES-256算法以供FPGA使用。
我有一个名为:
的端口entity rijndael is port
(
input : in std_logic_vector(255 downto 0)
subkey: in std_logic_vector(255 downto 0)
output: out std_logic_vector(255 downto 0)
);
end rijndael;
如何在架构中为{1}} AES算法的input
进程指定array
的每个字节作为subBytes()
个字节值段?
答案 0 :(得分:2)
从标准中看,AES中的字节值被组织成列和行,您基本上需要和索引系统来标识数组子范围,这些子范围指定输入的哪些8位与哪个行和列相关联。
如果你需要循环(如在生成循环中,来到这个硬件上)你可以使用多维数组并从输入数组子范围中分配它们,其中你有行和列索引。你可以使输入数组成为一个8位的数组,紧跟FIPS-197:
您会发现FIPS中使用的符号系统与Rijndael提交的不同,您最好在任何可能在某些时候提供帮助的人使用通用参考系统。 FIPS似乎意味着你应该使用大端数组,而你已经将输入声明为小端。
我将展示一个分析,阐述和模拟的设计规范。 (不能保证它是正确的,已经很晚了,我有点饿了。)
library ieee;
use ieee.std_logic_1164.all;
entity State is
port (
input: in std_logic_vector (0 to 255);
output: out std_logic_vector (0 to 255)
);
end entity;
architecture foo of State is
subtype in0 is natural range 0 to 7;
subtype in1 is natural range 8 to 15;
subtype in2 is natural range 16 to 23;
subtype in3 is natural range 24 to 31;
subtype in4 is natural range 32 to 39;
subtype in5 is natural range 40 to 47;
subtype in6 is natural range 48 to 55;
subtype in7 is natural range 56 to 63;
subtype in8 is natural range 64 to 71;
subtype in9 is natural range 72 to 79;
subtype in10 is natural range 80 to 87;
subtype in11 is natural range 88 to 95;
subtype in12 is natural range 96 to 103;
subtype in13 is natural range 104 to 111;
subtype in14 is natural range 112 to 119;
subtype in15 is natural range 120 to 127;
subtype in16 is natural range 128 to 135;
subtype in17 is natural range 136 to 143;
subtype in18 is natural range 144 to 151;
subtype in19 is natural range 152 to 159;
subtype in20 is natural range 160 to 167;
subtype in21 is natural range 168 to 175;
subtype in22 is natural range 176 to 183;
subtype in23 is natural range 184 to 191;
subtype in24 is natural range 192 to 199;
subtype in25 is natural range 200 to 207;
subtype in26 is natural range 208 to 215;
subtype in27 is natural range 216 to 223;
subtype in28 is natural range 224 to 231;
subtype in29 is natural range 232 to 239;
subtype in30 is natural range 240 to 247;
subtype in31 is natural range 248 to 255;
type state_array is array -- (row, col) of 8 bits
(natural range 0 to 3, natural range 0 to 7)
of std_logic_vector(0 to 7);
signal S: state_array;
begin
S <= state_array'(
( input(in0), input(in4), input(in8), input(in12),
input(in16), input(in20), input(in24), input(in28) ),
( input(in1), input(in5), input(in9), input(in13),
input(in17), input(in21), input(in25), input(in29) ),
( input(in2), input(in6), input(in10), input(in14),
input(in18), input(in22), input(in26), input(in30) ),
( input(in3), input(in7), input(in11), input(in15),
input(in19), input(in23), input(in27), input(in31) )
);
output <= S(0,0) & S(1,0) & S(2,0) & S(3,0) & -- columns on side
S(0,1) & S(1,1) & S(2,1) & S(3,1) &
S(0,2) & S(1,2) & S(2,2) & S(3,2) &
S(0,3) & S(1,3) & S(2,3) & S(3,3) &
S(0,4) & S(1,4) & S(2,4) & S(3,4) &
S(0,5) & S(1,5) & S(2,5) & S(3,5) &
S(0,6) & S(1,6) & S(2,6) & S(3,6) &
S(0,7) & S(1,7) & S(2,7) & S(3,7) ;
end architecture;
这为您提供了字节索引,因此您可以使用生成语句并根据状态(显示S
)进行字节转换以进行转换。您当然可以直接省去输入切片的子类型声明和范围。
答案 1 :(得分:1)
以下是我在实施AES-128时的定义:
constant KEY_LENGTH: integer := 128;
constant BLOCK_LENGTH: integer := 128;
subtype key_type is std_logic_vector(KEY_LENGTH-1 downto 0);
type key_array_type is array (natural range<>) of key_type;
subtype word_type is std_logic_vector(31 downto 0);
subtype byte_type is std_logic_vector(7 downto 0);
type state_type is array (0 to 3, 0 to 3) of std_logic_vector(7 downto 0);
type state_array_type is array (natural range<>) of state_type;
type column_type is array (0 to 3) of std_logic_vector(7 downto 0);
type column_array_type is array (natural range<>) of column_type;
这是公共界面:
function encrypt(
plain_text: std_logic_vector(BLOCK_LENGTH-1 downto 0);
cypher_key: in key_type
) return std_logic_vector;
在这里你可以看到一些私人方法。请注意,主要处理方法接受一个对象'state_type'并返回另一个值,也是state_type:
function shift_rows(state_in: state_type) return state_type;
function mix_columns(state_in: state_type) return state_type;
function add_round_key(state: state_type; round_key: key_type) return state_type;
function mix_column(column_in: column_type) return column_type;
function expand_key(cypher_key: key_type) return column_array_type;
function round_key(expanded_key: column_array_type; round_number: integer) return key_type;
我发现声明一些函数可以转换为自定义类型和std_logic_vector是有用的:
function vector_from_state(state: state_type) return std_logic_vector;
function state_from_vector(vector: std_logic_vector(127 downto 0)) return state_type;
function vector_from_column(column: column_type) return std_logic_vector;
function state_from_columns(columns: column_array_type) return state_type;
function vector_from_columns(columns: column_array_type) return std_logic_vector;
function columns_from_state(state: state_type) return column_array_type;
如果有人发现它有用,我可以根据要求将整个代码上传到GitHub。
答案 2 :(得分:0)
一个字节是8位;所以,std_logic_vector(7 downto 0)
是正确的。 std_logic_vector
是std_logic
的数组 - 每个std_logic
可以代表一个数字位。