11 #include <algorithm> // std::random_shuffle
12 #include <vector> // std::vector
17 typedef unsigned long mylong;
18 #define LLUI (long long unsigned int)
24 void display(mylong *mat, int r, int c) {
25 for(int i=0;i<r;i++) {
26 for(int j=0;j<c;j++) {
27 printf("%016llu ",LLUI mat[i*c+j]);
34 mylong *matrix_multiply(gf_t *gf, mylong *m1, mylong *m2, int r1, int c1, int r2, int c2, int w)
39 product = (mylong *) malloc(sizeof(mylong)*r1*c2);
40 for (i = 0; i < r1*c2; i++) product[i] = 0;
42 for (i = 0; i < r1; i++) {
43 for (j = 0; j < c2; j++) {
44 for (k = 0; k < r2; k++) {
45 product[i*c2+j] ^= gf->multiply.w64(gf,m1[i*c1+k], m2[k*c2+j]);
54 int invert_matrix(gf_t *gf, mylong *mat, mylong *inv, int rows)
56 int cols, i, j, k, x, rs2;
63 for (i = 0; i < rows; i++) {
64 for (j = 0; j < cols; j++) {
65 inv[k] = (i == j) ? 1 : 0;
69 // display(inv, rows, rows);
72 /* First -- convert into upper triangular */
73 for (i = 0; i < cols; i++) {
76 /* Swap rows if we ave a zero i,i element. If we can't swap, then the
77 matrix was not invertible */
79 if (mat[row_start+i] == 0) {
80 for (j = i+1; j < rows && mat[cols*j+i] == 0; j++) ;
81 if (j == rows) return -1;
83 for (k = 0; k < cols; k++) {
84 tmp = mat[row_start+k];
85 mat[row_start+k] = mat[rs2+k];
87 tmp = inv[row_start+k];
88 inv[row_start+k] = inv[rs2+k];
93 /* Multiply the row by 1/element i,i */
94 tmp = mat[row_start+i];
96 inverse = gf->divide.w64(gf,1, tmp);
97 for (j = 0; j < cols; j++) {
98 mat[row_start+j] = gf->multiply.w64(gf,mat[row_start+j], inverse);
99 inv[row_start+j] = gf->multiply.w64(gf,inv[row_start+j], inverse);
103 /* Now for each j>i, add A_ji*Ai to Aj */
105 for (j = i+1; j != cols; j++) {
110 for (x = 0; x < cols; x++) {
111 mat[rs2+x] ^= mat[row_start+x];
112 inv[rs2+x] ^= inv[row_start+x];
117 for (x = 0; x < cols; x++) {
118 mat[rs2+x] ^= gf->multiply.w64(gf,tmp, mat[row_start+x]);
119 inv[rs2+x] ^= gf->multiply.w64(gf,tmp, inv[row_start+x]);
126 /* Now the matrix is upper triangular. Start at the top and multiply down */
128 for (i = rows-1; i >= 0; i--) {
130 for (j = 0; j < i; j++) {
132 if (mat[rs2+i] != 0) {
135 for (k = 0; k < cols; k++) {
136 inv[rs2+k] ^= gf->multiply.w64(gf,tmp, inv[row_start+k]);
143 display(mat, rows, rows);
146 display(inv, rows, rows);
155 int invertible_matrix(gf_t *gf, int *mat, int rows, int w)
157 int cols, i, j, k, x, rs2;
163 /* First -- convert into upper triangular */
164 for (i = 0; i < cols; i++) {
167 /* Swap rows if we ave a zero i,i element. If we can't swap, then the
168 matrix was not invertible */
170 if (mat[row_start+i] == 0) {
171 for (j = i+1; j < rows && mat[cols*j+i] == 0; j++) ;
172 if (j == rows) return 0;
174 for (k = 0; k < cols; k++) {
175 tmp = mat[row_start+k];
176 mat[row_start+k] = mat[rs2+k];
181 /* Multiply the row by 1/element i,i */
182 tmp = mat[row_start+i];
184 inverse = gf->divide.w64(gf,1, tmp);
185 for (j = 0; j < cols; j++) {
186 mat[row_start+j] = gf->multiply.w64(gf,mat[row_start+j], inverse);
190 /* Now for each j>i, add A_ji*Ai to Aj */
192 for (j = i+1; j != cols; j++) {
197 for (x = 0; x < cols; x++) {
198 mat[rs2+x] ^= mat[row_start+x];
203 for (x = 0; x < cols; x++) {
204 mat[rs2+x] ^= gf->multiply.w64(gf,tmp,mat[row_start+x]);
217 mylong* readFullFile(int n, int t, mylong& sizeFile, mylong & padded_size) {
219 // ifstream stream("lena.png", ios::in | ios::binary | ios::ate);
220 // ifstream stream("lena_small.png", ios::in | ios::binary | ios::ate);
221 ifstream stream("/home/couturie/Downloads/CARCARIASS.zip", ios::in | ios::binary | ios::ate);
223 sizeFile=stream.tellg();
224 std::cout << sizeFile << std::endl;
225 stream.seekg(0, ios::beg);
232 vector<uint8_t> contents((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
240 //make padding, we need to pad to be divisible by 8*t, we
241 if((sizeFile+8)%(8*t)!=0) {
242 cout<<(int)(sizeFile/(8*t))<<endl;
244 int remainder=(8*t)*(1+(int)((sizeFile+8)/(8*t)))-sizeFile-8;
245 cout << "remainder " << remainder << endl;
246 uint8_t vec[remainder];
247 for(int i=0;i<remainder;i++)
249 //add remainder elements at the end
250 contents.insert(contents.end(),vec,vec+remainder);
251 //add 8 elements at the beginning for the size
252 contents.insert(contents.begin(),vec,vec+8);
257 cout << "res contents " << contents.size() << endl;
259 // for(int i=0;i<contents.size();i++)
260 // cout << (int)contents[i] << " ";
263 uint8_t *p_contents=&contents[0];
264 // mylong *p_contents2=reinterpret_cast<mylong*>(p_contents);
266 padded_size=contents.size()/8;
268 mylong *p_contents2=new mylong[padded_size];
269 memcpy(p_contents2,p_contents,sizeof(mylong)*padded_size);
270 //mylong *p_contents2=(mylong*)p_contents;
272 p_contents2[0]=sizeFile;
277 /* for(int i=0;i<padded_size;i++)
278 cout << p_contents2[i] << " ";
282 for(int i=8-1;i>=0;i--) {
287 cout << "convert val " << (long)res << endl;
290 for(int i=16-1;i>=8;i--) {
295 cout << "convert val " << (long)res << endl;
302 void saveFile(uint8_t *data, const char *fileName,long size_file) {
303 cout<<"size file "<<size_file<<endl;
304 FILE* pFile = fopen (fileName, "wb");
305 fwrite (data , sizeof(uint8_t), size_file, pFile);
311 void readFile(uint8_t *data, const char *fileName,long size_file) {
312 cout<<"size file "<<size_file<<endl;
313 FILE* pFile = fopen (fileName, "rb");
315 fseek(pFile, 0L, SEEK_END);
316 int sz = ftell(pFile);
319 cout << "error : size of this chunk is not correct !! " << endl;
322 fread (data , sizeof(uint8_t), size_file, pFile);
328 void saveFile8(mylong *data, const char *fileName,long size_file) {
330 cout<<"size file 8 "<<size_file<<endl;
332 FILE* pFile = fopen (fileName, "wb");
336 fwrite (data , sizeof(mylong), size_file, pFile);
344 int main(int argc, char **argv)
362 gf_init_easy(&gf, w);
366 matS=readFullFile(n,t,sizeFile,padded_size);
368 cout<<padded_size*8<<endl;
370 /* for(int i=0;i<padded_size;i++)
371 cout << matS[i] << " ";
375 int len=padded_size/t;
377 cout<<" len "<<len<<" "<<padded_size<<endl;
379 // matS = malloc(sizeof(mylong)*t*len);
380 matG = malloc(sizeof(mylong)*t*n);
386 std::srand ( unsigned ( std::time(0) ) );
389 for(int i=0;i<t;i++) {
390 for(int j=0;j<len;j++) {
391 matS[i*len+j]=lrand48()<<32|lrand48();
396 for(int i=0;i<n;i++) {
397 for(int j=0;j<t;j++) {
398 matG[i*t+j]=lrand48()<<32|lrand48();
404 printf("Matrix S:\n");
405 // display(matS, len, t);
408 printf("Matrix G:\n");
412 auto start = std::chrono::system_clock::now();
413 matC=matrix_multiply(&gf, matG, matS, n, t, t, len, w);
414 auto end = std::chrono::system_clock::now();
415 std::chrono::duration<double> elapsed_seconds = end-start;
416 std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n";
418 // display(matC,t,t);
422 for(int i=0;i<n;i++) {
424 ss <<"lena_"<<i<<".png";
425 string str = ss.str();
426 saveFile((uint8_t*)&matC[i*len], str.c_str(),len*sizeof(mylong));
431 mylong *matCs = malloc(sizeof(mylong)*t*len);
432 mylong *matGs = malloc(sizeof(mylong)*t*t);
435 std::vector<int> myvector;
438 for (int i=0; i<n; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
440 // using built-in random generator:
441 random_shuffle ( myvector.begin(), myvector.end() );
445 std::cout << "random chunk" << std::endl;
447 for(int ii=0;ii<t;ii++) {
448 // for(int i=n-1;i>=t;i--) {
449 // for(int i=0;i<n;i+=2) {
452 std::cout << myvector[i] << " ";
456 ss <<"lena_"<<i<<".png";
457 string str = ss.str();
458 readFile((uint8_t*)&matCs[ind*len], str.c_str(),len*sizeof(mylong));
460 // display(&matCs[ind*len],1,1);
461 // display(&matC[i*len],1,1);
463 /*for(int j=0;j<len;j++) {
464 matCs[ind*len+j]=matC[i*len+j];
469 for(int j=0;j<t;j++) {
470 matGs[ind*t+j]=matG[i*t+j];
474 std::cout << std::endl;
477 printf("Matrix Gs:\n");
478 display(matGs, t, t);
480 // printf("Matrix Cs:\n");
481 // display(matCs, t, len);
483 mylong* matGs_copy = malloc(sizeof(mylong)* t*t);
485 //WARNING invert changes the matrix
486 // invert = invertible_matrix(&gf,matGs, t, w);
487 // printf("\nInvertible Gs: %s\n", (invert == 1) ? "Yes" : "No");
489 memcpy(matGs_copy, matGs, sizeof(mylong)*t*t);
490 mylong *matInvGs = malloc(sizeof(mylong)*t*t);
491 invert_matrix(&gf, matGs_copy, matInvGs, t);
494 WARNING this changes matGs
495 identity=matrix_multiply(&gf, matInvGs, matGs, t, t, t, t, w);
496 printf("Identity:\n");
497 display(identity, t, t);
501 //printf("Matrix Gs:\n");
502 //display(matGs, t, t);
504 mylong *matS2 = malloc(sizeof(mylong)*t*len);
507 start = std::chrono::system_clock::now();
508 matS2=matrix_multiply(&gf, matInvGs, matCs, t, t, t, len, w);
509 end = std::chrono::system_clock::now();
510 elapsed_seconds = end-start;
511 std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n";
514 printf("Matrix S2:\n");
515 // display(matS2, len, t);
516 display(matS2, t, t);
519 for(int i=0;i<padded_size && equal;i++) {
520 equal=matS[i]==matS2[i];
525 printf("EQUAL !!!\n");
528 mylong new_size=matS2[0];
529 cout << "size of data " << new_size << endl;
532 //first elements that contains the size is removed
533 uint8_t *reconstucted_data=reinterpret_cast<uint8_t*>(&matS2[1]);
534 saveFile(reconstucted_data, "lena2.png",new_size);