URL
https://opencores.org/ocsvn/systemcaes/systemcaes/trunk
Subversion Repositories systemcaes
[/] [systemcaes/] [trunk/] [rtl/] [systemc/] [aes128lowarea/] [sbox.cpp] - Rev 28
Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// AES sbox module implementation //// //// //// //// This file is part of the SystemC AES //// //// //// //// Description: //// //// S-box calculation calculating inverse on gallois field //// //// //// //// To Do: //// //// - done //// //// //// //// Author(s): //// //// - Javier Castillo, jcastilo@opencores.org //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000 Authors and OPENCORES.ORG //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source is distributed in the hope that it will be //// //// useful, but WITHOUT ANY WARRANTY; without even the implied //// //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// //// PURPOSE. See the GNU Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from http://www.opencores.org/lgpl.shtml //// //// //// ////////////////////////////////////////////////////////////////////// // // CVS Revision History // // $Log: not supported by cvs2svn $ // Revision 1.1 2005/02/14 11:18:31 jcastillo // Moved // // Revision 1.2 2004/08/30 14:44:44 jcastillo // Code Formater used to give better appearance to SystemC code // // Revision 1.1.1.1 2004/07/05 09:46:22 jcastillo // First import // #include "sbox.h" void sbox::registers() { if (!reset.read()) { to_invert.write(0); ah_reg.write(0); alph.write(0); } else { to_invert.write(next_to_invert.read()); ah_reg.write(next_ah_reg.read()); alph.write(next_alph.read()); } } void sbox::first_mux() { sc_uint<8> data_var; sc_uint<8> InvInput; sc_uint<4> ah_t, al_t; bool aA, aB, aC, aD; data_var = data_i.read(); InvInput = data_var; switch (decrypt_i.read()) { case 1: //Apply inverse affine trasformation aA = data_var[0] ^ data_var[5]; aB = data_var[1] ^ data_var[4]; aC = data_var[2] ^ data_var[7]; aD = data_var[3] ^ data_var[6]; InvInput[0] = (!data_var[5]) ^ aC; InvInput[1] = data_var[0] ^ aD; InvInput[2] = (!data_var[7]) ^ aB; InvInput[3] = data_var[2] ^ aA; InvInput[4] = data_var[1] ^ aD; InvInput[5] = data_var[4] ^ aC; InvInput[6] = data_var[3] ^ aA; InvInput[7] = data_var[6] ^ aB; break; default: InvInput = data_var; break; } //Convert elements from GF(2^8) into two elements of GF(2^4^2) aA = InvInput[1] ^ InvInput[7]; aB = InvInput[5] ^ InvInput[7]; aC = InvInput[4] ^ InvInput[6]; al_t[0] = aC ^ InvInput[0] ^ InvInput[5]; al_t[1] = InvInput[1] ^ InvInput[2]; al_t[2] = aA; al_t[3] = InvInput[2] ^ InvInput[4]; ah_t[0] = aC ^ InvInput[5]; ah_t[1] = aA ^ aC; ah_t[2] = aB ^ InvInput[2] ^ InvInput[3]; ah_t[3] = aB; al.write(al_t); ah.write(ah_t); next_ah_reg.write(ah_t); } void sbox::end_mux() { sc_uint<8> data_var, data_o_var; bool aA, aB, aC, aD; //Take the output of the inverter data_var = inva.read(); switch (decrypt_i.read()) { case 0: //Apply affine trasformation aA = data_var[0] ^ data_var[1]; aB = data_var[2] ^ data_var[3]; aC = data_var[4] ^ data_var[5]; aD = data_var[6] ^ data_var[7]; data_o_var[0] = (!data_var[0]) ^ aC ^ aD; data_o_var[1] = (!data_var[5]) ^ aA ^ aD; data_o_var[2] = data_var[2] ^ aA ^ aD; data_o_var[3] = data_var[7] ^ aA ^ aB; data_o_var[4] = data_var[4] ^ aA ^ aB; data_o_var[5] = (!data_var[1]) ^ aB ^ aC; data_o_var[6] = (!data_var[6]) ^ aB ^ aC; data_o_var[7] = data_var[3] ^ aC ^ aD; data_o.write(data_o_var); break; default: data_o.write(data_var); break; } } //Four operations in parallel void sbox::square1() { sc_uint<4> ah_t; ah_t[0] = ah.read()[0] ^ ah.read()[2]; ah_t[1] = ah.read()[2]; ah_t[2] = ah.read()[1] ^ ah.read()[3]; ah_t[3] = ah.read()[3]; ah2.write(ah_t); } void sbox::square2() { sc_uint<4> al_t; al_t[0] = al.read()[0] ^ al.read()[2]; al_t[1] = al.read()[2]; al_t[2] = al.read()[1] ^ al.read()[3]; al_t[3] = al.read()[3]; al2.write(al_t); } void sbox::mul1() { //al x ah sc_uint<4> alxh_t; sc_uint<4> aA, aB; aA = al.read()[0] ^ al.read()[3]; aB = al.read()[2] ^ al.read()[3]; alxh_t[0] = (al.read()[0] & ah.read()[0]) ^ (al.read()[3] & ah.read()[1]) ^ (al.read()[2] & ah.read()[2]) ^ (al.read()[1] & ah.read()[3]); alxh_t[1] = (al.read()[1] & ah.read()[0]) ^ (aA & ah.read()[1]) ^ (aB & ah.read()[2]) ^ ((al.read()[1] ^ al.read()[2]) & ah.read()[3]); alxh_t[2] = (al.read()[2] & ah.read()[0]) ^ (al.read()[1] & ah.read()[1]) ^ (aA & ah.read()[2]) ^ (aB & ah.read()[3]); alxh_t[3] = (al.read()[3] & ah.read()[0]) ^ (al.read()[2] & ah.read()[1]) ^ (al.read()[1] & ah.read()[2]) ^ (aA & ah.read()[3]); alxh.write(alxh_t); } void sbox::sum1() { sc_uint<4> alph_t; alph_t[0] = al.read()[0] ^ ah.read()[0]; alph_t[1] = al.read()[1] ^ ah.read()[1]; alph_t[2] = al.read()[2] ^ ah.read()[2]; alph_t[3] = al.read()[3] ^ ah.read()[3]; next_alph.write(alph_t); } //Secuential operations void sbox::intermediate() { sc_uint<4> aA, aB; sc_uint<4> ah2e, ah2epl2, to_invert_var; //ah square is multiplied with e aA = ah2.read()[0] ^ ah2.read()[1]; aB = ah2.read()[2] ^ ah2.read()[3]; ah2e[0] = ah2.read()[1] ^ aB; ah2e[1] = aA; ah2e[2] = aA ^ ah2.read()[2]; ah2e[3] = aA ^ aB; //Addition of ah2e plus al2 ah2epl2[0] = ah2e[0] ^ al2.read()[0]; ah2epl2[1] = ah2e[1] ^ al2.read()[1]; ah2epl2[2] = ah2e[2] ^ al2.read()[2]; ah2epl2[3] = ah2e[3] ^ al2.read()[3]; //Addition of last result with the result of (al x ah) to_invert_var[0] = ah2epl2[0] ^ alxh.read()[0]; to_invert_var[1] = ah2epl2[1] ^ alxh.read()[1]; to_invert_var[2] = ah2epl2[2] ^ alxh.read()[2]; to_invert_var[3] = ah2epl2[3] ^ alxh.read()[3]; //Registers next_to_invert.write(to_invert_var); } void sbox::inversion() { sc_uint<4> to_invert_var; sc_uint<4> aA, d_t; to_invert_var = to_invert.read(); //Invert the result in GF(2^4) aA = to_invert_var[1] ^ to_invert_var[2] ^ to_invert_var[3] ^ (to_invert_var[1] & to_invert_var[2] & to_invert_var[3]); d_t[0] = aA ^ to_invert_var[0] ^ (to_invert_var[0] & to_invert_var[2]) ^ (to_invert_var[1] & to_invert_var[2]) ^ (to_invert_var[0] & to_invert_var[1] & to_invert_var[2]); d_t[1] = (to_invert_var[0] & to_invert_var[1]) ^ (to_invert_var[0] & to_invert_var[2]) ^ (to_invert_var[1] & to_invert_var[2]) ^ to_invert_var[3] ^ (to_invert_var[1] & to_invert_var[3]) ^ (to_invert_var[0] & to_invert_var[1] & to_invert_var[3]); d_t[2] = (to_invert_var[0] & to_invert_var[1]) ^ to_invert_var[2] ^ (to_invert_var[0] & to_invert_var[2]) ^ to_invert_var[3] ^ (to_invert_var[0] & to_invert_var[3]) ^ (to_invert_var[0] & to_invert_var[2] & to_invert_var[3]); d_t[3] = aA ^ (to_invert_var[0] & to_invert_var[3]) ^ (to_invert_var[1] & to_invert_var[3]) ^ (to_invert_var[2] & to_invert_var[3]); d.write(d_t); } void sbox::mul2() { //ah x d sc_uint<4> ahp_t; sc_uint<4> aA, aB; aA = ah_reg.read()[0] ^ ah_reg.read()[3]; aB = ah_reg.read()[2] ^ ah_reg.read()[3]; ahp_t[0] = (ah_reg.read()[0] & d.read()[0]) ^ (ah_reg.read()[3] & d.read()[1]) ^ (ah_reg.read()[2] & d.read()[2]) ^ (ah_reg.read()[1] & d.read()[3]); ahp_t[1] = (ah_reg.read()[1] & d.read()[0]) ^ (aA & d.read()[1]) ^ (aB & d.read()[2]) ^ ((ah_reg.read()[1] ^ ah_reg.read()[2]) & d.read()[3]); ahp_t[2] = (ah_reg.read()[2] & d.read()[0]) ^ (ah_reg.read()[1] & d.read()[1]) ^ (aA & d.read()[2]) ^ (aB & d.read()[3]); ahp_t[3] = (ah_reg.read()[3] & d.read()[0]) ^ (ah_reg.read()[2] & d.read()[1]) ^ (ah_reg.read()[1] & d.read()[2]) ^ (aA & d.read()[3]); ahp.write(ahp_t); } void sbox::mul3() { //d x al sc_uint<4> alp_t; sc_uint<4> aA, aB; aA = d.read()[0] ^ d.read()[3]; aB = d.read()[2] ^ d.read()[3]; alp_t[0] = (d.read()[0] & alph.read()[0]) ^ (d.read()[3] & alph.read()[1]) ^ (d.read()[2] & alph.read()[2]) ^ (d.read()[1] & alph.read()[3]); alp_t[1] = (d.read()[1] & alph.read()[0]) ^ (aA & alph.read()[1]) ^ (aB & alph.read()[2]) ^ ((d.read()[1] ^ d.read()[2]) & alph.read()[3]); alp_t[2] = (d.read()[2] & alph.read()[0]) ^ (d.read()[1] & alph.read()[1]) ^ (aA & alph.read()[2]) ^ (aB & alph.read()[3]); alp_t[3] = (d.read()[3] & alph.read()[0]) ^ (d.read()[2] & alph.read()[1]) ^ (d.read()[1] & alph.read()[2]) ^ (aA & alph.read()[3]); alp.write(alp_t); } //Convert again to GF(2^8); void sbox::inversemap() { sc_uint<4> aA, aB; sc_uint<4> alp_t, ahp_t; sc_uint<8> inva_t; alp_t = alp.read(); ahp_t = ahp.read(); aA = alp_t[1] ^ ahp_t[3]; aB = ahp_t[0] ^ ahp_t[1]; inva_t[0] = alp_t[0] ^ ahp_t[0]; inva_t[1] = aB ^ ahp_t[3]; inva_t[2] = aA ^ aB; inva_t[3] = aB ^ alp_t[1] ^ ahp_t[2]; inva_t[4] = aA ^ aB ^ alp_t[3]; inva_t[5] = aB ^ alp_t[2]; inva_t[6] = aA ^ alp_t[2] ^ alp_t[3] ^ ahp_t[0]; inva_t[7] = aB ^ alp_t[2] ^ ahp_t[3]; inva.write(inva_t); }