00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <omnetpp.h>
00025
00026 #include "OverlayKey.h"
00027 #include "Comparator.h"
00028
00029 #include <BinaryValue.h>
00030 #include "SHA1.h"
00031
00032 using namespace std;
00033
00034 uint32_t OverlayKey::keyLength = MAX_KEYLENGTH;
00035
00036
00037
00038
00039
00040
00041 uint32_t OverlayKey::aSize = OverlayKey::keyLength / (8*sizeof(mp_limb_t)) +
00042 (OverlayKey::keyLength % (8*sizeof(mp_limb_t))
00043 != 0 ? 1 : 0);
00044
00045 mp_limb_t OverlayKey::GMP_MSB_MASK = (OverlayKey::keyLength % GMP_LIMB_BITS)
00046 != 0 ? (((mp_limb_t)1 << (OverlayKey::keyLength % GMP_LIMB_BITS))-1)
00047 : (mp_limb_t) - 1;
00048
00049
00050
00051
00052
00053
00054 const OverlayKey OverlayKey::UNSPECIFIED_KEY;
00055 const OverlayKey OverlayKey::ZERO((uint32_t)0);
00056 const OverlayKey OverlayKey::ONE((uint32_t)1);
00057
00058
00059
00060 const char* HEX = "0123456789abcdef";
00061
00062
00063
00064
00065
00066
00067 OverlayKey::OverlayKey()
00068 {
00069 isUnspec = true;
00070 }
00071
00072
00073 OverlayKey::OverlayKey(uint32_t num)
00074 {
00075 clear();
00076 key[0] = num;
00077 trim();
00078 }
00079
00080
00081 OverlayKey::OverlayKey(const unsigned char* buf, uint32_t size)
00082 {
00083 int trimSize, offset;
00084 clear();
00085 trimSize = (int)min((uint32_t) (aSize * sizeof(mp_limb_t)), size);
00086 offset = aSize * sizeof(mp_limb_t) - trimSize;
00087 memcpy( ((char*)key) + offset, buf, trimSize);
00088 trim();
00089 }
00090
00091
00092 OverlayKey::OverlayKey(const std::string& str, uint32_t base)
00093 {
00094 if ((base < 2) || (base > 16)) {
00095 throw cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00096 }
00097
00098 string s(str);
00099 clear();
00100
00101 for (uint32_t i=0; i<s.size(); i++) {
00102 if ((s[i] >= '0') && (s[i] <= '9')) {
00103 s[i] -= '0';
00104 } else if ((s[i] >= 'a') && (s[i] <= 'f')) {
00105 s[i] -= ('a' - 10);
00106 } else if ((s[i] >= 'A') & (s[i] <= 'F')) {
00107 s[i] -= ('A' - 10);
00108 } else {
00109 throw cRuntimeError("OverlayKey::OverlayKey(): "
00110 "Invalid character in string!");
00111 }
00112 }
00113
00114 mpn_set_str ((mp_limb_t*)this->key, (const unsigned char*)s.c_str(),
00115 str.size(), base);
00116 trim();
00117 }
00118
00119
00120 OverlayKey::OverlayKey(const OverlayKey& rhs)
00121 {
00122 (*this) = rhs;
00123 }
00124
00125
00126 OverlayKey::~OverlayKey()
00127 {}
00128
00129
00130
00131
00132
00133 void OverlayKey::setKeyLength(uint32_t length)
00134 {
00135 if ((length < 1) || (length > OverlayKey::keyLength)) {
00136 opp_error("OverlayKey::setKeyLength(): length must be <= %i "
00137 "and setKeyLength() must not be called twice "
00138 "with different length!", MAX_KEYLENGTH);
00139 }
00140
00141 keyLength = length;
00142
00143 aSize = keyLength / (8*sizeof(mp_limb_t)) +
00144 (keyLength % (8*sizeof(mp_limb_t))!=0 ? 1 : 0);
00145
00146 GMP_MSB_MASK = (keyLength % GMP_LIMB_BITS)
00147 != 0 ? (((mp_limb_t)1 << (keyLength % GMP_LIMB_BITS))-1)
00148 : (mp_limb_t)-1;
00149 }
00150
00151
00152
00153 uint32_t OverlayKey::getLength()
00154 {
00155 return OverlayKey::keyLength;
00156 }
00157
00158 bool OverlayKey::isUnspecified() const
00159 {
00160 return isUnspec;
00161 }
00162
00163 std::string OverlayKey::toString(uint32_t base) const
00164 {
00165 if ((base != 2) && (base != 16)) {
00166 throw cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00167 }
00168
00169 if (isUnspec)
00170 return std::string("<unspec>");
00171 else {
00172 char temp[MAX_KEYLENGTH+1];
00173
00174 if (base==16) {
00175 int k=0;
00176 for (int i=(keyLength-1)/4; i>=0; i--, k++)
00177 temp[k] = HEX[this->getBitRange
00178 (4*i,4)];
00179
00180 temp[k] = 0;
00181 return std::string((const char*)temp);
00182 } else if (base==2) {
00183 int k=0;
00184 for (int i=keyLength-1; i>=0; i-=1, k++)
00185 temp[k] = HEX[this->getBit(i)];
00186 temp[k] = 0;
00187 return std::string((const char*)temp);
00188 } else {
00189 throw cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00190 }
00191
00192
00193 #if 0
00194 mp_size_t last = mpn_get_str((unsigned char*)temp, base,
00195 (mp_limb_t*)this->key, aSize);
00196 for (int i=0; i<last; i++) {
00197 temp[i] = HEX[temp[i]];
00198 }
00199 temp[last] = 0;
00200 return std::string((const char*)temp);
00201 #endif
00202
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211 OverlayKey& OverlayKey::operator=(const OverlayKey& rhs)
00212 {
00213 isUnspec = rhs.isUnspec;
00214 memcpy( key, rhs.key, aSize*sizeof(mp_limb_t) );
00215 return *this;
00216 }
00217
00218
00219 OverlayKey& OverlayKey::operator--()
00220 {
00221 return (*this -= ONE);
00222 }
00223
00224
00225 OverlayKey OverlayKey::operator--(int)
00226 {
00227 OverlayKey clone = *this;
00228 *this -= ONE;
00229 return clone;
00230 }
00231
00232
00233 OverlayKey& OverlayKey::operator++()
00234 {
00235 return (*this += ONE);
00236 }
00237
00238
00239 OverlayKey OverlayKey::operator++(int)
00240 {
00241 OverlayKey clone = *this;
00242 *this += ONE;
00243 return clone;
00244 }
00245
00246
00247 OverlayKey& OverlayKey::operator+=( const OverlayKey& rhs )
00248 {
00249 mpn_add_n((mp_limb_t*)key, (mp_limb_t*)key, (mp_limb_t*)rhs.key, aSize);
00250 trim();
00251 isUnspec = false;
00252 return *this;
00253 }
00254
00255
00256 OverlayKey& OverlayKey::operator-=( const OverlayKey& rhs )
00257 {
00258 mpn_sub_n((mp_limb_t*)key, (mp_limb_t*)key, (mp_limb_t*)rhs.key, aSize);
00259 trim();
00260 isUnspec = false;
00261 return *this;
00262 }
00263
00264
00265 OverlayKey OverlayKey::operator+(const OverlayKey& rhs) const
00266 {
00267 OverlayKey result = *this;
00268 result += rhs;
00269 return result;
00270 }
00271
00272
00273 OverlayKey OverlayKey::operator-(const OverlayKey& rhs) const
00274 {
00275 OverlayKey result = *this;
00276 result -= rhs;
00277 return result;
00278 }
00279
00280
00281 bool OverlayKey::operator<(const OverlayKey& compKey) const
00282 {
00283 return compareTo(compKey) < 0;
00284 }
00285 bool OverlayKey::operator>(const OverlayKey& compKey) const
00286 {
00287 return compareTo(compKey) > 0;
00288 }
00289 bool OverlayKey::operator<=(const OverlayKey& compKey) const
00290 {
00291 return compareTo(compKey) <=0;
00292 }
00293 bool OverlayKey::operator>=(const OverlayKey& compKey) const
00294 {
00295 return compareTo(compKey) >=0;
00296 }
00297 bool OverlayKey::operator==(const OverlayKey& compKey) const
00298 {
00299 return compareTo(compKey) ==0;
00300 }
00301 bool OverlayKey::operator!=(const OverlayKey& compKey) const
00302 {
00303 return compareTo(compKey) !=0;
00304 }
00305
00306
00307 OverlayKey OverlayKey::operator^ (const OverlayKey& rhs) const
00308 {
00309 OverlayKey result = *this;
00310 for (uint32_t i=0; i<aSize; i++) {
00311 result.key[i] ^= rhs.key[i];
00312 }
00313
00314 return result;
00315 }
00316
00317
00318 OverlayKey OverlayKey::operator| (const OverlayKey& rhs) const
00319 {
00320 OverlayKey result = *this;
00321 for (uint32_t i=0; i<aSize; i++) {
00322 result.key[i] |= rhs.key[i];
00323 }
00324
00325 return result;
00326 }
00327
00328
00329 OverlayKey OverlayKey::operator& (const OverlayKey& rhs) const
00330 {
00331 OverlayKey result = *this;
00332 for (uint32_t i=0; i<aSize; i++) {
00333 result.key[i] &= rhs.key[i];
00334 }
00335
00336 return result;
00337 }
00338
00339
00340 OverlayKey OverlayKey::operator~ () const
00341 {
00342 OverlayKey result = *this;
00343 for (uint32_t i=0; i<aSize; i++) {
00344 result.key[i] = ~key[i];
00345 }
00346 result.trim();
00347
00348 return result;
00349 }
00350
00351
00352 OverlayKey OverlayKey::operator>>(uint32_t num) const
00353 {
00354 OverlayKey result = ZERO;
00355 int i = num/GMP_LIMB_BITS;
00356
00357 num %= GMP_LIMB_BITS;
00358
00359 if (i>=(int)aSize)
00360 return result;
00361
00362 for (int j=0; j<(int)aSize-i; j++) {
00363 result.key[j] = key[j+i];
00364 }
00365 mpn_rshift(result.key,result.key,aSize,num);
00366 result.isUnspec = false;
00367 result.trim();
00368
00369 return result;
00370 }
00371
00372
00373 OverlayKey OverlayKey::operator<<(uint32_t num) const
00374 {
00375 OverlayKey result = ZERO;
00376 int i = num/GMP_LIMB_BITS;
00377
00378 num %= GMP_LIMB_BITS;
00379
00380 if (i>=(int)aSize)
00381 return result;
00382
00383 for (int j=0; j<(int)aSize-i; j++) {
00384 result.key[j+i] = key[j];
00385 }
00386 mpn_lshift(result.key,result.key,aSize,num);
00387 result.isUnspec = false;
00388 result.trim();
00389
00390 return result;
00391 }
00392
00393
00394 OverlayKeyBit OverlayKey::operator[](uint32_t n)
00395 {
00396 return OverlayKeyBit(getBit(n), n, this);
00397 }
00398
00399 OverlayKey& OverlayKey::setBit(uint32_t pos, bool value)
00400 {
00401 if (pos >= keyLength) {
00402 throw cRuntimeError("OverlayKey::setBitAt(): "
00403 "pos >= keyLength!");
00404 }
00405
00406 mp_limb_t digit = 1;
00407 digit = digit << (pos % GMP_LIMB_BITS);
00408
00409 if (value) {
00410 key[pos / GMP_LIMB_BITS] |= digit;
00411 } else {
00412
00413 key[pos / GMP_LIMB_BITS] &= ~digit;
00414 }
00415
00416 return *this;
00417 };
00418
00419
00420
00421
00422
00423
00424 uint32_t OverlayKey::getBitRange(uint32_t p, uint32_t n) const
00425 {
00426 int i = p / GMP_LIMB_BITS,
00427 f = p % GMP_LIMB_BITS,
00428 f2 = f + n - GMP_LIMB_BITS;
00429
00430 if ((p + n > OverlayKey::keyLength) || (n > 32)) {
00431 throw cRuntimeError("OverlayKey::get: Invalid range");
00432 }
00433 if (GMP_LIMB_BITS < 32) {
00434 throw cRuntimeError("OverlayKey::get: GMP_LIMB_BITS too small!");
00435 }
00436
00437 return ((key[i] >> f) |
00438 (f2 > 0 ? (key[i+1] << (GMP_LIMB_BITS - f)) : 0)) &
00439 (((uint32_t)(~0)) >> (GMP_LIMB_BITS - n));
00440 }
00441
00442
00443 OverlayKey OverlayKey::randomSuffix( uint32_t pos ) const
00444 {
00445 OverlayKey newKey = *this;
00446 int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
00447 mp_limb_t m = ((mp_limb_t)1 << j)-1;
00448 mp_limb_t rnd;
00449
00450
00451 omnet_random(&rnd,1);
00452 newKey.key[i] &= ~m;
00453 newKey.key[i] |= (rnd&m);
00454
00455 omnet_random(newKey.key,i);
00456 newKey.trim();
00457
00458 return newKey;
00459 }
00460
00461
00462 OverlayKey OverlayKey::randomPrefix( uint32_t pos ) const
00463 {
00464 OverlayKey newKey = *this;
00465 int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
00466 mp_limb_t m = ((mp_limb_t)1 << j)-1;
00467 mp_limb_t rnd;
00468
00469
00470 omnet_random(&rnd,1);
00471
00472 newKey.key[i] &= m;
00473 newKey.key[i] |= (rnd&~m);
00474 for (int k=aSize-1; k!=i; k--) {
00475
00476 omnet_random( &newKey.key[k], 1 );
00477 }
00478 newKey.trim();
00479
00480 return newKey;
00481 }
00482
00483
00484 uint32_t OverlayKey::sharedPrefixLength(const OverlayKey& compKey,
00485 uint32_t bitsPerDigit) const
00486 {
00487 if (compareTo(compKey) == 0) return keyLength;
00488
00489 uint32_t length = 0;
00490 int i;
00491 uint32_t j;
00492 bool msb = true;
00493
00494
00495 for (i=aSize-1; i>=0; --i) {
00496 if (this->key[i] != compKey.key[i]) {
00497
00498 mp_limb_t d = this->key[i] ^ compKey.key[i];
00499 if (msb) d <<= ( GMP_LIMB_BITS - (keyLength % GMP_LIMB_BITS) );
00500 for (j = GMP_LIMB_BITS-1; d >>= 1; --j);
00501 length += j;
00502 break;
00503 }
00504 length += GMP_LIMB_BITS;
00505 msb = false;
00506 }
00507
00508 return length / bitsPerDigit;
00509 }
00510
00511
00512 int OverlayKey::log_2() const
00513 {
00514 int16_t i = aSize-1;
00515
00516 while (i>=0 && key[i]==0) {
00517 i--;
00518 }
00519
00520 if (i<0) {
00521 return -1;
00522 }
00523
00524 mp_limb_t j = key[i];
00525 i *= GMP_LIMB_BITS;
00526 while (j!=0) {
00527 j >>= 1;
00528 i++;
00529 }
00530
00531 return i-1;
00532 }
00533
00534
00535 size_t OverlayKey::hash() const
00536 {
00537 return (size_t)key[0];
00538 }
00539
00540
00541 bool OverlayKey::isBetween(const OverlayKey& keyA,
00542 const OverlayKey& keyB) const
00543 {
00544 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00545 return false;
00546
00547 if (*this == keyA)
00548 return false;
00549 else if (keyA < keyB)
00550 return ((*this > keyA) && (*this < keyB));
00551 else
00552 return ((*this > keyA) || (*this < keyB));
00553 }
00554
00555
00556 bool OverlayKey::isBetweenR(const OverlayKey& keyA,
00557 const OverlayKey& keyB) const
00558 {
00559 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00560 return false;
00561
00562 if ((keyA == keyB) && (*this == keyA))
00563 return true;
00564 else if (keyA <= keyB)
00565 return ((*this > keyA) && (*this <= keyB));
00566 else
00567 return ((*this > keyA) || (*this <= keyB));
00568 }
00569
00570
00571 bool OverlayKey::isBetweenL(const OverlayKey& keyA,
00572 const OverlayKey& keyB) const
00573 {
00574 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00575 return false;
00576
00577 if ((keyA == keyB) && (*this == keyA))
00578 return true;
00579 else if (keyA <= keyB)
00580 return ((*this >= keyA) && (*this < keyB));
00581 else
00582 return ((*this >= keyA) || (*this < keyB));
00583 }
00584
00585
00586 bool OverlayKey::isBetweenLR(const OverlayKey& keyA,
00587 const OverlayKey& keyB) const
00588 {
00589 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00590 return false;
00591
00592 if ((keyA == keyB) && (*this == keyA))
00593 return true;
00594 else if (keyA <= keyB)
00595 return ((*this >= keyA) && (*this <= keyB));
00596 else
00597 return ((*this >= keyA) || (*this <= keyB));
00598 }
00599
00600
00601
00602
00603
00604
00605
00606 std::ostream& operator<<(std::ostream& os, const OverlayKey& c)
00607 {
00608 os << c.toString(16);
00609 return os;
00610 };
00611
00612
00613 OverlayKey OverlayKey::getMax()
00614 {
00615 OverlayKey newKey;
00616
00617 for (uint32_t i=0; i<aSize; i++) {
00618 newKey.key[i] = ~0;
00619 }
00620 newKey.isUnspec = false;
00621 newKey.trim();
00622
00623 return newKey;
00624 }
00625
00626
00627 OverlayKey OverlayKey::random()
00628 {
00629 OverlayKey newKey = ZERO;
00630
00631 omnet_random(newKey.key,aSize);
00632
00633 newKey.trim();
00634
00635 return newKey;
00636 }
00637
00638
00639 OverlayKey OverlayKey::sha1(const BinaryValue& input)
00640 {
00641 OverlayKey newKey = OverlayKey();
00642 uint8_t temp[20];
00643 CSHA1 sha1;
00644
00645 sha1.Reset();
00646 sha1.Update((uint8_t*)(&(*input.begin())), input.size());
00647 sha1.Final();
00648 sha1.GetHash(temp);
00649 mpn_set_str(newKey.key, (const uint8_t*)temp,
00650 (int)std::min((uint32_t)(aSize * sizeof(mp_limb_t)), 20U), 256);
00651 newKey.isUnspec = false;
00652 newKey.trim();
00653
00654 return newKey;
00655 }
00656
00657
00658 OverlayKey OverlayKey::pow2( uint32_t exponent )
00659 {
00660 if (exponent >= keyLength) {
00661 throw cRuntimeError("OverlayKey::pow2(): "
00662 "exponent >= keyLength!");
00663 }
00664
00665 OverlayKey newKey = ZERO;
00666
00667 newKey.key[exponent/GMP_LIMB_BITS] =
00668 (mp_limb_t)1 << (exponent % GMP_LIMB_BITS);
00669
00670 return newKey;
00671 }
00672
00673
00674 void OverlayKey::test()
00675 {
00676
00677 cout << endl << "--- Add test ..." << endl;
00678 OverlayKey key = 123456789;
00679 cout << " key=" << key << endl;
00680 cout << " key += 987654321 = " << (key+=987654321) << endl;
00681 cout << " prefix++ : " << (++key) << endl;
00682 cout << " postfix++ : " << (key++) << endl;
00683 cout << " key=" << key << endl;
00684
00685 OverlayKey k1 = 256, k2 = 10, k3 = 3;
00686
00687
00688 cout << endl << "--- Compare test ..." << endl;
00689 cout << " 256 < 10 = "<< (k1 < k2) << " k1="<<k1<<endl;
00690 cout << " 256 > 10 = "<< (k1 > k2) << " k2="<<k2<<endl;
00691
00692 cout << " 10 isBetween(3, 256)=" << k2.isBetween(k3, k1) << endl;
00693 cout << " 3 isBetween(10, 256)=" << k3.isBetween(k2, k1) << endl;
00694 cout << " 256 isBetween(10, 256)=" << k1.isBetween(k2, k1) << endl;
00695 cout << " 256 isBetweenR(10, 256)=" << k1.isBetweenR(k2, k1) << endl;
00696 cout << " max isBetween(max-1,0)=" << OverlayKey::getMax().isBetween(
00697 OverlayKey::getMax()-1, OverlayKey::ZERO) << endl;
00698 cout << " max-1 isBetween(max,1)=" << (OverlayKey::getMax()-1).isBetween(
00699 OverlayKey::getMax(), OverlayKey::ONE) << endl;
00700 cout << " max-1 isBetweenL(max-1,1)=" << (OverlayKey::getMax()-1).
00701 isBetweenL(OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00702 cout << " 1 isBetweenL(max-1,1)=" << (OverlayKey::ONE).isBetweenL(
00703 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00704 cout << " 1 isBetweenR(max-1,1)=" << OverlayKey::ONE.isBetweenR(
00705 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00706 cout << " 1 isBetween(max-1,1)=" << OverlayKey::ONE.isBetween(
00707 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00708 cout << " 1 isBetween(max-1,0)=" << OverlayKey::ONE.isBetween(
00709 OverlayKey::getMax()-1, OverlayKey::ZERO) << endl;
00710 cout << " 256 sharedPrefixLength(3)=" << k1.sharedPrefixLength(k3)
00711 << endl;
00712 cout << " 256 sharedPrefixLength(256)=" << k1.sharedPrefixLength(k1)
00713 << endl;
00714
00715
00716 cout << endl << "--- Warp around test ..." << endl;
00717
00718 k1 = OverlayKey::getMax();
00719 cout << "k1=max= " << k1.toString(16) << endl;
00720 cout << "k1+1 = " << (k1 + 1).toString(16) << endl;
00721 cout << "k1+2 = " << (k1 + 2).toString(16) << endl;
00722
00723 k1 = OverlayKey::ZERO;
00724 cout << "k1=0= " << k1.toString(16) << endl;
00725 cout << "k1-1 = " << (k1 - 1).toString(16) << endl;
00726 cout << "k1-2 = " << (k1 - 2).toString(16) << endl;
00727
00728 cout << "max > ONE=" << (OverlayKey::getMax() > OverlayKey::ONE) << endl;
00729 cout << "max < ONE=" << (OverlayKey::getMax() < OverlayKey::ONE) << endl;
00730
00731
00732 cout << endl << "--- Distance test ..." << endl;
00733
00734 cout << "KeyRingMetric::distance(1, max)="
00735 << KeyRingMetric().distance(OverlayKey::ONE, OverlayKey::getMax()) << endl;
00736 cout << "KeyUniRingMetric::distance(1, max)="
00737 << KeyUniRingMetric().distance(OverlayKey::ONE, OverlayKey::getMax()) << endl;
00738 cout << "KeyRingMetric::distance(max, 1)="
00739 << KeyRingMetric().distance(OverlayKey::getMax(), OverlayKey::ONE) << endl;
00740 cout << "KeyUniRingMetric::distance(max, 1)="
00741 << KeyUniRingMetric().distance(OverlayKey::getMax(), OverlayKey::ONE) << endl;
00742
00743
00744 cout << endl << "--- RandomSuffix and log2 test ..." << endl;
00745 k1 = OverlayKey::ZERO;
00746 for (uint32_t i=0; i<k1.getLength(); i++) {
00747 k2=k1.randomSuffix(i);
00748 cout << " " << k2.toString(16) << " log2=" << k2.log_2() << endl;
00749 }
00750 cout << endl << "--- RandomPrefix and log2 test ..." << endl;
00751 k1 = OverlayKey::getMax();
00752 for (uint32_t i=0; i<k1.getLength(); i++) {
00753 k2=k1.randomPrefix(i);
00754 cout << " " << k2.toString(16) << " log2=" << k2.log_2() << endl;
00755 }
00756
00757 cout << endl << "--- pow2 test..." << endl;
00758 for (uint32_t i=0; i<k1.getLength(); i++) {
00759 k2=pow2(i);
00760 cout << " 2^" << i << " = " << k2.toString(16) << " log2="
00761 << k2.log_2() << endl;
00762 }
00763
00764 cout << endl << "--- Bits test ..." << endl << " ";
00765 const char* BITS[] = { "000","001","010","011","100","101","110","111" };
00766 k1 = OverlayKey::random();
00767 for (int i=k1.getLength()-1; i>=0; i--)
00768 cout << k1[i];
00769 cout << " = " << endl << " ";
00770 for (int i=k1.getLength()-3; i>=0; i-=3)
00771 cout << BITS[k1.getBitRange(i,3)];
00772 cout << endl;
00773
00774 cout << endl << "--- SHA1 test ... (verified with test vectors)" << endl;
00775 cout << " Empty string: " << OverlayKey::sha1("").toString(16)
00776 << " = da39a3ee5e6b4b0d3255bfef95601890afd80709" << endl;
00777 cout << " 'Hello World' string: "
00778 << OverlayKey::sha1("Hello World").toString(16)
00779 << " = 0a4d55a8d778e5022fab701977c5d840bbc486d0" << endl;
00780 }
00781
00782
00783
00784
00785
00786
00787 inline void OverlayKey::trim()
00788 {
00789 key[aSize-1] &= GMP_MSB_MASK;
00790 }
00791
00792
00793
00794 int OverlayKey::compareTo( const OverlayKey& compKey ) const
00795 {
00796 if (compKey.isUnspec || isUnspec)
00797 opp_error("OverlayKey::compareTo(): key is unspecified!");
00798 return mpn_cmp(key,compKey.key,aSize);
00799 }
00800
00801
00802 inline void OverlayKey::clear()
00803 {
00804 memset( key, 0, aSize * sizeof(mp_limb_t) );
00805 isUnspec = false;
00806 }
00807
00808
00809 inline void omnet_random(mp_limb_t *r1p, mp_size_t r1n)
00810 {
00811
00812 uint32_t* chunkPtr = (uint32_t*)r1p;
00813
00814 for (uint32_t i=0; i < ((r1n*sizeof(mp_limb_t) + 3) / 4); i++) {
00815 chunkPtr[i] = intuniform(0, 0xFFFFFFFF);
00816 }
00817 }
00818
00819 #ifdef __GMP_SHORT_LIMB
00820 #define GMP_TYPE unsigned int
00821 #else
00822 #ifdef _LONG_LONG_LIMB
00823 #define GMP_TYPE unsigned long long int
00824 #else
00825 #define GMP_TYPE unsigned long int
00826 #endif
00827 #endif
00828
00829 void OverlayKey::netPack(cCommBuffer *b)
00830 {
00831 doPacking(b,(GMP_TYPE*)this->key, MAX_KEYLENGTH / (8*sizeof(mp_limb_t)) +
00832 (MAX_KEYLENGTH % (8*sizeof(mp_limb_t))!=0 ? 1 : 0));
00833 doPacking(b,this->isUnspec);
00834 }
00835
00836 void OverlayKey::netUnpack(cCommBuffer *b)
00837 {
00838 doUnpacking(b,(GMP_TYPE*)this->key, MAX_KEYLENGTH / (8*sizeof(mp_limb_t)) +
00839 (MAX_KEYLENGTH % (8*sizeof(mp_limb_t))!=0 ? 1 : 0));
00840 doUnpacking(b,this->isUnspec);
00841
00842 }
00843