This website uses cookies. By using this site, you consent to the use of cookies. For more information, please take a look at our Privacy Policy.
Home > FPGA Technical Tutorials > Design Recipes for FPGAs Using Verilog and VHDL > Secure Systems > Advanced Encryption Standard

TABLE OF CONTENTS

Xilinx FPGA FPGA Forum

Advanced Encryption Standard

FONT SIZE : AAA

In 1997, the U.S. National Institute of Standards and Technology (NIST) published a request for information regarding the creation of a new Advanced Encryption Standard (AES) for nonclassified government documents. The call also stipulated that the AES would specify an unclassified, publicly disclosed encryption algorithm(s), available royalty-free, worldwide.

In addition, the algorithm(s) must implement symmetric key cryptography as a block cipher and (at a minimum) support block sizes of 128 bits and key sizes of 128, 192, and 256 bits. After an open competition, the Rijndael algorithm was chosen as the winner and implemented as the AES standard. Rijndael allows key and block sizes to be 128, 192, or 256 bits. 

AES allows the same key sizes, but operates using a block size of 128 bits. The algorithm operates in a similar way to DES, with 10 rounds of confusion and diffusion operators (shuffling and mixing) blocks at a time. Each round has a separate key, generated from the overall key. The round structure is shown in Figure 10.7. 

The overall AES structure is given in Figure 10.8.

AES round structurepng

Figure 10.7 

AES round structure.

AES structurepng

Figure 10.8 

AES structure.

Each block consists of 128 bits, and these are divided into 16 8-bit bytes. Each of the operations acts upon these 8-bit bytes in a 4 × 4 matrix:

10.png

Note that each element (ai,j) is an 8-bit byte, viewed as elements of GF(28). The arithmetic operators take advantage of the Galois Field (GF) rules defined in the Rijndael algorithm; an example is that of addition that is implemented by XOR. 

Multiplication is more complicated, but each byte has the multiplicative inverse such that b.b = 00000001 (apart from 00000000, whose multiplicative inverse is 00000000). The model of the finite field GF(28) depends on the choice of an irreducible polynomial of degree 8, which for Rijndael is:

X8 + X4 + X3 + 1 (10.2)

Each of the round operations requires a specific mathematical exploration. Taking each in turn we can establish the requirements for each one. 

Taking the original matrix:

10.png

each element can be replaced byte-by-byte to generate a new matrix:

10.png

Byte substitution requires that for each input data block a(3, 3), we look up a table of substitutions and replace the bytes to produce a new matrix b(3, 3). The way it works is that for each input byte abcdefgh, we look up row abcd and column efgh and use the byte at that location in the output. 

The complete byte substitution table is defined as shown in Figure 10.9.

For example: If the input data byte was 7A, then this in binary terms is: 

0111 1010 

So the row required is 7 (0111) and the column required is A (1010). From this we can read off the resulting number from the table: 

218 = 1101 1010 = DA 

This is illustrated in the byte substitution table in Figure 10.9. 

We can see that this is a bit shuffling operation that is simply moving bytes around in a publicly defined manner that does not have anything to do with a key. 

Also note that the individual bits within the byte are not changed as such. This is a bytewise operation. The Shift Row function is essentially a set of cyclic shifts to the left with offsets of 0, 1, 2, 3, respectively.

13.png

AES byte substitution tablepng

Figure 10.9 

AES byte substitution table.

The Mix Columns function is a series of specific multiplications:

1.png

where 01 = 00000001, 02 = 00000010, 03 = 00000011. 

All multiplications are GF(28) and this transformation is invertible. 

The final operation in each round is to add the key using the following function:

2.png

The round keys are generated using the following method. The original key of 128 bits is represented as a 4 × 4 matrix of bytes (of 8 bits). This can be thought of as four columns W(0), W(1), W(2), W(3). Adjoin 40 columns W(4), . , W(43). The round key for round i consists of i columns. If i is a multiple of 4:

W(i) = W(i − 4) ⊕ T(W(i − 1)) (10.3)

where T is a transformation of a, b, c, d in column W(i − 1) using the following procedure: 

