Bunny2.0
Headers/BunnyAES.hxx
00001 
00002 
00003 
00004 
00006 //CONSTRUCTORS//
00008 
00012 template <unsigned nb_key, unsigned nround>
00013 inline
00014 BunnyAES<nb_key,nround>::BunnyAES(){
00015         rk.resize(nround+1) ; // allocates memory for the round keys
00016 }
00017 
00021 
00023 
00028 template <unsigned nb_key, unsigned nround>
00029 inline
00030 typename BunnyAES<nb_key,nround>::msgType
00031 BunnyAES<nb_key,nround>::encode( msgType m, keyType k ) {
00032         msgType c ;
00033         c = m ;
00034 
00035   keySchedule(k) ; //use BunnyAES keyschedule
00036 
00037         //Round 0, a-tipical
00038         c = addRoundKey(c,rk[0]) ;
00039         //cout << "state at round: 0 --> " << bitsetToHex(c) << endl ;
00040 
00041         //TYPICAL rounds
00042         for (unsigned i = 1 ; i < nround ; ++i){
00043                 //AES sBox
00044                 c = sBox(c) ;
00045                 //cout << "state after sBox: --> " << bitsetToHex(c) << endl ;
00046 
00047                 // AES mixing layer
00048                 c = shiftRows(c) ;
00049                 c = mixColumns(c) ;
00050                 //cout << "state after mixL: --> " << bitsetToHex(c) << endl ;
00051 
00052                 //AES add round key
00053                 c = addRoundKey(c,rk[i]) ;
00054                 //cout << "state at round: " << i <<  " --> " << bitsetToHex(c) << endl ;
00055         }
00056         //AES sBox
00057         c = sBox(c) ;
00058         //cout << "state after sBox: --> " << bitsetToHex(c) << endl ;
00059 
00060         // AES mixing layer - ATYPICAL (no mixColumns)
00061         c = shiftRows(c) ;
00062         //cout << "state after mixL: --> " << bitsetToHex(c) << endl ;
00063 
00064         //AES add round key
00065         c = addRoundKey(c,rk[nround]) ;
00066         //cout << "state at round: " << nround <<  " --> " << bitsetToHex(c) << endl ;
00067 
00068         return c ;
00069 }
00070 
00072 
00077 template <unsigned nb_key, unsigned nround>
00078 inline
00079 typename BunnyAES<nb_key,nround>::msgType
00080 BunnyAES<nb_key,nround>::decode( msgType m, keyType k ) {
00081         msgType c ;
00082         c = m ;
00083         keySchedule(k) ; //use BunnyAES keyschedule
00084 
00085         //Round 0, a-tipical (no mixColumns Inverse)
00086         c = addRoundKey(c,rk[nround]) ;
00087 
00088         // AES mixing layer - ATYPICAL (no mixColumns)
00089         c = shiftRowsInv(c) ;
00090 
00091         //AES sBox
00092         c = sBoxInverse(c) ;
00093 
00094         //TYPICAL rounds
00095         for (unsigned i = nround - 1 ; i > 0 ; --i){
00096                 //AES add round key
00097                 c = addRoundKey(c,rk[i]) ;
00098 
00099                 // AES mixing layer
00100                 c = mixColumnsInv(c) ;
00101                 c = shiftRowsInv(c) ;
00102 
00103                 //AES sBox
00104                 c = sBoxInverse(c) ;
00105         }
00106 
00107         //AES add round key
00108         c = addRoundKey(c,rk[0]) ;
00109 
00110         return c ;
00111 }
00112 
00116 
00118 
00123 template <unsigned nb_key, unsigned nround>
00124 inline
00125 void
00126 BunnyAES<nb_key,nround>::keySchedule(keyType k) {
00127         //AES128 needs 11 round keys
00128         //AES128 needs 13 round keys
00129         //AES128 needs 15 round keys
00130         //nround is the number of rounds without counting the first whitening
00131         unsigned int n, b ;
00132         sboxType temp ;
00133         bitset<32> rcon[16] ; // Constant assigned to each keyschedule round
00134 
00135         rcon[0]  = bitset<32> (string("10001101000000000000000000000000"));
00136         rcon[1]  = bitset<32> (string("00000001000000000000000000000000"));
00137         rcon[2]  = bitset<32> (string("00000010000000000000000000000000"));
00138         rcon[3]  = bitset<32> (string("00000100000000000000000000000000"));
00139         rcon[4]  = bitset<32> (string("00001000000000000000000000000000"));
00140         rcon[5]  = bitset<32> (string("00010000000000000000000000000000"));
00141         rcon[6]  = bitset<32> (string("00100000000000000000000000000000"));
00142         rcon[7]  = bitset<32> (string("01000000000000000000000000000000"));
00143         rcon[8]  = bitset<32> (string("10000000000000000000000000000000"));
00144         rcon[9]  = bitset<32> (string("00011011000000000000000000000000"));
00145         rcon[10] = bitset<32> (string("00110110000000000000000000000000"));
00146         rcon[11] = bitset<32> (string("01101100000000000000000000000000"));
00147 
00148         unsigned icon = 1 ; // index to count the costant rcon for each round
00149         b = (nround+1)*16 ; //16 bytes * 11,13,15 rounds = 176,208,240
00150         if (nb_key == 128) {
00151                 n = 16 ;
00152         } else if (nb_key == 192) {
00153                 n = 24 ;
00154         } else if (nb_key == 256) {
00155                 n = 32 ;
00156         }
00157 
00158         //number of 32-bit-words generated
00159         unsigned nword = (nround+1) * 4 ;// (nround+1) * 4
00160 
00161         //i.e.: nrow round keys at a time are filled
00162         //unsigned ncol = nb_msg/nb_sbox ;
00163         //unsigned nrow = nb_msg/nb_sbox + 1 ;
00164 
00165         vector<wordType> w ; //w will contains 32 bits words
00166 
00167         w.resize(nword) ; // initialize a vector of nword elements of type sboxType, set to 00...0
00168 
00169         //CREATE w, a vector of nwords words
00170         //put the key bits in the first 16 words
00171         for (unsigned i = 0 ; i < 4 ; ++i){
00172                 w[i] = extractWord(i*8*4,k) ;
00173         }
00174 
00175         for (unsigned i = 4 ; i < nword ; ++i){
00176                 if ( i % 4 == 0){
00177                         w[i] = w[i-1] ;
00178                         //Rotate the word w[i] 8 bits to the left
00179                         w[i] = rotLeft(w[i],8) ;
00180                         //Apply the sBoxes to w[i]
00181                         for (unsigned j = 0 ; j < 4 ; ++j){
00182                                 temp = extractFromWordToSboxType( j*8, w[i]) ; // extract nb_sbox bits starting from left to right
00183                                 temp = sbox(1,temp) ; // elaborate the nb_sbox bits extracted
00184                                 w[i] = copyIntoWord(w[i],j*8,temp) ; // put nb_bit bits in the position i*nb_sbox of the message c
00185                         }
00186                         //Exor w[i-4] and rcon[i]
00187                         w[i] = w[i] ^ rcon[icon] ^ w[i-4] ;
00188                         ++icon ;
00189                         //cout << "w[" << i << "] = "<< w[i] << endl ;
00190                 }
00191                 else {
00192                         w[i] = w[i-1] ^ w[i-4] ;
00193                         //cout << "w[" << i << "] = "<< w[i] << endl ;
00194                 }
00195         }
00196 
00197         //CREATE the ROUND KEYS
00198         for (unsigned i = 0 ; i <= nround ; ++i){
00199                 for (unsigned j = 0 ; j < 4 ; ++j){
00200                         rk[i] = copyIntoKey(rk[i],j*32,w[i*4+j]) ;
00201                 }
00202                 //cout << "rk[" << i << "] = " << rk[i] << endl ;
00203         }
00204         return ;
00205 }
00206 
00210 
00212 
00219 template <unsigned nb_key, unsigned nround>
00220 inline
00221 typename BunnyAES<nb_key,nround>::msgType
00222 BunnyAES<nb_key,nround>::shiftRows (msgType m ) const {
00223         // Shift second row
00224         MoveBits(m, 112, 80, 8) ;
00225         MoveBits(m, 80, 48, 8) ;
00226         MoveBits(m, 48, 16, 8) ;
00227         // Shift third row
00228         MoveBits(m, 104, 40, 8) ;
00229         MoveBits(m, 72, 8, 8) ;
00230         // Shift fourth row
00231         MoveBits(m, 32, 0, 8) ;
00232         MoveBits(m, 64, 32, 8) ;
00233         MoveBits(m, 96, 64, 8) ;
00234         return m ;
00235 }
00236 
00238 
00241 template <unsigned nb_key, unsigned nround>
00242 inline
00243 typename BunnyAES<nb_key,nround>::msgType
00244 BunnyAES<nb_key,nround>::shiftRowsInv (msgType m ) const {
00245         // Shift second row
00246         MoveBits(m, 16, 48, 8) ;
00247         MoveBits(m, 80, 48, 8) ;
00248         MoveBits(m, 112, 80, 8) ;
00249         // Shift third row
00250         MoveBits(m, 104, 40, 8) ;
00251         MoveBits(m, 72, 8, 8) ;
00252         // Shift fourth row
00253         MoveBits(m, 96, 64, 8) ;
00254         MoveBits(m, 64, 32, 8) ;
00255         MoveBits(m, 32, 0, 8) ;
00256         return m ;
00257 }
00258 
00260 
00267 template <unsigned nb_key, unsigned nround>
00268 inline
00269 typename BunnyAES<nb_key,nround>::msgType
00270 BunnyAES<nb_key,nround>::mixColumns (msgType m ) const {
00271         unsigned char col[4] ;
00272         msgType c ;
00273         string msgStr = bitsetToHex(m) ;
00274         string tmp ;
00275 
00276         for (unsigned i = 0 ; i < 4 ; ++i){     //for each column do
00277                 tmp.assign(msgStr,i*8,8) ;              // put in tmp a column as a string
00278                 stringToUchar(tmp,col) ;                // put in col a column as unsigned char
00279                 gmix_column(col) ;                              // mix the column
00280                                                                                 // put in tmp the column mixed
00281                 tmp.assign("") ;
00282                 for (unsigned j = 0 ; j < sizeof(col) ; ++j)
00283                         tmp.append(ucharToString(col[j])) ;
00284                                                                                 //replace the msg
00285                 msgStr.replace(i*8,8,tmp) ;
00286         }
00287         return msgType (hexTo<bitset<128> >(msgStr)) ;
00288 }
00289 
00291 
00294 template <unsigned nb_key, unsigned nround>
00295 inline
00296 typename BunnyAES<nb_key,nround>::msgType
00297 BunnyAES<nb_key,nround>::mixColumnsInv (msgType m ) const {
00298         unsigned char col[4] ;
00299         string  msgStr = bitsetToHex(m) ;
00300         string tmp ;
00301 
00302         for (unsigned i = 0 ; i < 4 ; ++i){     //for each column do
00303                 tmp.assign(msgStr,i*8,8) ;              // put in tmp a column as a string
00304                 stringToUchar(tmp,col) ;                // put in col a column as unsigned char
00305                 gmix_columnInv(col) ;                           // mix the column
00306                                                                                 // put in tmp the column mixed
00307                 tmp.assign("") ;
00308                 for (unsigned j = 0 ; j < sizeof(col) ; ++j)
00309                         tmp.append(ucharToString(col[j])) ;
00310                                                                                 //replace the msg
00311                 msgStr.replace(i*8,8,tmp) ;
00312         }
00313         return msgType (hexTo<bitset<128 > >(msgStr)) ;
00314 }
00315 
00317 
00324 template <unsigned nb_key, unsigned nround>
00325 inline
00326 typename BunnyAES<nb_key,nround>::msgType
00327 BunnyAES<nb_key,nround>::mixingLayer (msgType m ) {
00328         msgType c ;
00329         c = m ;
00330         c = shiftRows(c) ;
00331         c = mixColumns(c) ;
00332         return c ;
00333 }
00334 
00336 
00343 template <unsigned nb_key, unsigned nround>
00344 inline
00345 typename BunnyAES<nb_key,nround>::msgType
00346 BunnyAES<nb_key,nround>::mixingLayerInverse (msgType m ) {
00347         msgType c ;
00348         c = m ;
00349         c = mixColumnsInv(c) ;
00350         c = shiftRowsInv(c) ;
00351         return c ;
00352 }
00353 
00357 
00359 
00368 template <unsigned nb_key, unsigned nround>
00369 inline
00370 typename BunnyAES<nb_key,nround>::msgType
00371 BunnyAES<nb_key,nround>::sBox (msgType m){
00372         msgType c ;
00373         c = m ;
00374         sboxType s ;
00375 
00376         unsigned n = 16 ; // nb_msg / nb_sbox ;
00377         for (unsigned i = 0 ; i < n ; ++i){
00378                 s = extractBlock(i,m) ; // extract nb_sbox bits starting from left to right
00379                 //For AES
00380                 s = sbox(1,s) ; // elaborate the nb_sbox bits extracted
00381                 c = insertBlock(c,i,s) ; // put nb_bit bits in the position i*nb_sbox of the message c
00382         }
00383         return c;
00384 }
00385 
00386 
00388 template <unsigned nb_key, unsigned nround>
00389 inline
00390 typename BunnyAES<nb_key,nround>::msgType
00391 BunnyAES<nb_key,nround>::sBoxInverse (msgType m){
00392         msgType c ;
00393         c = m ;
00394         sboxType s ;
00395 
00396         unsigned n = 16 ; // nb_msg / nb_sbox ;
00397         for (unsigned i = 0 ; i < n ; ++i){
00398                 s = extractBlock(i,m) ; // extract nb_sbox bits starting from left to right
00399                 //For AES
00400                 s = sboxInverse(1,s) ; // elaborate the nb_sbox bits extracted
00401                 c = insertBlock(c,i,s) ; // put nb_bit bits in the position i*nb_sbox of the message c
00402         }
00403         return c;
00404 }
00405 
00407 
00416 template <unsigned nb_key, unsigned nround>
00417 inline
00418 typename BunnyAES<nb_key,nround>::sboxType
00419 BunnyAES<nb_key,nround>::sbox(unsigned nbox, sboxType x) {
00420         int AES_sbox_table [256] = {  99,124,119,123,242,107,111,197, 48,  1,103, 43,254,215,171,118,
00421                                                                  202,130,201,125,250, 89, 71,240,173,212,162,175,156,164,114,192,
00422                                                                  183,253,147, 38, 54, 63,247,204, 52,165,229,241,113,216, 49, 21,
00423                                                                    4,199, 35,195, 24,150,  5,154,  7, 18,128,226,235, 39,178,117,
00424                                                                    9,131, 44, 26, 27,110, 90,160, 82, 59,214,179, 41,227, 47,132,
00425                                                                   83,209,  0,237, 32,252,177, 91,106,203,190, 57, 74, 76, 88,207,
00426                                                                  208,239,170,251, 67, 77, 51,133, 69,249,  2,127, 80, 60,159,168,
00427                                                                   81,163, 64,143,146,157, 56,245,188,182,218, 33, 16,255,243,210,
00428                                                                  205, 12, 19,236, 95,151, 68, 23,196,167,126, 61,100, 93, 25,115,
00429                                                                   96,129, 79,220, 34, 42,144,136, 70,238,184, 20,222, 94, 11,219,
00430                                                                  224, 50, 58, 10, 73,  6, 36, 92,194,211,172, 98,145,149,228,121,
00431                                                                  231,200, 55,109,141,213, 78,169,108, 86,244,234,101,122,174,  8,
00432                                                                  186,120, 37, 46, 28,166,180,198,232,221,116, 31, 75,189,139,138,
00433                                                                  112, 62,181,102, 72,  3,246, 14, 97, 53, 87,185,134,193, 29,158,
00434                                                                  225,248,152, 17,105,217,142,148,155, 30,135,233,206, 85, 40,223,
00435                                                                  140,161,137, 13,191,230, 66,104, 65,153, 45, 15,176, 84,187, 22 };
00436         return sboxType ( AES_sbox_table[x.to_ulong()] );
00437 }
00438 
00440 
00449 template <unsigned nb_key, unsigned nround>
00450 inline
00451 typename BunnyAES<nb_key,nround>::sboxType
00452 BunnyAES<nb_key,nround>::sboxInverse(unsigned nbox, sboxType x) {
00453         int AES_sbox_Inv_table [256] = {  82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,124,227,57,130,155,47,255,135,52,142,67,68,196,222,233,203,84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,46,161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,248,246,100,134,104,152,22,212,164,92,204,93,101,182,146,108,112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,216,171,0,140,188,211,10,247,228,88,5,184,179,69,6,208,44,30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,79,103,220,234,151,242,207,206,240,180,230,115,150,172,116,34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,113,29,41,197,137,111,183,98,14,170,24,190,27,252,86,62,75,198,210,121,32,154,219,192,254,120,205,90,244,31,221,168,51,136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181,74,13,45,229,122,159,147,201,156,239,160,224,59,77,174,42,245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,214,38,225,105,20,99,85,33,12,125 };
00454         return sboxType ( AES_sbox_Inv_table[x.to_ulong()] );
00455 }
 All Classes Functions Variables Typedefs