]> AND Private Git Repository - Cipher_code.git/blob - OneRoundIoT/Delta/scprng.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Merge branch 'master' of ssh://info.iut-bm.univ-fcomte.fr/Cipher_code
[Cipher_code.git] / OneRoundIoT / Delta / scprng.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <sys/time.h>
5 #include<string.h>
6
7 typedef unsigned char uchar;
8
9
10
11
12 typedef uint64_t u8;
13
14 extern "C" {
15   int load_RGB_pixmap(char *filename, int *width, int *height, unsigned char**R_data, unsigned char**G_data, unsigned char**B_data);
16   void store_RGB_pixmap(char *filename, unsigned char *R_data, unsigned char *G_data, unsigned char *B_data, int width, int height);
17 }
18 using namespace std;
19
20
21
22 typedef struct sfcctx { u8 a; u8 b; u8 c; u8 count; } sfcctx;
23 #define rot64(x,k) (((x)<<(k))|((x)>>(64-(k))))
24
25 #define rotation  24
26 #define right_shift 11
27 #define left_shift 3
28
29
30 static inline u8 sfc( sfcctx *x ) {
31   u8 tmp = x->a + x->b + x->count++;
32   x->a = x->b ^ (x->b >> right_shift);
33   x->b = x->c + (x->c << left_shift);
34   x->c = rot64(x->c, rotation) + tmp;
35   return tmp;
36 }
37
38 static inline void sfcinit(sfcctx *x, uint64_t seed) {
39   x->a = seed;
40   x->b = seed;
41   x->c = seed;
42   x->count = 1;
43   for(int i=0;i<12;i++)
44     sfc(x);
45 }
46
47
48
49 typedef struct ranctx { u8 a; u8 b; u8 c; u8 d; } ranctx;
50
51
52
53 static inline u8 jsf( ranctx *x ) {
54   u8 e = x->a - rot64(x->b, 7);
55   x->a = x->b ^ rot64(x->c, 13);
56   x->b = x->c + rot64(x->d, 37);
57   x->c = x->d + e;
58   x->d = e + x->a;
59   return x->d;
60 }
61
62 static inline void jsfinit(ranctx *x, uint64_t seed) {
63   x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
64 }
65
66
67
68
69
70
71
72
73
74 inline uint64_t xorshift64( const uint64_t state)
75 {
76   uint64_t x = state;
77   x^= x << 13;
78   x^= x >> 7;
79   x^= x << 17;
80   return x;
81 }
82
83 static inline uint64_t splitmix64_stateless(uint64_t index) {
84   uint64_t z = (index + UINT64_C(0x9E3779B97F4A7C15));
85   z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9);
86   z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB);
87   return z ^ (z >> 31);
88 }
89
90
91 struct sulong2  {
92   uint64_t x;
93   uint64_t y;
94 };
95
96 typedef struct sulong2 ulong2;
97   
98 static inline uint64_t rotl(const uint64_t x, int k) {
99   return (x << k) | (x >> (64 - k));
100 }
101
102 // call this one before calling xoroshiro128plus
103 static inline void xoroshiro128plus_seed(ulong2 *xoro,uint64_t seed) {
104   xoro->x = splitmix64_stateless(seed);
105   xoro->y = splitmix64_stateless(seed + 1);
106 }
107
108 // returns random number, modifies xoroshiro128plus_s
109 static inline uint64_t xoroshiro128plus(ulong2 *xoro) {
110   const uint64_t s0 = xoro->x;
111   uint64_t s1 = xoro->y;
112   const uint64_t result = s0 + s1;
113
114   s1 ^= s0;
115   xoro->x = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
116   xoro->y = rotl(s1, 36);                   // c
117
118   return result;
119 }
120
121
122
123
124
125
126 double TimeStart()
127 {
128   struct timeval tstart;
129   gettimeofday(&tstart,0);
130   return( (double) (tstart.tv_sec + tstart.tv_usec*1e-6) );
131 }
132
133 double TimeStop(double t)
134 {
135   struct timeval tend;
136
137   gettimeofday(&tend,0);
138   t = (double) (tend.tv_sec + tend.tv_usec*1e-6) - t;
139   return (t);
140 }
141
142
143 uint xorshift32(const uint t)
144 {
145   /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
146   uint x = t;
147   x ^= x << 13;
148   x ^= x >> 17;
149   x ^= x << 5;
150   return x;
151 }
152
153
154
155
156
157 void rc4key(uchar *key, uchar *sc, int size_DK) {
158
159   for(int i=0;i<256;i++) {
160     sc[i]=i;
161   }
162
163
164   uchar j0 = 0;
165   for(int i0=0; i0<256; i0++) {
166     j0 = (j0 + sc[i0] + key[i0%size_DK] )&0xFF;
167     uchar tmp = sc[i0];
168     sc[i0] = sc[j0 ];
169     sc[j0] = tmp;
170   }
171 }
172
173
174 void rc4keyperm(uchar *key,int len, int rp,int *sc, int size_DK) {
175
176   //sc=1:len;
177
178
179
180   for (int i=0;i<len;i++) {
181     sc[i]=i;
182   }
183   for (int it = 0; it < rp; it++) {
184     int j0 = 1;
185     for(int i0 = 0; i0<len; i0++) {
186       j0 = (j0 + sc[i0] + sc[j0] + key[i0%size_DK] )% len;
187       int tmp = sc[i0];
188       sc[i0] = sc[j0];
189       sc[j0] = tmp;
190     }
191
192   }
193 }
194
195 #define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r))))
196 #define ROL64(x,r) (((x)<<(r))|((x)>>(64-(r))))
197 #define R(x,y,k) (x=ROR64(x,18), x+=y, x^=k, y=ROL64(y,13), y^=x)
198
199
200
201 void scprng(uint64_t *plain, uint64_t* cipher, int bufsize, int nb_bloc, uint64_t *Val, uint64_t* Val2,uchar *Sbox1, uchar *Sbox2, uchar * Sbox3, uchar *Sbox4, int *Pbox, int *Pbox2, int *Pbox3, int *Pbox4, uchar *DK, int delta) {
202   int update=0;
203
204   
205   
206   for(int nb=0;nb<nb_bloc;nb++) {
207
208     // #pragma omp parallel   
209     for(int j=0;j<bufsize;j++) {
210       //Val[j]=splitmix64_stateless(Val[j])^Val[Pbox[j]];
211       //Val[j]=xorshift64(Val[j])^Val[Pbox[j]];  //fail
212 //      Val[j]=xorshift64(Val[j])^Val[Pbox[j]]^Val[Pbox2[j]];
213
214       Val2[j]=xorshift64(Val[j])^Val[Pbox[j]]^Val[Pbox2[j]];      
215       //Val[j]=xoroshiro128plus(&xoro[j])^Val[Pbox[j]];
216       //Val[j]=jsf(&ctx[j])^Val[Pbox[j]];  //good
217       //Val[j]=sfc(&sfcd[j])^Val[Pbox[j]];  //good
218     }
219
220
221     
222     for(int j=0;j<bufsize;j++) {
223       Val[j]=ROR64(Val2[j],Pbox[j]&63);
224       cipher[nb*bufsize+j]=Val[j]^plain[nb*bufsize+j];
225     }
226   
227
228
229     
230     if(update==delta) {
231       update=0;
232       /*      uchar *ptr=(uchar*)Val;
233       for(int j=0;j<bufsize*8;j++)
234         ptr[j]^=Sbox2[Sbox1[ptr[j]+DK[j&63]]];
235       */
236
237       for(int j=0;j<bufsize;j++) {
238         Val[j]=R(Val[j],Val[Pbox[j]],Val[Pbox2[j]]);
239       }
240
241       /*      
242       for(int j=0;j<256;j++)
243         Sbox1[j]=Sbox3[Sbox1[j]];
244
245       for(int j=0;j<256;j++)
246         Sbox2[j]=Sbox4[Sbox2[j]];
247
248       for(int j=0;j<256;j++)
249         Sbox3[j]=Sbox4[Sbox3[j]];
250       */
251
252       for(int j=0;j<bufsize;j++)
253         Pbox[j]=Pbox3[Pbox[j]];
254
255       for(int j=0;j<bufsize;j++)
256         Pbox2[j]=Pbox4[Pbox2[j]];
257
258       for(int j=0;j<bufsize;j++)
259         Pbox3[j]=Pbox4[Pbox3[j]];
260
261
262       
263     }
264     else
265       update++;
266   }
267   
268
269   
270 }
271
272
273 int main(int argc, char **argv) {
274 //  printf("%d %d \n",sizeof(__uint64_t),sizeof(ulong));
275
276
277   uint nb_test=1;
278   
279   int width;
280   int height;
281   uchar *data_R, *data_G, *data_B;
282   int imsize;
283   uchar *buffer;
284
285   int size_buf=128;
286   
287   int lena=0;
288   int h=128;
289   for(int i=1; i<argc; i++){
290     if(strncmp(argv[i],"nb",2)==0)    nb_test = atoi(&(argv[i][2]));    //nb of test         
291     if(strncmp(argv[i],"h",1)==0) h = atoi(&(argv[i][1]));          //size of block
292     if(strncmp(argv[i],"sizebuf",7)==0) size_buf = atoi(&(argv[i][7]));          //SIZE of the buffer
293     if(strncmp(argv[i],"lena",4)==0) lena = atoi(&(argv[i][4]));          //Use Lena or buffer
294   }
295
296
297
298
299
300   
301
302    if(lena==1) {
303     load_RGB_pixmap("lena.ppm", &width, &height, &data_R, &data_G, &data_B);
304 //    load_RGB_pixmap("8192.ppm", &width, &height, &data_R, &data_G, &data_B);
305     imsize=width*height*3;
306 //  load_RGB_pixmap("No_ecb_mode_picture.ppm", &width, &height, &data_R, &data_G, &data_B);
307   }
308   else {
309     width=height=size_buf;
310     imsize=width*height;
311     buffer=new uchar[imsize];
312     for(int i=0;i<imsize;i++) {
313       buffer[i]=lrand48();
314     }
315   }
316
317
318   uchar* seq= new uchar[imsize];
319   uchar* seq2= new uchar[imsize];
320
321   int oneD=width*height;
322   if(lena) {
323     for(int i=0;i<oneD;i++) {
324       seq[i]=data_R[i];
325       seq[oneD+i]=data_G[i];
326       seq[2*oneD+i]=data_B[i];
327     }
328   }
329   else {
330     for(int i=0;i<oneD;i++) {
331       seq[i]=buffer[i];
332     }
333   }
334
335   uint64_t *SEQ=(uint64_t*)seq;
336   uint64_t *SEQ2=(uint64_t*)seq2;
337
338   
339   
340   uint64_t val=1021;
341   uint64_t val2=1021;
342
343   uint r1=21,r2=93;
344
345   uchar DK[64];
346   for(int i=0;i<64;i++)
347     DK[i]=splitmix64_stateless(i);
348
349
350   uchar Sbox1[256];
351   uchar Sbox2[256];
352   uchar Sbox3[256];
353   uchar Sbox4[256];
354   rc4key(DK, Sbox1, 8);
355   rc4key(&DK[8], Sbox2, 8);
356   rc4key(&DK[16], Sbox3, 8);
357   rc4key(&DK[24], Sbox4, 8);
358
359   int Pbox[h];
360   int Pbox2[h];
361   int Pbox3[h];
362   int Pbox4[h];
363   rc4keyperm(&DK[16], h, 1, Pbox, 16);
364   rc4keyperm(&DK[32], h, 1, Pbox2, 16);
365   rc4keyperm(&DK[8], h, 1, Pbox3, 16);
366   rc4keyperm(&DK[48], h, 1, Pbox4, 16);
367
368
369 //  uint64_t plain[bufsize];
370 //  uint64_t cipher[bufsize];
371   
372   
373   uint64_t Val[h];
374   uint64_t Val2[h];
375   for(int i=0;i<h;i++) {
376     Val[Pbox[i]]=splitmix64_stateless(i+DK[i&63]);
377   }
378   
379   
380   int delta=64;
381
382
383   
384
385   double t=TimeStart();
386   
387   int nb_bloc=imsize/(h*8);  //8 because we use 64bits numbers
388   
389
390
391   for(uint iter=0;iter<nb_test;iter++) {
392     scprng(SEQ, SEQ2, h, nb_bloc, Val,Val2,Sbox1, Sbox2, Sbox3, Sbox4, Pbox, Pbox2, Pbox3, Pbox4, DK, delta);
393   }
394
395   double time=TimeStop(t);
396   printf("%e  ",nb_test*nb_bloc*h*8/time);
397
398   if(lena) {
399     for(int i=0;i<oneD;i++) {
400       data_R[i]=seq2[i];
401       data_G[i]=seq2[oneD+i];
402       data_B[i]=seq2[2*oneD+i];
403     }
404     store_RGB_pixmap("lena2.ppm", data_R, data_G, data_B, width, height);
405   }
406
407
408
409   //reinit of parameters
410
411   rc4key(DK, Sbox1, 8);
412   rc4key(&DK[8], Sbox2, 8);
413   rc4key(&DK[16], Sbox3, 8);
414   rc4key(&DK[24], Sbox4, 8);
415
416   rc4keyperm(&DK[16], h, 1, Pbox, 16);
417   rc4keyperm(&DK[32], h, 1, Pbox2, 16);
418   rc4keyperm(&DK[8], h, 1, Pbox3, 16);
419   rc4keyperm(&DK[48], h, 1, Pbox4, 16);
420
421
422   for(int i=0;i<h;i++) {
423     Val[Pbox[i]]=splitmix64_stateless(i+DK[i&63]);
424   }
425
426   t=TimeStart();
427
428
429   for(uint iter=0;iter<nb_test;iter++) {
430     scprng(SEQ2, SEQ, h, nb_bloc, Val,Val2,Sbox1, Sbox2, Sbox3, Sbox4, Pbox, Pbox2, Pbox3, Pbox4, DK, delta);
431   }
432
433
434   time=TimeStop(t);
435   printf("%e\t",nb_test*nb_bloc*h*8/time);
436   
437   if(lena) {
438     for(int i=0;i<oneD;i++) {
439       data_R[i]=seq[i];
440       data_G[i]=seq[oneD+i];
441       data_B[i]=seq[2*oneD+i];
442     }
443     store_RGB_pixmap("lena3.ppm", data_R, data_G, data_B, width, height);
444   }
445   else {
446     bool equal=true;
447     for(int i=0;i<imsize;i++) {
448       //cout<<(int)buffer[i]<<endl;
449       if(buffer[i]!=seq[i]) {
450         equal=false;
451       }
452     }
453 //    cout<<"RESULT CORRECT: "<<equal<<endl;
454   }
455   
456   
457   
458 }