• Shift cyclically to get b, c, d, a. 

• Replace each byte with S-box entry using ByteSub, to get e, f, g, h. 

• Compute round constant r(i) = 00000010(i − 4)/4 in GF(28). 

• T(W(i − 1)) = (e ⊕ r(i), f , g, h) 

• If i is not a multiple of 4, W(i) = W(i − 4) ⊕ W(i − 1)

Implementing AES in VHDL 

We have two options for implementing block cipher operations in VHDL. We can use the structural approach (shown in the DES example previously in this chapter), or sometimes it makes sense to define a library of functions and use those to make much simpler models. 

In the example of AES, we can define a top level entity and architecture that has the bare minimum of structure and is completely defined using functions. This can be especially useful when working with behavioral synthesis software as this allows complete flexibility for architectural optimization.

1 library ieee;

2 use ieee.std_logic_1164.all; 3 entity AES is

4 port( 5 plaintext : in std_logic_vector(127 downto 0);

6 keytext : in std_logic_vector(127 downto 0);

7 encrypt : in std_logic;

8 go : in std_logic;

9 ciphertext : out std_logic_vector(127 downto 0);

10 done : out std_logic := ’0’

11 );

12 end;

13

14 use work.aes_functions.all;

15 architecture behavior of AES is

16 begin

17 process

18 begin

19 wait until go = ’1’;

20 done <= ’0’;

21 ciphertext <= aes_core(plaintext, keytext, encrypt);

22 done <= ’1’;

23 end process;

24 end;

In this example, we have the plaintext and keytext inputs defined as 128-bit-wide vectors and the ciphertext output is also defined as 128 bits wide. The go flag initiates the encryption and the done flag shows when this has been completed. 

Notice that we have a work library defined called aes_functions which encapsulates all the relevant functions for the AES algorithm. The set of functions is defined in a package (aes_functions) and the VHDL is given:

1 library ieee;

2 use ieee.std_logic_1164.all; 3 use ieee.numeric_std.all; 4 package aes_functions is

56 constant nr : integer := 10;

7 constant nb : integer := 4;

8 constant nk : integer := 4;

9

10 subtype vec1408 is std_logic_vector(1407 downto 0);

11 subtype vec128 is std_logic_vector(127 downto 0);

12 subtype vec64 is std_logic_vector(63 downto 0);

13 subtype vec32 is std_logic_vector(31 downto 0);

14 subtype vec16 is std_logic_vector(15 downto 0);

15 subtype vec8 is std_logic_vector(7 downto 0);

16

17 subtype int9 is integer range 0 to 9;

18

19 function input_output (input : vec128) return vec128;

20 function sbox (pt : vec8) return vec8;

21 function subbytes (plaintext : vec128) return vec128;

22 function shiftrows (plaintext : vec128) return vec128;

23 function ffmul(pt : vec8; mul : vec8) return vec8;

24 function mixcl( l0 : vec8; l1 : vec8; l2 : vec8; l3 : vec8) return vec8;

25 function mixcolumns(pt : vec128) return vec128;

26 function rcon (input : int9) return vec8;

27 function aes_keyexpansion(key : vec128) return vec1408;

28 function aes_core (signal plaintext : vec128; signal keytext : vec128;

signal encrypt : std_logic) return vec128;

29

30

31

32 end;

33

34 library ieee;

35 use ieee.std_logic_1164.all;

36 use ieee.numeric_std.all;

37 package body aes_functions is

38

39 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

40 function subbytes (plaintext : vec128)

41 −− moods inline

42 return vec128 is

43 variable ciphertext : vec128;

44 begin

45 ciphertext := sbox(plaintext(127 downto 120)) &

46 sbox(plaintext(119 downto 112)) &

47 sbox(plaintext(111 downto 104)) &

48 sbox(plaintext(103 downto 96)) &

49 sbox(plaintext(95 downto 88)) &

50 sbox(plaintext(87 downto 80)) &

51 sbox(plaintext(79 downto 72)) &

52 sbox(plaintext(71 downto 64)) &

53 sbox(plaintext(63 downto 56)) &

54 sbox(plaintext(55 downto 48)) &

