Bunny2.0
|
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 }