hw/ip/aes/rtl/aes_sbox_canright.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 Canright SBox #4
   6: //
   7: // For details, see the technical report: Canright, "A very compact Rijndael S-box"
   8: // available at https://hdl.handle.net/10945/25608
   9: 
  10: module aes_sbox_canright (
  11:   input  aes_pkg::mode_e mode_i,
  12:   input  logic [7:0]     data_i,
  13:   output logic [7:0]     data_o
  14: );
  15: 
  16:   import aes_pkg::*;
  17: 
  18:   ///////////////////////////
  19:   // Functions & Constants //
  20:   ///////////////////////////
  21: 
  22:   // Multiplication in GF(2^2), using normal basis [Omega^2, Omega]
  23:   // (see Figure 14 in the technical report)
  24:   function automatic logic [1:0] aes_mul_gf2p2(input logic [1:0] g, input logic [1:0] d);
  25:     logic [1:0] f;
  26:     logic       a, b, c;
  27:     a    = g[1] & d[1];
  28:     b    = (^g) & (^d);
  29:     c    = g[0] & d[0];
  30:     f[1] = a ^ b;
  31:     f[0] = c ^ b;
  32:     return f;
  33:   endfunction
  34: 
  35:   // Scale by Omega^2 = N in GF(2^2), using normal basis [Omega^2, Omega]
  36:   // (see Figure 16 in the technical report)
  37:   function automatic logic [1:0] aes_scale_omega2_gf2p2(input logic [1:0] g);
  38:     logic [1:0] d;
  39:     d[1] = g[0];
  40:     d[0] = g[1] ^ g[0];
  41:     return d;
  42:   endfunction
  43: 
  44:   // Scale by Omega = N^2 in GF(2^2), using normal basis [Omega^2, Omega]
  45:   // (see Figure 15 in the technical report)
  46:   function automatic logic [1:0] aes_scale_omega_gf2p2(input logic [1:0] g);
  47:     logic [1:0] d;
  48:     d[1] = g[1] ^ g[0];
  49:     d[0] = g[1];
  50:     return d;
  51:   endfunction
  52: 
  53:   // Square in GF(2^2), using normal basis [Omega^2, Omega]
  54:   // (see Figures 8 and 10 in the technical report)
  55:   function automatic logic [1:0] aes_square_gf2p2(input logic [1:0] g);
  56:     logic [1:0] d;
  57:     d[1] = g[0];
  58:     d[0] = g[1];
  59:     return d;
  60:   endfunction
  61: 
  62:   // Multiplication in GF(2^4), using normal basis [alpha^8, alpha^2]
  63:   // (see Figure 13 in the technical report)
  64:   function automatic logic [3:0] aes_mul_gf2p4(input logic [3:0] gamma, input logic [3:0] delta);
  65:     logic [3:0] theta;
  66:     logic [1:0] a, b, c;
  67:     a          = aes_mul_gf2p2(gamma[3:2], delta[3:2]);
  68:     b          = aes_mul_gf2p2(gamma[3:2] ^ gamma[1:0], delta[3:2] ^ delta[1:0]);
  69:     c          = aes_mul_gf2p2(gamma[1:0], delta[1:0]);
  70:     theta[3:2] = a ^ aes_scale_omega2_gf2p2(b);
  71:     theta[1:0] = c ^ aes_scale_omega2_gf2p2(b);
  72:     return theta;
  73:   endfunction
  74: 
  75:   // Square and scale by nu in GF(2^4)/GF(2^2), using normal basis [alpha^8, alpha^2]
  76:   // (see Figure 19 as well as Appendix A of the technical report)
  77:   function automatic logic [3:0] aes_square_scale_gf2p4_gf2p2(input logic [3:0] gamma);
  78:     logic [3:0] delta;
  79:     logic [1:0] a, b;
  80:     a          = gamma[3:2] ^ gamma[1:0];
  81:     b          = aes_square_gf2p2(gamma[1:0]);
  82:     delta[3:2] = aes_square_gf2p2(a);
  83:     delta[1:0] = aes_scale_omega_gf2p2(b);
  84:     return delta;
  85:   endfunction
  86: 
  87:   // Inverse in GF(2^4), using normal basis [alpha^8, alpha^2]
  88:   // (see Figure 12 in the technical report)
  89:   function automatic logic [3:0] aes_inverse_gf2p4(input logic [3:0] gamma);
  90:     logic [3:0] delta;
  91:     logic [1:0] a, b, c, d;
  92:     a          = gamma[3:2] ^ gamma[1:0];
  93:     b          = aes_mul_gf2p2(gamma[3:2], gamma[1:0]);
  94:     c          = aes_scale_omega2_gf2p2(aes_square_gf2p2(a));
  95:     d          = aes_square_gf2p2(c ^ b);
  96:     delta[3:2] = aes_mul_gf2p2(d, gamma[1:0]);
  97:     delta[1:0] = aes_mul_gf2p2(d, gamma[3:2]);
  98:     return delta;
  99:   endfunction
 100: 
 101:   // Inverse in GF(2^8), using normal basis [d^16, d]
 102:   // (see Figure 11 in the technical report)
 103:   function automatic logic [7:0] aes_inverse_gf2p8(input logic [7:0] gamma);
 104:     logic [7:0] delta;
 105:     logic [3:0] a, b, c, d;
 106:     a          = gamma[7:4] ^ gamma[3:0];
 107:     b          = aes_mul_gf2p4(gamma[7:4], gamma[3:0]);
 108:     c          = aes_square_scale_gf2p4_gf2p2(a);
 109:     d          = aes_inverse_gf2p4(c ^ b);
 110:     delta[7:4] = aes_mul_gf2p4(d, gamma[3:0]);
 111:     delta[3:0] = aes_mul_gf2p4(d, gamma[7:4]);
 112:     return delta;
 113:   endfunction
 114: 
 115:   // Basis conversion matrices to convert between polynomial basis A, normal basis X
 116:   // and basis S incorporating the bit matrix of the SBox. More specifically,
 117:   // multiplication by x2s performs the transformation from normal basis X into
 118:   // polynomial basis A, followed by the affine transformation (substep 2). Likewise,
 119:   // multiplication by s2x performs the inverse affine transformation followed by the
 120:   // transformation from polynomial basis A to normal basis X.
 121:   // (see Appendix A of the technical report)
 122:   const logic [7:0] a2x [8] = '{8'h98, 8'hf3, 8'hf2, 8'h48, 8'h09, 8'h81, 8'ha9, 8'hff};
 123:   const logic [7:0] x2a [8] = '{8'h64, 8'h78, 8'h6e, 8'h8c, 8'h68, 8'h29, 8'hde, 8'h60};
 124:   const logic [7:0] x2s [8] = '{8'h58, 8'h2d, 8'h9e, 8'h0b, 8'hdc, 8'h04, 8'h03, 8'h24};
 125:   const logic [7:0] s2x [8] = '{8'h8c, 8'h79, 8'h05, 8'heb, 8'h12, 8'h04, 8'h51, 8'h53};
 126: 
 127:   ///////////////////
 128:   // Canright SBox //
 129:   ///////////////////
 130: 
 131:   logic [7:0] data_basis_x, data_inverse;
 132: 
 133:   // Convert to normal basis X.
 134:   assign data_basis_x = (mode_i == AES_ENC) ? aes_mvm(data_i, a2x) :
 135:                                               aes_mvm(data_i ^ 8'h63, s2x);
 136: 
 137:   // Do the inversion in normal basis X.
 138:   assign data_inverse = aes_inverse_gf2p8(data_basis_x);
 139: 
 140:   // Convert to basis S or A.
 141:   assign data_o       = (mode_i == AES_ENC) ? aes_mvm(data_inverse, x2s) ^ 8'h63 :
 142:                                               aes_mvm(data_inverse, x2a);
 143: 
 144: endmodule
 145: