7 typedef unsigned char uchar;
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);
22 typedef struct sfcctx { u8 a; u8 b; u8 c; u8 count; } sfcctx;
23 #define rot64(x,k) (((x)<<(k))|((x)>>(64-(k))))
26 #define right_shift 11
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;
38 static inline void sfcinit(sfcctx *x, uint64_t seed) {
49 typedef struct ranctx { u8 a; u8 b; u8 c; u8 d; } ranctx;
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);
62 static inline void jsfinit(ranctx *x, uint64_t seed) {
63 x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
74 inline uint64_t xorshift64( const uint64_t state)
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);
96 typedef struct sulong2 ulong2;
98 static inline uint64_t rotl(const uint64_t x, int k) {
99 return (x << k) | (x >> (64 - k));
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);
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;
115 xoro->x = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
116 xoro->y = rotl(s1, 36); // c
128 struct timeval tstart;
129 gettimeofday(&tstart,0);
130 return( (double) (tstart.tv_sec + tstart.tv_usec*1e-6) );
133 double TimeStop(double t)
137 gettimeofday(&tend,0);
138 t = (double) (tend.tv_sec + tend.tv_usec*1e-6) - t;
143 uint xorshift32(const uint t)
145 /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
157 void rc4key(uchar *key, uchar *sc, int size_DK) {
159 for(int i=0;i<256;i++) {
165 for(int i0=0; i0<256; i0++) {
166 j0 = (j0 + sc[i0] + key[i0%size_DK] )&0xFF;
174 void rc4keyperm(uchar *key,int len, int rp,int *sc, int size_DK) {
180 for (int i=0;i<len;i++) {
183 for (int it = 0; it < rp; it++) {
185 for(int i0 = 0; i0<len; i0++) {
186 j0 = (j0 + sc[i0] + sc[j0] + key[i0%size_DK] )% len;
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)
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) {
206 for(int nb=0;nb<nb_bloc;nb++) {
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]];
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
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];
232 /* uchar *ptr=(uchar*)Val;
233 for(int j=0;j<bufsize*8;j++)
234 ptr[j]^=Sbox2[Sbox1[ptr[j]+DK[j&63]]];
237 for(int j=0;j<bufsize;j++) {
238 Val[j]=R(Val[j],Val[Pbox[j]],Val[Pbox2[j]]);
242 for(int j=0;j<256;j++)
243 Sbox1[j]=Sbox3[Sbox1[j]];
245 for(int j=0;j<256;j++)
246 Sbox2[j]=Sbox4[Sbox2[j]];
248 for(int j=0;j<256;j++)
249 Sbox3[j]=Sbox4[Sbox3[j]];
252 for(int j=0;j<bufsize;j++)
253 Pbox[j]=Pbox3[Pbox[j]];
255 for(int j=0;j<bufsize;j++)
256 Pbox2[j]=Pbox4[Pbox2[j]];
258 for(int j=0;j<bufsize;j++)
259 Pbox3[j]=Pbox4[Pbox3[j]];
273 int main(int argc, char **argv) {
274 // printf("%d %d \n",sizeof(__uint64_t),sizeof(ulong));
281 uchar *data_R, *data_G, *data_B;
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
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);
309 width=height=size_buf;
311 buffer=new uchar[imsize];
312 for(int i=0;i<imsize;i++) {
318 uchar* seq= new uchar[imsize];
319 uchar* seq2= new uchar[imsize];
321 int oneD=width*height;
323 for(int i=0;i<oneD;i++) {
325 seq[oneD+i]=data_G[i];
326 seq[2*oneD+i]=data_B[i];
330 for(int i=0;i<oneD;i++) {
335 uint64_t *SEQ=(uint64_t*)seq;
336 uint64_t *SEQ2=(uint64_t*)seq2;
346 for(int i=0;i<64;i++)
347 DK[i]=splitmix64_stateless(i);
354 rc4key(DK, Sbox1, 8);
355 rc4key(&DK[8], Sbox2, 8);
356 rc4key(&DK[16], Sbox3, 8);
357 rc4key(&DK[24], Sbox4, 8);
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);
369 // uint64_t plain[bufsize];
370 // uint64_t cipher[bufsize];
375 for(int i=0;i<h;i++) {
376 Val[Pbox[i]]=splitmix64_stateless(i+DK[i&63]);
385 double t=TimeStart();
387 int nb_bloc=imsize/(h*8); //8 because we use 64bits numbers
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);
395 double time=TimeStop(t);
396 printf("%e ",nb_test*nb_bloc*h*8/time);
399 for(int i=0;i<oneD;i++) {
401 data_G[i]=seq2[oneD+i];
402 data_B[i]=seq2[2*oneD+i];
404 store_RGB_pixmap("lena2.ppm", data_R, data_G, data_B, width, height);
409 //reinit of parameters
411 rc4key(DK, Sbox1, 8);
412 rc4key(&DK[8], Sbox2, 8);
413 rc4key(&DK[16], Sbox3, 8);
414 rc4key(&DK[24], Sbox4, 8);
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);
422 for(int i=0;i<h;i++) {
423 Val[Pbox[i]]=splitmix64_stateless(i+DK[i&63]);
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);
435 printf("%e\t",nb_test*nb_bloc*h*8/time);
438 for(int i=0;i<oneD;i++) {
440 data_G[i]=seq[oneD+i];
441 data_B[i]=seq[2*oneD+i];
443 store_RGB_pixmap("lena3.ppm", data_R, data_G, data_B, width, height);
447 for(int i=0;i<imsize;i++) {
448 //cout<<(int)buffer[i]<<endl;
449 if(buffer[i]!=seq[i]) {
453 // cout<<"RESULT CORRECT: "<<equal<<endl;