55 sbox(plaintext(47 downto 40)) &

56 sbox(plaintext(39 downto 32)) &

57 sbox(plaintext(31 downto 24)) &

58 sbox(plaintext(23 downto 16)) &

59 sbox(plaintext(15 downto 8)) &

60 sbox(plaintext(7 downto 0));

61 return ciphertext;

62 end;

63

64 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

65 function shiftrows (plaintext : vec128)

66 −− moods inline

67 return vec128 is

68 variable ciphertext : vec128;

69 begin

70 −−line 0 (the first): no shift

71 ciphertext := plaintext(31 downto 24) &

72 plaintext(55 downto 48) &

73 plaintext(79 downto 72) &

74 plaintext(103 downto 96) &

75 plaintext(127 downto 120) &

76 plaintext(23 downto 16) &

77 plaintext(47 downto 40) &

78 plaintext(71 downto 64) &

79 plaintext(95 downto 88) &

80 plaintext(119 downto 112) &

81 plaintext(15 downto 8) &

82 plaintext(39 downto 32) &

83 plaintext(63 downto 56) &

84 plaintext(87 downto 80) &

85 plaintext(111 downto 104) &

86 plaintext(7 downto 0);

87 return ciphertext;

88 end;

89

90 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

91

92 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

93 function tablelog (input : vec8)

94 −− moods inline

95 return vec8 is

96 variable output : vec8;

97 type table256 is array(0 to 255) of vec8;

98 constant pt_256 : table256 := (

99 −− moods rom

100 x"00", x"00", x"19", x"01", x"32",

101 x"02", x"1a", x"c6", x"4b",

102 x"c7", x"1b", x"68", x"33",

103 x"ee", x"df", x"03", x"64",

104

105 x"04", x"e0", x"0e", x"34",

106 x"8d", x"81", x"ef", x"4c",

107 x"71", x"08", x"c8", x"f8",

108 x"69", x"1c", x"c1", x"7d",

109

110 x"c2", x"1d", x"b5", x"f9",

111 x"b9", x"27", x"6a", x"4d",

112 x"e4", x"a6", x"72", x"9a",

113 x"c9", x"09", x"78", x"65",

114

115 x"2f", x"8a", x"05", x"21",

116 x"0f", x"e1", x"24", x"12",

117 x"f0", x"82", x"45", x"35",

118 x"93", x"da", x"8e", x"96",

119

120 x"8f", x"db", x"bd", x"36",

121 x"d0", x"ce", x"94", x"13",

122 x"5c", x"d2", x"f1", x"40",

123 x"46", x"83", x"38", x"66",

124 x"dd", x"fd", x"30", x"bf",

125 x"06", x"8b", x"62", x"b3",

126 x"25", x"e2", x"98", x"22",

127 x"88", x"91", x"10", x"7e",

128

129 x"6e", x"48", x"c3", x"a3",

130 x"b6", x"1e", x"42", x"3a",

131 x"6b", x"28", x"54", x"fa",

132 x"85", x"3d", x"ba", x"2b",

133

134 x"79", x"0a", x"15", x"9b",

135 x"9f", x"5e", x"ca", x"4e",

136 x"d4", x"ac", x"e5", x"f3",

137 x"73", x"a7", x"57", x"af",

138

139 x"58", x"a8", x"50", x"f4",

140 x"ea", x"d6", x"74", x"4f",

141 x"ae", x"e9", x"d5", x"e7",

142 x"e6", x"ad", x"e8", x"2c",

143

144 x"d7", x"75", x"7a", x"eb",

145 x"16", x"0b", x"f5", x"59",

146 x"cb", x"5f", x"b0", x"9c",

147 x"a9", x"51", x"a0", x"7f",

148

149 x"0c", x"f6", x"6f", x"17",

150 x"c4", x"49", x"ec", x"d8",

151 x"43", x"1f", x"2d", x"a4",

152 x"76", x"7b", x"b7", x"cc",

153

154 x"bb", x"3e", x"5a", x"fb",

155 x"60", x"b1", x"86", x"3b",

156 x"52", x"a1", x"6c", x"aa",

157 x"55", x"29", x"9d", x"97",

158

159 x"b2", x"87", x"90", x"61",

160 x"be", x"dc", x"fc", x"bc",

161 x"95", x"cf", x"cd", x"37",

162 x"3f", x"5b", x"d1", x"53",

163

164 x"39", x"84", x"3c", x"41",

165 x"a2", x"6d", x"47", x"14",

166 x"2a", x"9e", x"5d", x"56",

167 x"f2", x"d3", x"ab", x"44",

168

169 x"11", x"92", x"d9", x"23",

170 x"20", x"2e", x"89", x"b4",

171 x"7c", x"b8", x"26", x"77",

172 x"99", x"e3", x"a5", x"67",

173

174 x"4a", x"ed", x"de", x"c5",

175 x"31", x"fe", x"18", x"0d",

176 x"63", x"8c", x"80", x"c0",

177 x"f7", x"70", x"07" );

