seperate aes package

This commit is contained in:
munailwaqar 2025-03-03 14:22:08 +05:00 committed by Munail Waqar
parent 0a541c578e
commit 9a4bd5f1d4
5 changed files with 213 additions and 203 deletions

View file

@ -71,6 +71,7 @@ ${CVA6_REPO_DIR}/core/include/wt_cache_pkg.sv
${CVA6_REPO_DIR}/core/include/std_cache_pkg.sv
${CVA6_REPO_DIR}/core/include/instr_tracer_pkg.sv
${CVA6_REPO_DIR}/core/include/build_config_pkg.sv
${CVA6_REPO_DIR}/core/include/aes_pkg.sv
//CVXIF
${CVA6_REPO_DIR}/core/cvxif_compressed_if_driver.sv
@ -106,7 +107,7 @@ ${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/delta_counter.sv
${CVA6_REPO_DIR}/core/cva6.sv
${CVA6_REPO_DIR}/core/cva6_rvfi_probes.sv
${CVA6_REPO_DIR}/core/alu.sv
${CVA6_REPO_DIR}/core/aes_fu.sv
${CVA6_REPO_DIR}/core/aes.sv
// Note: depends on fpnew_pkg, above
${CVA6_REPO_DIR}/core/fpu_wrap.sv
${CVA6_REPO_DIR}/core/branch_unit.sv

View file

@ -1,5 +1,6 @@
module aes_fu
module aes
import ariane_pkg::*;
import aes_pkg::*;
#(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter type fu_data_t = logic

View file

@ -734,7 +734,7 @@ module ex_stage
// ----------------
generate
if (CVA6Cfg.ZKN) begin : aes_gen
aes_fu #(
aes #(
.CVA6Cfg (CVA6Cfg),
.fu_data_t(fu_data_t)
) aes_fu_i (

208
core/include/aes_pkg.sv Normal file
View file

@ -0,0 +1,208 @@
/// This package contains `functions` for AES instructions used in Scalar Cryptography (ZKN).
package aes_pkg;
// ----------------------
// AES functions
// ----------------------
// AES MixColumns Forward
function [31:0] aes_mixcolumn_fwd(input [31:0] x);
begin
aes_mixcolumn_fwd = {
(((x[7:0] << 1) ^ ((x[7]) ? 8'h1B : 8'h00)) ^ x[7:0]) ^ x[15:8] ^ x[23:16] ^ ((x[31:24] << 1) ^ ((x[31]) ? 8'h1B : 8'h00)),
x[7:0] ^ x[15:8] ^ ((x[23:16] << 1) ^ ((x[23]) ? 8'h1B : 8'h00)) ^ (((x[31:24] << 1) ^ ((x[31]) ? 8'h1B : 8'h00)) ^ x[31:24]),
x[7:0] ^ ((x[15:8] << 1) ^ ((x[15]) ? 8'h1B : 8'h00)) ^ (((x[23:16] << 1) ^ ((x[23]) ? 8'h1B : 8'h00)) ^ x[23:16]) ^ x[31:24],
((x[7:0] << 1) ^ ((x[7]) ? 8'h1B : 8'h00)) ^ (((x[15:8] << 1) ^ ((x[15]) ? 8'h1B : 8'h00)) ^ x[15:8]) ^ x[23:16] ^ x[31:24]
};
end
endfunction
// AES subword Forward
function [31:0] aes_subword_fwd(input [31:0] word);
aes_subword_fwd = {
aes_sbox_fwd(word[31:24]),
aes_sbox_fwd(word[23:16]),
aes_sbox_fwd(word[15:8]),
aes_sbox_fwd(word[7:0])
};
endfunction
// AES Round Constant
function [31:0] aes_decode_rcon(input [3:0] r);
case (r)
4'h0: aes_decode_rcon = 32'h00000001;
4'h1: aes_decode_rcon = 32'h00000002;
4'h2: aes_decode_rcon = 32'h00000004;
4'h3: aes_decode_rcon = 32'h00000008;
4'h4: aes_decode_rcon = 32'h00000010;
4'h5: aes_decode_rcon = 32'h00000020;
4'h6: aes_decode_rcon = 32'h00000040;
4'h7: aes_decode_rcon = 32'h00000080;
4'h8: aes_decode_rcon = 32'h0000001b;
4'h9: aes_decode_rcon = 32'h00000036;
4'hA: aes_decode_rcon = 32'h00000000;
4'hB: aes_decode_rcon = 32'h00000000;
4'hC: aes_decode_rcon = 32'h00000000;
4'hD: aes_decode_rcon = 32'h00000000;
4'hE: aes_decode_rcon = 32'h00000000;
4'hF: aes_decode_rcon = 32'h00000000;
default: aes_decode_rcon = 32'h00000000;
endcase
endfunction
// AES MixColumns Inverse
function logic [31:0] aes_mixcolumn_inv(input logic [31:0] x);
aes_mixcolumn_inv = {
(gfmul(x[7:0], 4'hB) ^ gfmul(x[15:8], 4'hD) ^ gfmul(x[23:16], 4'h9) ^ gfmul(x[31:24], 4'hE)),
(gfmul(x[7:0], 4'hD) ^ gfmul(x[15:8], 4'h9) ^ gfmul(x[23:16], 4'hE) ^ gfmul(x[31:24], 4'hB)),
(gfmul(x[7:0], 4'h9) ^ gfmul(x[15:8], 4'hE) ^ gfmul(x[23:16], 4'hB) ^ gfmul(x[31:24], 4'hD)),
(gfmul(x[7:0], 4'hE) ^ gfmul(x[15:8], 4'hB) ^ gfmul(x[23:16], 4'hD) ^ gfmul(x[31:24], 4'h9))
};
endfunction
// GF multiplication
function logic [7:0] gfmul(input logic [7:0] x, input logic [3:0] y);
logic [7:0] result, temp;
result = 8'h00;
if (y[0]) result ^= x;
if (y[1]) begin
result ^= ((x << 1) ^ ((x[7]) ? 8'h1B : 8'h00));
end
if (y[2]) begin
temp = (x << 1) ^ ((x[7]) ? 8'h1B : 8'h00);
result ^= (temp << 1) ^ ((temp[7]) ? 8'h1B : 8'h00);
end
if (y[3]) begin
temp = (x << 1) ^ ((x[7]) ? 8'h1B : 8'h00);
temp = (temp << 1) ^ ((temp[7]) ? 8'h1B : 8'h00);
result ^= (temp << 1) ^ ((temp[7]) ? 8'h1B : 8'h00);
end
return result;
endfunction
// AES Sbox implementation based on https://github.com/riscv/riscv-crypto
// AES Sbox Forward
function automatic logic [7:0] aes_sbox_fwd(input logic [7:0] in_byte);
logic [20:0] expanded;
logic [17:0] non_linear;
logic [ 7:0] compressed;
expanded = linear_top_layer(in_byte);
non_linear = non_linear_layer(expanded);
compressed = linear_bottom_layer(non_linear);
aes_sbox_fwd = compressed;
endfunction
// AES Sbox Inverse
function automatic logic [7:0] aes_sbox_inv(input logic [7:0] in_byte);
logic [20:0] expanded;
logic [17:0] non_linear;
logic [ 7:0] compressed;
expanded = aes_sbox_inv_top(in_byte);
non_linear = non_linear_layer(expanded);
compressed = aes_sbox_inv_out(non_linear);
aes_sbox_inv = compressed;
endfunction
// AES Sbox Forward Top Layer
function automatic logic [20:0] linear_top_layer(input logic [7:0] x);
return {
((x[7] ^ x[4]) ^ (x[5] ^ x[2])),
(((x[7] ^ x[4]) ^ ((x[6] ^ x[5]) ^ (x[4] ^ x[0]))) ^ ((x[0] ^ (x[6] ^ x[5])) ^ ((x[3] ^ x[1]) ^ (x[5] ^ x[2])))),
((x[7] ^ x[2]) ^ (((x[7] ^ x[4]) ^ (x[3] ^ x[1])) ^ (x[6] ^ x[5]))),
((x[7] ^ x[2]) ^ ((x[6] ^ x[5]) ^ (x[1] ^ x[0]))),
((x[6] ^ x[5]) ^ (x[1] ^ x[0])),
((x[7] ^ x[4]) ^ ((x[6] ^ x[5]) ^ (x[4] ^ x[0]))),
((x[6] ^ x[5]) ^ (x[4] ^ x[0])),
((x[0] ^ (x[6] ^ x[5])) ^ ((x[3] ^ x[1]) ^ (x[5] ^ x[2]))),
((x[3] ^ x[1]) ^ (x[5] ^ x[2])),
((x[3] ^ x[1]) ^ (x[6] ^ x[2])),
(((x[7] ^ x[4]) ^ (x[3] ^ x[1])) ^ (x[6] ^ x[2])),
((x[7] ^ x[1]) ^ (x[4] ^ x[2])),
(((x[7] ^ x[4]) ^ (x[3] ^ x[1])) ^ (x[6] ^ x[5])),
(x[0] ^ (x[6] ^ x[5])),
(x[0] ^ ((x[7] ^ x[4]) ^ (x[3] ^ x[1]))),
((x[7] ^ x[4]) ^ (x[3] ^ x[1])),
(x[4] ^ x[2]),
(x[7] ^ x[1]),
(x[7] ^ x[2]),
(x[7] ^ x[4]),
(x[0])
};
endfunction
// AES Sbox Middle Layer
function automatic logic [17:0] non_linear_layer(input logic [20:0] x);
logic t1, t2, t3, t4, t5;
logic [17:0] y;
t1 = (((x[10] ^ (x[9] & x[5])) ^ (x[17] & x[6])) ^ ((x[4] & x[20]) ^ (x[1] & x[11])));
t2 = ((((x[14] & x[0]) ^ (x[9] & x[5])) ^ x[18]) ^ ((x[2] & x[8]) ^ (x[1] & x[11])));
t3 = ((((x[3] ^ x[12]) ^ (x[3] & x[12])) ^ (x[16] & x[7])) ^ ((x[4] & x[20]) ^ (x[1] & x[11])));
t4 = ((((x[15] & x[13]) ^ (x[3] & x[12])) ^ ((x[2] & x[8]) ^ (x[1] & x[11]))) ^ x[19]);
t5 = ((((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1))) ^ (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1))));
y[0] = (((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1))) & x[7];
y[1] = (t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) & x[13];
y[2] = ((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4)))) & x[11];
y[3] = (((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4)))) ^ t5) & x[20];
y[4] = t5 & x[8];
y[5] = ((t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4))) ^ (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1)))) & x[9];
y[6] = (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1))) & x[17];
y[7] = (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4))) & x[14];
y[8] = ((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1)))) & x[3];
y[9] = (((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1))) & x[16];
y[10] = (t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) & x[15];
y[11] = ((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4)))) & x[1];
y[12] = (((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4)))) ^ t5) & x[4];
y[13] = t5 & x[2];
y[14] = ((t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4))) ^ (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1)))) & x[5];
y[15] = (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1))) & x[6];
y[16] = (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4))) & x[0];
y[17] = ((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1)))) & x[12];
return y;
endfunction
// AES Sbox Forward Bottom Layer
function automatic logic [7:0] linear_bottom_layer(input logic [17:0] x);
logic [7:0] y;
y[0] = ((x[12] ^ (x[17] ^ x[11])) ^~ ((x[8] ^ (x[1] ^ x[9])) ^ (x[14] ^ x[16])));
y[1] = ((x[0] ^ (x[11] ^ x[12])) ^~ ((x[1] ^ x[9]) ^ (x[3] ^ (x[4] ^ x[8]))));
y[2] = (((x[12] ^ (x[17] ^ x[11])) ^ (x[3] ^ (x[4] ^ x[8]))) ^ ((x[10] ^ (x[14] ^ x[16])) ^ (x[7] ^ (x[0] ^ x[6]))));
y[3] = (((x[11] ^ x[12]) ^ (x[0] ^ x[6])) ^ ((x[15] ^ x[5]) ^ (x[16] ^ x[1])));
y[4] = ((x[12] ^ (x[17] ^ x[11])) ^ ((x[0] ^ x[6]) ^ (x[14] ^ (x[15] ^ x[5]))));
y[5] = ((x[13] ^ (x[4] ^ x[8])) ^~ ((x[10] ^ (x[14] ^ x[16])) ^ (x[2] ^ x[11])));
y[6] = ((x[6] ^ (x[11] ^ x[12])) ^~ ((x[14] ^ (x[15] ^ x[5])) ^ (x[2] ^ x[3])));
y[7] = ((x[12] ^ (x[17] ^ x[11])) ^ ((x[5] ^ (x[0] ^ x[6])) ^ (x[2] ^ x[3])));
return y;
endfunction
// AES Sbox Inverse Top Layer
function automatic logic [20:0] aes_sbox_inv_top(input logic [7:0] x);
return {
((x[4] ^ x[3]) ^ (x[2] ^~ x[1])),
(x[5] ^~ (x[4] ^ x[3])),
(x[3] ^~ x[0]),
(x[7] ^ x[4]),
(x[6] ^~ x[4]),
((x[3] ^~ x[0]) ^ (x[6] ^ x[1])),
((x[6] ^~ x[4]) ^ (x[1] ^ x[0])),
(x[5] ^~ ((x[6] ^~ x[4]) ^ (x[1] ^ x[0]))),
((x[6] ^ x[1]) ^ (x[5] ^~ x[3])),
(((x[7] ^~ x[6]) ^ (x[3] ^~ x[0])) ^ ((x[4] ^ x[3]) ^ (x[2] ^~ x[1]))),
(((x[7] ^~ x[6]) ^ (x[3] ^~ x[0])) ^ (x[2] ^~ x[1])),
((x[7] ^~ x[6]) ^ (x[1] ^ x[0])),
((x[7] ^~ x[6]) ^ (x[3] ^~ x[0])),
(x[0] ^~ (x[4] ^ x[3])),
(x[6] ^~ (x[7] ^ x[4])),
((x[6] ^~ x[4]) ^ (x[5] ^~ x[2])),
(x[3] ^ (x[6] ^~ (x[7] ^ x[4]))),
((x[4] ^ x[3]) ^ (x[1] ^ x[0])),
(x[7] ^~ x[6]),
(x[4] ^ x[3]),
(x[7] ^ (x[5] ^~ x[2]))
};
endfunction
// AES Sbox Inverse Bottom Layer
function automatic logic [7:0] aes_sbox_inv_out(input logic [17:0] x);
logic [7:0] y;
y[0] = ((x[5] ^ x[13]) ^ (x[7] ^ x[11]));
y[1] = ((x[17] ^ x[12]) ^ (((x[2] ^ x[11]) ^ (x[8] ^ x[9])) ^ (x[0] ^ x[3])));
y[2] = (((x[4] ^ x[12]) ^ (x[15] ^ x[0])) ^ ((x[14] ^ x[1]) ^ ((x[2] ^ x[11]) ^ (x[8] ^ x[9]))));
y[3] = ((((x[2] ^ x[11]) ^ (x[8] ^ x[9])) ^ (x[0] ^ x[3])) ^ ((x[7] ^ (x[16] ^ x[6])) ^ (x[13] ^ (x[14] ^ x[1]))));
y[4] = ((x[14] ^ x[16]) ^ ((x[4] ^ x[12]) ^ ((x[2] ^ x[11]) ^ (x[8] ^ x[9]))));
y[5] = ((x[8] ^ (x[4] ^ x[12])) ^ (((x[2] ^ x[11]) ^ (x[15] ^ x[0])) ^ ((x[17] ^ x[10]) ^ (x[7] ^ (x[16] ^ x[6])))));
y[6] = (((x[5] ^ x[13]) ^ ((x[2] ^ x[11]) ^ (x[15] ^ x[0]))) ^ ((x[4] ^ x[9]) ^ ((x[16] ^ x[6]) ^ (x[17] ^ x[10]))));
y[7] = ((x[17] ^ x[1]) ^ ((x[4] ^ x[12]) ^ ((x[2] ^ x[11]) ^ (x[8] ^ x[9]))));
return y;
endfunction
endpackage

