hw/ip/aes/rtl/aes_mix_single_column.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4: //
5: // AES MixColumns for one single column of the state matrix
6: //
7: // For details, see Equations 4-7 of:
8: // Satoh et al., "A Compact Rijndael Hardware Architecture with S-Box Optimization"
9:
10: module aes_mix_single_column (
11: input aes_pkg::mode_e mode_i,
12: input logic [3:0][7:0] data_i,
13: output logic [3:0][7:0] data_o
14: );
15:
16: import aes_pkg::*;
17:
18: logic [3:0][7:0] x;
19: logic [1:0][7:0] y;
20: logic [1:0][7:0] z;
21:
22: logic [3:0][7:0] x_mul2;
23: logic [1:0][7:0] y_pre_mul4;
24: logic [7:0] y2, y2_pre_mul2;
25:
26: logic [1:0][7:0] z_muxed;
27:
28: // Drive x
29: assign x[0] = data_i[0] ^ data_i[3];
30: assign x[1] = data_i[3] ^ data_i[2];
31: assign x[2] = data_i[2] ^ data_i[1];
32: assign x[3] = data_i[1] ^ data_i[0];
33:
34: // Mul2(x)
35: for (genvar i = 0; i < 4; i++) begin : gen_x_mul2
36: assign x_mul2[i] = aes_mul2(x[i]);
37: end
38:
39: // Drive y_pre_mul4
40: assign y_pre_mul4[0] = data_i[3] ^ data_i[1];
41: assign y_pre_mul4[1] = data_i[2] ^ data_i[0];
42:
43: // Mul4(y_pre_mul4)
44: for (genvar i = 0; i < 2; i++) begin : gen_mul4
45: assign y[i] = aes_mul4(y_pre_mul4[i]);
46: end
47:
48: // Drive y2_pre_mul2
49: assign y2_pre_mul2 = y[0] ^ y[1];
50:
51: // Mul2(y)
52: assign y2 = aes_mul2(y2_pre_mul2);
53:
54: // Drive z
55: assign z[0] = y2 ^ y[0];
56: assign z[1] = y2 ^ y[1];
57:
58: // Mux z
59: assign z_muxed[0] = (mode_i == AES_ENC) ? 8'b0 : z[0];
60: assign z_muxed[1] = (mode_i == AES_ENC) ? 8'b0 : z[1];
61:
62: // Drive outputs
63: assign data_o[0] = data_i[1] ^ x_mul2[3] ^ x[1] ^ z_muxed[1];
64: assign data_o[1] = data_i[0] ^ x_mul2[2] ^ x[1] ^ z_muxed[0];
65: assign data_o[2] = data_i[3] ^ x_mul2[1] ^ x[3] ^ z_muxed[1];
66: assign data_o[3] = data_i[2] ^ x_mul2[0] ^ x[3] ^ z_muxed[0];
67:
68: endmodule
69: