From 1a0cdd1fa39d85ac808a83034b8132d999d62513 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20Couturier?= <raphael.couturier@univ-fcomte.fr> Date: Tue, 20 Aug 2019 21:59:50 +0200 Subject: [PATCH 1/1] new scprng --- OneRoundIoT/NEW/scprng.cpp | 41 +++- OneRoundIoT/NEW/scprng_old.cpp | 414 +++++++++++++++++++++++++++++++++ 2 files changed, 446 insertions(+), 9 deletions(-) create mode 100644 OneRoundIoT/NEW/scprng_old.cpp diff --git a/OneRoundIoT/NEW/scprng.cpp b/OneRoundIoT/NEW/scprng.cpp index 3b2eb6b..e0cc4c4 100644 --- a/OneRoundIoT/NEW/scprng.cpp +++ b/OneRoundIoT/NEW/scprng.cpp @@ -193,7 +193,7 @@ void rc4keyperm(uchar *key,int len, int rp,int *sc, int size_DK) { } -void scprng(uint64_t *plain, uint64_t* cipher, int bufsize, int nb_bloc, uint64_t *Val, uchar *Sbox1, uchar *Sbox2, int *Pbox, int *Pbox2, uchar *DK, int delta) { +void scprng(uint64_t *plain, uint64_t* cipher, int bufsize, int nb_bloc, uint64_t *Val, uchar *Sbox1, uchar *Sbox2, uchar * Sbox3, uchar *Sbox4, int *Pbox, int *Pbox2, int *Pbox3, int *Pbox4, uchar *DK, int delta) { int update=0; @@ -226,13 +226,28 @@ void scprng(uint64_t *plain, uint64_t* cipher, int bufsize, int nb_bloc, uint64_ uchar *ptr=(uchar*)Val; for(int j=0;j<bufsize*8;j++) ptr[j]^=Sbox2[Sbox1[ptr[j]+DK[j&63]]]; - rc4keyperm(ptr, bufsize, 1, Pbox, 64); - //only for xorshift - rc4keyperm(&ptr[32], bufsize, 1, Pbox2, 64); - + + for(int j=0;j<256;j++) + Sbox1[j]=Sbox3[Sbox1[j]]; + + for(int j=0;j<256;j++) + Sbox2[j]=Sbox4[Sbox2[j]]; + + for(int j=0;j<256;j++) + Sbox3[j]=Sbox4[Sbox3[j]]; + + + for(int j=0;j<bufsize;j++) + Pbox[j]=Pbox3[Pbox[j]]; + + for(int j=0;j<bufsize;j++) + Pbox2[j]=Pbox4[Pbox2[j]]; + + for(int j=0;j<bufsize;j++) + Pbox3[j]=Pbox4[Pbox3[j]]; + + - rc4key(ptr, Sbox1, 64); - rc4key(&ptr[64], Sbox2, 64); } else update++; @@ -322,13 +337,21 @@ int main(int argc, char **argv) { uchar Sbox1[256]; uchar Sbox2[256]; + uchar Sbox3[256]; + uchar Sbox4[256]; rc4key(DK, Sbox1, 8); rc4key(&DK[8], Sbox2, 8); + rc4key(&DK[16], Sbox3, 8); + rc4key(&DK[24], Sbox4, 8); int Pbox[h]; int Pbox2[h]; + int Pbox3[h]; + int Pbox4[h]; rc4keyperm(&DK[16], h, 1, Pbox, 16); rc4keyperm(&DK[32], h, 1, Pbox2, 16); + rc4keyperm(&DK[8], h, 1, Pbox3, 16); + rc4keyperm(&DK[48], h, 1, Pbox4, 16); // uint64_t plain[bufsize]; @@ -353,7 +376,7 @@ int main(int argc, char **argv) { for(uint iter=0;iter<nb_test;iter++) { - scprng(SEQ, SEQ2, h, nb_bloc, Val,Sbox1, Sbox2, Pbox, Pbox2, DK, delta); + scprng(SEQ, SEQ2, h, nb_bloc, Val,Sbox1, Sbox2, Sbox3, Sbox4, Pbox, Pbox2, Pbox3, Pbox4, DK, delta); } double time=TimeStop(t); @@ -383,7 +406,7 @@ int main(int argc, char **argv) { for(uint iter=0;iter<nb_test;iter++) { - scprng(SEQ2, SEQ, h, nb_bloc, Val,Sbox1, Sbox2, Pbox, Pbox2, DK, delta); + scprng(SEQ2, SEQ, h, nb_bloc, Val,Sbox1, Sbox2, Sbox3, Sbox4, Pbox, Pbox2, Pbox3, Pbox4, DK, delta); } diff --git a/OneRoundIoT/NEW/scprng_old.cpp b/OneRoundIoT/NEW/scprng_old.cpp new file mode 100644 index 0000000..3b2eb6b --- /dev/null +++ b/OneRoundIoT/NEW/scprng_old.cpp @@ -0,0 +1,414 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/time.h> +#include<string.h> + +typedef unsigned char uchar; + + + + +typedef uint64_t u8; + +extern "C" { + int load_RGB_pixmap(char *filename, int *width, int *height, unsigned char**R_data, unsigned char**G_data, unsigned char**B_data); + void store_RGB_pixmap(char *filename, unsigned char *R_data, unsigned char *G_data, unsigned char *B_data, int width, int height); +} +using namespace std; + + + +typedef struct sfcctx { u8 a; u8 b; u8 c; u8 count; } sfcctx; +#define rot64(x,k) (((x)<<(k))|((x)>>(64-(k)))) + +#define rotation 24 +#define right_shift 11 +#define left_shift 3 + + +static inline u8 sfc( sfcctx *x ) { + u8 tmp = x->a + x->b + x->count++; + x->a = x->b ^ (x->b >> right_shift); + x->b = x->c + (x->c << left_shift); + x->c = rot64(x->c, rotation) + tmp; + return tmp; +} + +static inline void sfcinit(sfcctx *x, uint64_t seed) { + x->a = seed; + x->b = seed; + x->c = seed; + x->count = 1; + for(int i=0;i<12;i++) + sfc(x); +} + + + +typedef struct ranctx { u8 a; u8 b; u8 c; u8 d; } ranctx; + + + +static inline u8 jsf( ranctx *x ) { + u8 e = x->a - rot64(x->b, 7); + x->a = x->b ^ rot64(x->c, 13); + x->b = x->c + rot64(x->d, 37); + x->c = x->d + e; + x->d = e + x->a; + return x->d; +} + +static inline void jsfinit(ranctx *x, uint64_t seed) { + x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; +} + + + + + + + + + +inline uint64_t xorshift64( const uint64_t state) +{ + uint64_t x = state; + x^= x << 13; + x^= x >> 7; + x^= x << 17; + return x; +} + +static inline uint64_t splitmix64_stateless(uint64_t index) { + uint64_t z = (index + UINT64_C(0x9E3779B97F4A7C15)); + z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9); + z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB); + return z ^ (z >> 31); +} + + +struct sulong2 { + uint64_t x; + uint64_t y; +}; + +typedef struct sulong2 ulong2; + +static inline uint64_t rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +// call this one before calling xoroshiro128plus +static inline void xoroshiro128plus_seed(ulong2 *xoro,uint64_t seed) { + xoro->x = splitmix64_stateless(seed); + xoro->y = splitmix64_stateless(seed + 1); +} + +// returns random number, modifies xoroshiro128plus_s +static inline uint64_t xoroshiro128plus(ulong2 *xoro) { + const uint64_t s0 = xoro->x; + uint64_t s1 = xoro->y; + const uint64_t result = s0 + s1; + + s1 ^= s0; + xoro->x = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b + xoro->y = rotl(s1, 36); // c + + return result; +} + + + + + + +double TimeStart() +{ + struct timeval tstart; + gettimeofday(&tstart,0); + return( (double) (tstart.tv_sec + tstart.tv_usec*1e-6) ); +} + +double TimeStop(double t) +{ + struct timeval tend; + + gettimeofday(&tend,0); + t = (double) (tend.tv_sec + tend.tv_usec*1e-6) - t; + return (t); +} + + +uint xorshift32(const uint t) +{ + /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */ + uint x = t; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return x; +} + + + + + +void rc4key(uchar *key, uchar *sc, int size_DK) { + + for(int i=0;i<256;i++) { + sc[i]=i; + } + + + uchar j0 = 0; + for(int i0=0; i0<256; i0++) { + j0 = (j0 + sc[i0] + key[i0%size_DK] )&0xFF; + uchar tmp = sc[i0]; + sc[i0] = sc[j0 ]; + sc[j0] = tmp; + } +} + + +void rc4keyperm(uchar *key,int len, int rp,int *sc, int size_DK) { + + //sc=1:len; + + + + for (int i=0;i<len;i++) { + sc[i]=i; + } + for (int it = 0; it < rp; it++) { + int j0 = 1; + for(int i0 = 0; i0<len; i0++) { + j0 = (j0 + sc[i0] + sc[j0] + key[i0%size_DK] )% len; + int tmp = sc[i0]; + sc[i0] = sc[j0]; + sc[j0] = tmp; + } + + } +} + + +void scprng(uint64_t *plain, uint64_t* cipher, int bufsize, int nb_bloc, uint64_t *Val, uchar *Sbox1, uchar *Sbox2, int *Pbox, int *Pbox2, uchar *DK, int delta) { + int update=0; + + + for(int nb=0;nb<nb_bloc;nb++) { + + for(int j=0;j<bufsize;j++) { + //Val[j]=splitmix64_stateless(Val[j])^Val[Pbox[j]]; + //Val[j]=xorshift64(Val[j])^Val[Pbox[j]]; //fail +// Val[j]=xorshift64(Val[j])^Val[Pbox[j]]^Val[Pbox2[j]]; + Val[j]=xorshift64(Val[j]); + + //Val[j]=xoroshiro128plus(&xoro[j])^Val[Pbox[j]]; + //Val[j]=jsf(&ctx[j])^Val[Pbox[j]]; //good + //Val[j]=sfc(&sfcd[j])^Val[Pbox[j]]; //good + } + for(int j=0;j<bufsize;j++) { + Val[j]=Val[j]^Val[Pbox[j]]^Val[Pbox2[j]]; + } + + + for(int j=0;j<bufsize;j++) { + cipher[nb*bufsize+j]=Val[j]^plain[nb*bufsize+j]; + } + + + + + if(update==delta) { + update=0; + uchar *ptr=(uchar*)Val; + for(int j=0;j<bufsize*8;j++) + ptr[j]^=Sbox2[Sbox1[ptr[j]+DK[j&63]]]; + rc4keyperm(ptr, bufsize, 1, Pbox, 64); + //only for xorshift + rc4keyperm(&ptr[32], bufsize, 1, Pbox2, 64); + + + rc4key(ptr, Sbox1, 64); + rc4key(&ptr[64], Sbox2, 64); + } + else + update++; + } + + + +} + + +int main(int argc, char **argv) { +// printf("%d %d \n",sizeof(__uint64_t),sizeof(ulong)); + + + uint nb_test=1; + + int width; + int height; + uchar *data_R, *data_G, *data_B; + int imsize; + uchar *buffer; + + int size_buf=128; + + int lena=0; + int h=128; + for(int i=1; i<argc; i++){ + if(strncmp(argv[i],"nb",2)==0) nb_test = atoi(&(argv[i][2])); //nb of test + if(strncmp(argv[i],"h",1)==0) h = atoi(&(argv[i][1])); //size of block + if(strncmp(argv[i],"sizebuf",7)==0) size_buf = atoi(&(argv[i][7])); //SIZE of the buffer + if(strncmp(argv[i],"lena",4)==0) lena = atoi(&(argv[i][4])); //Use Lena or buffer + } + + + + + + + + if(lena==1) { + load_RGB_pixmap("lena.ppm", &width, &height, &data_R, &data_G, &data_B); +// load_RGB_pixmap("8192.ppm", &width, &height, &data_R, &data_G, &data_B); + imsize=width*height*3; +// load_RGB_pixmap("No_ecb_mode_picture.ppm", &width, &height, &data_R, &data_G, &data_B); + } + else { + width=height=size_buf; + imsize=width*height; + buffer=new uchar[imsize]; + for(int i=0;i<imsize;i++) { + buffer[i]=lrand48(); + } + } + + + uchar* seq= new uchar[imsize]; + uchar* seq2= new uchar[imsize]; + + int oneD=width*height; + if(lena) { + for(int i=0;i<oneD;i++) { + seq[i]=data_R[i]; + seq[oneD+i]=data_G[i]; + seq[2*oneD+i]=data_B[i]; + } + } + else { + for(int i=0;i<oneD;i++) { + seq[i]=buffer[i]; + } + } + + uint64_t *SEQ=(uint64_t*)seq; + uint64_t *SEQ2=(uint64_t*)seq2; + + + + uint64_t val=1021; + uint64_t val2=1021; + + uint r1=21,r2=93; + + uchar DK[64]; + for(int i=0;i<64;i++) + DK[i]=splitmix64_stateless(i); + + + uchar Sbox1[256]; + uchar Sbox2[256]; + rc4key(DK, Sbox1, 8); + rc4key(&DK[8], Sbox2, 8); + + int Pbox[h]; + int Pbox2[h]; + rc4keyperm(&DK[16], h, 1, Pbox, 16); + rc4keyperm(&DK[32], h, 1, Pbox2, 16); + + +// uint64_t plain[bufsize]; +// uint64_t cipher[bufsize]; + + + uint64_t Val[h]; + for(int i=0;i<h;i++) { + Val[Pbox[i]]=splitmix64_stateless(i+DK[i&63]); + } + + + int delta=8; + + + + + double t=TimeStart(); + + int nb_bloc=imsize/(h*8); //8 because we use 64bits numbers + + + + for(uint iter=0;iter<nb_test;iter++) { + scprng(SEQ, SEQ2, h, nb_bloc, Val,Sbox1, Sbox2, Pbox, Pbox2, DK, delta); + } + + double time=TimeStop(t); + printf("%e ",nb_test*nb_bloc*h*8/time); + + if(lena) { + for(int i=0;i<oneD;i++) { + data_R[i]=seq2[i]; + data_G[i]=seq2[oneD+i]; + data_B[i]=seq2[2*oneD+i]; + } + store_RGB_pixmap("lena2.ppm", data_R, data_G, data_B, width, height); + } + + + //reinit of parameters + rc4key(DK, Sbox1, 8); + rc4key(&DK[8], Sbox2, 8); + + rc4keyperm(&DK[16], h, 1, Pbox, 16); + rc4keyperm(&DK[32], h, 1, Pbox2, 16); + for(int i=0;i<h;i++) { + Val[Pbox[i]]=splitmix64_stateless(i+DK[i&63]); + } + + t=TimeStart(); + + + for(uint iter=0;iter<nb_test;iter++) { + scprng(SEQ2, SEQ, h, nb_bloc, Val,Sbox1, Sbox2, Pbox, Pbox2, DK, delta); + } + + + time=TimeStop(t); + printf("%e\n",nb_test*nb_bloc*h*8/time); + + if(lena) { + for(int i=0;i<oneD;i++) { + data_R[i]=seq[i]; + data_G[i]=seq[oneD+i]; + data_B[i]=seq[2*oneD+i]; + } + store_RGB_pixmap("lena3.ppm", data_R, data_G, data_B, width, height); + } + else { + bool equal=true; + for(int i=0;i<imsize;i++) { + //cout<<(int)buffer[i]<<endl; + if(buffer[i]!=seq[i]) { + equal=false; + } + } +// cout<<"RESULT CORRECT: "<<equal<<endl; + } + + + +} -- 2.39.5