blob: 693998017ddc4ccb550198b9b9da8aa62be2d978 [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#include "Bitvec.h"
2
3#include "Random.h"
4
5#include <assert.h>
6#include <stdio.h>
7
8#ifndef DEBUG
9#undef assert
10void assert ( bool )
11{
12}
13#endif
14
15//----------------------------------------------------------------------------
16
17void printbits ( void * blob, int len )
18{
19 uint8_t * data = (uint8_t*)blob;
20
21 printf("[");
22 for(int i = 0; i < len; i++)
23 {
24 unsigned char byte = data[i];
25
26 int hi = (byte >> 4);
27 int lo = (byte & 0xF);
28
29 if(hi) printf("%01x",hi);
30 else printf(".");
31
32 if(lo) printf("%01x",lo);
33 else printf(".");
34
35 if(i != len-1) printf(" ");
36 }
37 printf("]");
38}
39
40void printbits2 ( uint8_t * k, int nbytes )
41{
42 printf("[");
43
44 for(int i = nbytes-1; i >= 0; i--)
45 {
46 uint8_t b = k[i];
47
48 for(int j = 7; j >= 0; j--)
49 {
50 uint8_t c = (b & (1 << j)) ? '#' : ' ';
51
52 putc(c,stdout);
53 }
54 }
55 printf("]");
56}
57
58void printhex32 ( void * blob, int len )
59{
60 assert((len & 3) == 0);
61
62 uint32_t * d = (uint32_t*)blob;
63
64 printf("{ ");
65
66 for(int i = 0; i < len/4; i++)
67 {
68 printf("0x%08x, ",d[i]);
69 }
70
71 printf("}");
72}
73
tanjent@gmail.combabb5532011-02-28 06:03:12 +000074void printbytes ( void * blob, int len )
75{
76 uint8_t * d = (uint8_t*)blob;
77
78 printf("{ ");
79
80 for(int i = 0; i < len; i++)
81 {
82 printf("0x%02x, ",d[i]);
83 }
84
85 printf(" };");
86}
87
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000088//-----------------------------------------------------------------------------
89
90uint32_t getbit ( void * block, int len, uint32_t bit )
91{
92 uint8_t * b = (uint8_t*)block;
93
94 int byte = bit >> 3;
95 bit = bit & 0x7;
96
97 if(byte < len) return (b[byte] >> bit) & 1;
98
99 return 0;
100}
101
102uint32_t getbit_wrap ( void * block, int len, uint32_t bit )
103{
104 uint8_t * b = (uint8_t*)block;
105
106 int byte = bit >> 3;
107 bit = bit & 0x7;
108
109 byte %= len;
110
111 return (b[byte] >> bit) & 1;
112}
113
114void setbit ( void * block, int len, uint32_t bit )
115{
116 uint8_t * b = (uint8_t*)block;
117
118 int byte = bit >> 3;
119 bit = bit & 0x7;
120
121 if(byte < len) b[byte] |= (1 << bit);
122}
123
124void setbit ( void * block, int len, uint32_t bit, uint32_t val )
125{
126 val ? setbit(block,len,bit) : clearbit(block,len,bit);
127}
128
129void clearbit ( void * block, int len, uint32_t bit )
130{
131 uint8_t * b = (uint8_t*)block;
132
133 int byte = bit >> 3;
134 bit = bit & 0x7;
135
136 if(byte < len) b[byte] &= ~(1 << bit);
137}
138
139void flipbit ( void * block, int len, uint32_t bit )
140{
141 uint8_t * b = (uint8_t*)block;
142
143 int byte = bit >> 3;
144 bit = bit & 0x7;
145
146 if(byte < len) b[byte] ^= (1 << bit);
147}
148
149//-----------------------------------------------------------------------------
150
151void lshift1 ( void * blob, int len, int c )
152{
153 int nbits = len*8;
154
155 for(int i = nbits-1; i >= 0; i--)
156 {
157 setbit(blob,len,i,getbit(blob,len,i-c));
158 }
159}
160
161
162void lshift8 ( void * blob, int nbytes, int c )
163{
164 uint8_t * k = (uint8_t*)blob;
165
166 if(c == 0) return;
167
168 int b = c >> 3;
169 c &= 7;
170
171 for(int i = nbytes-1; i >= b; i--)
172 {
173 k[i] = k[i-b];
174 }
175
176 for(int i = b-1; i >= 0; i--)
177 {
178 k[i] = 0;
179 }
180
181 if(c == 0) return;
182
183 for(int i = nbytes-1; i >= 0; i--)
184 {
185 uint8_t a = k[i];
186 uint8_t b = (i == 0) ? 0 : k[i-1];
187
188 k[i] = (a << c) | (b >> (8-c));
189 }
190}
191
192void lshift32 ( void * blob, int len, int c )
193{
194 assert((len & 3) == 0);
195
196 int nbytes = len;
197 int ndwords = nbytes / 4;
198
199 uint32_t * k = (uint32_t*)blob;
200
201 if(c == 0) return;
202
203 //----------
204
205 int b = c / 32;
206 c &= (32-1);
207
208 for(int i = ndwords-1; i >= b; i--)
209 {
210 k[i] = k[i-b];
211 }
212
213 for(int i = b-1; i >= 0; i--)
214 {
215 k[i] = 0;
216 }
217
218 if(c == 0) return;
219
220 for(int i = ndwords-1; i >= 0; i--)
221 {
222 uint32_t a = k[i];
223 uint32_t b = (i == 0) ? 0 : k[i-1];
224
225 k[i] = (a << c) | (b >> (32-c));
226 }
227}
228
229//-----------------------------------------------------------------------------
230
231void rshift1 ( void * blob, int len, int c )
232{
233 int nbits = len*8;
234
235 for(int i = 0; i < nbits; i++)
236 {
237 setbit(blob,len,i,getbit(blob,len,i+c));
238 }
239}
240
241void rshift8 ( void * blob, int nbytes, int c )
242{
243 uint8_t * k = (uint8_t*)blob;
244
245 if(c == 0) return;
246
247 int b = c >> 3;
248 c &= 7;
249
250 for(int i = 0; i < nbytes-b; i++)
251 {
252 k[i] = k[i+b];
253 }
254
255 for(int i = nbytes-b; i < nbytes; i++)
256 {
257 k[i] = 0;
258 }
259
260 if(c == 0) return;
261
262 for(int i = 0; i < nbytes; i++)
263 {
264 uint8_t a = (i == nbytes-1) ? 0 : k[i+1];
265 uint8_t b = k[i];
266
267 k[i] = (a << (8-c) ) | (b >> c);
268 }
269}
270
271void rshift32 ( void * blob, int len, int c )
272{
273 assert((len & 3) == 0);
274
275 int nbytes = len;
276 int ndwords = nbytes / 4;
277
278 uint32_t * k = (uint32_t*)blob;
279
280 //----------
281
282 if(c == 0) return;
283
284 int b = c / 32;
285 c &= (32-1);
286
287 for(int i = 0; i < ndwords-b; i++)
288 {
289 k[i] = k[i+b];
290 }
291
292 for(int i = ndwords-b; i < ndwords; i++)
293 {
294 k[i] = 0;
295 }
296
297 if(c == 0) return;
298
299 for(int i = 0; i < ndwords; i++)
300 {
301 uint32_t a = (i == ndwords-1) ? 0 : k[i+1];
302 uint32_t b = k[i];
303
304 k[i] = (a << (32-c) ) | (b >> c);
305 }
306}
307
308//-----------------------------------------------------------------------------
309
310void lrot1 ( void * blob, int len, int c )
311{
312 int nbits = len * 8;
313
314 for(int i = 0; i < c; i++)
315 {
316 uint32_t bit = getbit(blob,len,nbits-1);
317
318 lshift1(blob,len,1);
319
320 setbit(blob,len,0,bit);
321 }
322}
323
324void lrot8 ( void * blob, int len, int c )
325{
326 int nbytes = len;
327
328 uint8_t * k = (uint8_t*)blob;
329
330 if(c == 0) return;
331
332 //----------
333
334 int b = c / 8;
335 c &= (8-1);
336
337 for(int j = 0; j < b; j++)
338 {
339 uint8_t t = k[nbytes-1];
340
341 for(int i = nbytes-1; i > 0; i--)
342 {
343 k[i] = k[i-1];
344 }
345
346 k[0] = t;
347 }
348
349 uint8_t t = k[nbytes-1];
350
351 if(c == 0) return;
352
353 for(int i = nbytes-1; i >= 0; i--)
354 {
355 uint8_t a = k[i];
356 uint8_t b = (i == 0) ? t : k[i-1];
357
358 k[i] = (a << c) | (b >> (8-c));
359 }
360}
361
362void lrot32 ( void * blob, int len, int c )
363{
364 assert((len & 3) == 0);
365
366 int nbytes = len;
367 int ndwords = nbytes/4;
368
369 uint32_t * k = (uint32_t*)blob;
370
371 if(c == 0) return;
372
373 //----------
374
375 int b = c / 32;
376 c &= (32-1);
377
378 for(int j = 0; j < b; j++)
379 {
380 uint32_t t = k[ndwords-1];
381
382 for(int i = ndwords-1; i > 0; i--)
383 {
384 k[i] = k[i-1];
385 }
386
387 k[0] = t;
388 }
389
390 uint32_t t = k[ndwords-1];
391
392 if(c == 0) return;
393
394 for(int i = ndwords-1; i >= 0; i--)
395 {
396 uint32_t a = k[i];
397 uint32_t b = (i == 0) ? t : k[i-1];
398
399 k[i] = (a << c) | (b >> (32-c));
400 }
401}
402
403//-----------------------------------------------------------------------------
404
405void rrot1 ( void * blob, int len, int c )
406{
407 int nbits = len * 8;
408
409 for(int i = 0; i < c; i++)
410 {
411 uint32_t bit = getbit(blob,len,0);
412
413 rshift1(blob,len,1);
414
415 setbit(blob,len,nbits-1,bit);
416 }
417}
418
419void rrot8 ( void * blob, int len, int c )
420{
421 int nbytes = len;
422
423 uint8_t * k = (uint8_t*)blob;
424
425 if(c == 0) return;
426
427 //----------
428
429 int b = c / 8;
430 c &= (8-1);
431
432 for(int j = 0; j < b; j++)
433 {
434 uint8_t t = k[0];
435
436 for(int i = 0; i < nbytes-1; i++)
437 {
438 k[i] = k[i+1];
439 }
440
441 k[nbytes-1] = t;
442 }
443
444 if(c == 0) return;
445
446 //----------
447
448 uint8_t t = k[0];
449
450 for(int i = 0; i < nbytes; i++)
451 {
452 uint8_t a = (i == nbytes-1) ? t : k[i+1];
453 uint8_t b = k[i];
454
455 k[i] = (a << (8-c)) | (b >> c);
456 }
457}
458
459void rrot32 ( void * blob, int len, int c )
460{
461 assert((len & 3) == 0);
462
463 int nbytes = len;
464 int ndwords = nbytes/4;
465
466 uint32_t * k = (uint32_t*)blob;
467
468 if(c == 0) return;
469
470 //----------
471
472 int b = c / 32;
473 c &= (32-1);
474
475 for(int j = 0; j < b; j++)
476 {
477 uint32_t t = k[0];
478
479 for(int i = 0; i < ndwords-1; i++)
480 {
481 k[i] = k[i+1];
482 }
483
484 k[ndwords-1] = t;
485 }
486
487 if(c == 0) return;
488
489 //----------
490
491 uint32_t t = k[0];
492
493 for(int i = 0; i < ndwords; i++)
494 {
495 uint32_t a = (i == ndwords-1) ? t : k[i+1];
496 uint32_t b = k[i];
497
498 k[i] = (a << (32-c)) | (b >> c);
499 }
500}
501
502//-----------------------------------------------------------------------------
503
504uint32_t window1 ( void * blob, int len, int start, int count )
505{
506 int nbits = len*8;
507 start %= nbits;
508
509 uint32_t t = 0;
510
511 for(int i = 0; i < count; i++)
512 {
513 setbit(&t,sizeof(t),i, getbit_wrap(blob,len,start+i));
514 }
515
516 return t;
517}
518
519uint32_t window8 ( void * blob, int len, int start, int count )
520{
521 int nbits = len*8;
522 start %= nbits;
523
524 uint32_t t = 0;
525 uint8_t * k = (uint8_t*)blob;
526
527 if(count == 0) return 0;
528
529 int c = start & (8-1);
530 int d = start / 8;
531
532 for(int i = 0; i < 4; i++)
533 {
534 int ia = (i + d + 1) % len;
535 int ib = (i + d + 0) % len;
536
537 uint32_t a = k[ia];
538 uint32_t b = k[ib];
539
540 uint32_t m = (a << (8-c)) | (b >> c);
541
542 t |= (m << (8*i));
543
544 }
545
546 t &= ((1 << count)-1);
547
548 return t;
549}
550
551uint32_t window32 ( void * blob, int len, int start, int count )
552{
553 int nbits = len*8;
554 start %= nbits;
555
556 assert((len & 3) == 0);
557
558 int ndwords = len / 4;
559
560 uint32_t * k = (uint32_t*)blob;
561
562 if(count == 0) return 0;
563
564 int c = start & (32-1);
565 int d = start / 32;
566
567 if(c == 0) return (k[d] & ((1 << count) - 1));
568
569 int ia = (d + 1) % ndwords;
570 int ib = (d + 0) % ndwords;
571
572 uint32_t a = k[ia];
573 uint32_t b = k[ib];
574
575 uint32_t t = (a << (32-c)) | (b >> c);
576
577 t &= ((1 << count)-1);
578
579 return t;
580}
581
582//-----------------------------------------------------------------------------
583
584bool test_shift ( void )
585{
586 int nbits = 64;
587 int nbytes = nbits / 8;
588 int reps = 10000;
589
590 for(int j = 0; j < reps; j++)
591 {
592 if(j % (reps/10) == 0) printf(".");
593
594 uint64_t a = rand_u64();
595 uint64_t b;
596
597 for(int i = 0; i < nbits; i++)
598 {
599 b = a; lshift1 (&b,nbytes,i); assert(b == (a << i));
600 b = a; lshift8 (&b,nbytes,i); assert(b == (a << i));
601 b = a; lshift32 (&b,nbytes,i); assert(b == (a << i));
602
603 b = a; rshift1 (&b,nbytes,i); assert(b == (a >> i));
604 b = a; rshift8 (&b,nbytes,i); assert(b == (a >> i));
605 b = a; rshift32 (&b,nbytes,i); assert(b == (a >> i));
606
607 b = a; lrot1 (&b,nbytes,i); assert(b == _rotl64(a,i));
608 b = a; lrot8 (&b,nbytes,i); assert(b == _rotl64(a,i));
609 b = a; lrot32 (&b,nbytes,i); assert(b == _rotl64(a,i));
610
611 b = a; rrot1 (&b,nbytes,i); assert(b == _rotr64(a,i));
612 b = a; rrot8 (&b,nbytes,i); assert(b == _rotr64(a,i));
613 b = a; rrot32 (&b,nbytes,i); assert(b == _rotr64(a,i));
614 }
615 }
616
617 printf("PASS\n");
618 return true;
619}
620
621//-----------------------------------------------------------------------------
622
623template < int nbits >
624bool test_window2 ( void )
625{
626 struct keytype
627 {
628 uint8_t bytes[nbits/8];
629 };
630
631 int nbytes = nbits / 8;
632 int reps = 10000;
633
634 for(int j = 0; j < reps; j++)
635 {
636 if(j % (reps/10) == 0) printf(".");
637
638 keytype k;
639
640 rand_p(&k,nbytes);
641
642 for(int start = 0; start < nbits; start++)
643 {
644 for(int count = 0; count < 32; count++)
645 {
646 uint32_t a = window1(&k,nbytes,start,count);
647 uint32_t b = window8(&k,nbytes,start,count);
648 uint32_t c = window(&k,nbytes,start,count);
649
650 assert(a == b);
651 assert(a == c);
652 }
653 }
654 }
655
656 printf("PASS %d\n",nbits);
657
658 return true;
659}
660
661bool test_window ( void )
662{
663 int reps = 10000;
664
665 for(int j = 0; j < reps; j++)
666 {
667 if(j % (reps/10) == 0) printf(".");
668
669 int nbits = 64;
670 int nbytes = nbits / 8;
671
672 uint64_t x = rand_u64();
673
674 for(int start = 0; start < nbits; start++)
675 {
676 for(int count = 0; count < 32; count++)
677 {
678 uint32_t a = (uint32_t)_rotr64(x,start);
679 a &= ((1 << count)-1);
680
681 uint32_t b = window1 (&x,nbytes,start,count);
682 uint32_t c = window8 (&x,nbytes,start,count);
683 uint32_t d = window32(&x,nbytes,start,count);
684 uint32_t e = window (x,start,count);
685
686 assert(a == b);
687 assert(a == c);
688 assert(a == d);
689 assert(a == e);
690 }
691 }
692 }
693
694 printf("PASS 64\n");
695
696 test_window2<8>();
697 test_window2<16>();
698 test_window2<24>();
699 test_window2<32>();
700 test_window2<40>();
701 test_window2<48>();
702 test_window2<56>();
703 test_window2<64>();
704
705 return true;
706}
707
708//-----------------------------------------------------------------------------