]> AND Private Git Repository - Cipher_code.git/blob - IDA_new/gf-complete/src/gf_general.c
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] / IDA_new / gf-complete / src / gf_general.c
1 /*
2  * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
3  * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
4  * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
5  *
6  * gf_general.c
7  *
8  * This file has helper routines for doing basic GF operations with any
9  * legal value of w.  The problem is that w <= 32, w=64 and w=128 all have
10  * different data types, which is a pain.  The procedures in this file try
11  * to alleviate that pain.  They are used in gf_unit and gf_time.
12  */
13
14 #include <stdio.h>
15 #include <getopt.h>
16 #include <stdint.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <time.h>
20 #include <assert.h>
21
22 #include "gf_complete.h"
23 #include "gf_int.h"
24 #include "gf_method.h"
25 #include "gf_rand.h"
26 #include "gf_general.h"
27
28 void gf_general_set_zero(gf_general_t *v, int w)
29 {
30   if (w <= 32) {
31     v->w32 = 0;
32   } else if (w <= 64) {
33     v->w64 = 0;
34   } else {
35     v->w128[0] = 0;
36     v->w128[1] = 0;
37   }
38 }
39
40 void gf_general_set_one(gf_general_t *v, int w)
41 {
42   if (w <= 32) {
43     v->w32 = 1;
44   } else if (w <= 64) {
45     v->w64 = 1;
46   } else {
47     v->w128[0] = 0;
48     v->w128[1] = 1;
49   }
50 }
51
52 void gf_general_set_two(gf_general_t *v, int w)
53 {
54   if (w <= 32) {
55     v->w32 = 2;
56   } else if (w <= 64) {
57     v->w64 = 2;
58   } else {
59     v->w128[0] = 0;
60     v->w128[1] = 2;
61   }
62 }
63
64 int gf_general_is_zero(gf_general_t *v, int w) 
65 {
66   if (w <= 32) {
67     return (v->w32 == 0);
68   } else if (w <= 64) {
69     return (v->w64 == 0);
70   } else {
71     return (v->w128[0] == 0 && v->w128[1] == 0);
72   }
73 }
74
75 int gf_general_is_one(gf_general_t *v, int w) 
76 {
77   if (w <= 32) {
78     return (v->w32 == 1);
79   } else if (w <= 64) {
80     return (v->w64 == 1);
81   } else {
82     return (v->w128[0] == 0 && v->w128[1] == 1);
83   }
84 }
85
86 void gf_general_set_random(gf_general_t *v, int w, int zero_ok) 
87 {
88   if (w <= 32) {
89       v->w32 = MOA_Random_W(w, zero_ok);
90   } else if (w <= 64) {
91     while (1) {
92       v->w64 = MOA_Random_64();
93       if (v->w64 != 0 || zero_ok) return;
94     }
95   } else {
96     while (1) {
97       MOA_Random_128(v->w128);
98       if (v->w128[0] != 0 || v->w128[1] != 0 || zero_ok) return;
99     }
100   }
101 }
102
103 void gf_general_val_to_s(gf_general_t *v, int w, char *s, int hex)
104 {
105   if (w <= 32) {
106     if (hex) {
107       sprintf(s, "%x", v->w32);
108     } else {
109       sprintf(s, "%u", v->w32);
110     }
111   } else if (w <= 64) {
112     if (hex) {
113       sprintf(s, "%llx", (long long unsigned int) v->w64);
114     } else {
115       sprintf(s, "%lld", (long long unsigned int) v->w64);
116     }
117   } else {
118     if (v->w128[0] == 0) {
119       sprintf(s, "%llx", (long long unsigned int) v->w128[1]);
120     } else {
121       sprintf(s, "%llx%016llx", (long long unsigned int) v->w128[0], 
122                                 (long long unsigned int) v->w128[1]);
123     }
124   }
125 }
126
127 int gf_general_s_to_val(gf_general_t *v, int w, char *s, int hex)
128 {
129   int l;
130   int save;
131
132   if (w <= 32) {
133     if (hex) {
134       if (sscanf(s, "%x", &(v->w32)) == 0) return 0;
135     } else {
136       if (sscanf(s, "%u", &(v->w32)) == 0) return 0;
137     }
138     if (w == 32) return 1;
139     if (w == 31) {
140       if (v->w32 & ((gf_val_32_t)1 << 31)) return 0;
141       return 1;
142     } 
143     if (v->w32 & ~((1 << w)-1)) return 0;
144     return 1;
145   } else if (w <= 64) {
146     if (hex) return (sscanf(s, "%llx", (long long unsigned int *) (&(v->w64))) == 1);
147     return (sscanf(s, "%lld", (long long int *) (&(v->w64))) == 1);
148   } else {
149     if (!hex) return 0;
150     l = strlen(s);
151     if (l <= 16) {
152       v->w128[0] = 0;
153       return (sscanf(s, "%llx", (long long unsigned int *) (&(v->w128[1]))) == 1);
154     } else {
155       if (l > 32) return 0;
156       save = s[l-16];
157       s[l-16] = '\0';
158       if (sscanf(s, "%llx", (long long unsigned int *) (&(v->w128[0]))) == 0) {
159         s[l-16] = save;
160         return 0;
161       }
162       return (sscanf(s+(l-16), "%llx", (long long unsigned int *) (&(v->w128[1]))) == 1);
163     }
164   }
165 }
166     
167 void gf_general_add(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c)
168 {
169   gf_internal_t *h;
170   int w;
171
172   h = (gf_internal_t *) gf->scratch;
173   w = h->w;
174
175   if (w <= 32) {
176     c->w32 = a->w32 ^ b->w32;
177   } else if (w <= 64) {
178     c->w64 = a->w64 ^ b->w64;
179   } else {
180     c->w128[0] = a->w128[0] ^ b->w128[0];
181     c->w128[1] = a->w128[1] ^ b->w128[1];
182   }
183 }
184   
185 void gf_general_multiply(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c)
186 {
187   gf_internal_t *h;
188   int w;
189
190   h = (gf_internal_t *) gf->scratch;
191   w = h->w;
192
193   if (w <= 32) {
194     c->w32 = gf->multiply.w32(gf, a->w32, b->w32);
195   } else if (w <= 64) {
196     c->w64 = gf->multiply.w64(gf, a->w64, b->w64);
197   } else {
198     gf->multiply.w128(gf, a->w128, b->w128, c->w128);
199   }
200 }
201   
202 void gf_general_divide(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c)
203 {
204   gf_internal_t *h;
205   int w;
206
207   h = (gf_internal_t *) gf->scratch;
208   w = h->w;
209
210   if (w <= 32) {
211     c->w32 = gf->divide.w32(gf, a->w32, b->w32);
212   } else if (w <= 64) {
213     c->w64 = gf->divide.w64(gf, a->w64, b->w64);
214   } else {
215     gf->divide.w128(gf, a->w128, b->w128, c->w128);
216   }
217 }
218   
219 void gf_general_inverse(gf_t *gf, gf_general_t *a, gf_general_t *b)
220 {
221   gf_internal_t *h;
222   int w;
223
224   h = (gf_internal_t *) gf->scratch;
225   w = h->w;
226
227   if (w <= 32) {
228     b->w32 = gf->inverse.w32(gf, a->w32);
229   } else if (w <= 64) {
230     b->w64 = gf->inverse.w64(gf, a->w64);
231   } else {
232     gf->inverse.w128(gf, a->w128, b->w128);
233   }
234 }
235   
236 int gf_general_are_equal(gf_general_t *v1, gf_general_t *v2, int w)
237 {
238   if (w <= 32) {
239     return (v1->w32 == v2->w32);
240   } else if (w <= 64) {
241     return (v1->w64 == v2->w64);
242   } else {
243     return (v1->w128[0] == v2->w128[0] &&
244             v1->w128[1] == v2->w128[1]);
245   }
246 }
247
248 void gf_general_do_region_multiply(gf_t *gf, gf_general_t *a, void *ra, void *rb, int bytes, int xor)
249 {
250   gf_internal_t *h;
251   int w;
252
253   h = (gf_internal_t *) gf->scratch;
254   w = h->w;
255
256   if (w <= 32) {
257     gf->multiply_region.w32(gf, ra, rb, a->w32, bytes, xor);
258   } else if (w <= 64) {
259     gf->multiply_region.w64(gf, ra, rb, a->w64, bytes, xor);
260   } else {
261     gf->multiply_region.w128(gf, ra, rb, a->w128, bytes, xor);
262   }
263 }
264
265 void gf_general_do_region_check(gf_t *gf, gf_general_t *a, void *orig_a, void *orig_target, void *final_target, int bytes, int xor)
266 {
267   gf_internal_t *h;
268   int w, words, i;
269   gf_general_t oa, ot, ft, sb;
270   char sa[50], soa[50], sot[50], sft[50], ssb[50];
271
272   h = (gf_internal_t *) gf->scratch;
273   w = h->w;
274
275   words = (bytes * 8) / w;
276   for (i = 0; i < words; i++) {
277     if (w <= 32) {
278       oa.w32 = gf->extract_word.w32(gf, orig_a, bytes, i);
279       ot.w32 = gf->extract_word.w32(gf, orig_target, bytes, i);
280       ft.w32 = gf->extract_word.w32(gf, final_target, bytes, i);
281       sb.w32 = gf->multiply.w32(gf, a->w32, oa.w32);
282       if (xor) sb.w32 ^= ot.w32;
283     } else if (w <= 64) {
284       oa.w64 = gf->extract_word.w64(gf, orig_a, bytes, i);
285       ot.w64 = gf->extract_word.w64(gf, orig_target, bytes, i);
286       ft.w64 = gf->extract_word.w64(gf, final_target, bytes, i);
287       sb.w64 = gf->multiply.w64(gf, a->w64, oa.w64);
288       if (xor) sb.w64 ^= ot.w64;
289     } else {
290       gf->extract_word.w128(gf, orig_a, bytes, i, oa.w128);
291       gf->extract_word.w128(gf, orig_target, bytes, i, ot.w128);
292       gf->extract_word.w128(gf, final_target, bytes, i, ft.w128);
293       gf->multiply.w128(gf, a->w128, oa.w128, sb.w128);
294       if (xor) {
295         sb.w128[0] ^= ot.w128[0];
296         sb.w128[1] ^= ot.w128[1];
297       }
298     }
299
300     if (!gf_general_are_equal(&ft, &sb, w)) {
301       
302       fprintf(stderr,"Problem with region multiply (all values in hex):\n");
303       fprintf(stderr,"   Target address base: 0x%lx.  Word 0x%x of 0x%x.  Xor: %d\n", 
304                  (unsigned long) final_target, i, words, xor);
305       gf_general_val_to_s(a, w, sa, 1);
306       gf_general_val_to_s(&oa, w, soa, 1);
307       gf_general_val_to_s(&ot, w, sot, 1);
308       gf_general_val_to_s(&ft, w, sft, 1);
309       gf_general_val_to_s(&sb, w, ssb, 1);
310       fprintf(stderr,"   Value: %s\n", sa);
311       fprintf(stderr,"   Original source word: %s\n", soa);
312       if (xor) fprintf(stderr,"   XOR with target word: %s\n", sot);
313       fprintf(stderr,"   Product word: %s\n", sft);
314       fprintf(stderr,"   It should be: %s\n", ssb);
315       assert(0);
316     }
317   }
318 }
319
320 void gf_general_set_up_single_timing_test(int w, void *ra, void *rb, int size)
321 {
322   void *top;
323   gf_general_t g;
324   uint8_t *r8, *r8a;
325   uint16_t *r16;
326   uint32_t *r32;
327   uint64_t *r64;
328   int i;
329
330   top = (uint8_t *)rb+size;
331
332   /* If w is 8, 16, 32, 64 or 128, fill the regions with random bytes.
333      However, don't allow for zeros in rb, because that will screw up
334      division.
335      
336      When w is 4, you fill the regions with random 4-bit words in each byte.
337
338      Otherwise, treat every four bytes as an uint32_t
339      and fill it with a random value mod (1 << w).
340    */
341
342   if (w == 8 || w == 16 || w == 32 || w == 64 || w == 128) {
343     MOA_Fill_Random_Region (ra, size);
344     while (rb < top) {
345       gf_general_set_random(&g, w, 0);
346       switch (w) {
347         case 8: 
348           r8 = (uint8_t *) rb;
349           *r8 = g.w32;
350           break;
351         case 16: 
352           r16 = (uint16_t *) rb;
353           *r16 = g.w32;
354           break;
355         case 32: 
356           r32 = (uint32_t *) rb;
357           *r32 = g.w32;
358           break;
359         case 64:
360           r64 = (uint64_t *) rb;
361           *r64 = g.w64;
362           break;
363         case 128: 
364           r64 = (uint64_t *) rb;
365           r64[0] = g.w128[0];
366           r64[1] = g.w128[1];
367           break;
368       }
369       rb = (uint8_t *)rb + (w/8);
370     }
371   } else if (w == 4) {
372     r8a = (uint8_t *) ra;
373     r8 = (uint8_t *) rb;
374     while (r8 < (uint8_t *) top) {
375       gf_general_set_random(&g, w, 1);
376       *r8a = g.w32;
377       gf_general_set_random(&g, w, 0);
378       *r8 = g.w32;
379       r8a++;
380       r8++;
381     }
382   } else {
383     r32 = (uint32_t *) ra;
384     for (i = 0; i < size/4; i++) r32[i] = MOA_Random_W(w, 1);
385     r32 = (uint32_t *) rb;
386     for (i = 0; i < size/4; i++) r32[i] = MOA_Random_W(w, 0);
387   }
388 }
389
390 /* This sucks, but in order to time, you really need to avoid putting ifs in 
391    the inner loops.  So, I'm doing a separate timing test for each w: 
392    (4 & 8), 16, 32, 64, 128 and everything else.  Fortunately, the "everything else"
393    tests can be equivalent to w=32.
394
395    I'm also putting the results back into ra, because otherwise, the optimizer might
396    figure out that we're not really doing anything in the inner loops and it 
397    will chuck that. */
398
399 int gf_general_do_single_timing_test(gf_t *gf, void *ra, void *rb, int size, char test)
400 {
401   gf_internal_t *h;
402   void *top;
403   uint8_t *r8a, *r8b, *top8;
404   uint16_t *r16a, *r16b, *top16;
405   uint32_t *r32a, *r32b, *top32;
406   uint64_t *r64a, *r64b, *top64, *r64c;
407   int w, rv;
408
409   h = (gf_internal_t *) gf->scratch;
410   w = h->w;
411   top = (uint8_t *)ra + size;
412
413   if (w == 8 || w == 4) {
414     r8a = (uint8_t *) ra; 
415     r8b = (uint8_t *) rb; 
416     top8 = (uint8_t *) top;
417     if (test == 'M') {
418       while (r8a < top8) {
419         *r8a = gf->multiply.w32(gf, *r8a, *r8b);
420         r8a++;
421         r8b++;
422       }
423     } else if (test == 'D') {
424       while (r8a < top8) {
425         *r8a = gf->divide.w32(gf, *r8a, *r8b);
426         r8a++;
427         r8b++;
428       }
429     } else if (test == 'I') {
430       while (r8a < top8) {
431         *r8a = gf->inverse.w32(gf, *r8a);
432         r8a++;
433       }
434     }
435     return (top8 - (uint8_t *) ra);
436   }
437
438   if (w == 16) {
439     r16a = (uint16_t *) ra; 
440     r16b = (uint16_t *) rb; 
441     top16 = (uint16_t *) top;
442     if (test == 'M') {
443       while (r16a < top16) {
444         *r16a = gf->multiply.w32(gf, *r16a, *r16b);
445         r16a++;
446         r16b++;
447       }
448     } else if (test == 'D') {
449       while (r16a < top16) {
450         *r16a = gf->divide.w32(gf, *r16a, *r16b);
451         r16a++;
452         r16b++;
453       }
454     } else if (test == 'I') {
455       while (r16a < top16) {
456         *r16a = gf->inverse.w32(gf, *r16a);
457         r16a++;
458       }
459     }
460     return (top16 - (uint16_t *) ra);
461   }
462   if (w <= 32) {
463     r32a = (uint32_t *) ra; 
464     r32b = (uint32_t *) rb; 
465     top32 = (uint32_t *) ra + (size/4); /* This is for the "everything elses" */
466     
467     if (test == 'M') {
468       while (r32a < top32) {
469         *r32a = gf->multiply.w32(gf, *r32a, *r32b);
470         r32a++;
471         r32b++;
472       }
473     } else if (test == 'D') {
474       while (r32a < top32) {
475         *r32a = gf->divide.w32(gf, *r32a, *r32b);
476         r32a++;
477         r32b++;
478       }
479     } else if (test == 'I') {
480       while (r32a < top32) {
481         *r32a = gf->inverse.w32(gf, *r32a);
482         r32a++;
483       }
484     }
485     return (top32 - (uint32_t *) ra);
486   }
487   if (w == 64) {
488     r64a = (uint64_t *) ra; 
489     r64b = (uint64_t *) rb; 
490     top64 = (uint64_t *) top;
491     if (test == 'M') {
492       while (r64a < top64) {
493         *r64a = gf->multiply.w64(gf, *r64a, *r64b);
494         r64a++;
495         r64b++;
496       }
497     } else if (test == 'D') {
498       while (r64a < top64) {
499         *r64a = gf->divide.w64(gf, *r64a, *r64b);
500         r64a++;
501         r64b++;
502       }
503     } else if (test == 'I') {
504       while (r64a < top64) {
505         *r64a = gf->inverse.w64(gf, *r64a);
506         r64a++;
507       }
508     }
509     return (top64 - (uint64_t *) ra);
510   }
511   if (w == 128) {
512     r64a = (uint64_t *) ra; 
513     r64c = r64a;
514     r64a += 2;
515     r64b = (uint64_t *) rb; 
516     top64 = (uint64_t *) top;
517     rv = (top64 - r64a)/2;
518     if (test == 'M') {
519       while (r64a < top64) {
520         gf->multiply.w128(gf, r64a, r64b, r64c);
521         r64a += 2;
522         r64b += 2;
523       }
524     } else if (test == 'D') {
525       while (r64a < top64) {
526         gf->divide.w128(gf, r64a, r64b, r64c);
527         r64a += 2;
528         r64b += 2;
529       }
530     } else if (test == 'I') {
531       while (r64a < top64) {
532         gf->inverse.w128(gf, r64a, r64c);
533         r64a += 2;
534       }
535     }
536     return rv;
537   }
538   return 0;
539 }