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