178 begin

179 output := pt_256(to_integer(unsigned(input)));

180 return output;

181 end;

182

183 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

184 function tableexp (input : vec8)

185 −− moods inline

186 return vec8 is

187 variable output : vec8;

188 type table256 is array(0 to 255) of vec8;

189 constant pt_256 : table256 := (

190 −− moods rom

191 x"01", x"03", x"05", x"0f",

192 x"11", x"33", x"55", x"ff",

193 x"1a", x"2e", x"72", x"96",

194 x"a1", x"f8", x"13", x"35",

195

196 x"5f", x"e1", x"38", x"48",

197 x"d8", x"73", x"95", x"a4",

198 x"f7", x"02", x"06", x"0a",

199 x"1e", x"22", x"66", x"aa",

200

201 x"e5", x"34", x"5c", x"e4",

202 x"37", x"59", x"eb", x"26",

203 x"6a", x"be", x"d9", x"70",

204 x"90", x"ab", x"e6", x"31",

205

206 x"53", x"f5", x"04", x"0c",

207 x"14", x"3c", x"44", x"cc",

208 x"4f", x"d1", x"68", x"b8",

209 x"d3", x"6e", x"b2", x"cd",

210

211 x"4c", x"d4", x"67", x"a9",

212 x"e0", x"3b", x"4d", x"d7",

213 x"62", x"a6", x"f1", x"08",

214 x"18", x"28", x"78", x"88",

215

216 x"83", x"9e", x"b9", x"d0",

217 x"6b", x"bd", x"dc", x"7f",

218 x"81", x"98", x"b3", x"ce",

219 x"49", x"db", x"76", x"9a",

220

221 x"b5", x"c4", x"57", x"f9",

222 x"10", x"30", x"50", x"f0",

223 x"0b", x"1d", x"27", x"69",

224 x"bb", x"d6", x"61", x"a3",

225

226 x"fe", x"19", x"2b", x"7d",

227 x"87", x"92", x"ad", x"ec",

228 x"2f", x"71", x"93", x"ae",

229 x"e9", x"20", x"60", x"a0",

230

231 x"fb", x"16", x"3a", x"4e",

232 x"d2", x"6d", x"b7", x"c2",

233 x"5d", x"e7", x"32", x"56",

234 x"fa", x"15", x"3f", x"41",

235

236 x"c3", x"5e", x"e2", x"3d",

237 x"47", x"c9", x"40", x"c0",

238 x"5b", x"ed", x"2c", x"74",

239 x"9c", x"bf", x"da", x"75",

Secure Systems 159

240

241 x"9f", x"ba", x"d5", x"64",

242 x"ac", x"ef", x"2a", x"7e",

243 x"82", x"9d", x"bc", x"df",

244 x"7a", x"8e", x"89", x"80",

245

246 x"9b", x"b6", x"c1", x"58",

247 x"e8", x"23", x"65", x"af",

248 x"ea", x"25", x"6f", x"b1",

249 x"c8", x"43", x"c5", x"54",

250

251 x"fc", x"1f", x"21", x"63",

252 x"a5", x"f4", x"07", x"09",

253 x"1b", x"2d", x"77", x"99",

254 x"b0", x"cb", x"46", x"ca",

255

256 x"45", x"cf", x"4a", x"de",

257 x"79", x"8b", x"86", x"91",

258 x"a8", x"e3", x"3e", x"42",

259 x"c6", x"51", x"f3", x"0e",

260

261 x"12", x"36", x"5a", x"ee",

262 x"29", x"7b", x"8d", x"8c",

263 x"8f", x"8a", x"85", x"94",

264 x"a7", x"f2", x"0d", x"17",

265

266 x"39", x"4b", x"dd", x"7c",

267 x"84", x"97", x"a2", x"fd",

268 x"1c", x"24", x"6c", x"b4",

269 x"c7", x"52", x"f6", x"01");

