blob: 28e534617c0d4511f8d48955a7e11ac0fe944301 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// AES MixColumns for one single column of the state matrix
//
// For details, see Equations 4-7 of:
// Satoh et al., "A Compact Rijndael Hardware Architecture with S-Box Optimization"
module aes_mix_single_column (
input aes_pkg::ciph_op_e op_i,
input logic [3:0][7:0] data_i,
output logic [3:0][7:0] data_o
);
import aes_pkg::*;
logic [3:0][7:0] x;
logic [1:0][7:0] y;
logic [1:0][7:0] z;
logic [3:0][7:0] x_mul2;
logic [1:0][7:0] y_pre_mul4;
logic [7:0] y2, y2_pre_mul2;
logic [1:0][7:0] z_muxed;
// Drive x
assign x[0] = data_i[0] ^ data_i[3];
assign x[1] = data_i[3] ^ data_i[2];
assign x[2] = data_i[2] ^ data_i[1];
assign x[3] = data_i[1] ^ data_i[0];
// Mul2(x)
for (genvar i = 0; i < 4; i++) begin : gen_x_mul2
assign x_mul2[i] = aes_mul2(x[i]);
end
// Drive y_pre_mul4
assign y_pre_mul4[0] = data_i[3] ^ data_i[1];
assign y_pre_mul4[1] = data_i[2] ^ data_i[0];
// Mul4(y_pre_mul4)
for (genvar i = 0; i < 2; i++) begin : gen_mul4
assign y[i] = aes_mul4(y_pre_mul4[i]);
end
// Drive y2_pre_mul2
assign y2_pre_mul2 = y[0] ^ y[1];
// Mul2(y)
assign y2 = aes_mul2(y2_pre_mul2);
// Drive z
assign z[0] = y2 ^ y[0];
assign z[1] = y2 ^ y[1];
// Mux z
assign z_muxed[0] = (op_i == CIPH_FWD) ? 8'b0 :
(op_i == CIPH_INV) ? z[0] : 8'b0;
assign z_muxed[1] = (op_i == CIPH_FWD) ? 8'b0 :
(op_i == CIPH_INV) ? z[1] : 8'b0;
// Drive outputs
assign data_o[0] = data_i[1] ^ x_mul2[3] ^ x[1] ^ z_muxed[1];
assign data_o[1] = data_i[0] ^ x_mul2[2] ^ x[1] ^ z_muxed[0];
assign data_o[2] = data_i[3] ^ x_mul2[1] ^ x[3] ^ z_muxed[1];
assign data_o[3] = data_i[2] ^ x_mul2[0] ^ x[3] ^ z_muxed[0];
endmodule