]> AND Private Git Repository - Cipher_code.git/blob - LightweightARM/LWARM/lwarm.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
yes
[Cipher_code.git] / LightweightARM / LWARM / lwarm.cpp
1 //gcc pixmap_io.c  -c 
2 //g++ -O3 one_round_new.cpp pixmap_io.o  -o one_round_new -std=c++11   
3
4 #include <iostream>
5 #include <list>
6 #include<math.h>
7 #include<stdlib.h>
8 #include<stdio.h>
9 #include<string.h>
10 #include <fstream>
11 #include <sys/time.h>
12 #include <arm_neon.h>
13
14 /*#include <cryptopp/hex.h>
15 #include <cryptopp/sha.h>
16 #include <cryptopp/osrng.h>
17 #include <cryptopp/secblock.h>
18 */
19
20
21 extern "C" {
22   int load_RGB_pixmap(char *filename, int *width, int *height, unsigned char**R_data, unsigned char**G_data, unsigned char**B_data);
23   void store_RGB_pixmap(char *filename, unsigned char *R_data, unsigned char *G_data, unsigned char *B_data, int width, int height);
24 }
25
26
27 //using namespace CryptoPP;
28 using namespace std;
29
30
31 int key_size=256;
32 int nb_test=1;
33 int ctr=0;
34
35
36
37
38
39
40
41 typedef unsigned char   uchar;
42
43
44 double TimeStart()
45 {
46   struct timeval tstart;
47   gettimeofday(&tstart,0);
48   return( (double) (tstart.tv_sec + tstart.tv_usec*1e-6) );
49 }
50
51 double TimeStop(double t)
52 {
53   struct timeval tend;
54
55   gettimeofday(&tend,0);
56   t = (double) (tend.tv_sec + tend.tv_usec*1e-6) - t;
57   return (t);
58 }
59
60
61
62
63
64
65 void inverse_tables(uchar *tab, int size_tab,uchar *inv_perm_tabs) {
66
67   for(int i=0;i<size_tab;i++) {
68     inv_perm_tabs[tab[i]] = i;
69   }
70
71 }
72
73 void inverse_tables_int(int *tab, int size_tab,int *inv_perm_tabs) {
74
75   for(int i=0;i<size_tab;i++) {
76     inv_perm_tabs[tab[i]] = i;
77   }
78 }
79
80
81
82 void rc4key(uchar *key, uchar *sc, int size_DK) {
83
84   for(int i=0;i<256;i++) {
85     sc[i]=i;
86   }
87
88
89   uchar j0 = 0;
90   for(int i0=0; i0<256; i0++) {
91     j0 = (j0 + sc[i0] + key[i0%size_DK] )&0xFF;
92     uchar tmp = sc[i0];
93     sc[i0] = sc[j0 ];
94     sc[j0] = tmp;
95   }
96 }
97
98
99
100 void rc4keyperm(uchar *key,int len, int rp,int *sc, int size_DK) {
101
102   //sc=1:len;
103
104
105   
106   for (int i=0;i<len;i++) {
107     sc[i]=i;
108   }
109   for (int it = 0; it < rp; it++) {
110     int j0 = 1;
111     for(int i0 = 0; i0<len; i0++) {
112       j0 = (j0 + sc[i0] + sc[j0] + key[i0%size_DK] )% len;
113       int tmp = sc[i0];
114       sc[i0] = sc[j0];
115       sc[j0] = tmp;
116     }
117
118   }
119 }
120
121 void prga(uchar *sc, int ldata, uchar *r) {
122   uchar i0=0;
123   uchar j0=0;
124
125   for (int it=0; it<ldata; it++) {
126     i0 = ((i0+1)%255);
127     j0 = (j0 + sc[i0])&0xFF;
128     uchar tmp = sc[i0];
129     sc[i0] = sc[j0];
130     sc[j0] = tmp;
131     r[it]=sc[(sc[i0]+sc[j0])&0xFF];
132   }
133 }
134
135
136
137
138 template<int h2>
139 void encrypt_ctr(uchar* seq_in, uchar *seq_out, int len,uchar* RM1,int *Pbox, int *PboxRM, uchar *Sbox1, uchar *Sbox2, int enc) {
140
141
142   uchar *X=new uchar[h2];
143   uchar *fX=new uchar[h2];
144   int ind1,ind2;
145
146   
147    for(int a=0;a<h2;a++) {
148      X[a]=Sbox1[a&0xFF];           //Warning according to the size of h2, we can be outsize of Sbox1[a]
149    }
150
151    
152   for(int it=0;it<len;it++) {
153     if(enc) {
154       ind1=it*h2;
155       ind2=Pbox[it]*h2;
156     }
157     else {
158       ind2=it*h2;
159       ind1=Pbox[it]*h2;
160     }
161        
162
163
164     /*for(int a=0;a<h2;a+=4){
165       fX[a]=RM1[X[a]];
166       fX[a+1]=RM1[X[a+1]];
167       fX[a+2]=RM1[X[a+2]];
168       fX[a+3]=RM1[X[a+3]];
169       }*/
170
171     for(int a=0;a<h2;a+=4){
172       fX[a]=X[a];
173       fX[a+1]=X[a+1];
174       fX[a+2]=X[a+2];
175       fX[a+3]=X[a+3];
176     }
177
178     /*   if(it<513) {
179       for(int a=0;a<h2;a++)
180         printf("%d ",fX[a]);
181       printf("\n");
182       }*/
183     
184     *(int*)&fX[0]^=it;
185
186     /* if(it<513) {
187       for(int a=0;a<h2;a++)
188         printf("%d ",fX[a]);
189       printf("\n");
190       }*/
191
192     for(int a=0;a<h2;a+=4) {
193       fX[a]=fX[a]^RM1[a];
194       fX[a+1]=fX[a+1]^RM1[a+1];
195       fX[a+2]=fX[a+2]^RM1[a+2];
196       fX[a+3]=fX[a+3]^RM1[a+3];
197     }
198
199  
200     for(int a=0;a<h2;a+=4) {
201       fX[a]=Sbox2[fX[a]];
202       fX[a+1]=Sbox2[fX[a+1]];
203       fX[a+2]=Sbox2[fX[a+2]];
204       fX[a+3]=Sbox2[fX[a+3]];
205     }
206     
207      for(int a=0;a<h2;a+=4) {
208       fX[a]=fX[a]^seq_in[ind2+a];
209       fX[a+1]=fX[a+1]^seq_in[ind2+a+1];
210       fX[a+2]=fX[a+2]^seq_in[ind2+a+2];
211       fX[a+3]=fX[a+3]^seq_in[ind2+a+3];
212     }
213
214  
215     for(int a=0;a<h2;a+=4) {
216       seq_out[ind1+a]=fX[a];
217       seq_out[ind1+a+1]=fX[a+1];
218       seq_out[ind1+a+2]=fX[a+2];
219       seq_out[ind1+a+3]=fX[a+3];
220     }
221     
222     for(int a=0;a<h2;a+=4) {
223       RM1[a]=RM1[PboxRM[a]];
224       RM1[a+1]=RM1[PboxRM[a+1]];
225       RM1[a+2]=RM1[PboxRM[a+2]];
226       RM1[a+3]=RM1[PboxRM[a+3]];
227     }
228
229
230     
231   }
232
233
234 }
235
236
237 template<int h2>
238 void encrypt(uchar* seq_in, uchar *seq_out, int len,uchar* RM1,int *Pbox, int *PboxRM, uchar *Sbox1, uchar *Sbox2, int debug) {
239
240
241   uchar *X=new uchar[h2];
242   uchar *fX=new uchar[h2];
243   unsigned int *lX=(unsigned int*)X;
244   unsigned int *lseq_in=(unsigned int*)seq_in;
245
246
247   for(int it=0;it<len;it++) {
248     int ind1=it*h2;
249     int ind2=Pbox[it]*h2;
250
251     for(int a=0;a<h2;a+=4) {
252       X[a]=seq_in[ind2+a];
253       X[a+1]=seq_in[ind2+a+1];
254       X[a+2]=seq_in[ind2+a+2];
255       X[a+3]=seq_in[ind2+a+3];
256     }
257
258     for(int a=0;a<h2;a+=4){
259       fX[a]=Sbox1[X[a]];
260       fX[a+1]=Sbox1[X[a+1]];
261       fX[a+2]=Sbox1[X[a+2]];
262       fX[a+3]=Sbox1[X[a+3]];
263     }
264
265
266     for(int a=0;a<h2;a+=4) {
267       fX[a]=fX[a]^RM1[a];
268       fX[a+1]=fX[a+1]^RM1[a+1];
269       fX[a+2]=fX[a+2]^RM1[a+2];
270       fX[a+3]=fX[a+3]^RM1[a+3];
271     }
272
273
274     for(int a=0;a<h2;a+=4) {
275       seq_out[ind1+a]=Sbox2[fX[a]];
276       seq_out[ind1+a+1]=Sbox2[fX[a+1]];
277       seq_out[ind1+a+2]=Sbox2[fX[a+2]];
278       seq_out[ind1+a+3]=Sbox2[fX[a+3]];
279     }
280
281     for(int a=0;a<h2;a+=4) {
282       RM1[a]=RM1[PboxRM[a]];
283       RM1[a+1]=RM1[PboxRM[a+1]];
284       RM1[a+2]=RM1[PboxRM[a+2]];
285       RM1[a+3]=RM1[PboxRM[a+3]];
286
287     }
288
289
290   }
291
292
293
294
295 }
296
297
298 template<int h2>
299 void decrypt(uchar* seq_in, uchar *seq_out, int len,uchar* RM1,int *Pbox, int *PboxRM, uchar *Sbox1, uchar *Sbox2, int debug) {
300
301
302   uchar *fX=new uchar[h2];
303
304
305   uchar *Inv_Sbox1=new uchar[256];
306   inverse_tables(Sbox1,256,Inv_Sbox1);
307
308   uchar *Inv_Sbox2=new uchar[256];
309   inverse_tables(Sbox2,256,Inv_Sbox2);
310   
311
312
313
314   for(int it=0;it<len;it++) {
315
316     int ind1=it*h2;
317     int ind2=Pbox[it]*h2;
318
319
320
321
322     for(int a=0;a<h2;a+=4) {
323       fX[a]=seq_in[ind1+a];
324       fX[a+1]=seq_in[ind1+a+1];
325       fX[a+2]=seq_in[ind1+a+2];
326       fX[a+3]=seq_in[ind1+a+3];
327             
328     }
329     for(int a=0;a<h2;a+=4) {
330       fX[a]=Inv_Sbox2[fX[a]];
331       fX[a+1]=Inv_Sbox2[fX[a+1]];
332       fX[a+2]=Inv_Sbox2[fX[a+2]];
333       fX[a+3]=Inv_Sbox2[fX[a+3]];
334     }
335     for(int a=0;a<h2;a+=4) {
336       fX[a]=fX[a]^RM1[a];
337       fX[a+1]=fX[a+1]^RM1[a+1];
338       fX[a+2]=fX[a+2]^RM1[a+2];
339       fX[a+3]=fX[a+3]^RM1[a+3];
340     }
341
342     for(int a=0;a<h2;a+=4) {
343       RM1[a]=RM1[PboxRM[a]];
344       RM1[a+1]=RM1[PboxRM[a+1]];
345       RM1[a+2]=RM1[PboxRM[a+2]];
346       RM1[a+3]=RM1[PboxRM[a+3]];
347     }
348     
349     for(int a=0;a<h2;a+=4) {
350       seq_out[ind2+a]=Inv_Sbox1[fX[a]];
351       seq_out[ind2+a+1]=Inv_Sbox1[fX[a+1]];
352       seq_out[ind2+a+2]=Inv_Sbox1[fX[a+2]];
353       seq_out[ind2+a+3]=Inv_Sbox1[fX[a+3]];
354     }
355
356      
357   }
358
359
360 }
361
362 uchar sbox[256] =   {
363   //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
364   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
365   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
366   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
367   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
368   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
369   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
370   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
371   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
372   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
373   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
374   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
375   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
376   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
377   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
378   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
379   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
380
381
382 int Rcon[255] = {
383   0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
384   0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
385   0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
386   0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
387   0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
388   0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
389   0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
390   0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
391   0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
392   0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
393   0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
394   0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
395   0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
396   0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
397   0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
398   0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb
399 };
400
401
402
403 void KeyExpansion(uchar *RoundKey, uchar *key, int NN )
404 {
405   int i,j;
406   uchar temp[4],k;
407   int Nk = NN / 32;
408   int Nr = Nk + 6;
409
410   // The first round key is the key itself.
411   for(i=0;i<Nk;i++)
412     {
413       RoundKey[i*4]=key[i*4];
414       RoundKey[i*4+1]=key[i*4+1];
415       RoundKey[i*4+2]=key[i*4+2];
416       RoundKey[i*4+3]=key[i*4+3];
417     }
418
419   // All other round keys are found from the previous round keys.
420   while (i < 256)
421     {
422       for(j=0;j<4;j++)
423         {
424           temp[j]=RoundKey[(i-1) * 4 + j];
425         }
426       if (i % Nk == 0)
427         {
428           // This function rotates the 4 bytes in a word to the left once.
429           // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
430
431           // Function RotWord()
432           {
433             k = temp[0];
434             temp[0] = temp[1];
435             temp[1] = temp[2];
436             temp[2] = temp[3];
437             temp[3] = k;
438           }
439
440           // SubWord() is a function that takes a four-byte input word and
441           // applies the S-box to each of the four bytes to produce an output word.
442
443           // Function Subword()
444           {
445             temp[0]=sbox[temp[0]];
446             temp[1]=sbox[temp[1]];
447             temp[2]=sbox[temp[2]];
448             temp[3]=sbox[temp[3]];
449           }
450
451           temp[0] =  temp[0] ^ Rcon[i/Nk];
452         }
453       else if (Nk > 6 && i % Nk == 4)
454         {
455           // Function Subword()
456           {
457             temp[0]=sbox[temp[0]];
458             temp[1]=sbox[temp[1]];
459             temp[2]=sbox[temp[2]];
460             temp[3]=sbox[temp[3]];
461           }
462         }
463       RoundKey[i*4+0] = RoundKey[(i-Nk)*4+0] ^ temp[0];
464       RoundKey[i*4+1] = RoundKey[(i-Nk)*4+1] ^ temp[1];
465       RoundKey[i*4+2] = RoundKey[(i-Nk)*4+2] ^ temp[2];
466       RoundKey[i*4+3] = RoundKey[(i-Nk)*4+3] ^ temp[3];
467       i++;
468     }
469
470   printf("i %d\n",i);
471 }
472
473
474
475
476
477
478
479
480 #define key_size 256
481
482 uint8_t enc_key[key_size];
483
484
485
486
487
488
489 void AES_encrypt(const uint8_t *in, uint8_t *out, const uint8x16_t  *rdkeys, unsigned int rounds, int val_i,char** target)
490 {
491
492
493
494
495   // Load the block
496   uint8x16_t data = vld1q_u8(in);
497   uint8x16_t tmp;
498
499
500
501   uint64x2_t v1=vdupq_n_u64(val_i);
502
503   uint8x16_t key=reinterpret_cast<uint8x16_t>(v1);
504
505
506
507
508   tmp = veorq_u8(key, rdkeys[0]);
509   /*
510     if(val_i<1) {
511         static uint8_t p[16];
512
513         vst1q_u8 (p, key);
514
515         for(int i=0;i<16;i++)
516         *target += sprintf(*target, "%d ", p[i]);
517         *target += sprintf(*target, "\n ");
518
519         vst1q_u8 (p, rdkeys[0]);
520
521         for(int i=0;i<16;i++)
522         *target += sprintf(*target, "%d ", p[i]);
523         *target += sprintf(*target, "\n ");
524
525     }
526   */
527
528   // AES encryption with ARM intrinsics:
529   // rnds-1 (9 for AES128) cycles of AES:
530   // (Add, Shift, Sub) plus Mix Columns
531   unsigned int i;
532   for (i=1; i<rounds; ++i)
533     {
534       // AES single round encryption
535       tmp = vaeseq_u8(tmp, rdkeys[i]);
536       // AES mix columns
537       tmp = vaesmcq_u8(tmp);
538
539     }
540
541
542
543   tmp = veorq_u8(tmp, data);
544
545
546
547   vst1q_u8(out, tmp);
548
549
550
551 }
552
553
554
555 __attribute__((always_inline))
556 uint32x4_t _mm_shuffle_epi32_splat(uint32x4_t a)
557 {
558   return vdupq_n_u32(vgetq_lane_u32(a, 3));
559 }
560
561 __attribute__((always_inline))
562 uint8x16_t _mm_slli_si128(uint8x16_t a, int imm ) {
563   //return (int8x16_t) vextq_s8(vdupq_n_s8(0), (int8x16_t)a, 16 - (imm));
564   return (vextq_u8(vdupq_n_u8(0), a, 12));
565 }
566
567 __attribute__((always_inline))
568 uint8x16_t _mm_xor_si128(uint8x16_t a, uint8x16_t b)
569 {
570   return veorq_u8(a, b);
571 }
572
573 __attribute__((always_inline))
574 void print128_num(uint8x16_t v) {
575   uint8_t p[16];
576   vst1q_u8 (p, v);
577
578   for(int j=0;j<16;j++) {
579     cout<<(int)p[j]<<" ";
580   }
581   cout<<endl;
582
583 }
584
585
586 __attribute__((always_inline))
587 uint8x16_t AES_128_key_exp(uint8x16_t key, int val){
588
589   uint64x2_t v1=vdupq_n_u64(val);
590   cout<<"val "<<val;
591   uint8x16_t keygened=reinterpret_cast<uint8x16_t>(v1);
592   print128_num(keygened);
593   //  cout<<"keygened "<<keygened;
594   keygened = (uint8x16_t) _mm_shuffle_epi32_splat(keygened);
595
596   cout<<" la "<<endl;  
597   print128_num(key);
598   
599   key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
600   key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
601   key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
602   key = _mm_xor_si128(key, keygened);
603   cout<<" la2 "<<endl;  
604   print128_num(keygened);
605
606   return key; 
607 }
608
609
610 __attribute__((always_inline))
611 void aes128_load_key_enc_only(uint8_t *enc_key, uint8x16_t *key_schedule) {
612   key_schedule[0] = vld1q_u8(enc_key);
613   key_schedule[1] = AES_128_key_exp(key_schedule[0], 0x01);
614   key_schedule[2] = AES_128_key_exp(key_schedule[1], 0x02);
615   key_schedule[3] = AES_128_key_exp(key_schedule[2], 0x04);
616   key_schedule[4] = AES_128_key_exp(key_schedule[3], 0x08);
617   key_schedule[5] = AES_128_key_exp(key_schedule[4], 0x10);
618   key_schedule[6] = AES_128_key_exp(key_schedule[5], 0x20);
619   key_schedule[7] = AES_128_key_exp(key_schedule[6], 0x40);
620   key_schedule[8] = AES_128_key_exp(key_schedule[7], 0x80);
621   key_schedule[9] = AES_128_key_exp(key_schedule[8], 0x1B);
622   key_schedule[10] = AES_128_key_exp(key_schedule[9], 0x36);
623   key_schedule[11] = AES_128_key_exp(key_schedule[10], 0x51);
624   key_schedule[12] = AES_128_key_exp(key_schedule[11], 0x6C);
625   key_schedule[13] = AES_128_key_exp(key_schedule[12], 0x87);
626   key_schedule[14] = AES_128_key_exp(key_schedule[13], 0xA2);
627   key_schedule[15] = AES_128_key_exp(key_schedule[14], 0xBD);
628 }
629
630
631 void AES_encrypt4(const uint8_t *in, uint8_t *out, const uint8x16_t *rdkeys, unsigned int rounds, int val_i,char** target)
632 {
633
634
635
636
637   // Load the block
638   uint8x16_t data1 = vld1q_u8(in);
639   uint8x16_t data2 = vld1q_u8(in+16);
640   uint8x16_t data3 = vld1q_u8(in+32);
641   uint8x16_t data4 = vld1q_u8(in+48);
642   uint8x16_t tmp1,tmp2,tmp3,tmp4;
643
644
645
646   uint64x2_t v1=vdupq_n_u64(val_i);
647   uint8x16_t key1=reinterpret_cast<uint8x16_t>(v1);
648   v1=vdupq_n_u64(val_i+1);
649   uint8x16_t key2=reinterpret_cast<uint8x16_t>(v1);
650   v1=vdupq_n_u64(val_i+2);
651   uint8x16_t key3=reinterpret_cast<uint8x16_t>(v1);
652   v1=vdupq_n_u64(val_i+3);
653   uint8x16_t key4=reinterpret_cast<uint8x16_t>(v1);
654
655   tmp1 = veorq_u8(key1, rdkeys[0]);
656   tmp2 = veorq_u8(key2, rdkeys[0]);
657   tmp3 = veorq_u8(key3, rdkeys[0]);
658   tmp4 = veorq_u8(key4, rdkeys[0]);
659
660
661   // AES encryption with ARM intrinsics:
662   // rnds-1 (9 for AES128) cycles of AES:
663   // (Add, Shift, Sub) plus Mix Columns
664   unsigned int i;
665   for (i=1; i<rounds; ++i)
666     {
667       // AES single round encryption
668       tmp1 = vaeseq_u8(tmp1, rdkeys[i]);
669       // AES mix columns
670       tmp1 = vaesmcq_u8(tmp1);
671       tmp2 = vaeseq_u8(tmp2, rdkeys[i]);
672       tmp2 = vaesmcq_u8(tmp2);
673       tmp3 = vaeseq_u8(tmp3, rdkeys[i]);
674       tmp3 = vaesmcq_u8(tmp3);
675       tmp4 = vaeseq_u8(tmp4, rdkeys[i]);
676       tmp4 = vaesmcq_u8(tmp4);
677
678
679     }
680
681
682
683   tmp1 = veorq_u8(tmp1, data1);
684   vst1q_u8(out, tmp1);
685   tmp2 = veorq_u8(tmp2, data2);
686   vst1q_u8(out+16, tmp2);
687   tmp3 = veorq_u8(tmp3, data3);
688   vst1q_u8(out+32, tmp3);
689   tmp4 = veorq_u8(tmp4, data4);
690   vst1q_u8(out+48, tmp4);
691
692
693
694 }
695
696
697
698
699
700
701
702
703 int main(int argc, char** argv) {
704
705
706   int h=32;
707   int lena=0;
708   int size_buf=1;
709
710   int NN=128;
711
712   unsigned char RoundKey[256];
713   for(int i=0;i<256;i++) {
714     RoundKey[i]=0;
715   }
716   
717   for(int i=1; i<argc; i++){
718     if(strncmp(argv[i],"nb",2)==0)    nb_test = atoi(&(argv[i][2]));    //nb of test         
719     if(strncmp(argv[i],"ctr",3)==0) ctr = atoi(&(argv[i][3]));          //CTR ? 1  otherwise CBC like
720     if(strncmp(argv[i],"h",1)==0) h = atoi(&(argv[i][1]));          //CTR ? 1  otherwise CBC like
721     if(strncmp(argv[i],"sizebuf",7)==0) size_buf = atoi(&(argv[i][7]));          //SIZE of the buffer
722     if(strncmp(argv[i],"lena",4)==0) lena = atoi(&(argv[i][4]));          //Use Lena or buffer
723   }
724
725   printf("nb times %d\n",nb_test);
726   printf("ctr %d\n",ctr);
727   printf("h %d\n",h);
728   printf("lena %d\n",lena);
729   printf("size_buf %d\n",size_buf);
730
731   int h2=h*h;
732   
733
734       
735   int seed=time(NULL);
736   seed=12;
737   cout<<seed<<endl;
738   srand48(seed);
739
740   uchar Secretkey[key_size];
741
742   uchar counter[key_size];
743
744   for(int i=0;i<key_size;i++) {
745     Secretkey[i]=0;//lrand48()&0xFF;
746     counter[i]=0;//lrand48()&0xFF;
747   }
748
749
750   uint8x16_t *rdkeys=(uint8x16_t *)malloc(sizeof(uint8x16_t)*16);
751
752   char mystr[10000];
753   char *target = mystr;
754
755
756
757
758   uint8_t *enc_key = (uint8_t *)malloc(sizeof(uint8_t) * 16);
759   for (int i = 0; i < 16; i++) {
760     enc_key[i] = lrand48() & 0xFF;
761     //    cout<<(int)enc_key[i]<<endl;
762   }
763
764   //aes128_load_key_enc_only(enc_key, rdkeys);
765
766
767   KeyExpansion(RoundKey, enc_key, NN);
768
769
770   for (size_t i=0; i<256/16; ++i) {
771     rdkeys[i] = vld1q_u8(&RoundKey[i*16]);
772     print128_num(rdkeys[i]);
773   }
774
775
776   
777   
778   /*  cout<<"start of useless computation"<<endl;
779   double dummy=0;
780   for(int i=0;i<40000000;i++) {
781     dummy+=0.000000001*log(i+10);
782   }
783   cout<<"end of useless computation"<<dummy<<endl;
784   */
785   
786   int size = 64;
787   uchar DK[size];
788
789
790
791
792   int width;
793   int height;
794
795   uchar *data_R, *data_G, *data_B;
796   int imsize;
797   uchar *buffer;
798   
799   if(lena==1) {
800     load_RGB_pixmap("lena.ppm", &width, &height, &data_R, &data_G, &data_B);
801     imsize=width*height*3;
802 //  load_RGB_pixmap("No_ecb_mode_picture.ppm", &width, &height, &data_R, &data_G, &data_B);
803   }
804   else {
805     width=height=size_buf;
806     imsize=width*height;
807     buffer=new uchar[imsize];
808     for(int i=0;i<imsize;i++) {
809       buffer[i]=lrand48();
810     }
811   }
812
813
814
815   
816   
817   uchar* seq= new uchar[imsize];
818   uchar* seq2= new uchar[imsize];
819
820   for(int i=0;i<imsize;i++) {
821     seq2[i]=0;
822   }
823   
824   int oneD=width*height;
825   if(lena) {
826     for(int i=0;i<oneD;i++) {
827       seq[i]=data_R[i];
828       seq[oneD+i]=data_G[i];
829       seq[2*oneD+i]=data_B[i];
830     }
831   }
832   else {
833     for(int i=0;i<oneD;i++) {
834       seq[i]=buffer[i];
835     }
836   }
837
838
839
840   
841
842   int total_len=imsize;
843   int rp=1;
844   int len= total_len;
845
846
847   cout<<"len "<<len<<endl;
848   
849   uchar *mix=new uchar[256];
850
851
852
853     
854   for (int i = 0; i < 256 ; i++) {
855     mix[i]=Secretkey[i]^counter[i];
856   }
857
858   
859   cout<<"hash "<<endl;
860   for (int i = 0; i < 64 ; i++) {
861 //    DK[i]=digest[i];
862     DK[i]=mix[i];
863   }
864
865
866
867   
868   uchar Sbox1[256];
869   rc4key(DK, Sbox1, 16);
870
871   uchar Sbox2[256];
872   rc4key(&DK[16], Sbox2, 16);
873
874
875   
876   uchar sc[256];
877   rc4key(&DK[32], sc, 16);
878   
879   uchar outd[2*(h * h)];
880   prga(sc, 2*(h * h), outd);
881
882
883   uchar RM1[h*h];
884   uchar RM2[h*h];
885   for(int i=0;i<h2;i++){
886     RM1[i]=outd[i];
887     RM2[i]=outd[i+h2];
888   }
889               
890
891
892   
893     
894   
895   uchar keyp[16];
896   for (int i = 48; i < 64; i++)
897     keyp[i-48] = DK[i];
898
899 //  cout<<len<<endl;
900   int *Pbox=new int[len];
901   int *PboxRM=new int[h2];
902
903   rc4keyperm(keyp, len, rp, Pbox, 16);
904
905   printf("len %d\n",len);
906   for(int i=0;i<len;i++) {
907 //    printf("%d \n",Pbox[i]);
908   }
909   
910   rc4keyperm(RM2, h2, rp, PboxRM, h2);
911
912   for(int i=0;i<h2;i++){
913     RM2[i]=RM1[i];
914   }
915   int *Inv_Pbox=new int[len];
916   inverse_tables_int(Pbox,len,Inv_Pbox);
917   
918  
919  double time=0;
920   double t=TimeStart();
921
922   int i;
923
924   const int ROUNDS=10;
925   for(int a=0;a<nb_test;a++) {
926     for(int i=0;i<len/16/4;i++) {
927       AES_encrypt4((uint8_t *)&seq[i*64], (uint8_t *)&seq2[i*64], rdkeys, ROUNDS,i, &target);
928     }
929   }
930
931
932   time+=TimeStop(t);
933   cout<<"Time encrypt "<<time<<endl;
934
935
936   if(lena) {
937     for(int i=0;i<oneD;i++) {
938       data_R[i]=seq2[i];
939       data_G[i]=seq2[oneD+i];
940       data_B[i]=seq2[2*oneD+i];
941     }
942     store_RGB_pixmap("lena2.ppm", data_R, data_G, data_B, width, height);
943   }
944   
945
946
947   for(int i=0;i<imsize;i++) {
948     seq[i]=0;
949   }
950
951   
952   time=0;
953   t=TimeStart();
954   
955   for(int a=0;a<nb_test;a++) {
956     for(int i=0;i<len/16/4;i++) {
957       AES_encrypt4((uint8_t *)&seq2[i*64], (uint8_t *)&seq[i*64], rdkeys, ROUNDS,i, &target);
958     }
959   }
960
961
962
963   time+=TimeStop(t);
964   cout<<"Time decrypt "<<time<<endl;
965
966   if(lena) {
967     for(int i=0;i<oneD;i++) {
968       data_R[i]=seq[i];
969       data_G[i]=seq[oneD+i];
970       data_B[i]=seq[2*oneD+i];
971     }
972     store_RGB_pixmap("lena3.ppm", data_R, data_G, data_B, width, height);
973   }
974   else {
975     bool equal=true;
976     for(int i=0;i<imsize;i++) {
977       if(buffer[i]!=seq[i])
978         equal=false;
979     }
980     cout<<"RESULT CORRECT: "<<equal<<endl;
981   }
982   
983
984
985   return 0;
986 }