270 begin

271 output := pt_256(to_integer(unsigned(input)));

272 return output;

273 end;

274

275 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

276 function ffmul(pt : vec8; mul : vec8)

277 −− moods inline

278 return vec8 is

279 −−variable res : vec8;

280 variable tablogpt : vec8;

281 variable tablogmul : vec8;

282 variable tablogpt8 : unsigned(8 downto 0);

283 variable tablogmul8 : unsigned(8 downto 0);

284 variable carrie : std_logic_vector(8 downto 0);

285 variable power : vec8;

286 variable result: vec8;

287 begin

288 tablogpt := tablelog(pt);

289 tablogmul := tablelog(mul);

290

291 tablogpt8 := unsigned("0" & tablogpt);

292 tablogmul8 := unsigned("0" & tablogmul);

293

294 carrie := std_logic_vector(tablogmul8 + tablogpt8);

160 Chapter 10

295

296 if pt = x"00" or mul = x"00" then

297 result := x"00";

298 elsif carrie(8) = ’1’ or carrie(7 downto 0) = x"ff" then −− mod 255

299 power := std_logic_vector(unsigned(carrie(7 downto 0)) + 1); −− power =

power − 255

300 result := tableexp(power);

301 else

302 power := carrie(7 downto 0);

303 result := tableexp(power);

304 end if;

305 return result;

306 end;

307

308 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

309 function mixcl( l0 : vec8; l1 : vec8; l2 : vec8; l3 : vec8)

310 −− moods inline

311 return vec8 is

312 variable ct : vec8;

313 begin

314

315 ct := ffmul(l0, x"02") xor ffmul(l1, x"01") xor ffmul(l2, x"01") xor ffmul

(l3, x"03");

316

317 return ct;

318 end;

319

320 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

321 function mixcolumns(pt : vec128)

322 −− moods inline

323 return vec128 is

324 variable ct : vec128;

325 begin

326

327 ct := mixcl(pt(127 downto 120), pt(119 downto 112), pt(111 downto 104), pt

(103 downto 96)) &

328 mixcl(pt(119 downto 112), pt(111 downto 104), pt(103 downto 96), pt

(127 downto 120)) &

329 mixcl(pt(111 downto 104), pt(103 downto 96), pt(127 downto 120), pt

(119 downto 112)) &

330 mixcl(pt(103 downto 96), pt(127 downto 120), pt(119 downto 112), pt

(111 downto 104)) &

331

332 mixcl(pt(95 downto 88), pt(87 downto 80), pt(79 downto 72), pt(71

downto 64)) &

333 mixcl(pt(87 downto 80), pt(79 downto 72), pt(71 downto 64), pt(95

downto 88)) &

334 mixcl(pt(79 downto 72), pt(71 downto 64), pt(95 downto 88), pt(87

downto 80)) &

335 mixcl(pt(71 downto 64), pt(95 downto 88), pt(87 downto 80), pt(79

downto 72)) &

336

337 mixcl(pt(63 downto 56), pt(55 downto 48), pt(47 downto 40), pt(39

downto 32)) &

338 mixcl(pt(55 downto 48), pt(47 downto 40), pt(39 downto 32), pt(63

downto 56)) &

339 mixcl(pt(47 downto 40), pt(39 downto 32), pt(63 downto 56), pt(55

downto 48)) &

340 mixcl(pt(39 downto 32), pt(63 downto 56), pt(55 downto 48), pt(47

downto 40)) &

