Bunny2.0
|
00001 00002 00003 00004 00006 //CONSTRUCTORS// 00008 00012 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00013 inline 00014 Bunny<nb_msg, nb_key, nb_sbox,nround>::Bunny(){ 00015 rk.resize(nround+1) ; // allocates memory for the round keys 00016 } 00017 00018 00022 00024 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00025 inline 00026 void Bunny<nb_msg,nb_key,nb_sbox,nround>::printParameter() { 00027 std::cout << "-------------------------------\n" ; 00028 std::cout << "| BUNNY's PARAMETERS are: " << setw (5) << "|\n" ; 00029 std::cout << "| S-box size: " << setw (5) << nb_sbox << "|\n" ; 00030 std::cout << "| Message size: " << setw (5) << nb_msg << "|\n" ; 00031 std::cout << "| Key size: " << setw (5) << nb_key << "|\n" ; 00032 std::cout << "| Number of Rounds:" << setw (5) << nround << "|\n" ; 00033 std::cout << "-------------------------------\n" ; 00034 } 00035 00037 00042 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00043 inline 00044 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::sboxType 00045 Bunny<nb_msg,nb_key,nb_sbox,nround>::extractBlock( unsigned nblk, msgType x ) { 00046 sboxType y ; 00047 for ( unsigned i = 0 ; i < nb_sbox ; ++i) y[i] = x[i+nblk*nb_sbox] ; 00048 return y ; 00049 } 00050 00052 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00053 inline 00054 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::sboxType 00055 Bunny<nb_msg,nb_key,nb_sbox,nround>::extractFromWordToSboxType( unsigned pos, wordType x ) { 00056 sboxType y ; 00057 ASSERT( pos <= (x.size() - y.size()) && pos >= 0, 00058 "Error: trying to extract from a position which is not allowed!" ) ; 00059 pos = x.size() - pos - y.size() ; // this is because x[0] refers to the rightmost bit 00060 // std::copy( x . begin() + pos, x . begin() + pos + y . size(), y.begin() ) ; 00061 for ( unsigned i = 0 ; i < y.size() ; ++i) y[i] = x[i+pos] ; 00062 return y ; 00063 } 00064 00066 00071 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00072 inline 00073 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::msgType 00074 Bunny<nb_msg,nb_key,nb_sbox,nround>::insertBlock( msgType m, unsigned nblk, sboxType x ) { 00075 for (unsigned i = 0 ; i < nb_sbox ; ++i ) m[i+nblk*nb_sbox] = x[i] ; 00076 return m; 00077 } 00078 00080 00085 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00086 inline 00087 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::keyType 00088 Bunny<nb_msg,nb_key,nb_sbox,nround>::copyIntoKey(keyType m, unsigned pos, wordType x){ 00089 pos = m.size() - pos - x.size() ; // this is because x[0] refers to the rightmost bit 00090 for (unsigned i = 0 ; i < x.size() ; ++i ) m[i+pos] = x[i] ; 00091 return m; 00092 } 00093 00095 00101 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00102 inline 00103 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::wordType 00104 Bunny<nb_msg,nb_key,nb_sbox,nround>::copyIntoWord(wordType m, unsigned pos, sboxType x){ 00105 pos = m.size() - pos - x.size() ; // this is because x[0] refers to the rightmost bit 00106 for (unsigned i = 0 ; i < x.size() ; ++i ) m[i+pos] = x[i] ; 00107 return m; 00108 } 00109 00111 00116 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00117 inline 00118 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::wordType 00119 Bunny<nb_msg,nb_key,nb_sbox,nround>::extractWord( unsigned pos, keyType x ) { 00120 wordType y ; 00121 ASSERT( pos <= (x.size() - y.size()) && pos >= 0, 00122 "Error: trying to extract from a position which is not allowed!" ) ; 00123 pos = x.size() - pos - y.size() ; // this is because x[0] refers to the rightmost bit 00124 // std::copy( x . begin() + pos, x . begin() + pos + y . size(), y.begin() ) ; 00125 for ( unsigned i = 0 ; i < y.size() ; ++i) y[i] = x[i+pos] ; 00126 return y ; 00127 } 00128 00129 00133 00135 00140 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00141 inline 00142 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::msgType 00143 Bunny<nb_msg,nb_key,nb_sbox,nround>::encode( msgType m, keyType k ) { 00144 msgType c ; 00145 c = m ; 00146 keySchedule(k) ; 00147 //Round 0, a-tipical 00148 c = addRoundKey(c,rk[0]) ; 00149 //cout << "state at round: 0 --> " << bitsetToHex(c) << endl ; 00150 //Tipical rounds 00151 for (unsigned i = 1 ; i <= nround ; ++i){ 00152 c = sBox(c) ; 00153 //cout << "state after sBox: --> " << bitsetToHex(c) << endl ; 00154 c = mixingLayer(c) ; 00155 //cout << "state after mixL: --> " << bitsetToHex(c) << endl ; 00156 c = addRoundKey(c,rk[i]) ; 00157 //cout << "state at round: " << i << " --> " << bitsetToHex(c) << endl ; 00158 } 00159 return c ; 00160 } 00161 00162 00164 00169 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00170 inline 00171 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::msgType 00172 Bunny<nb_msg,nb_key,nb_sbox,nround>::decode (msgType m, keyType k) { 00173 msgType c ; 00174 c = m ; 00175 //keyschedule 00176 keySchedule(k) ; 00177 //Tipical rounds 00178 for (unsigned i = nround ; i > 0 ; --i){ 00179 c = addRoundKey(c,rk[i]) ; 00180 //cout << "state after add round: " << i << " --> " << bitsetToHex(c) << endl ; 00181 c = mixingLayerInverse(c) ; 00182 //cout << "state after mixLInv: --> " << bitsetToHex(c) << endl ; 00183 c = sBoxInverse(c) ; 00184 //cout << "state after sBoxInv: --> " << bitsetToHex(c) << endl ; 00185 } 00186 //Round 0, a-tipical 00187 c = addRoundKey(c,rk[0]) ; 00188 return c ; 00189 } 00190 00194 00196 00201 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00202 inline 00203 void Bunny<nb_msg,nb_key,nb_sbox,nround>::keySchedule(keyType k) { 00204 //number of word generated 00205 unsigned nword = 80 ;//(nround+10) * 4 ;//to have some more bitsj 00206 //dimension of the blocks that fill the round keys 00207 //i.e.: nrow round keys at a time are filled 00208 unsigned ncol = nb_msg/nb_sbox ; 00209 unsigned nrow = nb_msg/nb_sbox + 1 ; 00210 vector<sboxType> w ; 00211 00212 w.resize(nword) ; // initialize a vector of nword elements of type sboxType, set to 00...0 00213 00214 //CREATE W, a vector of 80 words 00215 //put the key bits in the first 4 words 00216 for (unsigned i = 0 ; i < (nb_msg/nb_sbox) ; ++i){ 00217 w[i] = extractBlock(i,k) ; 00218 } 00219 w[4] = sbox(0,w[0]) ^ w[1]; 00220 w[5] = sbox(1,w[1]) ^ w[2]; 00221 w[6] = sbox(2,w[2]) ^ w[3]; 00222 w[7] = sbox(3,w[3]) ^ w[0]; 00223 00224 for (unsigned i = 8; i < w.size() ; ++i){ 00225 // se i = 0 mod 8 => w[i] = w[i-8] ^ s2(RB(w[i-1])) + 101010 00226 if (i % 8 == 0) w[i] = w[i-8] ^ sbox(1,(w[i-1]<<1)) ^ sboxType (string("101010")) ; 00227 // se i = 4 mod 8 => w[i] = w[i-8] ^ s3(w[i-1]) 00228 else if (i % 8 == 4) w[i] = w[i-8] ^ sbox(2,w[i-1]) ; 00229 // se i != 0 mod 4 w[i] = w[i-8] ^ w[i-1] 00230 else w[i] = w[i-8] ^ w[i-1] ; 00231 } 00232 00233 //CREATE the ROUND KEYS 00234 //0,5,10,15 00235 //1,6,11,16 00236 //2,7,12,17 00237 //3,8,13,18 00238 //4,9,14,19 00239 //.. 00240 //20,25,30,35... 00241 unsigned pos = 0 ; 00242 for (unsigned i = 0 ; i <= nround ; ++i){ 00243 if ( (i % nrow) == 0 ) pos = i * ncol ; 00244 for (unsigned j = 0 ; j < ncol ; ++j){ 00245 //rk[i] = Bunny<nb_msg,nb_key,nb_sbox,nround>::copy(rk[i],j*nb_sbox,w[pos+j*nrow]) ; 00246 } 00247 ++pos ; 00248 } 00249 00250 //Print W 00251 /*cout << endl ; 00252 cout << "k = " << k << endl ; 00253 cout << "W = " << endl ; 00254 for (unsigned i = 0; i < w.size() ; ++i){ 00255 if (i % 4 == 3) cout << " " << w[i] << endl ; 00256 else cout << " " << w[i] ; 00257 }*/ 00258 return ; 00259 } 00260 00264 00266 00273 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00274 inline 00275 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::msgType 00276 Bunny<nb_msg,nb_key,nb_sbox,nround>::addRoundKey (msgType m, msgType k){ 00277 return m ^ k; 00278 } 00279 00283 00285 00294 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00295 inline 00296 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::msgType 00297 Bunny<nb_msg,nb_key,nb_sbox,nround>::sBox (msgType m){ 00298 msgType c = m ; 00299 unsigned n = nb_msg / nb_sbox ; 00300 for (unsigned i = 0 ; i < n ; ++i){ 00301 sboxType s ; 00302 s = extractBlock(i,m) ; // extract nb_sbox bits starting from left to right 00303 s = sbox(i,s) ; // elaborate the nb_sbox bits extracted 00304 c = insertBlock(c,i,s) ; // put nb_bit bits in the position i*nb_sbox of the message c 00305 } 00306 return c; 00307 } 00308 00310 template <unsigned nb_msg, unsigned nb_key, unsigned nb_sbox, unsigned nround> 00311 inline 00312 typename Bunny<nb_msg,nb_key,nb_sbox,nround>::msgType 00313 Bunny<nb_msg,nb_key,nb_sbox,nround>::sBoxInverse (msgType m){ 00314 msgType c = m ; 00315 unsigned n = nb_msg / nb_sbox ; 00316 for (unsigned i = 0 ; i < n ; ++i){ 00317 sboxType s ; 00318 s = extractBlock(i,m) ; // extract nb_sbox bits starting from left to right 00319 s = sboxInverse(i,s) ; // elaborate the nb_sbox bits extracted 00320 c = insertBlock(c,i,s) ; // put nb_bit bits in the position i*nb_sbox of the message c 00321 } 00322 return c; 00323 } 00324