View file

@ -848,204 +848,4 @@ package ariane_pkg;
return (n < 0) ? 0 : n;
endfunction : avoid_neg
// AES functions
// AES MixColumns Forward
function [31:0] aes_mixcolumn_fwd(input [31:0] x);
begin
aes_mixcolumn_fwd = {
(((x[7:0] << 1) ^ ((x[7]) ? 8'h1B : 8'h00)) ^ x[7:0]) ^ x[15:8] ^ x[23:16] ^ ((x[31:24] << 1) ^ ((x[31]) ? 8'h1B : 8'h00)),
x[7:0] ^ x[15:8] ^ ((x[23:16] << 1) ^ ((x[23]) ? 8'h1B : 8'h00)) ^ (((x[31:24] << 1) ^ ((x[31]) ? 8'h1B : 8'h00)) ^ x[31:24]),
x[7:0] ^ ((x[15:8] << 1) ^ ((x[15]) ? 8'h1B : 8'h00)) ^ (((x[23:16] << 1) ^ ((x[23]) ? 8'h1B : 8'h00)) ^ x[23:16]) ^ x[31:24],
((x[7:0] << 1) ^ ((x[7]) ? 8'h1B : 8'h00)) ^ (((x[15:8] << 1) ^ ((x[15]) ? 8'h1B : 8'h00)) ^ x[15:8]) ^ x[23:16] ^ x[31:24]
};
end
endfunction
// AES subword Forward
function [31:0] aes_subword_fwd(input [31:0] word);
aes_subword_fwd = {
aes_sbox_fwd(word[31:24]),
aes_sbox_fwd(word[23:16]),
aes_sbox_fwd(word[15:8]),
aes_sbox_fwd(word[7:0])
};
endfunction
// AES Round Constant
function [31:0] aes_decode_rcon(input [3:0] r);
case (r)
4'h0: aes_decode_rcon = 32'h00000001;
4'h1: aes_decode_rcon = 32'h00000002;
4'h2: aes_decode_rcon = 32'h00000004;
4'h3: aes_decode_rcon = 32'h00000008;
4'h4: aes_decode_rcon = 32'h00000010;
4'h5: aes_decode_rcon = 32'h00000020;
4'h6: aes_decode_rcon = 32'h00000040;
4'h7: aes_decode_rcon = 32'h00000080;
4'h8: aes_decode_rcon = 32'h0000001b;
4'h9: aes_decode_rcon = 32'h00000036;
4'hA: aes_decode_rcon = 32'h00000000;
4'hB: aes_decode_rcon = 32'h00000000;
4'hC: aes_decode_rcon = 32'h00000000;
4'hD: aes_decode_rcon = 32'h00000000;
4'hE: aes_decode_rcon = 32'h00000000;
4'hF: aes_decode_rcon = 32'h00000000;
default: aes_decode_rcon = 32'h00000000;
endcase
endfunction
// AES MixColumns Inverse
function logic [31:0] aes_mixcolumn_inv(input logic [31:0] x);
aes_mixcolumn_inv = {
(gfmul(x[7:0], 4'hB) ^ gfmul(x[15:8], 4'hD) ^ gfmul(x[23:16], 4'h9) ^ gfmul(x[31:24], 4'hE)),
(gfmul(x[7:0], 4'hD) ^ gfmul(x[15:8], 4'h9) ^ gfmul(x[23:16], 4'hE) ^ gfmul(x[31:24], 4'hB)),
(gfmul(x[7:0], 4'h9) ^ gfmul(x[15:8], 4'hE) ^ gfmul(x[23:16], 4'hB) ^ gfmul(x[31:24], 4'hD)),
(gfmul(x[7:0], 4'hE) ^ gfmul(x[15:8], 4'hB) ^ gfmul(x[23:16], 4'hD) ^ gfmul(x[31:24], 4'h9))
};
endfunction
// GF multiplication
function logic [7:0] gfmul(input logic [7:0] x, input logic [3:0] y);
logic [7:0] result, temp;
result = 8'h00;
if (y[0]) result ^= x;
if (y[1]) begin
result ^= ((x << 1) ^ ((x[7]) ? 8'h1B : 8'h00));
end
if (y[2]) begin
temp = (x << 1) ^ ((x[7]) ? 8'h1B : 8'h00);
result ^= (temp << 1) ^ ((temp[7]) ? 8'h1B : 8'h00);
end
if (y[3]) begin
temp = (x << 1) ^ ((x[7]) ? 8'h1B : 8'h00);
temp = (temp << 1) ^ ((temp[7]) ? 8'h1B : 8'h00);
result ^= (temp << 1) ^ ((temp[7]) ? 8'h1B : 8'h00);
end
return result;
endfunction
// AES Sbox implementation based on https://github.com/riscv/riscv-crypto
// AES Sbox Forward
function automatic logic [7:0] aes_sbox_fwd(input logic [7:0] in_byte);
logic [20:0] expanded;
logic [17:0] non_linear;
logic [ 7:0] compressed;
expanded = linear_top_layer(in_byte);
non_linear = non_linear_layer(expanded);
compressed = linear_bottom_layer(non_linear);
aes_sbox_fwd = compressed;
endfunction
// AES Sbox Inverse
function automatic logic [7:0] aes_sbox_inv(input logic [7:0] in_byte);
logic [20:0] expanded;
logic [17:0] non_linear;
logic [ 7:0] compressed;
expanded = aes_sbox_inv_top(in_byte);
non_linear = non_linear_layer(expanded);
compressed = aes_sbox_inv_out(non_linear);
aes_sbox_inv = compressed;
endfunction
// AES Sbox Forward Top Layer
function automatic logic [20:0] linear_top_layer(input logic [7:0] x);
return {
((x[7] ^ x[4]) ^ (x[5] ^ x[2])),
(((x[7] ^ x[4]) ^ ((x[6] ^ x[5]) ^ (x[4] ^ x[0]))) ^ ((x[0] ^ (x[6] ^ x[5])) ^ ((x[3] ^ x[1]) ^ (x[5] ^ x[2])))),
((x[7] ^ x[2]) ^ (((x[7] ^ x[4]) ^ (x[3] ^ x[1])) ^ (x[6] ^ x[5]))),
((x[7] ^ x[2]) ^ ((x[6] ^ x[5]) ^ (x[1] ^ x[0]))),
((x[6] ^ x[5]) ^ (x[1] ^ x[0])),
((x[7] ^ x[4]) ^ ((x[6] ^ x[5]) ^ (x[4] ^ x[0]))),
((x[6] ^ x[5]) ^ (x[4] ^ x[0])),
((x[0] ^ (x[6] ^ x[5])) ^ ((x[3] ^ x[1]) ^ (x[5] ^ x[2]))),
((x[3] ^ x[1]) ^ (x[5] ^ x[2])),
((x[3] ^ x[1]) ^ (x[6] ^ x[2])),
(((x[7] ^ x[4]) ^ (x[3] ^ x[1])) ^ (x[6] ^ x[2])),
((x[7] ^ x[1]) ^ (x[4] ^ x[2])),
(((x[7] ^ x[4]) ^ (x[3] ^ x[1])) ^ (x[6] ^ x[5])),
(x[0] ^ (x[6] ^ x[5])),
(x[0] ^ ((x[7] ^ x[4]) ^ (x[3] ^ x[1]))),
((x[7] ^ x[4]) ^ (x[3] ^ x[1])),
(x[4] ^ x[2]),
(x[7] ^ x[1]),
(x[7] ^ x[2]),
(x[7] ^ x[4]),
(x[0])
};
endfunction
// AES Sbox Middle Layer
function automatic logic [17:0] non_linear_layer(input logic [20:0] x);
logic t1, t2, t3, t4, t5;
logic [17:0] y;
t1 = (((x[10] ^ (x[9] & x[5])) ^ (x[17] & x[6])) ^ ((x[4] & x[20]) ^ (x[1] & x[11])));
t2 = ((((x[14] & x[0]) ^ (x[9] & x[5])) ^ x[18]) ^ ((x[2] & x[8]) ^ (x[1] & x[11])));
t3 = ((((x[3] ^ x[12]) ^ (x[3] & x[12])) ^ (x[16] & x[7])) ^ ((x[4] & x[20]) ^ (x[1] & x[11])));
t4 = ((((x[15] & x[13]) ^ (x[3] & x[12])) ^ ((x[2] & x[8]) ^ (x[1] & x[11]))) ^ x[19]);
t5 = ((((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1))) ^ (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1))));
y[0] = (((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1))) & x[7];
y[1] = (t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) & x[13];
y[2] = ((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4)))) & x[11];
y[3] = (((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4)))) ^ t5) & x[20];
y[4] = t5 & x[8];
y[5] = ((t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4))) ^ (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1)))) & x[9];
y[6] = (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1))) & x[17];
y[7] = (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4))) & x[14];
y[8] = ((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1)))) & x[3];
y[9] = (((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1))) & x[16];
y[10] = (t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) & x[15];
y[11] = ((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4)))) & x[1];
y[12] = (((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4)))) ^ t5) & x[4];
y[13] = t5 & x[2];
y[14] = ((t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4))) ^ (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1)))) & x[5];
y[15] = (((t3 ^ t4) & (t2 & t3)) ^ ((t3 ^ t4) ^ (t3 & t1))) & x[6];
y[16] = (t4 ^ ((t2 ^ (t3 & t1)) & (t3 ^ t4))) & x[0];
y[17] = ((t2 ^ ((t4 ^ (t3 & t1)) & (t1 ^ t2))) ^ (((t1 ^ t2) & (t1 & t4)) ^ ((t1 ^ t2) ^ (t3 & t1)))) & x[12];
return y;
endfunction
// AES Sbox Forward Bottom Layer
function automatic logic [7:0] linear_bottom_layer(input logic [17:0] x);
logic [7:0] y;
y[0] = ((x[12] ^ (x[17] ^ x[11])) ^~ ((x[8] ^ (x[1] ^ x[9])) ^ (x[14] ^ x[16])));
y[1] = ((x[0] ^ (x[11] ^ x[12])) ^~ ((x[1] ^ x[9]) ^ (x[3] ^ (x[4] ^ x[8]))));
y[2] = (((x[12] ^ (x[17] ^ x[11])) ^ (x[3] ^ (x[4] ^ x[8]))) ^ ((x[10] ^ (x[14] ^ x[16])) ^ (x[7] ^ (x[0] ^ x[6]))));
y[3] = (((x[11] ^ x[12]) ^ (x[0] ^ x[6])) ^ ((x[15] ^ x[5]) ^ (x[16] ^ x[1])));
y[4] = ((x[12] ^ (x[17] ^ x[11])) ^ ((x[0] ^ x[6]) ^ (x[14] ^ (x[15] ^ x[5]))));
y[5] = ((x[13] ^ (x[4] ^ x[8])) ^~ ((x[10] ^ (x[14] ^ x[16])) ^ (x[2] ^ x[11])));
y[6] = ((x[6] ^ (x[11] ^ x[12])) ^~ ((x[14] ^ (x[15] ^ x[5])) ^ (x[2] ^ x[3])));
y[7] = ((x[12] ^ (x[17] ^ x[11])) ^ ((x[5] ^ (x[0] ^ x[6])) ^ (x[2] ^ x[3])));
return y;
endfunction
// AES Sbox Inverse Top Layer
function automatic logic [20:0] aes_sbox_inv_top(input logic [7:0] x);
return {
((x[4] ^ x[3]) ^ (x[2] ^~ x[1])),
(x[5] ^~ (x[4] ^ x[3])),
(x[3] ^~ x[0]),
(x[7] ^ x[4]),
(x[6] ^~ x[4]),
((x[3] ^~ x[0]) ^ (x[6] ^ x[1])),
((x[6] ^~ x[4]) ^ (x[1] ^ x[0])),
(x[5] ^~ ((x[6] ^~ x[4]) ^ (x[1] ^ x[0]))),
((x[6] ^ x[1]) ^ (x[5] ^~ x[3])),
(((x[7] ^~ x[6]) ^ (x[3] ^~ x[0])) ^ ((x[4] ^ x[3]) ^ (x[2] ^~ x[1]))),
(((x[7] ^~ x[6]) ^ (x[3] ^~ x[0])) ^ (x[2] ^~ x[1])),
((x[7] ^~ x[6]) ^ (x[1] ^ x[0])),
((x[7] ^~ x[6]) ^ (x[3] ^~ x[0])),
(x[0] ^~ (x[4] ^ x[3])),
(x[6] ^~ (x[7] ^ x[4])),
((x[6] ^~ x[4]) ^ (x[5] ^~ x[2])),
(x[3] ^ (x[6] ^~ (x[7] ^ x[4]))),
((x[4] ^ x[3]) ^ (x[1] ^ x[0])),
(x[7] ^~ x[6]),
(x[4] ^ x[3]),
(x[7] ^ (x[5] ^~ x[2]))
};
endfunction
// AES Sbox Inverse Bottom Layer
function automatic logic [7:0] aes_sbox_inv_out(input logic [17:0] x);
logic [7:0] y;
y[0] = ((x[5] ^ x[13]) ^ (x[7] ^ x[11]));
y[1] = ((x[17] ^ x[12]) ^ (((x[2] ^ x[11]) ^ (x[8] ^ x[9])) ^ (x[0] ^ x[3])));
y[2] = (((x[4] ^ x[12]) ^ (x[15] ^ x[0])) ^ ((x[14] ^ x[1]) ^ ((x[2] ^ x[11]) ^ (x[8] ^ x[9]))));
y[3] = ((((x[2] ^ x[11]) ^ (x[8] ^ x[9])) ^ (x[0] ^ x[3])) ^ ((x[7] ^ (x[16] ^ x[6])) ^ (x[13] ^ (x[14] ^ x[1]))));
y[4] = ((x[14] ^ x[16]) ^ ((x[4] ^ x[12]) ^ ((x[2] ^ x[11]) ^ (x[8] ^ x[9]))));
y[5] = ((x[8] ^ (x[4] ^ x[12])) ^ (((x[2] ^ x[11]) ^ (x[15] ^ x[0])) ^ ((x[17] ^ x[10]) ^ (x[7] ^ (x[16] ^ x[6])))));
y[6] = (((x[5] ^ x[13]) ^ ((x[2] ^ x[11]) ^ (x[15] ^ x[0]))) ^ ((x[4] ^ x[9]) ^ ((x[16] ^ x[6]) ^ (x[17] ^ x[10]))));
y[7] = ((x[17] ^ x[1]) ^ ((x[4] ^ x[12]) ^ ((x[2] ^ x[11]) ^ (x[8] ^ x[9]))));
return y;
endfunction
endpackage