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

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