341

342 mixcl(pt(31 downto 24), pt(23 downto 16), pt(15 downto 8), pt(7 downto

0)) &

343 mixcl(pt(23 downto 16), pt(15 downto 8), pt(7 downto 0), pt(31 downto

24)) &

344 mixcl(pt(15 downto 8), pt(7 downto 0), pt(31 downto 24), pt(23 downto

16)) &

345 mixcl(pt(7 downto 0), pt(31 downto 24), pt(23 downto 16), pt(15 downto

8));

346

347 return ct;

348 end;

349

350 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

351 function input_output (input : vec128)

352 −− moods inline

353 return vec128 is

354 variable output : vec128;

355 function flip(input:vec32) return vec32 is

356 −− moods inline

357 begin

358 return input(7 downto 0) & input(15 downto 8)

359 & input(23 downto 16) & input(31 downto 24);

360 end;

361 begin

362 return flip(input(127 downto 96)) & flip(input(95 downto 64))

363 & flip(input(63 downto 32)) & flip(input(31 downto 0));

364 end;

365

366 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

367 function aes_keyexpansion(key : vec128)

368 −− moods inline

369 return vec1408 is

370 variable iok : vec128;

371 variable er0,er1,er2,er3,er4,er5,er6,er7,er8,er9:vec128;

372 −−variable zero: vec128;

373 −−variable expandedkeys: vec1408;

374

375 function exp_round(input : vec128; round: int9) return vec128 is

376 −− moods inline

377 variable r1,r2,r3,r4,r5: vec32;

378 begin

379 r1 := sbox(input(7 downto 0)) &

380 sbox(input(31 downto 24)) &

381 sbox(input(23 downto 16)) &

382 (sbox(input(15 downto 8)) xor rcon(round));

383

384 r2 := input(127 downto 96) xor r1;

385 r3 := input(95 downto 64) xor r2;

pter 10

386 r4 := input(63 downto 32) xor r3;

387 r5 := input(31 downto 0) xor r4;

388 return r2 & r3 & r4 & r5;

389 end;

390

391 begin

392 −− first round

393 iok := input_output(key);

394 −− other rounds

395 er9 := exp_round(iok,9);

396 er8 := exp_round(er9,8);

397 er7 := exp_round(er8,7);

398 er6 := exp_round(er7,6);

399 er5 := exp_round(er6,5);

400 er4 := exp_round(er5,4);

401 er3 := exp_round(er4,3);

402 er2 := exp_round(er3,2);

403 er1 := exp_round(er2,1);

404 er0 := exp_round(er1,0);

405

406 return (iok & er9 & er8 & er7 & er6 & er5 & er4 & er3 & er2 & er1 & er0);

407 end;

408

409 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

410

411 function aes_core (signal plaintext : vec128; signal keytext : vec128;

signal encrypt : std_logic)

412 −− moods inline

413 return vec128 is

414 variable rk0 : vec128;

415 variable ciphertext, expkey : vec128;

416 variable ct1, ct2,ct3,ct4,ct5,ct6,ct7,ct8: vec128;

417 variable expandedkeys : vec1408;

418 begin

419 −− expanded key schedule

420 expandedkeys := aes_keyexpansion(keytext);

421

422 −− round 0

423 ct1 := input_output(plaintext) xor expandedkeys(1407 downto 1280);

424

425 −− round 1 to nr−1

426 −−for i in 1 to nr−1 loop

427 for i in 1 to 9 loop

428 ct2 := subbytes(ct1);

429 ct3 := shiftrows(ct2);

430 ct4 := mixcolumns(ct3);

431 case(i) is

432 when 1 => expkey := expandedkeys(1279 downto 1152);

433 when 2 => expkey := expandedkeys(1151 downto 1024);

434 when 3 => expkey := expandedkeys(1023 downto 896);

435 when 4 => expkey := expandedkeys(895 downto 768);

436 when 5 => expkey := expandedkeys(767 downto 640);

437 when 6 => expkey := expandedkeys(639 downto 512);

438 when 7 => expkey := expandedkeys(511 downto 384);

