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