439 when 8 => expkey := expandedkeys(383 downto 256);

63

440 when 9 => expkey := expandedkeys(255 downto 128);

441 when others => null;

442 end case;

443 ct1 := ct4 xor expkey;

444 end loop;

445

446 −− final round nr=10

447 ct5 := subbytes(ct1);

448 ct6 := shiftrows(ct5);

449 ct7 := ct6 xor expandedkeys(1407−128∗nr downto 1280−128∗nr);

450

451 ciphertext := input_output(ct7);

452

453 return ciphertext;

454 end;

455

456

457

458 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

459 function rcon (input : int9)

460 −− moods inline

461 return vec8 is

462 type rcont_t is array(0 to 9) of vec8;

463 constant table_rcon: rcont_t := (

464 −− moods rom

465 x"36", x"1b", x"80", x"40", x"20", x"10", x"08", x"04", x"02", x"01");

466 begin

467 return table_rcon(input);

468 end;

469

470 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

471 function sbox (pt : vec8)

472 −− moods inline

473 return vec8 is

474 variable ct : vec8;

475 type table256 is array(0 to 255) of vec8;

476 constant pt_256 : table256 := (

477 −− moods rom

478 x"63", x"7c", x"77", x"7b", x"f2", x"6b", x"6f", x"c5",

479 x"30", x"01", x"67", x"2b", x"fe", x"d7", x"ab", x"76",

480 x"ca", x"82", x"c9", x"7d", x"fa", x"59", x"47", x"f0",

481 x"ad", x"d4", x"a2", x"af", x"9c", x"a4", x"72", x"c0",

482 x"b7", x"fd", x"93", x"26", x"36", x"3f", x"f7", x"cc",

483 x"34", x"a5", x"e5", x"f1", x"71", x"d8", x"31", x"15",

484 x"04", x"c7", x"23", x"c3", x"18", x"96", x"05", x"9a",

485 x"07", x"12", x"80", x"e2", x"eb", x"27", x"b2", x"75",

486 x"09", x"83", x"2c", x"1a", x"1b", x"6e", x"5a", x"a0",

487 x"52", x"3b", x"d6", x"b3", x"29", x"e3", x"2f", x"84",

488 x"53", x"d1", x"00", x"ed", x"20", x"fc", x"b1", x"5b",

489 x"6a", x"cb", x"be", x"39", x"4a", x"4c", x"58", x"cf",

490 x"d0", x"ef", x"aa", x"fb", x"43", x"4d", x"33", x"85",

491 x"45", x"f9", x"02", x"7f", x"50", x"3c", x"9f", x"a8",

492 x"51", x"a3", x"40", x"8f", x"92", x"9d", x"38", x"f5",

493 x"bc", x"b6", x"da", x"21", x"10", x"ff", x"f3", x"d2",

494 x"cd", x"0c", x"13", x"ec", x"5f", x"97", x"44", x"17",

495 x"c4", x"a7", x"7e", x"3d", x"64", x"5d", x"19", x"73",

496 x"60", x"81", x"4f", x"dc", x"22", x"2a", x"90", x"88",

497 x"46", x"ee", x"b8", x"14", x"de", x"5e", x"0b", x"db",

498 x"e0", x"32", x"3a", x"0a", x"49", x"06", x"24", x"5c",

499 x"c2", x"d3", x"ac", x"62", x"91", x"95", x"e4", x"79",

500 x"e7", x"c8", x"37", x"6d", x"8d", x"d5", x"4e", x"a9",

501 x"6c", x"56", x"f4", x"ea", x"65", x"7a", x"ae", x"08",

502 x"ba", x"78", x"25", x"2e", x"1c", x"a6", x"b4", x"c6",

503 x"e8", x"dd", x"74", x"1f", x"4b", x"bd", x"8b", x"8a",

504 x"70", x"3e", x"b5", x"66", x"48", x"03", x"f6", x"0e",

505 x"61", x"35", x"57", x"b9", x"86", x"c1", x"1d", x"9e",

506 x"e1", x"f8", x"98", x"11", x"69", x"d9", x"8e", x"94",

507 x"9b", x"1e", x"87", x"e9", x"ce", x"55", x"28", x"df",

508 x"8c", x"a1", x"89", x"0d", x"bf", x"e6", x"42", x"68",

509 x"41", x"99", x"2d", x"0f", x"b0", x"54", x"bb", x"16");

510 begin

511 ct := pt_256(to_integer(unsigned(pt)));

512 return ct;

513 end;

514

515 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

516 end;

After the functions and top level entity have been defined, we can implement a test bench that applies a set of test data to the inputs and verifies that the correct output has been obtained. Notice that we use the assertion technique to identify correct operation.

1 library ieee;

2 use ieee.std_logic_1164.all; 3 entity testAES is

4 end; 567 library ieee;

8 use ieee.std_logic_1164.all; 9 use work.aes_functions.all;

10 architecture behavior of testAES is

11

12 component aes

13 port(

14 plaintext : in std_logic_vector(127 downto 0);

15 keytext : in std_logic_vector(127 downto 0);

16 encrypt : in std_logic;

17 go : in std_logic;

18 ciphertext : out std_logic_vector(127 downto 0);

19 done : out std_logic

20 );

21 end component;

22

23 for all : aes use entity work.aes;

24

25 signal plaintext : std_logic_vector(127 downto 0);

26 signal keytext : std_logic_vector(127 downto 0);

27 signal encrypt : std_logic;

28 signal go : std_logic := ’0’;

29 signal ciphertext : std_logic_vector(127 downto 0);

30 signal done : std_logic;

31 signal ok : std_logic := ’0’;

32 begin

33 plaintext <= X”00000000000000000000000000000000”, X”3243

f6a8885a308d313198a2e0370734” after 50 ns ;

34 keytext <= X”00000000000000000000000000000000”, X”2

b7e151628aed2a6abf7158809cf4f3c” after 100 ns;

35 process (ciphertext)

36 variable ct : std_logic_vector(127 downto 0) := X”3925841

d02dc09fbdc118597196a0b32”;

37 begin

38 assert ct = ciphertext

39 report ”Test vectors do not match”

40 severity note;

41 assert not (ct = ciphertext)

42 report ”Test vectors Matched”

43 severity note;

44 end process;

45

46

47 process

48 begin

49 go <= not go after 20 ns;

50 end process;

51

52 DUT : aes port map (plaintext, keytext, encrypt, go, ciphertext, done);

53 end;


  • XC5VLX110-2FFG1760C

    Manufacturer:Xilinx

  • FPGA Virtex-5 LX Family 110592 Cells 65nm Technology 1V 1760-Pin FCBGA
  • Product Categories: FPGAs (Field Programmable Gate Array)

    Lifecycle:Active Active

    RoHS:

  • XC5VLX110-3FFG1760C

    Manufacturer:Xilinx

  • FPGA Virtex-5 LX Family 110592 Cells 65nm Technology 1V 1760-Pin FCBGA
  • Product Categories: FPGAs (Field Programmable Gate Array)

    Lifecycle:Active Active

    RoHS:

  • XC2V2000-5BFG957I

    Manufacturer:Xilinx

  • FPGA Virtex-II Family 2M Gates 24192 Cells 750MHz 0.15um Technology 1.5V 957-Pin FCBGA
  • Product Categories: FPGAs (Field Programmable Gate Array)

    Lifecycle:Obsolete -

    RoHS:

  • XC2V2000-5FFG896I

    Manufacturer:Xilinx

  • FPGA Virtex-II Family 2M Gates 24192 Cells 750MHz 0.15um Technology 1.5V 896-Pin FCBGA
  • Product Categories: FPGAs (Field Programmable Gate Array)

    Lifecycle:Obsolete -

    RoHS:

  • XC5VLX110T-1FF1136I

    Manufacturer:Xilinx

  • FPGA Virtex-5 LXT Family 110592 Cells 65nm Technology 1V 1136-Pin FCBGA
  • Product Categories: FPGAs

    Lifecycle:Active Active

    RoHS: No RoHS

Need Help?

Support

If you have any questions about the product and related issues, Please contact us.